From 9348be0acdf837727cb489bb5991c0e25b23a4a6 Mon Sep 17 00:00:00 2001 From: Gamonoid Date: Fri, 25 Nov 2016 13:53:36 +0100 Subject: [PATCH] Add vagrant machine, new test and travis-ci config --- .gitignore | 7 +- .travis.yml | 8 + Vagrantfile | 29 + build.xml | 39 +- deployment/clients/dev/config.php | 18 + deployment/clients/dev/cron.php | 7 + deployment/clients/dev/data.php | 3 + deployment/clients/dev/data/sample | 1 + deployment/clients/dev/entry.php | 18 + deployment/clients/dev/fileupload.php | 3 + deployment/clients/dev/fileupload_page.php | 3 + deployment/clients/dev/header.php | 3 + deployment/clients/dev/index.php | 22 + deployment/clients/dev/login.php | 3 + deployment/clients/dev/logout.php | 3 + deployment/clients/dev/rest.php | 3 + deployment/clients/dev/service.php | 3 + deployment/clients/dev/update.php | 18 + deployment/clients/test/config.php | 18 + deployment/clients/test/cron.php | 7 + deployment/clients/test/data.php | 3 + deployment/clients/test/data/sample | 1 + deployment/clients/test/entry.php | 18 + deployment/clients/test/fileupload.php | 3 + deployment/clients/test/fileupload_page.php | 3 + deployment/clients/test/header.php | 3 + deployment/clients/test/index.php | 22 + deployment/clients/test/login.php | 3 + deployment/clients/test/logout.php | 3 + deployment/clients/test/rest.php | 3 + deployment/clients/test/service.php | 3 + deployment/clients/test/update.php | 18 + src/api/Base.js | 6 + src/classes/BaseService.php | 22 +- src/classes/LanguageManager.php | 7 +- src/classes/Migration.php | 260 + src/classes/RestApiManager.php | 141 +- src/classes/SubActionManager.php | 8 +- src/classes/Validator.php | 46 + src/composer/composer.json | 4 +- src/composer/composer.lock | 2080 +++++++- src/composer/vendor/bin/phpdoc-md | 1 + src/composer/vendor/bin/phpunit | 1 + src/composer/vendor/bin/robo | 1 + .../vendor/composer/autoload_classmap.php | 456 ++ .../vendor/composer/autoload_files.php | 10 + .../vendor/composer/autoload_namespaces.php | 3 +- .../vendor/composer/autoload_psr4.php | 19 + .../vendor/composer/autoload_real.php | 18 + .../vendor/composer/autoload_static.php | 596 ++- src/composer/vendor/composer/installed.json | 2213 ++++++++- .../annotated-command/.editorconfig | 15 + .../.github/issue_template.md | 11 + .../.github/pull_request_template.md | 13 + .../annotated-command/.gitignore | 5 + .../annotated-command/.travis.yml | 34 + .../annotated-command/CHANGELOG.md | 51 + .../annotated-command/CONTRIBUTING.md | 31 + .../consolidation/annotated-command/LICENSE | 8 + .../consolidation/annotated-command/README.md | 251 + .../annotated-command/composer.json | 49 + .../annotated-command/composer.lock | 1932 ++++++++ .../annotated-command/phpunit.xml.dist | 19 + .../src/AnnotatedCommand.php | 346 ++ .../src/AnnotatedCommandFactory.php | 327 ++ .../annotated-command/src/AnnotationData.php | 20 + .../src/CommandCreationListenerInterface.php | 15 + .../annotated-command/src/CommandData.php | 116 + .../annotated-command/src/CommandError.php | 32 + .../src/CommandFileDiscovery.php | 383 ++ .../src/CommandInfoAltererInterface.php | 9 + .../src/CommandProcessor.php | 308 ++ .../src/ExitCodeInterface.php | 12 + .../src/Hooks/AlterResultInterface.php | 12 + .../src/Hooks/ExtractOutputInterface.php | 14 + .../src/Hooks/HookManager.php | 700 +++ .../src/Hooks/InitializeHookInterface.php | 15 + .../src/Hooks/InteractorInterface.php | 18 + .../src/Hooks/OptionHookInterface.php | 16 + .../src/Hooks/ProcessResultInterface.php | 27 + .../src/Hooks/StatusDeterminerInterface.php | 18 + .../src/Hooks/ValidatorInterface.php | 14 + .../src/Options/AlterOptionsCommandEvent.php | 85 + .../AutomaticOptionsProviderInterface.php | 21 + .../src/Options/PrepareFormatter.php | 10 + .../Options/PrepareTerminalWidthOption.php | 69 + .../src/OutputDataInterface.php | 13 + .../src/Parser/CommandInfo.php | 581 +++ .../src/Parser/DefaultsWithDescriptions.php | 160 + .../AbstractCommandDocBlockParser.php | 252 + .../Internal/CommandDocBlockParser2.php | 70 + .../Internal/CommandDocBlockParser3.php | 74 + .../Internal/CommandDocBlockParserFactory.php | 28 + .../src/ApplicationWithTerminalWidth.php | 26 + .../tests/src/ExampleAnnotatedCommand.php | 60 + .../tests/src/ExampleCommandFile.php | 351 ++ .../tests/src/ExampleCommandInfoAlterer.php | 15 + .../tests/src/ExampleHookAllCommandFile.php | 41 + .../tests/src/alpha/AlphaCommandFile.php | 243 + .../src/alpha/Exclude/ExcludedCommandFile.php | 14 + .../alpha/Inclusive/IncludedCommandFile.php | 16 + .../tests/src/beta/BetaCommandFile.php | 52 + .../tests/testAnnotatedCommand.php | 45 + .../tests/testAnnotatedCommandFactory.php | 639 +++ .../tests/testCommandFileDiscovery.php | 82 + .../tests/testCommandInfo.php | 61 + .../annotated-command/tests/testFullStack.php | 508 ++ .../vendor/consolidation/log/.gitignore | 3 + src/composer/vendor/consolidation/log/LICENSE | 8 + .../vendor/consolidation/log/README.md | 33 + .../vendor/consolidation/log/circle.yml | 12 + .../vendor/consolidation/log/composer.json | 35 + .../vendor/consolidation/log/phpunit.xml.dist | 7 + .../consolidation/log/src/ConsoleLogLevel.php | 25 + .../consolidation/log/src/LogOutputStyler.php | 115 + .../log/src/LogOutputStylerInterface.php | 105 + .../vendor/consolidation/log/src/Logger.php | 269 ++ .../log/src/SymfonyLogOutputStyler.php | 65 + .../log/src/UnstyledLogOutputStyler.php | 97 + .../log/tests/src/TestDataPermuter.php | 81 + .../log/tests/testLogMethods.php | 54 + .../tests/testLoggerVerbosityAndStyles.php | 164 + .../output-formatters/.editorconfig | 15 + .../.github/issue_template.md | 11 + .../.github/pull_request_template.md | 13 + .../output-formatters/.gitignore | 7 + .../output-formatters/.travis.yml | 30 + .../output-formatters/CHANGELOG.md | 35 + .../output-formatters/CONTRIBUTING.md | 31 + .../consolidation/output-formatters/LICENSE | 8 + .../consolidation/output-formatters/README.md | 130 + .../output-formatters/composer.json | 43 + .../output-formatters/docs/api.md | 658 +++ .../output-formatters/docs/index.md | 3 + .../output-formatters/mkdocs.yml | 7 + .../output-formatters/phpunit.xml.dist | 29 + .../Exception/AbstractDataFormatException.php | 57 + .../Exception/IncompatibleDataException.php | 19 + .../src/Exception/InvalidFormatException.php | 15 + .../src/Exception/UnknownFieldException.php | 14 + .../src/Exception/UnknownFormatException.php | 14 + .../src/FormatterManager.php | 395 ++ .../src/Formatters/CsvFormatter.php | 107 + .../src/Formatters/FormatterInterface.php | 18 + .../src/Formatters/JsonFormatter.php | 21 + .../src/Formatters/ListFormatter.php | 59 + .../src/Formatters/PrintRFormatter.php | 21 + .../src/Formatters/RenderDataInterface.php | 19 + .../src/Formatters/RenderTableDataTrait.php | 29 + .../src/Formatters/SectionsFormatter.php | 72 + .../src/Formatters/SerializeFormatter.php | 21 + .../src/Formatters/StringFormatter.php | 81 + .../src/Formatters/TableFormatter.php | 128 + .../src/Formatters/TsvFormatter.php | 40 + .../src/Formatters/VarExportFormatter.php | 21 + .../src/Formatters/XmlFormatter.php | 76 + .../src/Formatters/YamlFormatter.php | 27 + .../src/Options/FormatterOptions.php | 372 ++ .../src/Options/OverrideOptionsInterface.php | 17 + .../StructuredData/AbstractStructuredList.php | 90 + .../src/StructuredData/AssociativeList.php | 12 + .../src/StructuredData/CallableRenderer.php | 23 + .../src/StructuredData/ListDataInterface.php | 16 + .../StructuredData/OriginalDataInterface.php | 11 + .../src/StructuredData/PropertyList.php | 58 + .../RenderCellCollectionInterface.php | 16 + .../RenderCellCollectionTrait.php | 59 + .../StructuredData/RenderCellInterface.php | 22 + .../StructuredData/RestructureInterface.php | 15 + .../src/StructuredData/RowsOfFields.php | 39 + .../src/StructuredData/TableDataInterface.php | 22 + .../StructuredData/Xml/DomDataInterface.php | 12 + .../src/StructuredData/Xml/XmlSchema.php | 96 + .../StructuredData/Xml/XmlSchemaInterface.php | 73 + .../Transformations/DomToArraySimplifier.php | 212 + .../OverrideRestructureInterface.php | 17 + .../PropertyListTableTransformation.php | 11 + .../src/Transformations/PropertyParser.php | 36 + .../src/Transformations/ReorderFields.php | 123 + .../SimplifyToArrayInterface.php | 26 + .../Transformations/TableTransformation.php | 123 + .../src/Transformations/WordWrapper.php | 227 + .../src/Validate/ValidDataTypesInterface.php | 28 + .../src/Validate/ValidDataTypesTrait.php | 34 + .../src/Validate/ValidationInterface.php | 28 + .../tests/src/PropertyListWithCsvCells.php | 17 + .../src/RowsOfFieldsWithAlternatives.php | 17 + .../output-formatters/tests/testAPIDocs.php | 32 + .../tests/testFormatterOptions.php | 112 + .../tests/testFormatters.php | 1332 ++++++ .../tests/testIncompatibleData.php | 64 + .../tests/testValidFormats.php | 88 + .../vendor/consolidation/robo/.editorconfig | 15 + .../robo/.github/issue_template.md | 11 + .../robo/.github/pull_request_template.md | 13 + .../vendor/consolidation/robo/.gitignore | 9 + .../consolidation/robo/.scrutinizer.yml | 3 + .../vendor/consolidation/robo/.travis.yml | 47 + .../vendor/consolidation/robo/CHANGELOG.md | 240 + .../vendor/consolidation/robo/CONTRIBUTING.md | 15 + .../vendor/consolidation/robo/LICENSE | 20 + .../vendor/consolidation/robo/README.md | 174 + .../vendor/consolidation/robo/RoboFile.php | 377 ++ .../vendor/consolidation/robo/codeception.yml | 21 + .../vendor/consolidation/robo/composer.json | 70 + .../vendor/consolidation/robo/composer.lock | 3518 ++++++++++++++ .../Task/Development/GeneratedWrapper.tmpl | 39 + .../consolidation/robo/docs/collections.md | 250 + .../consolidation/robo/docs/extending.md | 191 + .../consolidation/robo/docs/framework.md | 89 + .../robo/docs/getting-started.md | 418 ++ .../vendor/consolidation/robo/docs/index.md | 24 + .../consolidation/robo/docs/tasks/ApiGen.md | 56 + .../consolidation/robo/docs/tasks/Archive.md | 52 + .../consolidation/robo/docs/tasks/Assets.md | 163 + .../consolidation/robo/docs/tasks/Base.md | 126 + .../consolidation/robo/docs/tasks/Bower.md | 60 + .../consolidation/robo/docs/tasks/Composer.md | 179 + .../robo/docs/tasks/Development.md | 282 ++ .../consolidation/robo/docs/tasks/Docker.md | 249 + .../consolidation/robo/docs/tasks/File.md | 129 + .../robo/docs/tasks/Filesystem.md | 217 + .../consolidation/robo/docs/tasks/Gulp.md | 31 + .../consolidation/robo/docs/tasks/Npm.md | 54 + .../consolidation/robo/docs/tasks/Remote.md | 143 + .../consolidation/robo/docs/tasks/Testing.md | 171 + .../consolidation/robo/docs/tasks/Vcs.md | 108 + .../consolidation/robo/examples/RoboFile.php | 425 ++ .../consolidation/robo/examples/robo.script | 44 + src/composer/vendor/consolidation/robo/robo | 21 + .../robo/scripts/composer/ScriptHandler.php | 58 + .../consolidation/robo/src/Application.php | 56 + .../robo/src/Collection/CallableTask.php | 53 + .../robo/src/Collection/Collection.php | 683 +++ .../robo/src/Collection/CollectionBuilder.php | 475 ++ .../src/Collection/CollectionInterface.php | 150 + .../src/Collection/CollectionProcessHook.php | 35 + .../robo/src/Collection/CompletionWrapper.php | 106 + .../robo/src/Collection/Element.php | 116 + .../Collection/NestedCollectionInterface.php | 15 + .../robo/src/Collection/TaskForEach.php | 198 + .../robo/src/Collection/Temporary.php | 59 + .../robo/src/Collection/loadTasks.php | 17 + .../robo/src/Common/BuilderAwareTrait.php | 46 + .../robo/src/Common/CommandArguments.php | 111 + .../robo/src/Common/CommandReceiver.php | 30 + .../robo/src/Common/ConfigAwareTrait.php | 77 + .../robo/src/Common/DynamicParams.php | 45 + .../robo/src/Common/ExecCommand.php | 197 + .../robo/src/Common/ExecOneCommand.php | 12 + .../consolidation/robo/src/Common/IO.php | 176 + .../robo/src/Common/InflectionTrait.php | 21 + .../robo/src/Common/InputAwareTrait.php | 51 + .../robo/src/Common/OutputAwareTrait.php | 51 + .../robo/src/Common/ProgressIndicator.php | 201 + .../Common/ProgressIndicatorAwareTrait.php | 124 + .../src/Common/ResourceExistenceChecker.php | 116 + .../consolidation/robo/src/Common/TaskIO.php | 235 + .../robo/src/Common/TimeKeeper.php | 69 + .../consolidation/robo/src/Common/Timer.php | 37 + .../vendor/consolidation/robo/src/Config.php | 122 + .../src/Contract/BuilderAwareInterface.php | 22 + .../robo/src/Contract/CommandInterface.php | 20 + .../robo/src/Contract/CompletionInterface.php | 18 + .../src/Contract/ConfigAwareInterface.php | 24 + .../robo/src/Contract/IOAwareInterface.php | 13 + .../robo/src/Contract/InflectionInterface.php | 52 + .../src/Contract/OutputAwareInterface.php | 19 + .../robo/src/Contract/PrintedInterface.php | 16 + .../ProgressIndicatorAwareInterface.php | 24 + .../robo/src/Contract/ProgressInterface.php | 19 + .../robo/src/Contract/RollbackInterface.php | 18 + .../robo/src/Contract/SimulatedInterface.php | 18 + .../robo/src/Contract/TaskInterface.php | 17 + .../src/Contract/WrappedTaskInterface.php | 10 + .../robo/src/Exception/TaskException.php | 13 + .../robo/src/Exception/TaskExitException.php | 13 + .../robo/src/GlobalOptionsEventListener.php | 45 + .../consolidation/robo/src/LoadAllTasks.php | 39 + .../robo/src/Log/ResultPrinter.php | 109 + .../robo/src/Log/RoboLogLevel.php | 11 + .../robo/src/Log/RoboLogStyle.php | 76 + .../consolidation/robo/src/Log/RoboLogger.php | 36 + .../vendor/consolidation/robo/src/Result.php | 234 + .../consolidation/robo/src/ResultData.php | 152 + .../vendor/consolidation/robo/src/Robo.php | 337 ++ .../vendor/consolidation/robo/src/Runner.php | 419 ++ .../robo/src/Task/ApiGen/ApiGen.php | 482 ++ .../robo/src/Task/ApiGen/loadTasks.php | 15 + .../robo/src/Task/Archive/Extract.php | 281 ++ .../robo/src/Task/Archive/Pack.php | 257 + .../robo/src/Task/Archive/loadTasks.php | 25 + .../robo/src/Task/Assets/CssPreprocessor.php | 214 + .../robo/src/Task/Assets/ImageMinify.php | 716 +++ .../robo/src/Task/Assets/Less.php | 108 + .../robo/src/Task/Assets/Minify.php | 297 ++ .../robo/src/Task/Assets/Scss.php | 93 + .../robo/src/Task/Assets/loadTasks.php | 45 + .../consolidation/robo/src/Task/Base/Exec.php | 224 + .../robo/src/Task/Base/ExecStack.php | 26 + .../robo/src/Task/Base/ParallelExec.php | 177 + .../robo/src/Task/Base/SymfonyCommand.php | 76 + .../robo/src/Task/Base/Watch.php | 89 + .../robo/src/Task/Base/loadShortcuts.php | 17 + .../robo/src/Task/Base/loadTasks.php | 45 + .../consolidation/robo/src/Task/BaseTask.php | 35 + .../robo/src/Task/Bower/Base.php | 88 + .../robo/src/Task/Bower/Install.php | 37 + .../robo/src/Task/Bower/Update.php | 36 + .../robo/src/Task/Bower/loadTasks.php | 25 + .../robo/src/Task/CommandStack.php | 123 + .../robo/src/Task/Composer/Base.php | 145 + .../robo/src/Task/Composer/DumpAutoload.php | 69 + .../robo/src/Task/Composer/Install.php | 40 + .../robo/src/Task/Composer/Remove.php | 75 + .../robo/src/Task/Composer/Update.php | 40 + .../robo/src/Task/Composer/Validate.php | 114 + .../robo/src/Task/Composer/loadTasks.php | 55 + .../robo/src/Task/Development/Changelog.php | 191 + .../Task/Development/GenerateMarkdownDoc.php | 769 +++ .../src/Task/Development/GenerateTask.php | 108 + .../robo/src/Task/Development/GitHub.php | 141 + .../src/Task/Development/GitHubRelease.php | 208 + .../robo/src/Task/Development/OpenBrowser.php | 80 + .../robo/src/Task/Development/PackPhar.php | 253 + .../robo/src/Task/Development/PhpServer.php | 86 + .../robo/src/Task/Development/SemVer.php | 233 + .../robo/src/Task/Development/loadTasks.php | 86 + .../robo/src/Task/Docker/Base.php | 28 + .../robo/src/Task/Docker/Build.php | 55 + .../robo/src/Task/Docker/Commit.php | 66 + .../robo/src/Task/Docker/Exec.php | 93 + .../robo/src/Task/Docker/Pull.php | 33 + .../robo/src/Task/Docker/Remove.php | 32 + .../robo/src/Task/Docker/Result.php | 35 + .../robo/src/Task/Docker/Run.php | 283 ++ .../robo/src/Task/Docker/Start.php | 41 + .../robo/src/Task/Docker/Stop.php | 41 + .../robo/src/Task/Docker/loadTasks.php | 85 + .../robo/src/Task/File/Concat.php | 101 + .../robo/src/Task/File/Replace.php | 139 + .../robo/src/Task/File/TmpFile.php | 73 + .../robo/src/Task/File/Write.php | 337 ++ .../robo/src/Task/File/loadTasks.php | 50 + .../robo/src/Task/Filesystem/BaseDir.php | 30 + .../robo/src/Task/Filesystem/CleanDir.php | 63 + .../robo/src/Task/Filesystem/CopyDir.php | 113 + .../robo/src/Task/Filesystem/DeleteDir.php | 36 + .../src/Task/Filesystem/FilesystemStack.php | 156 + .../robo/src/Task/Filesystem/FlattenDir.php | 294 ++ .../robo/src/Task/Filesystem/MirrorDir.php | 40 + .../robo/src/Task/Filesystem/TmpDir.php | 174 + .../robo/src/Task/Filesystem/WorkDir.php | 128 + .../src/Task/Filesystem/loadShortcuts.php | 160 + .../robo/src/Task/Filesystem/loadTasks.php | 87 + .../consolidation/robo/src/Task/Gulp/Base.php | 97 + .../consolidation/robo/src/Task/Gulp/Run.php | 36 + .../robo/src/Task/Gulp/loadTasks.php | 16 + .../consolidation/robo/src/Task/Npm/Base.php | 60 + .../robo/src/Task/Npm/Install.php | 36 + .../robo/src/Task/Npm/Update.php | 34 + .../robo/src/Task/Npm/loadTasks.php | 25 + .../robo/src/Task/Remote/Rsync.php | 491 ++ .../robo/src/Task/Remote/Ssh.php | 274 ++ .../robo/src/Task/Remote/loadTasks.php | 24 + .../consolidation/robo/src/Task/Simulator.php | 169 + .../robo/src/Task/StackBasedTask.php | 238 + .../robo/src/Task/Testing/Atoum.php | 184 + .../robo/src/Task/Testing/Behat.php | 164 + .../robo/src/Task/Testing/Codecept.php | 263 ++ .../robo/src/Task/Testing/PHPUnit.php | 199 + .../robo/src/Task/Testing/Phpspec.php | 116 + .../robo/src/Task/Testing/loadTasks.php | 55 + .../robo/src/Task/Vcs/GitStack.php | 153 + .../robo/src/Task/Vcs/HgStack.php | 153 + .../robo/src/Task/Vcs/SvnStack.php | 106 + .../robo/src/Task/Vcs/loadShortcuts.php | 35 + .../robo/src/Task/Vcs/loadTasks.php | 37 + .../consolidation/robo/src/TaskAccessor.php | 47 + .../consolidation/robo/src/TaskInfo.php | 35 + .../vendor/consolidation/robo/src/Tasks.php | 23 + .../consolidation/robo/tests/_bootstrap.php | 12 + .../robo/tests/_data/TestedRoboFile.php | 38 + .../robo/tests/_data/TestedRoboTask.php | 61 + .../robo/tests/_data/claypit/a.txt | 1 + .../robo/tests/_data/claypit/b.txt | 1 + .../robo/tests/_data/claypit/box/robo.txt | 1 + .../_data/claypit/some/deeply/existing_file | 1 + .../claypit/some/deeply/nested/structu.re | 1 + .../some_destination/deeply/existing_file | 1 + .../consolidation/robo/tests/_data/dump.sql | 1 + .../robo/tests/_data/parascript.php | 8 + .../consolidation/robo/tests/_data/sample.css | 35 + .../robo/tests/_helpers/CliGuy.php | 30 + .../robo/tests/_helpers/CliHelper.php | 66 + .../robo/tests/_helpers/CodeGuy.php | 26 + .../robo/tests/_helpers/CodeHelper.php | 37 + .../robo/tests/_helpers/SeeInOutputTrait.php | 62 + .../robo/tests/_helpers/TestHelper.php | 10 + .../robo/tests/_helpers/WebHelper.php | 10 + .../consolidation/robo/tests/cli.suite.yml | 3 + .../robo/tests/cli/AssetsCept.php | 24 + .../robo/tests/cli/CleanDirCept.php | 13 + .../robo/tests/cli/CollectionCest.php | 409 ++ .../robo/tests/cli/ConcatCept.php | 11 + .../robo/tests/cli/CopyDirCept.php | 10 + .../tests/cli/CopyDirOverwritesFilesCept.php | 12 + .../robo/tests/cli/CopyDirRecursiveCept.php | 11 + .../robo/tests/cli/DeleteDirCept.php | 11 + .../consolidation/robo/tests/cli/ExecCest.php | 13 + .../robo/tests/cli/FilesystemStackCest.php | 50 + .../robo/tests/cli/FlattenDirCept.php | 14 + .../robo/tests/cli/FlattenDirParentsCept.php | 12 + .../robo/tests/cli/GenTaskCest.php | 11 + .../tests/cli/GenerateMarkdownDocCest.php | 86 + .../robo/tests/cli/PackExtractCept.php | 57 + .../robo/tests/cli/ShortcutsCest.php | 25 + .../robo/tests/cli/SimulatedCest.php | 34 + .../robo/tests/cli/WriteFileCest.php | 111 + .../robo/tests/cli/_bootstrap.php | 9 + .../robo/tests/src/RoboFileFixture.php | 123 + .../Traits/Common/CommandArgumentsHost.php | 18 + .../consolidation/robo/tests/unit.suite.yml | 8 + .../robo/tests/unit/ApplicationTest.php | 140 + .../unit/Common/CommandArgumentsTest.php | 86 + .../unit/Common/ResourceExistenceChecker.php | 80 + .../robo/tests/unit/ConfigurationTest.php | 40 + .../robo/tests/unit/OutputTest.php | 81 + .../robo/tests/unit/ResultTest.php | 79 + .../robo/tests/unit/RunnerTest.php | 279 ++ .../robo/tests/unit/Task/ApiGenTest.php | 52 + .../robo/tests/unit/Task/AtoumTest.php | 38 + .../robo/tests/unit/Task/BehatTest.php | 43 + .../robo/tests/unit/Task/BowerTest.php | 59 + .../robo/tests/unit/Task/CodeceptionTest.php | 63 + .../robo/tests/unit/Task/CollectionTest.php | 183 + .../robo/tests/unit/Task/CommandStackTest.php | 26 + .../robo/tests/unit/Task/ComposerTest.php | 266 ++ .../robo/tests/unit/Task/DockerTest.php | 97 + .../robo/tests/unit/Task/ExecTaskTest.php | 73 + .../robo/tests/unit/Task/GitTest.php | 62 + .../robo/tests/unit/Task/GulpTest.php | 85 + .../robo/tests/unit/Task/HgTest.php | 86 + .../robo/tests/unit/Task/NpmTest.php | 52 + .../robo/tests/unit/Task/PHPServerTest.php | 59 + .../robo/tests/unit/Task/PHPUnitTest.php | 41 + .../robo/tests/unit/Task/ParallelExecTest.php | 43 + .../robo/tests/unit/Task/PhpspecTest.php | 42 + .../robo/tests/unit/Task/RsyncTest.php | 59 + .../robo/tests/unit/Task/SemVerTest.php | 72 + .../robo/tests/unit/Task/SshTest.php | 61 + .../robo/tests/unit/Task/SvnTest.php | 49 + .../robo/tests/unit/_bootstrap.php | 2 + .../container-interop/.gitignore | 3 + .../container-interop/LICENSE | 20 + .../container-interop/README.md | 85 + .../container-interop/composer.json | 11 + .../docs/ContainerInterface-meta.md | 114 + .../docs/ContainerInterface.md | 153 + .../docs/Delegate-lookup-meta.md | 259 + .../container-interop/docs/Delegate-lookup.md | 60 + .../docs/images/interoperating_containers.png | Bin 0 -> 35971 bytes .../docs/images/priority.png | Bin 0 -> 22949 bytes .../docs/images/side_by_side_containers.png | Bin 0 -> 22519 bytes .../Interop/Container/ContainerInterface.php | 37 + .../Exception/ContainerException.php | 13 + .../Container/Exception/NotFoundException.php | 13 + .../vendor/doctrine/instantiator/.gitignore | 5 + .../doctrine/instantiator/.scrutinizer.yml | 46 + .../doctrine/instantiator/.travis.install.sh | 14 + .../vendor/doctrine/instantiator/.travis.yml | 22 + .../doctrine/instantiator/CONTRIBUTING.md | 35 + .../vendor/doctrine/instantiator/LICENSE | 19 + .../vendor/doctrine/instantiator/README.md | 40 + .../doctrine/instantiator/composer.json | 45 + .../doctrine/instantiator/phpmd.xml.dist | 27 + .../doctrine/instantiator/phpunit.xml.dist | 22 + .../Exception/ExceptionInterface.php | 29 + .../Exception/InvalidArgumentException.php | 62 + .../Exception/UnexpectedValueException.php | 79 + .../Doctrine/Instantiator/Instantiator.php | 273 ++ .../Instantiator/InstantiatorInterface.php | 37 + .../InstantiatorPerformanceEvent.php | 96 + .../InvalidArgumentExceptionTest.php | 83 + .../UnexpectedValueExceptionTest.php | 69 + .../InstantiatorTest/InstantiatorTest.php | 219 + .../AbstractClassAsset.php | 29 + .../ArrayObjectAsset.php | 41 + .../InstantiatorTestAsset/ExceptionAsset.php | 41 + .../FinalExceptionAsset.php | 41 + .../InstantiatorTestAsset/PharAsset.php | 41 + .../PharExceptionAsset.php | 44 + .../SerializableArrayObjectAsset.php | 62 + .../SimpleSerializableAsset.php | 61 + .../SimpleTraitAsset.php | 29 + .../UnCloneableAsset.php | 50 + .../UnserializeExceptionArrayObjectAsset.php | 39 + .../WakeUpNoticesAsset.php | 38 + .../InstantiatorTestAsset/XMLReaderAsset.php | 41 + .../vendor/league/container/CHANGELOG.md | 108 + .../vendor/league/container/CONTRIBUTING.md | 29 + .../vendor/league/container/LICENSE.md | 21 + .../vendor/league/container/README.md | 67 + .../vendor/league/container/composer.json | 52 + .../Argument/ArgumentResolverInterface.php | 26 + .../src/Argument/ArgumentResolverTrait.php | 82 + .../container/src/Argument/RawArgument.php | 27 + .../src/Argument/RawArgumentInterface.php | 13 + .../vendor/league/container/src/Container.php | 296 ++ .../container/src/ContainerAwareInterface.php | 20 + .../container/src/ContainerAwareTrait.php | 34 + .../container/src/ContainerInterface.php | 59 + .../src/Definition/AbstractDefinition.php | 62 + .../src/Definition/CallableDefinition.php | 23 + .../src/Definition/ClassDefinition.php | 67 + .../Definition/ClassDefinitionInterface.php | 23 + .../src/Definition/DefinitionFactory.php | 28 + .../Definition/DefinitionFactoryInterface.php | 17 + .../src/Definition/DefinitionInterface.php | 30 + .../src/Exception/NotFoundException.php | 10 + .../src/ImmutableContainerAwareInterface.php | 22 + .../src/ImmutableContainerAwareTrait.php | 36 + .../src/ImmutableContainerInterface.php | 10 + .../container/src/Inflector/Inflector.php | 103 + .../src/Inflector/InflectorAggregate.php | 53 + .../Inflector/InflectorAggregateInterface.php | 25 + .../container/src/ReflectionContainer.php | 78 + .../AbstractServiceProvider.php | 27 + .../AbstractSignatureServiceProvider.php | 31 + .../BootableServiceProviderInterface.php | 14 + .../ServiceProviderAggregate.php | 88 + .../ServiceProviderAggregateInterface.php | 32 + .../ServiceProviderInterface.php | 26 + .../SignatureServiceProviderInterface.php | 24 + .../vendor/myclabs/deep-copy/.gitattributes | 7 + .../vendor/myclabs/deep-copy/.gitignore | 6 + .../vendor/myclabs/deep-copy/.travis.yml | 37 + src/composer/vendor/myclabs/deep-copy/LICENSE | 20 + .../vendor/myclabs/deep-copy/README.md | 271 ++ .../vendor/myclabs/deep-copy/composer.json | 21 + .../vendor/myclabs/deep-copy/doc/clone.png | Bin 0 -> 12380 bytes .../myclabs/deep-copy/doc/deep-clone.png | Bin 0 -> 14009 bytes .../myclabs/deep-copy/doc/deep-copy.png | Bin 0 -> 10895 bytes .../vendor/myclabs/deep-copy/doc/graph.png | Bin 0 -> 6436 bytes .../deep-copy/src/DeepCopy/DeepCopy.php | 246 + .../src/DeepCopy/Exception/CloneException.php | 6 + .../Doctrine/DoctrineCollectionFilter.php | 31 + .../DoctrineEmptyCollectionFilter.php | 24 + .../deep-copy/src/DeepCopy/Filter/Filter.php | 17 + .../src/DeepCopy/Filter/KeepFilter.php | 17 + .../src/DeepCopy/Filter/ReplaceFilter.php | 35 + .../src/DeepCopy/Filter/SetNullFilter.php | 22 + .../src/DeepCopy/Matcher/Matcher.php | 16 + .../src/DeepCopy/Matcher/PropertyMatcher.php | 37 + .../DeepCopy/Matcher/PropertyNameMatcher.php | 30 + .../DeepCopy/Matcher/PropertyTypeMatcher.php | 38 + .../DeepCopy/Reflection/ReflectionHelper.php | 39 + .../src/DeepCopy/TypeFilter/ReplaceFilter.php | 27 + .../DeepCopy/TypeFilter/ShallowCopyFilter.php | 14 + .../TypeFilter/Spl/SplDoublyLinkedList.php | 37 + .../src/DeepCopy/TypeFilter/TypeFilter.php | 12 + .../src/DeepCopy/TypeMatcher/TypeMatcher.php | 31 + .../reflection-common/.gitignore | 4 + .../phpdocumentor/reflection-common/LICENSE | 22 + .../phpdocumentor/reflection-common/README.md | 1 + .../reflection-common/composer.json | 29 + .../reflection-common/composer.lock | 974 ++++ .../reflection-common/phpunit.xml.dist | 26 + .../reflection-common/src/Element.php | 32 + .../reflection-common/src/File.php | 40 + .../reflection-common/src/Fqsen.php | 78 + .../reflection-common/src/Location.php | 57 + .../reflection-common/src/Project.php | 25 + .../reflection-common/src/ProjectFactory.php | 27 + .../tests/common/bootstrap.php | 10 + .../tests/unit/FqsenTest.php | 88 + .../reflection-docblock/.gitignore | 2 + .../reflection-docblock/.scrutinizer.yml | 32 + .../reflection-docblock/.travis.yml | 36 + .../phpdocumentor/reflection-docblock/LICENSE | 21 + .../reflection-docblock/README.md | 69 + .../reflection-docblock/composer.json | 28 + .../reflection-docblock/composer.lock | 1120 +++++ .../01-interpreting-a-simple-docblock.php | 27 + .../examples/02-interpreting-tags.php | 24 + .../examples/03-reconstituting-a-docblock.php | 27 + .../examples/04-adding-your-own-tag.php | 135 + .../playing-with-descriptions/02-escaping.php | 47 + .../reflection-docblock/phpmd.xml.dist | 23 + .../reflection-docblock/phpunit.xml.dist | 33 + .../reflection-docblock/src/DocBlock.php | 220 + .../src/DocBlock/Description.php | 103 + .../src/DocBlock/DescriptionFactory.php | 192 + .../src/DocBlock/ExampleFinder.php | 170 + .../src/DocBlock/Serializer.php | 143 + .../src/DocBlock/StandardTagFactory.php | 314 ++ .../reflection-docblock/src/DocBlock/Tag.php | 26 + .../src/DocBlock/TagFactory.php | 93 + .../src/DocBlock/Tags/Author.php | 100 + .../src/DocBlock/Tags/BaseTag.php | 52 + .../src/DocBlock/Tags/Covers.php | 84 + .../src/DocBlock/Tags/Deprecated.php | 97 + .../src/DocBlock/Tags/Example.php | 158 + .../DocBlock/Tags/Factory/StaticMethod.php | 18 + .../src/DocBlock/Tags/Factory/Strategy.php | 18 + .../src/DocBlock/Tags/Formatter.php | 27 + .../Tags/Formatter/PassthroughFormatter.php | 31 + .../src/DocBlock/Tags/Generic.php | 91 + .../src/DocBlock/Tags/Link.php | 77 + .../src/DocBlock/Tags/Method.php | 230 + .../src/DocBlock/Tags/Param.php | 141 + .../src/DocBlock/Tags/Property.php | 118 + .../src/DocBlock/Tags/PropertyRead.php | 118 + .../src/DocBlock/Tags/PropertyWrite.php | 118 + .../src/DocBlock/Tags/Return_.php | 73 + .../src/DocBlock/Tags/See.php | 81 + .../src/DocBlock/Tags/Since.php | 94 + .../src/DocBlock/Tags/Source.php | 96 + .../src/DocBlock/Tags/Throws.php | 72 + .../src/DocBlock/Tags/Uses.php | 83 + .../src/DocBlock/Tags/Var_.php | 118 + .../src/DocBlock/Tags/Version.php | 94 + .../src/DocBlockFactory.php | 277 ++ .../src/DocBlockFactoryInterface.php | 23 + .../integration/InterpretingDocBlocksTest.php | 97 + .../ReconstitutingADocBlockTest.php | 35 + .../tests/integration/UsingTagsTest.php | 39 + .../unit/DocBlock/DescriptionFactoryTest.php | 174 + .../tests/unit/DocBlock/DescriptionTest.php | 75 + .../tests/unit/DocBlock/SerializerTest.php | 201 + .../unit/DocBlock/StandardTagFactoryTest.php | 361 ++ .../tests/unit/DocBlock/Tags/AuthorTest.php | 148 + .../tests/unit/DocBlock/Tags/CoversTest.php | 155 + .../unit/DocBlock/Tags/DeprecatedTest.php | 166 + .../Formatter/PassthroughFormatterTest.php | 41 + .../tests/unit/DocBlock/Tags/GenericTest.php | 146 + .../tests/unit/DocBlock/Tags/LinkTest.php | 158 + .../tests/unit/DocBlock/Tags/MethodTest.php | 437 ++ .../tests/unit/DocBlock/Tags/ParamTest.php | 228 + .../unit/DocBlock/Tags/PropertyReadTest.php | 201 + .../tests/unit/DocBlock/Tags/PropertyTest.php | 200 + .../unit/DocBlock/Tags/PropertyWriteTest.php | 201 + .../tests/unit/DocBlock/Tags/ReturnTest.php | 170 + .../tests/unit/DocBlock/Tags/SeeTest.php | 173 + .../tests/unit/DocBlock/Tags/SinceTest.php | 166 + .../tests/unit/DocBlock/Tags/SourceTest.php | 199 + .../tests/unit/DocBlock/Tags/ThrowsTest.php | 170 + .../tests/unit/DocBlock/Tags/UsesTest.php | 174 + .../tests/unit/DocBlock/Tags/VarTest.php | 200 + .../tests/unit/DocBlock/Tags/VersionTest.php | 166 + .../tests/unit/DocBlockFactoryTest.php | 290 ++ .../tests/unit/DocBlockTest.php | 252 + .../phpdocumentor/type-resolver/.gitignore | 3 + .../type-resolver/.scrutinizer.yml | 31 + .../phpdocumentor/type-resolver/.travis.yml | 34 + .../phpdocumentor/type-resolver/LICENSE | 21 + .../phpdocumentor/type-resolver/README.md | 169 + .../phpdocumentor/type-resolver/composer.json | 27 + .../examples/01-resolving-simple-types.php | 13 + .../examples/02-resolving-classes.php | 12 + .../examples/03-resolving-all-elements.php | 17 + ...ing-the-context-using-class-reflection.php | 30 + ...ng-the-context-using-method-reflection.php | 30 + ...vering-the-context-using-file-contents.php | 22 + .../type-resolver/examples/Classy.php | 16 + .../type-resolver/phpmd.xml.dist | 23 + .../type-resolver/phpunit.xml.dist | 31 + .../type-resolver/src/FqsenResolver.php | 76 + .../phpdocumentor/type-resolver/src/Type.php | 18 + .../type-resolver/src/TypeResolver.php | 266 ++ .../type-resolver/src/Types/Array_.php | 87 + .../type-resolver/src/Types/Boolean.php | 31 + .../type-resolver/src/Types/Callable_.php | 31 + .../type-resolver/src/Types/Compound.php | 82 + .../type-resolver/src/Types/Context.php | 84 + .../src/Types/ContextFactory.php | 210 + .../type-resolver/src/Types/Float_.php | 31 + .../type-resolver/src/Types/Integer.php | 28 + .../type-resolver/src/Types/Mixed.php | 31 + .../type-resolver/src/Types/Null_.php | 31 + .../type-resolver/src/Types/Object_.php | 70 + .../type-resolver/src/Types/Resource.php | 31 + .../type-resolver/src/Types/Scalar.php | 31 + .../type-resolver/src/Types/Self_.php | 33 + .../type-resolver/src/Types/Static_.php | 38 + .../type-resolver/src/Types/String_.php | 31 + .../type-resolver/src/Types/This.php | 34 + .../type-resolver/src/Types/Void_.php | 34 + .../tests/unit/TypeResolverTest.php | 395 ++ .../tests/unit/Types/ContextFactoryTest.php | 188 + .../tests/unit/Types/ContextTest.php | 61 + .../vendor/phpspec/prophecy/.gitignore | 4 + .../vendor/phpspec/prophecy/.travis.yml | 29 + .../vendor/phpspec/prophecy/CHANGES.md | 147 + .../vendor/phpspec/prophecy/CONTRIBUTING.md | 21 + src/composer/vendor/phpspec/prophecy/LICENSE | 23 + .../vendor/phpspec/prophecy/README.md | 391 ++ .../vendor/phpspec/prophecy/composer.json | 43 + .../Argument/ArgumentsWildcardSpec.php | 146 + .../Argument/Token/AnyValueTokenSpec.php | 28 + .../Argument/Token/AnyValuesTokenSpec.php | 28 + .../Token/ApproximateValueTokenSpec.php | 55 + .../Argument/Token/ArrayCountTokenSpec.php | 64 + .../Argument/Token/ArrayEntryTokenSpec.php | 229 + .../Token/ArrayEveryEntryTokenSpec.php | 109 + .../Argument/Token/CallbackTokenSpec.php | 42 + .../Argument/Token/ExactValueTokenSpec.php | 155 + .../Token/IdenticalValueTokenSpec.php | 152 + .../Argument/Token/LogicalAndTokenSpec.php | 78 + .../Argument/Token/LogicalNotTokenSpec.php | 65 + .../Argument/Token/ObjectStateTokenSpec.php | 101 + .../Token/StringContainsTokenSpec.php | 49 + .../Prophecy/Argument/Token/TypeTokenSpec.php | 62 + .../prophecy/spec/Prophecy/ArgumentSpec.php | 107 + .../spec/Prophecy/Call/CallCenterSpec.php | 195 + .../prophecy/spec/Prophecy/Call/CallSpec.php | 54 + .../Comparator/ClosureComparatorSpec.php | 39 + .../spec/Prophecy/Comparator/FactorySpec.php | 20 + .../Comparator/ProphecyComparatorSpec.php | 39 + .../DisableConstructorPatchSpec.php | 59 + .../ClassPatch/HhvmExceptionPatchSpec.php | 37 + .../Doubler/ClassPatch/KeywordPatchSpec.php | 44 + .../Doubler/ClassPatch/MagicCallPatchSpec.php | 125 + .../ClassPatch/ProphecySubjectPatchSpec.php | 83 + .../ReflectionClassNewInstancePatchSpec.php | 47 + .../ClassPatch/SplFileInfoPatchSpec.php | 107 + .../ClassPatch/TraversablePatchSpec.php | 61 + .../spec/Prophecy/Doubler/DoublerSpec.php | 122 + .../Generator/ClassCodeGeneratorSpec.php | 323 ++ .../Doubler/Generator/ClassCreatorSpec.php | 44 + .../Doubler/Generator/ClassMirrorSpec.php | 784 ++++ .../Generator/Node/ArgumentNodeSpec.php | 92 + .../Doubler/Generator/Node/ClassNodeSpec.php | 200 + .../Doubler/Generator/Node/MethodNodeSpec.php | 141 + .../spec/Prophecy/Doubler/LazyDoubleSpec.php | 96 + .../Prophecy/Doubler/NameGeneratorSpec.php | 72 + .../Call/UnexpectedCallExceptionSpec.php | 32 + .../Doubler/ClassCreatorExceptionSpec.php | 28 + .../Doubler/ClassMirrorExceptionSpec.php | 27 + .../Doubler/ClassNotFoundExceptionSpec.php | 25 + .../Exception/Doubler/DoubleExceptionSpec.php | 14 + .../InterfaceNotFoundExceptionSpec.php | 24 + .../MethodNotExtendableExceptionSpec.php | 29 + .../Doubler/MethodNotFoundExceptionSpec.php | 40 + .../Prediction/AggregateExceptionSpec.php | 57 + .../Prediction/NoCallsExceptionSpec.php | 29 + .../UnexpectedCallsCountExceptionSpec.php | 31 + .../UnexpectedCallsExceptionSpec.php | 36 + .../Prophecy/MethodProphecyExceptionSpec.php | 30 + .../Prophecy/ObjectProphecyExceptionSpec.php | 27 + .../Prediction/CallPredictionSpec.php | 42 + .../Prediction/CallTimesPredictionSpec.php | 54 + .../Prediction/CallbackPredictionSpec.php | 36 + .../Prediction/NoCallsPredictionSpec.php | 43 + .../Prophecy/Promise/CallbackPromiseSpec.php | 110 + .../Promise/ReturnArgumentPromiseSpec.php | 41 + .../Prophecy/Promise/ReturnPromiseSpec.php | 61 + .../Prophecy/Promise/ThrowPromiseSpec.php | 58 + .../Prophecy/Prophecy/MethodProphecySpec.php | 384 ++ .../Prophecy/Prophecy/ObjectProphecySpec.php | 319 ++ .../spec/Prophecy/Prophecy/RevealerSpec.php | 51 + .../prophecy/spec/Prophecy/ProphetSpec.php | 91 + .../spec/Prophecy/Util/StringUtilSpec.php | 97 + .../prophecy/src/Prophecy/Argument.php | 212 + .../Prophecy/Argument/ArgumentsWildcard.php | 101 + .../Prophecy/Argument/Token/AnyValueToken.php | 52 + .../Argument/Token/AnyValuesToken.php | 52 + .../Argument/Token/ApproximateValueToken.php | 55 + .../Argument/Token/ArrayCountToken.php | 86 + .../Argument/Token/ArrayEntryToken.php | 143 + .../Argument/Token/ArrayEveryEntryToken.php | 82 + .../Prophecy/Argument/Token/CallbackToken.php | 75 + .../Argument/Token/ExactValueToken.php | 116 + .../Argument/Token/IdenticalValueToken.php | 74 + .../Argument/Token/LogicalAndToken.php | 80 + .../Argument/Token/LogicalNotToken.php | 73 + .../Argument/Token/ObjectStateToken.php | 104 + .../Argument/Token/StringContainsToken.php | 67 + .../Argument/Token/TokenInterface.php | 43 + .../src/Prophecy/Argument/Token/TypeToken.php | 76 + .../prophecy/src/Prophecy/Call/Call.php | 127 + .../prophecy/src/Prophecy/Call/CallCenter.php | 162 + .../Prophecy/Comparator/ClosureComparator.php | 42 + .../src/Prophecy/Comparator/Factory.php | 47 + .../Comparator/ProphecyComparator.php | 28 + .../src/Prophecy/Doubler/CachedDoubler.php | 68 + .../ClassPatch/ClassPatchInterface.php | 48 + .../ClassPatch/DisableConstructorPatch.php | 72 + .../Doubler/ClassPatch/HhvmExceptionPatch.php | 63 + .../Doubler/ClassPatch/KeywordPatch.php | 135 + .../Doubler/ClassPatch/MagicCallPatch.php | 85 + .../ClassPatch/ProphecySubjectPatch.php | 98 + .../ReflectionClassNewInstancePatch.php | 57 + .../Doubler/ClassPatch/SplFileInfoPatch.php | 105 + .../Doubler/ClassPatch/TraversablePatch.php | 83 + .../src/Prophecy/Doubler/DoubleInterface.php | 22 + .../prophecy/src/Prophecy/Doubler/Doubler.php | 146 + .../Doubler/Generator/ClassCodeGenerator.php | 112 + .../Doubler/Generator/ClassCreator.php | 67 + .../Doubler/Generator/ClassMirror.php | 254 + .../Doubler/Generator/Node/ArgumentNode.php | 91 + .../Doubler/Generator/Node/ClassNode.php | 166 + .../Doubler/Generator/Node/MethodNode.php | 188 + .../Doubler/Generator/ReflectionInterface.php | 22 + .../src/Prophecy/Doubler/LazyDouble.php | 127 + .../src/Prophecy/Doubler/NameGenerator.php | 52 + .../Call/UnexpectedCallException.php | 40 + .../Doubler/ClassCreatorException.php | 31 + .../Doubler/ClassMirrorException.php | 31 + .../Doubler/ClassNotFoundException.php | 33 + .../Exception/Doubler/DoubleException.php | 18 + .../Exception/Doubler/DoublerException.php | 18 + .../Doubler/InterfaceNotFoundException.php | 20 + .../Doubler/MethodNotExtendableException.php | 41 + .../Doubler/MethodNotFoundException.php | 60 + .../Doubler/ReturnByReferenceException.php | 41 + .../src/Prophecy/Exception/Exception.php | 26 + .../Exception/InvalidArgumentException.php | 16 + .../Prediction/AggregateException.php | 50 + .../Prediction/FailedPredictionException.php | 24 + .../Exception/Prediction/NoCallsException.php | 18 + .../Prediction/PredictionException.php | 18 + .../UnexpectedCallsCountException.php | 31 + .../Prediction/UnexpectedCallsException.php | 32 + .../Prophecy/MethodProphecyException.php | 34 + .../Prophecy/ObjectProphecyException.php | 34 + .../Exception/Prophecy/ProphecyException.php | 18 + .../ClassAndInterfaceTagRetriever.php | 69 + .../PhpDocumentor/ClassTagRetriever.php | 52 + .../PhpDocumentor/LegacyClassTagRetriever.php | 35 + .../MethodTagRetrieverInterface.php | 30 + .../Prophecy/Prediction/CallPrediction.php | 86 + .../Prediction/CallTimesPrediction.php | 107 + .../Prediction/CallbackPrediction.php | 65 + .../Prophecy/Prediction/NoCallsPrediction.php | 68 + .../Prediction/PredictionInterface.php | 37 + .../src/Prophecy/Promise/CallbackPromise.php | 66 + .../src/Prophecy/Promise/PromiseInterface.php | 35 + .../Promise/ReturnArgumentPromise.php | 61 + .../src/Prophecy/Promise/ReturnPromise.php | 55 + .../src/Prophecy/Promise/ThrowPromise.php | 91 + .../src/Prophecy/Prophecy/MethodProphecy.php | 438 ++ .../src/Prophecy/Prophecy/ObjectProphecy.php | 281 ++ .../Prophecy/Prophecy/ProphecyInterface.php | 27 + .../Prophecy/ProphecySubjectInterface.php | 34 + .../src/Prophecy/Prophecy/Revealer.php | 44 + .../Prophecy/Prophecy/RevealerInterface.php | 29 + .../phpspec/prophecy/src/Prophecy/Prophet.php | 134 + .../prophecy/src/Prophecy/Util/ExportUtil.php | 211 + .../prophecy/src/Prophecy/Util/StringUtil.php | 89 + .../phpunit/php-code-coverage/.gitattributes | 1 + .../phpunit/php-code-coverage/.gitignore | 12 + .../vendor/phpunit/php-code-coverage/.php_cs | 69 + .../phpunit/php-code-coverage/.travis.yml | 22 + .../phpunit/php-code-coverage/CONTRIBUTING.md | 1 + .../php-code-coverage/ChangeLog-2.2.md | 56 + .../php-code-coverage/ChangeLog-3.0.md | 31 + .../php-code-coverage/ChangeLog-3.1.md | 30 + .../php-code-coverage/ChangeLog-3.2.md | 23 + .../php-code-coverage/ChangeLog-3.3.md | 33 + .../php-code-coverage/ChangeLog-4.0.md | 26 + .../vendor/phpunit/php-code-coverage/LICENSE | 33 + .../phpunit/php-code-coverage/README.md | 51 + .../phpunit/php-code-coverage/build.xml | 41 + .../php-code-coverage/build/phpunit.xml | 16 + .../phpunit/php-code-coverage/composer.json | 51 + .../php-code-coverage/src/CodeCoverage.php | 1105 +++++ .../php-code-coverage/src/Driver/Driver.php | 52 + .../php-code-coverage/src/Driver/HHVM.php | 29 + .../php-code-coverage/src/Driver/PHPDBG.php | 111 + .../php-code-coverage/src/Driver/Xdebug.php | 117 + .../CoveredCodeNotExecutedException.php | 18 + .../src/Exception/Exception.php | 18 + .../Exception/InvalidArgumentException.php | 37 + .../MissingCoversAnnotationException.php | 18 + .../src/Exception/RuntimeException.php | 15 + .../UnintentionallyCoveredCodeException.php | 54 + .../phpunit/php-code-coverage/src/Filter.php | 173 + .../src/Node/AbstractNode.php | 342 ++ .../php-code-coverage/src/Node/Builder.php | 244 + .../php-code-coverage/src/Node/Directory.php | 483 ++ .../php-code-coverage/src/Node/File.php | 684 +++ .../php-code-coverage/src/Node/Iterator.php | 103 + .../php-code-coverage/src/Report/Clover.php | 251 + .../php-code-coverage/src/Report/Crap4j.php | 172 + .../src/Report/Html/Facade.php | 179 + .../src/Report/Html/Renderer.php | 297 ++ .../src/Report/Html/Renderer/Dashboard.php | 302 ++ .../src/Report/Html/Renderer/Directory.php | 101 + .../src/Report/Html/Renderer/File.php | 541 +++ .../Renderer/Template/coverage_bar.html.dist | 5 + .../Renderer/Template/css/bootstrap.min.css | 6 + .../Html/Renderer/Template/css/nv.d3.min.css | 1 + .../Html/Renderer/Template/css/style.css | 122 + .../Renderer/Template/dashboard.html.dist | 284 ++ .../Renderer/Template/directory.html.dist | 61 + .../Template/directory_item.html.dist | 13 + .../Html/Renderer/Template/file.html.dist | 90 + .../Renderer/Template/file_item.html.dist | 14 + .../fonts/glyphicons-halflings-regular.eot | Bin 0 -> 20127 bytes .../fonts/glyphicons-halflings-regular.svg | 288 ++ .../fonts/glyphicons-halflings-regular.ttf | Bin 0 -> 45404 bytes .../fonts/glyphicons-halflings-regular.woff | Bin 0 -> 23424 bytes .../fonts/glyphicons-halflings-regular.woff2 | Bin 0 -> 18028 bytes .../Renderer/Template/js/bootstrap.min.js | 7 + .../Html/Renderer/Template/js/d3.min.js | 5 + .../Html/Renderer/Template/js/holder.min.js | 12 + .../Renderer/Template/js/html5shiv.min.js | 326 ++ .../Html/Renderer/Template/js/jquery.min.js | 5 + .../Html/Renderer/Template/js/nv.d3.min.js | 8 + .../Html/Renderer/Template/js/respond.min.js | 5 + .../Renderer/Template/method_item.html.dist | 11 + .../php-code-coverage/src/Report/PHP.php | 51 + .../php-code-coverage/src/Report/Text.php | 257 + .../src/Report/Xml/Coverage.php | 67 + .../src/Report/Xml/Directory.php | 15 + .../src/Report/Xml/Facade.php | 246 + .../php-code-coverage/src/Report/Xml/File.php | 72 + .../src/Report/Xml/Method.php | 57 + .../php-code-coverage/src/Report/Xml/Node.php | 88 + .../src/Report/Xml/Project.php | 62 + .../src/Report/Xml/Report.php | 71 + .../src/Report/Xml/Tests.php | 46 + .../src/Report/Xml/Totals.php | 141 + .../php-code-coverage/src/Report/Xml/Unit.php | 96 + .../phpunit/php-code-coverage/src/Util.php | 48 + .../php-code-coverage/tests/TestCase.php | 343 ++ .../tests/_files/BankAccount-clover.xml | 26 + .../tests/_files/BankAccount-crap4j.xml | 59 + .../tests/_files/BankAccount-text.txt | 12 + .../tests/_files/BankAccount.php | 33 + .../tests/_files/BankAccountTest.php | 66 + .../_files/CoverageClassExtendedTest.php | 12 + .../tests/_files/CoverageClassTest.php | 12 + .../CoverageFunctionParenthesesTest.php | 11 + ...erageFunctionParenthesesWhitespaceTest.php | 11 + .../tests/_files/CoverageFunctionTest.php | 11 + .../CoverageMethodOneLineAnnotationTest.php | 11 + .../_files/CoverageMethodParenthesesTest.php | 12 + ...overageMethodParenthesesWhitespaceTest.php | 12 + .../tests/_files/CoverageMethodTest.php | 12 + .../tests/_files/CoverageNoneTest.php | 9 + .../tests/_files/CoverageNotPrivateTest.php | 12 + .../tests/_files/CoverageNotProtectedTest.php | 12 + .../tests/_files/CoverageNotPublicTest.php | 12 + .../tests/_files/CoverageNothingTest.php | 13 + .../tests/_files/CoveragePrivateTest.php | 12 + .../tests/_files/CoverageProtectedTest.php | 12 + .../tests/_files/CoveragePublicTest.php | 12 + .../CoverageTwoDefaultClassAnnotations.php | 18 + .../tests/_files/CoveredClass.php | 36 + .../tests/_files/CoveredFunction.php | 4 + .../NamespaceCoverageClassExtendedTest.php | 12 + .../_files/NamespaceCoverageClassTest.php | 12 + ...NamespaceCoverageCoversClassPublicTest.php | 15 + .../NamespaceCoverageCoversClassTest.php | 20 + .../_files/NamespaceCoverageMethodTest.php | 12 + .../NamespaceCoverageNotPrivateTest.php | 12 + .../NamespaceCoverageNotProtectedTest.php | 12 + .../_files/NamespaceCoverageNotPublicTest.php | 12 + .../_files/NamespaceCoveragePrivateTest.php | 12 + .../_files/NamespaceCoverageProtectedTest.php | 12 + .../_files/NamespaceCoveragePublicTest.php | 12 + .../tests/_files/NamespaceCoveredClass.php | 38 + .../_files/NotExistingCoveredElementTest.php | 24 + .../BankAccount.php.html | 267 ++ .../CoverageForBankAccount/dashboard.html | 290 ++ .../HTML/CoverageForBankAccount/index.html | 119 + .../dashboard.html | 288 ++ .../index.html | 119 + ...with_class_and_anonymous_function.php.html | 211 + .../dashboard.html | 286 ++ .../index.html | 119 + .../source_with_ignore.php.html | 279 ++ .../BankAccount.php.xml | 40 + .../XML/CoverageForBankAccount/index.xml | 29 + .../index.xml | 26 + ..._with_class_and_anonymous_function.php.xml | 41 + .../CoverageForFileWithIgnoredLines/index.xml | 26 + .../source_with_ignore.php.xml | 28 + .../class-with-anonymous-function-clover.xml | 22 + .../class-with-anonymous-function-crap4j.xml | 37 + .../class-with-anonymous-function-text.txt | 12 + .../tests/_files/ignored-lines-clover.xml | 17 + .../tests/_files/ignored-lines-crap4j.xml | 37 + .../tests/_files/ignored-lines-text.txt | 10 + ...urce_with_class_and_anonymous_function.php | 19 + .../tests/_files/source_with_ignore.php | 37 + .../tests/_files/source_with_namespace.php | 20 + .../source_with_oneline_annotations.php | 36 + .../tests/_files/source_without_ignore.php | 4 + .../tests/_files/source_without_namespace.php | 18 + .../php-code-coverage/tests/bootstrap.php | 5 + .../tests/tests/BuilderTest.php | 212 + .../tests/tests/CloverTest.php | 49 + .../tests/tests/CodeCoverageTest.php | 547 +++ .../tests/tests/Crap4jTest.php | 49 + .../tests/tests/FilterTest.php | 194 + .../tests/tests/HTMLTest.php | 103 + .../tests/tests/TextTest.php | 49 + .../tests/tests/UtilTest.php | 27 + .../php-code-coverage/tests/tests/XMLTest.php | 99 + .../phpunit/php-file-iterator/.gitattributes | 1 + .../phpunit/php-file-iterator/.gitignore | 7 + .../phpunit/php-file-iterator/ChangeLog.md | 10 + .../vendor/phpunit/php-file-iterator/LICENSE | 33 + .../phpunit/php-file-iterator/README.md | 12 + .../phpunit/php-file-iterator/composer.json | 36 + .../phpunit/php-file-iterator/src/Facade.php | 123 + .../phpunit/php-file-iterator/src/Factory.php | 91 + .../php-file-iterator/src/Iterator.php | 158 + .../phpunit/php-text-template/.gitattributes | 1 + .../phpunit/php-text-template/.gitignore | 5 + .../vendor/phpunit/php-text-template/LICENSE | 33 + .../phpunit/php-text-template/README.md | 14 + .../phpunit/php-text-template/composer.json | 29 + .../php-text-template/src/Template.php | 135 + .../vendor/phpunit/php-timer/.gitattributes | 1 + .../vendor/phpunit/php-timer/.gitignore | 3 + .../vendor/phpunit/php-timer/.travis.yml | 30 + src/composer/vendor/phpunit/php-timer/LICENSE | 33 + .../vendor/phpunit/php-timer/README.md | 47 + .../vendor/phpunit/php-timer/composer.json | 33 + .../vendor/phpunit/php-timer/src/Timer.php | 107 + .../phpunit/php-timer/tests/TimerTest.php | 101 + .../phpunit/php-token-stream/.gitattributes | 1 + .../phpunit/php-token-stream/.gitignore | 4 + .../phpunit/php-token-stream/.travis.yml | 35 + .../vendor/phpunit/php-token-stream/LICENSE | 33 + .../vendor/phpunit/php-token-stream/README.md | 14 + .../vendor/phpunit/php-token-stream/build.xml | 33 + .../php-token-stream/build/phpunit.xml | 17 + .../phpunit/php-token-stream/composer.json | 34 + .../phpunit/php-token-stream/src/Token.php | 848 ++++ .../php-token-stream/src/Token/Stream.php | 613 +++ .../src/Token/Stream/CachingFactory.php | 51 + .../tests/Token/ClassTest.php | 122 + .../tests/Token/ClosureTest.php | 85 + .../tests/Token/FunctionTest.php | 146 + .../tests/Token/IncludeTest.php | 73 + .../tests/Token/InterfaceTest.php | 191 + .../tests/Token/NamespaceTest.php | 80 + .../php-token-stream/tests/TokenTest.php | 42 + .../_fixture/classExtendsNamespacedClass.php | 10 + .../tests/_fixture/classInNamespace.php | 6 + .../tests/_fixture/classInScopedNamespace.php | 9 + .../_fixture/classUsesNamespacedFunction.php | 8 + ...h_method_that_declares_anonymous_class.php | 15 + ..._method_that_declares_anonymous_class2.php | 16 + .../tests/_fixture/closure.php | 7 + .../tests/_fixture/issue19.php | 3 + .../tests/_fixture/issue30.php | 8 + ...tipleNamespacesWithOneClassUsingBraces.php | 12 + ...espacesWithOneClassUsingNonBraceSyntax.php | 14 + .../tests/_fixture/source.php | 36 + .../tests/_fixture/source2.php | 6 + .../tests/_fixture/source3.php | 14 + .../tests/_fixture/source4.php | 30 + .../tests/_fixture/source5.php | 5 + .../php-token-stream/tests/bootstrap.php | 7 + .../phpunit-mock-objects/.gitattributes | 1 + .../phpunit/phpunit-mock-objects/.gitignore | 7 + .../phpunit/phpunit-mock-objects/.php_cs | 67 + .../phpunit/phpunit-mock-objects/.travis.yml | 22 + .../phpunit-mock-objects/CONTRIBUTING.md | 1 + .../phpunit/phpunit-mock-objects/LICENSE | 33 + .../phpunit/phpunit-mock-objects/README.md | 22 + .../phpunit/phpunit-mock-objects/build.xml | 42 + .../phpunit-mock-objects/build/travis-ci.xml | 12 + .../phpunit-mock-objects/composer.json | 53 + .../phpunit/phpunit-mock-objects/phpunit.xml | 21 + .../Framework/MockObject/Builder/Identity.php | 31 + .../MockObject/Builder/InvocationMocker.php | 291 ++ .../Framework/MockObject/Builder/Match.php | 27 + .../MockObject/Builder/MethodNameMatch.php | 27 + .../MockObject/Builder/Namespace.php | 38 + .../MockObject/Builder/ParametersMatch.php | 49 + .../src/Framework/MockObject/Builder/Stub.php | 27 + .../Exception/BadMethodCallException.php | 16 + .../MockObject/Exception/Exception.php | 18 + .../MockObject/Exception/RuntimeException.php | 16 + .../src/Framework/MockObject/Generator.php | 1309 ++++++ .../MockObject/Generator/deprecation.tpl.dist | 2 + .../Generator/mocked_class.tpl.dist | 40 + .../Generator/mocked_class_method.tpl.dist | 7 + .../Generator/mocked_clone.tpl.dist | 4 + .../Generator/mocked_method.tpl.dist | 22 + .../Generator/mocked_method_void.tpl.dist | 20 + .../Generator/mocked_static_method.tpl.dist | 5 + .../Generator/proxied_method.tpl.dist | 22 + .../Generator/proxied_method_void.tpl.dist | 22 + .../MockObject/Generator/trait_class.tpl.dist | 4 + .../Generator/unmocked_clone.tpl.dist | 5 + .../MockObject/Generator/wsdl_class.tpl.dist | 7 + .../MockObject/Generator/wsdl_method.tpl.dist | 4 + .../src/Framework/MockObject/Invocation.php | 22 + .../MockObject/Invocation/Object.php | 37 + .../MockObject/Invocation/Static.php | 192 + .../Framework/MockObject/InvocationMocker.php | 178 + .../src/Framework/MockObject/Invokable.php | 39 + .../src/Framework/MockObject/Matcher.php | 274 ++ .../MockObject/Matcher/AnyInvokedCount.php | 32 + .../MockObject/Matcher/AnyParameters.php | 35 + .../Matcher/ConsecutiveParameters.php | 126 + .../MockObject/Matcher/Invocation.php | 46 + .../MockObject/Matcher/InvokedAtIndex.php | 87 + .../Matcher/InvokedAtLeastCount.php | 57 + .../MockObject/Matcher/InvokedAtLeastOnce.php | 45 + .../MockObject/Matcher/InvokedAtMostCount.php | 57 + .../MockObject/Matcher/InvokedCount.php | 110 + .../MockObject/Matcher/InvokedRecorder.php | 68 + .../MockObject/Matcher/MethodName.php | 68 + .../MockObject/Matcher/Parameters.php | 158 + .../Matcher/StatelessInvocation.php | 54 + .../src/Framework/MockObject/MockBuilder.php | 408 ++ .../src/Framework/MockObject/MockObject.php | 55 + .../src/Framework/MockObject/Stub.php | 30 + .../MockObject/Stub/ConsecutiveCalls.php | 48 + .../Framework/MockObject/Stub/Exception.php | 48 + .../MockObject/Stub/MatcherCollection.php | 25 + .../src/Framework/MockObject/Stub/Return.php | 41 + .../MockObject/Stub/ReturnArgument.php | 38 + .../MockObject/Stub/ReturnCallback.php | 51 + .../MockObject/Stub/ReturnReference.php | 22 + .../Framework/MockObject/Stub/ReturnSelf.php | 34 + .../MockObject/Stub/ReturnValueMap.php | 47 + .../src/Framework/MockObject/Verifiable.php | 25 + .../tests/GeneratorTest.php | 225 + .../tests/MockBuilderTest.php | 126 + .../Builder/InvocationMockerTest.php | 63 + .../tests/MockObject/Generator/232.phpt | 129 + .../MockObject/Generator/abstract_class.phpt | 147 + .../tests/MockObject/Generator/class.phpt | 125 + .../Generator/class_call_parent_clone.phpt | 77 + .../class_call_parent_constructor.phpt | 76 + .../class_dont_call_parent_clone.phpt | 76 + .../class_dont_call_parent_constructor.phpt | 76 + ...ing_interface_call_parent_constructor.phpt | 81 + ...nterface_dont_call_parent_constructor.phpt | 81 + .../MockObject/Generator/class_partial.phpt | 103 + .../class_with_method_named_method.phpt | 92 + ...s_with_method_with_variadic_arguments.phpt | 99 + .../tests/MockObject/Generator/interface.phpt | 97 + .../invocation_object_clone_object.phpt | 126 + .../Generator/namespaced_class.phpt | 127 + .../namespaced_class_call_parent_clone.phpt | 79 + ...espaced_class_call_parent_constructor.phpt | 78 + ...mespaced_class_dont_call_parent_clone.phpt | 78 + ...ed_class_dont_call_parent_constructor.phpt | 78 + ...ing_interface_call_parent_constructor.phpt | 83 + ...nterface_dont_call_parent_constructor.phpt | 83 + .../Generator/namespaced_class_partial.phpt | 105 + .../Generator/namespaced_interface.phpt | 99 + .../Generator/nonexistent_class.phpt | 74 + .../nonexistent_class_with_namespace.phpt | 82 + ...ith_namespace_starting_with_separator.phpt | 82 + .../MockObject/Generator/nullable_types.phpt | 103 + .../tests/MockObject/Generator/proxy.phpt | 121 + ...eturn_type_declarations_object_method.phpt | 104 + .../return_type_declarations_self.phpt | 101 + ...eturn_type_declarations_static_method.phpt | 87 + .../return_type_declarations_void.phpt | 99 + .../Generator/scalar_type_declarations.phpt | 103 + .../MockObject/Generator/wsdl_class.phpt | 37 + .../Generator/wsdl_class_namespace.phpt | 39 + .../Generator/wsdl_class_partial.phpt | 30 + .../MockObject/Invocation/ObjectTest.php | 108 + .../MockObject/Invocation/StaticTest.php | 87 + .../Matcher/ConsecutiveParametersTest.php | 56 + .../class_with_deprecated_method.phpt | 105 + .../tests/MockObjectTest.php | 1037 ++++ .../tests/ProxyObjectTest.php | 39 + .../tests/_fixture/AbstractMockTestClass.php | 10 + .../tests/_fixture/AbstractTrait.php | 15 + .../tests/_fixture/AnInterface.php | 5 + .../_fixture/AnInterfaceWithReturnType.php | 5 + .../tests/_fixture/AnotherInterface.php | 5 + .../tests/_fixture/Bar.php | 8 + .../ClassThatImplementsSerializable.php | 15 + .../tests/_fixture/ClassWithSelfTypeHint.php | 7 + .../tests/_fixture/ClassWithStaticMethod.php | 7 + .../tests/_fixture/Foo.php | 8 + .../tests/_fixture/FunctionCallback.php | 9 + .../tests/_fixture/GoogleSearch.wsdl | 198 + .../InterfaceWithSemiReservedMethodName.php | 5 + .../_fixture/InterfaceWithStaticMethod.php | 5 + .../tests/_fixture/MethodCallback.php | 21 + .../_fixture/MethodCallbackByReference.php | 13 + .../tests/_fixture/MockTestInterface.php | 6 + .../tests/_fixture/Mockable.php | 28 + .../tests/_fixture/PartialMockTestClass.php | 18 + .../tests/_fixture/SingletonClass.php | 28 + .../tests/_fixture/SomeClass.php | 13 + .../tests/_fixture/StaticMockTestClass.php | 12 + .../tests/_fixture/StringableClass.php | 8 + .../_fixture/TraversableMockTestInterface.php | 4 + .../phpunit-mock-objects/tests/bootstrap.php | 3 + .../vendor/phpunit/phpunit/.gitattributes | 4 + .../vendor/phpunit/phpunit/.gitignore | 17 + src/composer/vendor/phpunit/phpunit/.php_cs | 70 + .../vendor/phpunit/phpunit/.travis.yml | 26 + .../vendor/phpunit/phpunit/CODE_OF_CONDUCT.md | 28 + .../vendor/phpunit/phpunit/CONTRIBUTING.md | 66 + .../vendor/phpunit/phpunit/ChangeLog-4.0.md | 176 + .../vendor/phpunit/phpunit/ChangeLog-4.1.md | 73 + .../vendor/phpunit/phpunit/ChangeLog-4.2.md | 56 + .../vendor/phpunit/phpunit/ChangeLog-4.3.md | 54 + .../vendor/phpunit/phpunit/ChangeLog-4.4.md | 57 + .../vendor/phpunit/phpunit/ChangeLog-4.5.md | 28 + .../vendor/phpunit/phpunit/ChangeLog-4.6.md | 95 + .../vendor/phpunit/phpunit/ChangeLog-4.7.md | 71 + .../vendor/phpunit/phpunit/ChangeLog-4.8.md | 227 + .../vendor/phpunit/phpunit/ChangeLog-5.0.md | 128 + .../vendor/phpunit/phpunit/ChangeLog-5.1.md | 68 + .../vendor/phpunit/phpunit/ChangeLog-5.2.md | 117 + .../vendor/phpunit/phpunit/ChangeLog-5.3.md | 55 + .../vendor/phpunit/phpunit/ChangeLog-5.4.md | 83 + .../vendor/phpunit/phpunit/ChangeLog-5.5.md | 74 + src/composer/vendor/phpunit/phpunit/LICENSE | 33 + src/composer/vendor/phpunit/phpunit/README.md | 46 + src/composer/vendor/phpunit/phpunit/build.xml | 398 ++ .../vendor/phpunit/phpunit/composer.json | 84 + src/composer/vendor/phpunit/phpunit/phpunit | 47 + .../vendor/phpunit/phpunit/phpunit.xml | 34 + .../vendor/phpunit/phpunit/phpunit.xsd | 253 + .../vendor/phpunit/phpunit/src/Exception.php | 18 + .../phpunit/src/Extensions/GroupTestSuite.php | 60 + .../phpunit/src/Extensions/PhptTestCase.php | 448 ++ .../phpunit/src/Extensions/PhptTestSuite.php | 40 + .../phpunit/src/Extensions/RepeatedTest.php | 90 + .../phpunit/src/Extensions/TestDecorator.php | 109 + .../phpunit/src/Extensions/TicketListener.php | 204 + .../src/ForwardCompatibility/TestCase.php | 17 + .../phpunit/phpunit/src/Framework/Assert.php | 2926 ++++++++++++ .../src/Framework/Assert/Functions.php | 2373 ++++++++++ .../src/Framework/AssertionFailedError.php | 27 + .../src/Framework/BaseTestListener.php | 59 + .../src/Framework/CodeCoverageException.php | 16 + .../phpunit/src/Framework/Constraint.php | 153 + .../phpunit/src/Framework/Constraint/And.php | 125 + .../src/Framework/Constraint/ArrayHasKey.php | 82 + .../src/Framework/Constraint/ArraySubset.php | 85 + .../src/Framework/Constraint/Attribute.php | 87 + .../src/Framework/Constraint/Callback.php | 59 + .../Constraint/ClassHasAttribute.php | 82 + .../Constraint/ClassHasStaticAttribute.php | 56 + .../src/Framework/Constraint/Composite.php | 70 + .../src/Framework/Constraint/Count.php | 104 + .../src/Framework/Constraint/Exception.php | 88 + .../Framework/Constraint/ExceptionCode.php | 69 + .../Framework/Constraint/ExceptionMessage.php | 69 + .../Constraint/ExceptionMessageRegExp.php | 77 + .../src/Framework/Constraint/FileExists.php | 60 + .../src/Framework/Constraint/GreaterThan.php | 55 + .../src/Framework/Constraint/IsAnything.php | 62 + .../src/Framework/Constraint/IsEmpty.php | 66 + .../src/Framework/Constraint/IsEqual.php | 179 + .../src/Framework/Constraint/IsFalse.php | 40 + .../src/Framework/Constraint/IsFinite.php | 40 + .../src/Framework/Constraint/IsIdentical.php | 132 + .../src/Framework/Constraint/IsInfinite.php | 40 + .../src/Framework/Constraint/IsInstanceOf.php | 94 + .../src/Framework/Constraint/IsJson.php | 77 + .../src/Framework/Constraint/IsNan.php | 40 + .../src/Framework/Constraint/IsNull.php | 40 + .../src/Framework/Constraint/IsTrue.php | 40 + .../src/Framework/Constraint/IsType.php | 143 + .../src/Framework/Constraint/JsonMatches.php | 71 + .../JsonMatches/ErrorMessageProvider.php | 69 + .../src/Framework/Constraint/LessThan.php | 55 + .../phpunit/src/Framework/Constraint/Not.php | 160 + .../Constraint/ObjectHasAttribute.php | 35 + .../phpunit/src/Framework/Constraint/Or.php | 117 + .../src/Framework/Constraint/PCREMatch.php | 63 + .../src/Framework/Constraint/SameSize.php | 28 + .../Framework/Constraint/StringContains.php | 81 + .../Framework/Constraint/StringEndsWith.php | 55 + .../Framework/Constraint/StringMatches.php | 101 + .../Framework/Constraint/StringStartsWith.php | 55 + .../Constraint/TraversableContains.php | 125 + .../Constraint/TraversableContainsOnly.php | 95 + .../phpunit/src/Framework/Constraint/Xor.php | 122 + .../phpunit/phpunit/src/Framework/Error.php | 34 + .../src/Framework/Error/Deprecated.php | 24 + .../phpunit/src/Framework/Error/Notice.php | 24 + .../phpunit/src/Framework/Error/Warning.php | 24 + .../phpunit/src/Framework/Exception.php | 77 + .../src/Framework/ExceptionWrapper.php | 91 + .../Framework/ExpectationFailedException.php | 41 + .../phpunit/src/Framework/IncompleteTest.php | 19 + .../src/Framework/IncompleteTestCase.php | 84 + .../src/Framework/IncompleteTestError.php | 19 + .../InvalidCoversTargetException.php | 16 + .../phpunit/src/Framework/OutputError.php | 19 + ...mework_CoveredCodeNotExecutedException.php | 19 + ...ework_MissingCoversAnnotationException.php | 19 + .../phpunit/src/Framework/RiskyTest.php | 19 + .../phpunit/src/Framework/RiskyTestError.php | 19 + .../phpunit/src/Framework/SelfDescribing.php | 24 + .../phpunit/src/Framework/SkippedTest.php | 18 + .../phpunit/src/Framework/SkippedTestCase.php | 82 + .../src/Framework/SkippedTestError.php | 19 + .../src/Framework/SkippedTestSuiteError.php | 19 + .../phpunit/src/Framework/SyntheticError.php | 80 + .../phpunit/phpunit/src/Framework/Test.php | 26 + .../phpunit/src/Framework/TestCase.php | 2565 ++++++++++ .../phpunit/src/Framework/TestFailure.php | 169 + .../phpunit/src/Framework/TestListener.php | 114 + .../phpunit/src/Framework/TestResult.php | 1355 ++++++ .../phpunit/src/Framework/TestSuite.php | 1042 ++++ .../src/Framework/TestSuite/DataProvider.php | 27 + .../UnintentionallyCoveredCodeError.php | 19 + .../phpunit/phpunit/src/Framework/Warning.php | 27 + .../phpunit/src/Framework/WarningTestCase.php | 81 + .../phpunit/src/Runner/BaseTestRunner.php | 141 + .../phpunit/phpunit/src/Runner/Exception.php | 16 + .../phpunit/src/Runner/Filter/Factory.php | 51 + .../phpunit/src/Runner/Filter/Group.php | 59 + .../src/Runner/Filter/Group/Exclude.php | 20 + .../src/Runner/Filter/Group/Include.php | 20 + .../phpunit/src/Runner/Filter/Test.php | 116 + .../src/Runner/StandardTestSuiteLoader.php | 118 + .../phpunit/src/Runner/TestSuiteLoader.php | 32 + .../phpunit/phpunit/src/Runner/Version.php | 77 + .../phpunit/phpunit/src/TextUI/Command.php | 1149 +++++ .../phpunit/src/TextUI/ResultPrinter.php | 708 +++ .../phpunit/phpunit/src/TextUI/TestRunner.php | 1122 +++++ .../phpunit/phpunit/src/Util/Blacklist.php | 115 + .../phpunit/src/Util/Configuration.php | 1163 +++++ .../src/Util/ConfigurationGenerator.php | 69 + .../phpunit/phpunit/src/Util/ErrorHandler.php | 117 + .../phpunit/phpunit/src/Util/Fileloader.php | 72 + .../phpunit/phpunit/src/Util/Filesystem.php | 42 + .../phpunit/phpunit/src/Util/Filter.php | 107 + .../phpunit/phpunit/src/Util/Getopt.php | 163 + .../phpunit/phpunit/src/Util/GlobalState.php | 192 + .../src/Util/InvalidArgumentHelper.php | 41 + .../phpunit/phpunit/src/Util/Log/JSON.php | 260 + .../phpunit/phpunit/src/Util/Log/JUnit.php | 462 ++ .../phpunit/phpunit/src/Util/Log/TAP.php | 271 ++ .../phpunit/phpunit/src/Util/Log/TeamCity.php | 410 ++ .../vendor/phpunit/phpunit/src/Util/PHP.php | 419 ++ .../phpunit/phpunit/src/Util/PHP/Default.php | 215 + .../Util/PHP/Template/TestCaseMethod.tpl.dist | 102 + .../phpunit/phpunit/src/Util/PHP/Windows.php | 41 + .../phpunit/src/Util/PHP/eval-stdin.php | 3 + .../phpunit/phpunit/src/Util/Printer.php | 172 + .../vendor/phpunit/phpunit/src/Util/Regex.php | 26 + .../phpunit/phpunit/src/Util/String.php | 71 + .../vendor/phpunit/phpunit/src/Util/Test.php | 1140 +++++ .../src/Util/TestDox/NamePrettifier.php | 144 + .../src/Util/TestDox/ResultPrinter.php | 414 ++ .../src/Util/TestDox/ResultPrinter/HTML.php | 144 + .../src/Util/TestDox/ResultPrinter/Text.php | 54 + .../src/Util/TestDox/ResultPrinter/XML.php | 228 + .../phpunit/src/Util/TestSuiteIterator.php | 103 + .../vendor/phpunit/phpunit/src/Util/Type.php | 38 + .../vendor/phpunit/phpunit/src/Util/XML.php | 255 + .../tests/Extensions/PhptTestCaseTest.php | 263 ++ .../tests/Extensions/RepeatedTestTest.php | 64 + .../phpunit/phpunit/tests/Fail/fail.phpt | 5 + .../phpunit/tests/Framework/AssertTest.php | 4178 +++++++++++++++++ .../tests/Framework/BaseTestListenerTest.php | 34 + .../tests/Framework/Constraint/CountTest.php | 63 + .../Constraint/ExceptionMessageRegExpTest.php | 56 + .../Constraint/ExceptionMessageTest.php | 52 + .../tests/Framework/Constraint/IsJsonTest.php | 32 + .../JsonMatches/ErrorMessageProviderTest.php | 83 + .../Framework/Constraint/JsonMatchesTest.php | 48 + .../tests/Framework/ConstraintTest.php | 3489 ++++++++++++++ .../phpunit/tests/Framework/SuiteTest.php | 258 + .../phpunit/tests/Framework/TestCaseTest.php | 642 +++ .../tests/Framework/TestFailureTest.php | 27 + .../tests/Framework/TestImplementorTest.php | 30 + .../tests/Framework/TestListenerTest.php | 114 + .../phpunit/tests/Regression/GitHub/1149.phpt | 20 + .../Regression/GitHub/1149/Issue1149Test.php | 18 + .../phpunit/tests/Regression/GitHub/1216.phpt | 25 + .../Regression/GitHub/1216/Issue1216Test.php | 8 + .../Regression/GitHub/1216/bootstrap1216.php | 2 + .../Regression/GitHub/1216/phpunit1216.xml | 8 + .../phpunit/tests/Regression/GitHub/1265.phpt | 21 + .../Regression/GitHub/1265/Issue1265Test.php | 8 + .../Regression/GitHub/1265/phpunit1265.xml | 2 + .../phpunit/tests/Regression/GitHub/1330.phpt | 24 + .../Regression/GitHub/1330/Issue1330Test.php | 8 + .../Regression/GitHub/1330/phpunit1330.xml | 5 + .../phpunit/tests/Regression/GitHub/1335.phpt | 19 + .../Regression/GitHub/1335/Issue1335Test.php | 67 + .../Regression/GitHub/1335/bootstrap1335.php | 13 + .../phpunit/tests/Regression/GitHub/1337.phpt | 19 + .../Regression/GitHub/1337/Issue1337Test.php | 19 + .../phpunit/tests/Regression/GitHub/1348.phpt | 34 + .../Regression/GitHub/1348/Issue1348Test.php | 14 + .../phpunit/tests/Regression/GitHub/1351.phpt | 46 + .../GitHub/1351/ChildProcessClass1351.php | 4 + .../Regression/GitHub/1351/Issue1351Test.php | 48 + .../phpunit/tests/Regression/GitHub/1374.phpt | 19 + .../Regression/GitHub/1374/Issue1374Test.php | 21 + .../phpunit/tests/Regression/GitHub/1437.phpt | 26 + .../Regression/GitHub/1437/Issue1437Test.php | 9 + .../phpunit/tests/Regression/GitHub/1468.phpt | 20 + .../Regression/GitHub/1468/Issue1468Test.php | 11 + .../phpunit/tests/Regression/GitHub/1471.phpt | 26 + .../Regression/GitHub/1471/Issue1471Test.php | 12 + .../phpunit/tests/Regression/GitHub/1472.phpt | 25 + .../Regression/GitHub/1472/Issue1472Test.php | 21 + .../phpunit/tests/Regression/GitHub/1570.phpt | 20 + .../Regression/GitHub/1570/Issue1570Test.php | 8 + .../phpunit/tests/Regression/GitHub/2158.phpt | 19 + .../Regression/GitHub/2158/Issue2158Test.php | 23 + .../tests/Regression/GitHub/2158/constant.inc | 5 + .../phpunit/tests/Regression/GitHub/244.phpt | 32 + .../Regression/GitHub/244/Issue244Test.php | 55 + .../phpunit/tests/Regression/GitHub/322.phpt | 26 + .../Regression/GitHub/322/Issue322Test.php | 17 + .../Regression/GitHub/322/phpunit322.xml | 11 + .../phpunit/tests/Regression/GitHub/433.phpt | 31 + .../Regression/GitHub/433/Issue433Test.php | 21 + .../phpunit/tests/Regression/GitHub/445.phpt | 32 + .../Regression/GitHub/445/Issue445Test.php | 21 + .../phpunit/tests/Regression/GitHub/498.phpt | 29 + .../Regression/GitHub/498/Issue498Test.php | 44 + .../phpunit/tests/Regression/GitHub/503.phpt | 33 + .../Regression/GitHub/503/Issue503Test.php | 11 + .../phpunit/tests/Regression/GitHub/581.phpt | 42 + .../Regression/GitHub/581/Issue581Test.php | 11 + .../phpunit/tests/Regression/GitHub/74.phpt | 28 + .../Regression/GitHub/74/Issue74Test.php | 9 + .../Regression/GitHub/74/NewException.php | 4 + .../phpunit/tests/Regression/GitHub/765.phpt | 26 + .../Regression/GitHub/765/Issue765Test.php | 22 + .../phpunit/tests/Regression/GitHub/797.phpt | 22 + .../Regression/GitHub/797/Issue797Test.php | 10 + .../Regression/GitHub/797/bootstrap797.php | 6 + .../phpunit/tests/Regression/GitHub/863.phpt | 24 + .../tests/Regression/GitHub/873-php5.phpt | 22 + .../tests/Regression/GitHub/873-php7.phpt | 22 + .../Regression/GitHub/873/Issue873Test.php | 9 + .../phpunit/tests/Regression/Trac/1021.phpt | 19 + .../Regression/Trac/1021/Issue1021Test.php | 23 + .../phpunit/tests/Regression/Trac/523.phpt | 19 + .../Regression/Trac/523/Issue523Test.php | 13 + .../phpunit/tests/Regression/Trac/578.phpt | 37 + .../Regression/Trac/578/Issue578Test.php | 20 + .../phpunit/tests/Regression/Trac/684.phpt | 25 + .../Regression/Trac/684/Issue684Test.php | 4 + .../phpunit/tests/Regression/Trac/783.phpt | 21 + .../tests/Regression/Trac/783/ChildSuite.php | 15 + .../tests/Regression/Trac/783/OneTest.php | 10 + .../tests/Regression/Trac/783/ParentSuite.php | 13 + .../tests/Regression/Trac/783/TwoTest.php | 10 + .../tests/Runner/BaseTestRunnerTest.php | 22 + .../tests/TextUI/_files/expect_external.txt | 1 + .../tests/TextUI/_files/phpt-env.expected.txt | 1 + .../tests/TextUI/_files/phpt_external.php | 2 + .../tests/TextUI/abstract-test-class.phpt | 24 + .../phpunit/tests/TextUI/assertion.phpt | 38 + .../tests/TextUI/code-coverage-ignore.phpt | 36 + .../phpunit/tests/TextUI/colors-always.phpt | 18 + .../tests/TextUI/concrete-test-class.phpt | 18 + .../tests/TextUI/custom-printer-debug.phpt | 26 + .../tests/TextUI/custom-printer-verbose.phpt | 31 + .../tests/TextUI/dataprovider-debug.phpt | 33 + .../dataprovider-log-xml-isolation.phpt | 46 + .../tests/TextUI/dataprovider-log-xml.phpt | 45 + .../tests/TextUI/dataprovider-testdox.phpt | 19 + .../phpunit/phpunit/tests/TextUI/debug.phpt | 25 + .../tests/TextUI/default-isolation.phpt | 19 + .../phpunit/phpunit/tests/TextUI/default.phpt | 18 + .../tests/TextUI/dependencies-clone.phpt | 22 + .../tests/TextUI/dependencies-isolation.phpt | 42 + .../phpunit/tests/TextUI/dependencies.phpt | 41 + .../tests/TextUI/dependencies2-isolation.phpt | 19 + .../phpunit/tests/TextUI/dependencies2.phpt | 18 + .../tests/TextUI/dependencies3-isolation.phpt | 19 + .../phpunit/tests/TextUI/dependencies3.phpt | 19 + .../TextUI/disable-code-coverage-ignore.phpt | 40 + .../phpunit/tests/TextUI/empty-testcase.phpt | 25 + .../phpunit/tests/TextUI/exception-stack.phpt | 64 + .../tests/TextUI/exclude-group-isolation.phpt | 21 + .../phpunit/tests/TextUI/exclude-group.phpt | 20 + .../tests/TextUI/failure-isolation.phpt | 141 + .../tests/TextUI/failure-reverse-list.phpt | 141 + .../phpunit/phpunit/tests/TextUI/failure.phpt | 140 + .../phpunit/tests/TextUI/fatal-isolation.phpt | 25 + .../tests/TextUI/filter-class-isolation.phpt | 21 + .../phpunit/tests/TextUI/filter-class.phpt | 20 + ...ider-by-classname-and-range-isolation.phpt | 21 + ...r-dataprovider-by-classname-and-range.phpt | 20 + ...lter-dataprovider-by-number-isolation.phpt | 21 + .../TextUI/filter-dataprovider-by-number.phpt | 20 + ...-dataprovider-by-only-range-isolation.phpt | 21 + .../filter-dataprovider-by-only-range.phpt | 20 + ...dataprovider-by-only-regexp-isolation.phpt | 21 + .../filter-dataprovider-by-only-regexp.phpt | 20 + ...dataprovider-by-only-string-isolation.phpt | 21 + .../filter-dataprovider-by-only-string.phpt | 20 + ...ilter-dataprovider-by-range-isolation.phpt | 21 + .../TextUI/filter-dataprovider-by-range.phpt | 20 + ...lter-dataprovider-by-regexp-isolation.phpt | 21 + .../TextUI/filter-dataprovider-by-regexp.phpt | 20 + ...lter-dataprovider-by-string-isolation.phpt | 21 + .../TextUI/filter-dataprovider-by-string.phpt | 20 + .../filter-method-case-insensitive.phpt | 20 + ...ilter-method-case-sensitive-no-result.phpt | 20 + .../tests/TextUI/filter-method-isolation.phpt | 21 + .../phpunit/tests/TextUI/filter-method.phpt | 20 + .../tests/TextUI/filter-no-results.phpt | 20 + .../tests/TextUI/forward-compatibility.phpt | 18 + .../phpunit/tests/TextUI/group-isolation.phpt | 21 + .../phpunit/phpunit/tests/TextUI/group.phpt | 20 + .../phpunit/phpunit/tests/TextUI/help.phpt | 101 + .../phpunit/phpunit/tests/TextUI/help2.phpt | 102 + .../phpunit/tests/TextUI/ini-isolation.phpt | 21 + .../phpunit/tests/TextUI/list-groups.phpt | 18 + .../phpunit/tests/TextUI/list-suites.phpt | 16 + .../tests/TextUI/log-json-post-66021.phpt | 71 + .../phpunit/phpunit/tests/TextUI/log-tap.phpt | 25 + .../phpunit/tests/TextUI/log-teamcity.phpt | 38 + .../phpunit/phpunit/tests/TextUI/log-xml.phpt | 28 + .../tests/TextUI/options-after-arguments.phpt | 18 + .../tests/TextUI/output-isolation.phpt | 20 + .../phpunit/tests/TextUI/phpt-args.phpt | 12 + .../phpunit/tests/TextUI/phpt-env.phpt | 12 + .../phpunit/tests/TextUI/phpt-external.phpt | 6 + .../phpunit/tests/TextUI/phpt-stderr.phpt | 8 + .../phpunit/tests/TextUI/phpt-stdin.phpt | 11 + .../phpunit/tests/TextUI/phpt-xfail.phpt | 18 + .../phpunit/phpunit/tests/TextUI/repeat.phpt | 20 + .../report-useless-tests-incomplete.phpt | 20 + .../report-useless-tests-isolation.phpt | 21 + .../tests/TextUI/report-useless-tests.phpt | 20 + .../tests/TextUI/stop-on-warning-via-cli.phpt | 25 + .../TextUI/stop-on-warning-via-config.phpt | 26 + .../phpunit/phpunit/tests/TextUI/tap.phpt | 17 + .../phpunit/tests/TextUI/teamcity.phpt | 37 + .../tests/TextUI/test-suffix-multiple.phpt | 19 + .../tests/TextUI/test-suffix-single.phpt | 19 + .../tests/TextUI/testdox-exclude-group.phpt | 25 + .../phpunit/tests/TextUI/testdox-group.phpt | 25 + .../phpunit/tests/TextUI/testdox-html.phpt | 56 + .../phpunit/tests/TextUI/testdox-text.phpt | 24 + .../phpunit/tests/TextUI/testdox-xml.phpt | 26 + .../phpunit/phpunit/tests/TextUI/testdox.phpt | 18 + .../phpunit/tests/Util/ConfigurationTest.php | 478 ++ .../phpunit/phpunit/tests/Util/GetoptTest.php | 62 + .../phpunit/tests/Util/GlobalStateTest.php | 35 + .../phpunit/phpunit/tests/Util/PHPTest.php | 133 + .../phpunit/phpunit/tests/Util/RegexTest.php | 52 + .../tests/Util/TestDox/NamePrettifierTest.php | 82 + .../phpunit/phpunit/tests/Util/TestTest.php | 856 ++++ .../phpunit/phpunit/tests/Util/XMLTest.php | 76 + .../phpunit/tests/_files/AbstractTest.php | 7 + .../phpunit/tests/_files/AssertionExample.php | 8 + .../tests/_files/AssertionExampleTest.php | 10 + .../phpunit/phpunit/tests/_files/Author.php | 27 + .../phpunit/tests/_files/BankAccount.php | 82 + .../phpunit/tests/_files/BankAccountTest.php | 94 + .../tests/_files/BankAccountTest.test.php | 87 + .../phpunit/tests/_files/BankAccountTest2.php | 56 + .../tests/_files/BaseTestListenerSample.php | 11 + .../tests/_files/BeforeAndAfterTest.php | 35 + .../_files/BeforeClassAndAfterClassTest.php | 35 + .../BeforeClassWithOnlyDataProviderTest.php | 39 + .../phpunit/phpunit/tests/_files/Book.php | 20 + .../phpunit/tests/_files/Calculator.php | 14 + .../ChangeCurrentWorkingDirectoryTest.php | 9 + .../_files/ClassWithNonPublicAttributes.php | 29 + .../ClassWithScalarTypeDeclarations.php | 7 + .../tests/_files/ClassWithToString.php | 22 + .../tests/_files/ClonedDependencyTest.php | 39 + .../phpunit/tests/_files/ConcreteTest.my.php | 7 + .../phpunit/tests/_files/ConcreteTest.php | 7 + .../_files/CoverageClassExtendedTest.php | 12 + .../tests/_files/CoverageClassTest.php | 12 + .../CoverageFunctionParenthesesTest.php | 11 + ...erageFunctionParenthesesWhitespaceTest.php | 11 + .../tests/_files/CoverageFunctionTest.php | 11 + .../CoverageMethodOneLineAnnotationTest.php | 11 + .../_files/CoverageMethodParenthesesTest.php | 12 + ...overageMethodParenthesesWhitespaceTest.php | 12 + .../tests/_files/CoverageMethodTest.php | 12 + .../_files/CoverageNamespacedFunctionTest.php | 11 + .../phpunit/tests/_files/CoverageNoneTest.php | 9 + .../tests/_files/CoverageNotPrivateTest.php | 12 + .../tests/_files/CoverageNotProtectedTest.php | 12 + .../tests/_files/CoverageNotPublicTest.php | 12 + .../tests/_files/CoverageNothingTest.php | 13 + .../tests/_files/CoveragePrivateTest.php | 12 + .../tests/_files/CoverageProtectedTest.php | 12 + .../tests/_files/CoveragePublicTest.php | 12 + .../CoverageTwoDefaultClassAnnotations.php | 17 + .../phpunit/tests/_files/CoveredClass.php | 36 + .../phpunit/tests/_files/CoveredFunction.php | 4 + .../phpunit/tests/_files/CustomPrinter.php | 4 + .../tests/_files/DataProviderDebugTest.php | 48 + .../tests/_files/DataProviderFilterTest.php | 39 + .../_files/DataProviderIncompleteTest.php | 37 + .../tests/_files/DataProviderSkippedTest.php | 37 + .../phpunit/tests/_files/DataProviderTest.php | 21 + .../tests/_files/DataProviderTestDoxTest.php | 26 + .../tests/_files/DependencyFailureTest.php | 29 + .../tests/_files/DependencySuccessTest.php | 21 + .../tests/_files/DependencyTestSuite.php | 13 + .../phpunit/tests/_files/DoubleTestCase.php | 25 + .../phpunit/tests/_files/DummyException.php | 5 + .../tests/_files/EmptyTestCaseTest.php | 4 + .../ExceptionInAssertPostConditionsTest.php | 35 + .../ExceptionInAssertPreConditionsTest.php | 35 + .../tests/_files/ExceptionInSetUpTest.php | 35 + .../tests/_files/ExceptionInTearDownTest.php | 35 + .../phpunit/tests/_files/ExceptionInTest.php | 35 + .../tests/_files/ExceptionNamespaceTest.php | 38 + .../tests/_files/ExceptionStackTest.php | 21 + .../phpunit/tests/_files/ExceptionTest.php | 139 + .../phpunit/phpunit/tests/_files/Failure.php | 8 + .../phpunit/tests/_files/FailureTest.php | 75 + .../phpunit/tests/_files/FatalTest.php | 13 + .../tests/_files/IgnoreCodeCoverageClass.php | 16 + .../_files/IgnoreCodeCoverageClassTest.php | 15 + .../phpunit/tests/_files/IncompleteTest.php | 8 + .../tests/_files/Inheritance/InheritanceA.php | 7 + .../tests/_files/Inheritance/InheritanceB.php | 8 + .../tests/_files/InheritedTestCase.php | 7 + .../phpunit/phpunit/tests/_files/IniTest.php | 8 + .../phpunit/tests/_files/IsolationTest.php | 13 + .../tests/_files/JsonData/arrayObject.json | 1 + .../tests/_files/JsonData/simpleObject.json | 1 + .../phpunit/tests/_files/MockRunner.php | 7 + .../phpunit/phpunit/tests/_files/Mockable.php | 26 + .../tests/_files/MultiDependencyTest.php | 23 + .../NamespaceCoverageClassExtendedTest.php | 12 + .../_files/NamespaceCoverageClassTest.php | 12 + ...NamespaceCoverageCoversClassPublicTest.php | 15 + .../NamespaceCoverageCoversClassTest.php | 20 + .../_files/NamespaceCoverageMethodTest.php | 12 + .../NamespaceCoverageNotPrivateTest.php | 12 + .../NamespaceCoverageNotProtectedTest.php | 12 + .../_files/NamespaceCoverageNotPublicTest.php | 12 + .../_files/NamespaceCoveragePrivateTest.php | 12 + .../_files/NamespaceCoverageProtectedTest.php | 12 + .../_files/NamespaceCoveragePublicTest.php | 12 + .../tests/_files/NamespaceCoveredClass.php | 38 + .../tests/_files/NamespaceCoveredFunction.php | 7 + .../tests/_files/NoArgTestCaseTest.php | 7 + .../phpunit/tests/_files/NoTestCaseClass.php | 4 + .../phpunit/tests/_files/NoTestCases.php | 7 + .../phpunit/tests/_files/NonStatic.php | 8 + .../_files/NotExistingCoveredElementTest.php | 24 + .../tests/_files/NotPublicTestCase.php | 11 + .../phpunit/tests/_files/NotVoidTestCase.php | 4 + .../phpunit/tests/_files/NothingTest.php | 7 + .../phpunit/tests/_files/OneTestCase.php | 11 + .../phpunit/tests/_files/OutputTestCase.php | 27 + .../phpunit/tests/_files/OverrideTestCase.php | 7 + .../RequirementsClassBeforeClassHookTest.php | 12 + .../_files/RequirementsClassDocBlockTest.php | 22 + .../phpunit/tests/_files/RequirementsTest.php | 345 ++ .../tests/_files/SampleArrayAccess.php | 36 + .../phpunit/tests/_files/SampleClass.php | 14 + .../phpunit/tests/_files/Singleton.php | 22 + .../phpunit/tests/_files/StackTest.php | 24 + .../tests/_files/StopOnWarningTestSuite.php | 13 + .../tests/_files/StopsOnWarningTest.php | 7 + .../phpunit/phpunit/tests/_files/Struct.php | 10 + .../phpunit/phpunit/tests/_files/Success.php | 7 + .../tests/_files/TemplateMethodsTest.php | 51 + .../phpunit/tests/_files/TestDoxGroupTest.php | 18 + .../phpunit/tests/_files/TestIncomplete.php | 8 + .../phpunit/tests/_files/TestIterator.php | 36 + .../phpunit/tests/_files/TestIterator2.php | 35 + .../phpunit/tests/_files/TestSkipped.php | 8 + .../phpunit/tests/_files/TestTestError.php | 8 + .../phpunit/tests/_files/TestWithTest.php | 24 + .../tests/_files/ThrowExceptionTestCase.php | 8 + .../tests/_files/ThrowNoExceptionTestCase.php | 7 + .../phpunit/phpunit/tests/_files/WasRun.php | 10 + .../phpunit/phpunit/tests/_files/bar.xml | 1 + .../_files/configuration.colors.empty.xml | 1 + .../_files/configuration.colors.false.xml | 1 + .../_files/configuration.colors.invalid.xml | 1 + .../_files/configuration.colors.true.xml | 1 + .../_files/configuration.custom-printer.xml | 2 + .../tests/_files/configuration.suites.xml | 6 + .../phpunit/tests/_files/configuration.xml | 120 + .../tests/_files/configuration_empty.xml | 49 + .../_files/configuration_stop_on_warning.xml | 2 + .../tests/_files/configuration_xinclude.xml | 73 + .../tests/_files/expectedFileFormat.txt | 1 + .../phpunit/phpunit/tests/_files/foo.xml | 1 + .../tests/_files/phpt-for-coverage.phpt | 8 + .../phpunit/tests/_files/phpt-xfail.phpt | 11 + ...uctureAttributesAreSameButValuesAreNot.xml | 10 + .../tests/_files/structureExpected.xml | 10 + .../tests/_files/structureIgnoreTextNodes.xml | 13 + .../_files/structureIsSameButDataIsNot.xml | 10 + .../structureWrongNumberOfAttributes.xml | 10 + .../_files/structureWrongNumberOfNodes.xml | 9 + .../phpunit/phpunit/tests/bootstrap.php | 6 + .../vendor/psr/log/Psr/Log/AbstractLogger.php | 40 +- .../vendor/psr/log/Psr/Log/LogLevel.php | 16 +- .../psr/log/Psr/Log/LoggerAwareInterface.php | 7 +- .../psr/log/Psr/Log/LoggerAwareTrait.php | 8 +- .../psr/log/Psr/Log/LoggerInterface.php | 51 +- .../vendor/psr/log/Psr/Log/LoggerTrait.php | 51 +- .../vendor/psr/log/Psr/Log/NullLogger.php | 9 +- .../log/Psr/Log/Test/LoggerInterfaceTest.php | 46 +- src/composer/vendor/psr/log/composer.json | 13 +- .../code-unit-reverse-lookup/.gitignore | 8 + .../code-unit-reverse-lookup/.php_cs | 67 + .../code-unit-reverse-lookup/.travis.yml | 16 + .../code-unit-reverse-lookup/ChangeLog.md | 10 + .../code-unit-reverse-lookup/LICENSE | 33 + .../code-unit-reverse-lookup/README.md | 13 + .../code-unit-reverse-lookup/build.xml | 27 + .../code-unit-reverse-lookup/composer.json | 28 + .../code-unit-reverse-lookup/phpunit.xml | 21 + .../code-unit-reverse-lookup/src/Wizard.php | 111 + .../tests/WizardTest.php | 43 + .../vendor/sebastian/comparator/.gitignore | 6 + .../vendor/sebastian/comparator/.travis.yml | 25 + .../vendor/sebastian/comparator/LICENSE | 33 + .../vendor/sebastian/comparator/README.md | 39 + .../vendor/sebastian/comparator/build.xml | 34 + .../sebastian/comparator/build/travis-ci.xml | 11 + .../vendor/sebastian/comparator/composer.json | 44 + .../sebastian/comparator/phpunit.xml.dist | 21 + .../comparator/src/ArrayComparator.php | 136 + .../sebastian/comparator/src/Comparator.php | 68 + .../comparator/src/ComparisonFailure.php | 129 + .../comparator/src/DOMNodeComparator.php | 110 + .../comparator/src/DateTimeComparator.php | 80 + .../comparator/src/DoubleComparator.php | 60 + .../comparator/src/ExceptionComparator.php | 51 + .../sebastian/comparator/src/Factory.php | 107 + .../comparator/src/MockObjectComparator.php | 45 + .../comparator/src/NumericComparator.php | 72 + .../comparator/src/ObjectComparator.php | 109 + .../comparator/src/ResourceComparator.php | 56 + .../comparator/src/ScalarComparator.php | 94 + .../src/SplObjectStorageComparator.php | 73 + .../comparator/src/TypeComparator.php | 63 + .../comparator/tests/ArrayComparatorTest.php | 163 + .../tests/DOMNodeComparatorTest.php | 162 + .../tests/DateTimeComparatorTest.php | 216 + .../comparator/tests/DoubleComparatorTest.php | 134 + .../tests/ExceptionComparatorTest.php | 136 + .../comparator/tests/FactoryTest.php | 115 + .../tests/MockObjectComparatorTest.php | 166 + .../tests/NumericComparatorTest.php | 122 + .../comparator/tests/ObjectComparatorTest.php | 150 + .../tests/ResourceComparatorTest.php | 120 + .../comparator/tests/ScalarComparatorTest.php | 158 + .../tests/SplObjectStorageComparatorTest.php | 137 + .../comparator/tests/TypeComparatorTest.php | 104 + .../comparator/tests/_files/Author.php | 28 + .../comparator/tests/_files/Book.php | 21 + .../tests/_files/ClassWithToString.php | 19 + .../comparator/tests/_files/SampleClass.php | 29 + .../comparator/tests/_files/Struct.php | 25 + .../comparator/tests/_files/TestClass.php | 14 + .../tests/_files/TestClassComparator.php | 14 + .../sebastian/comparator/tests/autoload.php | 38 + .../sebastian/comparator/tests/bootstrap.php | 7 + src/composer/vendor/sebastian/diff/.gitignore | 10 + src/composer/vendor/sebastian/diff/.php_cs | 66 + .../vendor/sebastian/diff/.travis.yml | 16 + src/composer/vendor/sebastian/diff/LICENSE | 33 + src/composer/vendor/sebastian/diff/README.md | 126 + src/composer/vendor/sebastian/diff/build.xml | 26 + .../vendor/sebastian/diff/composer.json | 33 + .../vendor/sebastian/diff/phpunit.xml.dist | 17 + .../vendor/sebastian/diff/src/Chunk.php | 104 + .../vendor/sebastian/diff/src/Diff.php | 75 + .../vendor/sebastian/diff/src/Differ.php | 261 + .../diff/src/LCS/LongestCommonSubsequence.php | 27 + ...LongestCommonSubsequenceImplementation.php | 93 + ...LongestCommonSubsequenceImplementation.php | 73 + .../vendor/sebastian/diff/src/Line.php | 56 + .../vendor/sebastian/diff/src/Parser.php | 99 + .../sebastian/diff/tests/DifferTest.php | Bin 0 -> 11492 bytes .../LCS/TimeEfficientImplementationTest.php | 175 + .../sebastian/diff/tests/ParserTest.php | 62 + .../sebastian/diff/tests/fixtures/patch.txt | 9 + .../sebastian/diff/tests/fixtures/patch2.txt | 21 + .../vendor/sebastian/environment/.gitignore | 4 + .../vendor/sebastian/environment/.travis.yml | 16 + .../vendor/sebastian/environment/LICENSE | 33 + .../vendor/sebastian/environment/README.md | 72 + .../vendor/sebastian/environment/build.xml | 26 + .../sebastian/environment/composer.json | 29 + .../vendor/sebastian/environment/phpunit.xml | 20 + .../sebastian/environment/src/Console.php | 113 + .../sebastian/environment/src/Runtime.php | 194 + .../environment/tests/ConsoleTest.php | 60 + .../environment/tests/RuntimeTest.php | 112 + .../vendor/sebastian/exporter/.gitignore | 9 + .../vendor/sebastian/exporter/.travis.yml | 23 + .../vendor/sebastian/exporter/LICENSE | 33 + .../vendor/sebastian/exporter/README.md | 171 + .../vendor/sebastian/exporter/build.xml | 27 + .../vendor/sebastian/exporter/composer.json | 48 + .../sebastian/exporter/phpunit.xml.dist | 21 + .../sebastian/exporter/src/Exporter.php | 301 ++ .../sebastian/exporter/tests/ExporterTest.php | 358 ++ .../vendor/sebastian/global-state/.gitignore | 6 + .../vendor/sebastian/global-state/.travis.yml | 20 + .../vendor/sebastian/global-state/LICENSE | 33 + .../vendor/sebastian/global-state/README.md | 15 + .../vendor/sebastian/global-state/build.xml | 33 + .../sebastian/global-state/composer.json | 37 + .../sebastian/global-state/phpunit.xml.dist | 21 + .../sebastian/global-state/src/Blacklist.php | 149 + .../global-state/src/CodeExporter.php | 93 + .../sebastian/global-state/src/Exception.php | 17 + .../sebastian/global-state/src/Restorer.php | 141 + .../global-state/src/RuntimeException.php | 17 + .../sebastian/global-state/src/Snapshot.php | 423 ++ .../global-state/tests/BlacklistTest.php | 113 + .../global-state/tests/SnapshotTest.php | 119 + .../tests/_fixture/BlacklistedChildClass.php | 17 + .../tests/_fixture/BlacklistedClass.php | 18 + .../tests/_fixture/BlacklistedImplementor.php | 18 + .../tests/_fixture/BlacklistedInterface.php | 17 + .../tests/_fixture/SnapshotClass.php | 37 + .../tests/_fixture/SnapshotDomDocument.php | 19 + .../tests/_fixture/SnapshotFunctions.php | 15 + .../tests/_fixture/SnapshotTrait.php | 17 + .../sebastian/object-enumerator/.gitignore | 8 + .../sebastian/object-enumerator/.php_cs | 67 + .../sebastian/object-enumerator/.travis.yml | 16 + .../sebastian/object-enumerator/ChangeLog.md | 9 + .../sebastian/object-enumerator/LICENSE | 33 + .../sebastian/object-enumerator/README.md | 13 + .../sebastian/object-enumerator/build.xml | 27 + .../sebastian/object-enumerator/composer.json | 29 + .../sebastian/object-enumerator/phpunit.xml | 21 + .../object-enumerator/src/Enumerator.php | 86 + .../object-enumerator/src/Exception.php | 15 + .../src/InvalidArgumentException.php | 15 + .../tests/EnumeratorTest.php | 127 + .../sebastian/recursion-context/.gitignore | 9 + .../sebastian/recursion-context/.travis.yml | 21 + .../sebastian/recursion-context/LICENSE | 33 + .../sebastian/recursion-context/README.md | 14 + .../sebastian/recursion-context/build.xml | 27 + .../sebastian/recursion-context/composer.json | 36 + .../recursion-context/phpunit.xml.dist | 20 + .../recursion-context/src/Context.php | 167 + .../recursion-context/src/Exception.php | 17 + .../src/InvalidArgumentException.php | 17 + .../recursion-context/tests/ContextTest.php | 144 + .../sebastian/resource-operations/.gitignore | 3 + .../sebastian/resource-operations/LICENSE | 33 + .../sebastian/resource-operations/README.md | 16 + .../sebastian/resource-operations/build.xml | 24 + .../resource-operations/build/generate.php | 62 + .../resource-operations/composer.json | 26 + .../src/ResourceOperations.php | 670 +++ .../vendor/sebastian/version/.gitattributes | 1 + .../vendor/sebastian/version/.gitignore | 1 + src/composer/vendor/sebastian/version/.php_cs | 66 + src/composer/vendor/sebastian/version/LICENSE | 33 + .../vendor/sebastian/version/README.md | 37 + .../vendor/sebastian/version/composer.json | 29 + .../vendor/sebastian/version/src/Version.php | 109 + .../vendor/symfony/console/.gitignore | 3 + .../vendor/symfony/console/Application.php | 1125 +++++ .../vendor/symfony/console/CHANGELOG.md | 79 + .../symfony/console/Command/Command.php | 633 +++ .../symfony/console/Command/HelpCommand.php | 86 + .../symfony/console/Command/ListCommand.php | 90 + .../vendor/symfony/console/ConsoleEvents.php | 53 + .../Descriptor/ApplicationDescription.php | 160 + .../symfony/console/Descriptor/Descriptor.php | 122 + .../Descriptor/DescriptorInterface.php | 31 + .../console/Descriptor/JsonDescriptor.php | 166 + .../console/Descriptor/MarkdownDescriptor.php | 143 + .../console/Descriptor/TextDescriptor.php | 283 ++ .../console/Descriptor/XmlDescriptor.php | 263 ++ .../console/Event/ConsoleCommandEvent.php | 62 + .../symfony/console/Event/ConsoleEvent.php | 67 + .../console/Event/ConsoleExceptionEvent.php | 67 + .../console/Event/ConsoleTerminateEvent.php | 58 + .../Exception/CommandNotFoundException.php | 43 + .../console/Exception/ExceptionInterface.php | 21 + .../Exception/InvalidArgumentException.php | 19 + .../Exception/InvalidOptionException.php | 21 + .../console/Exception/LogicException.php | 19 + .../console/Exception/RuntimeException.php | 19 + .../console/Formatter/OutputFormatter.php | 240 + .../Formatter/OutputFormatterInterface.php | 69 + .../Formatter/OutputFormatterStyle.php | 221 + .../OutputFormatterStyleInterface.php | 64 + .../Formatter/OutputFormatterStyleStack.php | 123 + .../console/Helper/DebugFormatterHelper.php | 127 + .../console/Helper/DescriptorHelper.php | 97 + .../console/Helper/FormatterHelper.php | 106 + .../vendor/symfony/console/Helper/Helper.php | 119 + .../console/Helper/HelperInterface.php | 41 + .../symfony/console/Helper/HelperSet.php | 115 + .../console/Helper/InputAwareHelper.php | 33 + .../symfony/console/Helper/ProcessHelper.php | 144 + .../symfony/console/Helper/ProgressBar.php | 600 +++ .../console/Helper/ProgressIndicator.php | 288 ++ .../symfony/console/Helper/QuestionHelper.php | 447 ++ .../console/Helper/SymfonyQuestionHelper.php | 120 + .../vendor/symfony/console/Helper/Table.php | 705 +++ .../symfony/console/Helper/TableCell.php | 79 + .../symfony/console/Helper/TableSeparator.php | 28 + .../symfony/console/Helper/TableStyle.php | 258 + .../symfony/console/Input/ArgvInput.php | 347 ++ .../symfony/console/Input/ArrayInput.php | 204 + .../vendor/symfony/console/Input/Input.php | 194 + .../symfony/console/Input/InputArgument.php | 131 + .../console/Input/InputAwareInterface.php | 28 + .../symfony/console/Input/InputDefinition.php | 414 ++ .../symfony/console/Input/InputInterface.php | 159 + .../symfony/console/Input/InputOption.php | 212 + .../symfony/console/Input/StringInput.php | 74 + src/composer/vendor/symfony/console/LICENSE | 19 + .../symfony/console/Logger/ConsoleLogger.php | 119 + .../symfony/console/Output/BufferedOutput.php | 48 + .../symfony/console/Output/ConsoleOutput.php | 157 + .../console/Output/ConsoleOutputInterface.php | 35 + .../symfony/console/Output/NullOutput.php | 123 + .../vendor/symfony/console/Output/Output.php | 177 + .../console/Output/OutputInterface.php | 119 + .../symfony/console/Output/StreamOutput.php | 105 + .../console/Question/ChoiceQuestion.php | 187 + .../console/Question/ConfirmationQuestion.php | 61 + .../symfony/console/Question/Question.php | 250 + src/composer/vendor/symfony/console/README.md | 20 + .../console/Resources/bin/hiddeninput.exe | Bin 0 -> 9216 bytes .../symfony/console/Style/OutputStyle.php | 148 + .../symfony/console/Style/StyleInterface.php | 159 + .../symfony/console/Style/SymfonyStyle.php | 435 ++ .../console/Tester/ApplicationTester.php | 176 + .../symfony/console/Tester/CommandTester.php | 132 + .../symfony/console/Tests/ApplicationTest.php | 1201 +++++ .../console/Tests/Command/CommandTest.php | 360 ++ .../console/Tests/Command/HelpCommandTest.php | 70 + .../console/Tests/Command/ListCommandTest.php | 112 + .../Descriptor/AbstractDescriptorTest.php | 106 + .../Tests/Descriptor/JsonDescriptorTest.php | 35 + .../Descriptor/MarkdownDescriptorTest.php | 27 + .../Tests/Descriptor/ObjectsProvider.php | 77 + .../Tests/Descriptor/TextDescriptorTest.php | 27 + .../Tests/Descriptor/XmlDescriptorTest.php | 27 + .../console/Tests/Fixtures/BarBucCommand.php | 11 + .../Tests/Fixtures/DescriptorApplication1.php | 18 + .../Tests/Fixtures/DescriptorApplication2.php | 24 + .../Tests/Fixtures/DescriptorCommand1.php | 27 + .../Tests/Fixtures/DescriptorCommand2.php | 32 + .../console/Tests/Fixtures/DummyOutput.php | 36 + .../console/Tests/Fixtures/Foo1Command.php | 26 + .../console/Tests/Fixtures/Foo2Command.php | 21 + .../console/Tests/Fixtures/Foo3Command.php | 29 + .../console/Tests/Fixtures/Foo4Command.php | 11 + .../console/Tests/Fixtures/Foo5Command.php | 10 + .../console/Tests/Fixtures/Foo6Command.php | 12 + .../console/Tests/Fixtures/FooCommand.php | 33 + .../Fixtures/FooSubnamespaced1Command.php | 26 + .../Fixtures/FooSubnamespaced2Command.php | 26 + .../console/Tests/Fixtures/FoobarCommand.php | 25 + .../Style/SymfonyStyle/command/command_0.php | 11 + .../Style/SymfonyStyle/command/command_1.php | 13 + .../Style/SymfonyStyle/command/command_10.php | 17 + .../Style/SymfonyStyle/command/command_11.php | 12 + .../Style/SymfonyStyle/command/command_12.php | 13 + .../Style/SymfonyStyle/command/command_13.php | 15 + .../Style/SymfonyStyle/command/command_14.php | 17 + .../Style/SymfonyStyle/command/command_15.php | 14 + .../Style/SymfonyStyle/command/command_16.php | 15 + .../Style/SymfonyStyle/command/command_2.php | 16 + .../Style/SymfonyStyle/command/command_3.php | 12 + .../Style/SymfonyStyle/command/command_4.php | 34 + .../Style/SymfonyStyle/command/command_5.php | 37 + .../Style/SymfonyStyle/command/command_6.php | 16 + .../Style/SymfonyStyle/command/command_7.php | 15 + .../Style/SymfonyStyle/command/command_8.php | 26 + .../Style/SymfonyStyle/command/command_9.php | 11 + .../Style/SymfonyStyle/output/output_0.txt | 3 + .../Style/SymfonyStyle/output/output_1.txt | 9 + .../Style/SymfonyStyle/output/output_10.txt | 7 + .../Style/SymfonyStyle/output/output_11.txt | 4 + .../Style/SymfonyStyle/output/output_12.txt | 6 + .../Style/SymfonyStyle/output/output_13.txt | 7 + .../Style/SymfonyStyle/output/output_14.txt | 6 + .../Style/SymfonyStyle/output/output_15.txt | 7 + .../Style/SymfonyStyle/output/output_16.txt | 8 + .../Style/SymfonyStyle/output/output_2.txt | 13 + .../Style/SymfonyStyle/output/output_3.txt | 7 + .../Style/SymfonyStyle/output/output_4.txt | 32 + .../Style/SymfonyStyle/output/output_5.txt | 18 + .../Style/SymfonyStyle/output/output_6.txt | 6 + .../Style/SymfonyStyle/output/output_7.txt | 5 + .../Style/SymfonyStyle/output/output_8.txt | 9 + .../Style/SymfonyStyle/output/output_9.txt | 5 + .../console/Tests/Fixtures/TestCommand.php | 28 + .../console/Tests/Fixtures/application_1.json | 154 + .../console/Tests/Fixtures/application_1.md | 181 + .../console/Tests/Fixtures/application_1.txt | 17 + .../console/Tests/Fixtures/application_1.xml | 104 + .../console/Tests/Fixtures/application_2.json | 336 ++ .../console/Tests/Fixtures/application_2.md | 376 ++ .../console/Tests/Fixtures/application_2.txt | 22 + .../console/Tests/Fixtures/application_2.xml | 184 + .../Tests/Fixtures/application_gethelp.txt | 1 + .../Fixtures/application_renderexception1.txt | 6 + .../Fixtures/application_renderexception2.txt | 8 + .../Fixtures/application_renderexception3.txt | 18 + .../application_renderexception3decorated.txt | 18 + .../Fixtures/application_renderexception4.txt | 7 + ...plication_renderexception_doublewidth1.txt | 8 + ..._renderexception_doublewidth1decorated.txt | 8 + ...plication_renderexception_doublewidth2.txt | 9 + .../Tests/Fixtures/application_run1.txt | 17 + .../Tests/Fixtures/application_run2.txt | 28 + .../Tests/Fixtures/application_run3.txt | 26 + .../Tests/Fixtures/application_run4.txt | 1 + .../console/Tests/Fixtures/command_1.json | 14 + .../console/Tests/Fixtures/command_1.md | 11 + .../console/Tests/Fixtures/command_1.txt | 7 + .../console/Tests/Fixtures/command_1.xml | 12 + .../console/Tests/Fixtures/command_2.json | 32 + .../console/Tests/Fixtures/command_2.md | 33 + .../console/Tests/Fixtures/command_2.txt | 13 + .../console/Tests/Fixtures/command_2.xml | 21 + .../Tests/Fixtures/input_argument_1.json | 7 + .../Tests/Fixtures/input_argument_1.md | 7 + .../Tests/Fixtures/input_argument_1.txt | 1 + .../Tests/Fixtures/input_argument_1.xml | 5 + .../Tests/Fixtures/input_argument_2.json | 7 + .../Tests/Fixtures/input_argument_2.md | 7 + .../Tests/Fixtures/input_argument_2.txt | 1 + .../Tests/Fixtures/input_argument_2.xml | 5 + .../Tests/Fixtures/input_argument_3.json | 7 + .../Tests/Fixtures/input_argument_3.md | 7 + .../Tests/Fixtures/input_argument_3.txt | 1 + .../Tests/Fixtures/input_argument_3.xml | 7 + .../Tests/Fixtures/input_argument_4.json | 7 + .../Tests/Fixtures/input_argument_4.md | 8 + .../Tests/Fixtures/input_argument_4.txt | 2 + .../Tests/Fixtures/input_argument_4.xml | 6 + .../Tests/Fixtures/input_definition_1.json | 4 + .../Tests/Fixtures/input_definition_1.md | 0 .../Tests/Fixtures/input_definition_1.txt | 0 .../Tests/Fixtures/input_definition_1.xml | 5 + .../Tests/Fixtures/input_definition_2.json | 12 + .../Tests/Fixtures/input_definition_2.md | 9 + .../Tests/Fixtures/input_definition_2.txt | 2 + .../Tests/Fixtures/input_definition_2.xml | 10 + .../Tests/Fixtures/input_definition_3.json | 14 + .../Tests/Fixtures/input_definition_3.md | 11 + .../Tests/Fixtures/input_definition_3.txt | 2 + .../Tests/Fixtures/input_definition_3.xml | 9 + .../Tests/Fixtures/input_definition_4.json | 22 + .../Tests/Fixtures/input_definition_4.md | 21 + .../Tests/Fixtures/input_definition_4.txt | 5 + .../Tests/Fixtures/input_definition_4.xml | 14 + .../Tests/Fixtures/input_option_1.json | 9 + .../console/Tests/Fixtures/input_option_1.md | 9 + .../console/Tests/Fixtures/input_option_1.txt | 1 + .../console/Tests/Fixtures/input_option_1.xml | 4 + .../Tests/Fixtures/input_option_2.json | 9 + .../console/Tests/Fixtures/input_option_2.md | 9 + .../console/Tests/Fixtures/input_option_2.txt | 1 + .../console/Tests/Fixtures/input_option_2.xml | 7 + .../Tests/Fixtures/input_option_3.json | 9 + .../console/Tests/Fixtures/input_option_3.md | 9 + .../console/Tests/Fixtures/input_option_3.txt | 1 + .../console/Tests/Fixtures/input_option_3.xml | 5 + .../Tests/Fixtures/input_option_4.json | 9 + .../console/Tests/Fixtures/input_option_4.md | 9 + .../console/Tests/Fixtures/input_option_4.txt | 1 + .../console/Tests/Fixtures/input_option_4.xml | 5 + .../Tests/Fixtures/input_option_5.json | 9 + .../console/Tests/Fixtures/input_option_5.md | 10 + .../console/Tests/Fixtures/input_option_5.txt | 2 + .../console/Tests/Fixtures/input_option_5.xml | 6 + .../Tests/Fixtures/input_option_6.json | 9 + .../console/Tests/Fixtures/input_option_6.md | 9 + .../console/Tests/Fixtures/input_option_6.txt | 1 + .../console/Tests/Fixtures/input_option_6.xml | 5 + .../OutputFormatterStyleStackTest.php | 70 + .../Formatter/OutputFormatterStyleTest.php | 99 + .../Tests/Formatter/OutputFormatterTest.php | 273 ++ .../Tests/Helper/FormatterHelperTest.php | 128 + .../console/Tests/Helper/HelperSetTest.php | 126 + .../console/Tests/Helper/HelperTest.php | 54 + .../Tests/Helper/ProcessHelperTest.php | 117 + .../console/Tests/Helper/ProgressBarTest.php | 664 +++ .../Tests/Helper/ProgressIndicatorTest.php | 182 + .../Tests/Helper/QuestionHelperTest.php | 435 ++ .../Helper/SymfonyQuestionHelperTest.php | 137 + .../console/Tests/Helper/TableStyleTest.php | 27 + .../console/Tests/Helper/TableTest.php | 727 +++ .../console/Tests/Input/ArgvInputTest.php | 384 ++ .../console/Tests/Input/ArrayInputTest.php | 159 + .../console/Tests/Input/InputArgumentTest.php | 111 + .../Tests/Input/InputDefinitionTest.php | 405 ++ .../console/Tests/Input/InputOptionTest.php | 204 + .../symfony/console/Tests/Input/InputTest.php | 132 + .../console/Tests/Input/StringInputTest.php | 86 + .../Tests/Logger/ConsoleLoggerTest.php | 58 + .../Tests/Output/ConsoleOutputTest.php | 25 + .../console/Tests/Output/NullOutputTest.php | 39 + .../console/Tests/Output/OutputTest.php | 175 + .../console/Tests/Output/StreamOutputTest.php | 60 + .../console/Tests/Style/SymfonyStyleTest.php | 73 + .../Tests/Tester/ApplicationTesterTest.php | 69 + .../Tests/Tester/CommandTesterTest.php | 84 + .../vendor/symfony/console/composer.json | 45 + .../vendor/symfony/console/phpunit.xml.dist | 39 + src/composer/vendor/symfony/debug/.gitignore | 3 + .../vendor/symfony/debug/BufferingLogger.php | 37 + .../vendor/symfony/debug/CHANGELOG.md | 47 + src/composer/vendor/symfony/debug/Debug.php | 63 + .../vendor/symfony/debug/DebugClassLoader.php | 314 ++ .../vendor/symfony/debug/ErrorHandler.php | 666 +++ .../Exception/ClassNotFoundException.php | 33 + .../debug/Exception/ContextErrorException.php | 36 + .../debug/Exception/FatalErrorException.php | 82 + .../debug/Exception/FatalThrowableError.php | 44 + .../debug/Exception/FlattenException.php | 256 + .../debug/Exception/OutOfMemoryException.php | 21 + .../Exception/UndefinedFunctionException.php | 33 + .../Exception/UndefinedMethodException.php | 33 + .../vendor/symfony/debug/ExceptionHandler.php | 415 ++ .../ClassNotFoundFatalErrorHandler.php | 206 + .../FatalErrorHandlerInterface.php | 32 + .../UndefinedFunctionFatalErrorHandler.php | 84 + .../UndefinedMethodFatalErrorHandler.php | 60 + src/composer/vendor/symfony/debug/LICENSE | 19 + src/composer/vendor/symfony/debug/README.md | 13 + .../symfony/debug/Resources/ext/README.md | 134 + .../symfony/debug/Resources/ext/config.m4 | 63 + .../symfony/debug/Resources/ext/config.w32 | 13 + .../debug/Resources/ext/php_symfony_debug.h | 60 + .../debug/Resources/ext/symfony_debug.c | 283 ++ .../debug/Resources/ext/tests/001.phpt | 151 + .../debug/Resources/ext/tests/002.phpt | 64 + .../debug/Resources/ext/tests/002_1.phpt | 47 + .../debug/Resources/ext/tests/003.phpt | 85 + .../debug/Tests/DebugClassLoaderTest.php | 315 ++ .../symfony/debug/Tests/ErrorHandlerTest.php | 509 ++ .../Tests/Exception/FlattenExceptionTest.php | 270 ++ .../debug/Tests/ExceptionHandlerTest.php | 132 + .../ClassNotFoundFatalErrorHandlerTest.php | 178 + ...UndefinedFunctionFatalErrorHandlerTest.php | 80 + .../UndefinedMethodFatalErrorHandlerTest.php | 66 + .../debug/Tests/Fixtures/ClassAlias.php | 3 + .../debug/Tests/Fixtures/DeprecatedClass.php | 12 + .../Tests/Fixtures/DeprecatedInterface.php | 12 + .../Tests/Fixtures/NonDeprecatedInterface.php | 7 + .../debug/Tests/Fixtures/PEARClass.php | 5 + .../debug/Tests/Fixtures/ToStringThrower.php | 24 + .../debug/Tests/Fixtures/casemismatch.php | 7 + .../debug/Tests/Fixtures/notPsr0Bis.php | 7 + .../Tests/Fixtures/psr4/Psr4CaseMismatch.php | 7 + .../debug/Tests/Fixtures/reallyNotPsr0.php | 7 + .../debug/Tests/Fixtures2/RequiredTwice.php | 7 + .../vendor/symfony/debug/Tests/HeaderMock.php | 38 + .../debug/Tests/MockExceptionHandler.php | 24 + .../vendor/symfony/debug/composer.json | 41 + .../vendor/symfony/debug/phpunit.xml.dist | 31 + .../symfony/event-dispatcher/.gitignore | 3 + .../symfony/event-dispatcher/CHANGELOG.md | 32 + .../ContainerAwareEventDispatcher.php | 195 + .../Debug/TraceableEventDispatcher.php | 372 ++ .../TraceableEventDispatcherInterface.php | 34 + .../Debug/WrappedListener.php | 71 + .../RegisterListenersPass.php | 113 + .../vendor/symfony/event-dispatcher/Event.php | 58 + .../event-dispatcher/EventDispatcher.php | 188 + .../EventDispatcherInterface.php | 100 + .../EventSubscriberInterface.php | 46 + .../symfony/event-dispatcher/GenericEvent.php | 186 + .../ImmutableEventDispatcher.php | 101 + .../vendor/symfony/event-dispatcher/LICENSE | 19 + .../vendor/symfony/event-dispatcher/README.md | 15 + .../Tests/AbstractEventDispatcherTest.php | 373 ++ .../ContainerAwareEventDispatcherTest.php | 207 + .../Debug/TraceableEventDispatcherTest.php | 216 + .../RegisterListenersPassTest.php | 200 + .../Tests/EventDispatcherTest.php | 22 + .../event-dispatcher/Tests/EventTest.php | 54 + .../Tests/GenericEventTest.php | 139 + .../Tests/ImmutableEventDispatcherTest.php | 105 + .../symfony/event-dispatcher/composer.json | 44 + .../symfony/event-dispatcher/phpunit.xml.dist | 29 + .../vendor/symfony/filesystem/.gitignore | 3 + .../vendor/symfony/filesystem/CHANGELOG.md | 38 + .../Exception/ExceptionInterface.php | 21 + .../Exception/FileNotFoundException.php | 34 + .../filesystem/Exception/IOException.php | 39 + .../Exception/IOExceptionInterface.php | 27 + .../vendor/symfony/filesystem/Filesystem.php | 594 +++ .../vendor/symfony/filesystem/LICENSE | 19 + .../vendor/symfony/filesystem/LockHandler.php | 112 + .../vendor/symfony/filesystem/README.md | 13 + .../filesystem/Tests/ExceptionTest.php | 46 + .../filesystem/Tests/FilesystemTest.php | 1174 +++++ .../filesystem/Tests/FilesystemTestCase.php | 128 + .../Tests/Fixtures/MockStream/MockStream.php | 46 + .../filesystem/Tests/LockHandlerTest.php | 100 + .../vendor/symfony/filesystem/composer.json | 33 + .../symfony/filesystem/phpunit.xml.dist | 28 + src/composer/vendor/symfony/finder/.gitignore | 3 + .../vendor/symfony/finder/CHANGELOG.md | 44 + .../symfony/finder/Comparator/Comparator.php | 98 + .../finder/Comparator/DateComparator.php | 53 + .../finder/Comparator/NumberComparator.php | 81 + .../Exception/AccessDeniedException.php | 19 + .../finder/Exception/ExceptionInterface.php | 23 + src/composer/vendor/symfony/finder/Finder.php | 716 +++ src/composer/vendor/symfony/finder/Glob.php | 104 + .../finder/Iterator/CustomFilterIterator.php | 63 + .../Iterator/DateRangeFilterIterator.php | 60 + .../Iterator/DepthRangeFilterIterator.php | 47 + .../ExcludeDirectoryFilterIterator.php | 86 + .../Iterator/FileTypeFilterIterator.php | 55 + .../Iterator/FilecontentFilterIterator.php | 58 + .../Iterator/FilenameFilterIterator.php | 47 + .../finder/Iterator/FilterIterator.php | 58 + .../Iterator/MultiplePcreFilterIterator.php | 114 + .../finder/Iterator/PathFilterIterator.php | 56 + .../Iterator/RecursiveDirectoryIterator.php | 156 + .../Iterator/SizeRangeFilterIterator.php | 59 + .../finder/Iterator/SortableIterator.php | 82 + src/composer/vendor/symfony/finder/LICENSE | 19 + src/composer/vendor/symfony/finder/README.md | 14 + .../vendor/symfony/finder/SplFileInfo.php | 81 + .../Tests/Comparator/ComparatorTest.php | 64 + .../Tests/Comparator/DateComparatorTest.php | 63 + .../Tests/Comparator/NumberComparatorTest.php | 107 + .../symfony/finder/Tests/FinderTest.php | 680 +++ .../finder/Tests/Fixtures/A/B/C/abc.dat | 0 .../symfony/finder/Tests/Fixtures/A/B/ab.dat | 0 .../symfony/finder/Tests/Fixtures/A/a.dat | 0 .../Tests/Fixtures/copy/A/B/C/abc.dat.copy | 0 .../Tests/Fixtures/copy/A/B/ab.dat.copy | 0 .../finder/Tests/Fixtures/copy/A/a.dat.copy | 0 .../symfony/finder/Tests/Fixtures/dolor.txt | 2 + .../symfony/finder/Tests/Fixtures/ipsum.txt | 2 + .../symfony/finder/Tests/Fixtures/lorem.txt | 2 + .../symfony/finder/Tests/Fixtures/one/a | 0 .../finder/Tests/Fixtures/one/b/c.neon | 0 .../finder/Tests/Fixtures/one/b/d.neon | 0 .../Fixtures/r+e.gex[c]a(r)s/dir/bar.dat | 0 .../finder/Tests/Fixtures/with space/foo.txt | 0 .../vendor/symfony/finder/Tests/GlobTest.php | 25 + .../Iterator/CustomFilterIteratorTest.php | 46 + .../Iterator/DateRangeFilterIteratorTest.php | 74 + .../Iterator/DepthRangeFilterIteratorTest.php | 83 + .../ExcludeDirectoryFilterIteratorTest.php | 80 + .../Iterator/FileTypeFilterIteratorTest.php | 73 + .../FilecontentFilterIteratorTest.php | 86 + .../Iterator/FilenameFilterIteratorTest.php | 54 + .../Tests/Iterator/FilterIteratorTest.php | 51 + .../finder/Tests/Iterator/Iterator.php | 55 + .../Tests/Iterator/IteratorTestCase.php | 98 + .../Tests/Iterator/MockFileListIterator.php | 21 + .../finder/Tests/Iterator/MockSplFileInfo.php | 132 + .../MultiplePcreFilterIteratorTest.php | 70 + .../Tests/Iterator/PathFilterIteratorTest.php | 83 + .../Tests/Iterator/RealIteratorTestCase.php | 110 + .../RecursiveDirectoryIteratorTest.php | 59 + .../Iterator/SizeRangeFilterIteratorTest.php | 69 + .../Tests/Iterator/SortableIteratorTest.php | 183 + .../vendor/symfony/finder/composer.json | 33 + .../vendor/symfony/finder/phpunit.xml.dist | 28 + .../vendor/symfony/polyfill-mbstring/LICENSE | 19 + .../symfony/polyfill-mbstring/Mbstring.php | 650 +++ .../symfony/polyfill-mbstring/README.md | 13 + .../Resources/unidata/lowerCase.php | 1101 +++++ .../Resources/unidata/upperCase.php | 1109 +++++ .../symfony/polyfill-mbstring/bootstrap.php | 56 + .../symfony/polyfill-mbstring/composer.json | 34 + .../vendor/symfony/process/.gitignore | 3 + .../vendor/symfony/process/CHANGELOG.md | 40 + .../process/Exception/ExceptionInterface.php | 21 + .../Exception/InvalidArgumentException.php | 21 + .../process/Exception/LogicException.php | 21 + .../Exception/ProcessFailedException.php | 54 + .../Exception/ProcessTimedOutException.php | 69 + .../process/Exception/RuntimeException.php | 21 + .../symfony/process/ExecutableFinder.php | 90 + .../vendor/symfony/process/InputStream.php | 90 + src/composer/vendor/symfony/process/LICENSE | 19 + .../symfony/process/PhpExecutableFinder.php | 90 + .../vendor/symfony/process/PhpProcess.php | 78 + .../symfony/process/Pipes/AbstractPipes.php | 169 + .../symfony/process/Pipes/PipesInterface.php | 67 + .../symfony/process/Pipes/UnixPipes.php | 153 + .../symfony/process/Pipes/WindowsPipes.php | 200 + .../vendor/symfony/process/Process.php | 1542 ++++++ .../vendor/symfony/process/ProcessBuilder.php | 284 ++ .../vendor/symfony/process/ProcessUtils.php | 119 + src/composer/vendor/symfony/process/README.md | 13 + .../process/Tests/ExecutableFinderTest.php | 132 + .../process/Tests/NonStopableProcess.php | 47 + .../process/Tests/PhpExecutableFinderTest.php | 71 + .../symfony/process/Tests/PhpProcessTest.php | 49 + .../PipeStdinInStdoutStdErrStreamSelect.php | 72 + .../process/Tests/ProcessBuilderTest.php | 225 + .../Tests/ProcessFailedExceptionTest.php | 146 + .../symfony/process/Tests/ProcessTest.php | 1415 ++++++ .../process/Tests/ProcessUtilsTest.php | 48 + .../symfony/process/Tests/SignalListener.php | 21 + .../vendor/symfony/process/composer.json | 33 + .../vendor/symfony/process/phpunit.xml.dist | 28 + src/composer/vendor/symfony/yaml/.gitignore | 3 + src/composer/vendor/symfony/yaml/CHANGELOG.md | 67 + src/composer/vendor/symfony/yaml/Dumper.php | 114 + src/composer/vendor/symfony/yaml/Escaper.php | 99 + .../symfony/yaml/Exception/DumpException.php | 21 + .../yaml/Exception/ExceptionInterface.php | 21 + .../symfony/yaml/Exception/ParseException.php | 141 + .../yaml/Exception/RuntimeException.php | 21 + src/composer/vendor/symfony/yaml/Inline.php | 688 +++ src/composer/vendor/symfony/yaml/LICENSE | 19 + src/composer/vendor/symfony/yaml/Parser.php | 845 ++++ src/composer/vendor/symfony/yaml/README.md | 13 + .../vendor/symfony/yaml/Tests/DumperTest.php | 370 ++ .../yaml/Tests/Fixtures/YtsAnchorAlias.yml | 31 + .../yaml/Tests/Fixtures/YtsBasicTests.yml | 202 + .../yaml/Tests/Fixtures/YtsBlockMapping.yml | 51 + .../Tests/Fixtures/YtsDocumentSeparator.yml | 85 + .../yaml/Tests/Fixtures/YtsErrorTests.yml | 25 + .../Tests/Fixtures/YtsFlowCollections.yml | 60 + .../yaml/Tests/Fixtures/YtsFoldedScalars.yml | 176 + .../Tests/Fixtures/YtsNullsAndEmpties.yml | 45 + .../Fixtures/YtsSpecificationExamples.yml | 1697 +++++++ .../yaml/Tests/Fixtures/YtsTypeTransfers.yml | 244 + .../symfony/yaml/Tests/Fixtures/arrow.gif | Bin 0 -> 185 bytes .../yaml/Tests/Fixtures/embededPhp.yml | 1 + .../yaml/Tests/Fixtures/escapedCharacters.yml | 155 + .../symfony/yaml/Tests/Fixtures/index.yml | 18 + .../multiple_lines_as_literal_block.yml | 14 + .../yaml/Tests/Fixtures/sfComments.yml | 76 + .../symfony/yaml/Tests/Fixtures/sfCompact.yml | 159 + .../yaml/Tests/Fixtures/sfMergeKey.yml | 58 + .../symfony/yaml/Tests/Fixtures/sfObjects.yml | 11 + .../symfony/yaml/Tests/Fixtures/sfQuotes.yml | 33 + .../symfony/yaml/Tests/Fixtures/sfTests.yml | 149 + .../Tests/Fixtures/unindentedCollections.yml | 82 + .../vendor/symfony/yaml/Tests/InlineTest.php | 598 +++ .../symfony/yaml/Tests/ParseExceptionTest.php | 33 + .../vendor/symfony/yaml/Tests/ParserTest.php | 1338 ++++++ .../vendor/symfony/yaml/Tests/YamlTest.php | 43 + .../vendor/symfony/yaml/Unescaper.php | 142 + src/composer/vendor/symfony/yaml/Yaml.php | 118 + .../vendor/symfony/yaml/composer.json | 33 + .../vendor/symfony/yaml/phpunit.xml.dist | 28 + .../victorjonsson/markdowndocs/.travis.yml | 9 + .../victorjonsson/markdowndocs/README.md | 96 + .../victorjonsson/markdowndocs/bin/phpdoc-md | 17 + .../victorjonsson/markdowndocs/composer.json | 23 + .../vendor/victorjonsson/markdowndocs/docs.md | 251 + .../victorjonsson/markdowndocs/phpdoc-md | 17 + .../victorjonsson/markdowndocs/phpunit.xml | 7 + .../src/PHPDocsMD/ClassEntity.php | 202 + .../src/PHPDocsMD/ClassEntityFactory.php | 40 + .../markdowndocs/src/PHPDocsMD/CodeEntity.php | 113 + .../src/PHPDocsMD/Console/CLI.php | 31 + .../PHPDocsMD/Console/PHPDocsMDCommand.php | 288 ++ .../markdowndocs/src/PHPDocsMD/DocInfo.php | 99 + .../src/PHPDocsMD/DocInfoExtractor.php | 174 + .../src/PHPDocsMD/FunctionEntity.php | 154 + .../src/PHPDocsMD/FunctionFinder.php | 66 + .../src/PHPDocsMD/MDTableGenerator.php | 204 + .../src/PHPDocsMD/ParamEntity.php | 66 + .../markdowndocs/src/PHPDocsMD/Reflector.php | 417 ++ .../src/PHPDocsMD/ReflectorInterface.php | 16 + .../src/PHPDocsMD/UseInspector.php | 50 + .../markdowndocs/src/PHPDocsMD/Utils.php | 96 + .../markdowndocs/test/ExampleClass.php | 157 + .../test/MDTableGeneratorTest.php | 123 + .../markdowndocs/test/ReflectorTest.php | 160 + .../markdowndocs/test/UseInspectorTest.php | 42 + .../webmozart/assert/.composer-auth.json | 7 + .../vendor/webmozart/assert/.gitignore | 2 + .../vendor/webmozart/assert/.styleci.yml | 7 + .../vendor/webmozart/assert/.travis.yml | 35 + .../vendor/webmozart/assert/CHANGELOG.md | 28 + src/composer/vendor/webmozart/assert/LICENSE | 20 + .../vendor/webmozart/assert/README.md | 235 + .../vendor/webmozart/assert/appveyor.yml | 36 + .../vendor/webmozart/assert/composer.json | 34 + .../vendor/webmozart/assert/phpunit.xml.dist | 16 + .../vendor/webmozart/assert/src/Assert.php | 903 ++++ .../webmozart/assert/tests/AssertTest.php | 422 ++ src/config.base.php | 11 +- src/data.php | 2 +- src/db_migrations/list.php | 3 + ...20161116_190001_unique_index_cron_name.php | 23 + src/fileupload_page.php | 10 +- src/model/models.inc.php | 3 + src/readme | 18 + src/robo/RoboFile.php | 51 + src/robo/robo.phar | Bin 0 -> 2314826 bytes src/scripts/ice_frameworkdb.sql | 14 + src/server.includes.inc.php | 7 +- src/templates/fields/fileupload.html | 2 +- src/templates/menu/menuButtonHelp.html | 2 +- src/utils/LogManager.php | 4 +- test/TestTemplate.php | 20 +- test/admin/UsersActionManagerTest.php | 31 - test/bootstrap.php | 20 +- test/classes/FileServiceTest.php | 21 + test/classes/LanguageManagerTest.php | 37 + test/data/sample.txt | 1 + test/smtp.txt | 4 + test/test.config.php | 37 +- 2417 files changed, 228307 insertions(+), 246 deletions(-) create mode 100644 .travis.yml create mode 100644 Vagrantfile create mode 100644 deployment/clients/dev/config.php create mode 100644 deployment/clients/dev/cron.php create mode 100644 deployment/clients/dev/data.php create mode 100755 deployment/clients/dev/data/sample create mode 100644 deployment/clients/dev/entry.php create mode 100644 deployment/clients/dev/fileupload.php create mode 100644 deployment/clients/dev/fileupload_page.php create mode 100644 deployment/clients/dev/header.php create mode 100644 deployment/clients/dev/index.php create mode 100644 deployment/clients/dev/login.php create mode 100644 deployment/clients/dev/logout.php create mode 100644 deployment/clients/dev/rest.php create mode 100644 deployment/clients/dev/service.php create mode 100644 deployment/clients/dev/update.php create mode 100644 deployment/clients/test/config.php create mode 100644 deployment/clients/test/cron.php create mode 100644 deployment/clients/test/data.php create mode 100755 deployment/clients/test/data/sample create mode 100644 deployment/clients/test/entry.php create mode 100644 deployment/clients/test/fileupload.php create mode 100644 deployment/clients/test/fileupload_page.php create mode 100644 deployment/clients/test/header.php create mode 100644 deployment/clients/test/index.php create mode 100644 deployment/clients/test/login.php create mode 100644 deployment/clients/test/logout.php create mode 100644 deployment/clients/test/rest.php create mode 100644 deployment/clients/test/service.php create mode 100644 deployment/clients/test/update.php create mode 100644 src/classes/Migration.php create mode 100644 src/classes/Validator.php create mode 120000 src/composer/vendor/bin/phpdoc-md create mode 120000 src/composer/vendor/bin/phpunit create mode 120000 src/composer/vendor/bin/robo create mode 100644 src/composer/vendor/composer/autoload_files.php create mode 100644 src/composer/vendor/consolidation/annotated-command/.editorconfig create mode 100644 src/composer/vendor/consolidation/annotated-command/.github/issue_template.md create mode 100644 src/composer/vendor/consolidation/annotated-command/.github/pull_request_template.md create mode 100644 src/composer/vendor/consolidation/annotated-command/.gitignore create mode 100644 src/composer/vendor/consolidation/annotated-command/.travis.yml create mode 100644 src/composer/vendor/consolidation/annotated-command/CHANGELOG.md create mode 100644 src/composer/vendor/consolidation/annotated-command/CONTRIBUTING.md create mode 100644 src/composer/vendor/consolidation/annotated-command/LICENSE create mode 100644 src/composer/vendor/consolidation/annotated-command/README.md create mode 100644 src/composer/vendor/consolidation/annotated-command/composer.json create mode 100644 src/composer/vendor/consolidation/annotated-command/composer.lock create mode 100644 src/composer/vendor/consolidation/annotated-command/phpunit.xml.dist create mode 100644 src/composer/vendor/consolidation/annotated-command/src/AnnotatedCommand.php create mode 100644 src/composer/vendor/consolidation/annotated-command/src/AnnotatedCommandFactory.php create mode 100644 src/composer/vendor/consolidation/annotated-command/src/AnnotationData.php create mode 100644 src/composer/vendor/consolidation/annotated-command/src/CommandCreationListenerInterface.php create mode 100644 src/composer/vendor/consolidation/annotated-command/src/CommandData.php create mode 100644 src/composer/vendor/consolidation/annotated-command/src/CommandError.php create mode 100644 src/composer/vendor/consolidation/annotated-command/src/CommandFileDiscovery.php create mode 100644 src/composer/vendor/consolidation/annotated-command/src/CommandInfoAltererInterface.php create mode 100644 src/composer/vendor/consolidation/annotated-command/src/CommandProcessor.php create mode 100644 src/composer/vendor/consolidation/annotated-command/src/ExitCodeInterface.php create mode 100644 src/composer/vendor/consolidation/annotated-command/src/Hooks/AlterResultInterface.php create mode 100644 src/composer/vendor/consolidation/annotated-command/src/Hooks/ExtractOutputInterface.php create mode 100644 src/composer/vendor/consolidation/annotated-command/src/Hooks/HookManager.php create mode 100644 src/composer/vendor/consolidation/annotated-command/src/Hooks/InitializeHookInterface.php create mode 100644 src/composer/vendor/consolidation/annotated-command/src/Hooks/InteractorInterface.php create mode 100644 src/composer/vendor/consolidation/annotated-command/src/Hooks/OptionHookInterface.php create mode 100644 src/composer/vendor/consolidation/annotated-command/src/Hooks/ProcessResultInterface.php create mode 100644 src/composer/vendor/consolidation/annotated-command/src/Hooks/StatusDeterminerInterface.php create mode 100644 src/composer/vendor/consolidation/annotated-command/src/Hooks/ValidatorInterface.php create mode 100644 src/composer/vendor/consolidation/annotated-command/src/Options/AlterOptionsCommandEvent.php create mode 100644 src/composer/vendor/consolidation/annotated-command/src/Options/AutomaticOptionsProviderInterface.php create mode 100644 src/composer/vendor/consolidation/annotated-command/src/Options/PrepareFormatter.php create mode 100644 src/composer/vendor/consolidation/annotated-command/src/Options/PrepareTerminalWidthOption.php create mode 100644 src/composer/vendor/consolidation/annotated-command/src/OutputDataInterface.php create mode 100644 src/composer/vendor/consolidation/annotated-command/src/Parser/CommandInfo.php create mode 100644 src/composer/vendor/consolidation/annotated-command/src/Parser/DefaultsWithDescriptions.php create mode 100644 src/composer/vendor/consolidation/annotated-command/src/Parser/Internal/AbstractCommandDocBlockParser.php create mode 100644 src/composer/vendor/consolidation/annotated-command/src/Parser/Internal/CommandDocBlockParser2.php create mode 100644 src/composer/vendor/consolidation/annotated-command/src/Parser/Internal/CommandDocBlockParser3.php create mode 100644 src/composer/vendor/consolidation/annotated-command/src/Parser/Internal/CommandDocBlockParserFactory.php create mode 100644 src/composer/vendor/consolidation/annotated-command/tests/src/ApplicationWithTerminalWidth.php create mode 100644 src/composer/vendor/consolidation/annotated-command/tests/src/ExampleAnnotatedCommand.php create mode 100644 src/composer/vendor/consolidation/annotated-command/tests/src/ExampleCommandFile.php create mode 100644 src/composer/vendor/consolidation/annotated-command/tests/src/ExampleCommandInfoAlterer.php create mode 100644 src/composer/vendor/consolidation/annotated-command/tests/src/ExampleHookAllCommandFile.php create mode 100644 src/composer/vendor/consolidation/annotated-command/tests/src/alpha/AlphaCommandFile.php create mode 100644 src/composer/vendor/consolidation/annotated-command/tests/src/alpha/Exclude/ExcludedCommandFile.php create mode 100644 src/composer/vendor/consolidation/annotated-command/tests/src/alpha/Inclusive/IncludedCommandFile.php create mode 100644 src/composer/vendor/consolidation/annotated-command/tests/src/beta/BetaCommandFile.php create mode 100644 src/composer/vendor/consolidation/annotated-command/tests/testAnnotatedCommand.php create mode 100644 src/composer/vendor/consolidation/annotated-command/tests/testAnnotatedCommandFactory.php create mode 100644 src/composer/vendor/consolidation/annotated-command/tests/testCommandFileDiscovery.php create mode 100644 src/composer/vendor/consolidation/annotated-command/tests/testCommandInfo.php create mode 100644 src/composer/vendor/consolidation/annotated-command/tests/testFullStack.php create mode 100644 src/composer/vendor/consolidation/log/.gitignore create mode 100644 src/composer/vendor/consolidation/log/LICENSE create mode 100644 src/composer/vendor/consolidation/log/README.md create mode 100644 src/composer/vendor/consolidation/log/circle.yml create mode 100644 src/composer/vendor/consolidation/log/composer.json create mode 100644 src/composer/vendor/consolidation/log/phpunit.xml.dist create mode 100644 src/composer/vendor/consolidation/log/src/ConsoleLogLevel.php create mode 100644 src/composer/vendor/consolidation/log/src/LogOutputStyler.php create mode 100644 src/composer/vendor/consolidation/log/src/LogOutputStylerInterface.php create mode 100644 src/composer/vendor/consolidation/log/src/Logger.php create mode 100644 src/composer/vendor/consolidation/log/src/SymfonyLogOutputStyler.php create mode 100644 src/composer/vendor/consolidation/log/src/UnstyledLogOutputStyler.php create mode 100644 src/composer/vendor/consolidation/log/tests/src/TestDataPermuter.php create mode 100644 src/composer/vendor/consolidation/log/tests/testLogMethods.php create mode 100644 src/composer/vendor/consolidation/log/tests/testLoggerVerbosityAndStyles.php create mode 100644 src/composer/vendor/consolidation/output-formatters/.editorconfig create mode 100644 src/composer/vendor/consolidation/output-formatters/.github/issue_template.md create mode 100644 src/composer/vendor/consolidation/output-formatters/.github/pull_request_template.md create mode 100644 src/composer/vendor/consolidation/output-formatters/.gitignore create mode 100644 src/composer/vendor/consolidation/output-formatters/.travis.yml create mode 100644 src/composer/vendor/consolidation/output-formatters/CHANGELOG.md create mode 100644 src/composer/vendor/consolidation/output-formatters/CONTRIBUTING.md create mode 100644 src/composer/vendor/consolidation/output-formatters/LICENSE create mode 100644 src/composer/vendor/consolidation/output-formatters/README.md create mode 100644 src/composer/vendor/consolidation/output-formatters/composer.json create mode 100644 src/composer/vendor/consolidation/output-formatters/docs/api.md create mode 100644 src/composer/vendor/consolidation/output-formatters/docs/index.md create mode 100644 src/composer/vendor/consolidation/output-formatters/mkdocs.yml create mode 100644 src/composer/vendor/consolidation/output-formatters/phpunit.xml.dist create mode 100644 src/composer/vendor/consolidation/output-formatters/src/Exception/AbstractDataFormatException.php create mode 100644 src/composer/vendor/consolidation/output-formatters/src/Exception/IncompatibleDataException.php create mode 100644 src/composer/vendor/consolidation/output-formatters/src/Exception/InvalidFormatException.php create mode 100644 src/composer/vendor/consolidation/output-formatters/src/Exception/UnknownFieldException.php create mode 100644 src/composer/vendor/consolidation/output-formatters/src/Exception/UnknownFormatException.php create mode 100644 src/composer/vendor/consolidation/output-formatters/src/FormatterManager.php create mode 100644 src/composer/vendor/consolidation/output-formatters/src/Formatters/CsvFormatter.php create mode 100644 src/composer/vendor/consolidation/output-formatters/src/Formatters/FormatterInterface.php create mode 100644 src/composer/vendor/consolidation/output-formatters/src/Formatters/JsonFormatter.php create mode 100644 src/composer/vendor/consolidation/output-formatters/src/Formatters/ListFormatter.php create mode 100644 src/composer/vendor/consolidation/output-formatters/src/Formatters/PrintRFormatter.php create mode 100644 src/composer/vendor/consolidation/output-formatters/src/Formatters/RenderDataInterface.php create mode 100644 src/composer/vendor/consolidation/output-formatters/src/Formatters/RenderTableDataTrait.php create mode 100644 src/composer/vendor/consolidation/output-formatters/src/Formatters/SectionsFormatter.php create mode 100644 src/composer/vendor/consolidation/output-formatters/src/Formatters/SerializeFormatter.php create mode 100644 src/composer/vendor/consolidation/output-formatters/src/Formatters/StringFormatter.php create mode 100644 src/composer/vendor/consolidation/output-formatters/src/Formatters/TableFormatter.php create mode 100644 src/composer/vendor/consolidation/output-formatters/src/Formatters/TsvFormatter.php create mode 100644 src/composer/vendor/consolidation/output-formatters/src/Formatters/VarExportFormatter.php create mode 100644 src/composer/vendor/consolidation/output-formatters/src/Formatters/XmlFormatter.php create mode 100644 src/composer/vendor/consolidation/output-formatters/src/Formatters/YamlFormatter.php create mode 100644 src/composer/vendor/consolidation/output-formatters/src/Options/FormatterOptions.php create mode 100644 src/composer/vendor/consolidation/output-formatters/src/Options/OverrideOptionsInterface.php create mode 100644 src/composer/vendor/consolidation/output-formatters/src/StructuredData/AbstractStructuredList.php create mode 100644 src/composer/vendor/consolidation/output-formatters/src/StructuredData/AssociativeList.php create mode 100644 src/composer/vendor/consolidation/output-formatters/src/StructuredData/CallableRenderer.php create mode 100644 src/composer/vendor/consolidation/output-formatters/src/StructuredData/ListDataInterface.php create mode 100644 src/composer/vendor/consolidation/output-formatters/src/StructuredData/OriginalDataInterface.php create mode 100644 src/composer/vendor/consolidation/output-formatters/src/StructuredData/PropertyList.php create mode 100644 src/composer/vendor/consolidation/output-formatters/src/StructuredData/RenderCellCollectionInterface.php create mode 100644 src/composer/vendor/consolidation/output-formatters/src/StructuredData/RenderCellCollectionTrait.php create mode 100644 src/composer/vendor/consolidation/output-formatters/src/StructuredData/RenderCellInterface.php create mode 100644 src/composer/vendor/consolidation/output-formatters/src/StructuredData/RestructureInterface.php create mode 100644 src/composer/vendor/consolidation/output-formatters/src/StructuredData/RowsOfFields.php create mode 100644 src/composer/vendor/consolidation/output-formatters/src/StructuredData/TableDataInterface.php create mode 100644 src/composer/vendor/consolidation/output-formatters/src/StructuredData/Xml/DomDataInterface.php create mode 100644 src/composer/vendor/consolidation/output-formatters/src/StructuredData/Xml/XmlSchema.php create mode 100644 src/composer/vendor/consolidation/output-formatters/src/StructuredData/Xml/XmlSchemaInterface.php create mode 100644 src/composer/vendor/consolidation/output-formatters/src/Transformations/DomToArraySimplifier.php create mode 100644 src/composer/vendor/consolidation/output-formatters/src/Transformations/OverrideRestructureInterface.php create mode 100644 src/composer/vendor/consolidation/output-formatters/src/Transformations/PropertyListTableTransformation.php create mode 100644 src/composer/vendor/consolidation/output-formatters/src/Transformations/PropertyParser.php create mode 100644 src/composer/vendor/consolidation/output-formatters/src/Transformations/ReorderFields.php create mode 100644 src/composer/vendor/consolidation/output-formatters/src/Transformations/SimplifyToArrayInterface.php create mode 100644 src/composer/vendor/consolidation/output-formatters/src/Transformations/TableTransformation.php create mode 100644 src/composer/vendor/consolidation/output-formatters/src/Transformations/WordWrapper.php create mode 100644 src/composer/vendor/consolidation/output-formatters/src/Validate/ValidDataTypesInterface.php create mode 100644 src/composer/vendor/consolidation/output-formatters/src/Validate/ValidDataTypesTrait.php create mode 100644 src/composer/vendor/consolidation/output-formatters/src/Validate/ValidationInterface.php create mode 100644 src/composer/vendor/consolidation/output-formatters/tests/src/PropertyListWithCsvCells.php create mode 100644 src/composer/vendor/consolidation/output-formatters/tests/src/RowsOfFieldsWithAlternatives.php create mode 100644 src/composer/vendor/consolidation/output-formatters/tests/testAPIDocs.php create mode 100644 src/composer/vendor/consolidation/output-formatters/tests/testFormatterOptions.php create mode 100644 src/composer/vendor/consolidation/output-formatters/tests/testFormatters.php create mode 100644 src/composer/vendor/consolidation/output-formatters/tests/testIncompatibleData.php create mode 100644 src/composer/vendor/consolidation/output-formatters/tests/testValidFormats.php create mode 100644 src/composer/vendor/consolidation/robo/.editorconfig create mode 100644 src/composer/vendor/consolidation/robo/.github/issue_template.md create mode 100644 src/composer/vendor/consolidation/robo/.github/pull_request_template.md create mode 100644 src/composer/vendor/consolidation/robo/.gitignore create mode 100644 src/composer/vendor/consolidation/robo/.scrutinizer.yml create mode 100644 src/composer/vendor/consolidation/robo/.travis.yml create mode 100644 src/composer/vendor/consolidation/robo/CHANGELOG.md create mode 100644 src/composer/vendor/consolidation/robo/CONTRIBUTING.md create mode 100644 src/composer/vendor/consolidation/robo/LICENSE create mode 100644 src/composer/vendor/consolidation/robo/README.md create mode 100644 src/composer/vendor/consolidation/robo/RoboFile.php create mode 100644 src/composer/vendor/consolidation/robo/codeception.yml create mode 100644 src/composer/vendor/consolidation/robo/composer.json create mode 100644 src/composer/vendor/consolidation/robo/composer.lock create mode 100644 src/composer/vendor/consolidation/robo/data/Task/Development/GeneratedWrapper.tmpl create mode 100644 src/composer/vendor/consolidation/robo/docs/collections.md create mode 100644 src/composer/vendor/consolidation/robo/docs/extending.md create mode 100644 src/composer/vendor/consolidation/robo/docs/framework.md create mode 100644 src/composer/vendor/consolidation/robo/docs/getting-started.md create mode 100644 src/composer/vendor/consolidation/robo/docs/index.md create mode 100644 src/composer/vendor/consolidation/robo/docs/tasks/ApiGen.md create mode 100644 src/composer/vendor/consolidation/robo/docs/tasks/Archive.md create mode 100644 src/composer/vendor/consolidation/robo/docs/tasks/Assets.md create mode 100644 src/composer/vendor/consolidation/robo/docs/tasks/Base.md create mode 100644 src/composer/vendor/consolidation/robo/docs/tasks/Bower.md create mode 100644 src/composer/vendor/consolidation/robo/docs/tasks/Composer.md create mode 100644 src/composer/vendor/consolidation/robo/docs/tasks/Development.md create mode 100644 src/composer/vendor/consolidation/robo/docs/tasks/Docker.md create mode 100644 src/composer/vendor/consolidation/robo/docs/tasks/File.md create mode 100644 src/composer/vendor/consolidation/robo/docs/tasks/Filesystem.md create mode 100644 src/composer/vendor/consolidation/robo/docs/tasks/Gulp.md create mode 100644 src/composer/vendor/consolidation/robo/docs/tasks/Npm.md create mode 100644 src/composer/vendor/consolidation/robo/docs/tasks/Remote.md create mode 100644 src/composer/vendor/consolidation/robo/docs/tasks/Testing.md create mode 100644 src/composer/vendor/consolidation/robo/docs/tasks/Vcs.md create mode 100644 src/composer/vendor/consolidation/robo/examples/RoboFile.php create mode 100755 src/composer/vendor/consolidation/robo/examples/robo.script create mode 100755 src/composer/vendor/consolidation/robo/robo create mode 100644 src/composer/vendor/consolidation/robo/scripts/composer/ScriptHandler.php create mode 100644 src/composer/vendor/consolidation/robo/src/Application.php create mode 100644 src/composer/vendor/consolidation/robo/src/Collection/CallableTask.php create mode 100644 src/composer/vendor/consolidation/robo/src/Collection/Collection.php create mode 100644 src/composer/vendor/consolidation/robo/src/Collection/CollectionBuilder.php create mode 100644 src/composer/vendor/consolidation/robo/src/Collection/CollectionInterface.php create mode 100644 src/composer/vendor/consolidation/robo/src/Collection/CollectionProcessHook.php create mode 100644 src/composer/vendor/consolidation/robo/src/Collection/CompletionWrapper.php create mode 100644 src/composer/vendor/consolidation/robo/src/Collection/Element.php create mode 100644 src/composer/vendor/consolidation/robo/src/Collection/NestedCollectionInterface.php create mode 100644 src/composer/vendor/consolidation/robo/src/Collection/TaskForEach.php create mode 100644 src/composer/vendor/consolidation/robo/src/Collection/Temporary.php create mode 100644 src/composer/vendor/consolidation/robo/src/Collection/loadTasks.php create mode 100644 src/composer/vendor/consolidation/robo/src/Common/BuilderAwareTrait.php create mode 100644 src/composer/vendor/consolidation/robo/src/Common/CommandArguments.php create mode 100644 src/composer/vendor/consolidation/robo/src/Common/CommandReceiver.php create mode 100644 src/composer/vendor/consolidation/robo/src/Common/ConfigAwareTrait.php create mode 100644 src/composer/vendor/consolidation/robo/src/Common/DynamicParams.php create mode 100644 src/composer/vendor/consolidation/robo/src/Common/ExecCommand.php create mode 100644 src/composer/vendor/consolidation/robo/src/Common/ExecOneCommand.php create mode 100644 src/composer/vendor/consolidation/robo/src/Common/IO.php create mode 100644 src/composer/vendor/consolidation/robo/src/Common/InflectionTrait.php create mode 100644 src/composer/vendor/consolidation/robo/src/Common/InputAwareTrait.php create mode 100644 src/composer/vendor/consolidation/robo/src/Common/OutputAwareTrait.php create mode 100644 src/composer/vendor/consolidation/robo/src/Common/ProgressIndicator.php create mode 100644 src/composer/vendor/consolidation/robo/src/Common/ProgressIndicatorAwareTrait.php create mode 100644 src/composer/vendor/consolidation/robo/src/Common/ResourceExistenceChecker.php create mode 100644 src/composer/vendor/consolidation/robo/src/Common/TaskIO.php create mode 100644 src/composer/vendor/consolidation/robo/src/Common/TimeKeeper.php create mode 100644 src/composer/vendor/consolidation/robo/src/Common/Timer.php create mode 100644 src/composer/vendor/consolidation/robo/src/Config.php create mode 100644 src/composer/vendor/consolidation/robo/src/Contract/BuilderAwareInterface.php create mode 100644 src/composer/vendor/consolidation/robo/src/Contract/CommandInterface.php create mode 100644 src/composer/vendor/consolidation/robo/src/Contract/CompletionInterface.php create mode 100644 src/composer/vendor/consolidation/robo/src/Contract/ConfigAwareInterface.php create mode 100644 src/composer/vendor/consolidation/robo/src/Contract/IOAwareInterface.php create mode 100644 src/composer/vendor/consolidation/robo/src/Contract/InflectionInterface.php create mode 100644 src/composer/vendor/consolidation/robo/src/Contract/OutputAwareInterface.php create mode 100644 src/composer/vendor/consolidation/robo/src/Contract/PrintedInterface.php create mode 100644 src/composer/vendor/consolidation/robo/src/Contract/ProgressIndicatorAwareInterface.php create mode 100644 src/composer/vendor/consolidation/robo/src/Contract/ProgressInterface.php create mode 100644 src/composer/vendor/consolidation/robo/src/Contract/RollbackInterface.php create mode 100644 src/composer/vendor/consolidation/robo/src/Contract/SimulatedInterface.php create mode 100644 src/composer/vendor/consolidation/robo/src/Contract/TaskInterface.php create mode 100644 src/composer/vendor/consolidation/robo/src/Contract/WrappedTaskInterface.php create mode 100644 src/composer/vendor/consolidation/robo/src/Exception/TaskException.php create mode 100644 src/composer/vendor/consolidation/robo/src/Exception/TaskExitException.php create mode 100644 src/composer/vendor/consolidation/robo/src/GlobalOptionsEventListener.php create mode 100644 src/composer/vendor/consolidation/robo/src/LoadAllTasks.php create mode 100644 src/composer/vendor/consolidation/robo/src/Log/ResultPrinter.php create mode 100644 src/composer/vendor/consolidation/robo/src/Log/RoboLogLevel.php create mode 100644 src/composer/vendor/consolidation/robo/src/Log/RoboLogStyle.php create mode 100644 src/composer/vendor/consolidation/robo/src/Log/RoboLogger.php create mode 100644 src/composer/vendor/consolidation/robo/src/Result.php create mode 100644 src/composer/vendor/consolidation/robo/src/ResultData.php create mode 100644 src/composer/vendor/consolidation/robo/src/Robo.php create mode 100644 src/composer/vendor/consolidation/robo/src/Runner.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/ApiGen/ApiGen.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/ApiGen/loadTasks.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Archive/Extract.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Archive/Pack.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Archive/loadTasks.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Assets/CssPreprocessor.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Assets/ImageMinify.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Assets/Less.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Assets/Minify.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Assets/Scss.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Assets/loadTasks.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Base/Exec.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Base/ExecStack.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Base/ParallelExec.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Base/SymfonyCommand.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Base/Watch.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Base/loadShortcuts.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Base/loadTasks.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/BaseTask.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Bower/Base.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Bower/Install.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Bower/Update.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Bower/loadTasks.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/CommandStack.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Composer/Base.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Composer/DumpAutoload.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Composer/Install.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Composer/Remove.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Composer/Update.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Composer/Validate.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Composer/loadTasks.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Development/Changelog.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Development/GenerateMarkdownDoc.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Development/GenerateTask.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Development/GitHub.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Development/GitHubRelease.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Development/OpenBrowser.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Development/PackPhar.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Development/PhpServer.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Development/SemVer.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Development/loadTasks.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Docker/Base.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Docker/Build.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Docker/Commit.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Docker/Exec.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Docker/Pull.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Docker/Remove.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Docker/Result.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Docker/Run.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Docker/Start.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Docker/Stop.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Docker/loadTasks.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/File/Concat.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/File/Replace.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/File/TmpFile.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/File/Write.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/File/loadTasks.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Filesystem/BaseDir.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Filesystem/CleanDir.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Filesystem/CopyDir.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Filesystem/DeleteDir.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Filesystem/FilesystemStack.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Filesystem/FlattenDir.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Filesystem/MirrorDir.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Filesystem/TmpDir.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Filesystem/WorkDir.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Filesystem/loadShortcuts.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Filesystem/loadTasks.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Gulp/Base.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Gulp/Run.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Gulp/loadTasks.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Npm/Base.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Npm/Install.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Npm/Update.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Npm/loadTasks.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Remote/Rsync.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Remote/Ssh.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Remote/loadTasks.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Simulator.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/StackBasedTask.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Testing/Atoum.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Testing/Behat.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Testing/Codecept.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Testing/PHPUnit.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Testing/Phpspec.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Testing/loadTasks.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Vcs/GitStack.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Vcs/HgStack.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Vcs/SvnStack.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Vcs/loadShortcuts.php create mode 100644 src/composer/vendor/consolidation/robo/src/Task/Vcs/loadTasks.php create mode 100644 src/composer/vendor/consolidation/robo/src/TaskAccessor.php create mode 100644 src/composer/vendor/consolidation/robo/src/TaskInfo.php create mode 100644 src/composer/vendor/consolidation/robo/src/Tasks.php create mode 100644 src/composer/vendor/consolidation/robo/tests/_bootstrap.php create mode 100644 src/composer/vendor/consolidation/robo/tests/_data/TestedRoboFile.php create mode 100644 src/composer/vendor/consolidation/robo/tests/_data/TestedRoboTask.php create mode 100644 src/composer/vendor/consolidation/robo/tests/_data/claypit/a.txt create mode 100644 src/composer/vendor/consolidation/robo/tests/_data/claypit/b.txt create mode 100644 src/composer/vendor/consolidation/robo/tests/_data/claypit/box/robo.txt create mode 100644 src/composer/vendor/consolidation/robo/tests/_data/claypit/some/deeply/existing_file create mode 100644 src/composer/vendor/consolidation/robo/tests/_data/claypit/some/deeply/nested/structu.re create mode 100644 src/composer/vendor/consolidation/robo/tests/_data/claypit/some_destination/deeply/existing_file create mode 100644 src/composer/vendor/consolidation/robo/tests/_data/dump.sql create mode 100644 src/composer/vendor/consolidation/robo/tests/_data/parascript.php create mode 100644 src/composer/vendor/consolidation/robo/tests/_data/sample.css create mode 100644 src/composer/vendor/consolidation/robo/tests/_helpers/CliGuy.php create mode 100644 src/composer/vendor/consolidation/robo/tests/_helpers/CliHelper.php create mode 100644 src/composer/vendor/consolidation/robo/tests/_helpers/CodeGuy.php create mode 100644 src/composer/vendor/consolidation/robo/tests/_helpers/CodeHelper.php create mode 100644 src/composer/vendor/consolidation/robo/tests/_helpers/SeeInOutputTrait.php create mode 100644 src/composer/vendor/consolidation/robo/tests/_helpers/TestHelper.php create mode 100644 src/composer/vendor/consolidation/robo/tests/_helpers/WebHelper.php create mode 100644 src/composer/vendor/consolidation/robo/tests/cli.suite.yml create mode 100644 src/composer/vendor/consolidation/robo/tests/cli/AssetsCept.php create mode 100644 src/composer/vendor/consolidation/robo/tests/cli/CleanDirCept.php create mode 100644 src/composer/vendor/consolidation/robo/tests/cli/CollectionCest.php create mode 100644 src/composer/vendor/consolidation/robo/tests/cli/ConcatCept.php create mode 100644 src/composer/vendor/consolidation/robo/tests/cli/CopyDirCept.php create mode 100644 src/composer/vendor/consolidation/robo/tests/cli/CopyDirOverwritesFilesCept.php create mode 100644 src/composer/vendor/consolidation/robo/tests/cli/CopyDirRecursiveCept.php create mode 100644 src/composer/vendor/consolidation/robo/tests/cli/DeleteDirCept.php create mode 100644 src/composer/vendor/consolidation/robo/tests/cli/ExecCest.php create mode 100644 src/composer/vendor/consolidation/robo/tests/cli/FilesystemStackCest.php create mode 100644 src/composer/vendor/consolidation/robo/tests/cli/FlattenDirCept.php create mode 100644 src/composer/vendor/consolidation/robo/tests/cli/FlattenDirParentsCept.php create mode 100644 src/composer/vendor/consolidation/robo/tests/cli/GenTaskCest.php create mode 100644 src/composer/vendor/consolidation/robo/tests/cli/GenerateMarkdownDocCest.php create mode 100644 src/composer/vendor/consolidation/robo/tests/cli/PackExtractCept.php create mode 100644 src/composer/vendor/consolidation/robo/tests/cli/ShortcutsCest.php create mode 100644 src/composer/vendor/consolidation/robo/tests/cli/SimulatedCest.php create mode 100644 src/composer/vendor/consolidation/robo/tests/cli/WriteFileCest.php create mode 100644 src/composer/vendor/consolidation/robo/tests/cli/_bootstrap.php create mode 100644 src/composer/vendor/consolidation/robo/tests/src/RoboFileFixture.php create mode 100644 src/composer/vendor/consolidation/robo/tests/src/Traits/Common/CommandArgumentsHost.php create mode 100644 src/composer/vendor/consolidation/robo/tests/unit.suite.yml create mode 100644 src/composer/vendor/consolidation/robo/tests/unit/ApplicationTest.php create mode 100644 src/composer/vendor/consolidation/robo/tests/unit/Common/CommandArgumentsTest.php create mode 100644 src/composer/vendor/consolidation/robo/tests/unit/Common/ResourceExistenceChecker.php create mode 100644 src/composer/vendor/consolidation/robo/tests/unit/ConfigurationTest.php create mode 100644 src/composer/vendor/consolidation/robo/tests/unit/OutputTest.php create mode 100644 src/composer/vendor/consolidation/robo/tests/unit/ResultTest.php create mode 100644 src/composer/vendor/consolidation/robo/tests/unit/RunnerTest.php create mode 100644 src/composer/vendor/consolidation/robo/tests/unit/Task/ApiGenTest.php create mode 100644 src/composer/vendor/consolidation/robo/tests/unit/Task/AtoumTest.php create mode 100644 src/composer/vendor/consolidation/robo/tests/unit/Task/BehatTest.php create mode 100644 src/composer/vendor/consolidation/robo/tests/unit/Task/BowerTest.php create mode 100644 src/composer/vendor/consolidation/robo/tests/unit/Task/CodeceptionTest.php create mode 100644 src/composer/vendor/consolidation/robo/tests/unit/Task/CollectionTest.php create mode 100644 src/composer/vendor/consolidation/robo/tests/unit/Task/CommandStackTest.php create mode 100644 src/composer/vendor/consolidation/robo/tests/unit/Task/ComposerTest.php create mode 100644 src/composer/vendor/consolidation/robo/tests/unit/Task/DockerTest.php create mode 100644 src/composer/vendor/consolidation/robo/tests/unit/Task/ExecTaskTest.php create mode 100644 src/composer/vendor/consolidation/robo/tests/unit/Task/GitTest.php create mode 100644 src/composer/vendor/consolidation/robo/tests/unit/Task/GulpTest.php create mode 100644 src/composer/vendor/consolidation/robo/tests/unit/Task/HgTest.php create mode 100644 src/composer/vendor/consolidation/robo/tests/unit/Task/NpmTest.php create mode 100644 src/composer/vendor/consolidation/robo/tests/unit/Task/PHPServerTest.php create mode 100644 src/composer/vendor/consolidation/robo/tests/unit/Task/PHPUnitTest.php create mode 100644 src/composer/vendor/consolidation/robo/tests/unit/Task/ParallelExecTest.php create mode 100644 src/composer/vendor/consolidation/robo/tests/unit/Task/PhpspecTest.php create mode 100644 src/composer/vendor/consolidation/robo/tests/unit/Task/RsyncTest.php create mode 100644 src/composer/vendor/consolidation/robo/tests/unit/Task/SemVerTest.php create mode 100644 src/composer/vendor/consolidation/robo/tests/unit/Task/SshTest.php create mode 100644 src/composer/vendor/consolidation/robo/tests/unit/Task/SvnTest.php create mode 100644 src/composer/vendor/consolidation/robo/tests/unit/_bootstrap.php create mode 100644 src/composer/vendor/container-interop/container-interop/.gitignore create mode 100644 src/composer/vendor/container-interop/container-interop/LICENSE create mode 100644 src/composer/vendor/container-interop/container-interop/README.md create mode 100644 src/composer/vendor/container-interop/container-interop/composer.json create mode 100644 src/composer/vendor/container-interop/container-interop/docs/ContainerInterface-meta.md create mode 100644 src/composer/vendor/container-interop/container-interop/docs/ContainerInterface.md create mode 100644 src/composer/vendor/container-interop/container-interop/docs/Delegate-lookup-meta.md create mode 100644 src/composer/vendor/container-interop/container-interop/docs/Delegate-lookup.md create mode 100644 src/composer/vendor/container-interop/container-interop/docs/images/interoperating_containers.png create mode 100644 src/composer/vendor/container-interop/container-interop/docs/images/priority.png create mode 100644 src/composer/vendor/container-interop/container-interop/docs/images/side_by_side_containers.png create mode 100644 src/composer/vendor/container-interop/container-interop/src/Interop/Container/ContainerInterface.php create mode 100644 src/composer/vendor/container-interop/container-interop/src/Interop/Container/Exception/ContainerException.php create mode 100644 src/composer/vendor/container-interop/container-interop/src/Interop/Container/Exception/NotFoundException.php create mode 100644 src/composer/vendor/doctrine/instantiator/.gitignore create mode 100644 src/composer/vendor/doctrine/instantiator/.scrutinizer.yml create mode 100755 src/composer/vendor/doctrine/instantiator/.travis.install.sh create mode 100644 src/composer/vendor/doctrine/instantiator/.travis.yml create mode 100644 src/composer/vendor/doctrine/instantiator/CONTRIBUTING.md create mode 100644 src/composer/vendor/doctrine/instantiator/LICENSE create mode 100644 src/composer/vendor/doctrine/instantiator/README.md create mode 100644 src/composer/vendor/doctrine/instantiator/composer.json create mode 100644 src/composer/vendor/doctrine/instantiator/phpmd.xml.dist create mode 100644 src/composer/vendor/doctrine/instantiator/phpunit.xml.dist create mode 100644 src/composer/vendor/doctrine/instantiator/src/Doctrine/Instantiator/Exception/ExceptionInterface.php create mode 100644 src/composer/vendor/doctrine/instantiator/src/Doctrine/Instantiator/Exception/InvalidArgumentException.php create mode 100644 src/composer/vendor/doctrine/instantiator/src/Doctrine/Instantiator/Exception/UnexpectedValueException.php create mode 100644 src/composer/vendor/doctrine/instantiator/src/Doctrine/Instantiator/Instantiator.php create mode 100644 src/composer/vendor/doctrine/instantiator/src/Doctrine/Instantiator/InstantiatorInterface.php create mode 100644 src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorPerformance/InstantiatorPerformanceEvent.php create mode 100644 src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTest/Exception/InvalidArgumentExceptionTest.php create mode 100644 src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTest/Exception/UnexpectedValueExceptionTest.php create mode 100644 src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTest/InstantiatorTest.php create mode 100644 src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/AbstractClassAsset.php create mode 100644 src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/ArrayObjectAsset.php create mode 100644 src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/ExceptionAsset.php create mode 100644 src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/FinalExceptionAsset.php create mode 100644 src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/PharAsset.php create mode 100644 src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/PharExceptionAsset.php create mode 100644 src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/SerializableArrayObjectAsset.php create mode 100644 src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/SimpleSerializableAsset.php create mode 100644 src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/SimpleTraitAsset.php create mode 100644 src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/UnCloneableAsset.php create mode 100644 src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/UnserializeExceptionArrayObjectAsset.php create mode 100644 src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/WakeUpNoticesAsset.php create mode 100644 src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/XMLReaderAsset.php create mode 100644 src/composer/vendor/league/container/CHANGELOG.md create mode 100644 src/composer/vendor/league/container/CONTRIBUTING.md create mode 100644 src/composer/vendor/league/container/LICENSE.md create mode 100644 src/composer/vendor/league/container/README.md create mode 100644 src/composer/vendor/league/container/composer.json create mode 100644 src/composer/vendor/league/container/src/Argument/ArgumentResolverInterface.php create mode 100644 src/composer/vendor/league/container/src/Argument/ArgumentResolverTrait.php create mode 100644 src/composer/vendor/league/container/src/Argument/RawArgument.php create mode 100644 src/composer/vendor/league/container/src/Argument/RawArgumentInterface.php create mode 100644 src/composer/vendor/league/container/src/Container.php create mode 100644 src/composer/vendor/league/container/src/ContainerAwareInterface.php create mode 100644 src/composer/vendor/league/container/src/ContainerAwareTrait.php create mode 100644 src/composer/vendor/league/container/src/ContainerInterface.php create mode 100644 src/composer/vendor/league/container/src/Definition/AbstractDefinition.php create mode 100644 src/composer/vendor/league/container/src/Definition/CallableDefinition.php create mode 100644 src/composer/vendor/league/container/src/Definition/ClassDefinition.php create mode 100644 src/composer/vendor/league/container/src/Definition/ClassDefinitionInterface.php create mode 100644 src/composer/vendor/league/container/src/Definition/DefinitionFactory.php create mode 100644 src/composer/vendor/league/container/src/Definition/DefinitionFactoryInterface.php create mode 100644 src/composer/vendor/league/container/src/Definition/DefinitionInterface.php create mode 100644 src/composer/vendor/league/container/src/Exception/NotFoundException.php create mode 100644 src/composer/vendor/league/container/src/ImmutableContainerAwareInterface.php create mode 100644 src/composer/vendor/league/container/src/ImmutableContainerAwareTrait.php create mode 100644 src/composer/vendor/league/container/src/ImmutableContainerInterface.php create mode 100644 src/composer/vendor/league/container/src/Inflector/Inflector.php create mode 100644 src/composer/vendor/league/container/src/Inflector/InflectorAggregate.php create mode 100644 src/composer/vendor/league/container/src/Inflector/InflectorAggregateInterface.php create mode 100644 src/composer/vendor/league/container/src/ReflectionContainer.php create mode 100644 src/composer/vendor/league/container/src/ServiceProvider/AbstractServiceProvider.php create mode 100644 src/composer/vendor/league/container/src/ServiceProvider/AbstractSignatureServiceProvider.php create mode 100644 src/composer/vendor/league/container/src/ServiceProvider/BootableServiceProviderInterface.php create mode 100644 src/composer/vendor/league/container/src/ServiceProvider/ServiceProviderAggregate.php create mode 100644 src/composer/vendor/league/container/src/ServiceProvider/ServiceProviderAggregateInterface.php create mode 100644 src/composer/vendor/league/container/src/ServiceProvider/ServiceProviderInterface.php create mode 100644 src/composer/vendor/league/container/src/ServiceProvider/SignatureServiceProviderInterface.php create mode 100755 src/composer/vendor/myclabs/deep-copy/.gitattributes create mode 100755 src/composer/vendor/myclabs/deep-copy/.gitignore create mode 100755 src/composer/vendor/myclabs/deep-copy/.travis.yml create mode 100644 src/composer/vendor/myclabs/deep-copy/LICENSE create mode 100644 src/composer/vendor/myclabs/deep-copy/README.md create mode 100644 src/composer/vendor/myclabs/deep-copy/composer.json create mode 100644 src/composer/vendor/myclabs/deep-copy/doc/clone.png create mode 100644 src/composer/vendor/myclabs/deep-copy/doc/deep-clone.png create mode 100644 src/composer/vendor/myclabs/deep-copy/doc/deep-copy.png create mode 100644 src/composer/vendor/myclabs/deep-copy/doc/graph.png create mode 100644 src/composer/vendor/myclabs/deep-copy/src/DeepCopy/DeepCopy.php create mode 100644 src/composer/vendor/myclabs/deep-copy/src/DeepCopy/Exception/CloneException.php create mode 100644 src/composer/vendor/myclabs/deep-copy/src/DeepCopy/Filter/Doctrine/DoctrineCollectionFilter.php create mode 100644 src/composer/vendor/myclabs/deep-copy/src/DeepCopy/Filter/Doctrine/DoctrineEmptyCollectionFilter.php create mode 100644 src/composer/vendor/myclabs/deep-copy/src/DeepCopy/Filter/Filter.php create mode 100644 src/composer/vendor/myclabs/deep-copy/src/DeepCopy/Filter/KeepFilter.php create mode 100644 src/composer/vendor/myclabs/deep-copy/src/DeepCopy/Filter/ReplaceFilter.php create mode 100644 src/composer/vendor/myclabs/deep-copy/src/DeepCopy/Filter/SetNullFilter.php create mode 100644 src/composer/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/Matcher.php create mode 100644 src/composer/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/PropertyMatcher.php create mode 100644 src/composer/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/PropertyNameMatcher.php create mode 100644 src/composer/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/PropertyTypeMatcher.php create mode 100644 src/composer/vendor/myclabs/deep-copy/src/DeepCopy/Reflection/ReflectionHelper.php create mode 100644 src/composer/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/ReplaceFilter.php create mode 100644 src/composer/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/ShallowCopyFilter.php create mode 100644 src/composer/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/Spl/SplDoublyLinkedList.php create mode 100644 src/composer/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/TypeFilter.php create mode 100644 src/composer/vendor/myclabs/deep-copy/src/DeepCopy/TypeMatcher/TypeMatcher.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-common/.gitignore create mode 100644 src/composer/vendor/phpdocumentor/reflection-common/LICENSE create mode 100644 src/composer/vendor/phpdocumentor/reflection-common/README.md create mode 100644 src/composer/vendor/phpdocumentor/reflection-common/composer.json create mode 100644 src/composer/vendor/phpdocumentor/reflection-common/composer.lock create mode 100644 src/composer/vendor/phpdocumentor/reflection-common/phpunit.xml.dist create mode 100644 src/composer/vendor/phpdocumentor/reflection-common/src/Element.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-common/src/File.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-common/src/Fqsen.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-common/src/Location.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-common/src/Project.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-common/src/ProjectFactory.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-common/tests/common/bootstrap.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-common/tests/unit/FqsenTest.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/.gitignore create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/.scrutinizer.yml create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/.travis.yml create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/LICENSE create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/README.md create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/composer.json create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/composer.lock create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/examples/01-interpreting-a-simple-docblock.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/examples/02-interpreting-tags.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/examples/03-reconstituting-a-docblock.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/examples/04-adding-your-own-tag.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/examples/playing-with-descriptions/02-escaping.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/phpmd.xml.dist create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/phpunit.xml.dist create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Description.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/DescriptionFactory.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/ExampleFinder.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Serializer.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/StandardTagFactory.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tag.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/TagFactory.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Author.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/BaseTag.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Covers.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Deprecated.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Example.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/StaticMethod.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/Strategy.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter/PassthroughFormatter.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Generic.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Link.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Method.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Param.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Property.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/PropertyRead.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/PropertyWrite.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Return_.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/See.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Since.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Source.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Throws.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Uses.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Var_.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Version.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlockFactory.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlockFactoryInterface.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/tests/integration/InterpretingDocBlocksTest.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/tests/integration/ReconstitutingADocBlockTest.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/tests/integration/UsingTagsTest.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/DescriptionFactoryTest.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/DescriptionTest.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/SerializerTest.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/StandardTagFactoryTest.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/AuthorTest.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/CoversTest.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/DeprecatedTest.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/Formatter/PassthroughFormatterTest.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/GenericTest.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/LinkTest.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/MethodTest.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/ParamTest.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/PropertyReadTest.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/PropertyTest.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/PropertyWriteTest.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/ReturnTest.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/SeeTest.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/SinceTest.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/SourceTest.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/ThrowsTest.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/UsesTest.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/VarTest.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/VersionTest.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlockFactoryTest.php create mode 100644 src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlockTest.php create mode 100644 src/composer/vendor/phpdocumentor/type-resolver/.gitignore create mode 100644 src/composer/vendor/phpdocumentor/type-resolver/.scrutinizer.yml create mode 100644 src/composer/vendor/phpdocumentor/type-resolver/.travis.yml create mode 100644 src/composer/vendor/phpdocumentor/type-resolver/LICENSE create mode 100644 src/composer/vendor/phpdocumentor/type-resolver/README.md create mode 100644 src/composer/vendor/phpdocumentor/type-resolver/composer.json create mode 100644 src/composer/vendor/phpdocumentor/type-resolver/examples/01-resolving-simple-types.php create mode 100644 src/composer/vendor/phpdocumentor/type-resolver/examples/02-resolving-classes.php create mode 100644 src/composer/vendor/phpdocumentor/type-resolver/examples/03-resolving-all-elements.php create mode 100644 src/composer/vendor/phpdocumentor/type-resolver/examples/04-discovering-the-context-using-class-reflection.php create mode 100644 src/composer/vendor/phpdocumentor/type-resolver/examples/05-discovering-the-context-using-method-reflection.php create mode 100644 src/composer/vendor/phpdocumentor/type-resolver/examples/06-discovering-the-context-using-file-contents.php create mode 100644 src/composer/vendor/phpdocumentor/type-resolver/examples/Classy.php create mode 100644 src/composer/vendor/phpdocumentor/type-resolver/phpmd.xml.dist create mode 100644 src/composer/vendor/phpdocumentor/type-resolver/phpunit.xml.dist create mode 100644 src/composer/vendor/phpdocumentor/type-resolver/src/FqsenResolver.php create mode 100644 src/composer/vendor/phpdocumentor/type-resolver/src/Type.php create mode 100644 src/composer/vendor/phpdocumentor/type-resolver/src/TypeResolver.php create mode 100644 src/composer/vendor/phpdocumentor/type-resolver/src/Types/Array_.php create mode 100644 src/composer/vendor/phpdocumentor/type-resolver/src/Types/Boolean.php create mode 100644 src/composer/vendor/phpdocumentor/type-resolver/src/Types/Callable_.php create mode 100644 src/composer/vendor/phpdocumentor/type-resolver/src/Types/Compound.php create mode 100644 src/composer/vendor/phpdocumentor/type-resolver/src/Types/Context.php create mode 100644 src/composer/vendor/phpdocumentor/type-resolver/src/Types/ContextFactory.php create mode 100644 src/composer/vendor/phpdocumentor/type-resolver/src/Types/Float_.php create mode 100644 src/composer/vendor/phpdocumentor/type-resolver/src/Types/Integer.php create mode 100644 src/composer/vendor/phpdocumentor/type-resolver/src/Types/Mixed.php create mode 100644 src/composer/vendor/phpdocumentor/type-resolver/src/Types/Null_.php create mode 100644 src/composer/vendor/phpdocumentor/type-resolver/src/Types/Object_.php create mode 100644 src/composer/vendor/phpdocumentor/type-resolver/src/Types/Resource.php create mode 100644 src/composer/vendor/phpdocumentor/type-resolver/src/Types/Scalar.php create mode 100644 src/composer/vendor/phpdocumentor/type-resolver/src/Types/Self_.php create mode 100644 src/composer/vendor/phpdocumentor/type-resolver/src/Types/Static_.php create mode 100644 src/composer/vendor/phpdocumentor/type-resolver/src/Types/String_.php create mode 100644 src/composer/vendor/phpdocumentor/type-resolver/src/Types/This.php create mode 100644 src/composer/vendor/phpdocumentor/type-resolver/src/Types/Void_.php create mode 100644 src/composer/vendor/phpdocumentor/type-resolver/tests/unit/TypeResolverTest.php create mode 100644 src/composer/vendor/phpdocumentor/type-resolver/tests/unit/Types/ContextFactoryTest.php create mode 100644 src/composer/vendor/phpdocumentor/type-resolver/tests/unit/Types/ContextTest.php create mode 100644 src/composer/vendor/phpspec/prophecy/.gitignore create mode 100644 src/composer/vendor/phpspec/prophecy/.travis.yml create mode 100644 src/composer/vendor/phpspec/prophecy/CHANGES.md create mode 100644 src/composer/vendor/phpspec/prophecy/CONTRIBUTING.md create mode 100644 src/composer/vendor/phpspec/prophecy/LICENSE create mode 100644 src/composer/vendor/phpspec/prophecy/README.md create mode 100644 src/composer/vendor/phpspec/prophecy/composer.json create mode 100644 src/composer/vendor/phpspec/prophecy/spec/Prophecy/Argument/ArgumentsWildcardSpec.php create mode 100644 src/composer/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/AnyValueTokenSpec.php create mode 100644 src/composer/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/AnyValuesTokenSpec.php create mode 100644 src/composer/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/ApproximateValueTokenSpec.php create mode 100644 src/composer/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/ArrayCountTokenSpec.php create mode 100644 src/composer/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/ArrayEntryTokenSpec.php create mode 100644 src/composer/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/ArrayEveryEntryTokenSpec.php create mode 100644 src/composer/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/CallbackTokenSpec.php create mode 100644 src/composer/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/ExactValueTokenSpec.php create mode 100644 src/composer/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/IdenticalValueTokenSpec.php create mode 100644 src/composer/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/LogicalAndTokenSpec.php create mode 100644 src/composer/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/LogicalNotTokenSpec.php create mode 100644 src/composer/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/ObjectStateTokenSpec.php create mode 100644 src/composer/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/StringContainsTokenSpec.php create mode 100644 src/composer/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/TypeTokenSpec.php create mode 100644 src/composer/vendor/phpspec/prophecy/spec/Prophecy/ArgumentSpec.php create mode 100644 src/composer/vendor/phpspec/prophecy/spec/Prophecy/Call/CallCenterSpec.php create mode 100644 src/composer/vendor/phpspec/prophecy/spec/Prophecy/Call/CallSpec.php create mode 100644 src/composer/vendor/phpspec/prophecy/spec/Prophecy/Comparator/ClosureComparatorSpec.php create mode 100644 src/composer/vendor/phpspec/prophecy/spec/Prophecy/Comparator/FactorySpec.php create mode 100644 src/composer/vendor/phpspec/prophecy/spec/Prophecy/Comparator/ProphecyComparatorSpec.php create mode 100644 src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/ClassPatch/DisableConstructorPatchSpec.php create mode 100644 src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/ClassPatch/HhvmExceptionPatchSpec.php create mode 100644 src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/ClassPatch/KeywordPatchSpec.php create mode 100644 src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/ClassPatch/MagicCallPatchSpec.php create mode 100644 src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/ClassPatch/ProphecySubjectPatchSpec.php create mode 100644 src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/ClassPatch/ReflectionClassNewInstancePatchSpec.php create mode 100644 src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/ClassPatch/SplFileInfoPatchSpec.php create mode 100644 src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/ClassPatch/TraversablePatchSpec.php create mode 100644 src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/DoublerSpec.php create mode 100644 src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/Generator/ClassCodeGeneratorSpec.php create mode 100644 src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/Generator/ClassCreatorSpec.php create mode 100644 src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/Generator/ClassMirrorSpec.php create mode 100644 src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/Generator/Node/ArgumentNodeSpec.php create mode 100644 src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/Generator/Node/ClassNodeSpec.php create mode 100644 src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/Generator/Node/MethodNodeSpec.php create mode 100644 src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/LazyDoubleSpec.php create mode 100644 src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/NameGeneratorSpec.php create mode 100644 src/composer/vendor/phpspec/prophecy/spec/Prophecy/Exception/Call/UnexpectedCallExceptionSpec.php create mode 100644 src/composer/vendor/phpspec/prophecy/spec/Prophecy/Exception/Doubler/ClassCreatorExceptionSpec.php create mode 100644 src/composer/vendor/phpspec/prophecy/spec/Prophecy/Exception/Doubler/ClassMirrorExceptionSpec.php create mode 100644 src/composer/vendor/phpspec/prophecy/spec/Prophecy/Exception/Doubler/ClassNotFoundExceptionSpec.php create mode 100644 src/composer/vendor/phpspec/prophecy/spec/Prophecy/Exception/Doubler/DoubleExceptionSpec.php create mode 100644 src/composer/vendor/phpspec/prophecy/spec/Prophecy/Exception/Doubler/InterfaceNotFoundExceptionSpec.php create mode 100644 src/composer/vendor/phpspec/prophecy/spec/Prophecy/Exception/Doubler/MethodNotExtendableExceptionSpec.php create mode 100644 src/composer/vendor/phpspec/prophecy/spec/Prophecy/Exception/Doubler/MethodNotFoundExceptionSpec.php create mode 100644 src/composer/vendor/phpspec/prophecy/spec/Prophecy/Exception/Prediction/AggregateExceptionSpec.php create mode 100644 src/composer/vendor/phpspec/prophecy/spec/Prophecy/Exception/Prediction/NoCallsExceptionSpec.php create mode 100644 src/composer/vendor/phpspec/prophecy/spec/Prophecy/Exception/Prediction/UnexpectedCallsCountExceptionSpec.php create mode 100644 src/composer/vendor/phpspec/prophecy/spec/Prophecy/Exception/Prediction/UnexpectedCallsExceptionSpec.php create mode 100644 src/composer/vendor/phpspec/prophecy/spec/Prophecy/Exception/Prophecy/MethodProphecyExceptionSpec.php create mode 100644 src/composer/vendor/phpspec/prophecy/spec/Prophecy/Exception/Prophecy/ObjectProphecyExceptionSpec.php create mode 100644 src/composer/vendor/phpspec/prophecy/spec/Prophecy/Prediction/CallPredictionSpec.php create mode 100644 src/composer/vendor/phpspec/prophecy/spec/Prophecy/Prediction/CallTimesPredictionSpec.php create mode 100644 src/composer/vendor/phpspec/prophecy/spec/Prophecy/Prediction/CallbackPredictionSpec.php create mode 100644 src/composer/vendor/phpspec/prophecy/spec/Prophecy/Prediction/NoCallsPredictionSpec.php create mode 100644 src/composer/vendor/phpspec/prophecy/spec/Prophecy/Promise/CallbackPromiseSpec.php create mode 100644 src/composer/vendor/phpspec/prophecy/spec/Prophecy/Promise/ReturnArgumentPromiseSpec.php create mode 100644 src/composer/vendor/phpspec/prophecy/spec/Prophecy/Promise/ReturnPromiseSpec.php create mode 100644 src/composer/vendor/phpspec/prophecy/spec/Prophecy/Promise/ThrowPromiseSpec.php create mode 100644 src/composer/vendor/phpspec/prophecy/spec/Prophecy/Prophecy/MethodProphecySpec.php create mode 100644 src/composer/vendor/phpspec/prophecy/spec/Prophecy/Prophecy/ObjectProphecySpec.php create mode 100644 src/composer/vendor/phpspec/prophecy/spec/Prophecy/Prophecy/RevealerSpec.php create mode 100644 src/composer/vendor/phpspec/prophecy/spec/Prophecy/ProphetSpec.php create mode 100644 src/composer/vendor/phpspec/prophecy/spec/Prophecy/Util/StringUtilSpec.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument/ArgumentsWildcard.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/AnyValueToken.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/AnyValuesToken.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ApproximateValueToken.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ArrayCountToken.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ArrayEntryToken.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ArrayEveryEntryToken.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/CallbackToken.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ExactValueToken.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/IdenticalValueToken.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/LogicalAndToken.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/LogicalNotToken.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ObjectStateToken.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/StringContainsToken.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/TokenInterface.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/TypeToken.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Call/Call.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Call/CallCenter.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Comparator/ClosureComparator.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Comparator/Factory.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Comparator/ProphecyComparator.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/CachedDoubler.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ClassPatchInterface.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/DisableConstructorPatch.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/HhvmExceptionPatch.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/KeywordPatch.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/MagicCallPatch.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ProphecySubjectPatch.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ReflectionClassNewInstancePatch.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/SplFileInfoPatch.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/TraversablePatch.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/DoubleInterface.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/Doubler.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ClassCodeGenerator.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ClassCreator.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ClassMirror.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/ArgumentNode.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/ClassNode.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/MethodNode.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ReflectionInterface.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/LazyDouble.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/NameGenerator.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Call/UnexpectedCallException.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ClassCreatorException.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ClassMirrorException.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ClassNotFoundException.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/DoubleException.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/DoublerException.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/InterfaceNotFoundException.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/MethodNotExtendableException.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/MethodNotFoundException.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ReturnByReferenceException.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Exception.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/InvalidArgumentException.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/AggregateException.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/FailedPredictionException.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/NoCallsException.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/PredictionException.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/UnexpectedCallsCountException.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/UnexpectedCallsException.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Prophecy/MethodProphecyException.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Prophecy/ObjectProphecyException.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Prophecy/ProphecyException.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/PhpDocumentor/ClassAndInterfaceTagRetriever.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/PhpDocumentor/ClassTagRetriever.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/PhpDocumentor/LegacyClassTagRetriever.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/PhpDocumentor/MethodTagRetrieverInterface.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Prediction/CallPrediction.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Prediction/CallTimesPrediction.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Prediction/CallbackPrediction.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Prediction/NoCallsPrediction.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Prediction/PredictionInterface.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Promise/CallbackPromise.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Promise/PromiseInterface.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Promise/ReturnArgumentPromise.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Promise/ReturnPromise.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Promise/ThrowPromise.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Prophecy/MethodProphecy.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Prophecy/ObjectProphecy.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Prophecy/ProphecyInterface.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Prophecy/ProphecySubjectInterface.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Prophecy/Revealer.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Prophecy/RevealerInterface.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Prophet.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Util/ExportUtil.php create mode 100644 src/composer/vendor/phpspec/prophecy/src/Prophecy/Util/StringUtil.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/.gitattributes create mode 100644 src/composer/vendor/phpunit/php-code-coverage/.gitignore create mode 100644 src/composer/vendor/phpunit/php-code-coverage/.php_cs create mode 100644 src/composer/vendor/phpunit/php-code-coverage/.travis.yml create mode 100644 src/composer/vendor/phpunit/php-code-coverage/CONTRIBUTING.md create mode 100644 src/composer/vendor/phpunit/php-code-coverage/ChangeLog-2.2.md create mode 100644 src/composer/vendor/phpunit/php-code-coverage/ChangeLog-3.0.md create mode 100644 src/composer/vendor/phpunit/php-code-coverage/ChangeLog-3.1.md create mode 100644 src/composer/vendor/phpunit/php-code-coverage/ChangeLog-3.2.md create mode 100644 src/composer/vendor/phpunit/php-code-coverage/ChangeLog-3.3.md create mode 100644 src/composer/vendor/phpunit/php-code-coverage/ChangeLog-4.0.md create mode 100644 src/composer/vendor/phpunit/php-code-coverage/LICENSE create mode 100644 src/composer/vendor/phpunit/php-code-coverage/README.md create mode 100644 src/composer/vendor/phpunit/php-code-coverage/build.xml create mode 100644 src/composer/vendor/phpunit/php-code-coverage/build/phpunit.xml create mode 100644 src/composer/vendor/phpunit/php-code-coverage/composer.json create mode 100644 src/composer/vendor/phpunit/php-code-coverage/src/CodeCoverage.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/src/Driver/Driver.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/src/Driver/HHVM.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/src/Driver/PHPDBG.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/src/Driver/Xdebug.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/src/Exception/CoveredCodeNotExecutedException.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/src/Exception/Exception.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/src/Exception/InvalidArgumentException.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/src/Exception/MissingCoversAnnotationException.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/src/Exception/RuntimeException.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/src/Exception/UnintentionallyCoveredCodeException.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/src/Filter.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/src/Node/AbstractNode.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/src/Node/Builder.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/src/Node/Directory.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/src/Node/File.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/src/Node/Iterator.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/src/Report/Clover.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/src/Report/Crap4j.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Facade.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Dashboard.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Directory.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/File.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/coverage_bar.html.dist create mode 100644 src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/css/bootstrap.min.css create mode 100644 src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/css/nv.d3.min.css create mode 100644 src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/css/style.css create mode 100644 src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/dashboard.html.dist create mode 100644 src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/directory.html.dist create mode 100644 src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/directory_item.html.dist create mode 100644 src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/file.html.dist create mode 100644 src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/file_item.html.dist create mode 100644 src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/fonts/glyphicons-halflings-regular.eot create mode 100644 src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/fonts/glyphicons-halflings-regular.svg create mode 100644 src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/fonts/glyphicons-halflings-regular.ttf create mode 100644 src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/fonts/glyphicons-halflings-regular.woff create mode 100644 src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/fonts/glyphicons-halflings-regular.woff2 create mode 100644 src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/bootstrap.min.js create mode 100644 src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/d3.min.js create mode 100644 src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/holder.min.js create mode 100644 src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/html5shiv.min.js create mode 100644 src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/jquery.min.js create mode 100644 src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/nv.d3.min.js create mode 100644 src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/respond.min.js create mode 100644 src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/method_item.html.dist create mode 100644 src/composer/vendor/phpunit/php-code-coverage/src/Report/PHP.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/src/Report/Text.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/src/Report/Xml/Coverage.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/src/Report/Xml/Directory.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/src/Report/Xml/Facade.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/src/Report/Xml/File.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/src/Report/Xml/Method.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/src/Report/Xml/Node.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/src/Report/Xml/Project.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/src/Report/Xml/Report.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/src/Report/Xml/Tests.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/src/Report/Xml/Totals.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/src/Report/Xml/Unit.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/src/Util.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/TestCase.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/_files/BankAccount-clover.xml create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/_files/BankAccount-crap4j.xml create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/_files/BankAccount-text.txt create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/_files/BankAccount.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/_files/BankAccountTest.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/_files/CoverageClassExtendedTest.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/_files/CoverageClassTest.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/_files/CoverageFunctionParenthesesTest.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/_files/CoverageFunctionParenthesesWhitespaceTest.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/_files/CoverageFunctionTest.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/_files/CoverageMethodOneLineAnnotationTest.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/_files/CoverageMethodParenthesesTest.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/_files/CoverageMethodParenthesesWhitespaceTest.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/_files/CoverageMethodTest.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/_files/CoverageNoneTest.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/_files/CoverageNotPrivateTest.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/_files/CoverageNotProtectedTest.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/_files/CoverageNotPublicTest.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/_files/CoverageNothingTest.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/_files/CoveragePrivateTest.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/_files/CoverageProtectedTest.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/_files/CoveragePublicTest.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/_files/CoverageTwoDefaultClassAnnotations.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/_files/CoveredClass.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/_files/CoveredFunction.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageClassExtendedTest.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageClassTest.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageCoversClassPublicTest.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageCoversClassTest.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageMethodTest.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageNotPrivateTest.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageNotProtectedTest.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageNotPublicTest.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoveragePrivateTest.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageProtectedTest.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoveragePublicTest.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoveredClass.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/_files/NotExistingCoveredElementTest.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForBankAccount/BankAccount.php.html create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForBankAccount/dashboard.html create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForBankAccount/index.html create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForClassWithAnonymousFunction/dashboard.html create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForClassWithAnonymousFunction/index.html create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForClassWithAnonymousFunction/source_with_class_and_anonymous_function.php.html create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForFileWithIgnoredLines/dashboard.html create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForFileWithIgnoredLines/index.html create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForFileWithIgnoredLines/source_with_ignore.php.html create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/_files/Report/XML/CoverageForBankAccount/BankAccount.php.xml create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/_files/Report/XML/CoverageForBankAccount/index.xml create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/_files/Report/XML/CoverageForClassWithAnonymousFunction/index.xml create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/_files/Report/XML/CoverageForClassWithAnonymousFunction/source_with_class_and_anonymous_function.php.xml create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/_files/Report/XML/CoverageForFileWithIgnoredLines/index.xml create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/_files/Report/XML/CoverageForFileWithIgnoredLines/source_with_ignore.php.xml create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/_files/class-with-anonymous-function-clover.xml create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/_files/class-with-anonymous-function-crap4j.xml create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/_files/class-with-anonymous-function-text.txt create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/_files/ignored-lines-clover.xml create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/_files/ignored-lines-crap4j.xml create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/_files/ignored-lines-text.txt create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/_files/source_with_class_and_anonymous_function.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/_files/source_with_ignore.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/_files/source_with_namespace.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/_files/source_with_oneline_annotations.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/_files/source_without_ignore.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/_files/source_without_namespace.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/bootstrap.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/tests/BuilderTest.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/tests/CloverTest.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/tests/CodeCoverageTest.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/tests/Crap4jTest.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/tests/FilterTest.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/tests/HTMLTest.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/tests/TextTest.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/tests/UtilTest.php create mode 100644 src/composer/vendor/phpunit/php-code-coverage/tests/tests/XMLTest.php create mode 100644 src/composer/vendor/phpunit/php-file-iterator/.gitattributes create mode 100644 src/composer/vendor/phpunit/php-file-iterator/.gitignore create mode 100644 src/composer/vendor/phpunit/php-file-iterator/ChangeLog.md create mode 100644 src/composer/vendor/phpunit/php-file-iterator/LICENSE create mode 100644 src/composer/vendor/phpunit/php-file-iterator/README.md create mode 100644 src/composer/vendor/phpunit/php-file-iterator/composer.json create mode 100644 src/composer/vendor/phpunit/php-file-iterator/src/Facade.php create mode 100644 src/composer/vendor/phpunit/php-file-iterator/src/Factory.php create mode 100644 src/composer/vendor/phpunit/php-file-iterator/src/Iterator.php create mode 100644 src/composer/vendor/phpunit/php-text-template/.gitattributes create mode 100644 src/composer/vendor/phpunit/php-text-template/.gitignore create mode 100644 src/composer/vendor/phpunit/php-text-template/LICENSE create mode 100644 src/composer/vendor/phpunit/php-text-template/README.md create mode 100644 src/composer/vendor/phpunit/php-text-template/composer.json create mode 100644 src/composer/vendor/phpunit/php-text-template/src/Template.php create mode 100644 src/composer/vendor/phpunit/php-timer/.gitattributes create mode 100644 src/composer/vendor/phpunit/php-timer/.gitignore create mode 100644 src/composer/vendor/phpunit/php-timer/.travis.yml create mode 100644 src/composer/vendor/phpunit/php-timer/LICENSE create mode 100644 src/composer/vendor/phpunit/php-timer/README.md create mode 100644 src/composer/vendor/phpunit/php-timer/composer.json create mode 100644 src/composer/vendor/phpunit/php-timer/src/Timer.php create mode 100644 src/composer/vendor/phpunit/php-timer/tests/TimerTest.php create mode 100644 src/composer/vendor/phpunit/php-token-stream/.gitattributes create mode 100644 src/composer/vendor/phpunit/php-token-stream/.gitignore create mode 100644 src/composer/vendor/phpunit/php-token-stream/.travis.yml create mode 100644 src/composer/vendor/phpunit/php-token-stream/LICENSE create mode 100644 src/composer/vendor/phpunit/php-token-stream/README.md create mode 100644 src/composer/vendor/phpunit/php-token-stream/build.xml create mode 100644 src/composer/vendor/phpunit/php-token-stream/build/phpunit.xml create mode 100644 src/composer/vendor/phpunit/php-token-stream/composer.json create mode 100644 src/composer/vendor/phpunit/php-token-stream/src/Token.php create mode 100644 src/composer/vendor/phpunit/php-token-stream/src/Token/Stream.php create mode 100644 src/composer/vendor/phpunit/php-token-stream/src/Token/Stream/CachingFactory.php create mode 100644 src/composer/vendor/phpunit/php-token-stream/tests/Token/ClassTest.php create mode 100644 src/composer/vendor/phpunit/php-token-stream/tests/Token/ClosureTest.php create mode 100644 src/composer/vendor/phpunit/php-token-stream/tests/Token/FunctionTest.php create mode 100644 src/composer/vendor/phpunit/php-token-stream/tests/Token/IncludeTest.php create mode 100644 src/composer/vendor/phpunit/php-token-stream/tests/Token/InterfaceTest.php create mode 100644 src/composer/vendor/phpunit/php-token-stream/tests/Token/NamespaceTest.php create mode 100644 src/composer/vendor/phpunit/php-token-stream/tests/TokenTest.php create mode 100644 src/composer/vendor/phpunit/php-token-stream/tests/_fixture/classExtendsNamespacedClass.php create mode 100644 src/composer/vendor/phpunit/php-token-stream/tests/_fixture/classInNamespace.php create mode 100644 src/composer/vendor/phpunit/php-token-stream/tests/_fixture/classInScopedNamespace.php create mode 100644 src/composer/vendor/phpunit/php-token-stream/tests/_fixture/classUsesNamespacedFunction.php create mode 100644 src/composer/vendor/phpunit/php-token-stream/tests/_fixture/class_with_method_that_declares_anonymous_class.php create mode 100644 src/composer/vendor/phpunit/php-token-stream/tests/_fixture/class_with_method_that_declares_anonymous_class2.php create mode 100644 src/composer/vendor/phpunit/php-token-stream/tests/_fixture/closure.php create mode 100644 src/composer/vendor/phpunit/php-token-stream/tests/_fixture/issue19.php create mode 100644 src/composer/vendor/phpunit/php-token-stream/tests/_fixture/issue30.php create mode 100644 src/composer/vendor/phpunit/php-token-stream/tests/_fixture/multipleNamespacesWithOneClassUsingBraces.php create mode 100644 src/composer/vendor/phpunit/php-token-stream/tests/_fixture/multipleNamespacesWithOneClassUsingNonBraceSyntax.php create mode 100644 src/composer/vendor/phpunit/php-token-stream/tests/_fixture/source.php create mode 100644 src/composer/vendor/phpunit/php-token-stream/tests/_fixture/source2.php create mode 100644 src/composer/vendor/phpunit/php-token-stream/tests/_fixture/source3.php create mode 100644 src/composer/vendor/phpunit/php-token-stream/tests/_fixture/source4.php create mode 100644 src/composer/vendor/phpunit/php-token-stream/tests/_fixture/source5.php create mode 100644 src/composer/vendor/phpunit/php-token-stream/tests/bootstrap.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/.gitattributes create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/.gitignore create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/.php_cs create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/.travis.yml create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/CONTRIBUTING.md create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/LICENSE create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/README.md create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/build.xml create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/build/travis-ci.xml create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/composer.json create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/phpunit.xml create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Identity.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/InvocationMocker.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Match.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/MethodNameMatch.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Namespace.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/ParametersMatch.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Stub.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Exception/BadMethodCallException.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Exception/Exception.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Exception/RuntimeException.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/deprecation.tpl.dist create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/mocked_class.tpl.dist create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/mocked_class_method.tpl.dist create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/mocked_clone.tpl.dist create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/mocked_method.tpl.dist create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/mocked_method_void.tpl.dist create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/mocked_static_method.tpl.dist create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/proxied_method.tpl.dist create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/proxied_method_void.tpl.dist create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/trait_class.tpl.dist create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/unmocked_clone.tpl.dist create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/wsdl_class.tpl.dist create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/wsdl_method.tpl.dist create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invocation.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invocation/Object.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invocation/Static.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/InvocationMocker.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invokable.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/AnyInvokedCount.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/AnyParameters.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/ConsecutiveParameters.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/Invocation.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtIndex.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtLeastCount.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtLeastOnce.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtMostCount.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedCount.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedRecorder.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/MethodName.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/Parameters.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/StatelessInvocation.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/MockBuilder.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/MockObject.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ConsecutiveCalls.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/Exception.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/MatcherCollection.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/Return.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnArgument.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnCallback.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnReference.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnSelf.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnValueMap.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Verifiable.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/GeneratorTest.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/MockBuilderTest.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Builder/InvocationMockerTest.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/232.phpt create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/abstract_class.phpt create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/class.phpt create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/class_call_parent_clone.phpt create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/class_call_parent_constructor.phpt create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/class_dont_call_parent_clone.phpt create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/class_dont_call_parent_constructor.phpt create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/class_implementing_interface_call_parent_constructor.phpt create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/class_implementing_interface_dont_call_parent_constructor.phpt create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/class_partial.phpt create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/class_with_method_named_method.phpt create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/class_with_method_with_variadic_arguments.phpt create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/interface.phpt create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/invocation_object_clone_object.phpt create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/namespaced_class.phpt create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/namespaced_class_call_parent_clone.phpt create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/namespaced_class_call_parent_constructor.phpt create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/namespaced_class_dont_call_parent_clone.phpt create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/namespaced_class_dont_call_parent_constructor.phpt create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/namespaced_class_implementing_interface_call_parent_constructor.phpt create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/namespaced_class_implementing_interface_dont_call_parent_constructor.phpt create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/namespaced_class_partial.phpt create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/namespaced_interface.phpt create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/nonexistent_class.phpt create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/nonexistent_class_with_namespace.phpt create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/nonexistent_class_with_namespace_starting_with_separator.phpt create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/nullable_types.phpt create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/proxy.phpt create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/return_type_declarations_object_method.phpt create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/return_type_declarations_self.phpt create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/return_type_declarations_static_method.phpt create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/return_type_declarations_void.phpt create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/scalar_type_declarations.phpt create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/wsdl_class.phpt create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/wsdl_class_namespace.phpt create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/wsdl_class_partial.phpt create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Invocation/ObjectTest.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Invocation/StaticTest.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Matcher/ConsecutiveParametersTest.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/MockObject/class_with_deprecated_method.phpt create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/MockObjectTest.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/ProxyObjectTest.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/_fixture/AbstractMockTestClass.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/_fixture/AbstractTrait.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/_fixture/AnInterface.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/_fixture/AnInterfaceWithReturnType.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/_fixture/AnotherInterface.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/_fixture/Bar.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/_fixture/ClassThatImplementsSerializable.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/_fixture/ClassWithSelfTypeHint.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/_fixture/ClassWithStaticMethod.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/_fixture/Foo.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/_fixture/FunctionCallback.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/_fixture/GoogleSearch.wsdl create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/_fixture/InterfaceWithSemiReservedMethodName.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/_fixture/InterfaceWithStaticMethod.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/_fixture/MethodCallback.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/_fixture/MethodCallbackByReference.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/_fixture/MockTestInterface.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/_fixture/Mockable.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/_fixture/PartialMockTestClass.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/_fixture/SingletonClass.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/_fixture/SomeClass.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/_fixture/StaticMockTestClass.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/_fixture/StringableClass.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/_fixture/TraversableMockTestInterface.php create mode 100644 src/composer/vendor/phpunit/phpunit-mock-objects/tests/bootstrap.php create mode 100644 src/composer/vendor/phpunit/phpunit/.gitattributes create mode 100644 src/composer/vendor/phpunit/phpunit/.gitignore create mode 100644 src/composer/vendor/phpunit/phpunit/.php_cs create mode 100644 src/composer/vendor/phpunit/phpunit/.travis.yml create mode 100644 src/composer/vendor/phpunit/phpunit/CODE_OF_CONDUCT.md create mode 100644 src/composer/vendor/phpunit/phpunit/CONTRIBUTING.md create mode 100644 src/composer/vendor/phpunit/phpunit/ChangeLog-4.0.md create mode 100644 src/composer/vendor/phpunit/phpunit/ChangeLog-4.1.md create mode 100644 src/composer/vendor/phpunit/phpunit/ChangeLog-4.2.md create mode 100644 src/composer/vendor/phpunit/phpunit/ChangeLog-4.3.md create mode 100644 src/composer/vendor/phpunit/phpunit/ChangeLog-4.4.md create mode 100644 src/composer/vendor/phpunit/phpunit/ChangeLog-4.5.md create mode 100644 src/composer/vendor/phpunit/phpunit/ChangeLog-4.6.md create mode 100644 src/composer/vendor/phpunit/phpunit/ChangeLog-4.7.md create mode 100644 src/composer/vendor/phpunit/phpunit/ChangeLog-4.8.md create mode 100644 src/composer/vendor/phpunit/phpunit/ChangeLog-5.0.md create mode 100644 src/composer/vendor/phpunit/phpunit/ChangeLog-5.1.md create mode 100644 src/composer/vendor/phpunit/phpunit/ChangeLog-5.2.md create mode 100644 src/composer/vendor/phpunit/phpunit/ChangeLog-5.3.md create mode 100644 src/composer/vendor/phpunit/phpunit/ChangeLog-5.4.md create mode 100644 src/composer/vendor/phpunit/phpunit/ChangeLog-5.5.md create mode 100644 src/composer/vendor/phpunit/phpunit/LICENSE create mode 100644 src/composer/vendor/phpunit/phpunit/README.md create mode 100644 src/composer/vendor/phpunit/phpunit/build.xml create mode 100644 src/composer/vendor/phpunit/phpunit/composer.json create mode 100755 src/composer/vendor/phpunit/phpunit/phpunit create mode 100644 src/composer/vendor/phpunit/phpunit/phpunit.xml create mode 100644 src/composer/vendor/phpunit/phpunit/phpunit.xsd create mode 100644 src/composer/vendor/phpunit/phpunit/src/Exception.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Extensions/GroupTestSuite.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Extensions/PhptTestCase.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Extensions/PhptTestSuite.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Extensions/RepeatedTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Extensions/TestDecorator.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Extensions/TicketListener.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/ForwardCompatibility/TestCase.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/Assert.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/Assert/Functions.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/AssertionFailedError.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/BaseTestListener.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/CodeCoverageException.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/Constraint.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/Constraint/And.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/Constraint/ArrayHasKey.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/Constraint/ArraySubset.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/Constraint/Attribute.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/Constraint/Callback.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/Constraint/ClassHasAttribute.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/Constraint/ClassHasStaticAttribute.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/Constraint/Composite.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/Constraint/Count.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/Constraint/Exception.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/Constraint/ExceptionCode.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/Constraint/ExceptionMessage.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/Constraint/ExceptionMessageRegExp.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/Constraint/FileExists.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/Constraint/GreaterThan.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/Constraint/IsAnything.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/Constraint/IsEmpty.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/Constraint/IsEqual.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/Constraint/IsFalse.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/Constraint/IsFinite.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/Constraint/IsIdentical.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/Constraint/IsInfinite.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/Constraint/IsInstanceOf.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/Constraint/IsJson.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/Constraint/IsNan.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/Constraint/IsNull.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/Constraint/IsTrue.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/Constraint/IsType.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/Constraint/JsonMatches.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/Constraint/JsonMatches/ErrorMessageProvider.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/Constraint/LessThan.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/Constraint/Not.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/Constraint/ObjectHasAttribute.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/Constraint/Or.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/Constraint/PCREMatch.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/Constraint/SameSize.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/Constraint/StringContains.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/Constraint/StringEndsWith.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/Constraint/StringMatches.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/Constraint/StringStartsWith.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/Constraint/TraversableContains.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/Constraint/TraversableContainsOnly.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/Constraint/Xor.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/Error.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/Error/Deprecated.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/Error/Notice.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/Error/Warning.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/Exception.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/ExceptionWrapper.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/ExpectationFailedException.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/IncompleteTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/IncompleteTestCase.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/IncompleteTestError.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/InvalidCoversTargetException.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/OutputError.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/PHPUnit_Framework_CoveredCodeNotExecutedException.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/PHPUnit_Framework_MissingCoversAnnotationException.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/RiskyTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/RiskyTestError.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/SelfDescribing.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/SkippedTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/SkippedTestCase.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/SkippedTestError.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/SkippedTestSuiteError.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/SyntheticError.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/Test.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/TestCase.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/TestFailure.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/TestListener.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/TestResult.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/TestSuite.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/TestSuite/DataProvider.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/UnintentionallyCoveredCodeError.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/Warning.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Framework/WarningTestCase.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Runner/BaseTestRunner.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Runner/Exception.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Runner/Filter/Factory.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Runner/Filter/Group.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Runner/Filter/Group/Exclude.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Runner/Filter/Group/Include.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Runner/Filter/Test.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Runner/StandardTestSuiteLoader.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Runner/TestSuiteLoader.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Runner/Version.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/TextUI/Command.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/TextUI/ResultPrinter.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/TextUI/TestRunner.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Util/Blacklist.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Util/Configuration.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Util/ConfigurationGenerator.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Util/ErrorHandler.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Util/Fileloader.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Util/Filesystem.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Util/Filter.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Util/Getopt.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Util/GlobalState.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Util/InvalidArgumentHelper.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Util/Log/JSON.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Util/Log/JUnit.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Util/Log/TAP.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Util/Log/TeamCity.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Util/PHP.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Util/PHP/Default.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Util/PHP/Template/TestCaseMethod.tpl.dist create mode 100644 src/composer/vendor/phpunit/phpunit/src/Util/PHP/Windows.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Util/Printer.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Util/Regex.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Util/String.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Util/Test.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Util/TestDox/NamePrettifier.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Util/TestDox/ResultPrinter.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Util/TestDox/ResultPrinter/HTML.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Util/TestDox/ResultPrinter/Text.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Util/TestDox/ResultPrinter/XML.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Util/TestSuiteIterator.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Util/Type.php create mode 100644 src/composer/vendor/phpunit/phpunit/src/Util/XML.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Extensions/PhptTestCaseTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Extensions/RepeatedTestTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Fail/fail.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Framework/AssertTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Framework/BaseTestListenerTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Framework/Constraint/CountTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Framework/Constraint/ExceptionMessageRegExpTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Framework/Constraint/ExceptionMessageTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Framework/Constraint/IsJsonTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Framework/Constraint/JsonMatches/ErrorMessageProviderTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Framework/Constraint/JsonMatchesTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Framework/ConstraintTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Framework/SuiteTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Framework/TestCaseTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Framework/TestFailureTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Framework/TestImplementorTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Framework/TestListenerTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/GitHub/1149.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/GitHub/1149/Issue1149Test.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/GitHub/1216.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/GitHub/1216/Issue1216Test.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/GitHub/1216/bootstrap1216.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/GitHub/1216/phpunit1216.xml create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/GitHub/1265.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/GitHub/1265/Issue1265Test.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/GitHub/1265/phpunit1265.xml create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/GitHub/1330.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/GitHub/1330/Issue1330Test.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/GitHub/1330/phpunit1330.xml create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/GitHub/1335.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/GitHub/1335/Issue1335Test.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/GitHub/1335/bootstrap1335.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/GitHub/1337.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/GitHub/1337/Issue1337Test.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/GitHub/1348.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/GitHub/1348/Issue1348Test.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/GitHub/1351.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/GitHub/1351/ChildProcessClass1351.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/GitHub/1351/Issue1351Test.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/GitHub/1374.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/GitHub/1374/Issue1374Test.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/GitHub/1437.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/GitHub/1437/Issue1437Test.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/GitHub/1468.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/GitHub/1468/Issue1468Test.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/GitHub/1471.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/GitHub/1471/Issue1471Test.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/GitHub/1472.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/GitHub/1472/Issue1472Test.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/GitHub/1570.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/GitHub/1570/Issue1570Test.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/GitHub/2158.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/GitHub/2158/Issue2158Test.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/GitHub/2158/constant.inc create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/GitHub/244.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/GitHub/244/Issue244Test.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/GitHub/322.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/GitHub/322/Issue322Test.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/GitHub/322/phpunit322.xml create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/GitHub/433.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/GitHub/433/Issue433Test.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/GitHub/445.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/GitHub/445/Issue445Test.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/GitHub/498.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/GitHub/498/Issue498Test.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/GitHub/503.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/GitHub/503/Issue503Test.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/GitHub/581.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/GitHub/581/Issue581Test.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/GitHub/74.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/GitHub/74/Issue74Test.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/GitHub/74/NewException.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/GitHub/765.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/GitHub/765/Issue765Test.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/GitHub/797.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/GitHub/797/Issue797Test.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/GitHub/797/bootstrap797.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/GitHub/863.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/GitHub/873-php5.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/GitHub/873-php7.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/GitHub/873/Issue873Test.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/Trac/1021.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/Trac/1021/Issue1021Test.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/Trac/523.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/Trac/523/Issue523Test.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/Trac/578.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/Trac/578/Issue578Test.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/Trac/684.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/Trac/684/Issue684Test.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/Trac/783.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/Trac/783/ChildSuite.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/Trac/783/OneTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/Trac/783/ParentSuite.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Regression/Trac/783/TwoTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Runner/BaseTestRunnerTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/_files/expect_external.txt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/_files/phpt-env.expected.txt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/_files/phpt_external.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/abstract-test-class.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/assertion.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/code-coverage-ignore.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/colors-always.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/concrete-test-class.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/custom-printer-debug.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/custom-printer-verbose.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/dataprovider-debug.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/dataprovider-log-xml-isolation.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/dataprovider-log-xml.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/dataprovider-testdox.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/debug.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/default-isolation.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/default.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/dependencies-clone.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/dependencies-isolation.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/dependencies.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/dependencies2-isolation.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/dependencies2.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/dependencies3-isolation.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/dependencies3.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/disable-code-coverage-ignore.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/empty-testcase.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/exception-stack.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/exclude-group-isolation.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/exclude-group.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/failure-isolation.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/failure-reverse-list.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/failure.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/fatal-isolation.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/filter-class-isolation.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/filter-class.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-classname-and-range-isolation.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-classname-and-range.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-number-isolation.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-number.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-only-range-isolation.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-only-range.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-only-regexp-isolation.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-only-regexp.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-only-string-isolation.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-only-string.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-range-isolation.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-range.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-regexp-isolation.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-regexp.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-string-isolation.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-string.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/filter-method-case-insensitive.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/filter-method-case-sensitive-no-result.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/filter-method-isolation.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/filter-method.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/filter-no-results.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/forward-compatibility.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/group-isolation.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/group.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/help.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/help2.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/ini-isolation.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/list-groups.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/list-suites.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/log-json-post-66021.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/log-tap.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/log-teamcity.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/log-xml.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/options-after-arguments.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/output-isolation.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/phpt-args.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/phpt-env.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/phpt-external.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/phpt-stderr.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/phpt-stdin.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/phpt-xfail.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/repeat.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/report-useless-tests-incomplete.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/report-useless-tests-isolation.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/report-useless-tests.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/stop-on-warning-via-cli.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/stop-on-warning-via-config.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/tap.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/teamcity.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/test-suffix-multiple.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/test-suffix-single.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/testdox-exclude-group.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/testdox-group.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/testdox-html.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/testdox-text.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/testdox-xml.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/TextUI/testdox.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Util/ConfigurationTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Util/GetoptTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Util/GlobalStateTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Util/PHPTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Util/RegexTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Util/TestDox/NamePrettifierTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Util/TestTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/Util/XMLTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/AbstractTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/AssertionExample.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/AssertionExampleTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/Author.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/BankAccount.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/BankAccountTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/BankAccountTest.test.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/BankAccountTest2.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/BaseTestListenerSample.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/BeforeAndAfterTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/BeforeClassAndAfterClassTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/BeforeClassWithOnlyDataProviderTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/Book.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/Calculator.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/ChangeCurrentWorkingDirectoryTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/ClassWithNonPublicAttributes.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/ClassWithScalarTypeDeclarations.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/ClassWithToString.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/ClonedDependencyTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/ConcreteTest.my.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/ConcreteTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/CoverageClassExtendedTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/CoverageClassTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/CoverageFunctionParenthesesTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/CoverageFunctionParenthesesWhitespaceTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/CoverageFunctionTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/CoverageMethodOneLineAnnotationTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/CoverageMethodParenthesesTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/CoverageMethodParenthesesWhitespaceTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/CoverageMethodTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/CoverageNamespacedFunctionTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/CoverageNoneTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/CoverageNotPrivateTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/CoverageNotProtectedTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/CoverageNotPublicTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/CoverageNothingTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/CoveragePrivateTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/CoverageProtectedTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/CoveragePublicTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/CoverageTwoDefaultClassAnnotations.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/CoveredClass.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/CoveredFunction.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/CustomPrinter.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/DataProviderDebugTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/DataProviderFilterTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/DataProviderIncompleteTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/DataProviderSkippedTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/DataProviderTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/DataProviderTestDoxTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/DependencyFailureTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/DependencySuccessTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/DependencyTestSuite.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/DoubleTestCase.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/DummyException.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/EmptyTestCaseTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/ExceptionInAssertPostConditionsTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/ExceptionInAssertPreConditionsTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/ExceptionInSetUpTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/ExceptionInTearDownTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/ExceptionInTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/ExceptionNamespaceTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/ExceptionStackTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/ExceptionTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/Failure.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/FailureTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/FatalTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/IgnoreCodeCoverageClass.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/IgnoreCodeCoverageClassTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/IncompleteTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/Inheritance/InheritanceA.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/Inheritance/InheritanceB.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/InheritedTestCase.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/IniTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/IsolationTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/JsonData/arrayObject.json create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/JsonData/simpleObject.json create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/MockRunner.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/Mockable.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/MultiDependencyTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/NamespaceCoverageClassExtendedTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/NamespaceCoverageClassTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/NamespaceCoverageCoversClassPublicTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/NamespaceCoverageCoversClassTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/NamespaceCoverageMethodTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/NamespaceCoverageNotPrivateTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/NamespaceCoverageNotProtectedTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/NamespaceCoverageNotPublicTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/NamespaceCoveragePrivateTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/NamespaceCoverageProtectedTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/NamespaceCoveragePublicTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/NamespaceCoveredClass.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/NamespaceCoveredFunction.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/NoArgTestCaseTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/NoTestCaseClass.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/NoTestCases.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/NonStatic.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/NotExistingCoveredElementTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/NotPublicTestCase.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/NotVoidTestCase.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/NothingTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/OneTestCase.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/OutputTestCase.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/OverrideTestCase.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/RequirementsClassBeforeClassHookTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/RequirementsClassDocBlockTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/RequirementsTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/SampleArrayAccess.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/SampleClass.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/Singleton.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/StackTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/StopOnWarningTestSuite.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/StopsOnWarningTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/Struct.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/Success.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/TemplateMethodsTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/TestDoxGroupTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/TestIncomplete.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/TestIterator.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/TestIterator2.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/TestSkipped.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/TestTestError.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/TestWithTest.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/ThrowExceptionTestCase.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/ThrowNoExceptionTestCase.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/WasRun.php create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/bar.xml create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/configuration.colors.empty.xml create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/configuration.colors.false.xml create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/configuration.colors.invalid.xml create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/configuration.colors.true.xml create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/configuration.custom-printer.xml create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/configuration.suites.xml create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/configuration.xml create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/configuration_empty.xml create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/configuration_stop_on_warning.xml create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/configuration_xinclude.xml create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/expectedFileFormat.txt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/foo.xml create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/phpt-for-coverage.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/phpt-xfail.phpt create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/structureAttributesAreSameButValuesAreNot.xml create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/structureExpected.xml create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/structureIgnoreTextNodes.xml create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/structureIsSameButDataIsNot.xml create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/structureWrongNumberOfAttributes.xml create mode 100644 src/composer/vendor/phpunit/phpunit/tests/_files/structureWrongNumberOfNodes.xml create mode 100644 src/composer/vendor/phpunit/phpunit/tests/bootstrap.php create mode 100644 src/composer/vendor/sebastian/code-unit-reverse-lookup/.gitignore create mode 100644 src/composer/vendor/sebastian/code-unit-reverse-lookup/.php_cs create mode 100644 src/composer/vendor/sebastian/code-unit-reverse-lookup/.travis.yml create mode 100644 src/composer/vendor/sebastian/code-unit-reverse-lookup/ChangeLog.md create mode 100644 src/composer/vendor/sebastian/code-unit-reverse-lookup/LICENSE create mode 100644 src/composer/vendor/sebastian/code-unit-reverse-lookup/README.md create mode 100644 src/composer/vendor/sebastian/code-unit-reverse-lookup/build.xml create mode 100644 src/composer/vendor/sebastian/code-unit-reverse-lookup/composer.json create mode 100644 src/composer/vendor/sebastian/code-unit-reverse-lookup/phpunit.xml create mode 100644 src/composer/vendor/sebastian/code-unit-reverse-lookup/src/Wizard.php create mode 100644 src/composer/vendor/sebastian/code-unit-reverse-lookup/tests/WizardTest.php create mode 100644 src/composer/vendor/sebastian/comparator/.gitignore create mode 100644 src/composer/vendor/sebastian/comparator/.travis.yml create mode 100644 src/composer/vendor/sebastian/comparator/LICENSE create mode 100644 src/composer/vendor/sebastian/comparator/README.md create mode 100644 src/composer/vendor/sebastian/comparator/build.xml create mode 100644 src/composer/vendor/sebastian/comparator/build/travis-ci.xml create mode 100644 src/composer/vendor/sebastian/comparator/composer.json create mode 100644 src/composer/vendor/sebastian/comparator/phpunit.xml.dist create mode 100644 src/composer/vendor/sebastian/comparator/src/ArrayComparator.php create mode 100644 src/composer/vendor/sebastian/comparator/src/Comparator.php create mode 100644 src/composer/vendor/sebastian/comparator/src/ComparisonFailure.php create mode 100644 src/composer/vendor/sebastian/comparator/src/DOMNodeComparator.php create mode 100644 src/composer/vendor/sebastian/comparator/src/DateTimeComparator.php create mode 100644 src/composer/vendor/sebastian/comparator/src/DoubleComparator.php create mode 100644 src/composer/vendor/sebastian/comparator/src/ExceptionComparator.php create mode 100644 src/composer/vendor/sebastian/comparator/src/Factory.php create mode 100644 src/composer/vendor/sebastian/comparator/src/MockObjectComparator.php create mode 100644 src/composer/vendor/sebastian/comparator/src/NumericComparator.php create mode 100644 src/composer/vendor/sebastian/comparator/src/ObjectComparator.php create mode 100644 src/composer/vendor/sebastian/comparator/src/ResourceComparator.php create mode 100644 src/composer/vendor/sebastian/comparator/src/ScalarComparator.php create mode 100644 src/composer/vendor/sebastian/comparator/src/SplObjectStorageComparator.php create mode 100644 src/composer/vendor/sebastian/comparator/src/TypeComparator.php create mode 100644 src/composer/vendor/sebastian/comparator/tests/ArrayComparatorTest.php create mode 100644 src/composer/vendor/sebastian/comparator/tests/DOMNodeComparatorTest.php create mode 100644 src/composer/vendor/sebastian/comparator/tests/DateTimeComparatorTest.php create mode 100644 src/composer/vendor/sebastian/comparator/tests/DoubleComparatorTest.php create mode 100644 src/composer/vendor/sebastian/comparator/tests/ExceptionComparatorTest.php create mode 100644 src/composer/vendor/sebastian/comparator/tests/FactoryTest.php create mode 100644 src/composer/vendor/sebastian/comparator/tests/MockObjectComparatorTest.php create mode 100644 src/composer/vendor/sebastian/comparator/tests/NumericComparatorTest.php create mode 100644 src/composer/vendor/sebastian/comparator/tests/ObjectComparatorTest.php create mode 100644 src/composer/vendor/sebastian/comparator/tests/ResourceComparatorTest.php create mode 100644 src/composer/vendor/sebastian/comparator/tests/ScalarComparatorTest.php create mode 100644 src/composer/vendor/sebastian/comparator/tests/SplObjectStorageComparatorTest.php create mode 100644 src/composer/vendor/sebastian/comparator/tests/TypeComparatorTest.php create mode 100644 src/composer/vendor/sebastian/comparator/tests/_files/Author.php create mode 100644 src/composer/vendor/sebastian/comparator/tests/_files/Book.php create mode 100644 src/composer/vendor/sebastian/comparator/tests/_files/ClassWithToString.php create mode 100644 src/composer/vendor/sebastian/comparator/tests/_files/SampleClass.php create mode 100644 src/composer/vendor/sebastian/comparator/tests/_files/Struct.php create mode 100644 src/composer/vendor/sebastian/comparator/tests/_files/TestClass.php create mode 100644 src/composer/vendor/sebastian/comparator/tests/_files/TestClassComparator.php create mode 100644 src/composer/vendor/sebastian/comparator/tests/autoload.php create mode 100644 src/composer/vendor/sebastian/comparator/tests/bootstrap.php create mode 100644 src/composer/vendor/sebastian/diff/.gitignore create mode 100644 src/composer/vendor/sebastian/diff/.php_cs create mode 100644 src/composer/vendor/sebastian/diff/.travis.yml create mode 100644 src/composer/vendor/sebastian/diff/LICENSE create mode 100644 src/composer/vendor/sebastian/diff/README.md create mode 100644 src/composer/vendor/sebastian/diff/build.xml create mode 100644 src/composer/vendor/sebastian/diff/composer.json create mode 100644 src/composer/vendor/sebastian/diff/phpunit.xml.dist create mode 100644 src/composer/vendor/sebastian/diff/src/Chunk.php create mode 100644 src/composer/vendor/sebastian/diff/src/Diff.php create mode 100644 src/composer/vendor/sebastian/diff/src/Differ.php create mode 100644 src/composer/vendor/sebastian/diff/src/LCS/LongestCommonSubsequence.php create mode 100644 src/composer/vendor/sebastian/diff/src/LCS/MemoryEfficientLongestCommonSubsequenceImplementation.php create mode 100644 src/composer/vendor/sebastian/diff/src/LCS/TimeEfficientLongestCommonSubsequenceImplementation.php create mode 100644 src/composer/vendor/sebastian/diff/src/Line.php create mode 100644 src/composer/vendor/sebastian/diff/src/Parser.php create mode 100644 src/composer/vendor/sebastian/diff/tests/DifferTest.php create mode 100644 src/composer/vendor/sebastian/diff/tests/LCS/TimeEfficientImplementationTest.php create mode 100644 src/composer/vendor/sebastian/diff/tests/ParserTest.php create mode 100644 src/composer/vendor/sebastian/diff/tests/fixtures/patch.txt create mode 100644 src/composer/vendor/sebastian/diff/tests/fixtures/patch2.txt create mode 100644 src/composer/vendor/sebastian/environment/.gitignore create mode 100644 src/composer/vendor/sebastian/environment/.travis.yml create mode 100644 src/composer/vendor/sebastian/environment/LICENSE create mode 100644 src/composer/vendor/sebastian/environment/README.md create mode 100644 src/composer/vendor/sebastian/environment/build.xml create mode 100644 src/composer/vendor/sebastian/environment/composer.json create mode 100644 src/composer/vendor/sebastian/environment/phpunit.xml create mode 100644 src/composer/vendor/sebastian/environment/src/Console.php create mode 100644 src/composer/vendor/sebastian/environment/src/Runtime.php create mode 100644 src/composer/vendor/sebastian/environment/tests/ConsoleTest.php create mode 100644 src/composer/vendor/sebastian/environment/tests/RuntimeTest.php create mode 100644 src/composer/vendor/sebastian/exporter/.gitignore create mode 100644 src/composer/vendor/sebastian/exporter/.travis.yml create mode 100644 src/composer/vendor/sebastian/exporter/LICENSE create mode 100644 src/composer/vendor/sebastian/exporter/README.md create mode 100644 src/composer/vendor/sebastian/exporter/build.xml create mode 100644 src/composer/vendor/sebastian/exporter/composer.json create mode 100644 src/composer/vendor/sebastian/exporter/phpunit.xml.dist create mode 100644 src/composer/vendor/sebastian/exporter/src/Exporter.php create mode 100644 src/composer/vendor/sebastian/exporter/tests/ExporterTest.php create mode 100644 src/composer/vendor/sebastian/global-state/.gitignore create mode 100644 src/composer/vendor/sebastian/global-state/.travis.yml create mode 100644 src/composer/vendor/sebastian/global-state/LICENSE create mode 100644 src/composer/vendor/sebastian/global-state/README.md create mode 100644 src/composer/vendor/sebastian/global-state/build.xml create mode 100644 src/composer/vendor/sebastian/global-state/composer.json create mode 100644 src/composer/vendor/sebastian/global-state/phpunit.xml.dist create mode 100644 src/composer/vendor/sebastian/global-state/src/Blacklist.php create mode 100644 src/composer/vendor/sebastian/global-state/src/CodeExporter.php create mode 100644 src/composer/vendor/sebastian/global-state/src/Exception.php create mode 100644 src/composer/vendor/sebastian/global-state/src/Restorer.php create mode 100644 src/composer/vendor/sebastian/global-state/src/RuntimeException.php create mode 100644 src/composer/vendor/sebastian/global-state/src/Snapshot.php create mode 100644 src/composer/vendor/sebastian/global-state/tests/BlacklistTest.php create mode 100644 src/composer/vendor/sebastian/global-state/tests/SnapshotTest.php create mode 100644 src/composer/vendor/sebastian/global-state/tests/_fixture/BlacklistedChildClass.php create mode 100644 src/composer/vendor/sebastian/global-state/tests/_fixture/BlacklistedClass.php create mode 100644 src/composer/vendor/sebastian/global-state/tests/_fixture/BlacklistedImplementor.php create mode 100644 src/composer/vendor/sebastian/global-state/tests/_fixture/BlacklistedInterface.php create mode 100644 src/composer/vendor/sebastian/global-state/tests/_fixture/SnapshotClass.php create mode 100644 src/composer/vendor/sebastian/global-state/tests/_fixture/SnapshotDomDocument.php create mode 100644 src/composer/vendor/sebastian/global-state/tests/_fixture/SnapshotFunctions.php create mode 100644 src/composer/vendor/sebastian/global-state/tests/_fixture/SnapshotTrait.php create mode 100644 src/composer/vendor/sebastian/object-enumerator/.gitignore create mode 100644 src/composer/vendor/sebastian/object-enumerator/.php_cs create mode 100644 src/composer/vendor/sebastian/object-enumerator/.travis.yml create mode 100644 src/composer/vendor/sebastian/object-enumerator/ChangeLog.md create mode 100644 src/composer/vendor/sebastian/object-enumerator/LICENSE create mode 100644 src/composer/vendor/sebastian/object-enumerator/README.md create mode 100644 src/composer/vendor/sebastian/object-enumerator/build.xml create mode 100644 src/composer/vendor/sebastian/object-enumerator/composer.json create mode 100644 src/composer/vendor/sebastian/object-enumerator/phpunit.xml create mode 100644 src/composer/vendor/sebastian/object-enumerator/src/Enumerator.php create mode 100644 src/composer/vendor/sebastian/object-enumerator/src/Exception.php create mode 100644 src/composer/vendor/sebastian/object-enumerator/src/InvalidArgumentException.php create mode 100644 src/composer/vendor/sebastian/object-enumerator/tests/EnumeratorTest.php create mode 100644 src/composer/vendor/sebastian/recursion-context/.gitignore create mode 100644 src/composer/vendor/sebastian/recursion-context/.travis.yml create mode 100644 src/composer/vendor/sebastian/recursion-context/LICENSE create mode 100644 src/composer/vendor/sebastian/recursion-context/README.md create mode 100644 src/composer/vendor/sebastian/recursion-context/build.xml create mode 100644 src/composer/vendor/sebastian/recursion-context/composer.json create mode 100644 src/composer/vendor/sebastian/recursion-context/phpunit.xml.dist create mode 100644 src/composer/vendor/sebastian/recursion-context/src/Context.php create mode 100644 src/composer/vendor/sebastian/recursion-context/src/Exception.php create mode 100644 src/composer/vendor/sebastian/recursion-context/src/InvalidArgumentException.php create mode 100644 src/composer/vendor/sebastian/recursion-context/tests/ContextTest.php create mode 100644 src/composer/vendor/sebastian/resource-operations/.gitignore create mode 100644 src/composer/vendor/sebastian/resource-operations/LICENSE create mode 100644 src/composer/vendor/sebastian/resource-operations/README.md create mode 100644 src/composer/vendor/sebastian/resource-operations/build.xml create mode 100755 src/composer/vendor/sebastian/resource-operations/build/generate.php create mode 100644 src/composer/vendor/sebastian/resource-operations/composer.json create mode 100644 src/composer/vendor/sebastian/resource-operations/src/ResourceOperations.php create mode 100644 src/composer/vendor/sebastian/version/.gitattributes create mode 100644 src/composer/vendor/sebastian/version/.gitignore create mode 100644 src/composer/vendor/sebastian/version/.php_cs create mode 100644 src/composer/vendor/sebastian/version/LICENSE create mode 100644 src/composer/vendor/sebastian/version/README.md create mode 100644 src/composer/vendor/sebastian/version/composer.json create mode 100644 src/composer/vendor/sebastian/version/src/Version.php create mode 100644 src/composer/vendor/symfony/console/.gitignore create mode 100644 src/composer/vendor/symfony/console/Application.php create mode 100644 src/composer/vendor/symfony/console/CHANGELOG.md create mode 100644 src/composer/vendor/symfony/console/Command/Command.php create mode 100644 src/composer/vendor/symfony/console/Command/HelpCommand.php create mode 100644 src/composer/vendor/symfony/console/Command/ListCommand.php create mode 100644 src/composer/vendor/symfony/console/ConsoleEvents.php create mode 100644 src/composer/vendor/symfony/console/Descriptor/ApplicationDescription.php create mode 100644 src/composer/vendor/symfony/console/Descriptor/Descriptor.php create mode 100644 src/composer/vendor/symfony/console/Descriptor/DescriptorInterface.php create mode 100644 src/composer/vendor/symfony/console/Descriptor/JsonDescriptor.php create mode 100644 src/composer/vendor/symfony/console/Descriptor/MarkdownDescriptor.php create mode 100644 src/composer/vendor/symfony/console/Descriptor/TextDescriptor.php create mode 100644 src/composer/vendor/symfony/console/Descriptor/XmlDescriptor.php create mode 100644 src/composer/vendor/symfony/console/Event/ConsoleCommandEvent.php create mode 100644 src/composer/vendor/symfony/console/Event/ConsoleEvent.php create mode 100644 src/composer/vendor/symfony/console/Event/ConsoleExceptionEvent.php create mode 100644 src/composer/vendor/symfony/console/Event/ConsoleTerminateEvent.php create mode 100644 src/composer/vendor/symfony/console/Exception/CommandNotFoundException.php create mode 100644 src/composer/vendor/symfony/console/Exception/ExceptionInterface.php create mode 100644 src/composer/vendor/symfony/console/Exception/InvalidArgumentException.php create mode 100644 src/composer/vendor/symfony/console/Exception/InvalidOptionException.php create mode 100644 src/composer/vendor/symfony/console/Exception/LogicException.php create mode 100644 src/composer/vendor/symfony/console/Exception/RuntimeException.php create mode 100644 src/composer/vendor/symfony/console/Formatter/OutputFormatter.php create mode 100644 src/composer/vendor/symfony/console/Formatter/OutputFormatterInterface.php create mode 100644 src/composer/vendor/symfony/console/Formatter/OutputFormatterStyle.php create mode 100644 src/composer/vendor/symfony/console/Formatter/OutputFormatterStyleInterface.php create mode 100644 src/composer/vendor/symfony/console/Formatter/OutputFormatterStyleStack.php create mode 100644 src/composer/vendor/symfony/console/Helper/DebugFormatterHelper.php create mode 100644 src/composer/vendor/symfony/console/Helper/DescriptorHelper.php create mode 100644 src/composer/vendor/symfony/console/Helper/FormatterHelper.php create mode 100644 src/composer/vendor/symfony/console/Helper/Helper.php create mode 100644 src/composer/vendor/symfony/console/Helper/HelperInterface.php create mode 100644 src/composer/vendor/symfony/console/Helper/HelperSet.php create mode 100644 src/composer/vendor/symfony/console/Helper/InputAwareHelper.php create mode 100644 src/composer/vendor/symfony/console/Helper/ProcessHelper.php create mode 100644 src/composer/vendor/symfony/console/Helper/ProgressBar.php create mode 100644 src/composer/vendor/symfony/console/Helper/ProgressIndicator.php create mode 100644 src/composer/vendor/symfony/console/Helper/QuestionHelper.php create mode 100644 src/composer/vendor/symfony/console/Helper/SymfonyQuestionHelper.php create mode 100644 src/composer/vendor/symfony/console/Helper/Table.php create mode 100644 src/composer/vendor/symfony/console/Helper/TableCell.php create mode 100644 src/composer/vendor/symfony/console/Helper/TableSeparator.php create mode 100644 src/composer/vendor/symfony/console/Helper/TableStyle.php create mode 100644 src/composer/vendor/symfony/console/Input/ArgvInput.php create mode 100644 src/composer/vendor/symfony/console/Input/ArrayInput.php create mode 100644 src/composer/vendor/symfony/console/Input/Input.php create mode 100644 src/composer/vendor/symfony/console/Input/InputArgument.php create mode 100644 src/composer/vendor/symfony/console/Input/InputAwareInterface.php create mode 100644 src/composer/vendor/symfony/console/Input/InputDefinition.php create mode 100644 src/composer/vendor/symfony/console/Input/InputInterface.php create mode 100644 src/composer/vendor/symfony/console/Input/InputOption.php create mode 100644 src/composer/vendor/symfony/console/Input/StringInput.php create mode 100644 src/composer/vendor/symfony/console/LICENSE create mode 100644 src/composer/vendor/symfony/console/Logger/ConsoleLogger.php create mode 100644 src/composer/vendor/symfony/console/Output/BufferedOutput.php create mode 100644 src/composer/vendor/symfony/console/Output/ConsoleOutput.php create mode 100644 src/composer/vendor/symfony/console/Output/ConsoleOutputInterface.php create mode 100644 src/composer/vendor/symfony/console/Output/NullOutput.php create mode 100644 src/composer/vendor/symfony/console/Output/Output.php create mode 100644 src/composer/vendor/symfony/console/Output/OutputInterface.php create mode 100644 src/composer/vendor/symfony/console/Output/StreamOutput.php create mode 100644 src/composer/vendor/symfony/console/Question/ChoiceQuestion.php create mode 100644 src/composer/vendor/symfony/console/Question/ConfirmationQuestion.php create mode 100644 src/composer/vendor/symfony/console/Question/Question.php create mode 100644 src/composer/vendor/symfony/console/README.md create mode 100644 src/composer/vendor/symfony/console/Resources/bin/hiddeninput.exe create mode 100644 src/composer/vendor/symfony/console/Style/OutputStyle.php create mode 100644 src/composer/vendor/symfony/console/Style/StyleInterface.php create mode 100644 src/composer/vendor/symfony/console/Style/SymfonyStyle.php create mode 100644 src/composer/vendor/symfony/console/Tester/ApplicationTester.php create mode 100644 src/composer/vendor/symfony/console/Tester/CommandTester.php create mode 100644 src/composer/vendor/symfony/console/Tests/ApplicationTest.php create mode 100644 src/composer/vendor/symfony/console/Tests/Command/CommandTest.php create mode 100644 src/composer/vendor/symfony/console/Tests/Command/HelpCommandTest.php create mode 100644 src/composer/vendor/symfony/console/Tests/Command/ListCommandTest.php create mode 100644 src/composer/vendor/symfony/console/Tests/Descriptor/AbstractDescriptorTest.php create mode 100644 src/composer/vendor/symfony/console/Tests/Descriptor/JsonDescriptorTest.php create mode 100644 src/composer/vendor/symfony/console/Tests/Descriptor/MarkdownDescriptorTest.php create mode 100644 src/composer/vendor/symfony/console/Tests/Descriptor/ObjectsProvider.php create mode 100644 src/composer/vendor/symfony/console/Tests/Descriptor/TextDescriptorTest.php create mode 100644 src/composer/vendor/symfony/console/Tests/Descriptor/XmlDescriptorTest.php create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/BarBucCommand.php create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/DescriptorApplication1.php create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/DescriptorApplication2.php create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/DescriptorCommand1.php create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/DescriptorCommand2.php create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/DummyOutput.php create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/Foo1Command.php create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/Foo2Command.php create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/Foo3Command.php create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/Foo4Command.php create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/Foo5Command.php create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/Foo6Command.php create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/FooCommand.php create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/FooSubnamespaced1Command.php create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/FooSubnamespaced2Command.php create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/FoobarCommand.php create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_0.php create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_1.php create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_10.php create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_11.php create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_12.php create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_13.php create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_14.php create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_15.php create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_16.php create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_2.php create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_3.php create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_4.php create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_5.php create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_6.php create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_7.php create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_8.php create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_9.php create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_0.txt create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_1.txt create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_10.txt create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_11.txt create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_12.txt create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_13.txt create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_14.txt create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_15.txt create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_16.txt create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_2.txt create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_3.txt create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_4.txt create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_5.txt create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_6.txt create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_7.txt create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_8.txt create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_9.txt create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/TestCommand.php create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/application_1.json create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/application_1.md create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/application_1.txt create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/application_1.xml create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/application_2.json create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/application_2.md create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/application_2.txt create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/application_2.xml create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/application_gethelp.txt create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/application_renderexception1.txt create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/application_renderexception2.txt create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/application_renderexception3.txt create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/application_renderexception3decorated.txt create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/application_renderexception4.txt create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/application_renderexception_doublewidth1.txt create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/application_renderexception_doublewidth1decorated.txt create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/application_renderexception_doublewidth2.txt create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/application_run1.txt create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/application_run2.txt create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/application_run3.txt create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/application_run4.txt create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/command_1.json create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/command_1.md create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/command_1.txt create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/command_1.xml create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/command_2.json create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/command_2.md create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/command_2.txt create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/command_2.xml create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/input_argument_1.json create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/input_argument_1.md create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/input_argument_1.txt create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/input_argument_1.xml create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/input_argument_2.json create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/input_argument_2.md create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/input_argument_2.txt create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/input_argument_2.xml create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/input_argument_3.json create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/input_argument_3.md create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/input_argument_3.txt create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/input_argument_3.xml create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/input_argument_4.json create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/input_argument_4.md create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/input_argument_4.txt create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/input_argument_4.xml create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/input_definition_1.json rename .gitmodules => src/composer/vendor/symfony/console/Tests/Fixtures/input_definition_1.md (100%) create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/input_definition_1.txt create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/input_definition_1.xml create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/input_definition_2.json create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/input_definition_2.md create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/input_definition_2.txt create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/input_definition_2.xml create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/input_definition_3.json create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/input_definition_3.md create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/input_definition_3.txt create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/input_definition_3.xml create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/input_definition_4.json create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/input_definition_4.md create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/input_definition_4.txt create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/input_definition_4.xml create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/input_option_1.json create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/input_option_1.md create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/input_option_1.txt create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/input_option_1.xml create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/input_option_2.json create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/input_option_2.md create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/input_option_2.txt create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/input_option_2.xml create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/input_option_3.json create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/input_option_3.md create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/input_option_3.txt create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/input_option_3.xml create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/input_option_4.json create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/input_option_4.md create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/input_option_4.txt create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/input_option_4.xml create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/input_option_5.json create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/input_option_5.md create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/input_option_5.txt create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/input_option_5.xml create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/input_option_6.json create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/input_option_6.md create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/input_option_6.txt create mode 100644 src/composer/vendor/symfony/console/Tests/Fixtures/input_option_6.xml create mode 100644 src/composer/vendor/symfony/console/Tests/Formatter/OutputFormatterStyleStackTest.php create mode 100644 src/composer/vendor/symfony/console/Tests/Formatter/OutputFormatterStyleTest.php create mode 100644 src/composer/vendor/symfony/console/Tests/Formatter/OutputFormatterTest.php create mode 100644 src/composer/vendor/symfony/console/Tests/Helper/FormatterHelperTest.php create mode 100644 src/composer/vendor/symfony/console/Tests/Helper/HelperSetTest.php create mode 100644 src/composer/vendor/symfony/console/Tests/Helper/HelperTest.php create mode 100644 src/composer/vendor/symfony/console/Tests/Helper/ProcessHelperTest.php create mode 100644 src/composer/vendor/symfony/console/Tests/Helper/ProgressBarTest.php create mode 100644 src/composer/vendor/symfony/console/Tests/Helper/ProgressIndicatorTest.php create mode 100644 src/composer/vendor/symfony/console/Tests/Helper/QuestionHelperTest.php create mode 100644 src/composer/vendor/symfony/console/Tests/Helper/SymfonyQuestionHelperTest.php create mode 100644 src/composer/vendor/symfony/console/Tests/Helper/TableStyleTest.php create mode 100644 src/composer/vendor/symfony/console/Tests/Helper/TableTest.php create mode 100644 src/composer/vendor/symfony/console/Tests/Input/ArgvInputTest.php create mode 100644 src/composer/vendor/symfony/console/Tests/Input/ArrayInputTest.php create mode 100644 src/composer/vendor/symfony/console/Tests/Input/InputArgumentTest.php create mode 100644 src/composer/vendor/symfony/console/Tests/Input/InputDefinitionTest.php create mode 100644 src/composer/vendor/symfony/console/Tests/Input/InputOptionTest.php create mode 100644 src/composer/vendor/symfony/console/Tests/Input/InputTest.php create mode 100644 src/composer/vendor/symfony/console/Tests/Input/StringInputTest.php create mode 100644 src/composer/vendor/symfony/console/Tests/Logger/ConsoleLoggerTest.php create mode 100644 src/composer/vendor/symfony/console/Tests/Output/ConsoleOutputTest.php create mode 100644 src/composer/vendor/symfony/console/Tests/Output/NullOutputTest.php create mode 100644 src/composer/vendor/symfony/console/Tests/Output/OutputTest.php create mode 100644 src/composer/vendor/symfony/console/Tests/Output/StreamOutputTest.php create mode 100644 src/composer/vendor/symfony/console/Tests/Style/SymfonyStyleTest.php create mode 100644 src/composer/vendor/symfony/console/Tests/Tester/ApplicationTesterTest.php create mode 100644 src/composer/vendor/symfony/console/Tests/Tester/CommandTesterTest.php create mode 100644 src/composer/vendor/symfony/console/composer.json create mode 100644 src/composer/vendor/symfony/console/phpunit.xml.dist create mode 100644 src/composer/vendor/symfony/debug/.gitignore create mode 100644 src/composer/vendor/symfony/debug/BufferingLogger.php create mode 100644 src/composer/vendor/symfony/debug/CHANGELOG.md create mode 100644 src/composer/vendor/symfony/debug/Debug.php create mode 100644 src/composer/vendor/symfony/debug/DebugClassLoader.php create mode 100644 src/composer/vendor/symfony/debug/ErrorHandler.php create mode 100644 src/composer/vendor/symfony/debug/Exception/ClassNotFoundException.php create mode 100644 src/composer/vendor/symfony/debug/Exception/ContextErrorException.php create mode 100644 src/composer/vendor/symfony/debug/Exception/FatalErrorException.php create mode 100644 src/composer/vendor/symfony/debug/Exception/FatalThrowableError.php create mode 100644 src/composer/vendor/symfony/debug/Exception/FlattenException.php create mode 100644 src/composer/vendor/symfony/debug/Exception/OutOfMemoryException.php create mode 100644 src/composer/vendor/symfony/debug/Exception/UndefinedFunctionException.php create mode 100644 src/composer/vendor/symfony/debug/Exception/UndefinedMethodException.php create mode 100644 src/composer/vendor/symfony/debug/ExceptionHandler.php create mode 100644 src/composer/vendor/symfony/debug/FatalErrorHandler/ClassNotFoundFatalErrorHandler.php create mode 100644 src/composer/vendor/symfony/debug/FatalErrorHandler/FatalErrorHandlerInterface.php create mode 100644 src/composer/vendor/symfony/debug/FatalErrorHandler/UndefinedFunctionFatalErrorHandler.php create mode 100644 src/composer/vendor/symfony/debug/FatalErrorHandler/UndefinedMethodFatalErrorHandler.php create mode 100644 src/composer/vendor/symfony/debug/LICENSE create mode 100644 src/composer/vendor/symfony/debug/README.md create mode 100644 src/composer/vendor/symfony/debug/Resources/ext/README.md create mode 100644 src/composer/vendor/symfony/debug/Resources/ext/config.m4 create mode 100644 src/composer/vendor/symfony/debug/Resources/ext/config.w32 create mode 100644 src/composer/vendor/symfony/debug/Resources/ext/php_symfony_debug.h create mode 100644 src/composer/vendor/symfony/debug/Resources/ext/symfony_debug.c create mode 100644 src/composer/vendor/symfony/debug/Resources/ext/tests/001.phpt create mode 100644 src/composer/vendor/symfony/debug/Resources/ext/tests/002.phpt create mode 100644 src/composer/vendor/symfony/debug/Resources/ext/tests/002_1.phpt create mode 100644 src/composer/vendor/symfony/debug/Resources/ext/tests/003.phpt create mode 100644 src/composer/vendor/symfony/debug/Tests/DebugClassLoaderTest.php create mode 100644 src/composer/vendor/symfony/debug/Tests/ErrorHandlerTest.php create mode 100644 src/composer/vendor/symfony/debug/Tests/Exception/FlattenExceptionTest.php create mode 100644 src/composer/vendor/symfony/debug/Tests/ExceptionHandlerTest.php create mode 100644 src/composer/vendor/symfony/debug/Tests/FatalErrorHandler/ClassNotFoundFatalErrorHandlerTest.php create mode 100644 src/composer/vendor/symfony/debug/Tests/FatalErrorHandler/UndefinedFunctionFatalErrorHandlerTest.php create mode 100644 src/composer/vendor/symfony/debug/Tests/FatalErrorHandler/UndefinedMethodFatalErrorHandlerTest.php create mode 100644 src/composer/vendor/symfony/debug/Tests/Fixtures/ClassAlias.php create mode 100644 src/composer/vendor/symfony/debug/Tests/Fixtures/DeprecatedClass.php create mode 100644 src/composer/vendor/symfony/debug/Tests/Fixtures/DeprecatedInterface.php create mode 100644 src/composer/vendor/symfony/debug/Tests/Fixtures/NonDeprecatedInterface.php create mode 100644 src/composer/vendor/symfony/debug/Tests/Fixtures/PEARClass.php create mode 100644 src/composer/vendor/symfony/debug/Tests/Fixtures/ToStringThrower.php create mode 100644 src/composer/vendor/symfony/debug/Tests/Fixtures/casemismatch.php create mode 100644 src/composer/vendor/symfony/debug/Tests/Fixtures/notPsr0Bis.php create mode 100644 src/composer/vendor/symfony/debug/Tests/Fixtures/psr4/Psr4CaseMismatch.php create mode 100644 src/composer/vendor/symfony/debug/Tests/Fixtures/reallyNotPsr0.php create mode 100644 src/composer/vendor/symfony/debug/Tests/Fixtures2/RequiredTwice.php create mode 100644 src/composer/vendor/symfony/debug/Tests/HeaderMock.php create mode 100644 src/composer/vendor/symfony/debug/Tests/MockExceptionHandler.php create mode 100644 src/composer/vendor/symfony/debug/composer.json create mode 100644 src/composer/vendor/symfony/debug/phpunit.xml.dist create mode 100644 src/composer/vendor/symfony/event-dispatcher/.gitignore create mode 100644 src/composer/vendor/symfony/event-dispatcher/CHANGELOG.md create mode 100644 src/composer/vendor/symfony/event-dispatcher/ContainerAwareEventDispatcher.php create mode 100644 src/composer/vendor/symfony/event-dispatcher/Debug/TraceableEventDispatcher.php create mode 100644 src/composer/vendor/symfony/event-dispatcher/Debug/TraceableEventDispatcherInterface.php create mode 100644 src/composer/vendor/symfony/event-dispatcher/Debug/WrappedListener.php create mode 100644 src/composer/vendor/symfony/event-dispatcher/DependencyInjection/RegisterListenersPass.php create mode 100644 src/composer/vendor/symfony/event-dispatcher/Event.php create mode 100644 src/composer/vendor/symfony/event-dispatcher/EventDispatcher.php create mode 100644 src/composer/vendor/symfony/event-dispatcher/EventDispatcherInterface.php create mode 100644 src/composer/vendor/symfony/event-dispatcher/EventSubscriberInterface.php create mode 100644 src/composer/vendor/symfony/event-dispatcher/GenericEvent.php create mode 100644 src/composer/vendor/symfony/event-dispatcher/ImmutableEventDispatcher.php create mode 100644 src/composer/vendor/symfony/event-dispatcher/LICENSE create mode 100644 src/composer/vendor/symfony/event-dispatcher/README.md create mode 100644 src/composer/vendor/symfony/event-dispatcher/Tests/AbstractEventDispatcherTest.php create mode 100644 src/composer/vendor/symfony/event-dispatcher/Tests/ContainerAwareEventDispatcherTest.php create mode 100644 src/composer/vendor/symfony/event-dispatcher/Tests/Debug/TraceableEventDispatcherTest.php create mode 100644 src/composer/vendor/symfony/event-dispatcher/Tests/DependencyInjection/RegisterListenersPassTest.php create mode 100644 src/composer/vendor/symfony/event-dispatcher/Tests/EventDispatcherTest.php create mode 100644 src/composer/vendor/symfony/event-dispatcher/Tests/EventTest.php create mode 100644 src/composer/vendor/symfony/event-dispatcher/Tests/GenericEventTest.php create mode 100644 src/composer/vendor/symfony/event-dispatcher/Tests/ImmutableEventDispatcherTest.php create mode 100644 src/composer/vendor/symfony/event-dispatcher/composer.json create mode 100644 src/composer/vendor/symfony/event-dispatcher/phpunit.xml.dist create mode 100644 src/composer/vendor/symfony/filesystem/.gitignore create mode 100644 src/composer/vendor/symfony/filesystem/CHANGELOG.md create mode 100644 src/composer/vendor/symfony/filesystem/Exception/ExceptionInterface.php create mode 100644 src/composer/vendor/symfony/filesystem/Exception/FileNotFoundException.php create mode 100644 src/composer/vendor/symfony/filesystem/Exception/IOException.php create mode 100644 src/composer/vendor/symfony/filesystem/Exception/IOExceptionInterface.php create mode 100644 src/composer/vendor/symfony/filesystem/Filesystem.php create mode 100644 src/composer/vendor/symfony/filesystem/LICENSE create mode 100644 src/composer/vendor/symfony/filesystem/LockHandler.php create mode 100644 src/composer/vendor/symfony/filesystem/README.md create mode 100644 src/composer/vendor/symfony/filesystem/Tests/ExceptionTest.php create mode 100644 src/composer/vendor/symfony/filesystem/Tests/FilesystemTest.php create mode 100644 src/composer/vendor/symfony/filesystem/Tests/FilesystemTestCase.php create mode 100644 src/composer/vendor/symfony/filesystem/Tests/Fixtures/MockStream/MockStream.php create mode 100644 src/composer/vendor/symfony/filesystem/Tests/LockHandlerTest.php create mode 100644 src/composer/vendor/symfony/filesystem/composer.json create mode 100644 src/composer/vendor/symfony/filesystem/phpunit.xml.dist create mode 100644 src/composer/vendor/symfony/finder/.gitignore create mode 100644 src/composer/vendor/symfony/finder/CHANGELOG.md create mode 100644 src/composer/vendor/symfony/finder/Comparator/Comparator.php create mode 100644 src/composer/vendor/symfony/finder/Comparator/DateComparator.php create mode 100644 src/composer/vendor/symfony/finder/Comparator/NumberComparator.php create mode 100644 src/composer/vendor/symfony/finder/Exception/AccessDeniedException.php create mode 100644 src/composer/vendor/symfony/finder/Exception/ExceptionInterface.php create mode 100644 src/composer/vendor/symfony/finder/Finder.php create mode 100644 src/composer/vendor/symfony/finder/Glob.php create mode 100644 src/composer/vendor/symfony/finder/Iterator/CustomFilterIterator.php create mode 100644 src/composer/vendor/symfony/finder/Iterator/DateRangeFilterIterator.php create mode 100644 src/composer/vendor/symfony/finder/Iterator/DepthRangeFilterIterator.php create mode 100644 src/composer/vendor/symfony/finder/Iterator/ExcludeDirectoryFilterIterator.php create mode 100644 src/composer/vendor/symfony/finder/Iterator/FileTypeFilterIterator.php create mode 100644 src/composer/vendor/symfony/finder/Iterator/FilecontentFilterIterator.php create mode 100644 src/composer/vendor/symfony/finder/Iterator/FilenameFilterIterator.php create mode 100644 src/composer/vendor/symfony/finder/Iterator/FilterIterator.php create mode 100644 src/composer/vendor/symfony/finder/Iterator/MultiplePcreFilterIterator.php create mode 100644 src/composer/vendor/symfony/finder/Iterator/PathFilterIterator.php create mode 100644 src/composer/vendor/symfony/finder/Iterator/RecursiveDirectoryIterator.php create mode 100644 src/composer/vendor/symfony/finder/Iterator/SizeRangeFilterIterator.php create mode 100644 src/composer/vendor/symfony/finder/Iterator/SortableIterator.php create mode 100644 src/composer/vendor/symfony/finder/LICENSE create mode 100644 src/composer/vendor/symfony/finder/README.md create mode 100644 src/composer/vendor/symfony/finder/SplFileInfo.php create mode 100644 src/composer/vendor/symfony/finder/Tests/Comparator/ComparatorTest.php create mode 100644 src/composer/vendor/symfony/finder/Tests/Comparator/DateComparatorTest.php create mode 100644 src/composer/vendor/symfony/finder/Tests/Comparator/NumberComparatorTest.php create mode 100644 src/composer/vendor/symfony/finder/Tests/FinderTest.php create mode 100644 src/composer/vendor/symfony/finder/Tests/Fixtures/A/B/C/abc.dat create mode 100644 src/composer/vendor/symfony/finder/Tests/Fixtures/A/B/ab.dat create mode 100644 src/composer/vendor/symfony/finder/Tests/Fixtures/A/a.dat create mode 100644 src/composer/vendor/symfony/finder/Tests/Fixtures/copy/A/B/C/abc.dat.copy create mode 100644 src/composer/vendor/symfony/finder/Tests/Fixtures/copy/A/B/ab.dat.copy create mode 100644 src/composer/vendor/symfony/finder/Tests/Fixtures/copy/A/a.dat.copy create mode 100644 src/composer/vendor/symfony/finder/Tests/Fixtures/dolor.txt create mode 100644 src/composer/vendor/symfony/finder/Tests/Fixtures/ipsum.txt create mode 100644 src/composer/vendor/symfony/finder/Tests/Fixtures/lorem.txt create mode 100644 src/composer/vendor/symfony/finder/Tests/Fixtures/one/a create mode 100644 src/composer/vendor/symfony/finder/Tests/Fixtures/one/b/c.neon create mode 100644 src/composer/vendor/symfony/finder/Tests/Fixtures/one/b/d.neon create mode 100644 src/composer/vendor/symfony/finder/Tests/Fixtures/r+e.gex[c]a(r)s/dir/bar.dat create mode 100644 src/composer/vendor/symfony/finder/Tests/Fixtures/with space/foo.txt create mode 100755 src/composer/vendor/symfony/finder/Tests/GlobTest.php create mode 100644 src/composer/vendor/symfony/finder/Tests/Iterator/CustomFilterIteratorTest.php create mode 100644 src/composer/vendor/symfony/finder/Tests/Iterator/DateRangeFilterIteratorTest.php create mode 100644 src/composer/vendor/symfony/finder/Tests/Iterator/DepthRangeFilterIteratorTest.php create mode 100644 src/composer/vendor/symfony/finder/Tests/Iterator/ExcludeDirectoryFilterIteratorTest.php create mode 100644 src/composer/vendor/symfony/finder/Tests/Iterator/FileTypeFilterIteratorTest.php create mode 100644 src/composer/vendor/symfony/finder/Tests/Iterator/FilecontentFilterIteratorTest.php create mode 100644 src/composer/vendor/symfony/finder/Tests/Iterator/FilenameFilterIteratorTest.php create mode 100644 src/composer/vendor/symfony/finder/Tests/Iterator/FilterIteratorTest.php create mode 100644 src/composer/vendor/symfony/finder/Tests/Iterator/Iterator.php create mode 100644 src/composer/vendor/symfony/finder/Tests/Iterator/IteratorTestCase.php create mode 100644 src/composer/vendor/symfony/finder/Tests/Iterator/MockFileListIterator.php create mode 100644 src/composer/vendor/symfony/finder/Tests/Iterator/MockSplFileInfo.php create mode 100644 src/composer/vendor/symfony/finder/Tests/Iterator/MultiplePcreFilterIteratorTest.php create mode 100644 src/composer/vendor/symfony/finder/Tests/Iterator/PathFilterIteratorTest.php create mode 100644 src/composer/vendor/symfony/finder/Tests/Iterator/RealIteratorTestCase.php create mode 100644 src/composer/vendor/symfony/finder/Tests/Iterator/RecursiveDirectoryIteratorTest.php create mode 100644 src/composer/vendor/symfony/finder/Tests/Iterator/SizeRangeFilterIteratorTest.php create mode 100644 src/composer/vendor/symfony/finder/Tests/Iterator/SortableIteratorTest.php create mode 100644 src/composer/vendor/symfony/finder/composer.json create mode 100644 src/composer/vendor/symfony/finder/phpunit.xml.dist create mode 100644 src/composer/vendor/symfony/polyfill-mbstring/LICENSE create mode 100644 src/composer/vendor/symfony/polyfill-mbstring/Mbstring.php create mode 100644 src/composer/vendor/symfony/polyfill-mbstring/README.md create mode 100644 src/composer/vendor/symfony/polyfill-mbstring/Resources/unidata/lowerCase.php create mode 100644 src/composer/vendor/symfony/polyfill-mbstring/Resources/unidata/upperCase.php create mode 100644 src/composer/vendor/symfony/polyfill-mbstring/bootstrap.php create mode 100644 src/composer/vendor/symfony/polyfill-mbstring/composer.json create mode 100644 src/composer/vendor/symfony/process/.gitignore create mode 100644 src/composer/vendor/symfony/process/CHANGELOG.md create mode 100644 src/composer/vendor/symfony/process/Exception/ExceptionInterface.php create mode 100644 src/composer/vendor/symfony/process/Exception/InvalidArgumentException.php create mode 100644 src/composer/vendor/symfony/process/Exception/LogicException.php create mode 100644 src/composer/vendor/symfony/process/Exception/ProcessFailedException.php create mode 100644 src/composer/vendor/symfony/process/Exception/ProcessTimedOutException.php create mode 100644 src/composer/vendor/symfony/process/Exception/RuntimeException.php create mode 100644 src/composer/vendor/symfony/process/ExecutableFinder.php create mode 100644 src/composer/vendor/symfony/process/InputStream.php create mode 100644 src/composer/vendor/symfony/process/LICENSE create mode 100644 src/composer/vendor/symfony/process/PhpExecutableFinder.php create mode 100644 src/composer/vendor/symfony/process/PhpProcess.php create mode 100644 src/composer/vendor/symfony/process/Pipes/AbstractPipes.php create mode 100644 src/composer/vendor/symfony/process/Pipes/PipesInterface.php create mode 100644 src/composer/vendor/symfony/process/Pipes/UnixPipes.php create mode 100644 src/composer/vendor/symfony/process/Pipes/WindowsPipes.php create mode 100644 src/composer/vendor/symfony/process/Process.php create mode 100644 src/composer/vendor/symfony/process/ProcessBuilder.php create mode 100644 src/composer/vendor/symfony/process/ProcessUtils.php create mode 100644 src/composer/vendor/symfony/process/README.md create mode 100644 src/composer/vendor/symfony/process/Tests/ExecutableFinderTest.php create mode 100644 src/composer/vendor/symfony/process/Tests/NonStopableProcess.php create mode 100644 src/composer/vendor/symfony/process/Tests/PhpExecutableFinderTest.php create mode 100644 src/composer/vendor/symfony/process/Tests/PhpProcessTest.php create mode 100644 src/composer/vendor/symfony/process/Tests/PipeStdinInStdoutStdErrStreamSelect.php create mode 100644 src/composer/vendor/symfony/process/Tests/ProcessBuilderTest.php create mode 100644 src/composer/vendor/symfony/process/Tests/ProcessFailedExceptionTest.php create mode 100644 src/composer/vendor/symfony/process/Tests/ProcessTest.php create mode 100644 src/composer/vendor/symfony/process/Tests/ProcessUtilsTest.php create mode 100644 src/composer/vendor/symfony/process/Tests/SignalListener.php create mode 100644 src/composer/vendor/symfony/process/composer.json create mode 100644 src/composer/vendor/symfony/process/phpunit.xml.dist create mode 100644 src/composer/vendor/symfony/yaml/.gitignore create mode 100644 src/composer/vendor/symfony/yaml/CHANGELOG.md create mode 100644 src/composer/vendor/symfony/yaml/Dumper.php create mode 100644 src/composer/vendor/symfony/yaml/Escaper.php create mode 100644 src/composer/vendor/symfony/yaml/Exception/DumpException.php create mode 100644 src/composer/vendor/symfony/yaml/Exception/ExceptionInterface.php create mode 100644 src/composer/vendor/symfony/yaml/Exception/ParseException.php create mode 100644 src/composer/vendor/symfony/yaml/Exception/RuntimeException.php create mode 100644 src/composer/vendor/symfony/yaml/Inline.php create mode 100644 src/composer/vendor/symfony/yaml/LICENSE create mode 100644 src/composer/vendor/symfony/yaml/Parser.php create mode 100644 src/composer/vendor/symfony/yaml/README.md create mode 100644 src/composer/vendor/symfony/yaml/Tests/DumperTest.php create mode 100644 src/composer/vendor/symfony/yaml/Tests/Fixtures/YtsAnchorAlias.yml create mode 100644 src/composer/vendor/symfony/yaml/Tests/Fixtures/YtsBasicTests.yml create mode 100644 src/composer/vendor/symfony/yaml/Tests/Fixtures/YtsBlockMapping.yml create mode 100644 src/composer/vendor/symfony/yaml/Tests/Fixtures/YtsDocumentSeparator.yml create mode 100644 src/composer/vendor/symfony/yaml/Tests/Fixtures/YtsErrorTests.yml create mode 100644 src/composer/vendor/symfony/yaml/Tests/Fixtures/YtsFlowCollections.yml create mode 100644 src/composer/vendor/symfony/yaml/Tests/Fixtures/YtsFoldedScalars.yml create mode 100644 src/composer/vendor/symfony/yaml/Tests/Fixtures/YtsNullsAndEmpties.yml create mode 100644 src/composer/vendor/symfony/yaml/Tests/Fixtures/YtsSpecificationExamples.yml create mode 100644 src/composer/vendor/symfony/yaml/Tests/Fixtures/YtsTypeTransfers.yml create mode 100644 src/composer/vendor/symfony/yaml/Tests/Fixtures/arrow.gif create mode 100644 src/composer/vendor/symfony/yaml/Tests/Fixtures/embededPhp.yml create mode 100644 src/composer/vendor/symfony/yaml/Tests/Fixtures/escapedCharacters.yml create mode 100644 src/composer/vendor/symfony/yaml/Tests/Fixtures/index.yml create mode 100644 src/composer/vendor/symfony/yaml/Tests/Fixtures/multiple_lines_as_literal_block.yml create mode 100644 src/composer/vendor/symfony/yaml/Tests/Fixtures/sfComments.yml create mode 100644 src/composer/vendor/symfony/yaml/Tests/Fixtures/sfCompact.yml create mode 100644 src/composer/vendor/symfony/yaml/Tests/Fixtures/sfMergeKey.yml create mode 100644 src/composer/vendor/symfony/yaml/Tests/Fixtures/sfObjects.yml create mode 100644 src/composer/vendor/symfony/yaml/Tests/Fixtures/sfQuotes.yml create mode 100644 src/composer/vendor/symfony/yaml/Tests/Fixtures/sfTests.yml create mode 100644 src/composer/vendor/symfony/yaml/Tests/Fixtures/unindentedCollections.yml create mode 100644 src/composer/vendor/symfony/yaml/Tests/InlineTest.php create mode 100644 src/composer/vendor/symfony/yaml/Tests/ParseExceptionTest.php create mode 100644 src/composer/vendor/symfony/yaml/Tests/ParserTest.php create mode 100644 src/composer/vendor/symfony/yaml/Tests/YamlTest.php create mode 100644 src/composer/vendor/symfony/yaml/Unescaper.php create mode 100644 src/composer/vendor/symfony/yaml/Yaml.php create mode 100644 src/composer/vendor/symfony/yaml/composer.json create mode 100644 src/composer/vendor/symfony/yaml/phpunit.xml.dist create mode 100644 src/composer/vendor/victorjonsson/markdowndocs/.travis.yml create mode 100644 src/composer/vendor/victorjonsson/markdowndocs/README.md create mode 100755 src/composer/vendor/victorjonsson/markdowndocs/bin/phpdoc-md create mode 100644 src/composer/vendor/victorjonsson/markdowndocs/composer.json create mode 100644 src/composer/vendor/victorjonsson/markdowndocs/docs.md create mode 100755 src/composer/vendor/victorjonsson/markdowndocs/phpdoc-md create mode 100644 src/composer/vendor/victorjonsson/markdowndocs/phpunit.xml create mode 100644 src/composer/vendor/victorjonsson/markdowndocs/src/PHPDocsMD/ClassEntity.php create mode 100644 src/composer/vendor/victorjonsson/markdowndocs/src/PHPDocsMD/ClassEntityFactory.php create mode 100644 src/composer/vendor/victorjonsson/markdowndocs/src/PHPDocsMD/CodeEntity.php create mode 100644 src/composer/vendor/victorjonsson/markdowndocs/src/PHPDocsMD/Console/CLI.php create mode 100644 src/composer/vendor/victorjonsson/markdowndocs/src/PHPDocsMD/Console/PHPDocsMDCommand.php create mode 100644 src/composer/vendor/victorjonsson/markdowndocs/src/PHPDocsMD/DocInfo.php create mode 100644 src/composer/vendor/victorjonsson/markdowndocs/src/PHPDocsMD/DocInfoExtractor.php create mode 100644 src/composer/vendor/victorjonsson/markdowndocs/src/PHPDocsMD/FunctionEntity.php create mode 100644 src/composer/vendor/victorjonsson/markdowndocs/src/PHPDocsMD/FunctionFinder.php create mode 100644 src/composer/vendor/victorjonsson/markdowndocs/src/PHPDocsMD/MDTableGenerator.php create mode 100644 src/composer/vendor/victorjonsson/markdowndocs/src/PHPDocsMD/ParamEntity.php create mode 100644 src/composer/vendor/victorjonsson/markdowndocs/src/PHPDocsMD/Reflector.php create mode 100644 src/composer/vendor/victorjonsson/markdowndocs/src/PHPDocsMD/ReflectorInterface.php create mode 100644 src/composer/vendor/victorjonsson/markdowndocs/src/PHPDocsMD/UseInspector.php create mode 100644 src/composer/vendor/victorjonsson/markdowndocs/src/PHPDocsMD/Utils.php create mode 100644 src/composer/vendor/victorjonsson/markdowndocs/test/ExampleClass.php create mode 100644 src/composer/vendor/victorjonsson/markdowndocs/test/MDTableGeneratorTest.php create mode 100644 src/composer/vendor/victorjonsson/markdowndocs/test/ReflectorTest.php create mode 100644 src/composer/vendor/victorjonsson/markdowndocs/test/UseInspectorTest.php create mode 100644 src/composer/vendor/webmozart/assert/.composer-auth.json create mode 100644 src/composer/vendor/webmozart/assert/.gitignore create mode 100644 src/composer/vendor/webmozart/assert/.styleci.yml create mode 100644 src/composer/vendor/webmozart/assert/.travis.yml create mode 100644 src/composer/vendor/webmozart/assert/CHANGELOG.md create mode 100644 src/composer/vendor/webmozart/assert/LICENSE create mode 100644 src/composer/vendor/webmozart/assert/README.md create mode 100644 src/composer/vendor/webmozart/assert/appveyor.yml create mode 100644 src/composer/vendor/webmozart/assert/composer.json create mode 100644 src/composer/vendor/webmozart/assert/phpunit.xml.dist create mode 100644 src/composer/vendor/webmozart/assert/src/Assert.php create mode 100644 src/composer/vendor/webmozart/assert/tests/AssertTest.php create mode 100644 src/db_migrations/list.php create mode 100644 src/db_migrations/v20161116_190001_unique_index_cron_name.php create mode 100644 src/robo/RoboFile.php create mode 100755 src/robo/robo.phar delete mode 100644 test/admin/UsersActionManagerTest.php create mode 100644 test/classes/FileServiceTest.php create mode 100644 test/classes/LanguageManagerTest.php create mode 100644 test/data/sample.txt create mode 100644 test/smtp.txt diff --git a/.gitignore b/.gitignore index 6b70ddab..fc3bcd98 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,8 @@ /.settings /.buildpath /.project -/.idea -build +/.idea/ +/build +/deployment/clients/dev/data/ +/deployment/clients/test/data/ +/.vagrant diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..c3ddebfb --- /dev/null +++ b/.travis.yml @@ -0,0 +1,8 @@ +language: php +php: + - '5.4' + - '5.5' + - '5.6' + - '7.0' + - hhvm + - nightly \ No newline at end of file diff --git a/Vagrantfile b/Vagrantfile new file mode 100644 index 00000000..4d0f2b62 --- /dev/null +++ b/Vagrantfile @@ -0,0 +1,29 @@ +# -*- mode: ruby -*- +# vi: set ft=ruby : + +Vagrant.configure(2) do |config| + config.vm.box = "thilinah/jessie64_isotope" + config.vm.box_version = "0.0.1" + config.vm.network "private_network", ip: "192.168.40.40" + config.vm.synced_folder ".", "/vagrant", type: "nfs" + + config.vm.provider "virtualbox" do |vb| + vb.memory = "1024" + vb.cpus = "2" + vb.name = "app.dev" + end + + + config.vm.provision "shell", inline: <<-SHELL + sudo apt-get update + SHELL + + config.vm.hostname = "app.dev" + + config.hostsupdater.aliases = [ + "app.dev", + "app.app.dev", + "clients.app.dev" + ] + +end diff --git a/build.xml b/build.xml index 80c96b3d..0426957e 100644 --- a/build.xml +++ b/build.xml @@ -3,6 +3,7 @@ + @@ -16,7 +17,7 @@ description=""/> - + - - - - - - - - - - - - + description="Copy generated files to QA app"> + + + + + + + + + + + + @@ -215,7 +216,13 @@ - + + + + + + + Load($v[1]."= ?",array($item->$k)); - if($tObj->$v[1] == $item->$k){ + if($tObj->{$v[1]} == $item->$k){ $v[2] = str_replace("+"," ",$v[2]); $values = explode(" ", $v[2]); if(count($values) == 1){ $idField = $k."_id"; $item->$idField = $item->$k; - $item->$k = $tObj->$v[2]; + $item->$k = $tObj->{$v[2]}; }else{ $objVal = ""; @@ -551,13 +552,13 @@ class BaseService{ $fTable = $v[0]; $tObj = new $fTable(); $tObj->Load($v[1]."= ?",array($obj->$k)); - if($tObj->$v[1] == $obj->$k){ + if($tObj->{$v[1]} == $obj->$k){ $name = $k."_Name"; $values = explode("+", $v[2]); if(count($values) == 1){ $idField = $name."_id"; $obj->$idField = $obj->$name; - $obj->$name = $tObj->$v[2]; + $obj->$name = $tObj->{$v[2]}; }else{ $objVal = ""; foreach($values as $v){ @@ -1244,6 +1245,14 @@ class BaseService{ return SettingsManager::getInstance()->getSetting('Analytics: Google Key'); } + public function setMigrationManager($migrationManager){ + $this->migrationManager = $migrationManager; + } + + public function getMigrationManager(){ + return $this->migrationManager; + } + /** * Set the audit manager * @method setAuditManager @@ -1575,6 +1584,11 @@ class CustomFieldManager { return $object; } + + + public function syncMigrations(){ + + } } diff --git a/src/classes/LanguageManager.php b/src/classes/LanguageManager.php index 492da0eb..7ffdd69c 100644 --- a/src/classes/LanguageManager.php +++ b/src/classes/LanguageManager.php @@ -35,12 +35,13 @@ class LanguageManager{ private function getCurrentLang(){ $user = BaseService::getInstance()->getCurrentUser(); - LogManager::getInstance()->info("User:".json_encode($user)); if(empty($user) || empty($user->lang) || $user->lang == "NULL"){ $lang = SettingsManager::getInstance()->getSetting('System: Language'); LogManager::getInstance()->info("System Lang:".$lang); }else{ - $lang = $user->lang; + $supportedLang = new SupportedLanguage(); + $supportedLang->Load("id = ?",array($user->lang)); + $lang = $supportedLang->name; } if(empty($lang) || !file_exists(APP_BASE_PATH.'lang/'.$lang.'.po')){ $lang = 'en'; @@ -72,4 +73,4 @@ class LanguageManager{ return $string; } -} \ No newline at end of file +} diff --git a/src/classes/Migration.php b/src/classes/Migration.php new file mode 100644 index 00000000..ab7c3e3d --- /dev/null +++ b/src/classes/Migration.php @@ -0,0 +1,260 @@ +file = $file; + } + + public function up(){ + return true; + } + + public function down(){ + return true; + } + + protected function db(){ + if($this->db == null){ + $this->db = NewADOConnection('mysqli'); + $res = $this->db->Connect(APP_HOST, APP_USERNAME, APP_PASSWORD, APP_DB); + } + return $this->db; + } + + public function getLastError(){ + return $this->lastError; + } + + public function executeQuery($sql){ + $ret = $this->db()->Execute($sql); + if(!$ret){ + $this->lastError = $this->db()->ErrorMsg(); + } + return $ret; + } + + /* + public function up() + { + $sql = <<<'SQL' + create table `Migrations` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `file` varchar(300) NOT NULL, + `version` int(11) NOT NULL, + `created` DATETIME default '0000-00-00 00:00:00', + `updated` DATETIME default '0000-00-00 00:00:00', + `status` enum('Pending','Up','Down','UpError','DownError') default 'Pending', + `last_error` varchar(500) NULL, + primary key (`id`), + unique key `KEY_Migrations_file` (`file`), + index `KEY_Migrations_status` (`status`), + index `KEY_Migrations_status` (`version`) + ) engine=innodb default charset=utf8; +SQL; + return $this->db()->Execute($sql); + } + + public function down() + { + return $this->db()->Execute('DROP TABLE Migrations'); + } + */ +} + + +class MigrationManager{ + + private $migration_path; + + protected $db = null; + + public function __construct() + { + $this->migration_path = APP_BASE_PATH .'/db_migrations/'; + } + + public function setMigrationPath($migration_path){ + $this->migration_path = $migration_path; + } + + public function getMigrationById($id){ + $migration = new Migration(); + $migration->Load("id = ?",array($id)); + return $migration; + } + + public function getCurrentMigrations(){ + $migration = new Migration(); + return $migration->Find("1 = 1"); + } + + public function getPendingMigrations(){ + $migration = new Migration(); + return $migration->Find("status = ?",array('Pending')); + } + + public function getFirstAddedMigration($statuses){ + $migration = new Migration(); + return $migration->Find("status in ('".implode("','",$statuses)."') order by created limit 1",array()); + } + + public function getLastRunMigration($statuses){ + $migration = new Migration(); + return $migration->Find("status in ('".implode("','",$statuses)."') order by updated desc limit 1",array()); + } + + public function queueMigrations(){ + + $migrations = array(); + $ams = scandir($this->migration_path); + foreach($ams as $am) { + if (is_file($this->migration_path . $am)) { + $migrations[$am] = $this->migration_path . $am; + } + } + + ksort($migrations); + + if(!empty($migrations)){ + $migrationsInDB = $this->getCurrentMigrations(); + $migrationsInDBKeyVal = array(); + foreach ($migrationsInDB as $migration){ + $migrationsInDBKeyVal[$migration->file] = $migration; + } + + foreach($migrations as $file => $path){ + if(!isset($migrationsInDBKeyVal[$file])){ + if($file == 'list.php'){ + continue; + } + $migration = new Migration(); + $migration->file = $file; + $parts = explode("_",$file); + $migration->version = intval($parts[1]); + $migration->created = date("Y-m-d H:i:s"); + $migration->updated = date("Y-m-d H:i:s"); + $migration->status = 'Pending'; + $migration->Save(); + } + } + } + } + + public function runPendingMigrations(){ + $migrations = $this->getPendingMigrations(); + foreach ($migrations as $migration){ + $this->runMigrationUp($migration); + } + } + + public function runMigration($action){ + $method = 'runMigration'.ucfirst($action); + + if($action == 'up'){ + $statuses = array("Pending","Down"); + $queryMethod = 'getFirstAddedMigration'; + }else if($action == 'down'){ + $statuses = array("Up"); + $queryMethod = 'getLastRunMigration'; + }else{ + return false; + } + $migrations = $this->$queryMethod($statuses); + if(count($migrations) > 0){ + $this->$method($migrations[0]); + return $this->getMigrationById($migrations[0]->id); + }else{ + $this->queueMigrations(); + $migrations = $this->$queryMethod($statuses); + if(count($migrations) > 0){ + $this->$method($migrations[0]); + return $this->getMigrationById($migrations[0]->id); + } + } + + return false; + } + + + public function runMigrationUp($migration){ + if($migration->status != 'Pending' && $migration->status != 'UpError' && $migration->status != 'Down'){ + return false; + } + + $path = $this->migration_path . $migration->file; + if(!file_exists($path)){ + return false; + } + $migrationName = str_replace('.php','',$migration->file); + if(!class_exists($migrationName)){ + include $path; + } + $migClass = new $migrationName; + $res = $migClass->up(); + if(!$res){ + $migration->last_error = $migClass->getLastError(); + $migration->status = "UpError"; + $migration->updated = date("Y-m-d H:i:s"); + $migration->Save(); + } + + $migration->status = "Up"; + $migration->updated = date("Y-m-d H:i:s"); + $migration->Save(); + return $migration; + + } + + public function runMigrationDown($migration){ + if($migration->status != 'Up' && $migration->status != 'UpError'){ + return false; + } + + $path = $this->migration_path . $migration->file; + if(!file_exists($path)){ + return false; + } + + $migrationName = str_replace('.php','',$migration->file); + if(!class_exists($migrationName)){ + include $path; + } + $migClass = new $migrationName; + $res = $migClass->down(); + if(!$res){ + $migration->last_error = $migClass->getLastError(); + $migration->status = "DownError"; + $migration->updated = date("Y-m-d H:i:s"); + $migration->Save(); + } + + $migration->status = "Down"; + $migration->updated = date("Y-m-d H:i:s"); + $migration->Save(); + return $migration; + } + + public function ensureMigrations(){ + + $migration = new Migration(); + $migration->Load("1 = 1 order by id desc limit 1"); + + include $this->migration_path . "list.php"; + + if (count($migrationList) > 0 && (empty($migration->id) || $migrationList[0].".php" != $migration->file)) { + LogManager::getInstance()->info("ensureMigrations - execute migrations"); + $this->queueMigrations(); + $this->runPendingMigrations(); + } + } + +} \ No newline at end of file diff --git a/src/classes/RestApiManager.php b/src/classes/RestApiManager.php index 320a48e6..4db9f098 100644 --- a/src/classes/RestApiManager.php +++ b/src/classes/RestApiManager.php @@ -125,26 +125,124 @@ class RestApiManager{ class RestEndPoint{ public function process($type , $parameter = NULL){ - $resp = $this->$type($parameter); - $this->printResponse($resp); + + $accessTokenValidation = $this->validateAccessToken(); + if($accessTokenValidation->getStatus() == IceResponse::ERROR){ + $resp = $accessTokenValidation; + }else{ + $resp = $this->$type($parameter); + } + + if($resp->getStatus() == IceResponse::SUCCESS && $resp->getCode() == null){ + header('Content-Type: application/json'); + http_response_code(200); + $this->printResponse($resp->getObject()); + + }else if($resp->getStatus() == IceResponse::SUCCESS){ + header('Content-Type: application/json'); + http_response_code($resp->getCode()); + $this->printResponse($resp->getObject()); + + }else{ + header('Content-Type: application/json'); + http_response_code($resp->getCode()); + $messages = array(); + $messages[] = array( + "code" => $resp->getCode(), + "message" => $resp->getObject() + ); + $this->printResponse(array("error",[$messages])); + } + } public function get($parameter){ - return new IceResponse(IceResponse::ERROR, "Method not Implemented"); + return new IceResponse(IceResponse::ERROR, "Method not Implemented", 404); } public function post($parameter){ - return new IceResponse(IceResponse::ERROR, "Method not Implemented"); + return new IceResponse(IceResponse::ERROR, "Method not Implemented", 404); } public function put($parameter){ - return new IceResponse(IceResponse::ERROR, "Method not Implemented"); + return new IceResponse(IceResponse::ERROR, "Method not Implemented", 404); } public function delete($parameter){ - return new IceResponse(IceResponse::ERROR, "Method not Implemented"); + return new IceResponse(IceResponse::ERROR, "Method not Implemented", 404); } + public function basicValidation($map, $data){ + $validator = new Validator(); + $map = $this->getAssocMap($map); + unset($map['id']); + foreach ($data as $key=>$val) { + if(!isset($map[$key])){ + unset($data[$key]); + continue; + } + + $vrules = $map[$key]; + if ((!isset($vrules['allow-null']) || $vrules['allow-null'] == false) && $vrules['validation'] != "none" && empty($data[$key])){ + return new IceResponse(IceResponse::ERROR, "Field should have a value - ".$key, 400); + } else if(isset($vrules['remote-source'])){ + $class = $vrules['remote-source'][0]; + $obj = new $class(); + $idField = $vrules['remote-source'][1]; + $obj->Load($idField." = ?", array($val)); + if(empty($obj->$idField) || $obj->$idField != $val){ + if($vrules['allow-null'] == true ){ + $data[$key] = null; + }else{ + return new IceResponse(IceResponse::ERROR, "Not found - ".$key, 400); + } + } + } + if(!isset($vrules['remote-source'])){ + if((!isset($vrules['validation']) || empty($vrules['validation']))){ + if(!$validator->validateRequired($val)){ + return new IceResponse(IceResponse::ERROR, "Required field value missing - ".$key, 400); + } + }else if($vrules['validation'] != "none"){ + $validationRule = "validate". ucfirst($vrules['validation']); + if(!$validator->$validationRule($val)){ + return new IceResponse(IceResponse::ERROR, "Validation failed - ".$key, 400); + } + } + } + + } + + //check if request has all required fields + foreach ($map as $key=>$val) { + $vrules = $map[$key]; + if(!isset($vrules['remote-source'])) { + if ($vrules['validation'] != "none") { + if (!isset($data[$key])) { + return new IceResponse(IceResponse::ERROR, "Required field missing - " . $key, 400); + } + } + }else{ + if (!isset($vrules['allow-null']) || $vrules['allow-null'] == false) { + if (!isset($data[$key])) { + return new IceResponse(IceResponse::ERROR, "Required field missing - " . $key, 400); + } + } + } + } + + return new IceResponse(IceResponse::SUCCESS, null); + + } + + public function getAssocMap($map){ + $amap = array(); + foreach ($map as $item){ + $amap[$item[0]] = $item[1]; + } + return $amap; + } + public function clearObject($obj){ return BaseService::getInstance()->cleanUpAdoDB($obj); } @@ -155,8 +253,39 @@ class RestEndPoint{ return $accessTokenValidation; } + public function getValidate($parameter, $data){ + return new IceResponse(IceResponse::SUCCESS, null); + } + + public function postValidate($parameter, $data){ + return new IceResponse(IceResponse::SUCCESS, null); + } + + public function putValidate($parameter, $data){ + return new IceResponse(IceResponse::SUCCESS, null); + } + + public function deleteValidate($parameter, $data){ + return new IceResponse(IceResponse::SUCCESS, null); + } + + public function cleanDBObject($obj){ + unset($obj->keysToIgnore); + return $obj; + } + public function printResponse($response){ echo json_encode($response,JSON_PRETTY_PRINT); } + + public function getRequestBodyJSON() { + $rawInput = file_get_contents('php://input'); + return json_decode($rawInput, true); + } + + public function getRequestBody() { + $rawInput = file_get_contents('php://input'); + return $rawInput; + } } diff --git a/src/classes/SubActionManager.php b/src/classes/SubActionManager.php index 954da6ab..16d6b309 100644 --- a/src/classes/SubActionManager.php +++ b/src/classes/SubActionManager.php @@ -28,10 +28,12 @@ class IceResponse{ var $status; var $data; + var $code; - public function __construct($status,$data = null){ + public function __construct($status, $data = null, $code = null){ $this->status = $status; $this->data = $data; + $this->code = $code; } public function getStatus(){ @@ -45,6 +47,10 @@ class IceResponse{ public function getObject(){ return $this->data; } + + public function getCode(){ + return $this->code; + } public function getJsonArray(){ return array("status"=>$this->status,"data"=>$this->data); diff --git a/src/classes/Validator.php b/src/classes/Validator.php new file mode 100644 index 00000000..da149767 --- /dev/null +++ b/src/classes/Validator.php @@ -0,0 +1,46 @@ +=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": { + "phpunit/phpunit": "4.*", + "satooshi/php-coveralls": "^1.0", + "squizlabs/php_codesniffer": "^2.7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Consolidation\\AnnotatedCommand\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Greg Anderson", + "email": "greg.1.anderson@greenknowe.org" + } + ], + "description": "Initialize Symfony Console commands from annotated command class methods.", + "time": "2016-11-19 01:02:43" + }, + { + "name": "consolidation/log", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/consolidation/log.git", + "reference": "74ba81b4edc585616747cc5c5309ce56fec41254" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/consolidation/log/zipball/74ba81b4edc585616747cc5c5309ce56fec41254", + "reference": "74ba81b4edc585616747cc5c5309ce56fec41254", + "shasum": "" + }, + "require": { + "php": ">=5.5.0", + "psr/log": "~1.0", + "symfony/console": "~2.5|~3.0" + }, + "require-dev": { + "phpunit/phpunit": "4.*", + "squizlabs/php_codesniffer": "2.*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Consolidation\\Log\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Greg Anderson", + "email": "greg.1.anderson@greenknowe.org" + } + ], + "description": "Improved Psr-3 / Psr\\Log logger based on Symfony Console components.", + "time": "2016-03-23 23:46:42" + }, + { + "name": "consolidation/output-formatters", + "version": "3.1.3", + "source": { + "type": "git", + "url": "https://github.com/consolidation/output-formatters.git", + "reference": "1e6c6ab49904a31c310940ec4efccf5f36e386e4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/consolidation/output-formatters/zipball/1e6c6ab49904a31c310940ec4efccf5f36e386e4", + "reference": "1e6c6ab49904a31c310940ec4efccf5f36e386e4", + "shasum": "" + }, + "require": { + "php": ">=5.4.0", + "symfony/console": "~2.5|~3.0", + "symfony/finder": "~2.5|~3.0", + "victorjonsson/markdowndocs": "^1.3" + }, + "require-dev": { + "phpunit/phpunit": "4.*", + "satooshi/php-coveralls": "^1.0", + "squizlabs/php_codesniffer": "2.*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Consolidation\\OutputFormatters\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Greg Anderson", + "email": "greg.1.anderson@greenknowe.org" + } + ], + "description": "Format text by applying transformations provided by plug-in formatters.", + "time": "2016-11-18 23:04:31" + }, + { + "name": "consolidation/robo", + "version": "1.0.4", + "source": { + "type": "git", + "url": "https://github.com/consolidation/Robo.git", + "reference": "bfe2246358298d7839114612f84bcfdca3c14066" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/consolidation/Robo/zipball/bfe2246358298d7839114612f84bcfdca3c14066", + "reference": "bfe2246358298d7839114612f84bcfdca3c14066", + "shasum": "" + }, + "require": { + "consolidation/annotated-command": "^2.0.1", + "consolidation/log": "~1", + "consolidation/output-formatters": "^2.1.2|~3", + "league/container": "^2.2", + "php": ">=5.5.0", + "symfony/console": "~2.8|~3.0", + "symfony/event-dispatcher": "~2.5|~3.0", + "symfony/filesystem": "~2.5|~3.0", + "symfony/finder": "~2.5|~3.0", + "symfony/process": "~2.5|~3.0" + }, + "replace": { + "codegyre/robo": "< 1.0" + }, + "require-dev": { + "codeception/aspect-mock": "~1", + "codeception/base": "^2.2.6", + "codeception/verify": "^0.3.2", + "henrikbjorn/lurker": "~1", + "natxet/cssmin": "~3", + "patchwork/jsqueeze": "~2", + "pear/archive_tar": "^1.4.2", + "phpunit/php-code-coverage": "~2|~4", + "satooshi/php-coveralls": "~1", + "squizlabs/php_codesniffer": "~2" + }, + "suggest": { + "henrikbjorn/lurker": "For monitoring filesystem changes in taskWatch", + "natxet/CssMin": "For minifying JS files in taskMinify", + "patchwork/jsqueeze": "For minifying JS files in taskMinify", + "pear/archive_tar": "Allows tar archives to be created and extracted in taskPack and taskExtract, respectively." + }, + "bin": [ + "robo" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "classmap": [ + "scripts/composer/ScriptHandler.php" + ], + "psr-4": { + "Robo\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Davert", + "email": "davert.php@resend.cc" + } + ], + "description": "Modern task runner", + "time": "2016-11-15 19:24:36" + }, + { + "name": "container-interop/container-interop", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/container-interop/container-interop.git", + "reference": "fc08354828f8fd3245f77a66b9e23a6bca48297e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/container-interop/container-interop/zipball/fc08354828f8fd3245f77a66b9e23a6bca48297e", + "reference": "fc08354828f8fd3245f77a66b9e23a6bca48297e", + "shasum": "" + }, + "type": "library", + "autoload": { + "psr-4": { + "Interop\\Container\\": "src/Interop/Container/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Promoting the interoperability of container objects (DIC, SL, etc.)", + "time": "2014-12-30 15:22:37" + }, { "name": "gettext/gettext", "version": "v4.0.0", @@ -121,6 +373,70 @@ ], "time": "2015-03-27 11:32:41" }, + { + "name": "league/container", + "version": "2.2.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/container.git", + "reference": "c0e7d947b690891f700dc4967ead7bdb3d6708c1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/container/zipball/c0e7d947b690891f700dc4967ead7bdb3d6708c1", + "reference": "c0e7d947b690891f700dc4967ead7bdb3d6708c1", + "shasum": "" + }, + "require": { + "container-interop/container-interop": "^1.1", + "php": ">=5.4.0" + }, + "provide": { + "container-interop/container-interop-implementation": "^1.1" + }, + "replace": { + "orno/di": "~2.0" + }, + "require-dev": { + "phpunit/phpunit": "4.*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev", + "dev-1.x": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Container\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Phil Bennett", + "email": "philipobenito@gmail.com", + "homepage": "http://www.philipobenito.com", + "role": "Developer" + } + ], + "description": "A fast and intuitive dependency injection container.", + "homepage": "https://github.com/thephpleague/container", + "keywords": [ + "container", + "dependency", + "di", + "injection", + "league", + "provider", + "service" + ], + "time": "2016-03-17 11:07:59" + }, { "name": "monolog/monolog", "version": "1.13.1", @@ -195,23 +511,177 @@ "time": "2015-03-09 09:58:04" }, { - "name": "psr/log", - "version": "1.0.0", + "name": "phpdocumentor/reflection-common", + "version": "1.0", "source": { "type": "git", - "url": "https://github.com/php-fig/log.git", - "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b" + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/fe0936ee26643249e916849d48e3a51d5f5e278b", - "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/144c307535e82c8fdcaacbcfc1d6d8eeb896687c", + "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c", "shasum": "" }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "phpunit/phpunit": "^4.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ], + "time": "2015-12-27 11:43:31" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "3.1.1", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "8331b5efe816ae05461b7ca1e721c01b46bafb3e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/8331b5efe816ae05461b7ca1e721c01b46bafb3e", + "reference": "8331b5efe816ae05461b7ca1e721c01b46bafb3e", + "shasum": "" + }, + "require": { + "php": ">=5.5", + "phpdocumentor/reflection-common": "^1.0@dev", + "phpdocumentor/type-resolver": "^0.2.0", + "webmozart/assert": "^1.0" + }, + "require-dev": { + "mockery/mockery": "^0.9.4", + "phpunit/phpunit": "^4.4" + }, "type": "library", "autoload": { - "psr-0": { - "Psr\\Log\\": "" + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "time": "2016-09-30 07:12:33" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "0.2", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "b39c7a5b194f9ed7bd0dd345c751007a41862443" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/b39c7a5b194f9ed7bd0dd345c751007a41862443", + "reference": "b39c7a5b194f9ed7bd0dd345c751007a41862443", + "shasum": "" + }, + "require": { + "php": ">=5.5", + "phpdocumentor/reflection-common": "^1.0" + }, + "require-dev": { + "mockery/mockery": "^0.9.4", + "phpunit/phpunit": "^5.2||^4.8.24" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "time": "2016-06-10 07:14:17" + }, + { + "name": "psr/log", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", + "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" } }, "notification-url": "https://packagist.org/downloads/", @@ -225,12 +695,397 @@ } ], "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", "keywords": [ "log", "psr", "psr-3" ], - "time": "2012-12-21 11:40:51" + "time": "2016-10-10 12:19:37" + }, + { + "name": "symfony/console", + "version": "v3.1.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "c99da1119ae61e15de0e4829196b9fba6f73d065" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/c99da1119ae61e15de0e4829196b9fba6f73d065", + "reference": "c99da1119ae61e15de0e4829196b9fba6f73d065", + "shasum": "" + }, + "require": { + "php": ">=5.5.9", + "symfony/debug": "~2.8|~3.0", + "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.1-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-10-06 01:44:51" + }, + { + "name": "symfony/debug", + "version": "v3.1.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/debug.git", + "reference": "e2b3f74a67fc928adc3c1b9027f73e1bc01190a8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/debug/zipball/e2b3f74a67fc928adc3c1b9027f73e1bc01190a8", + "reference": "e2b3f74a67fc928adc3c1b9027f73e1bc01190a8", + "shasum": "" + }, + "require": { + "php": ">=5.5.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.8|~3.0", + "symfony/http-kernel": "~2.8|~3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Debug\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Debug Component", + "homepage": "https://symfony.com", + "time": "2016-09-06 11:02:40" + }, + { + "name": "symfony/event-dispatcher", + "version": "v3.1.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "28b0832b2553ffb80cabef6a7a812ff1e670c0bc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/28b0832b2553ffb80cabef6a7a812ff1e670c0bc", + "reference": "28b0832b2553ffb80cabef6a7a812ff1e670c0bc", + "shasum": "" + }, + "require": { + "php": ">=5.5.9" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "~2.8|~3.0", + "symfony/dependency-injection": "~2.8|~3.0", + "symfony/expression-language": "~2.8|~3.0", + "symfony/stopwatch": "~2.8|~3.0" + }, + "suggest": { + "symfony/dependency-injection": "", + "symfony/http-kernel": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony EventDispatcher Component", + "homepage": "https://symfony.com", + "time": "2016-10-13 06:28:43" + }, + { + "name": "symfony/filesystem", + "version": "v3.1.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "0565b61bf098cb4dc09f4f103f033138ae4f42c6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/0565b61bf098cb4dc09f4f103f033138ae4f42c6", + "reference": "0565b61bf098cb4dc09f4f103f033138ae4f42c6", + "shasum": "" + }, + "require": { + "php": ">=5.5.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-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-10-18 04:30:12" + }, + { + "name": "symfony/finder", + "version": "v3.1.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "205b5ffbb518a98ba2ae60a52656c4a31ab00c6f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/205b5ffbb518a98ba2ae60a52656c4a31ab00c6f", + "reference": "205b5ffbb518a98ba2ae60a52656c4a31ab00c6f", + "shasum": "" + }, + "require": { + "php": ">=5.5.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-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-09-28 00:11:12" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.3.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" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3-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-11-14 01:06:16" + }, + { + "name": "symfony/process", + "version": "v3.1.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "66de154ae86b1a07001da9fbffd620206e4faf94" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/66de154ae86b1a07001da9fbffd620206e4faf94", + "reference": "66de154ae86b1a07001da9fbffd620206e4faf94", + "shasum": "" + }, + "require": { + "php": ">=5.5.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-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-09-29 14:13:09" }, { "name": "twig/twig", @@ -292,9 +1147,1210 @@ "templating" ], "time": "2016-01-11 14:02:19" + }, + { + "name": "victorjonsson/markdowndocs", + "version": "1.3.7", + "source": { + "type": "git", + "url": "https://github.com/victorjonsson/PHP-Markdown-Documentation-Generator.git", + "reference": "a8244617cdce4804cd94ea508c82e8d7e29a273a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/victorjonsson/PHP-Markdown-Documentation-Generator/zipball/a8244617cdce4804cd94ea508c82e8d7e29a273a", + "reference": "a8244617cdce4804cd94ea508c82e8d7e29a273a", + "shasum": "" + }, + "require": { + "php": ">=5.5.0", + "symfony/console": ">=2.6" + }, + "require-dev": { + "phpunit/phpunit": "3.7.23" + }, + "bin": [ + "bin/phpdoc-md" + ], + "type": "library", + "autoload": { + "psr-0": { + "PHPDocsMD": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Victor Jonsson", + "email": "kontakt@victorjonsson.se" + } + ], + "description": "Command line tool for generating markdown-formatted class documentation", + "homepage": "https://github.com/victorjonsson/PHP-Markdown-Documentation-Generator", + "time": "2016-10-11 21:10:19" + }, + { + "name": "webmozart/assert", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/webmozart/assert.git", + "reference": "bb2d123231c095735130cc8f6d31385a44c7b308" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozart/assert/zipball/bb2d123231c095735130cc8f6d31385a44c7b308", + "reference": "bb2d123231c095735130cc8f6d31385a44c7b308", + "shasum": "" + }, + "require": { + "php": "^5.3.3|^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.6", + "sebastian/version": "^1.0.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "time": "2016-08-09 15:02:57" + } + ], + "packages-dev": [ + { + "name": "doctrine/instantiator", + "version": "1.0.5", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d", + "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d", + "shasum": "" + }, + "require": { + "php": ">=5.3,<8.0-DEV" + }, + "require-dev": { + "athletic/athletic": "~0.1.8", + "ext-pdo": "*", + "ext-phar": "*", + "phpunit/phpunit": "~4.0", + "squizlabs/php_codesniffer": "~2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "http://ocramius.github.com/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://github.com/doctrine/instantiator", + "keywords": [ + "constructor", + "instantiate" + ], + "time": "2015-06-14 21:17:01" + }, + { + "name": "myclabs/deep-copy", + "version": "1.5.5", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "399c1f9781e222f6eb6cc238796f5200d1b7f108" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/399c1f9781e222f6eb6cc238796f5200d1b7f108", + "reference": "399c1f9781e222f6eb6cc238796f5200d1b7f108", + "shasum": "" + }, + "require": { + "php": ">=5.4.0" + }, + "require-dev": { + "doctrine/collections": "1.*", + "phpunit/phpunit": "~4.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "homepage": "https://github.com/myclabs/DeepCopy", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "time": "2016-10-31 17:19:45" + }, + { + "name": "phpspec/prophecy", + "version": "v1.6.1", + "source": { + "type": "git", + "url": "https://github.com/phpspec/prophecy.git", + "reference": "58a8137754bc24b25740d4281399a4a3596058e0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/58a8137754bc24b25740d4281399a4a3596058e0", + "reference": "58a8137754bc24b25740d4281399a4a3596058e0", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.2", + "php": "^5.3|^7.0", + "phpdocumentor/reflection-docblock": "^2.0|^3.0.2", + "sebastian/comparator": "^1.1", + "sebastian/recursion-context": "^1.0" + }, + "require-dev": { + "phpspec/phpspec": "^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.6.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-06-07 08:13:47" + }, + { + "name": "phpunit/php-code-coverage", + "version": "4.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "6cba06ff75a1a63a71033e1a01b89056f3af1e8d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/6cba06ff75a1a63a71033e1a01b89056f3af1e8d", + "reference": "6cba06ff75a1a63a71033e1a01b89056f3af1e8d", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0", + "phpunit/php-file-iterator": "~1.3", + "phpunit/php-text-template": "~1.2", + "phpunit/php-token-stream": "^1.4.2", + "sebastian/code-unit-reverse-lookup": "~1.0", + "sebastian/environment": "^1.3.2 || ^2.0", + "sebastian/version": "~1.0|~2.0" + }, + "require-dev": { + "ext-xdebug": ">=2.1.4", + "phpunit/phpunit": "^5.4" + }, + "suggest": { + "ext-dom": "*", + "ext-xdebug": ">=2.4.0", + "ext-xmlwriter": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0.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": "2016-11-01 05:06:24" + }, + { + "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.9", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-token-stream.git", + "reference": "3b402f65a4cc90abf6e1104e388b896ce209631b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3b402f65a4cc90abf6e1104e388b896ce209631b", + "reference": "3b402f65a4cc90abf6e1104e388b896ce209631b", + "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": "2016-11-15 14:06:22" + }, + { + "name": "phpunit/phpunit", + "version": "5.5.7", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "3f67cee782c9abfaee5e32fd2f57cdd54bc257ba" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/3f67cee782c9abfaee5e32fd2f57cdd54bc257ba", + "reference": "3f67cee782c9abfaee5e32fd2f57cdd54bc257ba", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "myclabs/deep-copy": "~1.3", + "php": "^5.6 || ^7.0", + "phpspec/prophecy": "^1.3.1", + "phpunit/php-code-coverage": "^4.0.1", + "phpunit/php-file-iterator": "~1.4", + "phpunit/php-text-template": "~1.2", + "phpunit/php-timer": "^1.0.6", + "phpunit/phpunit-mock-objects": "^3.2", + "sebastian/comparator": "~1.1", + "sebastian/diff": "~1.2", + "sebastian/environment": "^1.3 || ^2.0", + "sebastian/exporter": "~1.2", + "sebastian/global-state": "~1.0", + "sebastian/object-enumerator": "~1.0", + "sebastian/resource-operations": "~1.0", + "sebastian/version": "~1.0|~2.0", + "symfony/yaml": "~2.1|~3.0" + }, + "conflict": { + "phpdocumentor/reflection-docblock": "3.0.2" + }, + "require-dev": { + "ext-pdo": "*" + }, + "suggest": { + "ext-tidy": "*", + "ext-xdebug": "*", + "phpunit/php-invoker": "~1.1" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.5.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "time": "2016-10-03 13:04:15" + }, + { + "name": "phpunit/phpunit-mock-objects", + "version": "3.4.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", + "reference": "45026c8383187ad1dcb14fbfec77dced265b9cfc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/45026c8383187ad1dcb14fbfec77dced265b9cfc", + "reference": "45026c8383187ad1dcb14fbfec77dced265b9cfc", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.2", + "php": "^5.6 || ^7.0", + "phpunit/php-text-template": "^1.2", + "sebastian/exporter": "^1.2 || ^2.0" + }, + "conflict": { + "phpunit/phpunit": "<5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.4" + }, + "suggest": { + "ext-soap": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.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": "Mock Object library for PHPUnit", + "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", + "keywords": [ + "mock", + "xunit" + ], + "time": "2016-11-19 09:07:46" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "c36f5e7cfce482fde5bf8d10d41a53591e0198fe" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/c36f5e7cfce482fde5bf8d10d41a53591e0198fe", + "reference": "c36f5e7cfce482fde5bf8d10d41a53591e0198fe", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "require-dev": { + "phpunit/phpunit": "~5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "time": "2016-02-13 06:45:14" + }, + { + "name": "sebastian/comparator", + "version": "1.2.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "6a1ed12e8b2409076ab22e3897126211ff8b1f7f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/6a1ed12e8b2409076ab22e3897126211ff8b1f7f", + "reference": "6a1ed12e8b2409076ab22e3897126211ff8b1f7f", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "sebastian/diff": "~1.2", + "sebastian/exporter": "~1.2 || ~2.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" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "http://www.github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "time": "2016-11-19 09:18:40" + }, + { + "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.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/be2c607e43ce4c89ecd60e75c6a85c126e754aea", + "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8 || ^5.0" + }, + "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-08-18 05:49:44" + }, + { + "name": "sebastian/exporter", + "version": "1.2.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/42c4c2eec485ee3e159ec9884f95b431287edde4", + "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "sebastian/recursion-context": "~1.0" + }, + "require-dev": { + "ext-mbstring": "*", + "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": "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": "2016-06-17 09:04:28" + }, + { + "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/object-enumerator", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "d4ca2fb70344987502567bc50081c03e6192fb26" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/d4ca2fb70344987502567bc50081c03e6192fb26", + "reference": "d4ca2fb70344987502567bc50081c03e6192fb26", + "shasum": "" + }, + "require": { + "php": ">=5.6", + "sebastian/recursion-context": "~1.0" + }, + "require-dev": { + "phpunit/phpunit": "~5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "time": "2016-01-28 13:25:10" + }, + { + "name": "sebastian/recursion-context", + "version": "1.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "938df7a6478e72795e5f8266cff24d06e3136f2e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/938df7a6478e72795e5f8266cff24d06e3136f2e", + "reference": "938df7a6478e72795e5f8266cff24d06e3136f2e", + "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": "2016-11-15 06:55:36" + }, + { + "name": "sebastian/resource-operations", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/resource-operations.git", + "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "shasum": "" + }, + "require": { + "php": ">=5.6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides a list of PHP built-in functions that operate on resources", + "homepage": "https://www.github.com/sebastianbergmann/resource-operations", + "time": "2015-07-28 20:34:47" + }, + { + "name": "sebastian/version", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "c829badbd8fdf16a0bad8aa7fa7971c029f1b9c5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c829badbd8fdf16a0bad8aa7fa7971c029f1b9c5", + "reference": "c829badbd8fdf16a0bad8aa7fa7971c029f1b9c5", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "time": "2016-02-04 12:56:52" + }, + { + "name": "symfony/yaml", + "version": "v3.1.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "7ff51b06c6c3d5cc6686df69004a42c69df09e27" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/7ff51b06c6c3d5cc6686df69004a42c69df09e27", + "reference": "7ff51b06c6c3d5cc6686df69004a42c69df09e27", + "shasum": "" + }, + "require": { + "php": ">=5.5.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-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-10-24 18:41:13" } ], - "packages-dev": [], "aliases": [], "minimum-stability": "stable", "stability-flags": [], diff --git a/src/composer/vendor/bin/phpdoc-md b/src/composer/vendor/bin/phpdoc-md new file mode 120000 index 00000000..95ab23ba --- /dev/null +++ b/src/composer/vendor/bin/phpdoc-md @@ -0,0 +1 @@ +../victorjonsson/markdowndocs/bin/phpdoc-md \ No newline at end of file diff --git a/src/composer/vendor/bin/phpunit b/src/composer/vendor/bin/phpunit new file mode 120000 index 00000000..2c489303 --- /dev/null +++ b/src/composer/vendor/bin/phpunit @@ -0,0 +1 @@ +../phpunit/phpunit/phpunit \ No newline at end of file diff --git a/src/composer/vendor/bin/robo b/src/composer/vendor/bin/robo new file mode 120000 index 00000000..701d42dd --- /dev/null +++ b/src/composer/vendor/bin/robo @@ -0,0 +1 @@ +../consolidation/robo/robo \ No newline at end of file diff --git a/src/composer/vendor/composer/autoload_classmap.php b/src/composer/vendor/composer/autoload_classmap.php index 7a91153b..6bb4897d 100644 --- a/src/composer/vendor/composer/autoload_classmap.php +++ b/src/composer/vendor/composer/autoload_classmap.php @@ -6,4 +6,460 @@ $vendorDir = dirname(dirname(__FILE__)); $baseDir = dirname($vendorDir); return array( + 'File_Iterator' => $vendorDir . '/phpunit/php-file-iterator/src/Iterator.php', + 'File_Iterator_Facade' => $vendorDir . '/phpunit/php-file-iterator/src/Facade.php', + 'File_Iterator_Factory' => $vendorDir . '/phpunit/php-file-iterator/src/Factory.php', + 'PHPUnit\\Framework\\TestCase' => $vendorDir . '/phpunit/phpunit/src/ForwardCompatibility/TestCase.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', + 'PHPUnit_Extensions_PhptTestSuite' => $vendorDir . '/phpunit/phpunit/src/Extensions/PhptTestSuite.php', + 'PHPUnit_Extensions_RepeatedTest' => $vendorDir . '/phpunit/phpunit/src/Extensions/RepeatedTest.php', + 'PHPUnit_Extensions_TestDecorator' => $vendorDir . '/phpunit/phpunit/src/Extensions/TestDecorator.php', + 'PHPUnit_Extensions_TicketListener' => $vendorDir . '/phpunit/phpunit/src/Extensions/TicketListener.php', + 'PHPUnit_Framework_Assert' => $vendorDir . '/phpunit/phpunit/src/Framework/Assert.php', + 'PHPUnit_Framework_AssertionFailedError' => $vendorDir . '/phpunit/phpunit/src/Framework/AssertionFailedError.php', + 'PHPUnit_Framework_BaseTestListener' => $vendorDir . '/phpunit/phpunit/src/Framework/BaseTestListener.php', + 'PHPUnit_Framework_CodeCoverageException' => $vendorDir . '/phpunit/phpunit/src/Framework/CodeCoverageException.php', + 'PHPUnit_Framework_Constraint' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint.php', + 'PHPUnit_Framework_Constraint_And' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/And.php', + 'PHPUnit_Framework_Constraint_ArrayHasKey' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ArrayHasKey.php', + 'PHPUnit_Framework_Constraint_ArraySubset' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ArraySubset.php', + 'PHPUnit_Framework_Constraint_Attribute' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Attribute.php', + 'PHPUnit_Framework_Constraint_Callback' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Callback.php', + 'PHPUnit_Framework_Constraint_ClassHasAttribute' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ClassHasAttribute.php', + 'PHPUnit_Framework_Constraint_ClassHasStaticAttribute' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ClassHasStaticAttribute.php', + 'PHPUnit_Framework_Constraint_Composite' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Composite.php', + 'PHPUnit_Framework_Constraint_Count' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Count.php', + 'PHPUnit_Framework_Constraint_Exception' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Exception.php', + 'PHPUnit_Framework_Constraint_ExceptionCode' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ExceptionCode.php', + 'PHPUnit_Framework_Constraint_ExceptionMessage' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ExceptionMessage.php', + 'PHPUnit_Framework_Constraint_ExceptionMessageRegExp' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ExceptionMessageRegExp.php', + 'PHPUnit_Framework_Constraint_FileExists' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/FileExists.php', + 'PHPUnit_Framework_Constraint_GreaterThan' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/GreaterThan.php', + 'PHPUnit_Framework_Constraint_IsAnything' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsAnything.php', + 'PHPUnit_Framework_Constraint_IsEmpty' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsEmpty.php', + 'PHPUnit_Framework_Constraint_IsEqual' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsEqual.php', + 'PHPUnit_Framework_Constraint_IsFalse' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsFalse.php', + 'PHPUnit_Framework_Constraint_IsFinite' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsFinite.php', + 'PHPUnit_Framework_Constraint_IsIdentical' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsIdentical.php', + 'PHPUnit_Framework_Constraint_IsInfinite' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsInfinite.php', + 'PHPUnit_Framework_Constraint_IsInstanceOf' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsInstanceOf.php', + 'PHPUnit_Framework_Constraint_IsJson' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsJson.php', + 'PHPUnit_Framework_Constraint_IsNan' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsNan.php', + 'PHPUnit_Framework_Constraint_IsNull' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsNull.php', + 'PHPUnit_Framework_Constraint_IsTrue' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsTrue.php', + 'PHPUnit_Framework_Constraint_IsType' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsType.php', + 'PHPUnit_Framework_Constraint_JsonMatches' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/JsonMatches.php', + 'PHPUnit_Framework_Constraint_JsonMatches_ErrorMessageProvider' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/JsonMatches/ErrorMessageProvider.php', + 'PHPUnit_Framework_Constraint_LessThan' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/LessThan.php', + 'PHPUnit_Framework_Constraint_Not' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Not.php', + 'PHPUnit_Framework_Constraint_ObjectHasAttribute' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ObjectHasAttribute.php', + 'PHPUnit_Framework_Constraint_Or' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Or.php', + 'PHPUnit_Framework_Constraint_PCREMatch' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/PCREMatch.php', + 'PHPUnit_Framework_Constraint_SameSize' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/SameSize.php', + 'PHPUnit_Framework_Constraint_StringContains' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/StringContains.php', + 'PHPUnit_Framework_Constraint_StringEndsWith' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/StringEndsWith.php', + 'PHPUnit_Framework_Constraint_StringMatches' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/StringMatches.php', + 'PHPUnit_Framework_Constraint_StringStartsWith' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/StringStartsWith.php', + 'PHPUnit_Framework_Constraint_TraversableContains' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/TraversableContains.php', + 'PHPUnit_Framework_Constraint_TraversableContainsOnly' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/TraversableContainsOnly.php', + 'PHPUnit_Framework_Constraint_Xor' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Xor.php', + 'PHPUnit_Framework_CoveredCodeNotExecutedException' => $vendorDir . '/phpunit/phpunit/src/Framework/PHPUnit_Framework_CoveredCodeNotExecutedException.php', + 'PHPUnit_Framework_Error' => $vendorDir . '/phpunit/phpunit/src/Framework/Error.php', + 'PHPUnit_Framework_Error_Deprecated' => $vendorDir . '/phpunit/phpunit/src/Framework/Error/Deprecated.php', + 'PHPUnit_Framework_Error_Notice' => $vendorDir . '/phpunit/phpunit/src/Framework/Error/Notice.php', + 'PHPUnit_Framework_Error_Warning' => $vendorDir . '/phpunit/phpunit/src/Framework/Error/Warning.php', + 'PHPUnit_Framework_Exception' => $vendorDir . '/phpunit/phpunit/src/Framework/Exception.php', + 'PHPUnit_Framework_ExceptionWrapper' => $vendorDir . '/phpunit/phpunit/src/Framework/ExceptionWrapper.php', + 'PHPUnit_Framework_ExpectationFailedException' => $vendorDir . '/phpunit/phpunit/src/Framework/ExpectationFailedException.php', + 'PHPUnit_Framework_IncompleteTest' => $vendorDir . '/phpunit/phpunit/src/Framework/IncompleteTest.php', + 'PHPUnit_Framework_IncompleteTestCase' => $vendorDir . '/phpunit/phpunit/src/Framework/IncompleteTestCase.php', + 'PHPUnit_Framework_IncompleteTestError' => $vendorDir . '/phpunit/phpunit/src/Framework/IncompleteTestError.php', + 'PHPUnit_Framework_InvalidCoversTargetException' => $vendorDir . '/phpunit/phpunit/src/Framework/InvalidCoversTargetException.php', + 'PHPUnit_Framework_MissingCoversAnnotationException' => $vendorDir . '/phpunit/phpunit/src/Framework/PHPUnit_Framework_MissingCoversAnnotationException.php', + 'PHPUnit_Framework_MockObject_BadMethodCallException' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Exception/BadMethodCallException.php', + 'PHPUnit_Framework_MockObject_Builder_Identity' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Identity.php', + 'PHPUnit_Framework_MockObject_Builder_InvocationMocker' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/InvocationMocker.php', + 'PHPUnit_Framework_MockObject_Builder_Match' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Match.php', + 'PHPUnit_Framework_MockObject_Builder_MethodNameMatch' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/MethodNameMatch.php', + 'PHPUnit_Framework_MockObject_Builder_Namespace' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Namespace.php', + 'PHPUnit_Framework_MockObject_Builder_ParametersMatch' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/ParametersMatch.php', + 'PHPUnit_Framework_MockObject_Builder_Stub' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Stub.php', + 'PHPUnit_Framework_MockObject_Exception' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Exception/Exception.php', + 'PHPUnit_Framework_MockObject_Generator' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator.php', + 'PHPUnit_Framework_MockObject_Invocation' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invocation.php', + 'PHPUnit_Framework_MockObject_InvocationMocker' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/InvocationMocker.php', + 'PHPUnit_Framework_MockObject_Invocation_Object' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invocation/Object.php', + 'PHPUnit_Framework_MockObject_Invocation_Static' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invocation/Static.php', + 'PHPUnit_Framework_MockObject_Invokable' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invokable.php', + 'PHPUnit_Framework_MockObject_Matcher' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher.php', + 'PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/AnyInvokedCount.php', + 'PHPUnit_Framework_MockObject_Matcher_AnyParameters' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/AnyParameters.php', + 'PHPUnit_Framework_MockObject_Matcher_ConsecutiveParameters' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/ConsecutiveParameters.php', + 'PHPUnit_Framework_MockObject_Matcher_Invocation' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/Invocation.php', + 'PHPUnit_Framework_MockObject_Matcher_InvokedAtIndex' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtIndex.php', + 'PHPUnit_Framework_MockObject_Matcher_InvokedAtLeastCount' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtLeastCount.php', + 'PHPUnit_Framework_MockObject_Matcher_InvokedAtLeastOnce' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtLeastOnce.php', + 'PHPUnit_Framework_MockObject_Matcher_InvokedAtMostCount' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtMostCount.php', + 'PHPUnit_Framework_MockObject_Matcher_InvokedCount' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedCount.php', + 'PHPUnit_Framework_MockObject_Matcher_InvokedRecorder' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedRecorder.php', + 'PHPUnit_Framework_MockObject_Matcher_MethodName' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/MethodName.php', + 'PHPUnit_Framework_MockObject_Matcher_Parameters' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/Parameters.php', + 'PHPUnit_Framework_MockObject_Matcher_StatelessInvocation' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/StatelessInvocation.php', + 'PHPUnit_Framework_MockObject_MockBuilder' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/MockBuilder.php', + 'PHPUnit_Framework_MockObject_MockObject' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/MockObject.php', + 'PHPUnit_Framework_MockObject_RuntimeException' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Exception/RuntimeException.php', + 'PHPUnit_Framework_MockObject_Stub' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub.php', + 'PHPUnit_Framework_MockObject_Stub_ConsecutiveCalls' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ConsecutiveCalls.php', + 'PHPUnit_Framework_MockObject_Stub_Exception' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/Exception.php', + 'PHPUnit_Framework_MockObject_Stub_MatcherCollection' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/MatcherCollection.php', + 'PHPUnit_Framework_MockObject_Stub_Return' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/Return.php', + 'PHPUnit_Framework_MockObject_Stub_ReturnArgument' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnArgument.php', + 'PHPUnit_Framework_MockObject_Stub_ReturnCallback' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnCallback.php', + 'PHPUnit_Framework_MockObject_Stub_ReturnReference' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnReference.php', + 'PHPUnit_Framework_MockObject_Stub_ReturnSelf' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnSelf.php', + 'PHPUnit_Framework_MockObject_Stub_ReturnValueMap' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnValueMap.php', + 'PHPUnit_Framework_MockObject_Verifiable' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Verifiable.php', + 'PHPUnit_Framework_OutputError' => $vendorDir . '/phpunit/phpunit/src/Framework/OutputError.php', + 'PHPUnit_Framework_RiskyTest' => $vendorDir . '/phpunit/phpunit/src/Framework/RiskyTest.php', + 'PHPUnit_Framework_RiskyTestError' => $vendorDir . '/phpunit/phpunit/src/Framework/RiskyTestError.php', + 'PHPUnit_Framework_SelfDescribing' => $vendorDir . '/phpunit/phpunit/src/Framework/SelfDescribing.php', + 'PHPUnit_Framework_SkippedTest' => $vendorDir . '/phpunit/phpunit/src/Framework/SkippedTest.php', + 'PHPUnit_Framework_SkippedTestCase' => $vendorDir . '/phpunit/phpunit/src/Framework/SkippedTestCase.php', + 'PHPUnit_Framework_SkippedTestError' => $vendorDir . '/phpunit/phpunit/src/Framework/SkippedTestError.php', + 'PHPUnit_Framework_SkippedTestSuiteError' => $vendorDir . '/phpunit/phpunit/src/Framework/SkippedTestSuiteError.php', + 'PHPUnit_Framework_SyntheticError' => $vendorDir . '/phpunit/phpunit/src/Framework/SyntheticError.php', + 'PHPUnit_Framework_Test' => $vendorDir . '/phpunit/phpunit/src/Framework/Test.php', + 'PHPUnit_Framework_TestCase' => $vendorDir . '/phpunit/phpunit/src/Framework/TestCase.php', + 'PHPUnit_Framework_TestFailure' => $vendorDir . '/phpunit/phpunit/src/Framework/TestFailure.php', + 'PHPUnit_Framework_TestListener' => $vendorDir . '/phpunit/phpunit/src/Framework/TestListener.php', + 'PHPUnit_Framework_TestResult' => $vendorDir . '/phpunit/phpunit/src/Framework/TestResult.php', + 'PHPUnit_Framework_TestSuite' => $vendorDir . '/phpunit/phpunit/src/Framework/TestSuite.php', + 'PHPUnit_Framework_TestSuite_DataProvider' => $vendorDir . '/phpunit/phpunit/src/Framework/TestSuite/DataProvider.php', + 'PHPUnit_Framework_UnintentionallyCoveredCodeError' => $vendorDir . '/phpunit/phpunit/src/Framework/UnintentionallyCoveredCodeError.php', + 'PHPUnit_Framework_Warning' => $vendorDir . '/phpunit/phpunit/src/Framework/Warning.php', + 'PHPUnit_Framework_WarningTestCase' => $vendorDir . '/phpunit/phpunit/src/Framework/WarningTestCase.php', + 'PHPUnit_Runner_BaseTestRunner' => $vendorDir . '/phpunit/phpunit/src/Runner/BaseTestRunner.php', + 'PHPUnit_Runner_Exception' => $vendorDir . '/phpunit/phpunit/src/Runner/Exception.php', + 'PHPUnit_Runner_Filter_Factory' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/Factory.php', + 'PHPUnit_Runner_Filter_GroupFilterIterator' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/Group.php', + 'PHPUnit_Runner_Filter_Group_Exclude' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/Group/Exclude.php', + 'PHPUnit_Runner_Filter_Group_Include' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/Group/Include.php', + 'PHPUnit_Runner_Filter_Test' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/Test.php', + 'PHPUnit_Runner_StandardTestSuiteLoader' => $vendorDir . '/phpunit/phpunit/src/Runner/StandardTestSuiteLoader.php', + 'PHPUnit_Runner_TestSuiteLoader' => $vendorDir . '/phpunit/phpunit/src/Runner/TestSuiteLoader.php', + 'PHPUnit_Runner_Version' => $vendorDir . '/phpunit/phpunit/src/Runner/Version.php', + 'PHPUnit_TextUI_Command' => $vendorDir . '/phpunit/phpunit/src/TextUI/Command.php', + 'PHPUnit_TextUI_ResultPrinter' => $vendorDir . '/phpunit/phpunit/src/TextUI/ResultPrinter.php', + 'PHPUnit_TextUI_TestRunner' => $vendorDir . '/phpunit/phpunit/src/TextUI/TestRunner.php', + 'PHPUnit_Util_Blacklist' => $vendorDir . '/phpunit/phpunit/src/Util/Blacklist.php', + 'PHPUnit_Util_Configuration' => $vendorDir . '/phpunit/phpunit/src/Util/Configuration.php', + 'PHPUnit_Util_ConfigurationGenerator' => $vendorDir . '/phpunit/phpunit/src/Util/ConfigurationGenerator.php', + 'PHPUnit_Util_ErrorHandler' => $vendorDir . '/phpunit/phpunit/src/Util/ErrorHandler.php', + 'PHPUnit_Util_Fileloader' => $vendorDir . '/phpunit/phpunit/src/Util/Fileloader.php', + 'PHPUnit_Util_Filesystem' => $vendorDir . '/phpunit/phpunit/src/Util/Filesystem.php', + 'PHPUnit_Util_Filter' => $vendorDir . '/phpunit/phpunit/src/Util/Filter.php', + 'PHPUnit_Util_Getopt' => $vendorDir . '/phpunit/phpunit/src/Util/Getopt.php', + 'PHPUnit_Util_GlobalState' => $vendorDir . '/phpunit/phpunit/src/Util/GlobalState.php', + 'PHPUnit_Util_InvalidArgumentHelper' => $vendorDir . '/phpunit/phpunit/src/Util/InvalidArgumentHelper.php', + 'PHPUnit_Util_Log_JSON' => $vendorDir . '/phpunit/phpunit/src/Util/Log/JSON.php', + 'PHPUnit_Util_Log_JUnit' => $vendorDir . '/phpunit/phpunit/src/Util/Log/JUnit.php', + 'PHPUnit_Util_Log_TAP' => $vendorDir . '/phpunit/phpunit/src/Util/Log/TAP.php', + 'PHPUnit_Util_Log_TeamCity' => $vendorDir . '/phpunit/phpunit/src/Util/Log/TeamCity.php', + 'PHPUnit_Util_PHP' => $vendorDir . '/phpunit/phpunit/src/Util/PHP.php', + 'PHPUnit_Util_PHP_Default' => $vendorDir . '/phpunit/phpunit/src/Util/PHP/Default.php', + 'PHPUnit_Util_PHP_Windows' => $vendorDir . '/phpunit/phpunit/src/Util/PHP/Windows.php', + 'PHPUnit_Util_Printer' => $vendorDir . '/phpunit/phpunit/src/Util/Printer.php', + 'PHPUnit_Util_Regex' => $vendorDir . '/phpunit/phpunit/src/Util/Regex.php', + 'PHPUnit_Util_String' => $vendorDir . '/phpunit/phpunit/src/Util/String.php', + 'PHPUnit_Util_Test' => $vendorDir . '/phpunit/phpunit/src/Util/Test.php', + 'PHPUnit_Util_TestDox_NamePrettifier' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/NamePrettifier.php', + 'PHPUnit_Util_TestDox_ResultPrinter' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/ResultPrinter.php', + 'PHPUnit_Util_TestDox_ResultPrinter_HTML' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/ResultPrinter/HTML.php', + 'PHPUnit_Util_TestDox_ResultPrinter_Text' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/ResultPrinter/Text.php', + 'PHPUnit_Util_TestDox_ResultPrinter_XML' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/ResultPrinter/XML.php', + 'PHPUnit_Util_TestSuiteIterator' => $vendorDir . '/phpunit/phpunit/src/Util/TestSuiteIterator.php', + 'PHPUnit_Util_Type' => $vendorDir . '/phpunit/phpunit/src/Util/Type.php', + 'PHPUnit_Util_XML' => $vendorDir . '/phpunit/phpunit/src/Util/XML.php', + 'PHP_Timer' => $vendorDir . '/phpunit/php-timer/src/Timer.php', + 'PHP_Token' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_TokenWithScope' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_TokenWithScopeAndVisibility' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ABSTRACT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_AMPERSAND' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_AND_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ARRAY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ARRAY_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_AS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ASYNC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_AT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_AWAIT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BACKTICK' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BAD_CHARACTER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BOOLEAN_AND' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BOOLEAN_OR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BOOL_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BREAK' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CALLABLE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CARET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CASE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CATCH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CHARACTER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLASS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLASS_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLASS_NAME_CONSTANT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLONE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLOSE_BRACKET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLOSE_CURLY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLOSE_SQUARE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLOSE_TAG' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_COALESCE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_COLON' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_COMMA' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_COMMENT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_COMPILER_HALT_OFFSET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CONCAT_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CONST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CONSTANT_ENCAPSED_STRING' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CONTINUE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CURLY_OPEN' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DEC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DECLARE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DEFAULT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DIR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DIV' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DIV_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DNUMBER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DO' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOC_COMMENT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOLLAR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOLLAR_OPEN_CURLY_BRACES' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOUBLE_ARROW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOUBLE_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOUBLE_COLON' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOUBLE_QUOTES' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ECHO' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ELLIPSIS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ELSE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ELSEIF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EMPTY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENCAPSED_AND_WHITESPACE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDDECLARE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDFOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDFOREACH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDIF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDSWITCH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDWHILE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_END_HEREDOC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENUM' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EQUALS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EVAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EXCLAMATION_MARK' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EXIT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EXTENDS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FILE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FINAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FINALLY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FOREACH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FUNCTION' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FUNC_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_GLOBAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_GOTO' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_GT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_HALT_COMPILER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IMPLEMENTS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IN' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INCLUDE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INCLUDE_ONCE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INLINE_HTML' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INSTANCEOF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INSTEADOF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INTERFACE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INT_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ISSET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_GREATER_OR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_IDENTICAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_NOT_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_NOT_IDENTICAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_SMALLER_OR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_Includes' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_JOIN' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LAMBDA_ARROW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LAMBDA_CP' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LAMBDA_OP' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LINE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LIST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LNUMBER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LOGICAL_AND' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LOGICAL_OR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LOGICAL_XOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_METHOD_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_MINUS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_MINUS_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_MOD_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_MULT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_MUL_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NAMESPACE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NEW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NS_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NS_SEPARATOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NUM_STRING' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OBJECT_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OBJECT_OPERATOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ONUMBER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OPEN_BRACKET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OPEN_CURLY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OPEN_SQUARE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OPEN_TAG' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OPEN_TAG_WITH_ECHO' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PAAMAYIM_NEKUDOTAYIM' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PERCENT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PIPE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PLUS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PLUS_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_POW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_POW_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PRINT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PRIVATE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PROTECTED' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PUBLIC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_QUESTION_MARK' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_REQUIRE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_REQUIRE_ONCE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_RETURN' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SEMICOLON' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SHAPE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SL_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SPACESHIP' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_START_HEREDOC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_STATIC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_STRING' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_STRING_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_STRING_VARNAME' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SUPER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SWITCH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_Stream' => $vendorDir . '/phpunit/php-token-stream/src/Token/Stream.php', + 'PHP_Token_Stream_CachingFactory' => $vendorDir . '/phpunit/php-token-stream/src/Token/Stream/CachingFactory.php', + 'PHP_Token_THROW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TILDE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TRAIT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TRAIT_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TRY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TYPE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TYPELIST_GT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TYPELIST_LT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_UNSET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_UNSET_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_USE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_USE_FUNCTION' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_VAR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_VARIABLE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_WHERE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_WHILE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_WHITESPACE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_ATTRIBUTE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_CATEGORY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_CATEGORY_LABEL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_CHILDREN' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_LABEL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_REQUIRED' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_TAG_GT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_TAG_LT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_TEXT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XOR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_YIELD' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_YIELD_FROM' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'Robo\\composer\\ScriptHandler' => $vendorDir . '/consolidation/robo/scripts/composer/ScriptHandler.php', + 'SebastianBergmann\\CodeCoverage\\CodeCoverage' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage.php', + 'SebastianBergmann\\CodeCoverage\\CoveredCodeNotExecutedException' => $vendorDir . '/phpunit/php-code-coverage/src/Exception/CoveredCodeNotExecutedException.php', + 'SebastianBergmann\\CodeCoverage\\Driver\\Driver' => $vendorDir . '/phpunit/php-code-coverage/src/Driver/Driver.php', + 'SebastianBergmann\\CodeCoverage\\Driver\\HHVM' => $vendorDir . '/phpunit/php-code-coverage/src/Driver/HHVM.php', + 'SebastianBergmann\\CodeCoverage\\Driver\\PHPDBG' => $vendorDir . '/phpunit/php-code-coverage/src/Driver/PHPDBG.php', + 'SebastianBergmann\\CodeCoverage\\Driver\\Xdebug' => $vendorDir . '/phpunit/php-code-coverage/src/Driver/Xdebug.php', + 'SebastianBergmann\\CodeCoverage\\Exception' => $vendorDir . '/phpunit/php-code-coverage/src/Exception/Exception.php', + 'SebastianBergmann\\CodeCoverage\\Filter' => $vendorDir . '/phpunit/php-code-coverage/src/Filter.php', + 'SebastianBergmann\\CodeCoverage\\InvalidArgumentException' => $vendorDir . '/phpunit/php-code-coverage/src/Exception/InvalidArgumentException.php', + 'SebastianBergmann\\CodeCoverage\\MissingCoversAnnotationException' => $vendorDir . '/phpunit/php-code-coverage/src/Exception/MissingCoversAnnotationException.php', + 'SebastianBergmann\\CodeCoverage\\Node\\AbstractNode' => $vendorDir . '/phpunit/php-code-coverage/src/Node/AbstractNode.php', + 'SebastianBergmann\\CodeCoverage\\Node\\Builder' => $vendorDir . '/phpunit/php-code-coverage/src/Node/Builder.php', + 'SebastianBergmann\\CodeCoverage\\Node\\Directory' => $vendorDir . '/phpunit/php-code-coverage/src/Node/Directory.php', + 'SebastianBergmann\\CodeCoverage\\Node\\File' => $vendorDir . '/phpunit/php-code-coverage/src/Node/File.php', + 'SebastianBergmann\\CodeCoverage\\Node\\Iterator' => $vendorDir . '/phpunit/php-code-coverage/src/Node/Iterator.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Clover' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Clover.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Crap4j' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Crap4j.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Dashboard' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Html/Renderer/Dashboard.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Directory' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Html/Renderer/Directory.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Facade' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Html/Facade.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Html\\File' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Html/Renderer/File.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Renderer' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Html/Renderer.php', + 'SebastianBergmann\\CodeCoverage\\Report\\PHP' => $vendorDir . '/phpunit/php-code-coverage/src/Report/PHP.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Text' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Text.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Coverage' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Coverage.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Directory' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Directory.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Facade' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Facade.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\File' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/File.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Method' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Method.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Node' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Node.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Project' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Project.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Report' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Report.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Tests' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Tests.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Totals' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Totals.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Unit' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Unit.php', + 'SebastianBergmann\\CodeCoverage\\RuntimeException' => $vendorDir . '/phpunit/php-code-coverage/src/Exception/RuntimeException.php', + 'SebastianBergmann\\CodeCoverage\\UnintentionallyCoveredCodeException' => $vendorDir . '/phpunit/php-code-coverage/src/Exception/UnintentionallyCoveredCodeException.php', + 'SebastianBergmann\\CodeCoverage\\Util' => $vendorDir . '/phpunit/php-code-coverage/src/Util.php', + 'SebastianBergmann\\CodeUnitReverseLookup\\Wizard' => $vendorDir . '/sebastian/code-unit-reverse-lookup/src/Wizard.php', + 'SebastianBergmann\\Comparator\\ArrayComparator' => $vendorDir . '/sebastian/comparator/src/ArrayComparator.php', + 'SebastianBergmann\\Comparator\\Comparator' => $vendorDir . '/sebastian/comparator/src/Comparator.php', + 'SebastianBergmann\\Comparator\\ComparisonFailure' => $vendorDir . '/sebastian/comparator/src/ComparisonFailure.php', + 'SebastianBergmann\\Comparator\\DOMNodeComparator' => $vendorDir . '/sebastian/comparator/src/DOMNodeComparator.php', + 'SebastianBergmann\\Comparator\\DateTimeComparator' => $vendorDir . '/sebastian/comparator/src/DateTimeComparator.php', + 'SebastianBergmann\\Comparator\\DoubleComparator' => $vendorDir . '/sebastian/comparator/src/DoubleComparator.php', + 'SebastianBergmann\\Comparator\\ExceptionComparator' => $vendorDir . '/sebastian/comparator/src/ExceptionComparator.php', + 'SebastianBergmann\\Comparator\\Factory' => $vendorDir . '/sebastian/comparator/src/Factory.php', + 'SebastianBergmann\\Comparator\\MockObjectComparator' => $vendorDir . '/sebastian/comparator/src/MockObjectComparator.php', + 'SebastianBergmann\\Comparator\\NumericComparator' => $vendorDir . '/sebastian/comparator/src/NumericComparator.php', + 'SebastianBergmann\\Comparator\\ObjectComparator' => $vendorDir . '/sebastian/comparator/src/ObjectComparator.php', + 'SebastianBergmann\\Comparator\\ResourceComparator' => $vendorDir . '/sebastian/comparator/src/ResourceComparator.php', + 'SebastianBergmann\\Comparator\\ScalarComparator' => $vendorDir . '/sebastian/comparator/src/ScalarComparator.php', + 'SebastianBergmann\\Comparator\\SplObjectStorageComparator' => $vendorDir . '/sebastian/comparator/src/SplObjectStorageComparator.php', + 'SebastianBergmann\\Comparator\\TypeComparator' => $vendorDir . '/sebastian/comparator/src/TypeComparator.php', + 'SebastianBergmann\\Diff\\Chunk' => $vendorDir . '/sebastian/diff/src/Chunk.php', + 'SebastianBergmann\\Diff\\Diff' => $vendorDir . '/sebastian/diff/src/Diff.php', + 'SebastianBergmann\\Diff\\Differ' => $vendorDir . '/sebastian/diff/src/Differ.php', + 'SebastianBergmann\\Diff\\LCS\\LongestCommonSubsequence' => $vendorDir . '/sebastian/diff/src/LCS/LongestCommonSubsequence.php', + 'SebastianBergmann\\Diff\\LCS\\MemoryEfficientImplementation' => $vendorDir . '/sebastian/diff/src/LCS/MemoryEfficientLongestCommonSubsequenceImplementation.php', + 'SebastianBergmann\\Diff\\LCS\\TimeEfficientImplementation' => $vendorDir . '/sebastian/diff/src/LCS/TimeEfficientLongestCommonSubsequenceImplementation.php', + 'SebastianBergmann\\Diff\\Line' => $vendorDir . '/sebastian/diff/src/Line.php', + 'SebastianBergmann\\Diff\\Parser' => $vendorDir . '/sebastian/diff/src/Parser.php', + 'SebastianBergmann\\Environment\\Console' => $vendorDir . '/sebastian/environment/src/Console.php', + 'SebastianBergmann\\Environment\\Runtime' => $vendorDir . '/sebastian/environment/src/Runtime.php', + 'SebastianBergmann\\Exporter\\Exporter' => $vendorDir . '/sebastian/exporter/src/Exporter.php', + 'SebastianBergmann\\GlobalState\\Blacklist' => $vendorDir . '/sebastian/global-state/src/Blacklist.php', + 'SebastianBergmann\\GlobalState\\CodeExporter' => $vendorDir . '/sebastian/global-state/src/CodeExporter.php', + 'SebastianBergmann\\GlobalState\\Exception' => $vendorDir . '/sebastian/global-state/src/Exception.php', + 'SebastianBergmann\\GlobalState\\Restorer' => $vendorDir . '/sebastian/global-state/src/Restorer.php', + 'SebastianBergmann\\GlobalState\\RuntimeException' => $vendorDir . '/sebastian/global-state/src/RuntimeException.php', + 'SebastianBergmann\\GlobalState\\Snapshot' => $vendorDir . '/sebastian/global-state/src/Snapshot.php', + 'SebastianBergmann\\ObjectEnumerator\\Enumerator' => $vendorDir . '/sebastian/object-enumerator/src/Enumerator.php', + 'SebastianBergmann\\ObjectEnumerator\\Exception' => $vendorDir . '/sebastian/object-enumerator/src/Exception.php', + 'SebastianBergmann\\ObjectEnumerator\\InvalidArgumentException' => $vendorDir . '/sebastian/object-enumerator/src/InvalidArgumentException.php', + 'SebastianBergmann\\RecursionContext\\Context' => $vendorDir . '/sebastian/recursion-context/src/Context.php', + 'SebastianBergmann\\RecursionContext\\Exception' => $vendorDir . '/sebastian/recursion-context/src/Exception.php', + 'SebastianBergmann\\RecursionContext\\InvalidArgumentException' => $vendorDir . '/sebastian/recursion-context/src/InvalidArgumentException.php', + 'SebastianBergmann\\ResourceOperations\\ResourceOperations' => $vendorDir . '/sebastian/resource-operations/src/ResourceOperations.php', + 'SebastianBergmann\\Version' => $vendorDir . '/sebastian/version/src/Version.php', + 'Text_Template' => $vendorDir . '/phpunit/php-text-template/src/Template.php', ); diff --git a/src/composer/vendor/composer/autoload_files.php b/src/composer/vendor/composer/autoload_files.php new file mode 100644 index 00000000..315ab83b --- /dev/null +++ b/src/composer/vendor/composer/autoload_files.php @@ -0,0 +1,10 @@ + $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php', +); diff --git a/src/composer/vendor/composer/autoload_namespaces.php b/src/composer/vendor/composer/autoload_namespaces.php index 35f816d5..3163d160 100644 --- a/src/composer/vendor/composer/autoload_namespaces.php +++ b/src/composer/vendor/composer/autoload_namespaces.php @@ -7,5 +7,6 @@ $baseDir = dirname($vendorDir); return array( 'Twig_' => array($vendorDir . '/twig/twig/lib'), - 'Psr\\Log\\' => array($vendorDir . '/psr/log'), + 'Prophecy\\' => array($vendorDir . '/phpspec/prophecy/src'), + 'PHPDocsMD' => array($vendorDir . '/victorjonsson/markdowndocs/src'), ); diff --git a/src/composer/vendor/composer/autoload_psr4.php b/src/composer/vendor/composer/autoload_psr4.php index 11dca6fe..513028ae 100644 --- a/src/composer/vendor/composer/autoload_psr4.php +++ b/src/composer/vendor/composer/autoload_psr4.php @@ -6,7 +6,26 @@ $vendorDir = dirname(dirname(__FILE__)); $baseDir = dirname($vendorDir); return array( + 'phpDocumentor\\Reflection\\' => array($vendorDir . '/phpdocumentor/reflection-common/src', $vendorDir . '/phpdocumentor/type-resolver/src', $vendorDir . '/phpdocumentor/reflection-docblock/src'), + 'Webmozart\\Assert\\' => array($vendorDir . '/webmozart/assert/src'), + 'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'), + 'Symfony\\Component\\Yaml\\' => array($vendorDir . '/symfony/yaml'), + 'Symfony\\Component\\Process\\' => array($vendorDir . '/symfony/process'), + 'Symfony\\Component\\Finder\\' => array($vendorDir . '/symfony/finder'), + 'Symfony\\Component\\Filesystem\\' => array($vendorDir . '/symfony/filesystem'), + 'Symfony\\Component\\EventDispatcher\\' => array($vendorDir . '/symfony/event-dispatcher'), + 'Symfony\\Component\\Debug\\' => array($vendorDir . '/symfony/debug'), + 'Symfony\\Component\\Console\\' => array($vendorDir . '/symfony/console'), + 'Robo\\' => array($vendorDir . '/consolidation/robo/src'), + 'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'), 'Monolog\\' => array($vendorDir . '/monolog/monolog/src/Monolog'), + 'League\\Container\\' => array($vendorDir . '/league/container/src'), + 'Interop\\Container\\' => array($vendorDir . '/container-interop/container-interop/src/Interop/Container'), 'Gettext\\Languages\\' => array($vendorDir . '/gettext/languages/src'), 'Gettext\\' => array($vendorDir . '/gettext/gettext/src'), + 'Doctrine\\Instantiator\\' => array($vendorDir . '/doctrine/instantiator/src/Doctrine/Instantiator'), + 'DeepCopy\\' => array($vendorDir . '/myclabs/deep-copy/src/DeepCopy'), + 'Consolidation\\OutputFormatters\\' => array($vendorDir . '/consolidation/output-formatters/src'), + 'Consolidation\\Log\\' => array($vendorDir . '/consolidation/log/src'), + 'Consolidation\\AnnotatedCommand\\' => array($vendorDir . '/consolidation/annotated-command/src'), ); diff --git a/src/composer/vendor/composer/autoload_real.php b/src/composer/vendor/composer/autoload_real.php index e81e9eaf..64b2ec07 100644 --- a/src/composer/vendor/composer/autoload_real.php +++ b/src/composer/vendor/composer/autoload_real.php @@ -47,6 +47,24 @@ class ComposerAutoloaderInit91d733469d809ee1828b45ab2da48a10 $loader->register(true); + if ($useStaticLoader) { + $includeFiles = Composer\Autoload\ComposerStaticInit91d733469d809ee1828b45ab2da48a10::$files; + } else { + $includeFiles = require __DIR__ . '/autoload_files.php'; + } + foreach ($includeFiles as $fileIdentifier => $file) { + composerRequire91d733469d809ee1828b45ab2da48a10($fileIdentifier, $file); + } + return $loader; } } + +function composerRequire91d733469d809ee1828b45ab2da48a10($fileIdentifier, $file) +{ + if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { + require $file; + + $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; + } +} diff --git a/src/composer/vendor/composer/autoload_static.php b/src/composer/vendor/composer/autoload_static.php index 2d99756d..ca1a40c9 100644 --- a/src/composer/vendor/composer/autoload_static.php +++ b/src/composer/vendor/composer/autoload_static.php @@ -6,23 +6,131 @@ namespace Composer\Autoload; class ComposerStaticInit91d733469d809ee1828b45ab2da48a10 { + public static $files = array ( + '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php', + ); + public static $prefixLengthsPsr4 = array ( + 'p' => + array ( + 'phpDocumentor\\Reflection\\' => 25, + ), + 'W' => + array ( + 'Webmozart\\Assert\\' => 17, + ), + 'S' => + array ( + 'Symfony\\Polyfill\\Mbstring\\' => 26, + 'Symfony\\Component\\Yaml\\' => 23, + 'Symfony\\Component\\Process\\' => 26, + 'Symfony\\Component\\Finder\\' => 25, + 'Symfony\\Component\\Filesystem\\' => 29, + 'Symfony\\Component\\EventDispatcher\\' => 34, + 'Symfony\\Component\\Debug\\' => 24, + 'Symfony\\Component\\Console\\' => 26, + ), + 'R' => + array ( + 'Robo\\' => 5, + ), + 'P' => + array ( + 'Psr\\Log\\' => 8, + ), 'M' => array ( 'Monolog\\' => 8, ), + 'L' => + array ( + 'League\\Container\\' => 17, + ), + 'I' => + array ( + 'Interop\\Container\\' => 18, + ), 'G' => array ( 'Gettext\\Languages\\' => 18, 'Gettext\\' => 8, ), + 'D' => + array ( + 'Doctrine\\Instantiator\\' => 22, + 'DeepCopy\\' => 9, + ), + 'C' => + array ( + 'Consolidation\\OutputFormatters\\' => 31, + 'Consolidation\\Log\\' => 18, + 'Consolidation\\AnnotatedCommand\\' => 31, + ), ); public static $prefixDirsPsr4 = array ( + 'phpDocumentor\\Reflection\\' => + array ( + 0 => __DIR__ . '/..' . '/phpdocumentor/reflection-common/src', + 1 => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src', + 2 => __DIR__ . '/..' . '/phpdocumentor/reflection-docblock/src', + ), + 'Webmozart\\Assert\\' => + array ( + 0 => __DIR__ . '/..' . '/webmozart/assert/src', + ), + 'Symfony\\Polyfill\\Mbstring\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/polyfill-mbstring', + ), + 'Symfony\\Component\\Yaml\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/yaml', + ), + 'Symfony\\Component\\Process\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/process', + ), + 'Symfony\\Component\\Finder\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/finder', + ), + 'Symfony\\Component\\Filesystem\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/filesystem', + ), + 'Symfony\\Component\\EventDispatcher\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/event-dispatcher', + ), + 'Symfony\\Component\\Debug\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/debug', + ), + 'Symfony\\Component\\Console\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/console', + ), + 'Robo\\' => + array ( + 0 => __DIR__ . '/..' . '/consolidation/robo/src', + ), + 'Psr\\Log\\' => + array ( + 0 => __DIR__ . '/..' . '/psr/log/Psr/Log', + ), 'Monolog\\' => array ( 0 => __DIR__ . '/..' . '/monolog/monolog/src/Monolog', ), + 'League\\Container\\' => + array ( + 0 => __DIR__ . '/..' . '/league/container/src', + ), + 'Interop\\Container\\' => + array ( + 0 => __DIR__ . '/..' . '/container-interop/container-interop/src/Interop/Container', + ), 'Gettext\\Languages\\' => array ( 0 => __DIR__ . '/..' . '/gettext/languages/src', @@ -31,6 +139,26 @@ class ComposerStaticInit91d733469d809ee1828b45ab2da48a10 array ( 0 => __DIR__ . '/..' . '/gettext/gettext/src', ), + 'Doctrine\\Instantiator\\' => + array ( + 0 => __DIR__ . '/..' . '/doctrine/instantiator/src/Doctrine/Instantiator', + ), + 'DeepCopy\\' => + array ( + 0 => __DIR__ . '/..' . '/myclabs/deep-copy/src/DeepCopy', + ), + 'Consolidation\\OutputFormatters\\' => + array ( + 0 => __DIR__ . '/..' . '/consolidation/output-formatters/src', + ), + 'Consolidation\\Log\\' => + array ( + 0 => __DIR__ . '/..' . '/consolidation/log/src', + ), + 'Consolidation\\AnnotatedCommand\\' => + array ( + 0 => __DIR__ . '/..' . '/consolidation/annotated-command/src', + ), ); public static $prefixesPsr0 = array ( @@ -43,19 +171,483 @@ class ComposerStaticInit91d733469d809ee1828b45ab2da48a10 ), 'P' => array ( - 'Psr\\Log\\' => + 'Prophecy\\' => array ( - 0 => __DIR__ . '/..' . '/psr/log', + 0 => __DIR__ . '/..' . '/phpspec/prophecy/src', + ), + 'PHPDocsMD' => + array ( + 0 => __DIR__ . '/..' . '/victorjonsson/markdowndocs/src', ), ), ); + public static $classMap = array ( + 'File_Iterator' => __DIR__ . '/..' . '/phpunit/php-file-iterator/src/Iterator.php', + 'File_Iterator_Facade' => __DIR__ . '/..' . '/phpunit/php-file-iterator/src/Facade.php', + 'File_Iterator_Factory' => __DIR__ . '/..' . '/phpunit/php-file-iterator/src/Factory.php', + 'PHPUnit\\Framework\\TestCase' => __DIR__ . '/..' . '/phpunit/phpunit/src/ForwardCompatibility/TestCase.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', + 'PHPUnit_Extensions_PhptTestSuite' => __DIR__ . '/..' . '/phpunit/phpunit/src/Extensions/PhptTestSuite.php', + 'PHPUnit_Extensions_RepeatedTest' => __DIR__ . '/..' . '/phpunit/phpunit/src/Extensions/RepeatedTest.php', + 'PHPUnit_Extensions_TestDecorator' => __DIR__ . '/..' . '/phpunit/phpunit/src/Extensions/TestDecorator.php', + 'PHPUnit_Extensions_TicketListener' => __DIR__ . '/..' . '/phpunit/phpunit/src/Extensions/TicketListener.php', + 'PHPUnit_Framework_Assert' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Assert.php', + 'PHPUnit_Framework_AssertionFailedError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/AssertionFailedError.php', + 'PHPUnit_Framework_BaseTestListener' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/BaseTestListener.php', + 'PHPUnit_Framework_CodeCoverageException' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/CodeCoverageException.php', + 'PHPUnit_Framework_Constraint' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint.php', + 'PHPUnit_Framework_Constraint_And' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/And.php', + 'PHPUnit_Framework_Constraint_ArrayHasKey' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ArrayHasKey.php', + 'PHPUnit_Framework_Constraint_ArraySubset' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ArraySubset.php', + 'PHPUnit_Framework_Constraint_Attribute' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/Attribute.php', + 'PHPUnit_Framework_Constraint_Callback' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/Callback.php', + 'PHPUnit_Framework_Constraint_ClassHasAttribute' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ClassHasAttribute.php', + 'PHPUnit_Framework_Constraint_ClassHasStaticAttribute' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ClassHasStaticAttribute.php', + 'PHPUnit_Framework_Constraint_Composite' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/Composite.php', + 'PHPUnit_Framework_Constraint_Count' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/Count.php', + 'PHPUnit_Framework_Constraint_Exception' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/Exception.php', + 'PHPUnit_Framework_Constraint_ExceptionCode' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ExceptionCode.php', + 'PHPUnit_Framework_Constraint_ExceptionMessage' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ExceptionMessage.php', + 'PHPUnit_Framework_Constraint_ExceptionMessageRegExp' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ExceptionMessageRegExp.php', + 'PHPUnit_Framework_Constraint_FileExists' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/FileExists.php', + 'PHPUnit_Framework_Constraint_GreaterThan' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/GreaterThan.php', + 'PHPUnit_Framework_Constraint_IsAnything' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsAnything.php', + 'PHPUnit_Framework_Constraint_IsEmpty' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsEmpty.php', + 'PHPUnit_Framework_Constraint_IsEqual' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsEqual.php', + 'PHPUnit_Framework_Constraint_IsFalse' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsFalse.php', + 'PHPUnit_Framework_Constraint_IsFinite' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsFinite.php', + 'PHPUnit_Framework_Constraint_IsIdentical' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsIdentical.php', + 'PHPUnit_Framework_Constraint_IsInfinite' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsInfinite.php', + 'PHPUnit_Framework_Constraint_IsInstanceOf' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsInstanceOf.php', + 'PHPUnit_Framework_Constraint_IsJson' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsJson.php', + 'PHPUnit_Framework_Constraint_IsNan' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsNan.php', + 'PHPUnit_Framework_Constraint_IsNull' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsNull.php', + 'PHPUnit_Framework_Constraint_IsTrue' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsTrue.php', + 'PHPUnit_Framework_Constraint_IsType' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsType.php', + 'PHPUnit_Framework_Constraint_JsonMatches' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/JsonMatches.php', + 'PHPUnit_Framework_Constraint_JsonMatches_ErrorMessageProvider' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/JsonMatches/ErrorMessageProvider.php', + 'PHPUnit_Framework_Constraint_LessThan' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/LessThan.php', + 'PHPUnit_Framework_Constraint_Not' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/Not.php', + 'PHPUnit_Framework_Constraint_ObjectHasAttribute' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ObjectHasAttribute.php', + 'PHPUnit_Framework_Constraint_Or' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/Or.php', + 'PHPUnit_Framework_Constraint_PCREMatch' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/PCREMatch.php', + 'PHPUnit_Framework_Constraint_SameSize' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/SameSize.php', + 'PHPUnit_Framework_Constraint_StringContains' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/StringContains.php', + 'PHPUnit_Framework_Constraint_StringEndsWith' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/StringEndsWith.php', + 'PHPUnit_Framework_Constraint_StringMatches' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/StringMatches.php', + 'PHPUnit_Framework_Constraint_StringStartsWith' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/StringStartsWith.php', + 'PHPUnit_Framework_Constraint_TraversableContains' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/TraversableContains.php', + 'PHPUnit_Framework_Constraint_TraversableContainsOnly' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/TraversableContainsOnly.php', + 'PHPUnit_Framework_Constraint_Xor' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/Xor.php', + 'PHPUnit_Framework_CoveredCodeNotExecutedException' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/PHPUnit_Framework_CoveredCodeNotExecutedException.php', + 'PHPUnit_Framework_Error' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Error.php', + 'PHPUnit_Framework_Error_Deprecated' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Error/Deprecated.php', + 'PHPUnit_Framework_Error_Notice' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Error/Notice.php', + 'PHPUnit_Framework_Error_Warning' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Error/Warning.php', + 'PHPUnit_Framework_Exception' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Exception.php', + 'PHPUnit_Framework_ExceptionWrapper' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/ExceptionWrapper.php', + 'PHPUnit_Framework_ExpectationFailedException' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/ExpectationFailedException.php', + 'PHPUnit_Framework_IncompleteTest' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/IncompleteTest.php', + 'PHPUnit_Framework_IncompleteTestCase' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/IncompleteTestCase.php', + 'PHPUnit_Framework_IncompleteTestError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/IncompleteTestError.php', + 'PHPUnit_Framework_InvalidCoversTargetException' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/InvalidCoversTargetException.php', + 'PHPUnit_Framework_MissingCoversAnnotationException' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/PHPUnit_Framework_MissingCoversAnnotationException.php', + 'PHPUnit_Framework_MockObject_BadMethodCallException' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Exception/BadMethodCallException.php', + 'PHPUnit_Framework_MockObject_Builder_Identity' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Identity.php', + 'PHPUnit_Framework_MockObject_Builder_InvocationMocker' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/InvocationMocker.php', + 'PHPUnit_Framework_MockObject_Builder_Match' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Match.php', + 'PHPUnit_Framework_MockObject_Builder_MethodNameMatch' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/MethodNameMatch.php', + 'PHPUnit_Framework_MockObject_Builder_Namespace' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Namespace.php', + 'PHPUnit_Framework_MockObject_Builder_ParametersMatch' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/ParametersMatch.php', + 'PHPUnit_Framework_MockObject_Builder_Stub' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Stub.php', + 'PHPUnit_Framework_MockObject_Exception' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Exception/Exception.php', + 'PHPUnit_Framework_MockObject_Generator' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator.php', + 'PHPUnit_Framework_MockObject_Invocation' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invocation.php', + 'PHPUnit_Framework_MockObject_InvocationMocker' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/InvocationMocker.php', + 'PHPUnit_Framework_MockObject_Invocation_Object' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invocation/Object.php', + 'PHPUnit_Framework_MockObject_Invocation_Static' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invocation/Static.php', + 'PHPUnit_Framework_MockObject_Invokable' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invokable.php', + 'PHPUnit_Framework_MockObject_Matcher' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher.php', + 'PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/AnyInvokedCount.php', + 'PHPUnit_Framework_MockObject_Matcher_AnyParameters' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/AnyParameters.php', + 'PHPUnit_Framework_MockObject_Matcher_ConsecutiveParameters' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/ConsecutiveParameters.php', + 'PHPUnit_Framework_MockObject_Matcher_Invocation' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/Invocation.php', + 'PHPUnit_Framework_MockObject_Matcher_InvokedAtIndex' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtIndex.php', + 'PHPUnit_Framework_MockObject_Matcher_InvokedAtLeastCount' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtLeastCount.php', + 'PHPUnit_Framework_MockObject_Matcher_InvokedAtLeastOnce' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtLeastOnce.php', + 'PHPUnit_Framework_MockObject_Matcher_InvokedAtMostCount' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtMostCount.php', + 'PHPUnit_Framework_MockObject_Matcher_InvokedCount' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedCount.php', + 'PHPUnit_Framework_MockObject_Matcher_InvokedRecorder' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedRecorder.php', + 'PHPUnit_Framework_MockObject_Matcher_MethodName' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/MethodName.php', + 'PHPUnit_Framework_MockObject_Matcher_Parameters' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/Parameters.php', + 'PHPUnit_Framework_MockObject_Matcher_StatelessInvocation' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/StatelessInvocation.php', + 'PHPUnit_Framework_MockObject_MockBuilder' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/MockBuilder.php', + 'PHPUnit_Framework_MockObject_MockObject' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/MockObject.php', + 'PHPUnit_Framework_MockObject_RuntimeException' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Exception/RuntimeException.php', + 'PHPUnit_Framework_MockObject_Stub' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub.php', + 'PHPUnit_Framework_MockObject_Stub_ConsecutiveCalls' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ConsecutiveCalls.php', + 'PHPUnit_Framework_MockObject_Stub_Exception' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/Exception.php', + 'PHPUnit_Framework_MockObject_Stub_MatcherCollection' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/MatcherCollection.php', + 'PHPUnit_Framework_MockObject_Stub_Return' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/Return.php', + 'PHPUnit_Framework_MockObject_Stub_ReturnArgument' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnArgument.php', + 'PHPUnit_Framework_MockObject_Stub_ReturnCallback' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnCallback.php', + 'PHPUnit_Framework_MockObject_Stub_ReturnReference' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnReference.php', + 'PHPUnit_Framework_MockObject_Stub_ReturnSelf' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnSelf.php', + 'PHPUnit_Framework_MockObject_Stub_ReturnValueMap' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnValueMap.php', + 'PHPUnit_Framework_MockObject_Verifiable' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Verifiable.php', + 'PHPUnit_Framework_OutputError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/OutputError.php', + 'PHPUnit_Framework_RiskyTest' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/RiskyTest.php', + 'PHPUnit_Framework_RiskyTestError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/RiskyTestError.php', + 'PHPUnit_Framework_SelfDescribing' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/SelfDescribing.php', + 'PHPUnit_Framework_SkippedTest' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/SkippedTest.php', + 'PHPUnit_Framework_SkippedTestCase' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/SkippedTestCase.php', + 'PHPUnit_Framework_SkippedTestError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/SkippedTestError.php', + 'PHPUnit_Framework_SkippedTestSuiteError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/SkippedTestSuiteError.php', + 'PHPUnit_Framework_SyntheticError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/SyntheticError.php', + 'PHPUnit_Framework_Test' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Test.php', + 'PHPUnit_Framework_TestCase' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/TestCase.php', + 'PHPUnit_Framework_TestFailure' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/TestFailure.php', + 'PHPUnit_Framework_TestListener' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/TestListener.php', + 'PHPUnit_Framework_TestResult' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/TestResult.php', + 'PHPUnit_Framework_TestSuite' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/TestSuite.php', + 'PHPUnit_Framework_TestSuite_DataProvider' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/TestSuite/DataProvider.php', + 'PHPUnit_Framework_UnintentionallyCoveredCodeError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/UnintentionallyCoveredCodeError.php', + 'PHPUnit_Framework_Warning' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Warning.php', + 'PHPUnit_Framework_WarningTestCase' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/WarningTestCase.php', + 'PHPUnit_Runner_BaseTestRunner' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/BaseTestRunner.php', + 'PHPUnit_Runner_Exception' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Exception.php', + 'PHPUnit_Runner_Filter_Factory' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Filter/Factory.php', + 'PHPUnit_Runner_Filter_GroupFilterIterator' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Filter/Group.php', + 'PHPUnit_Runner_Filter_Group_Exclude' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Filter/Group/Exclude.php', + 'PHPUnit_Runner_Filter_Group_Include' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Filter/Group/Include.php', + 'PHPUnit_Runner_Filter_Test' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Filter/Test.php', + 'PHPUnit_Runner_StandardTestSuiteLoader' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/StandardTestSuiteLoader.php', + 'PHPUnit_Runner_TestSuiteLoader' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/TestSuiteLoader.php', + 'PHPUnit_Runner_Version' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Version.php', + 'PHPUnit_TextUI_Command' => __DIR__ . '/..' . '/phpunit/phpunit/src/TextUI/Command.php', + 'PHPUnit_TextUI_ResultPrinter' => __DIR__ . '/..' . '/phpunit/phpunit/src/TextUI/ResultPrinter.php', + 'PHPUnit_TextUI_TestRunner' => __DIR__ . '/..' . '/phpunit/phpunit/src/TextUI/TestRunner.php', + 'PHPUnit_Util_Blacklist' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Blacklist.php', + 'PHPUnit_Util_Configuration' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Configuration.php', + 'PHPUnit_Util_ConfigurationGenerator' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/ConfigurationGenerator.php', + 'PHPUnit_Util_ErrorHandler' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/ErrorHandler.php', + 'PHPUnit_Util_Fileloader' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Fileloader.php', + 'PHPUnit_Util_Filesystem' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Filesystem.php', + 'PHPUnit_Util_Filter' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Filter.php', + 'PHPUnit_Util_Getopt' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Getopt.php', + 'PHPUnit_Util_GlobalState' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/GlobalState.php', + 'PHPUnit_Util_InvalidArgumentHelper' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/InvalidArgumentHelper.php', + 'PHPUnit_Util_Log_JSON' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Log/JSON.php', + 'PHPUnit_Util_Log_JUnit' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Log/JUnit.php', + 'PHPUnit_Util_Log_TAP' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Log/TAP.php', + 'PHPUnit_Util_Log_TeamCity' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Log/TeamCity.php', + 'PHPUnit_Util_PHP' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/PHP.php', + 'PHPUnit_Util_PHP_Default' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/PHP/Default.php', + 'PHPUnit_Util_PHP_Windows' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/PHP/Windows.php', + 'PHPUnit_Util_Printer' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Printer.php', + 'PHPUnit_Util_Regex' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Regex.php', + 'PHPUnit_Util_String' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/String.php', + 'PHPUnit_Util_Test' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Test.php', + 'PHPUnit_Util_TestDox_NamePrettifier' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/TestDox/NamePrettifier.php', + 'PHPUnit_Util_TestDox_ResultPrinter' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/TestDox/ResultPrinter.php', + 'PHPUnit_Util_TestDox_ResultPrinter_HTML' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/TestDox/ResultPrinter/HTML.php', + 'PHPUnit_Util_TestDox_ResultPrinter_Text' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/TestDox/ResultPrinter/Text.php', + 'PHPUnit_Util_TestDox_ResultPrinter_XML' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/TestDox/ResultPrinter/XML.php', + 'PHPUnit_Util_TestSuiteIterator' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/TestSuiteIterator.php', + 'PHPUnit_Util_Type' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Type.php', + 'PHPUnit_Util_XML' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/XML.php', + 'PHP_Timer' => __DIR__ . '/..' . '/phpunit/php-timer/src/Timer.php', + 'PHP_Token' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_TokenWithScope' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_TokenWithScopeAndVisibility' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ABSTRACT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_AMPERSAND' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_AND_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ARRAY' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ARRAY_CAST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_AS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ASYNC' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_AT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_AWAIT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BACKTICK' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BAD_CHARACTER' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BOOLEAN_AND' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BOOLEAN_OR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BOOL_CAST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BREAK' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CALLABLE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CARET' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CASE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CATCH' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CHARACTER' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLASS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLASS_C' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLASS_NAME_CONSTANT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLONE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLOSE_BRACKET' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLOSE_CURLY' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLOSE_SQUARE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLOSE_TAG' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_COALESCE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_COLON' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_COMMA' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_COMMENT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_COMPILER_HALT_OFFSET' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CONCAT_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CONST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CONSTANT_ENCAPSED_STRING' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CONTINUE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CURLY_OPEN' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DEC' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DECLARE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DEFAULT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DIR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DIV' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DIV_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DNUMBER' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DO' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOC_COMMENT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOLLAR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOLLAR_OPEN_CURLY_BRACES' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOUBLE_ARROW' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOUBLE_CAST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOUBLE_COLON' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOUBLE_QUOTES' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ECHO' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ELLIPSIS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ELSE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ELSEIF' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EMPTY' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENCAPSED_AND_WHITESPACE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDDECLARE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDFOR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDFOREACH' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDIF' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDSWITCH' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDWHILE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_END_HEREDOC' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENUM' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EQUALS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EVAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EXCLAMATION_MARK' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EXIT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EXTENDS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FILE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FINAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FINALLY' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FOR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FOREACH' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FUNCTION' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FUNC_C' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_GLOBAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_GOTO' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_GT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_HALT_COMPILER' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IF' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IMPLEMENTS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IN' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INC' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INCLUDE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INCLUDE_ONCE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INLINE_HTML' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INSTANCEOF' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INSTEADOF' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INTERFACE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INT_CAST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ISSET' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_GREATER_OR_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_IDENTICAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_NOT_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_NOT_IDENTICAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_SMALLER_OR_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_Includes' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_JOIN' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LAMBDA_ARROW' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LAMBDA_CP' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LAMBDA_OP' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LINE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LIST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LNUMBER' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LOGICAL_AND' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LOGICAL_OR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LOGICAL_XOR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_METHOD_C' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_MINUS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_MINUS_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_MOD_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_MULT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_MUL_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NAMESPACE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NEW' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NS_C' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NS_SEPARATOR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NUM_STRING' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OBJECT_CAST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OBJECT_OPERATOR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ONUMBER' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OPEN_BRACKET' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OPEN_CURLY' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OPEN_SQUARE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OPEN_TAG' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OPEN_TAG_WITH_ECHO' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OR_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PAAMAYIM_NEKUDOTAYIM' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PERCENT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PIPE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PLUS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PLUS_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_POW' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_POW_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PRINT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PRIVATE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PROTECTED' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PUBLIC' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_QUESTION_MARK' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_REQUIRE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_REQUIRE_ONCE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_RETURN' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SEMICOLON' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SHAPE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SL_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SPACESHIP' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SR_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_START_HEREDOC' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_STATIC' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_STRING' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_STRING_CAST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_STRING_VARNAME' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SUPER' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SWITCH' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_Stream' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token/Stream.php', + 'PHP_Token_Stream_CachingFactory' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token/Stream/CachingFactory.php', + 'PHP_Token_THROW' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TILDE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TRAIT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TRAIT_C' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TRY' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TYPE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TYPELIST_GT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TYPELIST_LT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_UNSET' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_UNSET_CAST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_USE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_USE_FUNCTION' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_VAR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_VARIABLE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_WHERE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_WHILE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_WHITESPACE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_ATTRIBUTE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_CATEGORY' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_CATEGORY_LABEL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_CHILDREN' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_LABEL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_REQUIRED' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_TAG_GT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_TAG_LT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_TEXT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XOR_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_YIELD' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_YIELD_FROM' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'Robo\\composer\\ScriptHandler' => __DIR__ . '/..' . '/consolidation/robo/scripts/composer/ScriptHandler.php', + 'SebastianBergmann\\CodeCoverage\\CodeCoverage' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/CodeCoverage.php', + 'SebastianBergmann\\CodeCoverage\\CoveredCodeNotExecutedException' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Exception/CoveredCodeNotExecutedException.php', + 'SebastianBergmann\\CodeCoverage\\Driver\\Driver' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Driver/Driver.php', + 'SebastianBergmann\\CodeCoverage\\Driver\\HHVM' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Driver/HHVM.php', + 'SebastianBergmann\\CodeCoverage\\Driver\\PHPDBG' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Driver/PHPDBG.php', + 'SebastianBergmann\\CodeCoverage\\Driver\\Xdebug' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Driver/Xdebug.php', + 'SebastianBergmann\\CodeCoverage\\Exception' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Exception/Exception.php', + 'SebastianBergmann\\CodeCoverage\\Filter' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Filter.php', + 'SebastianBergmann\\CodeCoverage\\InvalidArgumentException' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Exception/InvalidArgumentException.php', + 'SebastianBergmann\\CodeCoverage\\MissingCoversAnnotationException' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Exception/MissingCoversAnnotationException.php', + 'SebastianBergmann\\CodeCoverage\\Node\\AbstractNode' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Node/AbstractNode.php', + 'SebastianBergmann\\CodeCoverage\\Node\\Builder' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Node/Builder.php', + 'SebastianBergmann\\CodeCoverage\\Node\\Directory' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Node/Directory.php', + 'SebastianBergmann\\CodeCoverage\\Node\\File' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Node/File.php', + 'SebastianBergmann\\CodeCoverage\\Node\\Iterator' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Node/Iterator.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Clover' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Clover.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Crap4j' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Crap4j.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Dashboard' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Html/Renderer/Dashboard.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Directory' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Html/Renderer/Directory.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Facade' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Html/Facade.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Html\\File' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Html/Renderer/File.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Renderer' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Html/Renderer.php', + 'SebastianBergmann\\CodeCoverage\\Report\\PHP' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/PHP.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Text' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Text.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Coverage' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Coverage.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Directory' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Directory.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Facade' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Facade.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\File' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/File.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Method' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Method.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Node' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Node.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Project' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Project.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Report' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Report.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Tests' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Tests.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Totals' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Totals.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Unit' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Unit.php', + 'SebastianBergmann\\CodeCoverage\\RuntimeException' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Exception/RuntimeException.php', + 'SebastianBergmann\\CodeCoverage\\UnintentionallyCoveredCodeException' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Exception/UnintentionallyCoveredCodeException.php', + 'SebastianBergmann\\CodeCoverage\\Util' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Util.php', + 'SebastianBergmann\\CodeUnitReverseLookup\\Wizard' => __DIR__ . '/..' . '/sebastian/code-unit-reverse-lookup/src/Wizard.php', + 'SebastianBergmann\\Comparator\\ArrayComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/ArrayComparator.php', + 'SebastianBergmann\\Comparator\\Comparator' => __DIR__ . '/..' . '/sebastian/comparator/src/Comparator.php', + 'SebastianBergmann\\Comparator\\ComparisonFailure' => __DIR__ . '/..' . '/sebastian/comparator/src/ComparisonFailure.php', + 'SebastianBergmann\\Comparator\\DOMNodeComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/DOMNodeComparator.php', + 'SebastianBergmann\\Comparator\\DateTimeComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/DateTimeComparator.php', + 'SebastianBergmann\\Comparator\\DoubleComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/DoubleComparator.php', + 'SebastianBergmann\\Comparator\\ExceptionComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/ExceptionComparator.php', + 'SebastianBergmann\\Comparator\\Factory' => __DIR__ . '/..' . '/sebastian/comparator/src/Factory.php', + 'SebastianBergmann\\Comparator\\MockObjectComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/MockObjectComparator.php', + 'SebastianBergmann\\Comparator\\NumericComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/NumericComparator.php', + 'SebastianBergmann\\Comparator\\ObjectComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/ObjectComparator.php', + 'SebastianBergmann\\Comparator\\ResourceComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/ResourceComparator.php', + 'SebastianBergmann\\Comparator\\ScalarComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/ScalarComparator.php', + 'SebastianBergmann\\Comparator\\SplObjectStorageComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/SplObjectStorageComparator.php', + 'SebastianBergmann\\Comparator\\TypeComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/TypeComparator.php', + 'SebastianBergmann\\Diff\\Chunk' => __DIR__ . '/..' . '/sebastian/diff/src/Chunk.php', + 'SebastianBergmann\\Diff\\Diff' => __DIR__ . '/..' . '/sebastian/diff/src/Diff.php', + 'SebastianBergmann\\Diff\\Differ' => __DIR__ . '/..' . '/sebastian/diff/src/Differ.php', + 'SebastianBergmann\\Diff\\LCS\\LongestCommonSubsequence' => __DIR__ . '/..' . '/sebastian/diff/src/LCS/LongestCommonSubsequence.php', + 'SebastianBergmann\\Diff\\LCS\\MemoryEfficientImplementation' => __DIR__ . '/..' . '/sebastian/diff/src/LCS/MemoryEfficientLongestCommonSubsequenceImplementation.php', + 'SebastianBergmann\\Diff\\LCS\\TimeEfficientImplementation' => __DIR__ . '/..' . '/sebastian/diff/src/LCS/TimeEfficientLongestCommonSubsequenceImplementation.php', + 'SebastianBergmann\\Diff\\Line' => __DIR__ . '/..' . '/sebastian/diff/src/Line.php', + 'SebastianBergmann\\Diff\\Parser' => __DIR__ . '/..' . '/sebastian/diff/src/Parser.php', + 'SebastianBergmann\\Environment\\Console' => __DIR__ . '/..' . '/sebastian/environment/src/Console.php', + 'SebastianBergmann\\Environment\\Runtime' => __DIR__ . '/..' . '/sebastian/environment/src/Runtime.php', + 'SebastianBergmann\\Exporter\\Exporter' => __DIR__ . '/..' . '/sebastian/exporter/src/Exporter.php', + 'SebastianBergmann\\GlobalState\\Blacklist' => __DIR__ . '/..' . '/sebastian/global-state/src/Blacklist.php', + 'SebastianBergmann\\GlobalState\\CodeExporter' => __DIR__ . '/..' . '/sebastian/global-state/src/CodeExporter.php', + 'SebastianBergmann\\GlobalState\\Exception' => __DIR__ . '/..' . '/sebastian/global-state/src/Exception.php', + 'SebastianBergmann\\GlobalState\\Restorer' => __DIR__ . '/..' . '/sebastian/global-state/src/Restorer.php', + 'SebastianBergmann\\GlobalState\\RuntimeException' => __DIR__ . '/..' . '/sebastian/global-state/src/RuntimeException.php', + 'SebastianBergmann\\GlobalState\\Snapshot' => __DIR__ . '/..' . '/sebastian/global-state/src/Snapshot.php', + 'SebastianBergmann\\ObjectEnumerator\\Enumerator' => __DIR__ . '/..' . '/sebastian/object-enumerator/src/Enumerator.php', + 'SebastianBergmann\\ObjectEnumerator\\Exception' => __DIR__ . '/..' . '/sebastian/object-enumerator/src/Exception.php', + 'SebastianBergmann\\ObjectEnumerator\\InvalidArgumentException' => __DIR__ . '/..' . '/sebastian/object-enumerator/src/InvalidArgumentException.php', + 'SebastianBergmann\\RecursionContext\\Context' => __DIR__ . '/..' . '/sebastian/recursion-context/src/Context.php', + 'SebastianBergmann\\RecursionContext\\Exception' => __DIR__ . '/..' . '/sebastian/recursion-context/src/Exception.php', + 'SebastianBergmann\\RecursionContext\\InvalidArgumentException' => __DIR__ . '/..' . '/sebastian/recursion-context/src/InvalidArgumentException.php', + 'SebastianBergmann\\ResourceOperations\\ResourceOperations' => __DIR__ . '/..' . '/sebastian/resource-operations/src/ResourceOperations.php', + 'SebastianBergmann\\Version' => __DIR__ . '/..' . '/sebastian/version/src/Version.php', + 'Text_Template' => __DIR__ . '/..' . '/phpunit/php-text-template/src/Template.php', + ); + public static function getInitializer(ClassLoader $loader) { return \Closure::bind(function () use ($loader) { $loader->prefixLengthsPsr4 = ComposerStaticInit91d733469d809ee1828b45ab2da48a10::$prefixLengthsPsr4; $loader->prefixDirsPsr4 = ComposerStaticInit91d733469d809ee1828b45ab2da48a10::$prefixDirsPsr4; $loader->prefixesPsr0 = ComposerStaticInit91d733469d809ee1828b45ab2da48a10::$prefixesPsr0; + $loader->classMap = ComposerStaticInit91d733469d809ee1828b45ab2da48a10::$classMap; }, null, ClassLoader::class); } diff --git a/src/composer/vendor/composer/installed.json b/src/composer/vendor/composer/installed.json index b2b9de09..4afa3d00 100644 --- a/src/composer/vendor/composer/installed.json +++ b/src/composer/vendor/composer/installed.json @@ -1,44 +1,4 @@ [ - { - "name": "psr/log", - "version": "1.0.0", - "version_normalized": "1.0.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": "" - }, - "time": "2012-12-21 11:40:51", - "type": "library", - "installation-source": "dist", - "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" - ] - }, { "name": "monolog/monolog", "version": "1.13.1", @@ -294,5 +254,2178 @@ "po", "translation" ] + }, + { + "name": "symfony/event-dispatcher", + "version": "v3.1.6", + "version_normalized": "3.1.6.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "28b0832b2553ffb80cabef6a7a812ff1e670c0bc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/28b0832b2553ffb80cabef6a7a812ff1e670c0bc", + "reference": "28b0832b2553ffb80cabef6a7a812ff1e670c0bc", + "shasum": "" + }, + "require": { + "php": ">=5.5.9" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "~2.8|~3.0", + "symfony/dependency-injection": "~2.8|~3.0", + "symfony/expression-language": "~2.8|~3.0", + "symfony/stopwatch": "~2.8|~3.0" + }, + "suggest": { + "symfony/dependency-injection": "", + "symfony/http-kernel": "" + }, + "time": "2016-10-13 06:28:43", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony EventDispatcher Component", + "homepage": "https://symfony.com" + }, + { + "name": "symfony/filesystem", + "version": "v3.1.6", + "version_normalized": "3.1.6.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "0565b61bf098cb4dc09f4f103f033138ae4f42c6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/0565b61bf098cb4dc09f4f103f033138ae4f42c6", + "reference": "0565b61bf098cb4dc09f4f103f033138ae4f42c6", + "shasum": "" + }, + "require": { + "php": ">=5.5.9" + }, + "time": "2016-10-18 04:30:12", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "installation-source": "dist", + "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" + }, + { + "name": "symfony/process", + "version": "v3.1.6", + "version_normalized": "3.1.6.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "66de154ae86b1a07001da9fbffd620206e4faf94" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/66de154ae86b1a07001da9fbffd620206e4faf94", + "reference": "66de154ae86b1a07001da9fbffd620206e4faf94", + "shasum": "" + }, + "require": { + "php": ">=5.5.9" + }, + "time": "2016-09-29 14:13:09", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "installation-source": "dist", + "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" + }, + { + "name": "psr/log", + "version": "1.0.2", + "version_normalized": "1.0.2.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", + "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "time": "2016-10-10 12:19:37", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ] + }, + { + "name": "symfony/debug", + "version": "v3.1.6", + "version_normalized": "3.1.6.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/debug.git", + "reference": "e2b3f74a67fc928adc3c1b9027f73e1bc01190a8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/debug/zipball/e2b3f74a67fc928adc3c1b9027f73e1bc01190a8", + "reference": "e2b3f74a67fc928adc3c1b9027f73e1bc01190a8", + "shasum": "" + }, + "require": { + "php": ">=5.5.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.8|~3.0", + "symfony/http-kernel": "~2.8|~3.0" + }, + "time": "2016-09-06 11:02:40", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Component\\Debug\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Debug Component", + "homepage": "https://symfony.com" + }, + { + "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-14 01:06:16", + "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": "symfony/console", + "version": "v3.1.6", + "version_normalized": "3.1.6.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "c99da1119ae61e15de0e4829196b9fba6f73d065" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/c99da1119ae61e15de0e4829196b9fba6f73d065", + "reference": "c99da1119ae61e15de0e4829196b9fba6f73d065", + "shasum": "" + }, + "require": { + "php": ">=5.5.9", + "symfony/debug": "~2.8|~3.0", + "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": "" + }, + "time": "2016-10-06 01:44:51", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "installation-source": "dist", + "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" + }, + { + "name": "symfony/finder", + "version": "v3.1.6", + "version_normalized": "3.1.6.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "205b5ffbb518a98ba2ae60a52656c4a31ab00c6f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/205b5ffbb518a98ba2ae60a52656c4a31ab00c6f", + "reference": "205b5ffbb518a98ba2ae60a52656c4a31ab00c6f", + "shasum": "" + }, + "require": { + "php": ">=5.5.9" + }, + "time": "2016-09-28 00:11:12", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "installation-source": "dist", + "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" + }, + { + "name": "container-interop/container-interop", + "version": "1.1.0", + "version_normalized": "1.1.0.0", + "source": { + "type": "git", + "url": "https://github.com/container-interop/container-interop.git", + "reference": "fc08354828f8fd3245f77a66b9e23a6bca48297e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/container-interop/container-interop/zipball/fc08354828f8fd3245f77a66b9e23a6bca48297e", + "reference": "fc08354828f8fd3245f77a66b9e23a6bca48297e", + "shasum": "" + }, + "time": "2014-12-30 15:22:37", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Interop\\Container\\": "src/Interop/Container/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Promoting the interoperability of container objects (DIC, SL, etc.)" + }, + { + "name": "league/container", + "version": "2.2.0", + "version_normalized": "2.2.0.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/container.git", + "reference": "c0e7d947b690891f700dc4967ead7bdb3d6708c1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/container/zipball/c0e7d947b690891f700dc4967ead7bdb3d6708c1", + "reference": "c0e7d947b690891f700dc4967ead7bdb3d6708c1", + "shasum": "" + }, + "require": { + "container-interop/container-interop": "^1.1", + "php": ">=5.4.0" + }, + "provide": { + "container-interop/container-interop-implementation": "^1.1" + }, + "replace": { + "orno/di": "~2.0" + }, + "require-dev": { + "phpunit/phpunit": "4.*" + }, + "time": "2016-03-17 11:07:59", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev", + "dev-1.x": "1.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "League\\Container\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Phil Bennett", + "email": "philipobenito@gmail.com", + "homepage": "http://www.philipobenito.com", + "role": "Developer" + } + ], + "description": "A fast and intuitive dependency injection container.", + "homepage": "https://github.com/thephpleague/container", + "keywords": [ + "container", + "dependency", + "di", + "injection", + "league", + "provider", + "service" + ] + }, + { + "name": "victorjonsson/markdowndocs", + "version": "1.3.7", + "version_normalized": "1.3.7.0", + "source": { + "type": "git", + "url": "https://github.com/victorjonsson/PHP-Markdown-Documentation-Generator.git", + "reference": "a8244617cdce4804cd94ea508c82e8d7e29a273a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/victorjonsson/PHP-Markdown-Documentation-Generator/zipball/a8244617cdce4804cd94ea508c82e8d7e29a273a", + "reference": "a8244617cdce4804cd94ea508c82e8d7e29a273a", + "shasum": "" + }, + "require": { + "php": ">=5.5.0", + "symfony/console": ">=2.6" + }, + "require-dev": { + "phpunit/phpunit": "3.7.23" + }, + "time": "2016-10-11 21:10:19", + "bin": [ + "bin/phpdoc-md" + ], + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-0": { + "PHPDocsMD": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Victor Jonsson", + "email": "kontakt@victorjonsson.se" + } + ], + "description": "Command line tool for generating markdown-formatted class documentation", + "homepage": "https://github.com/victorjonsson/PHP-Markdown-Documentation-Generator" + }, + { + "name": "consolidation/log", + "version": "1.0.3", + "version_normalized": "1.0.3.0", + "source": { + "type": "git", + "url": "https://github.com/consolidation/log.git", + "reference": "74ba81b4edc585616747cc5c5309ce56fec41254" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/consolidation/log/zipball/74ba81b4edc585616747cc5c5309ce56fec41254", + "reference": "74ba81b4edc585616747cc5c5309ce56fec41254", + "shasum": "" + }, + "require": { + "php": ">=5.5.0", + "psr/log": "~1.0", + "symfony/console": "~2.5|~3.0" + }, + "require-dev": { + "phpunit/phpunit": "4.*", + "squizlabs/php_codesniffer": "2.*" + }, + "time": "2016-03-23 23:46:42", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Consolidation\\Log\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Greg Anderson", + "email": "greg.1.anderson@greenknowe.org" + } + ], + "description": "Improved Psr-3 / Psr\\Log logger based on Symfony Console components." + }, + { + "name": "webmozart/assert", + "version": "1.1.0", + "version_normalized": "1.1.0.0", + "source": { + "type": "git", + "url": "https://github.com/webmozart/assert.git", + "reference": "bb2d123231c095735130cc8f6d31385a44c7b308" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozart/assert/zipball/bb2d123231c095735130cc8f6d31385a44c7b308", + "reference": "bb2d123231c095735130cc8f6d31385a44c7b308", + "shasum": "" + }, + "require": { + "php": "^5.3.3|^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.6", + "sebastian/version": "^1.0.1" + }, + "time": "2016-08-09 15:02:57", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ] + }, + { + "name": "phpdocumentor/reflection-common", + "version": "1.0", + "version_normalized": "1.0.0.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/144c307535e82c8fdcaacbcfc1d6d8eeb896687c", + "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "phpunit/phpunit": "^4.6" + }, + "time": "2015-12-27 11:43:31", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ] + }, + { + "name": "phpdocumentor/type-resolver", + "version": "0.2", + "version_normalized": "0.2.0.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "b39c7a5b194f9ed7bd0dd345c751007a41862443" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/b39c7a5b194f9ed7bd0dd345c751007a41862443", + "reference": "b39c7a5b194f9ed7bd0dd345c751007a41862443", + "shasum": "" + }, + "require": { + "php": ">=5.5", + "phpdocumentor/reflection-common": "^1.0" + }, + "require-dev": { + "mockery/mockery": "^0.9.4", + "phpunit/phpunit": "^5.2||^4.8.24" + }, + "time": "2016-06-10 07:14:17", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ] + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "3.1.1", + "version_normalized": "3.1.1.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "8331b5efe816ae05461b7ca1e721c01b46bafb3e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/8331b5efe816ae05461b7ca1e721c01b46bafb3e", + "reference": "8331b5efe816ae05461b7ca1e721c01b46bafb3e", + "shasum": "" + }, + "require": { + "php": ">=5.5", + "phpdocumentor/reflection-common": "^1.0@dev", + "phpdocumentor/type-resolver": "^0.2.0", + "webmozart/assert": "^1.0" + }, + "require-dev": { + "mockery/mockery": "^0.9.4", + "phpunit/phpunit": "^4.4" + }, + "time": "2016-09-30 07:12:33", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock." + }, + { + "name": "consolidation/robo", + "version": "1.0.4", + "version_normalized": "1.0.4.0", + "source": { + "type": "git", + "url": "https://github.com/consolidation/Robo.git", + "reference": "bfe2246358298d7839114612f84bcfdca3c14066" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/consolidation/Robo/zipball/bfe2246358298d7839114612f84bcfdca3c14066", + "reference": "bfe2246358298d7839114612f84bcfdca3c14066", + "shasum": "" + }, + "require": { + "consolidation/annotated-command": "^2.0.1", + "consolidation/log": "~1", + "consolidation/output-formatters": "^2.1.2|~3", + "league/container": "^2.2", + "php": ">=5.5.0", + "symfony/console": "~2.8|~3.0", + "symfony/event-dispatcher": "~2.5|~3.0", + "symfony/filesystem": "~2.5|~3.0", + "symfony/finder": "~2.5|~3.0", + "symfony/process": "~2.5|~3.0" + }, + "replace": { + "codegyre/robo": "< 1.0" + }, + "require-dev": { + "codeception/aspect-mock": "~1", + "codeception/base": "^2.2.6", + "codeception/verify": "^0.3.2", + "henrikbjorn/lurker": "~1", + "natxet/cssmin": "~3", + "patchwork/jsqueeze": "~2", + "pear/archive_tar": "^1.4.2", + "phpunit/php-code-coverage": "~2|~4", + "satooshi/php-coveralls": "~1", + "squizlabs/php_codesniffer": "~2" + }, + "suggest": { + "henrikbjorn/lurker": "For monitoring filesystem changes in taskWatch", + "natxet/CssMin": "For minifying JS files in taskMinify", + "patchwork/jsqueeze": "For minifying JS files in taskMinify", + "pear/archive_tar": "Allows tar archives to be created and extracted in taskPack and taskExtract, respectively." + }, + "time": "2016-11-15 19:24:36", + "bin": [ + "robo" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "scripts/composer/ScriptHandler.php" + ], + "psr-4": { + "Robo\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Davert", + "email": "davert.php@resend.cc" + } + ], + "description": "Modern task runner" + }, + { + "name": "symfony/yaml", + "version": "v3.1.6", + "version_normalized": "3.1.6.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "7ff51b06c6c3d5cc6686df69004a42c69df09e27" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/7ff51b06c6c3d5cc6686df69004a42c69df09e27", + "reference": "7ff51b06c6c3d5cc6686df69004a42c69df09e27", + "shasum": "" + }, + "require": { + "php": ">=5.5.9" + }, + "time": "2016-10-24 18:41:13", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "installation-source": "dist", + "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" + }, + { + "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.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.2" + }, + "suggest": { + "ext-uopz": "*" + }, + "time": "2015-10-12 03:26:01", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ] + }, + { + "name": "sebastian/recursion-context", + "version": "1.0.4", + "version_normalized": "1.0.4.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "938df7a6478e72795e5f8266cff24d06e3136f2e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/938df7a6478e72795e5f8266cff24d06e3136f2e", + "reference": "938df7a6478e72795e5f8266cff24d06e3136f2e", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "time": "2016-11-15 06:55:36", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "http://www.github.com/sebastianbergmann/recursion-context" + }, + { + "name": "sebastian/exporter", + "version": "1.2.2", + "version_normalized": "1.2.2.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/42c4c2eec485ee3e159ec9884f95b431287edde4", + "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "sebastian/recursion-context": "~1.0" + }, + "require-dev": { + "ext-mbstring": "*", + "phpunit/phpunit": "~4.4" + }, + "time": "2016-06-17 09:04:28", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "http://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ] + }, + { + "name": "sebastian/environment", + "version": "1.3.8", + "version_normalized": "1.3.8.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/be2c607e43ce4c89ecd60e75c6a85c126e754aea", + "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8 || ^5.0" + }, + "time": "2016-08-18 05:49:44", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ] + }, + { + "name": "sebastian/diff", + "version": "1.4.1", + "version_normalized": "1.4.1.0", + "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" + }, + "time": "2015-12-08 07:14:41", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff" + ] + }, + { + "name": "doctrine/instantiator", + "version": "1.0.5", + "version_normalized": "1.0.5.0", + "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" + }, + "time": "2015-06-14 21:17:01", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "http://ocramius.github.com/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://github.com/doctrine/instantiator", + "keywords": [ + "constructor", + "instantiate" + ] + }, + { + "name": "phpspec/prophecy", + "version": "v1.6.1", + "version_normalized": "1.6.1.0", + "source": { + "type": "git", + "url": "https://github.com/phpspec/prophecy.git", + "reference": "58a8137754bc24b25740d4281399a4a3596058e0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/58a8137754bc24b25740d4281399a4a3596058e0", + "reference": "58a8137754bc24b25740d4281399a4a3596058e0", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.2", + "php": "^5.3|^7.0", + "phpdocumentor/reflection-docblock": "^2.0|^3.0.2", + "sebastian/comparator": "^1.1", + "sebastian/recursion-context": "^1.0" + }, + "require-dev": { + "phpspec/phpspec": "^2.0" + }, + "time": "2016-06-07 08:13:47", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.6.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-0": { + "Prophecy\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + }, + { + "name": "Marcello Duarte", + "email": "marcello.duarte@gmail.com" + } + ], + "description": "Highly opinionated mocking framework for PHP 5.3+", + "homepage": "https://github.com/phpspec/prophecy", + "keywords": [ + "Double", + "Dummy", + "fake", + "mock", + "spy", + "stub" + ] + }, + { + "name": "sebastian/version", + "version": "2.0.0", + "version_normalized": "2.0.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "c829badbd8fdf16a0bad8aa7fa7971c029f1b9c5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c829badbd8fdf16a0bad8aa7fa7971c029f1b9c5", + "reference": "c829badbd8fdf16a0bad8aa7fa7971c029f1b9c5", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "time": "2016-02-04 12:56:52", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version" + }, + { + "name": "sebastian/resource-operations", + "version": "1.0.0", + "version_normalized": "1.0.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/resource-operations.git", + "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "shasum": "" + }, + "require": { + "php": ">=5.6.0" + }, + "time": "2015-07-28 20:34:47", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides a list of PHP built-in functions that operate on resources", + "homepage": "https://www.github.com/sebastianbergmann/resource-operations" + }, + { + "name": "sebastian/object-enumerator", + "version": "1.0.0", + "version_normalized": "1.0.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "d4ca2fb70344987502567bc50081c03e6192fb26" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/d4ca2fb70344987502567bc50081c03e6192fb26", + "reference": "d4ca2fb70344987502567bc50081c03e6192fb26", + "shasum": "" + }, + "require": { + "php": ">=5.6", + "sebastian/recursion-context": "~1.0" + }, + "require-dev": { + "phpunit/phpunit": "~5" + }, + "time": "2016-01-28 13:25:10", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/" + }, + { + "name": "sebastian/comparator", + "version": "1.2.2", + "version_normalized": "1.2.2.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "6a1ed12e8b2409076ab22e3897126211ff8b1f7f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/6a1ed12e8b2409076ab22e3897126211ff8b1f7f", + "reference": "6a1ed12e8b2409076ab22e3897126211ff8b1f7f", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "sebastian/diff": "~1.2", + "sebastian/exporter": "~1.2 || ~2.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "time": "2016-11-19 09:18:40", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "http://www.github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ] + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "1.0.0", + "version_normalized": "1.0.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "c36f5e7cfce482fde5bf8d10d41a53591e0198fe" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/c36f5e7cfce482fde5bf8d10d41a53591e0198fe", + "reference": "c36f5e7cfce482fde5bf8d10d41a53591e0198fe", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "require-dev": { + "phpunit/phpunit": "~5" + }, + "time": "2016-02-13 06:45:14", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/" + }, + { + "name": "myclabs/deep-copy", + "version": "1.5.5", + "version_normalized": "1.5.5.0", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "399c1f9781e222f6eb6cc238796f5200d1b7f108" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/399c1f9781e222f6eb6cc238796f5200d1b7f108", + "reference": "399c1f9781e222f6eb6cc238796f5200d1b7f108", + "shasum": "" + }, + "require": { + "php": ">=5.4.0" + }, + "require-dev": { + "doctrine/collections": "1.*", + "phpunit/phpunit": "~4.1" + }, + "time": "2016-10-31 17:19:45", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "homepage": "https://github.com/myclabs/DeepCopy", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ] + }, + { + "name": "consolidation/output-formatters", + "version": "3.1.3", + "version_normalized": "3.1.3.0", + "source": { + "type": "git", + "url": "https://github.com/consolidation/output-formatters.git", + "reference": "1e6c6ab49904a31c310940ec4efccf5f36e386e4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/consolidation/output-formatters/zipball/1e6c6ab49904a31c310940ec4efccf5f36e386e4", + "reference": "1e6c6ab49904a31c310940ec4efccf5f36e386e4", + "shasum": "" + }, + "require": { + "php": ">=5.4.0", + "symfony/console": "~2.5|~3.0", + "symfony/finder": "~2.5|~3.0", + "victorjonsson/markdowndocs": "^1.3" + }, + "require-dev": { + "phpunit/phpunit": "4.*", + "satooshi/php-coveralls": "^1.0", + "squizlabs/php_codesniffer": "2.*" + }, + "time": "2016-11-18 23:04:31", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Consolidation\\OutputFormatters\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Greg Anderson", + "email": "greg.1.anderson@greenknowe.org" + } + ], + "description": "Format text by applying transformations provided by plug-in formatters." + }, + { + "name": "consolidation/annotated-command", + "version": "2.1.3", + "version_normalized": "2.1.3.0", + "source": { + "type": "git", + "url": "https://github.com/consolidation/annotated-command.git", + "reference": "6dcc442cbdc2c5145bb19e042d6b5f3979003b9f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/consolidation/annotated-command/zipball/6dcc442cbdc2c5145bb19e042d6b5f3979003b9f", + "reference": "6dcc442cbdc2c5145bb19e042d6b5f3979003b9f", + "shasum": "" + }, + "require": { + "consolidation/output-formatters": "^3.1.3", + "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": { + "phpunit/phpunit": "4.*", + "satooshi/php-coveralls": "^1.0", + "squizlabs/php_codesniffer": "^2.7" + }, + "time": "2016-11-19 01:02:43", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-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": "phpunit/php-text-template", + "version": "1.2.1", + "version_normalized": "1.2.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "time": "2015-06-21 13:50:34", + "type": "library", + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ] + }, + { + "name": "phpunit/phpunit-mock-objects", + "version": "3.4.1", + "version_normalized": "3.4.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", + "reference": "45026c8383187ad1dcb14fbfec77dced265b9cfc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/45026c8383187ad1dcb14fbfec77dced265b9cfc", + "reference": "45026c8383187ad1dcb14fbfec77dced265b9cfc", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.2", + "php": "^5.6 || ^7.0", + "phpunit/php-text-template": "^1.2", + "sebastian/exporter": "^1.2 || ^2.0" + }, + "conflict": { + "phpunit/phpunit": "<5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.4" + }, + "suggest": { + "ext-soap": "*" + }, + "time": "2016-11-19 09:07:46", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2.x-dev" + } + }, + "installation-source": "dist", + "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" + ] + }, + { + "name": "phpunit/php-timer", + "version": "1.0.8", + "version_normalized": "1.0.8.0", + "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" + }, + "time": "2016-05-12 18:03:57", + "type": "library", + "installation-source": "dist", + "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" + ] + }, + { + "name": "phpunit/php-file-iterator", + "version": "1.4.1", + "version_normalized": "1.4.1.0", + "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" + }, + "time": "2015-06-21 13:08:43", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, + "installation-source": "dist", + "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" + ] + }, + { + "name": "phpunit/php-token-stream", + "version": "1.4.9", + "version_normalized": "1.4.9.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-token-stream.git", + "reference": "3b402f65a4cc90abf6e1104e388b896ce209631b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3b402f65a4cc90abf6e1104e388b896ce209631b", + "reference": "3b402f65a4cc90abf6e1104e388b896ce209631b", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.2" + }, + "time": "2016-11-15 14:06:22", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Wrapper around PHP's tokenizer extension.", + "homepage": "https://github.com/sebastianbergmann/php-token-stream/", + "keywords": [ + "tokenizer" + ] + }, + { + "name": "phpunit/php-code-coverage", + "version": "4.0.2", + "version_normalized": "4.0.2.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "6cba06ff75a1a63a71033e1a01b89056f3af1e8d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/6cba06ff75a1a63a71033e1a01b89056f3af1e8d", + "reference": "6cba06ff75a1a63a71033e1a01b89056f3af1e8d", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0", + "phpunit/php-file-iterator": "~1.3", + "phpunit/php-text-template": "~1.2", + "phpunit/php-token-stream": "^1.4.2", + "sebastian/code-unit-reverse-lookup": "~1.0", + "sebastian/environment": "^1.3.2 || ^2.0", + "sebastian/version": "~1.0|~2.0" + }, + "require-dev": { + "ext-xdebug": ">=2.1.4", + "phpunit/phpunit": "^5.4" + }, + "suggest": { + "ext-dom": "*", + "ext-xdebug": ">=2.4.0", + "ext-xmlwriter": "*" + }, + "time": "2016-11-01 05:06:24", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0.x-dev" + } + }, + "installation-source": "dist", + "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" + ] + }, + { + "name": "phpunit/phpunit", + "version": "5.5.7", + "version_normalized": "5.5.7.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "3f67cee782c9abfaee5e32fd2f57cdd54bc257ba" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/3f67cee782c9abfaee5e32fd2f57cdd54bc257ba", + "reference": "3f67cee782c9abfaee5e32fd2f57cdd54bc257ba", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "myclabs/deep-copy": "~1.3", + "php": "^5.6 || ^7.0", + "phpspec/prophecy": "^1.3.1", + "phpunit/php-code-coverage": "^4.0.1", + "phpunit/php-file-iterator": "~1.4", + "phpunit/php-text-template": "~1.2", + "phpunit/php-timer": "^1.0.6", + "phpunit/phpunit-mock-objects": "^3.2", + "sebastian/comparator": "~1.1", + "sebastian/diff": "~1.2", + "sebastian/environment": "^1.3 || ^2.0", + "sebastian/exporter": "~1.2", + "sebastian/global-state": "~1.0", + "sebastian/object-enumerator": "~1.0", + "sebastian/resource-operations": "~1.0", + "sebastian/version": "~1.0|~2.0", + "symfony/yaml": "~2.1|~3.0" + }, + "conflict": { + "phpdocumentor/reflection-docblock": "3.0.2" + }, + "require-dev": { + "ext-pdo": "*" + }, + "suggest": { + "ext-tidy": "*", + "ext-xdebug": "*", + "phpunit/php-invoker": "~1.1" + }, + "time": "2016-10-03 13:04:15", + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.5.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ] } ] diff --git a/src/composer/vendor/consolidation/annotated-command/.editorconfig b/src/composer/vendor/consolidation/annotated-command/.editorconfig new file mode 100644 index 00000000..095771e6 --- /dev/null +++ b/src/composer/vendor/consolidation/annotated-command/.editorconfig @@ -0,0 +1,15 @@ +# This file is for unifying the coding style for different editors and IDEs +# editorconfig.org + +root = true + +[*] +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[**.php] +indent_style = space +indent_size = 4 + diff --git a/src/composer/vendor/consolidation/annotated-command/.github/issue_template.md b/src/composer/vendor/consolidation/annotated-command/.github/issue_template.md new file mode 100644 index 00000000..97335f49 --- /dev/null +++ b/src/composer/vendor/consolidation/annotated-command/.github/issue_template.md @@ -0,0 +1,11 @@ +### Steps to reproduce +What did you do? + +### Expected behavior +Tell us what should happen + +### Actual behavior +Tell us what happens instead + +### System Configuration +Which O.S. and PHP version are you using? diff --git a/src/composer/vendor/consolidation/annotated-command/.github/pull_request_template.md b/src/composer/vendor/consolidation/annotated-command/.github/pull_request_template.md new file mode 100644 index 00000000..a80b513c --- /dev/null +++ b/src/composer/vendor/consolidation/annotated-command/.github/pull_request_template.md @@ -0,0 +1,13 @@ +### Disposition +This pull request: + +- [ ] Fixes a bug +- [ ] Adds a feature +- [ ] Breaks backwards compatibility +- [ ] Has tests that cover changes + +### Summary +Short overview of what changed. + +### Description +Any additional information. diff --git a/src/composer/vendor/consolidation/annotated-command/.gitignore b/src/composer/vendor/consolidation/annotated-command/.gitignore new file mode 100644 index 00000000..48d3686b --- /dev/null +++ b/src/composer/vendor/consolidation/annotated-command/.gitignore @@ -0,0 +1,5 @@ +.DS_Store +phpunit.xml +vendor +build +.idea diff --git a/src/composer/vendor/consolidation/annotated-command/.travis.yml b/src/composer/vendor/consolidation/annotated-command/.travis.yml new file mode 100644 index 00000000..0966ef0d --- /dev/null +++ b/src/composer/vendor/consolidation/annotated-command/.travis.yml @@ -0,0 +1,34 @@ +language: php + +branches: + # Only test the master branch and SemVer tags. + only: + - master + - /^[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+.*$/ + +matrix: + include: + - php: 7.0 + env: dependencies=highest + - php: 5.6 + - php: 5.5 + - php: 5.4 + env: dependencies=lowest + +sudo: false + +cache: + directories: + - $HOME/.composer/cache + +before_script: + - if [ -z "$dependencies" ]; then composer install --prefer-dist; fi; + - if [ "$dependencies" = "lowest" ]; then composer update --prefer-dist --prefer-lowest -n; fi; + - if [ "$dependencies" = "highest" ]; then composer update --prefer-dist -n; fi; + +script: + - vendor/bin/phpunit + - vendor/bin/phpcs --standard=PSR2 -n src + +after_success: + - travis_retry php vendor/bin/coveralls -v diff --git a/src/composer/vendor/consolidation/annotated-command/CHANGELOG.md b/src/composer/vendor/consolidation/annotated-command/CHANGELOG.md new file mode 100644 index 00000000..7a03b967 --- /dev/null +++ b/src/composer/vendor/consolidation/annotated-command/CHANGELOG.md @@ -0,0 +1,51 @@ +# Change Log + + +### 2.0.1 ~ 2.0.3 - 14 November 2016 + +- Fix version requirement for output-formatters in composer.json +- Use output-formatters ~3 +- Move php_codesniffer back to require-dev (moved to require by mistake) + + +### 2.0.0 - 30 September 2016 + +- **Breaking** Hooks with no command name now apply to all commands defined in the same class. This is a change of behavior from the 1.x branch, where hooks with no command name applied to a command with the same method name in a *different* class. +- **Breaking** The interfaces ValidatorInterface, ProcessResultInterface and AlterResultInterface have been updated to be passed a CommandData object, which contains an Input and Output object, plus the AnnotationData. +- **Breaking** The Symfony Command Event hook has been renamed to COMMAND_EVENT. There is a new COMMAND hook that behaves like the existing Drush command hook (i.e. the post-command event is called after the primary command method runs). +- Add an accessor function AnnotatedCommandFactory::setIncludeAllPublicMethods() to control whether all public methods of a command class, or only those with a @command annotation will be treated as commands. Default remains to treat all public methods as commands. The parameters to AnnotatedCommandFactory::createCommandsFromClass() and AnnotatedCommandFactory::createCommandsFromClassInfo() still behave the same way, but are deprecated. If omitted, the value set by the accessor will be used. +- @option and @usage annotations provided with @hook methods will be added to the help text of the command they hook. This should be done if a hook needs to add a new option, e.g. to control the behavior of the hook. +- @option annotations can now be either `@option type $name description`, or just `@option name description`. +- `@hook option` can be used to programatically add options to a command. +- A CommandInfoAltererInterface can be added via AnnotatedCommandFactory::addCommandInfoAlterer(); it will be given the opportunity to adjust every CommandInfo object parsed from a command file prior to the creation of commands. +- AnnotatedCommandFactory::setIncludeAllPublicMethods(false) may be used to require methods to be annotated with @commnad in order to be considered commands. This is in preference to the existing parameters of various command-creation methods of AnnotatedCommandFactory, which are now all deprecated in favor of this setter function. +- If a --field option is given, it will also force the output format to 'string'. +- Setter methods more consistently return $this. +- Removed PassThroughArgsInput. This class was unnecessary. + + +### 1.4.0 - 13 September 2016 + +- Add basic annotation hook capability, to allow hook functions to be attached to commands with arbitrary annotations. + + +### 1.3.0 - 8 September 2016 + +- Add ComandFileDiscovery::setSearchDepth(). The search depth applies to each search location, unless there are no search locations, in which case it applies to the base directory. + + +### 1.2.0 - 2 August 2016 + +- Support both the 2.x and 3.x versions of phpdocumentor/reflection-docblock. +- Support php 5.4. +- **Bug** Do not allow an @param docblock comment for the options to override the meaning of the options. + + +### 1.1.0 - 6 July 2016 + +- Introduce AnnotatedCommandFactory::createSelectedCommandsFromClassInfo() method. + + +### 1.0.0 - 20 May 2016 + +- First stable release. diff --git a/src/composer/vendor/consolidation/annotated-command/CONTRIBUTING.md b/src/composer/vendor/consolidation/annotated-command/CONTRIBUTING.md new file mode 100644 index 00000000..7a526eb5 --- /dev/null +++ b/src/composer/vendor/consolidation/annotated-command/CONTRIBUTING.md @@ -0,0 +1,31 @@ +# Contributing to Consolidation + +Thank you for your interest in contributing to the Consolidation effort! Consolidation aims to provide reusable, loosely-coupled components useful for building command-line tools. Consolidation is built on top of Symfony Console, but aims to separate the tool from the implementation details of Symfony. + +Here are some of the guidelines you should follow to make the most of your efforts: + +## Code Style Guidelines + +Consolidation adheres to the [PSR-2 Coding Style Guide](http://www.php-fig.org/psr/psr-2/) for PHP code. + +## Pull Request Guidelines + +Every pull request is run through: + + - phpcs -n --standard=PSR2 src + - phpunit + - [Scrutinizer](https://scrutinizer-ci.com/g/consolidation/annotated-command/) + +It is easy to run the unit tests and code sniffer locally; just run: + + - composer cs + +To run the code beautifier, which will fix many of the problems reported by phpcs: + + - composer cbf + +These two commands (`composer cs` and `composer cbf`) are defined in the `scripts` section of [composer.json](composer.json). + +After submitting a pull request, please examine the Scrutinizer report. It is not required to fix all Scrutinizer issues; you may ignore recommendations that you disagree with. The spacing patches produced by Scrutinizer do not conform to PSR2 standards, and therefore should never be applied. DocBlock patches may be applied at your discression. Things that Scrutinizer identifies as a bug nearly always need to be addressed. + +Pull requests must pass phpcs and phpunit in order to be merged; ideally, new functionality will also include new unit tests. diff --git a/src/composer/vendor/consolidation/annotated-command/LICENSE b/src/composer/vendor/consolidation/annotated-command/LICENSE new file mode 100644 index 00000000..2078bd88 --- /dev/null +++ b/src/composer/vendor/consolidation/annotated-command/LICENSE @@ -0,0 +1,8 @@ +Copyright (c) 2016 Consolidation Org Developers + + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/src/composer/vendor/consolidation/annotated-command/README.md b/src/composer/vendor/consolidation/annotated-command/README.md new file mode 100644 index 00000000..9e6d7728 --- /dev/null +++ b/src/composer/vendor/consolidation/annotated-command/README.md @@ -0,0 +1,251 @@ +# Consolidation\AnnotatedCommand + +Initialize Symfony Console commands from annotated command class methods. + +[![Travis CI](https://travis-ci.org/consolidation/annotated-command.svg?branch=master)](https://travis-ci.org/consolidation/annotated-command) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/consolidation/annotated-command/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/consolidation/annotated-command/?branch=master) [![Coverage Status](https://coveralls.io/repos/github/consolidation/annotated-command/badge.svg?branch=master)](https://coveralls.io/github/consolidation/annotated-command?branch=master) [![License](https://poser.pugx.org/consolidation/annotated-command/license)](https://packagist.org/packages/consolidation/annotated-command) + +## Component Status + +Currently in use in [Robo](https://github.com/consolidation/Robo) (1.x+), [Drush](https://github.com/drush-ops/drush) (9.x+) and [Terminus](https://github.com/pantheon-systems/terminus) (1.x+). + +## Motivation + +Symfony Console provides a set of classes that are widely used to implement command line tools. Increasingly, it is becoming popular to use annotations to describe the characteristics of the command (e.g. its arguments, options and so on) implemented by the annotated method. + +Extant commandline tools that utilize this technique include: + +- [Robo](https://github.com/consolidation/Robo) +- [wp-cli](https://github.com/wp-cli/wp-cli) +- [Pantheon Terminus](https://github.com/pantheon-systems/terminus) + +This library provides routines to produce the Symfony\Component\Console\Command\Command from all public methods defined in the provided class. + +**Note** If you are looking for a very fast way to write a Symfony Console-base command-line tool, you should consider using [Robo](https://github.com/consolidation/Robo), which is built on top of this library, and adds additional conveniences to get you going quickly. See [Using Robo as a Framework](https://github.com/consolidation/Robo/docs/framework.md). It is possible to use this project without Robo if desired, of course. + +## Library Usage + +This is a library intended to be used in some other project. Require from your composer.json file: +``` + "require": { + "consolidation/annotated-command": "~2" + }, +``` + +## Example Annotated Command Class +The public methods of the command class define its commands, and the parameters of each method define its arguments and options. The command options, if any, are declared as the last parameter of the methods. The options will be passed in as an associative array; the default options of the last parameter should list the options recognized by the command. + +The rest of the parameters are arguments. Parameters with a default value are optional; those without a default value are required. +```php +class MyCommandClass +{ + /** + * This is the my:cat command + * + * This command will concatenate two parameters. If the --flip flag + * is provided, then the result is the concatenation of two and one. + * + * @command my:cat + * @param integer $one The first parameter. + * @param integer $two The other parameter. + * @option flip Whether or not the second parameter should come first in the result. + * @aliases c + * @usage bet alpha --flip + * Concatenate "alpha" and "bet". + */ + public function myCat($one, $two, $options = ['flip' => false]) + { + if ($options['flip']) { + return "{$two}{$one}"; + } + return "{$one}{$two}"; + } +} +``` +## Hooks + +Commandfiles may provide hooks in addition to commands. A commandfile method that contains a @hook annotation is registered as a hook instead of a command. The format of the hook annotation is: +``` +@hook type commandname|annotation +``` +The commandname may be the command's primary name (e.g. `my:command`), it's method name (e.g. myCommand) or any of its aliases. + +If an annotation is given instead, then this hook function will run for all commands with the specified annotation. + +There are ten types of hooks supported: + +- Command Event (Symfony) +- Option +- Initialize (Symfony) +- Interact (Symfony) +- Validate +- Command +- Process +- Alter +- Status +- Extract + +Most of these also have "pre" and "post" varieties, to give more flexibility vis-a-vis hook ordering (and for consistency). Note that many validate, process and alter hooks may run, but the first status or extract hook that successfully returns a result will halt processing of further hooks of the same type. + +Each hook has an interface that defines its calling conventions; however, any callable may be used when registering a hook, which is convenient if versions of PHP prior to 7.0 (with no anonymous classes) need to be supported. + +### Command Event Hook + +The command-event hook is called via the Symfony Console command event notification callback mechanism. This happens prior to event dispatching and command / option validation. Note that Symfony does not allow the $input object to be altered in this hook; any change made here will be reset, as Symfony re-parses the object. Changes to arguments and options should be done in the initialize hook (non-interactive alterations) or the interact hook (which is naturally for interactive alterations). + +### Option Event Hook + +The option event hook ([OptionHookInterface](src/Hooks/OptionHookInterface.php)) is called for a specific command, whenever it is executed, or its help command is called. Any additional options for the command may be added here by instantiating and returnng an InputOption array. + +### Initialize Hook + +The initialize hook ([InitializeHookInterface](src/Hooks/InitializeHookInterface.php)) runs prior to the interact hook. It may supply command arguments and options from a configuration file or other sources. It should never do any user interaction. + +### Interact Hook + +The interact hook ([InteractorInterface](src/Hooks/InteractorInterface.php)) runs prior to argument and option validation. Required arguments and options not supplied on the command line may be provided during this phase by prompting the user. Note that the interact hook is not called if the --no-interaction flag is supplied, whereas the command-event hook and the inject-configuration hook are. + +### Validate Hook + +The purpose of the validate hook ([ValidatorInterface](src/Hooks/ValidatorInterface.php)) is to ensure the state of the targets of the current command are usabe in the context required by that command. Symfony has already validated the arguments and options prior to this hook. It is possible to alter the values of the arguments and options if necessary, although this is better done in the configure hook. A validation hook may take one of several actions: + +- Do nothing. This indicates that validation succeeded. +- Return a CommandError. Validation fails, and execution stops. The CommandError contains a status result code and a message, which is printed. +- Throw an exception. The exception is converted into a CommandError. +- Return false. Message is empty, and status is 1. Deprecated. + +The validate hook may change the arguments and options of the command by modifying the Input object in the provided CommandData parameter. Any number of validation hooks may run, but if any fails, then execution of the command stops. + +### Command Hook + +The command hook is provided for semantic purposes. The pre-command and command hooks are equivalent to the post-validate hook, and should confirm to the interface ([ValidatorInterface](src/Hooks/ValidatorInterface.php)). All of the post-validate hooks will be called before the first pre-command hook is called. Similarly, the post-command hook is equivalent to the pre-process hook, and should implement the interface ([ProcessResultInterface](src/Hooks/ProcessResultInterface.php)). + +The command callback itself (the method annotated @command) is called after the last command hook, and prior to the first post-command hook. + +### Process Hook + +The process hook ([ProcessResultInterface](src/Hooks/ProcessResultInterface.php)) is specifically designed to convert a series of processing instructions into a final result. An example of this is implemented in Robo; if a Robo command returns a TaskInterface, then a Robo process hook will execute the task and return the result. This allows a pre-process hook to alter the task, e.g. by adding more operations to a task collection. + +The process hook should not be used for other purposes. + +### Alter Hook + +An alter hook ([AlterResultInterface](src/Hooks/AlterResultInterface.php)) changes the result object. Alter hooks should only operate on result objects of a type they explicitly recognize. They may return an object of the same type, or they may convert the object to some other type. + +If something goes wrong, and the alter hooks wishes to force the command to fail, then it may either return a CommandError object, or throw an exception. + +### Status Hook + +The status hook ([StatusDeterminerInterface](src/Hooks/StatusDeterminerInterface.php)) is responsible for determing whether a command succeeded (status code 0) or failed (status code > 0). The result object returned by a command may be a compound object that contains multiple bits of information about the command result. If the result object implements [ExitCodeInterface](ExitCodeInterface.php), then the `getExitCode()` method of the result object is called to determine what the status result code for the command should be. If ExitCodeInterface is not implemented, then all of the status hooks attached to this command are executed; the first one that successfully returns a result will stop further execution of status hooks, and the result it returned will be used as the status result code for this operation. + +If no status hook returns any result, then success is presumed. + +### Extract Hook + +The extract hook ([ExtractOutputInterface](src/Hooks/ExtractOutputInterface.php)) is responsible for determining what the actual rendered output for the command should be. The result object returned by a command may be a compound object that contains multiple bits of information about the command result. If the result object implements [OutputDataInterface](OutputDataInterface.php), then the `getOutputData()` method of the result object is called to determine what information should be displayed to the user as a result of the command's execution. If OutputDataInterface is not implemented, then all of the extract hooks attached to this command are executed; the first one that successfully returns output data will stop further execution of extract hooks. + +If no extract hook returns any data, then the result object itself is printed if it is a string; otherwise, no output is emitted (other than any produced by the command itself). + +## Output + +If a command method returns an integer, it is used as the command exit status code. If the command method returns a string, it is printed. + +If the [Consolidation/OutputFormatters](https://github.com/consolidation/output-formatters) project is used, then users may specify a --format option to select the formatter to use to transform the output from whatever form the command provides to a string. To make this work, the application must provide a formatter to the AnnotatedCommandFactory. See [API Usage](#api-usage) below. + +## Logging + +The Annotated-Command project is completely agnostic to logging. If a command wishes to log progress, then the CommandFile class should implement LoggerAwareInterface, and the Commandline tool should inject a logger for its use via the LoggerAwareTrait `setLogger()` method. Using [Robo](https://github.com/consolidation/robo) is recommended. + +## Access to Symfony Objects + +If you want to use annotations, but still want access to the Symfony Command, e.g. to get a reference to the helpers in order to call some legacy code, you may create an ordinary Symfony Command that extends \Consolidation\AnnotatedCommand\AnnotatedCommand, which is a \Symfony\Component\Console\Command\Command. Omit the configure method, and place your annotations on the `execute()` method. + +It is also possible to add InputInterface or OutputInterface parameters to any annotated method of a command file. + +## API Usage + +If you would like to use Annotated Commands to build a commandline tool, it is recommended that you use [Robo as a framework](http://robo.li/framework.md), as it will set up all of the various command classes for you. If you would like to integrate Annotated Commands into some other framework, see the sections below. + +### Set up Command Factory and Instantiate Commands + +To use annotated commands in an application, pass an instance of your command class in to AnnotatedCommandFactory::createCommandsFromClass(). The result will be a list of Commands that may be added to your application. +```php +$myCommandClassInstance = new MyCommandClass(); +$commandFactory = new AnnotatedCommandFactory(); +$commandFactory->setIncludeAllPublicMethods(true); +$commandFactory->commandProcessor()->setFormatterManager(new FormatterManager()); +$commandList = $commandFactory->createCommandsFromClass($myCommandClassInstance); +foreach ($commandList as $command) { + $application->add($command); +} +``` +You may have more than one command class, if you wish. If so, simply call AnnotatedCommandFactory::createCommandsFromClass() multiple times. + +If you do not wish every public method in your classes to be added as commands, use `AnnotatedCommandFactory::setIncludeAllPublicMethods(false)`, and only methods annotated with @command will become commands. + +Note that the `setFormatterManager()` operation is optional; omit this if not using [Consolidation/OutputFormatters](https://github.com/consolidation/output-formatters). + +A CommandInfoAltererInterface can be added via AnnotatedCommandFactory::addCommandInfoAlterer(); it will be given the opportunity to adjust every CommandInfo object parsed from a command file prior to the creation of commands. + +### Command File Discovery + +A discovery class, CommandFileDiscovery, is also provided to help find command files on the filesystem. Usage is as follows: +```php +$discovery = new CommandFileDiscovery(); +$myCommandFiles = $discovery->discover($path, '\Drupal'); +foreach ($myCommandFiles as $myCommandClass) { + $myCommandClassInstance = new $myCommandClass(); + // ... as above +} +``` +For a discussion on command file naming conventions and search locations, see https://github.com/consolidation/annotated-command/issues/12. + +If different namespaces are used at different command file paths, change the call to discover as follows: +```php +$myCommandFiles = $discovery->discover(['\Ns1' => $path1, '\Ns2' => $path2]); +``` +As a shortcut for the above, the method `discoverNamespaced()` will take the last directory name of each path, and append it to the base namespace provided. This matches the conventions used by Drupal modules, for example. + +### Configuring Output Formatts (e.g. to enable wordwrap) + +The Output Formatters project supports automatic formatting of tabular output. In order for wordwrapping to work correctly, the terminal width must be passed in to the Output Formatters handlers via `FormatterOptions::setWidth()`. + +In the Annotated Commands project, this is done via dependency injection. If a `PrepareFormatter` object is passed to `CommandProcessor::addPrepareFormatter()`, then it will be given an opportunity to set properties on the `FormatterOptions` when it is created. + +A `PrepareTerminalWidthOption` class is provided to use the Symfony Application class to fetch the terminal width, and provide it to the FormatterOptions. It is injected as follows: +```php +$terminalWidthOption = new PrepareTerminalWidthOption(); +$terminalWidthOption->setApplication($application); +$commandFactory->commandProcessor()->addPrepareFormatter($terminalWidthOption); +``` +To provide greater control over the width used, create your own `PrepareTerminalWidthOption` subclass, and adjust the width as needed. + +## Other Callbacks + +In addition to the hooks provided by the hook manager, there are additional callbacks available to alter the way the annotated command library operates. + +### Factory Listeners + +Factory listeners are notified every time a command file instance is used to create annotated commands. +``` +public function AnnotatedCommandFactory::addListener(CommandCreationListenerInterface $listener); +``` +Listeners can be used to construct command file instances as they are provided to the command factory. + +### Option Providers + +An option provider is given an opportunity to add options to a command as it is being constructed. +``` +public function AnnotatedCommandFactory::addAutomaticOptionProvider(AutomaticOptionsProviderInterface $listener); +``` +The complete CommandInfo record with all of the annotation data is available, so you can, for example, add an option `--foo` to every command whose method is annotated `@fooable`. + +### CommandInfo Alterers + +CommandInfo alterers can adjust information about a command immediately before it is created. Typically, these will be used to supply default values for annotations custom to the command, or take other actions based on the interfaces implemented by the commandfile instance. +``` +public function alterCommandInfo(CommandInfo $commandInfo, $commandFileInstance); +``` + +## Comparison to Existing Solutions + +The existing solutions used their own hand-rolled regex-based parsers to process the contents of the DocBlock comments. consolidation/annotated-command uses the [phpdocumentor/reflection-docblock](https://github.com/phpDocumentor/ReflectionDocBlock) project (which is itself a regex-based parser) to interpret DocBlock contents. diff --git a/src/composer/vendor/consolidation/annotated-command/composer.json b/src/composer/vendor/consolidation/annotated-command/composer.json new file mode 100644 index 00000000..9132e750 --- /dev/null +++ b/src/composer/vendor/consolidation/annotated-command/composer.json @@ -0,0 +1,49 @@ +{ + "name": "consolidation/annotated-command", + "description": "Initialize Symfony Console commands from annotated command class methods.", + "license": "MIT", + "authors": [ + { + "name": "Greg Anderson", + "email": "greg.1.anderson@greenknowe.org" + } + ], + "autoload":{ + "psr-4":{ + "Consolidation\\AnnotatedCommand\\": "src" + } + }, + "autoload-dev": { + "psr-4": { + "Consolidation\\TestUtils\\": "tests/src" + } + }, + "require": { + "php": ">=5.4.0", + "consolidation/output-formatters": "^3.1.3", + "psr/log": "~1", + "symfony/console": "^2.8|~3", + "symfony/event-dispatcher": "^2.5|~3", + "symfony/finder": "^2.5|~3", + "phpdocumentor/reflection-docblock": "^2.0|^3.0.2" + }, + "require-dev": { + "phpunit/phpunit": "4.*", + "satooshi/php-coveralls": "^1.0", + "squizlabs/php_codesniffer": "^2.7" + }, + "scripts": { + "cs": "phpcs --standard=PSR2 -n src", + "cbf": "phpcbf --standard=PSR2 -n src", + "unit": "SHELL_INTERACTIVE=true phpunit --colors=always", + "test": [ + "@unit", + "@cs" + ] + }, + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } + } +} diff --git a/src/composer/vendor/consolidation/annotated-command/composer.lock b/src/composer/vendor/consolidation/annotated-command/composer.lock new file mode 100644 index 00000000..fc3a9760 --- /dev/null +++ b/src/composer/vendor/consolidation/annotated-command/composer.lock @@ -0,0 +1,1932 @@ +{ + "_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": "3022aec17694795060ac3d71280fbc23", + "content-hash": "3053742fe70568ac2d3264b50fad5a41", + "packages": [ + { + "name": "consolidation/output-formatters", + "version": "3.1.3", + "source": { + "type": "git", + "url": "https://github.com/consolidation/output-formatters.git", + "reference": "1e6c6ab49904a31c310940ec4efccf5f36e386e4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/consolidation/output-formatters/zipball/1e6c6ab49904a31c310940ec4efccf5f36e386e4", + "reference": "1e6c6ab49904a31c310940ec4efccf5f36e386e4", + "shasum": "" + }, + "require": { + "php": ">=5.4.0", + "symfony/console": "~2.5|~3.0", + "symfony/finder": "~2.5|~3.0", + "victorjonsson/markdowndocs": "^1.3" + }, + "require-dev": { + "phpunit/phpunit": "4.*", + "satooshi/php-coveralls": "^1.0", + "squizlabs/php_codesniffer": "2.*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Consolidation\\OutputFormatters\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Greg Anderson", + "email": "greg.1.anderson@greenknowe.org" + } + ], + "description": "Format text by applying transformations provided by plug-in formatters.", + "time": "2016-11-18 23:04:31" + }, + { + "name": "phpdocumentor/reflection-common", + "version": "1.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/144c307535e82c8fdcaacbcfc1d6d8eeb896687c", + "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "phpunit/phpunit": "^4.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ], + "time": "2015-12-27 11:43:31" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "3.1.1", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "8331b5efe816ae05461b7ca1e721c01b46bafb3e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/8331b5efe816ae05461b7ca1e721c01b46bafb3e", + "reference": "8331b5efe816ae05461b7ca1e721c01b46bafb3e", + "shasum": "" + }, + "require": { + "php": ">=5.5", + "phpdocumentor/reflection-common": "^1.0@dev", + "phpdocumentor/type-resolver": "^0.2.0", + "webmozart/assert": "^1.0" + }, + "require-dev": { + "mockery/mockery": "^0.9.4", + "phpunit/phpunit": "^4.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "time": "2016-09-30 07:12:33" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "0.2", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "b39c7a5b194f9ed7bd0dd345c751007a41862443" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/b39c7a5b194f9ed7bd0dd345c751007a41862443", + "reference": "b39c7a5b194f9ed7bd0dd345c751007a41862443", + "shasum": "" + }, + "require": { + "php": ">=5.5", + "phpdocumentor/reflection-common": "^1.0" + }, + "require-dev": { + "mockery/mockery": "^0.9.4", + "phpunit/phpunit": "^5.2||^4.8.24" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "time": "2016-06-10 07:14:17" + }, + { + "name": "psr/log", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", + "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "time": "2016-10-10 12:19:37" + }, + { + "name": "symfony/console", + "version": "v3.1.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "c99da1119ae61e15de0e4829196b9fba6f73d065" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/c99da1119ae61e15de0e4829196b9fba6f73d065", + "reference": "c99da1119ae61e15de0e4829196b9fba6f73d065", + "shasum": "" + }, + "require": { + "php": ">=5.5.9", + "symfony/debug": "~2.8|~3.0", + "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.1-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-10-06 01:44:51" + }, + { + "name": "symfony/debug", + "version": "v3.1.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/debug.git", + "reference": "e2b3f74a67fc928adc3c1b9027f73e1bc01190a8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/debug/zipball/e2b3f74a67fc928adc3c1b9027f73e1bc01190a8", + "reference": "e2b3f74a67fc928adc3c1b9027f73e1bc01190a8", + "shasum": "" + }, + "require": { + "php": ">=5.5.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.8|~3.0", + "symfony/http-kernel": "~2.8|~3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Debug\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Debug Component", + "homepage": "https://symfony.com", + "time": "2016-09-06 11:02:40" + }, + { + "name": "symfony/event-dispatcher", + "version": "v3.1.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "28b0832b2553ffb80cabef6a7a812ff1e670c0bc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/28b0832b2553ffb80cabef6a7a812ff1e670c0bc", + "reference": "28b0832b2553ffb80cabef6a7a812ff1e670c0bc", + "shasum": "" + }, + "require": { + "php": ">=5.5.9" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "~2.8|~3.0", + "symfony/dependency-injection": "~2.8|~3.0", + "symfony/expression-language": "~2.8|~3.0", + "symfony/stopwatch": "~2.8|~3.0" + }, + "suggest": { + "symfony/dependency-injection": "", + "symfony/http-kernel": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony EventDispatcher Component", + "homepage": "https://symfony.com", + "time": "2016-10-13 06:28:43" + }, + { + "name": "symfony/finder", + "version": "v3.1.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "205b5ffbb518a98ba2ae60a52656c4a31ab00c6f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/205b5ffbb518a98ba2ae60a52656c4a31ab00c6f", + "reference": "205b5ffbb518a98ba2ae60a52656c4a31ab00c6f", + "shasum": "" + }, + "require": { + "php": ">=5.5.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-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-09-28 00:11:12" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.3.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" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3-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-11-14 01:06:16" + }, + { + "name": "victorjonsson/markdowndocs", + "version": "1.3.7", + "source": { + "type": "git", + "url": "https://github.com/victorjonsson/PHP-Markdown-Documentation-Generator.git", + "reference": "a8244617cdce4804cd94ea508c82e8d7e29a273a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/victorjonsson/PHP-Markdown-Documentation-Generator/zipball/a8244617cdce4804cd94ea508c82e8d7e29a273a", + "reference": "a8244617cdce4804cd94ea508c82e8d7e29a273a", + "shasum": "" + }, + "require": { + "php": ">=5.5.0", + "symfony/console": ">=2.6" + }, + "require-dev": { + "phpunit/phpunit": "3.7.23" + }, + "bin": [ + "bin/phpdoc-md" + ], + "type": "library", + "autoload": { + "psr-0": { + "PHPDocsMD": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Victor Jonsson", + "email": "kontakt@victorjonsson.se" + } + ], + "description": "Command line tool for generating markdown-formatted class documentation", + "homepage": "https://github.com/victorjonsson/PHP-Markdown-Documentation-Generator", + "time": "2016-10-11 21:10:19" + }, + { + "name": "webmozart/assert", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/webmozart/assert.git", + "reference": "bb2d123231c095735130cc8f6d31385a44c7b308" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozart/assert/zipball/bb2d123231c095735130cc8f6d31385a44c7b308", + "reference": "bb2d123231c095735130cc8f6d31385a44c7b308", + "shasum": "" + }, + "require": { + "php": "^5.3.3|^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.6", + "sebastian/version": "^1.0.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "time": "2016-08-09 15:02:57" + } + ], + "packages-dev": [ + { + "name": "doctrine/instantiator", + "version": "1.0.5", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d", + "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d", + "shasum": "" + }, + "require": { + "php": ">=5.3,<8.0-DEV" + }, + "require-dev": { + "athletic/athletic": "~0.1.8", + "ext-pdo": "*", + "ext-phar": "*", + "phpunit/phpunit": "~4.0", + "squizlabs/php_codesniffer": "~2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "http://ocramius.github.com/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://github.com/doctrine/instantiator", + "keywords": [ + "constructor", + "instantiate" + ], + "time": "2015-06-14 21:17:01" + }, + { + "name": "guzzle/guzzle", + "version": "v3.8.1", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "4de0618a01b34aa1c8c33a3f13f396dcd3882eba" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/4de0618a01b34aa1c8c33a3f13f396dcd3882eba", + "reference": "4de0618a01b34aa1c8c33a3f13f396dcd3882eba", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "php": ">=5.3.3", + "symfony/event-dispatcher": ">=2.1" + }, + "replace": { + "guzzle/batch": "self.version", + "guzzle/cache": "self.version", + "guzzle/common": "self.version", + "guzzle/http": "self.version", + "guzzle/inflection": "self.version", + "guzzle/iterator": "self.version", + "guzzle/log": "self.version", + "guzzle/parser": "self.version", + "guzzle/plugin": "self.version", + "guzzle/plugin-async": "self.version", + "guzzle/plugin-backoff": "self.version", + "guzzle/plugin-cache": "self.version", + "guzzle/plugin-cookie": "self.version", + "guzzle/plugin-curlauth": "self.version", + "guzzle/plugin-error-response": "self.version", + "guzzle/plugin-history": "self.version", + "guzzle/plugin-log": "self.version", + "guzzle/plugin-md5": "self.version", + "guzzle/plugin-mock": "self.version", + "guzzle/plugin-oauth": "self.version", + "guzzle/service": "self.version", + "guzzle/stream": "self.version" + }, + "require-dev": { + "doctrine/cache": "*", + "monolog/monolog": "1.*", + "phpunit/phpunit": "3.7.*", + "psr/log": "1.0.*", + "symfony/class-loader": "*", + "zendframework/zend-cache": "<2.3", + "zendframework/zend-log": "<2.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.8-dev" + } + }, + "autoload": { + "psr-0": { + "Guzzle": "src/", + "Guzzle\\Tests": "tests/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Guzzle Community", + "homepage": "https://github.com/guzzle/guzzle/contributors" + } + ], + "description": "Guzzle is a PHP HTTP client library and framework for building RESTful web service clients", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "rest", + "web service" + ], + "abandoned": "guzzlehttp/guzzle", + "time": "2014-01-28 22:29:15" + }, + { + "name": "phpspec/prophecy", + "version": "v1.6.1", + "source": { + "type": "git", + "url": "https://github.com/phpspec/prophecy.git", + "reference": "58a8137754bc24b25740d4281399a4a3596058e0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/58a8137754bc24b25740d4281399a4a3596058e0", + "reference": "58a8137754bc24b25740d4281399a4a3596058e0", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.2", + "php": "^5.3|^7.0", + "phpdocumentor/reflection-docblock": "^2.0|^3.0.2", + "sebastian/comparator": "^1.1", + "sebastian/recursion-context": "^1.0" + }, + "require-dev": { + "phpspec/phpspec": "^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.6.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-06-07 08:13:47" + }, + { + "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.9", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-token-stream.git", + "reference": "3b402f65a4cc90abf6e1104e388b896ce209631b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3b402f65a4cc90abf6e1104e388b896ce209631b", + "reference": "3b402f65a4cc90abf6e1104e388b896ce209631b", + "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": "2016-11-15 14:06:22" + }, + { + "name": "phpunit/phpunit", + "version": "4.8.28", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "558a3a0d28b4cb7e4a593a4fbd2220e787076225" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/558a3a0d28b4cb7e4a593a4fbd2220e787076225", + "reference": "558a3a0d28b4cb7e4a593a4fbd2220e787076225", + "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-11-14 06:25: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": "satooshi/php-coveralls", + "version": "v1.0.1", + "source": { + "type": "git", + "url": "https://github.com/satooshi/php-coveralls.git", + "reference": "da51d304fe8622bf9a6da39a8446e7afd432115c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/satooshi/php-coveralls/zipball/da51d304fe8622bf9a6da39a8446e7afd432115c", + "reference": "da51d304fe8622bf9a6da39a8446e7afd432115c", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-simplexml": "*", + "guzzle/guzzle": "^2.8|^3.0", + "php": ">=5.3.3", + "psr/log": "^1.0", + "symfony/config": "^2.1|^3.0", + "symfony/console": "^2.1|^3.0", + "symfony/stopwatch": "^2.0|^3.0", + "symfony/yaml": "^2.0|^3.0" + }, + "suggest": { + "symfony/http-kernel": "Allows Symfony integration" + }, + "bin": [ + "bin/coveralls" + ], + "type": "library", + "autoload": { + "psr-4": { + "Satooshi\\": "src/Satooshi/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kitamura Satoshi", + "email": "with.no.parachute@gmail.com", + "homepage": "https://www.facebook.com/satooshi.jp" + } + ], + "description": "PHP client library for Coveralls API", + "homepage": "https://github.com/satooshi/php-coveralls", + "keywords": [ + "ci", + "coverage", + "github", + "test" + ], + "time": "2016-01-20 17:35:46" + }, + { + "name": "sebastian/comparator", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "ce2bda23a56456f19e35d98241446b581f648c14" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/ce2bda23a56456f19e35d98241446b581f648c14", + "reference": "ce2bda23a56456f19e35d98241446b581f648c14", + "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": "2016-11-17 14:39:37" + }, + { + "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.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/be2c607e43ce4c89ecd60e75c6a85c126e754aea", + "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8 || ^5.0" + }, + "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-08-18 05:49:44" + }, + { + "name": "sebastian/exporter", + "version": "1.2.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/42c4c2eec485ee3e159ec9884f95b431287edde4", + "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "sebastian/recursion-context": "~1.0" + }, + "require-dev": { + "ext-mbstring": "*", + "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": "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": "2016-06-17 09:04:28" + }, + { + "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.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "938df7a6478e72795e5f8266cff24d06e3136f2e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/938df7a6478e72795e5f8266cff24d06e3136f2e", + "reference": "938df7a6478e72795e5f8266cff24d06e3136f2e", + "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": "2016-11-15 06:55:36" + }, + { + "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": "squizlabs/php_codesniffer", + "version": "2.7.0", + "source": { + "type": "git", + "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", + "reference": "571e27b6348e5b3a637b2abc82ac0d01e6d7bbed" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/571e27b6348e5b3a637b2abc82ac0d01e6d7bbed", + "reference": "571e27b6348e5b3a637b2abc82ac0d01e6d7bbed", + "shasum": "" + }, + "require": { + "ext-simplexml": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": ">=5.1.2" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "bin": [ + "scripts/phpcs", + "scripts/phpcbf" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "autoload": { + "classmap": [ + "CodeSniffer.php", + "CodeSniffer/CLI.php", + "CodeSniffer/Exception.php", + "CodeSniffer/File.php", + "CodeSniffer/Fixer.php", + "CodeSniffer/Report.php", + "CodeSniffer/Reporting.php", + "CodeSniffer/Sniff.php", + "CodeSniffer/Tokens.php", + "CodeSniffer/Reports/", + "CodeSniffer/Tokenizers/", + "CodeSniffer/DocGenerators/", + "CodeSniffer/Standards/AbstractPatternSniff.php", + "CodeSniffer/Standards/AbstractScopeSniff.php", + "CodeSniffer/Standards/AbstractVariableSniff.php", + "CodeSniffer/Standards/IncorrectPatternException.php", + "CodeSniffer/Standards/Generic/Sniffs/", + "CodeSniffer/Standards/MySource/Sniffs/", + "CodeSniffer/Standards/PEAR/Sniffs/", + "CodeSniffer/Standards/PSR1/Sniffs/", + "CodeSniffer/Standards/PSR2/Sniffs/", + "CodeSniffer/Standards/Squiz/Sniffs/", + "CodeSniffer/Standards/Zend/Sniffs/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Greg Sherwood", + "role": "lead" + } + ], + "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", + "homepage": "http://www.squizlabs.com/php-codesniffer", + "keywords": [ + "phpcs", + "standards" + ], + "time": "2016-09-01 23:53:02" + }, + { + "name": "symfony/config", + "version": "v3.1.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/config.git", + "reference": "949e7e846743a7f9e46dc50eb639d5fde1f53341" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/config/zipball/949e7e846743a7f9e46dc50eb639d5fde1f53341", + "reference": "949e7e846743a7f9e46dc50eb639d5fde1f53341", + "shasum": "" + }, + "require": { + "php": ">=5.5.9", + "symfony/filesystem": "~2.8|~3.0" + }, + "suggest": { + "symfony/yaml": "To use the yaml reference dumper" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Config\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Config Component", + "homepage": "https://symfony.com", + "time": "2016-09-25 08:27:07" + }, + { + "name": "symfony/filesystem", + "version": "v3.1.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "0565b61bf098cb4dc09f4f103f033138ae4f42c6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/0565b61bf098cb4dc09f4f103f033138ae4f42c6", + "reference": "0565b61bf098cb4dc09f4f103f033138ae4f42c6", + "shasum": "" + }, + "require": { + "php": ">=5.5.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-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-10-18 04:30:12" + }, + { + "name": "symfony/stopwatch", + "version": "v3.1.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/stopwatch.git", + "reference": "bb42806b12c5f89db4ebf64af6741afe6d8457e1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/bb42806b12c5f89db4ebf64af6741afe6d8457e1", + "reference": "bb42806b12c5f89db4ebf64af6741afe6d8457e1", + "shasum": "" + }, + "require": { + "php": ">=5.5.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Stopwatch\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Stopwatch Component", + "homepage": "https://symfony.com", + "time": "2016-06-29 05:41:56" + }, + { + "name": "symfony/yaml", + "version": "v3.1.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "7ff51b06c6c3d5cc6686df69004a42c69df09e27" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/7ff51b06c6c3d5cc6686df69004a42c69df09e27", + "reference": "7ff51b06c6c3d5cc6686df69004a42c69df09e27", + "shasum": "" + }, + "require": { + "php": ">=5.5.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-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-10-24 18:41:13" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": ">=5.4.0" + }, + "platform-dev": [] +} diff --git a/src/composer/vendor/consolidation/annotated-command/phpunit.xml.dist b/src/composer/vendor/consolidation/annotated-command/phpunit.xml.dist new file mode 100644 index 00000000..a35a5042 --- /dev/null +++ b/src/composer/vendor/consolidation/annotated-command/phpunit.xml.dist @@ -0,0 +1,19 @@ + + + + tests + + + + + + + + + src + + + diff --git a/src/composer/vendor/consolidation/annotated-command/src/AnnotatedCommand.php b/src/composer/vendor/consolidation/annotated-command/src/AnnotatedCommand.php new file mode 100644 index 00000000..8db1e73e --- /dev/null +++ b/src/composer/vendor/consolidation/annotated-command/src/AnnotatedCommand.php @@ -0,0 +1,346 @@ +getName(); + } + } + parent::__construct($name); + if ($commandInfo && $commandInfo->hasAnnotation('command')) { + $this->setCommandInfo($commandInfo); + $this->setCommandOptions($commandInfo); + } + } + + public function setCommandCallback($commandCallback) + { + $this->commandCallback = $commandCallback; + return $this; + } + + public function setCommandProcessor($commandProcessor) + { + $this->commandProcessor = $commandProcessor; + return $this; + } + + public function commandProcessor() + { + // If someone is using an AnnotatedCommand, and is NOT getting + // it from an AnnotatedCommandFactory OR not correctly injecting + // a command processor via setCommandProcessor() (ideally via the + // DI container), then we'll just give each annotated command its + // own command processor. This is not ideal; preferably, there would + // only be one instance of the command processor in the application. + if (!isset($this->commandProcessor)) { + $this->commandProcessor = new CommandProcessor(new HookManager()); + } + return $this->commandProcessor; + } + + public function getReturnType() + { + return $this->returnType; + } + + public function setReturnType($returnType) + { + $this->returnType = $returnType; + return $this; + } + + public function getAnnotationData() + { + return $this->annotationData; + } + + public function setAnnotationData($annotationData) + { + $this->annotationData = $annotationData; + return $this; + } + + public function setCommandInfo($commandInfo) + { + $this->setDescription($commandInfo->getDescription()); + $this->setHelp($commandInfo->getHelp()); + $this->setAliases($commandInfo->getAliases()); + $this->setAnnotationData($commandInfo->getAnnotations()); + foreach ($commandInfo->getExampleUsages() as $usage => $description) { + // Symfony Console does not support attaching a description to a usage + $this->addUsage($usage); + } + $this->setCommandArguments($commandInfo); + $this->setReturnType($commandInfo->getReturnType()); + return $this; + } + + protected function setCommandArguments($commandInfo) + { + $this->setUsesInputInterface($commandInfo); + $this->setUsesOutputInterface($commandInfo); + $this->setCommandArgumentsFromParameters($commandInfo); + return $this; + } + + /** + * Check whether the first parameter is an InputInterface. + */ + protected function checkUsesInputInterface($params) + { + $firstParam = reset($params); + return $firstParam instanceof InputInterface; + } + + /** + * Determine whether this command wants to get its inputs + * via an InputInterface or via its command parameters + */ + protected function setUsesInputInterface($commandInfo) + { + $params = $commandInfo->getParameters(); + $this->usesInputInterface = $this->checkUsesInputInterface($params); + return $this; + } + + /** + * Determine whether this command wants to send its output directly + * to the provided OutputInterface, or whether it will returned + * structured output to be processed by the command processor. + */ + protected function setUsesOutputInterface($commandInfo) + { + $params = $commandInfo->getParameters(); + $index = $this->checkUsesInputInterface($params) ? 1 : 0; + $this->usesOutputInterface = + (count($params) > $index) && + ($params[$index] instanceof OutputInterface); + return $this; + } + + protected function setCommandArgumentsFromParameters($commandInfo) + { + $args = $commandInfo->arguments()->getValues(); + foreach ($args as $name => $defaultValue) { + $description = $commandInfo->arguments()->getDescription($name); + $hasDefault = $commandInfo->arguments()->hasDefault($name); + $parameterMode = $this->getCommandArgumentMode($hasDefault, $defaultValue); + $this->addArgument($name, $parameterMode, $description, $defaultValue); + } + return $this; + } + + protected function getCommandArgumentMode($hasDefault, $defaultValue) + { + if (!$hasDefault) { + return InputArgument::REQUIRED; + } + if (is_array($defaultValue)) { + return InputArgument::IS_ARRAY; + } + return InputArgument::OPTIONAL; + } + + public function setCommandOptions($commandInfo, $automaticOptions = []) + { + $inputOptions = $commandInfo->inputOptions(); + + $this->addOptions($inputOptions + $automaticOptions, $automaticOptions); + return $this; + } + + public function addOptions($inputOptions, $automaticOptions = []) + { + foreach ($inputOptions as $name => $inputOption) { + $description = $inputOption->getDescription(); + + if (empty($description) && isset($automaticOptions[$name])) { + $description = $automaticOptions[$name]->getDescription(); + $inputOption = static::inputOptionSetDescription($inputOption, $description); + } + $this->getDefinition()->addOption($inputOption); + } + } + + protected static function inputOptionSetDescription($inputOption, $description) + { + // Recover the 'mode' value, because Symfony is stubborn + $mode = 0; + if ($inputOption->isValueRequired()) { + $mode |= InputOption::VALUE_REQUIRED; + } + if ($inputOption->isValueOptional()) { + $mode |= InputOption::VALUE_OPTIONAL; + } + if ($inputOption->isArray()) { + $mode |= InputOption::VALUE_IS_ARRAY; + } + if (!$mode) { + $mode = InputOption::VALUE_NONE; + } + + $inputOption = new InputOption( + $inputOption->getName(), + $inputOption->getShortcut(), + $mode, + $description, + $inputOption->getDefault() + ); + return $inputOption; + } + + /** + * Returns all of the hook names that may be called for this command. + * + * @return array + */ + public function getNames() + { + return HookManager::getNames($this, $this->commandCallback); + } + + /** + * Add any options to this command that are defined by hook implementations + */ + public function optionsHook() + { + $this->commandProcessor()->optionsHook( + $this, + $this->getNames(), + $this->annotationData + ); + } + + public function optionsHookForHookAnnotations($commandInfoList) + { + foreach ($commandInfoList as $commandInfo) { + $inputOptions = $commandInfo->inputOptions(); + $this->addOptions($inputOptions); + foreach ($commandInfo->getExampleUsages() as $usage => $description) { + if (!in_array($usage, $this->getUsages())) { + $this->addUsage($usage); + } + } + } + } + + /** + * {@inheritdoc} + */ + protected function interact(InputInterface $input, OutputInterface $output) + { + $this->commandProcessor()->interact( + $input, + $output, + $this->getNames(), + $this->annotationData + ); + } + + protected function initialize(InputInterface $input, OutputInterface $output) + { + // Allow the hook manager a chance to provide configuration values, + // if there are any registered hooks to do that. + $this->commandProcessor()->initializeHook($input, $this->getNames(), $this->annotationData); + } + + /** + * {@inheritdoc} + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + // Validate, run, process, alter, handle results. + return $this->commandProcessor()->process( + $output, + $this->getNames(), + $this->commandCallback, + $this->createCommandData($input, $output) + ); + } + + /** + * This function is available for use by a class that may + * wish to extend this class rather than use annotations to + * define commands. Using this technique does allow for the + * use of annotations to define hooks. + */ + public function processResults(InputInterface $input, OutputInterface $output, $results) + { + $commandData = $this->createCommandData($input, $output); + $commandProcessor = $this->commandProcessor(); + $names = $this->getNames(); + $results = $commandProcessor->processResults( + $names, + $results, + $commandData + ); + return $commandProcessor->handleResults( + $output, + $names, + $results, + $commandData + ); + } + + protected function createCommandData(InputInterface $input, OutputInterface $output) + { + $commandData = new CommandData( + $this->annotationData, + $input, + $output + ); + + $commandData->setUseIOInterfaces( + $this->usesOutputInterface, + $this->usesInputInterface + ); + + return $commandData; + } +} diff --git a/src/composer/vendor/consolidation/annotated-command/src/AnnotatedCommandFactory.php b/src/composer/vendor/consolidation/annotated-command/src/AnnotatedCommandFactory.php new file mode 100644 index 00000000..5765167f --- /dev/null +++ b/src/composer/vendor/consolidation/annotated-command/src/AnnotatedCommandFactory.php @@ -0,0 +1,327 @@ +commandProcessor = new CommandProcessor(new HookManager()); + $this->addAutomaticOptionProvider($this); + } + + public function setCommandProcessor(CommandProcessor $commandProcessor) + { + $this->commandProcessor = $commandProcessor; + return $this; + } + + /** + * @return CommandProcessor + */ + public function commandProcessor() + { + return $this->commandProcessor; + } + + /** + * Set the 'include all public methods flag'. If true (the default), then + * every public method of each commandFile will be used to create commands. + * If it is false, then only those public methods annotated with @command + * or @name (deprecated) will be used to create commands. + */ + public function setIncludeAllPublicMethods($includeAllPublicMethods) + { + $this->includeAllPublicMethods = $includeAllPublicMethods; + return $this; + } + + public function getIncludeAllPublicMethods() + { + return $this->includeAllPublicMethods; + } + + /** + * @return HookManager + */ + public function hookManager() + { + return $this->commandProcessor()->hookManager(); + } + + /** + * Add a listener that is notified immediately before the command + * factory creates commands from a commandFile instance. This + * listener can use this opportunity to do more setup for the commandFile, + * and so on. + * + * @param CommandCreationListenerInterface $listener + */ + public function addListener(CommandCreationListenerInterface $listener) + { + $this->listeners[] = $listener; + } + + /** + * Call all command creation listeners + * + * @param object $commandFileInstance + */ + protected function notify($commandFileInstance) + { + foreach ($this->listeners as $listener) { + $listener->notifyCommandFileAdded($commandFileInstance); + } + } + + public function addAutomaticOptionProvider(AutomaticOptionsProviderInterface $optionsProvider) + { + $this->automaticOptionsProviderList[] = $optionsProvider; + } + + public function addCommandInfoAlterer(CommandInfoAltererInterface $alterer) + { + $this->commandInfoAlterers[] = $alterer; + } + + /** + * n.b. This registers all hooks from the commandfile instance as a side-effect. + */ + public function createCommandsFromClass($commandFileInstance, $includeAllPublicMethods = null) + { + // Deprecated: avoid using the $includeAllPublicMethods in favor of the setIncludeAllPublicMethods() accessor. + if (!isset($includeAllPublicMethods)) { + $includeAllPublicMethods = $this->getIncludeAllPublicMethods(); + } + $this->notify($commandFileInstance); + $commandInfoList = $this->getCommandInfoListFromClass($commandFileInstance); + $this->registerCommandHooksFromClassInfo($commandInfoList, $commandFileInstance); + return $this->createCommandsFromClassInfo($commandInfoList, $commandFileInstance, $includeAllPublicMethods); + } + + public function getCommandInfoListFromClass($classNameOrInstance) + { + $commandInfoList = []; + + // Ignore special functions, such as __construct and __call, which + // can never be commands. + $commandMethodNames = array_filter( + get_class_methods($classNameOrInstance) ?: [], + function ($m) { + return !preg_match('#^_#', $m); + } + ); + + foreach ($commandMethodNames as $commandMethodName) { + $commandInfoList[] = new CommandInfo($classNameOrInstance, $commandMethodName); + } + + return $commandInfoList; + } + + public function createCommandInfo($classNameOrInstance, $commandMethodName) + { + return new CommandInfo($classNameOrInstance, $commandMethodName); + } + + public function createCommandsFromClassInfo($commandInfoList, $commandFileInstance, $includeAllPublicMethods = null) + { + // Deprecated: avoid using the $includeAllPublicMethods in favor of the setIncludeAllPublicMethods() accessor. + if (!isset($includeAllPublicMethods)) { + $includeAllPublicMethods = $this->getIncludeAllPublicMethods(); + } + return $this->createSelectedCommandsFromClassInfo( + $commandInfoList, + $commandFileInstance, + function ($commandInfo) use ($includeAllPublicMethods) { + return static::isCommandMethod($commandInfo, $includeAllPublicMethods); + } + ); + } + + public function createSelectedCommandsFromClassInfo($commandInfoList, $commandFileInstance, callable $commandSelector) + { + $commandList = []; + + foreach ($commandInfoList as $commandInfo) { + if ($commandSelector($commandInfo)) { + $command = $this->createCommand($commandInfo, $commandFileInstance); + $commandList[] = $command; + } + } + + return $commandList; + } + + public static function isCommandMethod($commandInfo, $includeAllPublicMethods) + { + // Ignore everything labeled @hook + if ($commandInfo->hasAnnotation('hook')) { + return false; + } + // Include everything labeled @command + if ($commandInfo->hasAnnotation('command')) { + return true; + } + // Skip anything named like an accessor ('get' or 'set') + if (preg_match('#^(get[A-Z]|set[A-Z])#', $commandInfo->getMethodName())) { + return false; + } + + // Default to the setting of 'include all public methods'. + return $includeAllPublicMethods; + } + + public function registerCommandHooksFromClassInfo($commandInfoList, $commandFileInstance) + { + foreach ($commandInfoList as $commandInfo) { + if ($commandInfo->hasAnnotation('hook')) { + $this->registerCommandHook($commandInfo, $commandFileInstance); + } + } + } + + /** + * Register a command hook given the CommandInfo for a method. + * + * The hook format is: + * + * @hook type name type + * + * For example, the pre-validate hook for the core:init command is: + * + * @hook pre-validate core:init + * + * If no command name is provided, then this hook will affect every + * command that is defined in the same file. + * + * If no hook is provided, then we will presume that ALTER_RESULT + * is intended. + * + * @param CommandInfo $commandInfo Information about the command hook method. + * @param object $commandFileInstance An instance of the CommandFile class. + */ + public function registerCommandHook(CommandInfo $commandInfo, $commandFileInstance) + { + // Ignore if the command info has no @hook + if (!$commandInfo->hasAnnotation('hook')) { + return; + } + $hookData = $commandInfo->getAnnotation('hook'); + $hook = $this->getNthWord($hookData, 0, HookManager::ALTER_RESULT); + $commandName = $this->getNthWord($hookData, 1); + + // Register the hook + $callback = [$commandFileInstance, $commandInfo->getMethodName()]; + $this->commandProcessor()->hookManager()->add($callback, $hook, $commandName); + + // If the hook has options, then also register the commandInfo + // with the hook manager, so that we can add options and such to + // the commands they hook. + if (!$commandInfo->options()->isEmpty()) { + $this->commandProcessor()->hookManager()->recordHookOptions($commandInfo, $commandName); + } + } + + protected function getNthWord($string, $n, $default = '', $delimiter = ' ') + { + $words = explode($delimiter, $string); + if (!empty($words[$n])) { + return $words[$n]; + } + return $default; + } + + public function createCommand(CommandInfo $commandInfo, $commandFileInstance) + { + $this->alterCommandInfo($commandInfo, $commandFileInstance); + $command = new AnnotatedCommand($commandInfo->getName()); + $commandCallback = [$commandFileInstance, $commandInfo->getMethodName()]; + $command->setCommandCallback($commandCallback); + $command->setCommandProcessor($this->commandProcessor); + $command->setCommandInfo($commandInfo); + $automaticOptions = $this->callAutomaticOptionsProviders($commandInfo); + $command->setCommandOptions($commandInfo, $automaticOptions); + // Annotation commands are never bootstrap-aware, but for completeness + // we will notify on every created command, as some clients may wish to + // use this notification for some other purpose. + $this->notify($command); + return $command; + } + + /** + * Give plugins an opportunity to update the commandInfo + */ + public function alterCommandInfo(CommandInfo $commandInfo, $commandFileInstance) + { + foreach ($this->commandInfoAlterers as $alterer) { + $alterer->alterCommandInfo($commandInfo, $commandFileInstance); + } + } + + /** + * Get the options that are implied by annotations, e.g. @fields implies + * that there should be a --fields and a --format option. + * + * @return InputOption[] + */ + public function callAutomaticOptionsProviders(CommandInfo $commandInfo) + { + $automaticOptions = []; + foreach ($this->automaticOptionsProviderList as $automaticOptionsProvider) { + $automaticOptions += $automaticOptionsProvider->automaticOptions($commandInfo); + } + return $automaticOptions; + } + + /** + * Get the options that are implied by annotations, e.g. @fields implies + * that there should be a --fields and a --format option. + * + * @return InputOption[] + */ + public function automaticOptions(CommandInfo $commandInfo) + { + $automaticOptions = []; + $formatManager = $this->commandProcessor()->formatterManager(); + if ($formatManager) { + $annotationData = $commandInfo->getAnnotations()->getArrayCopy(); + $formatterOptions = new FormatterOptions($annotationData); + $dataType = $commandInfo->getReturnType(); + $automaticOptions = $formatManager->automaticOptions($formatterOptions, $dataType); + } + return $automaticOptions; + } +} diff --git a/src/composer/vendor/consolidation/annotated-command/src/AnnotationData.php b/src/composer/vendor/consolidation/annotated-command/src/AnnotationData.php new file mode 100644 index 00000000..c5728ecd --- /dev/null +++ b/src/composer/vendor/consolidation/annotated-command/src/AnnotationData.php @@ -0,0 +1,20 @@ +has($key) ? $this[$key] : $default; + } + + public function has($key) + { + return isset($this[$key]); + } + + public function keys() + { + return array_keys($this->getArrayCopy()); + } +} diff --git a/src/composer/vendor/consolidation/annotated-command/src/CommandCreationListenerInterface.php b/src/composer/vendor/consolidation/annotated-command/src/CommandCreationListenerInterface.php new file mode 100644 index 00000000..f3a50eae --- /dev/null +++ b/src/composer/vendor/consolidation/annotated-command/src/CommandCreationListenerInterface.php @@ -0,0 +1,15 @@ +annotationData = $annotationData; + $this->input = $input; + $this->output = $output; + $this->usesInputInterface = false; + $this->usesOutputInterface = false; + $this->includeOptionsInArgs = true; + } + + /** + * For internal use only; indicates that the function to be called + * should be passed an InputInterface &/or an OutputInterface. + * @param booean $usesInputInterface + * @param boolean $usesOutputInterface + * @return self + */ + public function setUseIOInterfaces($usesInputInterface, $usesOutputInterface) + { + $this->usesInputInterface = $usesInputInterface; + $this->usesOutputInterface = $usesOutputInterface; + return $this; + } + + /** + * For backwards-compatibility mode only: disable addition of + * options on the end of the arguments list. + */ + public function setIncludeOptionsInArgs($includeOptionsInArgs) + { + $this->includeOptionsInArgs = $includeOptionsInArgs; + return $this; + } + + public function annotationData() + { + return $this->annotationData; + } + + public function input() + { + return $this->input; + } + + public function output() + { + return $this->output; + } + + public function arguments() + { + return $this->input->getArguments(); + } + + public function options() + { + return $this->input->getOptions(); + } + + public function getArgsWithoutAppName() + { + $args = $this->arguments(); + + // When called via the Application, the first argument + // will be the command name. The Application alters the + // input definition to match, adding a 'command' argument + // to the beginning. + array_shift($args); + + if ($this->usesInputInterface) { + array_unshift($args, $this->input()); + } + + if ($this->usesOutputInterface) { + array_unshift($args, $this->output()); + } + + return $args; + } + + public function getArgsAndOptions() + { + // Get passthrough args, and add the options on the end. + $args = $this->getArgsWithoutAppName(); + if ($this->includeOptionsInArgs) { + $args['options'] = $this->options(); + } + return $args; + } +} diff --git a/src/composer/vendor/consolidation/annotated-command/src/CommandError.php b/src/composer/vendor/consolidation/annotated-command/src/CommandError.php new file mode 100644 index 00000000..bfe257bd --- /dev/null +++ b/src/composer/vendor/consolidation/annotated-command/src/CommandError.php @@ -0,0 +1,32 @@ +message = $message; + // Ensure the exit code is non-zero. The exit code may have + // come from an exception, and those often default to zero if + // a specific value is not provided. + $this->exitCode = $exitCode == 0 ? 1 : $exitCode; + } + public function getExitCode() + { + return $this->exitCode; + } + + public function getOutputData() + { + return $this->message; + } +} diff --git a/src/composer/vendor/consolidation/annotated-command/src/CommandFileDiscovery.php b/src/composer/vendor/consolidation/annotated-command/src/CommandFileDiscovery.php new file mode 100644 index 00000000..7c47528d --- /dev/null +++ b/src/composer/vendor/consolidation/annotated-command/src/CommandFileDiscovery.php @@ -0,0 +1,383 @@ +discoverNamespaced($moduleList, '\Drupal'); + * + * To discover global commands: + * + * $commandFiles = $discovery->discover($drupalRoot, '\Drupal'); + */ +class CommandFileDiscovery +{ + /** @var string[] */ + protected $excludeList; + /** @var string[] */ + protected $searchLocations; + /** @var string */ + protected $searchPattern = '*Commands.php'; + /** @var boolean */ + protected $includeFilesAtBase = true; + /** @var integer */ + protected $searchDepth = 2; + + public function __construct() + { + $this->excludeList = ['Exclude']; + $this->searchLocations = [ + 'Command', + 'CliTools', // TODO: Maybe remove + ]; + } + + /** + * Specify whether to search for files at the base directory + * ($directoryList parameter to discover and discoverNamespaced + * methods), or only in the directories listed in the search paths. + * + * @param boolean $includeFilesAtBase + */ + public function setIncludeFilesAtBase($includeFilesAtBase) + { + $this->includeFilesAtBase = $includeFilesAtBase; + return $this; + } + + /** + * Set the list of excludes to add to the finder, replacing + * whatever was there before. + * + * @param array $excludeList The list of directory names to skip when + * searching for command files. + */ + public function setExcludeList($excludeList) + { + $this->excludeList = $excludeList; + return $this; + } + + /** + * Add one more location to the exclude list. + * + * @param string $exclude One directory name to skip when searching + * for command files. + */ + public function addExclude($exclude) + { + $this->excludeList[] = $exclude; + return $this; + } + + /** + * Set the search depth. By default, fills immediately in the + * base directory are searched, plus all of the search locations + * to this specified depth. If the search locations is set to + * an empty array, then the base directory is searched to this + * depth. + */ + public function setSearchDepth($searchDepth) + { + $this->searchDepth = $searchDepth; + return $this; + } + + /** + * Set the list of search locations to examine in each directory where + * command files may be found. This replaces whatever was there before. + * + * @param array $searchLocations The list of locations to search for command files. + */ + public function setSearchLocations($searchLocations) + { + $this->searchLocations = $searchLocations; + return $this; + } + + /** + * Add one more location to the search location list. + * + * @param string $location One more relative path to search + * for command files. + */ + public function addSearchLocation($location) + { + $this->searchLocations[] = $location; + return $this; + } + + /** + * Specify the pattern / regex used by the finder to search for + * command files. + */ + public function setSearchPattern($searchPattern) + { + $this->searchPattern = $searchPattern; + return $this; + } + + /** + * Given a list of directories, e.g. Drupal modules like: + * + * core/modules/block + * core/modules/dblog + * modules/default_content + * + * Discover command files in any of these locations. + * + * @param string|string[] $directoryList Places to search for commands. + * + * @return array + */ + public function discoverNamespaced($directoryList, $baseNamespace = '') + { + return $this->discover($this->convertToNamespacedList((array)$directoryList), $baseNamespace); + } + + /** + * Given a simple list containing paths to directories, where + * the last component of the path should appear in the namespace, + * after the base namespace, this function will return an + * associative array mapping the path's basename (e.g. the module + * name) to the directory path. + * + * Module names must be unique. + * + * @param string[] $directoryList A list of module locations + * + * @return array + */ + public function convertToNamespacedList($directoryList) + { + $namespacedArray = []; + foreach ((array)$directoryList as $directory) { + $namespacedArray[basename($directory)] = $directory; + } + return $namespacedArray; + } + + /** + * Search for command files in the specified locations. This is the function that + * should be used for all locations that are NOT modules of a framework. + * + * @param string|string[] $directoryList Places to search for commands. + * @return array + */ + public function discover($directoryList, $baseNamespace = '') + { + $commandFiles = []; + foreach ((array)$directoryList as $key => $directory) { + $itemsNamespace = $this->joinNamespace([$baseNamespace, $key]); + $commandFiles = array_merge( + $commandFiles, + $this->discoverCommandFiles($directory, $itemsNamespace), + $this->discoverCommandFiles("$directory/src", $itemsNamespace) + ); + } + return $commandFiles; + } + + /** + * Search for command files in specific locations within a single directory. + * + * In each location, we will accept only a few places where command files + * can be found. This will reduce the need to search through many unrelated + * files. + * + * The default search locations include: + * + * . + * CliTools + * src/CliTools + * + * The pattern we will look for is any file whose name ends in 'Commands.php'. + * A list of paths to found files will be returned. + */ + protected function discoverCommandFiles($directory, $baseNamespace) + { + $commandFiles = []; + // In the search location itself, we will search for command files + // immediately inside the directory only. + if ($this->includeFilesAtBase) { + $commandFiles = $this->discoverCommandFilesInLocation( + $directory, + $this->getBaseDirectorySearchDepth(), + $baseNamespace + ); + } + + // In the other search locations, + foreach ($this->searchLocations as $location) { + $itemsNamespace = $this->joinNamespace([$baseNamespace, $location]); + $commandFiles = array_merge( + $commandFiles, + $this->discoverCommandFilesInLocation( + "$directory/$location", + $this->getSearchDepth(), + $itemsNamespace + ) + ); + } + return $commandFiles; + } + + /** + * Return a Finder search depth appropriate for our selected search depth. + * + * @return string + */ + protected function getSearchDepth() + { + return $this->searchDepth <= 0 ? '== 0' : '<= ' . $this->searchDepth; + } + + /** + * Return a Finder search depth for the base directory. If the + * searchLocations array has been populated, then we will only search + * for files immediately inside the base directory; no traversal into + * deeper directories will be done, as that would conflict with the + * specification provided by the search locations. If there is no + * search location, then we will search to whatever depth was specified + * by the client. + * + * @return string + */ + protected function getBaseDirectorySearchDepth() + { + if (!empty($this->searchLocations)) { + return '== 0'; + } + return $this->getSearchDepth(); + } + + /** + * Search for command files in just one particular location. Returns + * an associative array mapping from the pathname of the file to the + * classname that it contains. The pathname may be ignored if the search + * location is included in the autoloader. + * + * @param string $directory The location to search + * @param string $depth How deep to search (e.g. '== 0' or '< 2') + * @param string $baseNamespace Namespace to prepend to each classname + * + * @return array + */ + protected function discoverCommandFilesInLocation($directory, $depth, $baseNamespace) + { + if (!is_dir($directory)) { + return []; + } + $finder = $this->createFinder($directory, $depth); + + $commands = []; + foreach ($finder as $file) { + $relativePathName = $file->getRelativePathname(); + $relativeNamespaceAndClassname = str_replace( + ['/', '.php'], + ['\\', ''], + $relativePathName + ); + $classname = $this->joinNamespace([$baseNamespace, $relativeNamespaceAndClassname]); + $commandFilePath = $this->joinPaths([$directory, $relativePathName]); + $commands[$commandFilePath] = $classname; + } + + return $commands; + } + + /** + * Create a Finder object for use in searching a particular directory + * location. + * + * @param string $directory The location to search + * @param string $depth The depth limitation + * + * @return Finder + */ + protected function createFinder($directory, $depth) + { + $finder = new Finder(); + $finder->files() + ->name($this->searchPattern) + ->in($directory) + ->depth($depth); + + foreach ($this->excludeList as $item) { + $finder->exclude($item); + } + + return $finder; + } + + /** + * Combine the items of the provied array into a backslash-separated + * namespace string. Empty and numeric items are omitted. + * + * @param array $namespaceParts List of components of a namespace + * + * @return string + */ + protected function joinNamespace(array $namespaceParts) + { + return $this->joinParts( + '\\', + $namespaceParts, + function ($item) { + return !is_numeric($item) && !empty($item); + } + ); + } + + /** + * Combine the items of the provied array into a slash-separated + * pathname. Empty items are omitted. + * + * @param array $pathParts List of components of a path + * + * @return string + */ + protected function joinPaths(array $pathParts) + { + return $this->joinParts( + '/', + $pathParts, + function ($item) { + return !empty($item); + } + ); + } + + /** + * Simple wrapper around implode and array_filter. + * + * @param string $delimiter + * @param array $parts + * @param callable $filterFunction + */ + protected function joinParts($delimiter, $parts, $filterFunction) + { + return implode( + $delimiter, + array_filter($parts, $filterFunction) + ); + } +} diff --git a/src/composer/vendor/consolidation/annotated-command/src/CommandInfoAltererInterface.php b/src/composer/vendor/consolidation/annotated-command/src/CommandInfoAltererInterface.php new file mode 100644 index 00000000..55376d14 --- /dev/null +++ b/src/composer/vendor/consolidation/annotated-command/src/CommandInfoAltererInterface.php @@ -0,0 +1,9 @@ +hookManager = $hookManager; + } + + /** + * Return the hook manager + * @return HookManager + */ + public function hookManager() + { + return $this->hookManager; + } + + public function addPrepareFormatter(PrepareFormatter $preparer) + { + $this->prepareOptionsList[] = $preparer; + } + + public function setFormatterManager(FormatterManager $formatterManager) + { + $this->formatterManager = $formatterManager; + return $this; + } + + public function setDisplayErrorFunction(callable $fn) + { + $this->displayErrorFunction = $fn; + return $this; + } + + /** + * Return the formatter manager + * @return FormatterManager + */ + public function formatterManager() + { + return $this->formatterManager; + } + + public function initializeHook( + InputInterface $input, + $names, + AnnotationData $annotationData + ) { + return $this->hookManager()->initializeHook($input, $names, $annotationData); + } + + public function optionsHook( + AnnotatedCommand $command, + $names, + AnnotationData $annotationData + ) { + $this->hookManager()->optionsHook($command, $names, $annotationData); + } + + public function interact( + InputInterface $input, + OutputInterface $output, + $names, + AnnotationData $annotationData + ) { + return $this->hookManager()->interact($input, $output, $names, $annotationData); + } + + public function process( + OutputInterface $output, + $names, + $commandCallback, + CommandData $commandData + ) { + $result = []; + try { + $result = $this->validateRunAndAlter( + $names, + $commandCallback, + $commandData + ); + return $this->handleResults($output, $names, $result, $commandData); + } catch (\Exception $e) { + $result = new CommandError($e->getMessage(), $e->getCode()); + return $this->handleResults($output, $names, $result, $commandData); + } + } + + public function validateRunAndAlter( + $names, + $commandCallback, + CommandData $commandData + ) { + // Validators return any object to signal a validation error; + // if the return an array, it replaces the arguments. + $validated = $this->hookManager()->validateArguments($names, $commandData); + if (is_object($validated)) { + return $validated; + } + + // Run the command, alter the results, and then handle output and status + $result = $this->runCommandCallback($commandCallback, $commandData); + return $this->processResults($names, $result, $commandData); + } + + public function processResults($names, $result, CommandData $commandData) + { + return $this->hookManager()->alterResult($names, $result, $commandData); + } + + /** + * Handle the result output and status code calculation. + */ + public function handleResults(OutputInterface $output, $names, $result, CommandData $commandData) + { + $status = $this->hookManager()->determineStatusCode($names, $result); + // If the result is an integer and no separate status code was provided, then use the result as the status and do no output. + if (is_integer($result) && !isset($status)) { + return $result; + } + $status = $this->interpretStatusCode($status); + + // Get the structured output, the output stream and the formatter + $structuredOutput = $this->hookManager()->extractOutput($names, $result); + $output = $this->chooseOutputStream($output, $status); + if ($status != 0) { + return $this->writeErrorMessage($output, $status, $structuredOutput, $result); + } + if ($this->dataCanBeFormatted($structuredOutput) && isset($this->formatterManager)) { + return $this->writeUsingFormatter($output, $structuredOutput, $commandData); + } + return $this->writeCommandOutput($output, $structuredOutput); + } + + protected function dataCanBeFormatted($structuredOutput) + { + if (!isset($this->formatterManager)) { + return false; + } + return + is_object($structuredOutput) || + is_array($structuredOutput); + } + + /** + * Run the main command callback + */ + protected function runCommandCallback($commandCallback, CommandData $commandData) + { + $result = false; + try { + $args = $commandData->getArgsAndOptions(); + $result = call_user_func_array($commandCallback, $args); + } catch (\Exception $e) { + $result = new CommandError($e->getMessage(), $e->getCode()); + } + return $result; + } + + /** + * Determine the formatter that should be used to render + * output. + * + * If the user specified a format via the --format option, + * then always return that. Otherwise, return the default + * format, unless --pipe was specified, in which case + * return the default pipe format, format-pipe. + * + * n.b. --pipe is a handy option introduced in Drush 2 + * (or perhaps even Drush 1) that indicates that the command + * should select the output format that is most appropriate + * for use in scripts (e.g. to pipe to another command). + * + * @return string + */ + protected function getFormat(FormatterOptions $options) + { + // In Symfony Console, there is no way for us to differentiate + // between the user specifying '--format=table', and the user + // not specifying --format when the default value is 'table'. + // Therefore, we must make --field always override --format; it + // cannot become the default value for --format. + if ($options->get('field')) { + return 'string'; + } + $defaults = []; + if ($options->get('pipe')) { + return $options->get('pipe-format', [], 'tsv'); + } + return $options->getFormat($defaults); + } + + /** + * Determine whether we should use stdout or stderr. + */ + protected function chooseOutputStream(OutputInterface $output, $status) + { + // If the status code indicates an error, then print the + // result to stderr rather than stdout + if ($status && ($output instanceof ConsoleOutputInterface)) { + return $output->getErrorOutput(); + } + return $output; + } + + /** + * Call the formatter to output the provided data. + */ + protected function writeUsingFormatter(OutputInterface $output, $structuredOutput, CommandData $commandData) + { + $formatterOptions = $this->createFormatterOptions($commandData); + $format = $this->getFormat($formatterOptions); + $this->formatterManager->write( + $output, + $format, + $structuredOutput, + $formatterOptions + ); + return 0; + } + + /** + * Create a FormatterOptions object for use in writing the formatted output. + * @param CommandData $commandData + * @return FormatterOptions + */ + protected function createFormatterOptions($commandData) + { + $options = $commandData->input()->getOptions(); + $formatterOptions = new FormatterOptions($commandData->annotationData()->getArrayCopy(), $options); + foreach ($this->prepareOptionsList as $preparer) { + $preparer->prepare($commandData, $formatterOptions); + } + return $formatterOptions; + } + + /** + * Description + * @param OutputInterface $output + * @param int $status + * @param string $structuredOutput + * @param mixed $originalResult + * @return type + */ + protected function writeErrorMessage($output, $status, $structuredOutput, $originalResult) + { + if (isset($this->displayErrorFunction)) { + call_user_func($this->displayErrorFunction, $output, $structuredOutput, $status, $originalResult); + } else { + $this->writeCommandOutput($output, $structuredOutput); + } + return $status; + } + + /** + * If the result object is a string, then print it. + */ + protected function writeCommandOutput( + OutputInterface $output, + $structuredOutput + ) { + // If there is no formatter, we will print strings, + // but can do no more than that. + if (is_string($structuredOutput)) { + $output->writeln($structuredOutput); + } + return 0; + } + + /** + * If a status code was set, then return it; otherwise, + * presume success. + */ + protected function interpretStatusCode($status) + { + if (isset($status)) { + return $status; + } + return 0; + } +} diff --git a/src/composer/vendor/consolidation/annotated-command/src/ExitCodeInterface.php b/src/composer/vendor/consolidation/annotated-command/src/ExitCodeInterface.php new file mode 100644 index 00000000..bec902bb --- /dev/null +++ b/src/composer/vendor/consolidation/annotated-command/src/ExitCodeInterface.php @@ -0,0 +1,12 @@ +hooks; + } + + /** + * Add a hook + * + * @param mixed $callback The callback function to call + * @param string $hook The name of the hook to add + * @param string $name The name of the command to hook + * ('*' for all) + */ + public function add(callable $callback, $hook, $name = '*') + { + if (empty($name)) { + $name = static::getClassNameFromCallback($callback); + } + $this->hooks[$name][$hook][] = $callback; + return $this; + } + + public function recordHookOptions($commandInfo, $name) + { + $this->hookOptions[$name][] = $commandInfo; + return $this; + } + + public static function getNames($command, $callback) + { + return array_filter( + array_merge( + static::getNamesUsingCommands($command), + [static::getClassNameFromCallback($callback)] + ) + ); + } + + protected static function getNamesUsingCommands($command) + { + return array_merge( + [$command->getName()], + $command->getAliases() + ); + } + + /** + * If a command hook does not specify any particular command + * name that it should be attached to, then it will be applied + * to every command that is defined in the same class as the hook. + * This is controlled by using the namespace + class name of + * the implementing class of the callback hook. + */ + protected static function getClassNameFromCallback($callback) + { + if (!is_array($callback)) { + return ''; + } + $reflectionClass = new \ReflectionClass($callback[0]); + return $reflectionClass->getName(); + } + + /** + * Add an configuration provider hook + * + * @param type InitializeHookInterface $provider + * @param type $name The name of the command to hook + * ('*' for all) + */ + public function addInitializeHook(InitializeHookInterface $initializeHook, $name = '*') + { + $this->hooks[$name][self::INITIALIZE][] = $initializeHook; + return $this; + } + + /** + * Add an option hook + * + * @param type ValidatorInterface $validator + * @param type $name The name of the command to hook + * ('*' for all) + */ + public function addOptionHook(OptionHookInterface $interactor, $name = '*') + { + $this->hooks[$name][self::INTERACT][] = $interactor; + return $this; + } + + /** + * Add an interact hook + * + * @param type ValidatorInterface $validator + * @param type $name The name of the command to hook + * ('*' for all) + */ + public function addInteractor(InteractorInterface $interactor, $name = '*') + { + $this->hooks[$name][self::INTERACT][] = $interactor; + return $this; + } + + /** + * Add a pre-validator hook + * + * @param type ValidatorInterface $validator + * @param type $name The name of the command to hook + * ('*' for all) + */ + public function addPreValidator(ValidatorInterface $validator, $name = '*') + { + $this->hooks[$name][self::PRE_ARGUMENT_VALIDATOR][] = $validator; + return $this; + } + + /** + * Add a validator hook + * + * @param type ValidatorInterface $validator + * @param type $name The name of the command to hook + * ('*' for all) + */ + public function addValidator(ValidatorInterface $validator, $name = '*') + { + $this->hooks[$name][self::ARGUMENT_VALIDATOR][] = $validator; + return $this; + } + + /** + * Add a pre-command hook. This is the same as a validator hook, except + * that it will run after all of the post-validator hooks. + * + * @param type ValidatorInterface $preCommand + * @param type $name The name of the command to hook + * ('*' for all) + */ + public function addPreCommandHook(ValidatorInterface $preCommand, $name = '*') + { + $this->hooks[$name][self::PRE_COMMAND_HOOK][] = $preCommand; + return $this; + } + + /** + * Add a post-command hook. This is the same as a pre-process hook, + * except that it will run before the first pre-process hook. + * + * @param type ProcessResultInterface $postCommand + * @param type $name The name of the command to hook + * ('*' for all) + */ + public function addPostCommandHook(ProcessResultInterface $postCommand, $name = '*') + { + $this->hooks[$name][self::POST_COMMAND_HOOK][] = $postCommand; + return $this; + } + + /** + * Add a result processor. + * + * @param type ProcessResultInterface $resultProcessor + * @param type $name The name of the command to hook + * ('*' for all) + */ + public function addResultProcessor(ProcessResultInterface $resultProcessor, $name = '*') + { + $this->hooks[$name][self::PROCESS_RESULT][] = $resultProcessor; + return $this; + } + + /** + * Add a result alterer. After a result is processed + * by a result processor, an alter hook may be used + * to convert the result from one form to another. + * + * @param type AlterResultInterface $resultAlterer + * @param type $name The name of the command to hook + * ('*' for all) + */ + public function addAlterResult(AlterResultInterface $resultAlterer, $name = '*') + { + $this->hooks[$name][self::ALTER_RESULT][] = $resultAlterer; + return $this; + } + + /** + * Add a status determiner. Usually, a command should return + * an integer on error, or a result object on success (which + * implies a status code of zero). If a result contains the + * status code in some other field, then a status determiner + * can be used to call the appropriate accessor method to + * determine the status code. This is usually not necessary, + * though; a command that fails may return a CommandError + * object, which contains a status code and a result message + * to display. + * @see CommandError::getExitCode() + * + * @param type StatusDeterminerInterface $statusDeterminer + * @param type $name The name of the command to hook + * ('*' for all) + */ + public function addStatusDeterminer(StatusDeterminerInterface $statusDeterminer, $name = '*') + { + $this->hooks[$name][self::STATUS_DETERMINER][] = $statusDeterminer; + return $this; + } + + /** + * Add an output extractor. If a command returns an object + * object, by default it is passed directly to the output + * formatter (if in use) for rendering. If the result object + * contains more information than just the data to render, though, + * then an output extractor can be used to call the appopriate + * accessor method of the result object to get the data to + * rendered. This is usually not necessary, though; it is preferable + * to have complex result objects implement the OutputDataInterface. + * @see OutputDataInterface::getOutputData() + * + * @param type ExtractOutputInterface $outputExtractor + * @param type $name The name of the command to hook + * ('*' for all) + */ + public function addOutputExtractor(ExtractOutputInterface $outputExtractor, $name = '*') + { + $this->hooks[$name][self::EXTRACT_OUTPUT][] = $outputExtractor; + return $this; + } + + public function initializeHook( + InputInterface $input, + $names, + AnnotationData $annotationData + ) { + $providers = $this->getInitializeHooks($names, $annotationData); + foreach ($providers as $provider) { + $this->callInjectConfigurationHook($provider, $input, $annotationData); + } + } + + public function optionsHook( + \Consolidation\AnnotatedCommand\AnnotatedCommand $command, + $names, + AnnotationData $annotationData + ) { + $optionHooks = $this->getOptionHooks($names, $annotationData); + foreach ($optionHooks as $optionHook) { + $this->callOptionHook($optionHook, $command, $annotationData); + } + $commandInfoList = $this->getHookOptionsForCommand($command); + $command->optionsHookForHookAnnotations($commandInfoList); + } + + public function getHookOptionsForCommand($command) + { + $names = $this->addWildcardHooksToNames($command->getNames(), $command->getAnnotationData()); + return $this->getHookOptions($names); + } + + /** + * @return CommandInfo[] + */ + public function getHookOptions($names) + { + $result = []; + foreach ($names as $name) { + if (isset($this->hookOptions[$name])) { + $result = array_merge($result, $this->hookOptions[$name]); + } + } + return $result; + } + + public function interact( + InputInterface $input, + OutputInterface $output, + $names, + AnnotationData $annotationData + ) { + $interactors = $this->getInteractors($names, $annotationData); + foreach ($interactors as $interactor) { + $this->callInteractor($interactor, $input, $output, $annotationData); + } + } + + public function validateArguments($names, CommandData $commandData) + { + $validators = $this->getValidators($names, $commandData->annotationData()); + foreach ($validators as $validator) { + $validated = $this->callValidator($validator, $commandData); + if ($validated === false) { + return new CommandError(); + } + if (is_object($validated)) { + return $validated; + } + } + } + + /** + * Process result and decide what to do with it. + * Allow client to add transformation / interpretation + * callbacks. + */ + public function alterResult($names, $result, CommandData $commandData) + { + $processors = $this->getProcessResultHooks($names, $commandData->annotationData()); + foreach ($processors as $processor) { + $result = $this->callProcessor($processor, $result, $commandData); + } + $alterers = $this->getAlterResultHooks($names, $commandData->annotationData()); + foreach ($alterers as $alterer) { + $result = $this->callProcessor($alterer, $result, $commandData); + } + + return $result; + } + + /** + * Call all status determiners, and see if any of them + * know how to convert to a status code. + */ + public function determineStatusCode($names, $result) + { + // If the result (post-processing) is an object that + // implements ExitCodeInterface, then we will ask it + // to give us the status code. + if ($result instanceof ExitCodeInterface) { + return $result->getExitCode(); + } + + // If the result does not implement ExitCodeInterface, + // then we'll see if there is a determiner that can + // extract a status code from the result. + $determiners = $this->getStatusDeterminers($names); + foreach ($determiners as $determiner) { + $status = $this->callDeterminer($determiner, $result); + if (isset($status)) { + return $status; + } + } + } + + /** + * Convert the result object to printable output in + * structured form. + */ + public function extractOutput($names, $result) + { + if ($result instanceof OutputDataInterface) { + return $result->getOutputData(); + } + + $extractors = $this->getOutputExtractors($names); + foreach ($extractors as $extractor) { + $structuredOutput = $this->callExtractor($extractor, $result); + if (isset($structuredOutput)) { + return $structuredOutput; + } + } + + return $result; + } + + protected function getCommandEventHooks($names) + { + return $this->getHooks( + $names, + [ + self::PRE_COMMAND_EVENT, + self::COMMAND_EVENT, + self::POST_COMMAND_EVENT + ] + ); + } + + protected function getInitializeHooks($names, AnnotationData $annotationData) + { + return $this->getHooks( + $names, + [ + self::PRE_INITIALIZE, + self::INITIALIZE, + self::POST_INITIALIZE + ], + $annotationData + ); + } + + protected function getOptionHooks($names, AnnotationData $annotationData) + { + return $this->getHooks( + $names, + [ + self::PRE_OPTION_HOOK, + self::OPTION_HOOK, + self::POST_OPTION_HOOK + ], + $annotationData + ); + } + + protected function getInteractors($names, AnnotationData $annotationData) + { + return $this->getHooks( + $names, + [ + self::PRE_INTERACT, + self::INTERACT, + self::POST_INTERACT + ], + $annotationData + ); + } + + protected function getValidators($names, AnnotationData $annotationData) + { + return $this->getHooks( + $names, + [ + self::PRE_ARGUMENT_VALIDATOR, + self::ARGUMENT_VALIDATOR, + self::POST_ARGUMENT_VALIDATOR, + self::PRE_COMMAND_HOOK, + self::COMMAND_HOOK, + ], + $annotationData + ); + } + + protected function getProcessResultHooks($names, AnnotationData $annotationData) + { + return $this->getHooks( + $names, + [ + self::PRE_PROCESS_RESULT, + self::PROCESS_RESULT, + self::POST_PROCESS_RESULT + ], + $annotationData + ); + } + + protected function getAlterResultHooks($names, AnnotationData $annotationData) + { + return $this->getHooks( + $names, + [ + self::PRE_ALTER_RESULT, + self::ALTER_RESULT, + self::POST_ALTER_RESULT, + self::POST_COMMAND_HOOK, + ], + $annotationData + ); + } + + protected function getStatusDeterminers($names) + { + return $this->getHooks( + $names, + [ + self::STATUS_DETERMINER, + ] + ); + } + + protected function getOutputExtractors($names) + { + return $this->getHooks( + $names, + [ + self::EXTRACT_OUTPUT, + ] + ); + } + + /** + * Get a set of hooks with the provided name(s). Include the + * pre- and post- hooks, and also include the global hooks ('*') + * in addition to the named hooks provided. + * + * @param string|array $names The name of the function being hooked. + * @param string[] $hooks A list of hooks (e.g. [HookManager::ALTER_RESULT]) + * + * @return callable[] + */ + public function getHooks($names, $hooks, $annotationData = null) + { + return $this->get($this->addWildcardHooksToNames($names, $annotationData), $hooks); + } + + protected function addWildcardHooksToNames($names, $annotationData = null) + { + $names = array_merge( + (array)$names, + ($annotationData == null) ? [] : array_map(function ($item) { + return "@$item"; + }, $annotationData->keys()) + ); + $names[] = '*'; + return array_unique($names); + } + + /** + * Get a set of hooks with the provided name(s). + * + * @param string|array $names The name of the function being hooked. + * @param string[] $hooks The list of hook names (e.g. [HookManager::ALTER_RESULT]) + * + * @return callable[] + */ + public function get($names, $hooks) + { + $result = []; + foreach ((array)$hooks as $hook) { + foreach ((array)$names as $name) { + $result = array_merge($result, $this->getHook($name, $hook)); + } + } + return $result; + } + + /** + * Get a single named hook. + * + * @param string $name The name of the hooked method + * @param string $hook The specific hook name (e.g. alter) + * + * @return callable[] + */ + protected function getHook($name, $hook) + { + if (isset($this->hooks[$name][$hook])) { + return $this->hooks[$name][$hook]; + } + return []; + } + + protected function callInjectConfigurationHook($provider, $input, AnnotationData $annotationData) + { + if ($provider instanceof InitializeHookInterface) { + return $provider->applyConfiguration($input, $annotationData); + } + if (is_callable($provider)) { + return $provider($input, $annotationData); + } + } + + protected function callOptionHook($optionHook, $command, AnnotationData $annotationData) + { + if ($optionHook instanceof OptionHookInterface) { + return $optionHook->getOptions($command, $annotationData); + } + if (is_callable($optionHook)) { + return $optionHook($command, $annotationData); + } + } + + protected function callInteractor($interactor, $input, $output, AnnotationData $annotationData) + { + if ($interactor instanceof InteractorInterface) { + return $interactor->interact($input, $output, $annotationData); + } + if (is_callable($interactor)) { + return $interactor($input, $output, $annotationData); + } + } + + protected function callValidator($validator, CommandData $commandData) + { + if ($validator instanceof ValidatorInterface) { + return $validator->validate($commandData); + } + if (is_callable($validator)) { + return $validator($commandData); + } + } + + protected function callProcessor($processor, $result, CommandData $commandData) + { + $processed = null; + if ($processor instanceof ProcessResultInterface) { + $processed = $processor->process($result, $commandData); + } + if (is_callable($processor)) { + $processed = $processor($result, $commandData); + } + if (isset($processed)) { + return $processed; + } + return $result; + } + + protected function callDeterminer($determiner, $result) + { + if ($determiner instanceof StatusDeterminerInterface) { + return $determiner->determineStatusCode($result); + } + if (is_callable($determiner)) { + return $determiner($result); + } + } + + protected function callExtractor($extractor, $result) + { + if ($extractor instanceof ExtractOutputInterface) { + return $extractor->extractOutput($result); + } + if (is_callable($extractor)) { + return $extractor($result); + } + } + + /** + * @param ConsoleCommandEvent $event + */ + public function callCommandEventHooks(ConsoleCommandEvent $event) + { + /* @var Command $command */ + $command = $event->getCommand(); + $names = [$command->getName()]; + $commandEventHooks = $this->getCommandEventHooks($names); + foreach ($commandEventHooks as $commandEvent) { + if (is_callable($commandEvent)) { + $commandEvent($event); + } + } + } + + public function findAndAddHookOptions($command) + { + if (!$command instanceof \Consolidation\AnnotatedCommand\AnnotatedCommand) { + return; + } + $command->optionsHook(); + } + + /** + * @{@inheritdoc} + */ + public static function getSubscribedEvents() + { + return [ConsoleEvents::COMMAND => 'callCommandEventHooks']; + } +} diff --git a/src/composer/vendor/consolidation/annotated-command/src/Hooks/InitializeHookInterface.php b/src/composer/vendor/consolidation/annotated-command/src/Hooks/InitializeHookInterface.php new file mode 100644 index 00000000..8e70ef11 --- /dev/null +++ b/src/composer/vendor/consolidation/annotated-command/src/Hooks/InitializeHookInterface.php @@ -0,0 +1,15 @@ +application = $application; + } + + /** + * @param ConsoleCommandEvent $event + */ + public function alterCommandOptions(ConsoleCommandEvent $event) + { + /* @var Command $command */ + $command = $event->getCommand(); + $input = $event->getInput(); + if ($command->getName() == 'help') { + // Symfony 3.x prepares $input for us; Symfony 2.x, on the other + // hand, passes it in prior to binding with the command definition, + // so we have to go to a little extra work. It may be inadvisable + // to do these steps for commands other than 'help'. + if (!$input->hasArgument('command_name')) { + $command->ignoreValidationErrors(); + $command->mergeApplicationDefinition(); + $input->bind($command->getDefinition()); + } + + $nameOfCommandToDescribe = $event->getInput()->getArgument('command_name'); + $commandToDescribe = $this->application->find($nameOfCommandToDescribe); + $this->findAndAddHookOptions($commandToDescribe); + } else { + $this->findAndAddHookOptions($command); + } + } + + public function findAndAddHookOptions($command) + { + if (!$command instanceof AnnotatedCommand) { + return; + } + $command->optionsHook(); + } + + + /** + * @{@inheritdoc} + */ + public static function getSubscribedEvents() + { + return [ConsoleEvents::COMMAND => 'alterCommandOptions']; + } +} diff --git a/src/composer/vendor/consolidation/annotated-command/src/Options/AutomaticOptionsProviderInterface.php b/src/composer/vendor/consolidation/annotated-command/src/Options/AutomaticOptionsProviderInterface.php new file mode 100644 index 00000000..1349fe79 --- /dev/null +++ b/src/composer/vendor/consolidation/annotated-command/src/Options/AutomaticOptionsProviderInterface.php @@ -0,0 +1,21 @@ +defaultWidth = $defaultWidth; + } + + public function setApplication(Application $application) + { + $this->application = $application; + } + + public function prepare(CommandData $commandData, FormatterOptions $options) + { + $width = $this->getTerminalWidth(); + if (!$width) { + $width = $this->defaultWidth; + } + + // Enforce minimum and maximum widths + $width = min($width, $this->getMaxWidth($commandData)); + $width = max($width, $this->getMinWidth($commandData)); + + $options->setWidth($width); + } + + protected function getTerminalWidth() + { + if (!$this->application) { + return 0; + } + + $dimensions = $this->application->getTerminalDimensions(); + if ($dimensions[0] == null) { + return 0; + } + + return $dimensions[0]; + } + + protected function getMaxWidth(CommandData $commandData) + { + return $this->maxWidth; + } + + protected function getMinWidth(CommandData $commandData) + { + return $this->minWidth; + } +} diff --git a/src/composer/vendor/consolidation/annotated-command/src/OutputDataInterface.php b/src/composer/vendor/consolidation/annotated-command/src/OutputDataInterface.php new file mode 100644 index 00000000..9102764d --- /dev/null +++ b/src/composer/vendor/consolidation/annotated-command/src/OutputDataInterface.php @@ -0,0 +1,13 @@ +reflection = new \ReflectionMethod($classNameOrInstance, $methodName); + $this->methodName = $methodName; + $this->otherAnnotations = new AnnotationData(); + // Set up a default name for the command from the method name. + // This can be overridden via @command or @name annotations. + $this->name = $this->convertName($this->reflection->name); + $this->options = new DefaultsWithDescriptions($this->determineOptionsFromParameters(), false); + $this->arguments = $this->determineAgumentClassifications(); + // Remember the name of the last parameter, if it holds the options. + // We will use this information to ignore @param annotations for the options. + if (!empty($this->options)) { + $this->optionParamName = $this->lastParameterName(); + } + } + + /** + * Recover the method name provided to the constructor. + * + * @return string + */ + public function getMethodName() + { + return $this->methodName; + } + + /** + * Return the primary name for this command. + * + * @return string + */ + public function getName() + { + $this->parseDocBlock(); + return $this->name; + } + + /** + * Set the primary name for this command. + * + * @param string $name + */ + public function setName($name) + { + $this->name = $name; + return $this; + } + + public function getReturnType() + { + $this->parseDocBlock(); + return $this->returnType; + } + + public function setReturnType($returnType) + { + $this->returnType = $returnType; + return $this; + } + + /** + * Get any annotations included in the docblock comment for the + * implementation method of this command that are not already + * handled by the primary methods of this class. + * + * @return AnnotationData + */ + public function getRawAnnotations() + { + $this->parseDocBlock(); + return $this->otherAnnotations; + } + + /** + * Get any annotations included in the docblock comment, + * also including default values such as @command. We add + * in the default @command annotation late, and only in a + * copy of the annotation data because we use the existance + * of a @command to indicate that this CommandInfo is + * a command, and not a hook or anything else. + * + * @return AnnotationData + */ + public function getAnnotations() + { + return new AnnotationData( + $this->getRawAnnotations()->getArrayCopy() + + [ + 'command' => $this->getName(), + ] + ); + } + + /** + * Return a specific named annotation for this command. + * + * @param string $annotation The name of the annotation. + * @return string + */ + public function getAnnotation($annotation) + { + // hasAnnotation parses the docblock + if (!$this->hasAnnotation($annotation)) { + return null; + } + return $this->otherAnnotations[$annotation]; + } + + /** + * Check to see if the specified annotation exists for this command. + * + * @param string $annotation The name of the annotation. + * @return boolean + */ + public function hasAnnotation($annotation) + { + $this->parseDocBlock(); + return isset($this->otherAnnotations[$annotation]); + } + + /** + * Save any tag that we do not explicitly recognize in the + * 'otherAnnotations' map. + */ + public function addAnnotation($name, $content) + { + $this->otherAnnotations[$name] = $content; + } + + /** + * Remove an annotation that was previoudly set. + */ + public function removeAnnotation($name) + { + unset($this->otherAnnotations[$name]); + } + + /** + * Get the synopsis of the command (~first line). + * + * @return string + */ + public function getDescription() + { + $this->parseDocBlock(); + return $this->description; + } + + /** + * Set the command description. + * + * @param string $description The description to set. + */ + public function setDescription($description) + { + $this->description = $description; + return $this; + } + + /** + * Get the help text of the command (the description) + */ + public function getHelp() + { + $this->parseDocBlock(); + return $this->help; + } + /** + * Set the help text for this command. + * + * @param string $help The help text. + */ + public function setHelp($help) + { + $this->help = $help; + return $this; + } + + /** + * Return the list of aliases for this command. + * @return string[] + */ + public function getAliases() + { + $this->parseDocBlock(); + return $this->aliases; + } + + /** + * Set aliases that can be used in place of the command's primary name. + * + * @param string|string[] $aliases + */ + public function setAliases($aliases) + { + if (is_string($aliases)) { + $aliases = explode(',', static::convertListToCommaSeparated($aliases)); + } + $this->aliases = array_filter($aliases); + return $this; + } + + /** + * Return the examples for this command. This is @usage instead of + * @example because the later is defined by the phpdoc standard to + * be example method calls. + * + * @return string[] + */ + public function getExampleUsages() + { + $this->parseDocBlock(); + return $this->exampleUsage; + } + + /** + * Add an example usage for this command. + * + * @param string $usage An example of the command, including the command + * name and all of its example arguments and options. + * @param string $description An explanation of what the example does. + */ + public function setExampleUsage($usage, $description) + { + $this->exampleUsage[$usage] = $description; + return $this; + } + + /** + * Return the list of refleaction parameters. + * + * @return ReflectionParameter[] + */ + public function getParameters() + { + return $this->reflection->getParameters(); + } + + /** + * Descriptions of commandline arguements for this command. + * + * @return DefaultsWithDescriptions + */ + public function arguments() + { + return $this->arguments; + } + + /** + * Descriptions of commandline options for this command. + * + * @return DefaultsWithDescriptions + */ + public function options() + { + return $this->options; + } + + /** + * Return the name of the last parameter if it holds the options. + */ + public function optionParamName() + { + return $this->optionParamName; + } + + /** + * Get the inputOptions for the options associated with this CommandInfo + * object, e.g. via @option annotations, or from + * $options = ['someoption' => 'defaultvalue'] in the command method + * parameter list. + * + * @return InputOption[] + */ + public function inputOptions() + { + $explicitOptions = []; + + $opts = $this->options()->getValues(); + foreach ($opts as $name => $defaultValue) { + $description = $this->options()->getDescription($name); + + $fullName = $name; + $shortcut = ''; + if (strpos($name, '|')) { + list($fullName, $shortcut) = explode('|', $name, 2); + } + + if (is_bool($defaultValue)) { + $explicitOptions[$fullName] = new InputOption($fullName, $shortcut, InputOption::VALUE_NONE, $description); + } elseif ($defaultValue === InputOption::VALUE_REQUIRED) { + $explicitOptions[$fullName] = new InputOption($fullName, $shortcut, InputOption::VALUE_REQUIRED, $description); + } else { + $explicitOptions[$fullName] = new InputOption($fullName, $shortcut, InputOption::VALUE_OPTIONAL, $description, $defaultValue); + } + } + + return $explicitOptions; + } + + /** + * An option might have a name such as 'silent|s'. In this + * instance, we will allow the @option or @default tag to + * reference the option only by name (e.g. 'silent' or 's' + * instead of 'silent|s'). + * + * @param string $optionName + * @return string + */ + public function findMatchingOption($optionName) + { + // Exit fast if there's an exact match + if ($this->options->exists($optionName)) { + return $optionName; + } + $existingOptionName = $this->findExistingOption($optionName); + if (isset($existingOptionName)) { + return $existingOptionName; + } + return $this->findOptionAmongAlternatives($optionName); + } + + /** + * @param string $optionName + * @return string + */ + protected function findOptionAmongAlternatives($optionName) + { + // Check the other direction: if the annotation contains @silent|s + // and the options array has 'silent|s'. + $checkMatching = explode('|', $optionName); + if (count($checkMatching) > 1) { + foreach ($checkMatching as $checkName) { + if ($this->options->exists($checkName)) { + $this->options->rename($checkName, $optionName); + return $optionName; + } + } + } + return $optionName; + } + + /** + * @param string $optionName + * @return string|null + */ + protected function findExistingOption($optionName) + { + // Check to see if we can find the option name in an existing option, + // e.g. if the options array has 'silent|s' => false, and the annotation + // is @silent. + foreach ($this->options()->getValues() as $name => $default) { + if (in_array($optionName, explode('|', $name))) { + return $name; + } + } + } + + /** + * Examine the parameters of the method for this command, and + * build a list of commandline arguements for them. + * + * @return array + */ + protected function determineAgumentClassifications() + { + $result = new DefaultsWithDescriptions(); + $params = $this->reflection->getParameters(); + $optionsFromParameters = $this->determineOptionsFromParameters(); + if (!empty($optionsFromParameters)) { + array_pop($params); + } + foreach ($params as $param) { + $this->addParameterToResult($result, $param); + } + return $result; + } + + /** + * Examine the provided parameter, and determine whether it + * is a parameter that will be filled in with a positional + * commandline argument. + */ + protected function addParameterToResult($result, $param) + { + // Commandline arguments must be strings, so ignore any + // parameter that is typehinted to any non-primative class. + if ($param->getClass() != null) { + return; + } + $result->add($param->name); + if ($param->isDefaultValueAvailable()) { + $defaultValue = $param->getDefaultValue(); + if (!$this->isAssoc($defaultValue)) { + $result->setDefaultValue($param->name, $defaultValue); + } + } elseif ($param->isArray()) { + $result->setDefaultValue($param->name, []); + } + } + + /** + * Examine the parameters of the method for this command, and determine + * the disposition of the options from them. + * + * @return array + */ + protected function determineOptionsFromParameters() + { + $params = $this->reflection->getParameters(); + if (empty($params)) { + return []; + } + $param = end($params); + if (!$param->isDefaultValueAvailable()) { + return []; + } + if (!$this->isAssoc($param->getDefaultValue())) { + return []; + } + return $param->getDefaultValue(); + } + + protected function lastParameterName() + { + $params = $this->reflection->getParameters(); + $param = end($params); + if (!$param) { + return ''; + } + return $param->name; + } + + /** + * Helper; determine if an array is associative or not. An array + * is not associative if its keys are numeric, and numbered sequentially + * from zero. All other arrays are considered to be associative. + * + * @param arrau $arr The array + * @return boolean + */ + protected function isAssoc($arr) + { + if (!is_array($arr)) { + return false; + } + return array_keys($arr) !== range(0, count($arr) - 1); + } + + /** + * Convert from a method name to the corresponding command name. A + * method 'fooBar' will become 'foo:bar', and 'fooBarBazBoz' will + * become 'foo:bar-baz-boz'. + * + * @param string $camel method name. + * @return string + */ + protected function convertName($camel) + { + $splitter="-"; + $camel=preg_replace('/(?!^)[[:upper:]][[:lower:]]/', '$0', preg_replace('/(?!^)[[:upper:]]+/', $splitter.'$0', $camel)); + $camel = preg_replace("/$splitter/", ':', $camel, 1); + return strtolower($camel); + } + + /** + * Parse the docBlock comment for this command, and set the + * fields of this class with the data thereby obtained. + */ + protected function parseDocBlock() + { + if (!$this->docBlockIsParsed) { + // The parse function will insert data from the provided method + // into this object, using our accessors. + CommandDocBlockParserFactory::parse($this, $this->reflection); + $this->docBlockIsParsed = true; + } + } + + /** + * Given a list that might be 'a b c' or 'a, b, c' or 'a,b,c', + * convert the data into the last of these forms. + */ + protected static function convertListToCommaSeparated($text) + { + return preg_replace('#[ \t\n\r,]+#', ',', $text); + } +} diff --git a/src/composer/vendor/consolidation/annotated-command/src/Parser/DefaultsWithDescriptions.php b/src/composer/vendor/consolidation/annotated-command/src/Parser/DefaultsWithDescriptions.php new file mode 100644 index 00000000..8f9e8173 --- /dev/null +++ b/src/composer/vendor/consolidation/annotated-command/src/Parser/DefaultsWithDescriptions.php @@ -0,0 +1,160 @@ +values = $values; + $this->hasDefault = []; + $this->descriptions = []; + $this->defaultDefault = $defaultDefault; + } + + /** + * Return just the key : default values mapping + * + * @return array + */ + public function getValues() + { + return $this->values; + } + + /** + * Return true if this set of options is empty + * + * @return + */ + public function isEmpty() + { + return empty($this->values); + } + + /** + * Check to see whether the speicifed key exists in the collection. + * + * @param string $key + * @return boolean + */ + public function exists($key) + { + return array_key_exists($key, $this->values); + } + + /** + * Get the value of one entry. + * + * @param string $key The key of the item. + * @return string + */ + public function get($key) + { + if (array_key_exists($key, $this->values)) { + return $this->values[$key]; + } + return $this->defaultDefault; + } + + /** + * Get the description of one entry. + * + * @param string $key The key of the item. + * @return string + */ + public function getDescription($key) + { + if (array_key_exists($key, $this->descriptions)) { + return $this->descriptions[$key]; + } + return ''; + } + + /** + * Add another argument to this command. + * + * @param string $key Name of the argument. + * @param string $description Help text for the argument. + * @param mixed $defaultValue The default value for the argument. + */ + public function add($key, $description = '', $defaultValue = null) + { + if (!$this->exists($key) || isset($defaultValue)) { + $this->values[$key] = isset($defaultValue) ? $defaultValue : $this->defaultDefault; + } + unset($this->descriptions[$key]); + if (!empty($description)) { + $this->descriptions[$key] = $description; + } + } + + /** + * Change the default value of an entry. + * + * @param string $key + * @param mixed $defaultValue + */ + public function setDefaultValue($key, $defaultValue) + { + $this->values[$key] = $defaultValue; + $this->hasDefault[$key] = true; + return $this; + } + + /** + * Check to see if the named argument definitively has a default value. + * + * @param string $key + * @return bool + */ + public function hasDefault($key) + { + return array_key_exists($key, $this->hasDefault); + } + + /** + * Remove an entry + * + * @param string $key The entry to remove + */ + public function clear($key) + { + unset($this->values[$key]); + unset($this->descriptions[$key]); + } + + /** + * Rename an existing option to something else. + */ + public function rename($oldName, $newName) + { + $this->add($newName, $this->getDescription($oldName), $this->get($oldName)); + $this->clear($oldName); + } +} diff --git a/src/composer/vendor/consolidation/annotated-command/src/Parser/Internal/AbstractCommandDocBlockParser.php b/src/composer/vendor/consolidation/annotated-command/src/Parser/Internal/AbstractCommandDocBlockParser.php new file mode 100644 index 00000000..0534a994 --- /dev/null +++ b/src/composer/vendor/consolidation/annotated-command/src/Parser/Internal/AbstractCommandDocBlockParser.php @@ -0,0 +1,252 @@ + 'processCommandTag', + 'name' => 'processCommandTag', + 'arg' => 'processArgumentTag', + 'param' => 'processParamTag', + 'return' => 'processReturnTag', + 'option' => 'processOptionTag', + 'default' => 'processDefaultTag', + 'aliases' => 'processAliases', + 'usage' => 'processUsageTag', + 'description' => 'processAlternateDescriptionTag', + 'desc' => 'processAlternateDescriptionTag', + ]; + + public function __construct(CommandInfo $commandInfo, \ReflectionMethod $reflection) + { + $this->commandInfo = $commandInfo; + $this->reflection = $reflection; + } + + protected function processAllTags($phpdoc) + { + // Iterate over all of the tags, and process them as necessary. + foreach ($phpdoc->getTags() as $tag) { + $processFn = [$this, 'processGenericTag']; + if (array_key_exists($tag->getName(), $this->tagProcessors)) { + $processFn = [$this, $this->tagProcessors[$tag->getName()]]; + } + $processFn($tag); + } + } + + abstract protected function getTagContents($tag); + + /** + * Parse the docBlock comment for this command, and set the + * fields of this class with the data thereby obtained. + */ + abstract public function parse(); + + /** + * Save any tag that we do not explicitly recognize in the + * 'otherAnnotations' map. + */ + protected function processGenericTag($tag) + { + $this->commandInfo->addAnnotation($tag->getName(), $this->getTagContents($tag)); + } + + /** + * Set the name of the command from a @command or @name annotation. + */ + protected function processCommandTag($tag) + { + $commandName = $this->getTagContents($tag); + $this->commandInfo->setName($commandName); + // We also store the name in the 'other annotations' so that is is + // possible to determine if the method had a @command annotation. + $this->commandInfo->addAnnotation($tag->getName(), $commandName); + } + + /** + * The @description and @desc annotations may be used in + * place of the synopsis (which we call 'description'). + * This is discouraged. + * + * @deprecated + */ + protected function processAlternateDescriptionTag($tag) + { + $this->commandInfo->setDescription($this->getTagContents($tag)); + } + + /** + * Store the data from a @arg annotation in our argument descriptions. + */ + protected function processArgumentTag($tag) + { + if (!$this->pregMatchNameAndDescription((string)$tag->getDescription(), $match)) { + return; + } + $this->addOptionOrArgumentTag($tag, $this->commandInfo->arguments(), $match); + } + + /** + * Store the data from an @option annotation in our option descriptions. + */ + protected function processOptionTag($tag) + { + if (!$this->pregMatchOptionNameAndDescription((string)$tag->getDescription(), $match)) { + return; + } + $this->addOptionOrArgumentTag($tag, $this->commandInfo->options(), $match); + } + + protected function addOptionOrArgumentTag($tag, DefaultsWithDescriptions $set, $nameAndDescription) + { + $variableName = $this->commandInfo->findMatchingOption($nameAndDescription['name']); + $desc = $nameAndDescription['description']; + $description = static::removeLineBreaks($desc); + $set->add($variableName, $description); + } + + /** + * Store the data from a @default annotation in our argument or option store, + * as appropriate. + */ + protected function processDefaultTag($tag) + { + if (!$this->pregMatchNameAndDescription((string)$tag->getDescription(), $match)) { + return; + } + $variableName = $match['name']; + $defaultValue = $this->interpretDefaultValue($match['description']); + if ($this->commandInfo->arguments()->exists($variableName)) { + $this->commandInfo->arguments()->setDefaultValue($variableName, $defaultValue); + return; + } + $variableName = $this->commandInfo->findMatchingOption($variableName); + if ($this->commandInfo->options()->exists($variableName)) { + $this->commandInfo->options()->setDefaultValue($variableName, $defaultValue); + } + } + + /** + * Store the data from a @usage annotation in our example usage list. + */ + protected function processUsageTag($tag) + { + $lines = explode("\n", $this->getTagContents($tag)); + $usage = array_shift($lines); + $description = static::removeLineBreaks(implode("\n", $lines)); + + $this->commandInfo->setExampleUsage($usage, $description); + } + + /** + * Process the comma-separated list of aliases + */ + protected function processAliases($tag) + { + $this->commandInfo->setAliases((string)$tag->getDescription()); + } + + /** + * Store the data from a @param annotation in our argument descriptions. + */ + protected function processParamTag($tag) + { + $variableName = $tag->getVariableName(); + $variableName = str_replace('$', '', $variableName); + $description = static::removeLineBreaks((string)$tag->getDescription()); + if ($variableName == $this->commandInfo->optionParamName()) { + return; + } + $this->commandInfo->arguments()->add($variableName, $description); + } + + /** + * Store the data from a @return annotation in our argument descriptions. + */ + abstract protected function processReturnTag($tag); + + protected function interpretDefaultValue($defaultValue) + { + $defaults = [ + 'null' => null, + 'true' => true, + 'false' => false, + "''" => '', + '[]' => [], + ]; + foreach ($defaults as $defaultName => $defaultTypedValue) { + if ($defaultValue == $defaultName) { + return $defaultTypedValue; + } + } + return $defaultValue; + } + + /** + * Given a docblock description in the form "$variable description", + * return the variable name and description via the 'match' parameter. + */ + protected function pregMatchNameAndDescription($source, &$match) + { + $nameRegEx = '\\$(?P[^ \t]+)[ \t]+'; + $descriptionRegEx = '(?P.*)'; + $optionRegEx = "/{$nameRegEx}{$descriptionRegEx}/s"; + + return preg_match($optionRegEx, $source, $match); + } + + /** + * Given a docblock description in the form "$variable description", + * return the variable name and description via the 'match' parameter. + */ + protected function pregMatchOptionNameAndDescription($source, &$match) + { + // Strip type and $ from the text before the @option name, if present. + $source = preg_replace('/^[a-zA-Z]* ?\\$/', '', $source); + $nameRegEx = '(?P[^ \t]+)[ \t]+'; + $descriptionRegEx = '(?P.*)'; + $optionRegEx = "/{$nameRegEx}{$descriptionRegEx}/s"; + + return preg_match($optionRegEx, $source, $match); + } + + /** + * Given a list that might be 'a b c' or 'a, b, c' or 'a,b,c', + * convert the data into the last of these forms. + */ + protected static function convertListToCommaSeparated($text) + { + return preg_replace('#[ \t\n\r,]+#', ',', $text); + } + + /** + * Take a multiline description and convert it into a single + * long unbroken line. + */ + protected static function removeLineBreaks($text) + { + return trim(preg_replace('#[ \t\n\r]+#', ' ', $text)); + } +} diff --git a/src/composer/vendor/consolidation/annotated-command/src/Parser/Internal/CommandDocBlockParser2.php b/src/composer/vendor/consolidation/annotated-command/src/Parser/Internal/CommandDocBlockParser2.php new file mode 100644 index 00000000..22ecad2b --- /dev/null +++ b/src/composer/vendor/consolidation/annotated-command/src/Parser/Internal/CommandDocBlockParser2.php @@ -0,0 +1,70 @@ +reflection->getDocComment(); + $phpdoc = new DocBlock($docblockComment); + + // First set the description (synopsis) and help. + $this->commandInfo->setDescription((string)$phpdoc->getShortDescription()); + $this->commandInfo->setHelp((string)$phpdoc->getLongDescription()); + + $this->processAllTags($phpdoc); + } + + protected function getTagContents($tag) + { + return $tag->getContent(); + } + + /** + * Store the data from a @arg annotation in our argument descriptions. + */ + protected function processArgumentTag($tag) + { + if (!$this->pregMatchNameAndDescription((string)$tag->getDescription(), $match)) { + return; + } + $this->addOptionOrArgumentTag($tag, $this->commandInfo->arguments(), $match); + } + + /** + * Store the data from a @param annotation in our argument descriptions. + */ + protected function processParamTag($tag) + { + if (!$tag instanceof ParamTag) { + return; + } + return parent::processParamTag($tag); + } + + /** + * Store the data from a @return annotation in our argument descriptions. + */ + protected function processReturnTag($tag) + { + if (!$tag instanceof ReturnTag) { + return; + } + $this->commandInfo->setReturnType($tag->getType()); + } +} diff --git a/src/composer/vendor/consolidation/annotated-command/src/Parser/Internal/CommandDocBlockParser3.php b/src/composer/vendor/consolidation/annotated-command/src/Parser/Internal/CommandDocBlockParser3.php new file mode 100644 index 00000000..ed0eb580 --- /dev/null +++ b/src/composer/vendor/consolidation/annotated-command/src/Parser/Internal/CommandDocBlockParser3.php @@ -0,0 +1,74 @@ +reflection->getDocComment(); + if (empty($docComment)) { + return; + } + $phpdoc = $this->createDocBlock(); + + // First set the description (synopsis) and help. + $this->commandInfo->setDescription((string)$phpdoc->getSummary()); + $this->commandInfo->setHelp((string)$phpdoc->getDescription()); + + $this->processAllTags($phpdoc); + } + + public function createDocBlock() + { + $docBlockFactory = \phpDocumentor\Reflection\DocBlockFactory::createInstance(); + $contextFactory = new \phpDocumentor\Reflection\Types\ContextFactory(); + + return $docBlockFactory->create( + $this->reflection, + $contextFactory->createFromReflector($this->reflection) + ); + } + + protected function getTagContents($tag) + { + return (string)$tag; + } + + /** + * Store the data from a @param annotation in our argument descriptions. + */ + protected function processParamTag($tag) + { + if (!$tag instanceof Param) { + return; + } + return parent::processParamTag($tag); + } + + /** + * Store the data from a @return annotation in our argument descriptions. + */ + protected function processReturnTag($tag) + { + if (!$tag instanceof Return_) { + return; + } + // If there is a spurrious trailing space on the return type, remove it. + $this->commandInfo->setReturnType(trim($this->getTagContents($tag))); + } +} diff --git a/src/composer/vendor/consolidation/annotated-command/src/Parser/Internal/CommandDocBlockParserFactory.php b/src/composer/vendor/consolidation/annotated-command/src/Parser/Internal/CommandDocBlockParserFactory.php new file mode 100644 index 00000000..fe1bdecd --- /dev/null +++ b/src/composer/vendor/consolidation/annotated-command/src/Parser/Internal/CommandDocBlockParserFactory.php @@ -0,0 +1,28 @@ +parse(); + } + + private static function create(CommandInfo $commandInfo, \ReflectionMethod $reflection) + { + if (static::hasReflectionDocBlock3()) { + return new CommandDocBlockParser3($commandInfo, $reflection); + } + return new CommandDocBlockParser2($commandInfo, $reflection); + } + + private static function hasReflectionDocBlock3() + { + return class_exists('phpDocumentor\Reflection\DocBlockFactory') && class_exists('phpDocumentor\Reflection\Types\ContextFactory'); + } +} diff --git a/src/composer/vendor/consolidation/annotated-command/tests/src/ApplicationWithTerminalWidth.php b/src/composer/vendor/consolidation/annotated-command/tests/src/ApplicationWithTerminalWidth.php new file mode 100644 index 00000000..1efaf6d8 --- /dev/null +++ b/src/composer/vendor/consolidation/annotated-command/tests/src/ApplicationWithTerminalWidth.php @@ -0,0 +1,26 @@ +width = $width; + $this->height = $height; + } + + public function getTerminalDimensions() + { + return [ $this->width, $this->height ]; + } +} diff --git a/src/composer/vendor/consolidation/annotated-command/tests/src/ExampleAnnotatedCommand.php b/src/composer/vendor/consolidation/annotated-command/tests/src/ExampleAnnotatedCommand.php new file mode 100644 index 00000000..e114f8be --- /dev/null +++ b/src/composer/vendor/consolidation/annotated-command/tests/src/ExampleAnnotatedCommand.php @@ -0,0 +1,60 @@ +getArgument('one'); + $two = $input->getArgument('two'); + $flip = $input->getOption('flip'); + + $result = $this->myCat($one, $two, $flip); + + // We could also just use $output->writeln($result) here, + // but calling processResults enables the use of output + // formatters. Note also that if you use processResults, you + // should correctly inject the command processor into your + // annotated command via AnnotatedCommand::setCommandProcessor(). + return $this->processResults($input, $output, $result); + } +} diff --git a/src/composer/vendor/consolidation/annotated-command/tests/src/ExampleCommandFile.php b/src/composer/vendor/consolidation/annotated-command/tests/src/ExampleCommandFile.php new file mode 100644 index 00000000..3c6d8a0d --- /dev/null +++ b/src/composer/vendor/consolidation/annotated-command/tests/src/ExampleCommandFile.php @@ -0,0 +1,351 @@ +state = $state; + } + + public function setOutput($output) + { + $this->output = $output; + } + + /** + * This is the my:cat command + * + * This command will concatenate two parameters. If the --flip flag + * is provided, then the result is the concatenation of two and one. + * + * @param string $one The first parameter. + * @param string $two The other parameter. + * @option boolean $flip Whether or not the second parameter should come first in the result. + * @aliases c + * @usage bet alpha --flip + * Concatenate "alpha" and "bet". + * @arbitrary This annotation is here merely as a marker used in testing. + */ + public function myCat($one, $two = '', $options = ['flip' => false]) + { + if ($options['flip']) { + return "{$two}{$one}"; + } + return "{$one}{$two}"; + } + + /** + * @command my:repeat + */ + public function myRepeat($one, $two = '', $options = ['repeat' => 1]) + { + return str_repeat("{$one}{$two}", $options['repeat']); + } + + /** + * @command my:join + */ + public function myJoin(array $args, $options = ['flip' => false, 'repeat' => 1]) + { + if ($options['flip']) { + $args = array_reverse($args); + } + $result = implode('', $args); + return str_repeat($result, $options['repeat']); + } + + /** + * This is a command with no options + * + * This command will concatenate two parameters. + * + * @param $one The first parameter. + * @param $two The other parameter. + * @aliases nope + * @usage alpha bet + * Concatenate "alpha" and "bet". + */ + public function commandWithNoOptions($one, $two = 'default') + { + return "{$one}{$two}"; + } + + /** + * This command has no arguments--only options + * + * Return a result only if not silent. + * + * @option silent Supress output. + */ + public function commandWithNoArguments($opts = ['silent|s' => false]) + { + if (!$opts['silent']) { + return "Hello, world"; + } + } + + /** + * Shortcut on annotation + * + * This command defines the option shortcut on the annotation instead of in the options array. + * + * @param $opts The options + * @option silent|s Supress output. + */ + public function shortcutOnAnnotation($opts = ['silent' => false]) + { + if (!$opts['silent']) { + return "Hello, world"; + } + } + + /** + * This is the test:arithmatic command + * + * This command will add one and two. If the --negate flag + * is provided, then the result is negated. + * + * @command test:arithmatic + * @param integer $one The first number to add. + * @param integer $two The other number to add. + * @option negate Whether or not the result should be negated. + * @aliases arithmatic + * @usage 2 2 --negate + * Add two plus two and then negate. + * @custom + */ + public function testArithmatic($one, $two, $options = ['negate' => false]) + { + $result = $one + $two; + if ($options['negate']) { + $result = -$result; + } + + // Integer return codes are exit codes (errors), so + // return a the result as a string so that it will be printed. + return "$result"; + } + + /** + * This is the test:state command + * + * This command tests to see if the state of the Commandfile instance + */ + public function testState() + { + return $this->state; + } + + /** + * This is the test:passthrough command + * + * This command takes a variable number of parameters as + * an array and returns them as a csv. + */ + public function testPassthrough(array $params) + { + return implode(',', $params); + } + + /** + * This command wraps its parameter in []; its alter hook + * then wraps the result in <>. + */ + public function testHook($parameter) + { + return "[$parameter]"; + } + + /** + * Wrap the results of test:hook in <>. + * + * @hook alter test:hook + */ + public function hookTestHook($result) + { + return "<$result>"; + } + + /** + * This test is very similar to the preceding test, except + * it uses an annotation hook instead of a named-function hook. + * + * @hookme + * @before > + * @after < + */ + public function testAnnotationHook($parameter) + { + return "($parameter)"; + } + + /** + * Wrap the results of test:hook in whatever the @before and @after + * annotations contain. + * + * @hook alter @hookme + */ + public function hookTestAnnotatedHook($result, CommandData $commandData) + { + $before = $commandData->annotationData()->get('before', '-'); + $after = $commandData->annotationData()->get('after', '-'); + return "$before$result$after"; + } + + /** + * Alter the results of the hook with its command name. + * + * @hook alter @addmycommandname + */ + public function hookAddCommandName($result, CommandData $commandData) + { + $annotationData = $commandData->annotationData(); + return "$result from " . $annotationData['command']; + } + + /** + * Here is a hook with an explicit command annotation that we will alter + * with the preceeding hook + * + * @command alter-me + * @addmycommandname + */ + public function alterMe() + { + return "splendiferous"; + } + + /** + * Here is another hook that has no command annotation that should be + * altered with the default value for the command name + * + * @addmycommandname + */ + public function alterMeToo() + { + return "fantabulous"; + } + + /** + * @hook pre-command test:post-command + */ + public function hookTestPreCommandHook(CommandData $commandData) + { + // Use 'writeln' to detect order that hooks are called + $this->output->writeln("foo"); + } + + /** + * @command test:post-command + */ + public function testPostCommand($value) + { + $this->output->writeln($value); + } + + /** + * @hook post-command test:post-command + */ + public function hookTestPostCommandHook($result, CommandData $commandData) + { + // Use 'writeln' to detect order that hooks are called + $this->output->writeln("baz"); + } + + public function testHello($who) + { + return "Hello, $who."; + } + + public function testException($what) + { + throw new \Exception($what); + } + + /** + * @hook init test:hello + */ + public function initializeTestHello($input, AnnotationData $annotationData) + { + $who = $input->getArgument('who'); + if (!$who) { + $input->setArgument('who', 'Huey'); + } + } + + /** + * @hook command-event test:hello + */ + public function commandEventTestHello(ConsoleCommandEvent $event) + { + // Note that Symfony Console will not allow us to alter the + // input from this hook, so we'll just print something to + // show that this hook was executed. + $input = $event->getInput(); + $who = $input->getArgument('who'); + $this->output->writeln("Here comes $who!"); + } + + /** + * @hook interact test:hello + */ + public function interactTestHello($input, $output) + { + $who = $input->getArgument('who'); + if (!$who) { + $input->setArgument('who', 'Goofey'); + } + } + + /** + * @hook validate test:hello + */ + public function validateTestHello($commandData) + { + $args = $commandData->arguments(); + if ($args['who'] == 'Donald Duck') { + return new CommandError("I won't say hello to Donald Duck."); + } + if ($args['who'] == 'Drumph') { + throw new \Exception('Irrational value error.'); + } + } + + /** + * Test default values in arguments + * + * @param string|null $one + * @param string|null $two + * @return string + */ + public function defaults($one = null, $two = null) + { + if ($one && $two) { + return "$one and $two"; + } + if ($one) { + return "only $one"; + } + return "nothing provided"; + } +} diff --git a/src/composer/vendor/consolidation/annotated-command/tests/src/ExampleCommandInfoAlterer.php b/src/composer/vendor/consolidation/annotated-command/tests/src/ExampleCommandInfoAlterer.php new file mode 100644 index 00000000..824122d3 --- /dev/null +++ b/src/composer/vendor/consolidation/annotated-command/tests/src/ExampleCommandInfoAlterer.php @@ -0,0 +1,15 @@ +hasAnnotation('arbitrary')) { + $commandInfo->addAnnotation('dynamic', "This annotation was dynamically added by ExampleCommandInfoAlterer"); + } + } +} diff --git a/src/composer/vendor/consolidation/annotated-command/tests/src/ExampleHookAllCommandFile.php b/src/composer/vendor/consolidation/annotated-command/tests/src/ExampleHookAllCommandFile.php new file mode 100644 index 00000000..12319aa4 --- /dev/null +++ b/src/composer/vendor/consolidation/annotated-command/tests/src/ExampleHookAllCommandFile.php @@ -0,0 +1,41 @@ + false]) + { + if ($options['flip']) { + return "{$two}{$one}"; + } + return "{$one}{$two}"; + } + + public function doRepeat($one, $two = '', $options = ['repeat' => 1]) + { + return str_repeat("{$one}{$two}", $options['repeat']); + } + + /** + * This hook function does not specify which command or annotation + * it is hooking; that makes it apply to every command in the same class. + * + * @hook alter + */ + public function alterAllCommands($result) + { + if (is_string($result)) { + $result = "*** $result ***"; + } + return $result; + } +} diff --git a/src/composer/vendor/consolidation/annotated-command/tests/src/alpha/AlphaCommandFile.php b/src/composer/vendor/consolidation/annotated-command/tests/src/alpha/AlphaCommandFile.php new file mode 100644 index 00000000..a58817ba --- /dev/null +++ b/src/composer/vendor/consolidation/annotated-command/tests/src/alpha/AlphaCommandFile.php @@ -0,0 +1,243 @@ + 42]; + } + + /** + * @command example:output + */ + public function exampleOutput() + { + return 'Hello, World.'; + } + + /** + * @command example:cat + */ + public function exampleCat($one, $two = '', $options = ['flip' => false]) + { + if ($options['flip']) { + return "{$two}{$one}"; + } + return "{$one}{$two}"; + } + + /** + * @command example:echo + */ + public function exampleEcho(array $args) + { + return ['item-list' => $args]; + } + + /** + * @command example:message + */ + public function exampleMessage() + { + return ['message' => 'Shipwrecked; send bananas.']; + } + + /** + * Test command with formatters + * + * @command example:table + * @field-labels + * first: I + * second: II + * third: III + * @usage example:table --format=yaml + * @usage example:table --format=csv + * @usage example:table --fields=first,third + * @usage example:table --fields=III,II + * @return \Consolidation\OutputFormatters\StructuredData\RowsOfFields + */ + public function exampleTable($options = ['format' => 'table', 'fields' => '']) + { + $outputData = [ + [ 'first' => 'One', 'second' => 'Two', 'third' => 'Three' ], + [ 'first' => 'Eins', 'second' => 'Zwei', 'third' => 'Drei' ], + [ 'first' => 'Ichi', 'second' => 'Ni', 'third' => 'San' ], + [ 'first' => 'Uno', 'second' => 'Dos', 'third' => 'Tres' ], + ]; + return new RowsOfFields($outputData); + } + + /** + * Test word wrapping + * + * @command example:wrap + * @field-labels + * first: First + * second: Second + * + * @return \Consolidation\OutputFormatters\StructuredData\RowsOfFields + */ + public function exampleWrap() + { + $data = [ + [ + 'first' => 'This is a really long cell that contains a lot of data. When it is rendered, it should be wrapped across multiple lines.', + 'second' => 'This is the second column of the same table. It is also very long, and should be wrapped across multiple lines, just like the first column.', + ] + ]; + return new RowsOfFields($data); + } + + /** + * @hook option example:table + */ + public function additionalOptionForExampleTable($command, $annotationData) + { + $command->addOption( + 'dynamic', + '', + InputOption::VALUE_NONE, + 'Option added by @hook option example:table' + ); + } + + /** + * Demonstrate an alter hook with an option + * + * @hook alter example:table + * @option french Add a row with French numbers. + * @usage example:table --french + */ + public function alterFormatters($result, CommandData $commandData) + { + if ($commandData->input()->getOption('french')) { + $result[] = [ 'first' => 'Un', 'second' => 'Deux', 'third' => 'Trois' ]; + } + + return $result; + } + + /** + * Test command with formatters using an associative list + * + * @command example:list + * @field-labels + * sftp_command: SFTP Command + * sftp_username: SFTP Username + * sftp_host: SFTP Host + * sftp_password: SFTP Password + * sftp_url: SFTP URL + * git_command: Git Command + * git_username: Git Username + * git_host: Git Host + * git_port: Git Port + * git_url: Git URL + * mysql_command: MySQL Command + * mysql_username: MySQL Username + * mysql_host: MySQL Host + * mysql_password: MySQL Password + * mysql_url: MySQL URL + * mysql_port: MySQL Port + * mysql_database: MySQL Database + * redis_command: Redis Command + * redis_port: Redis Port + * redis_url: Redis URL + * redis_password: Redis Password + * @default-fields *_command + * @return \Consolidation\OutputFormatters\StructuredData\AssociativeList + */ + public function exampleAssociativeList() + { + $outputData = [ + 'sftp_command' => 'sftp -o Port=2222 dev@appserver.dev.drush.in', + 'sftp_username' => 'dev', + 'sftp_host' => 'appserver.dev.drush.in', + 'sftp_password' => 'Use your account password', + 'sftp_url' => 'sftp://dev@appserver.dev.drush.in:2222', + 'git_command' => 'git clone ssh://codeserver.dev@codeserver.dev.drush.in:2222/~/repository.git wp-update', + 'git_username' => 'codeserver.dev', + 'git_host' => 'codeserver.dev.drush.in', + 'git_port' => 2222, + 'git_url' => 'ssh://codeserver.dev@codeserver.dev.drush.in:2222/~/repository.git', + 'mysql_command' => 'mysql -u pantheon -p4b33cb -h dbserver.dev.drush.in -P 16191 pantheon', + 'mysql_username' => 'pantheon', + 'mysql_host' => 'dbserver.dev.drush.in', + 'mysql_password' => '4b33cb', + 'mysql_url' => 'mysql://pantheon:4b33cb@dbserver.dev.drush.in:16191/pantheon', + 'mysql_port' => 16191, + 'mysql_database' => 'pantheon', + ]; + return new AssociativeList($outputData); + } + + /** + * This command has no annotations; this means that it will not be + * found when createCommandsFromClass() is called with + * '$includeAllPublicMethods' set to false. + */ + public function withoutAnnotations() + { + return 'ok'; + } + + /** + * @command command:with-one-optional-argument + * + * This command has just one optional argument. + * + * Return a result only if not silent. + * + * @option silent Supress output. + */ + public function commandWithOneOptionalArgument($who = 'world', $opts = ['silent|s' => false]) + { + if (!$opts['silent']) { + return "Hello, $who"; + } + } + + /** + * This should be a command, because it is annotated like one. + * + * @command get:serious + */ + public function getSerious() + { + return 'very serious'; + } + + /** + * This should not be a command, because it looks like an accessor and + * has no @command annotation. + */ + public function getLost() + { + return 'very lost'; + } +} diff --git a/src/composer/vendor/consolidation/annotated-command/tests/src/alpha/Exclude/ExcludedCommandFile.php b/src/composer/vendor/consolidation/annotated-command/tests/src/alpha/Exclude/ExcludedCommandFile.php new file mode 100644 index 00000000..d4f50b6e --- /dev/null +++ b/src/composer/vendor/consolidation/annotated-command/tests/src/alpha/Exclude/ExcludedCommandFile.php @@ -0,0 +1,14 @@ +input()->getOption('chinese')) { + $result[] = [ 'first' => '壹', 'second' => '貳', 'third' => '叁' ]; + } + + return $result; + } + + /** + * Demonstrate an alter hook with an option + * + * @hook alter * + * @option kanji Add a row with Kanji numbers. + * @usage example:table --kanji + */ + public function alterFormattersKanji($result, CommandData $commandData) + { + if ($commandData->input()->getOption('kanji')) { + $result[] = [ 'first' => '一', 'second' => '二', 'third' => '三' ]; + } + + return $result; + } +} diff --git a/src/composer/vendor/consolidation/annotated-command/tests/testAnnotatedCommand.php b/src/composer/vendor/consolidation/annotated-command/tests/testAnnotatedCommand.php new file mode 100644 index 00000000..098be138 --- /dev/null +++ b/src/composer/vendor/consolidation/annotated-command/tests/testAnnotatedCommand.php @@ -0,0 +1,45 @@ +assertInstanceOf('\Symfony\Component\Console\Command\Command', $command); + $this->assertEquals('my:cat', $command->getName()); + $this->assertEquals('This is the my:cat command implemented as an AnnotatedCommand subclass.', $command->getDescription()); + $this->assertEquals("This command will concatenate two parameters. If the --flip flag\nis provided, then the result is the concatenation of two and one.", $command->getHelp()); + $this->assertEquals('c', implode(',', $command->getAliases())); + // Symfony Console composes the synopsis; perhaps we should not test it. Remove if this gives false failures. + $this->assertEquals('my:cat [--flip] [--] []', $command->getSynopsis()); + $this->assertEquals('my:cat bet alpha --flip', implode(',', $command->getUsages())); + + $input = new StringInput('my:cat bet alpha --flip'); + $this->assertRunCommandViaApplicationEquals($command, $input, 'alphabet'); + } + + // TODO: Make a base test class to hold this. + function assertRunCommandViaApplicationEquals($command, $input, $expectedOutput, $expectedStatusCode = 0) + { + $output = new BufferedOutput(); + + $application = new Application('TestApplication', '0.0.0'); + $application->setAutoExit(false); + $application->add($command); + + $statusCode = $application->run($input, $output); + $commandOutput = trim($output->fetch()); + + $this->assertEquals($expectedOutput, $commandOutput); + $this->assertEquals($expectedStatusCode, $statusCode); + } +} diff --git a/src/composer/vendor/consolidation/annotated-command/tests/testAnnotatedCommandFactory.php b/src/composer/vendor/consolidation/annotated-command/tests/testAnnotatedCommandFactory.php new file mode 100644 index 00000000..1a0755d7 --- /dev/null +++ b/src/composer/vendor/consolidation/annotated-command/tests/testAnnotatedCommandFactory.php @@ -0,0 +1,639 @@ +commandFileInstance = new \Consolidation\TestUtils\ExampleCommandFile; + $this->commandFactory = new AnnotatedCommandFactory(); + $commandInfo = $this->commandFactory->createCommandInfo($this->commandFileInstance, 'testArithmatic'); + + $command = $this->commandFactory->createCommand($commandInfo, $this->commandFileInstance); + + $this->assertInstanceOf('\Symfony\Component\Console\Command\Command', $command); + $this->assertEquals('test:arithmatic', $command->getName()); + $this->assertEquals('This is the test:arithmatic command', $command->getDescription()); + $this->assertEquals("This command will add one and two. If the --negate flag\nis provided, then the result is negated.", $command->getHelp()); + $this->assertEquals('arithmatic', implode(',', $command->getAliases())); + $this->assertEquals('test:arithmatic [--negate] [--] ', $command->getSynopsis()); + $this->assertEquals('test:arithmatic 2 2 --negate', implode(',', $command->getUsages())); + + $input = new StringInput('arithmatic 2 3 --negate'); + $this->assertRunCommandViaApplicationEquals($command, $input, '-5'); + } + + /** + * Test CommandInfo command annotation altering. + */ + function testAnnotatedCommandInfoAlteration() + { + $this->commandFileInstance = new \Consolidation\TestUtils\ExampleCommandFile; + $this->commandFactory = new AnnotatedCommandFactory(); + $commandInfo = $this->commandFactory->createCommandInfo($this->commandFileInstance, 'myCat'); + + $command = $this->commandFactory->createCommand($commandInfo, $this->commandFileInstance); + + $annotationData = $command->getAnnotationData(); + $this->assertTrue($annotationData->has('arbitrary')); + $this->assertFalse($annotationData->has('dynamic')); + + $this->commandFactory->addCommandInfoAlterer(new ExampleCommandInfoAlterer()); + + $command = $this->commandFactory->createCommand($commandInfo, $this->commandFileInstance); + + $annotationData = $command->getAnnotationData(); + $this->assertTrue($annotationData->has('arbitrary')); + $this->assertTrue($annotationData->has('dynamic')); + } + + function testMyCatCommand() + { + $this->commandFileInstance = new \Consolidation\TestUtils\ExampleCommandFile; + $this->commandFactory = new AnnotatedCommandFactory(); + $commandInfo = $this->commandFactory->createCommandInfo($this->commandFileInstance, 'myCat'); + + $command = $this->commandFactory->createCommand($commandInfo, $this->commandFileInstance); + + $this->assertInstanceOf('\Symfony\Component\Console\Command\Command', $command); + $this->assertEquals('my:cat', $command->getName()); + $this->assertEquals('This is the my:cat command', $command->getDescription()); + $this->assertEquals("This command will concatenate two parameters. If the --flip flag\nis provided, then the result is the concatenation of two and one.", $command->getHelp()); + $this->assertEquals('c', implode(',', $command->getAliases())); + $this->assertEquals('my:cat [--flip] [--] []', $command->getSynopsis()); + $this->assertEquals('my:cat bet alpha --flip', implode(',', $command->getUsages())); + + $input = new StringInput('my:cat bet alpha --flip'); + $this->assertRunCommandViaApplicationEquals($command, $input, 'alphabet'); + } + + function testDefaultsCommand() + { + $this->commandFileInstance = new \Consolidation\TestUtils\ExampleCommandFile; + $this->commandFactory = new AnnotatedCommandFactory(); + $commandInfo = $this->commandFactory->createCommandInfo($this->commandFileInstance, 'defaults'); + + $command = $this->commandFactory->createCommand($commandInfo, $this->commandFileInstance); + + $this->assertInstanceOf('\Symfony\Component\Console\Command\Command', $command); + $this->assertEquals('defaults', $command->getName()); + $this->assertEquals('Test default values in arguments', $command->getDescription()); + + $input = new StringInput('defaults'); + $this->assertRunCommandViaApplicationEquals($command, $input, 'nothing provided'); + + $input = new StringInput('defaults ichi'); + $this->assertRunCommandViaApplicationEquals($command, $input, 'only ichi'); + + $input = new StringInput('defaults I II'); + $this->assertRunCommandViaApplicationEquals($command, $input, 'I and II'); + } + + function testCommandWithNoOptions() + { + $this->commandFileInstance = new \Consolidation\TestUtils\ExampleCommandFile; + $this->commandFactory = new AnnotatedCommandFactory(); + $commandInfo = $this->commandFactory->createCommandInfo($this->commandFileInstance, 'commandWithNoOptions'); + + $command = $this->commandFactory->createCommand($commandInfo, $this->commandFileInstance); + + $this->assertInstanceOf('\Symfony\Component\Console\Command\Command', $command); + $this->assertEquals('command:with-no-options', $command->getName()); + $this->assertEquals('This is a command with no options', $command->getDescription()); + $this->assertEquals("This command will concatenate two parameters.", $command->getHelp()); + $this->assertEquals('nope', implode(',', $command->getAliases())); + $this->assertEquals('command:with-no-options []', $command->getSynopsis()); + $this->assertEquals('command:with-no-options alpha bet', implode(',', $command->getUsages())); + + $input = new StringInput('command:with-no-options something'); + $this->assertRunCommandViaApplicationEquals($command, $input, 'somethingdefault'); + } + + function testCommandWithNoArguments() + { + $this->commandFileInstance = new \Consolidation\TestUtils\ExampleCommandFile; + $this->commandFactory = new AnnotatedCommandFactory(); + $commandInfo = $this->commandFactory->createCommandInfo($this->commandFileInstance, 'commandWithNoArguments'); + + $command = $this->commandFactory->createCommand($commandInfo, $this->commandFileInstance); + + $this->assertInstanceOf('\Symfony\Component\Console\Command\Command', $command); + $this->assertEquals('command:with-no-arguments', $command->getName()); + $this->assertEquals('This command has no arguments--only options', $command->getDescription()); + $this->assertEquals("Return a result only if not silent.", $command->getHelp()); + $this->assertEquals('command:with-no-arguments [-s|--silent]', $command->getSynopsis()); + + $input = new StringInput('command:with-no-arguments'); + $this->assertRunCommandViaApplicationEquals($command, $input, 'Hello, world'); + $input = new StringInput('command:with-no-arguments -s'); + $this->assertRunCommandViaApplicationEquals($command, $input, ''); + $input = new StringInput('command:with-no-arguments --silent'); + $this->assertRunCommandViaApplicationEquals($command, $input, ''); + } + + function testCommandWithShortcutOnAnnotation() + { + $this->commandFileInstance = new \Consolidation\TestUtils\ExampleCommandFile; + $this->commandFactory = new AnnotatedCommandFactory(); + $commandInfo = $this->commandFactory->createCommandInfo($this->commandFileInstance, 'shortcutOnAnnotation'); + + $command = $this->commandFactory->createCommand($commandInfo, $this->commandFileInstance); + + $this->assertInstanceOf('\Symfony\Component\Console\Command\Command', $command); + $this->assertEquals('shortcut:on-annotation', $command->getName()); + $this->assertEquals('Shortcut on annotation', $command->getDescription()); + $this->assertEquals("This command defines the option shortcut on the annotation instead of in the options array.", $command->getHelp()); + $this->assertEquals('shortcut:on-annotation [-s|--silent]', $command->getSynopsis()); + + $input = new StringInput('shortcut:on-annotation'); + $this->assertRunCommandViaApplicationEquals($command, $input, 'Hello, world'); + $input = new StringInput('shortcut:on-annotation -s'); + $this->assertRunCommandViaApplicationEquals($command, $input, ''); + $input = new StringInput('shortcut:on-annotation --silent'); + $this->assertRunCommandViaApplicationEquals($command, $input, ''); + } + + function testState() + { + $this->commandFileInstance = new \Consolidation\TestUtils\ExampleCommandFile('secret secret'); + $this->commandFactory = new AnnotatedCommandFactory(); + $commandInfo = $this->commandFactory->createCommandInfo($this->commandFileInstance, 'testState'); + + $command = $this->commandFactory->createCommand($commandInfo, $this->commandFileInstance); + + $this->assertInstanceOf('\Symfony\Component\Console\Command\Command', $command); + $this->assertEquals('test:state', $command->getName()); + + $input = new StringInput('test:state'); + $this->assertRunCommandViaApplicationEquals($command, $input, 'secret secret'); + } + + function testPassthroughArray() + { + $this->commandFileInstance = new \Consolidation\TestUtils\ExampleCommandFile; + $this->commandFactory = new AnnotatedCommandFactory(); + $commandInfo = $this->commandFactory->createCommandInfo($this->commandFileInstance, 'testPassthrough'); + + $command = $this->commandFactory->createCommand($commandInfo, $this->commandFileInstance); + + $this->assertInstanceOf('\Symfony\Component\Console\Command\Command', $command); + $this->assertEquals('test:passthrough', $command->getName()); + + $input = new StringInput('test:passthrough a b c -- x y z'); + $this->assertRunCommandViaApplicationEquals($command, $input, 'a,b,c,x,y,z'); + } + + function testPassThroughNonArray() + { + $this->commandFileInstance = new \Consolidation\TestUtils\ExampleCommandFile; + $this->commandFactory = new AnnotatedCommandFactory(); + $commandInfo = $this->commandFactory->createCommandInfo($this->commandFileInstance, 'myJoin'); + + $command = $this->commandFactory->createCommand($commandInfo, $this->commandFileInstance); + + $input = new StringInput('my:join bet --flip -- x y z'); + $this->assertRunCommandViaApplicationEquals($command, $input, 'zyxbet'); + // Can't look at 'hasOption' until after the command initializes the + // option, because Symfony. + $this->assertTrue($input->hasOption('flip')); + } + + function testPassThroughWithInputManipulation() + { + $this->commandFileInstance = new \Consolidation\TestUtils\ExampleCommandFile; + $this->commandFactory = new AnnotatedCommandFactory(); + $commandInfo = $this->commandFactory->createCommandInfo($this->commandFileInstance, 'myJoin'); + + $command = $this->commandFactory->createCommand($commandInfo, $this->commandFileInstance); + + $input = new StringInput('my:join bet --repeat=2 -- x y z'); + $this->assertRunCommandViaApplicationEquals($command, $input, 'betxyzbetxyz'); + // Symfony does not allow us to manipulate the options via setOption until + // the definition from the command object has been set up. + $input->setOption('repeat', 3); + $this->assertEquals(3, $input->getOption('repeat')); + $input->setArgument(0, 'q'); + // Manipulating $input does not work -- the changes are not effective. + // The end result here should be 'qx y yqx y yqx y y' + $this->assertRunCommandViaApplicationEquals($command, $input, 'betxyzbetxyz'); + } + + function testHookedCommand() + { + $this->commandFileInstance = new \Consolidation\TestUtils\ExampleCommandFile(); + $this->commandFactory = new AnnotatedCommandFactory(); + + $hookInfo = $this->commandFactory->createCommandInfo($this->commandFileInstance, 'hookTestHook'); + + $this->assertTrue($hookInfo->hasAnnotation('hook')); + $this->assertEquals('alter test:hook', $hookInfo->getAnnotation('hook')); + + $this->commandFactory->registerCommandHook($hookInfo, $this->commandFileInstance); + + $hookCallback = $this->commandFactory->hookManager()->get('test:hook', [HookManager::ALTER_RESULT]); + $this->assertTrue($hookCallback != null); + $this->assertEquals(1, count($hookCallback)); + $this->assertEquals(2, count($hookCallback[0])); + $this->assertTrue(is_callable($hookCallback[0])); + $this->assertEquals('hookTestHook', $hookCallback[0][1]); + + $commandInfo = $this->commandFactory->createCommandInfo($this->commandFileInstance, 'testHook'); + $command = $this->commandFactory->createCommand($commandInfo, $this->commandFileInstance); + + $this->assertInstanceOf('\Symfony\Component\Console\Command\Command', $command); + $this->assertEquals('test:hook', $command->getName()); + + $input = new StringInput('test:hook bar'); + $this->assertRunCommandViaApplicationEquals($command, $input, '<[bar]>'); + } + + function testPostCommandCalledAfterCommand() + { + $this->commandFileInstance = new \Consolidation\TestUtils\ExampleCommandFile(); + $this->commandFactory = new AnnotatedCommandFactory(); + + $hookInfo = $this->commandFactory->createCommandInfo($this->commandFileInstance, 'hookTestPostCommandHook'); + + $this->assertTrue($hookInfo->hasAnnotation('hook')); + $this->assertEquals('post-command test:post-command', $hookInfo->getAnnotation('hook')); + + $this->commandFactory->registerCommandHook($hookInfo, $this->commandFileInstance); + + $hookCallback = $this->commandFactory->hookManager()->get('test:post-command', [HookManager::POST_COMMAND_HOOK]); + $this->assertTrue($hookCallback != null); + $this->assertEquals(1, count($hookCallback)); + $this->assertEquals(2, count($hookCallback[0])); + $this->assertTrue(is_callable($hookCallback[0])); + $this->assertEquals('hookTestPostCommandHook', $hookCallback[0][1]); + + $hookInfo = $this->commandFactory->createCommandInfo($this->commandFileInstance, 'hookTestPreCommandHook'); + + $this->assertTrue($hookInfo->hasAnnotation('hook')); + $this->assertEquals('pre-command test:post-command', $hookInfo->getAnnotation('hook')); + + $this->commandFactory->registerCommandHook($hookInfo, $this->commandFileInstance); + + $hookCallback = $this->commandFactory->hookManager()->get('test:post-command', [HookManager::PRE_COMMAND_HOOK]); + $this->assertTrue($hookCallback != null); + $this->assertEquals(1, count($hookCallback)); + $this->assertEquals(2, count($hookCallback[0])); + $this->assertTrue(is_callable($hookCallback[0])); + $this->assertEquals('hookTestPreCommandHook', $hookCallback[0][1]); + + $commandInfo = $this->commandFactory->createCommandInfo($this->commandFileInstance, 'testPostCommand'); + $command = $this->commandFactory->createCommand($commandInfo, $this->commandFileInstance); + + $this->assertInstanceOf('\Symfony\Component\Console\Command\Command', $command); + $this->assertEquals('test:post-command', $command->getName()); + + $input = new StringInput('test:post-command bar'); + $this->assertRunCommandViaApplicationEquals($command, $input, "foo\nbar\nbaz", 0, $this->commandFileInstance); + } + + function testHookAllCommands() + { + $this->commandFileInstance = new \Consolidation\TestUtils\ExampleHookAllCommandFile(); + $this->commandFactory = new AnnotatedCommandFactory(); + + $hookInfo = $this->commandFactory->createCommandInfo($this->commandFileInstance, 'alterAllCommands'); + + $this->assertTrue($hookInfo->hasAnnotation('hook')); + $this->assertEquals('alter', $hookInfo->getAnnotation('hook')); + + $this->commandFactory->registerCommandHook($hookInfo, $this->commandFileInstance); + + $hookCallback = $this->commandFactory->hookManager()->get('Consolidation\TestUtils\ExampleHookAllCommandFile', [HookManager::ALTER_RESULT]); + $this->assertTrue($hookCallback != null); + $this->assertEquals(1, count($hookCallback)); + $this->assertEquals(2, count($hookCallback[0])); + $this->assertTrue(is_callable($hookCallback[0])); + $this->assertEquals('alterAllCommands', $hookCallback[0][1]); + + $commandInfo = $this->commandFactory->createCommandInfo($this->commandFileInstance, 'doCat'); + $command = $this->commandFactory->createCommand($commandInfo, $this->commandFileInstance); + + $this->assertInstanceOf('\Symfony\Component\Console\Command\Command', $command); + $this->assertEquals('do:cat', $command->getName()); + + $input = new StringInput('do:cat bar'); + $this->assertRunCommandViaApplicationEquals($command, $input, '*** bar ***'); + } + + function testAnnotatedHookedCommand() + { + $this->commandFileInstance = new \Consolidation\TestUtils\ExampleCommandFile(); + $this->commandFactory = new AnnotatedCommandFactory(); + + $hookInfo = $this->commandFactory->createCommandInfo($this->commandFileInstance, 'hookTestAnnotatedHook'); + + $this->assertTrue($hookInfo->hasAnnotation('hook')); + $this->assertEquals('alter @hookme', $hookInfo->getAnnotation('hook')); + + $this->commandFactory->registerCommandHook($hookInfo, $this->commandFileInstance); + $hookCallback = $this->commandFactory->hookManager()->get('@hookme', [HookManager::ALTER_RESULT]); + $this->assertTrue($hookCallback != null); + $this->assertEquals(1, count($hookCallback)); + $this->assertEquals(2, count($hookCallback[0])); + $this->assertTrue(is_callable($hookCallback[0])); + $this->assertEquals('hookTestAnnotatedHook', $hookCallback[0][1]); + + $commandInfo = $this->commandFactory->createCommandInfo($this->commandFileInstance, 'testAnnotationHook'); + $annotationData = $commandInfo->getRawAnnotations(); + $this->assertEquals('hookme,before,after', implode(',', $annotationData->keys())); + $this->assertEquals('@hookme,@before,@after', implode(',', array_map(function ($item) { return "@$item"; }, $annotationData->keys()))); + + $command = $this->commandFactory->createCommand($commandInfo, $this->commandFileInstance); + + $this->assertInstanceOf('\Symfony\Component\Console\Command\Command', $command); + $this->assertEquals('test:annotation-hook', $command->getName()); + + $input = new StringInput('test:annotation-hook baz'); + $this->assertRunCommandViaApplicationEquals($command, $input, '>(baz)<'); + } + + function testHookHasCommandAnnotation() + { + $this->commandFileInstance = new \Consolidation\TestUtils\ExampleCommandFile(); + $this->commandFactory = new AnnotatedCommandFactory(); + + $hookInfo = $this->commandFactory->createCommandInfo($this->commandFileInstance, 'hookAddCommandName'); + + $this->assertTrue($hookInfo->hasAnnotation('hook')); + $this->assertEquals('alter @addmycommandname', $hookInfo->getAnnotation('hook')); + + $this->commandFactory->registerCommandHook($hookInfo, $this->commandFileInstance); + $hookCallback = $this->commandFactory->hookManager()->get('@addmycommandname', [HookManager::ALTER_RESULT]); + $this->assertTrue($hookCallback != null); + $this->assertEquals(1, count($hookCallback)); + $this->assertEquals(2, count($hookCallback[0])); + $this->assertTrue(is_callable($hookCallback[0])); + $this->assertEquals('hookAddCommandName', $hookCallback[0][1]); + + $commandInfo = $this->commandFactory->createCommandInfo($this->commandFileInstance, 'alterMe'); + $annotationData = $commandInfo->getRawAnnotations(); + $this->assertEquals('command,addmycommandname', implode(',', $annotationData->keys())); + + $command = $this->commandFactory->createCommand($commandInfo, $this->commandFileInstance); + + $this->assertInstanceOf('\Symfony\Component\Console\Command\Command', $command); + $this->assertEquals('alter-me', $command->getName()); + + $input = new StringInput('alter-me'); + $this->assertRunCommandViaApplicationEquals($command, $input, 'splendiferous from alter-me'); + + $commandInfo = $this->commandFactory->createCommandInfo($this->commandFileInstance, 'alterMeToo'); + $annotationData = $commandInfo->getRawAnnotations(); + $this->assertEquals('addmycommandname', implode(',', $annotationData->keys())); + $annotationData = $commandInfo->getAnnotations(); + $this->assertEquals('addmycommandname,command', implode(',', $annotationData->keys())); + + $command = $this->commandFactory->createCommand($commandInfo, $this->commandFileInstance); + + $this->assertInstanceOf('\Symfony\Component\Console\Command\Command', $command); + $this->assertEquals('alter:me-too', $command->getName()); + + $input = new StringInput('alter:me-too'); + $this->assertRunCommandViaApplicationEquals($command, $input, 'fantabulous from alter:me-too'); + } + + + function testHookedCommandWithHookAddedLater() + { + $this->commandFileInstance = new \Consolidation\TestUtils\ExampleCommandFile(); + $this->commandFactory = new AnnotatedCommandFactory(); + $commandInfo = $this->commandFactory->createCommandInfo($this->commandFileInstance, 'testHook'); + + $command = $this->commandFactory->createCommand($commandInfo, $this->commandFileInstance); + + $this->assertInstanceOf('\Symfony\Component\Console\Command\Command', $command); + $this->assertEquals('test:hook', $command->getName()); + + // Run the command once without the hook + $input = new StringInput('test:hook foo'); + $this->assertRunCommandViaApplicationEquals($command, $input, '[foo]'); + + // Register the hook and run the command again + $hookInfo = $this->commandFactory->createCommandInfo($this->commandFileInstance, 'hookTestHook'); + + $this->assertTrue($hookInfo->hasAnnotation('hook')); + $this->assertEquals('alter test:hook', $hookInfo->getAnnotation('hook')); + + $this->commandFactory->registerCommandHook($hookInfo, $this->commandFileInstance); + $hookCallback = $this->commandFactory->hookManager()->get('test:hook', [HookManager::ALTER_RESULT]);; + $this->assertTrue($hookCallback != null); + $this->assertEquals(1, count($hookCallback)); + $this->assertEquals(2, count($hookCallback[0])); + $this->assertTrue(is_callable($hookCallback[0])); + $this->assertEquals('hookTestHook', $hookCallback[0][1]); + + $input = new StringInput('test:hook bar'); + $this->assertRunCommandViaApplicationEquals($command, $input, '<[bar]>'); + } + + function testInitializeHook() + { + $this->commandFileInstance = new \Consolidation\TestUtils\ExampleCommandFile(); + $this->commandFactory = new AnnotatedCommandFactory(); + + $hookInfo = $this->commandFactory->createCommandInfo($this->commandFileInstance, 'initializeTestHello'); + + $this->assertTrue($hookInfo->hasAnnotation('hook')); + $this->assertEquals($hookInfo->getAnnotation('hook'), 'init test:hello'); + + $this->commandFactory->registerCommandHook($hookInfo, $this->commandFileInstance); + + $hookCallback = $this->commandFactory->hookManager()->get('test:hello', [HookManager::INITIALIZE]); + $this->assertTrue($hookCallback != null); + $this->assertEquals(1, count($hookCallback)); + $this->assertEquals(2, count($hookCallback[0])); + $this->assertTrue(is_callable($hookCallback[0])); + $this->assertEquals('initializeTestHello', $hookCallback[0][1]); + + $commandInfo = $this->commandFactory->createCommandInfo($this->commandFileInstance, 'testHello'); + $command = $this->commandFactory->createCommand($commandInfo, $this->commandFileInstance); + + $this->assertInstanceOf('\Symfony\Component\Console\Command\Command', $command); + $this->assertEquals('test:hello', $command->getName()); + $commandGetNames = $this->callProtected($command, 'getNames'); + $this->assertEquals('test:hello,Consolidation\TestUtils\ExampleCommandFile', implode(',', $commandGetNames)); + + $hookCallback = $command->commandProcessor()->hookManager()->get('test:hello', 'init'); + $this->assertTrue($hookCallback != null); + $this->assertEquals('initializeTestHello', $hookCallback[0][1]); + + $input = new StringInput('test:hello'); + $this->assertRunCommandViaApplicationEquals($command, $input, "Hello, Huey."); + } + + function testCommandEventHook() + { + $this->commandFileInstance = new \Consolidation\TestUtils\ExampleCommandFile(); + $this->commandFactory = new AnnotatedCommandFactory(); + + $hookInfo = $this->commandFactory->createCommandInfo($this->commandFileInstance, 'commandEventTestHello'); + + $this->assertTrue($hookInfo->hasAnnotation('hook')); + $this->assertEquals($hookInfo->getAnnotation('hook'), 'command-event test:hello'); + + $this->commandFactory->registerCommandHook($hookInfo, $this->commandFileInstance); + + $hookCallback = $this->commandFactory->hookManager()->get('test:hello', [HookManager::COMMAND_EVENT]); + $this->assertTrue($hookCallback != null); + $this->assertEquals(1, count($hookCallback)); + $this->assertEquals(2, count($hookCallback[0])); + $this->assertTrue(is_callable($hookCallback[0])); + $this->assertEquals('commandEventTestHello', $hookCallback[0][1]); + + $commandInfo = $this->commandFactory->createCommandInfo($this->commandFileInstance, 'testHello'); + $command = $this->commandFactory->createCommand($commandInfo, $this->commandFileInstance); + + $this->assertInstanceOf('\Symfony\Component\Console\Command\Command', $command); + $this->assertEquals('test:hello', $command->getName()); + $commandGetNames = $this->callProtected($command, 'getNames'); + $this->assertEquals('test:hello,Consolidation\TestUtils\ExampleCommandFile', implode(',', $commandGetNames)); + + $hookCallback = $command->commandProcessor()->hookManager()->get('test:hello', 'command-event'); + $this->assertTrue($hookCallback != null); + $this->assertEquals('commandEventTestHello', $hookCallback[0][1]); + + $input = new StringInput('test:hello Pluto'); + $this->assertRunCommandViaApplicationEquals($command, $input, "Here comes Pluto!\nHello, Pluto."); + } + + + function testInteractAndValidate() + { + $this->commandFileInstance = new \Consolidation\TestUtils\ExampleCommandFile(); + $this->commandFactory = new AnnotatedCommandFactory(); + + $hookInfo = $this->commandFactory->createCommandInfo($this->commandFileInstance, 'interactTestHello'); + + $this->assertTrue($hookInfo->hasAnnotation('hook')); + $this->assertEquals($hookInfo->getAnnotation('hook'), 'interact test:hello'); + + $this->commandFactory->registerCommandHook($hookInfo, $this->commandFileInstance); + + $hookInfo = $this->commandFactory->createCommandInfo($this->commandFileInstance, 'validateTestHello'); + + $this->assertTrue($hookInfo->hasAnnotation('hook')); + $this->assertEquals($hookInfo->getAnnotation('hook'), 'validate test:hello'); + + $this->commandFactory->registerCommandHook($hookInfo, $this->commandFileInstance); + + $hookCallback = $this->commandFactory->hookManager()->get('test:hello', [HookManager::ARGUMENT_VALIDATOR]); + $this->assertTrue($hookCallback != null); + $this->assertEquals(1, count($hookCallback)); + $this->assertEquals(2, count($hookCallback[0])); + $this->assertTrue(is_callable($hookCallback[0])); + $this->assertEquals('validateTestHello', $hookCallback[0][1]); + + $hookCallback = $this->commandFactory->hookManager()->get('test:hello', [HookManager::INTERACT]); + $this->assertTrue($hookCallback != null); + $this->assertEquals(1, count($hookCallback)); + $this->assertEquals(2, count($hookCallback[0])); + $this->assertTrue(is_callable($hookCallback[0])); + $this->assertEquals('interactTestHello', $hookCallback[0][1]); + + $commandInfo = $this->commandFactory->createCommandInfo($this->commandFileInstance, 'testHello'); + $command = $this->commandFactory->createCommand($commandInfo, $this->commandFileInstance); + + $this->assertInstanceOf('\Symfony\Component\Console\Command\Command', $command); + $this->assertEquals('test:hello', $command->getName()); + $commandGetNames = $this->callProtected($command, 'getNames'); + $this->assertEquals('test:hello,Consolidation\TestUtils\ExampleCommandFile', implode(',', $commandGetNames)); + + $testInteractInput = new StringInput('test:hello'); + $definition = new \Symfony\Component\Console\Input\InputDefinition( + [ + new \Symfony\Component\Console\Input\InputArgument('application', \Symfony\Component\Console\Input\InputArgument::REQUIRED), + new \Symfony\Component\Console\Input\InputArgument('who', \Symfony\Component\Console\Input\InputArgument::REQUIRED), + ] + ); + $testInteractInput->bind($definition); + $testInteractOutput = new BufferedOutput(); + $command->commandProcessor()->interact( + $testInteractInput, + $testInteractOutput, + $commandGetNames, + $command->getAnnotationData() + ); + $this->assertEquals('Goofey', $testInteractInput->getArgument('who')); + + $hookCallback = $command->commandProcessor()->hookManager()->get('test:hello', 'interact'); + $this->assertTrue($hookCallback != null); + $this->assertEquals('interactTestHello', $hookCallback[0][1]); + + $input = new StringInput('test:hello "Mickey Mouse"'); + $this->assertRunCommandViaApplicationEquals($command, $input, 'Hello, Mickey Mouse.'); + + $input = new StringInput('test:hello'); + $this->assertRunCommandViaApplicationEquals($command, $input, 'Hello, Goofey.'); + + $input = new StringInput('test:hello "Donald Duck"'); + $this->assertRunCommandViaApplicationEquals($command, $input, "I won't say hello to Donald Duck.", 1); + + $input = new StringInput('test:hello "Drumph"'); + $this->assertRunCommandViaApplicationEquals($command, $input, "Irrational value error.", 1); + + // Try the last test again with a display error function installed. + $this->commandFactory->commandProcessor()->setDisplayErrorFunction( + function ($output, $message) { + $output->writeln("*** $message ****"); + } + ); + + $input = new StringInput('test:hello "Drumph"'); + $this->assertRunCommandViaApplicationEquals($command, $input, "*** Irrational value error. ****", 1); + } + + function callProtected($object, $method, $args = []) + { + $r = new \ReflectionMethod($object, $method); + $r->setAccessible(true); + return $r->invokeArgs($object, $args); + } + + function assertRunCommandViaApplicationEquals($command, $input, $expectedOutput, $expectedStatusCode = 0) + { + $output = new BufferedOutput(); + if ($this->commandFileInstance && method_exists($this->commandFileInstance, 'setOutput')) { + $this->commandFileInstance->setOutput($output); + } + + $application = new Application('TestApplication', '0.0.0'); + $alterOptionsEventManager = new AlterOptionsCommandEvent($application); + + $eventDispatcher = new \Symfony\Component\EventDispatcher\EventDispatcher(); + $eventDispatcher->addSubscriber($this->commandFactory->commandProcessor()->hookManager()); + $eventDispatcher->addSubscriber($alterOptionsEventManager); + $application->setDispatcher($eventDispatcher); + + $application->setAutoExit(false); + $application->add($command); + + $statusCode = $application->run($input, $output); + $commandOutput = trim($output->fetch()); + + $this->assertEquals($expectedOutput, $commandOutput); + $this->assertEquals($expectedStatusCode, $statusCode); + } +} diff --git a/src/composer/vendor/consolidation/annotated-command/tests/testCommandFileDiscovery.php b/src/composer/vendor/consolidation/annotated-command/tests/testCommandFileDiscovery.php new file mode 100644 index 00000000..c03c5ba6 --- /dev/null +++ b/src/composer/vendor/consolidation/annotated-command/tests/testCommandFileDiscovery.php @@ -0,0 +1,82 @@ +setSearchPattern('*CommandFile.php') + ->setSearchLocations(['alpha']); + + chdir(__DIR__); + $commandFiles = $discovery->discover('.', '\Consolidation\TestUtils'); + + $commandFilePaths = array_keys($commandFiles); + $commandFileNamespaces = array_values($commandFiles); + + // Ensure that the command files that we expected to + // find were all found. We don't find anything in + // 'beta' because only 'alpha' is in the search path. + $this->assertContains('./src/ExampleCommandFile.php', $commandFilePaths); + $this->assertContains('./src/ExampleHookAllCommandFile.php', $commandFilePaths); + $this->assertContains('./src/alpha/AlphaCommandFile.php', $commandFilePaths); + $this->assertContains('./src/alpha/Inclusive/IncludedCommandFile.php', $commandFilePaths); + + // Make sure that there are no additional items found. + $this->assertEquals(4, count($commandFilePaths)); + + // Ensure that the command file namespaces that we expected + // to be generated all match. + $this->assertContains('\Consolidation\TestUtils\ExampleCommandFile', $commandFileNamespaces); + $this->assertContains('\Consolidation\TestUtils\ExampleHookAllCommandFile', $commandFileNamespaces); + $this->assertContains('\Consolidation\TestUtils\alpha\AlphaCommandFile', $commandFileNamespaces); + $this->assertContains('\Consolidation\TestUtils\alpha\Inclusive\IncludedCommandFile', $commandFileNamespaces); + + // We do not need to test for additional namespace items, because we + // know that the length of the array_keys must be the same as the + // length of the array_values. + } + + function testDeepCommandDiscovery() + { + $discovery = new CommandFileDiscovery(); + $discovery + ->setSearchPattern('*CommandFile.php') + ->setSearchDepth(1) + ->setSearchLocations([]); + + chdir(__DIR__); + $commandFiles = $discovery->discover('.', '\Consolidation\TestUtils'); + + $commandFilePaths = array_keys($commandFiles); + $commandFileNamespaces = array_values($commandFiles); + + // Ensure that the command files that we expected to + // find were all found. We find both 'alpha' and 'beta' + // items because the search locations is empty, which + // causes the search at the base directory to be deep. + // We do not find alpha/Inclusive, though, as the search + // depth is only 2, which excludes directories that are + // three levels deep. + $this->assertContains('./src/ExampleCommandFile.php', $commandFilePaths); + $this->assertContains('./src/ExampleHookAllCommandFile.php', $commandFilePaths); + $this->assertContains('./src/alpha/AlphaCommandFile.php', $commandFilePaths); + $this->assertContains('./src/beta/BetaCommandFile.php', $commandFilePaths); + + // Make sure that there are no additional items found. + $this->assertEquals(4, count($commandFilePaths)); + + // Ensure that the command file namespaces that we expected + // to be generated all match. + $this->assertContains('\Consolidation\TestUtils\ExampleCommandFile', $commandFileNamespaces); + $this->assertContains('\Consolidation\TestUtils\ExampleHookAllCommandFile', $commandFileNamespaces); + $this->assertContains('\Consolidation\TestUtils\alpha\AlphaCommandFile', $commandFileNamespaces); + $this->assertContains('\Consolidation\TestUtils\beta\BetaCommandFile', $commandFileNamespaces); + + // We do not need to test for additional namespace items, because we + // know that the length of the array_keys must be the same as the + // length of the array_values. + } +} diff --git a/src/composer/vendor/consolidation/annotated-command/tests/testCommandInfo.php b/src/composer/vendor/consolidation/annotated-command/tests/testCommandInfo.php new file mode 100644 index 00000000..29fb2ebf --- /dev/null +++ b/src/composer/vendor/consolidation/annotated-command/tests/testCommandInfo.php @@ -0,0 +1,61 @@ + $value) { + if (!is_string($value)) { + $value = var_export($value, true); + } + $result[] = "{$key}=>{$value}"; + } + return implode("\n", $result); + } + + /** + * Test CommandInfo command annotation parsing. + */ + function testParsing() + { + $commandInfo = new CommandInfo('\Consolidation\TestUtils\ExampleCommandFile', 'testArithmatic'); + + $this->assertEquals('test:arithmatic', $commandInfo->getName()); + $this->assertEquals( + 'This is the test:arithmatic command', + $commandInfo->getDescription() + ); + $this->assertEquals( + "This command will add one and two. If the --negate flag\nis provided, then the result is negated.", + $commandInfo->getHelp() + ); + $this->assertEquals('arithmatic', implode(',', $commandInfo->getAliases())); + $this->assertEquals( + '2 2 --negate=>Add two plus two and then negate.', + $this->flattenArray($commandInfo->getExampleUsages()) + ); + $this->assertEquals( + 'The first number to add.', + $commandInfo->arguments()->getDescription('one') + ); + $this->assertEquals( + 'The other number to add.', + $commandInfo->arguments()->getDescription('two') + ); + $this->assertEquals( + 'Whether or not the result should be negated.', + $commandInfo->options()->getDescription('negate') + ); + } + + function testReturnValue() + { + $commandInfo = new CommandInfo('\Consolidation\TestUtils\alpha\AlphaCommandFile', 'exampleTable'); + $this->assertEquals('example:table', $commandInfo->getName()); + $this->assertEquals('\Consolidation\OutputFormatters\StructuredData\RowsOfFields', $commandInfo->getReturnType()); + } +} diff --git a/src/composer/vendor/consolidation/annotated-command/tests/testFullStack.php b/src/composer/vendor/consolidation/annotated-command/tests/testFullStack.php new file mode 100644 index 00000000..8f3e10ad --- /dev/null +++ b/src/composer/vendor/consolidation/annotated-command/tests/testFullStack.php @@ -0,0 +1,508 @@ +application = new ApplicationWithTerminalWidth('TestApplication', '0.0.0'); + $this->commandFactory = new AnnotatedCommandFactory(); + $alterOptionsEventManager = new AlterOptionsCommandEvent($this->application); + $eventDispatcher = new \Symfony\Component\EventDispatcher\EventDispatcher(); + $eventDispatcher->addSubscriber($this->commandFactory->commandProcessor()->hookManager()); + $eventDispatcher->addSubscriber($alterOptionsEventManager); + $this->application->setDispatcher($eventDispatcher); + $this->application->setAutoExit(false); + } + + function testValidFormats() + { + $formatter = new FormatterManager(); + $formatter->addDefaultFormatters(); + $formatter->addDefaultSimplifiers(); + $commandInfo = new CommandInfo('\Consolidation\TestUtils\alpha\AlphaCommandFile', 'exampleTable'); + $this->assertEquals('example:table', $commandInfo->getName()); + $this->assertEquals('\Consolidation\OutputFormatters\StructuredData\RowsOfFields', $commandInfo->getReturnType()); + } + + function testAutomaticOptions() + { + $commandFileInstance = new \Consolidation\TestUtils\alpha\AlphaCommandFile; + $formatter = new FormatterManager(); + $formatter->addDefaultFormatters(); + $formatter->addDefaultSimplifiers(); + + $this->commandFactory->commandProcessor()->setFormatterManager($formatter); + $commandInfo = $this->commandFactory->createCommandInfo($commandFileInstance, 'exampleTable'); + + $command = $this->commandFactory->createCommand($commandInfo, $commandFileInstance); + $this->application->add($command); + + $containsList = + [ + '--format[=FORMAT] Format the result data. Available formats: csv,json,list,php,print-r,sections,string,table,tsv,var_export,xml,yaml [default: "table"]', + '--fields[=FIELDS] Available fields: I (first), II (second), III (third) [default: ""]', + ]; + $this->assertRunCommandViaApplicationContains('help example:table', $containsList); + } + + function testCommandsAndHooks() + { + // First, search for commandfiles in the 'alpha' + // directory. Note that this same functionality + // is tested more thoroughly in isolation in + // testCommandFileDiscovery.php + $discovery = new CommandFileDiscovery(); + $discovery + ->setSearchPattern('*CommandFile.php') + ->setIncludeFilesAtBase(false) + ->setSearchLocations(['alpha']); + + chdir(__DIR__); + $commandFiles = $discovery->discover('.', '\Consolidation\TestUtils'); + + $formatter = new FormatterManager(); + $formatter->addDefaultFormatters(); + $formatter->addDefaultSimplifiers(); + $hookManager = new HookManager(); + $terminalWidthOption = new PrepareTerminalWidthOption(); + $terminalWidthOption->setApplication($this->application); + $commandProcessor = new CommandProcessor($hookManager); + $commandProcessor->setFormatterManager($formatter); + $commandProcessor->addPrepareFormatter($terminalWidthOption); + + // Create a new factory, and load all of the files + // discovered above. The command factory class is + // tested in isolation in testAnnotatedCommandFactory.php, + // but this is the only place where + $factory = new AnnotatedCommandFactory(); + $factory->setCommandProcessor($commandProcessor); + // $factory->addListener(...); + $factory->setIncludeAllPublicMethods(false); + $this->addDiscoveredCommands($factory, $commandFiles); + + $this->assertRunCommandViaApplicationContains('list', ['example:table'], ['additional:option', 'without:annotations']); + + $this->assertTrue($this->application->has('example:table')); + $this->assertFalse($this->application->has('without:annotations')); + + // Fetch a reference to the 'example:table' command and test its valid format types + $exampleTableCommand = $this->application->find('example:table'); + $returnType = $exampleTableCommand->getReturnType(); + $this->assertEquals('\Consolidation\OutputFormatters\StructuredData\RowsOfFields', $returnType); + $validFormats = $formatter->validFormats($returnType); + $this->assertEquals('csv,json,list,php,print-r,sections,string,table,tsv,var_export,xml,yaml', implode(',', $validFormats)); + + // Control: run commands without hooks. + $this->assertRunCommandViaApplicationEquals('always:fail', 'This command always fails.', 13); + $this->assertRunCommandViaApplicationEquals('simulated:status', '42'); + $this->assertRunCommandViaApplicationEquals('example:output', 'Hello, World.'); + $this->assertRunCommandViaApplicationEquals('example:cat bet alpha --flip', 'alphabet'); + $this->assertRunCommandViaApplicationEquals('example:echo a b c', "a\tb\tc"); + $this->assertRunCommandViaApplicationEquals('example:message', 'Shipwrecked; send bananas.'); + $this->assertRunCommandViaApplicationEquals('command:with-one-optional-argument', 'Hello, world'); + $this->assertRunCommandViaApplicationEquals('command:with-one-optional-argument Joe', 'Hello, Joe'); + + // Add some hooks. + $factory->hookManager()->addValidator(new ExampleValidator()); + $factory->hookManager()->addResultProcessor(new ExampleResultProcessor()); + $factory->hookManager()->addAlterResult(new ExampleResultAlterer()); + $factory->hookManager()->addStatusDeterminer(new ExampleStatusDeterminer()); + $factory->hookManager()->addOutputExtractor(new ExampleOutputExtractor()); + + // Run the same commands as before, and confirm that results + // are different now that the hooks are in place. + $this->assertRunCommandViaApplicationEquals('simulated:status', '', 42); + $this->assertRunCommandViaApplicationEquals('example:output', 'Hello, World!'); + $this->assertRunCommandViaApplicationEquals('example:cat bet alpha --flip', 'alphareplaced'); + $this->assertRunCommandViaApplicationEquals('example:echo a b c', 'a,b,c'); + $this->assertRunCommandViaApplicationEquals('example:message', 'Shipwrecked; send bananas.'); + + $expected = <<assertRunCommandViaApplicationEquals('example:table', $expected); + + $expected = <<assertRunCommandViaApplicationEquals('example:table --fields=III,II', $expected); + + $expectedSingleField = <<assertRunCommandViaApplicationEquals('example:table --field=II', $expectedSingleField); + + // Check the help for the example table command and see if the options + // from the alter hook were added. We expect that we should not see + // any of the information from the alter hook in the 'beta' folder yet. + $this->assertRunCommandViaApplicationContains('help example:table', + [ + 'Option added by @hook option example:table', + 'example:table --french', + 'Add a row with French numbers.' + ], + [ + 'chinese', + 'kanji', + ] + ); + + $expectedOutputWithFrench = <<assertRunCommandViaApplicationEquals('example:table --french', $expectedOutputWithFrench); + + $expectedAssociativeListTable = <<assertRunCommandViaApplicationEquals('example:list', $expectedAssociativeListTable); + $this->assertRunCommandViaApplicationEquals('example:list --field=sftp_command', 'sftp -o Port=2222 dev@appserver.dev.drush.in'); + + $this->assertRunCommandViaApplicationEquals('get:serious', 'very serious'); + $this->assertRunCommandViaApplicationContains('get:lost', 'Command "get:lost" is not defined.', [], 1); + + $this->assertRunCommandViaApplicationContains('help example:wrap', + [ + 'Test word wrapping', + '[default: "table"]', + ] + ); + + $expectedUnwrappedOutput = <<application->setWidthAndHeight(0, 0); + $this->assertRunCommandViaApplicationEquals('example:wrap', $expectedUnwrappedOutput); + + $expectedWrappedOutput = <<application->setWidthAndHeight(42, 24); + $this->assertRunCommandViaApplicationEquals('example:wrap', $expectedWrappedOutput); + } + + function testCommandsAndHooksIncludeAllPublicMethods() + { + // First, search for commandfiles in the 'alpha' + // directory. Note that this same functionality + // is tested more thoroughly in isolation in + // testCommandFileDiscovery.php + $discovery = new CommandFileDiscovery(); + $discovery + ->setSearchPattern('*CommandFile.php') + ->setIncludeFilesAtBase(false) + ->setSearchLocations(['alpha']); + + chdir(__DIR__); + $commandFiles = $discovery->discover('.', '\Consolidation\TestUtils'); + + $formatter = new FormatterManager(); + $formatter->addDefaultFormatters(); + $formatter->addDefaultSimplifiers(); + $hookManager = new HookManager(); + $commandProcessor = new CommandProcessor($hookManager); + $commandProcessor->setFormatterManager($formatter); + + // Create a new factory, and load all of the files + // discovered above. The command factory class is + // tested in isolation in testAnnotatedCommandFactory.php, + // but this is the only place where + $factory = new AnnotatedCommandFactory(); + $factory->setCommandProcessor($commandProcessor); + // $factory->addListener(...); + + // Now we will once again add all commands, this time including all + // public methods. The command 'withoutAnnotations' should now be found. + $factory->setIncludeAllPublicMethods(true); + $this->addDiscoveredCommands($factory, $commandFiles); + $this->assertTrue($this->application->has('without:annotations')); + + $this->assertRunCommandViaApplicationContains('list', ['example:table', 'without:annotations'], ['alter:formatters']); + + $this->assertRunCommandViaApplicationEquals('get:serious', 'very serious'); + $this->assertRunCommandViaApplicationContains('get:lost', 'Command "get:lost" is not defined.', [], 1); + } + + function testCommandsAndHooksWithBetaFolder() + { + // First, search for commandfiles in the 'alpha' + // directory. Note that this same functionality + // is tested more thoroughly in isolation in + // testCommandFileDiscovery.php + $discovery = new CommandFileDiscovery(); + $discovery + ->setSearchPattern('*CommandFile.php') + ->setIncludeFilesAtBase(false) + ->setSearchLocations(['alpha', 'beta']); + + chdir(__DIR__); + $commandFiles = $discovery->discover('.', '\Consolidation\TestUtils'); + + $formatter = new FormatterManager(); + $formatter->addDefaultFormatters(); + $formatter->addDefaultSimplifiers(); + $hookManager = new HookManager(); + $commandProcessor = new CommandProcessor($hookManager); + $commandProcessor->setFormatterManager($formatter); + + // Create a new factory, and load all of the files + // discovered above. The command factory class is + // tested in isolation in testAnnotatedCommandFactory.php, + // but this is the only place where + $factory = new AnnotatedCommandFactory(); + $factory->setCommandProcessor($commandProcessor); + // $factory->addListener(...); + $factory->setIncludeAllPublicMethods(true); + $this->addDiscoveredCommands($factory, $commandFiles); + + // A few asserts, to make sure that our hooks all get registered. + $allRegisteredHooks = $hookManager->getAllHooks(); + $registeredHookNames = array_keys($allRegisteredHooks); + sort($registeredHookNames); + $this->assertEquals('*,example:table', implode(',', $registeredHookNames)); + $allHooksForExampleTable = $allRegisteredHooks['example:table']; + $allHookPhasesForExampleTable = array_keys($allHooksForExampleTable); + sort($allHookPhasesForExampleTable); + $this->assertEquals('alter,option', implode(',', $allHookPhasesForExampleTable)); + + $this->assertContains('alterFormattersChinese', var_export($allHooksForExampleTable, true)); + + $alterHooksForExampleTable = $this->callProtected($hookManager, 'getHooks', [['example:table'], 'alter']); + $this->assertContains('alterFormattersKanji', var_export($alterHooksForExampleTable, true)); + + $allHooksForAnyCommand = $allRegisteredHooks['*']; + $allHookPhasesForAnyCommand = array_keys($allHooksForAnyCommand); + sort($allHookPhasesForAnyCommand); + $this->assertEquals('alter', implode(',', $allHookPhasesForAnyCommand)); + + $this->assertContains('alterFormattersKanji', var_export($allHooksForAnyCommand, true)); + + // Help should have the information from the hooks in the 'beta' folder + $this->assertRunCommandViaApplicationContains('help example:table', + [ + 'Option added by @hook option example:table', + 'example:table --french', + 'Add a row with French numbers.', + 'chinese', + 'kanji', + ] + ); + + // Confirm that the "unavailable" command is now available + $this->assertTrue($this->application->has('unavailable:command')); + + $expectedOutputWithChinese = <<assertRunCommandViaApplicationEquals('example:table --chinese', $expectedOutputWithChinese); + + $expectedOutputWithKanji = <<assertRunCommandViaApplicationEquals('example:table --kanji', $expectedOutputWithKanji); + } + + public function addDiscoveredCommands($factory, $commandFiles) { + foreach ($commandFiles as $path => $commandClass) { + $this->assertFileExists($path); + if (!class_exists($commandClass)) { + include $path; + } + $commandInstance = new $commandClass(); + $commandList = $factory->createCommandsFromClass($commandInstance); + foreach ($commandList as $command) { + $this->application->add($command); + } + } + } + + function assertRunCommandViaApplicationEquals($cmd, $expectedOutput, $expectedStatusCode = 0) + { + $input = new StringInput($cmd); + $output = new BufferedOutput(); + + $statusCode = $this->application->run($input, $output); + $commandOutput = trim($output->fetch()); + + $expectedOutput = $this->simplifyWhitespace($expectedOutput); + $commandOutput = $this->simplifyWhitespace($commandOutput); + + $this->assertEquals($expectedOutput, $commandOutput); + $this->assertEquals($expectedStatusCode, $statusCode); + } + + function assertRunCommandViaApplicationContains($cmd, $containsList, $doesNotContainList = [], $expectedStatusCode = 0) + { + $input = new StringInput($cmd); + $output = new BufferedOutput(); + $containsList = (array) $containsList; + + $statusCode = $this->application->run($input, $output); + $commandOutput = trim($output->fetch()); + + $commandOutput = $this->simplifyWhitespace($commandOutput); + + foreach ($containsList as $expectedToContain) { + $this->assertContains($this->simplifyWhitespace($expectedToContain), $commandOutput); + } + foreach ($doesNotContainList as $expectedToNotContain) { + $this->assertNotContains($this->simplifyWhitespace($expectedToNotContain), $commandOutput); + } + $this->assertEquals($expectedStatusCode, $statusCode); + } + + function simplifyWhitespace($data) + { + return trim(preg_replace('#[ \t]+$#m', '', $data)); + } + + function callProtected($object, $method, $args = []) + { + $r = new \ReflectionMethod($object, $method); + $r->setAccessible(true); + return $r->invokeArgs($object, $args); + } + +} + +class ExampleValidator implements ValidatorInterface +{ + public function validate(CommandData $commandData) + { + $args = $commandData->arguments(); + if (isset($args['one']) && ($args['one'] == 'bet')) { + $commandData->input()->setArgument('one', 'replaced'); + return $args; + } + } +} + +class ExampleResultProcessor implements ProcessResultInterface +{ + public function process($result, CommandData $commandData) + { + if (is_array($result) && array_key_exists('item-list', $result)) { + return implode(',', $result['item-list']); + } + } +} + +class ExampleResultAlterer implements AlterResultInterface +{ + public function process($result, CommandData $commandData) + { + if (is_string($result) && ($result == 'Hello, World.')) { + return 'Hello, World!'; + } + } +} + +class ExampleStatusDeterminer implements StatusDeterminerInterface +{ + public function determineStatusCode($result) + { + if (is_array($result) && array_key_exists('status-code', $result)) { + return $result['status-code']; + } + } +} + +class ExampleOutputExtractor implements ExtractOutputInterface +{ + public function extractOutput($result) + { + if (is_array($result) && array_key_exists('message', $result)) { + return $result['message']; + } + } +} diff --git a/src/composer/vendor/consolidation/log/.gitignore b/src/composer/vendor/consolidation/log/.gitignore new file mode 100644 index 00000000..c1cea0a5 --- /dev/null +++ b/src/composer/vendor/consolidation/log/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +vendor +composer.lock diff --git a/src/composer/vendor/consolidation/log/LICENSE b/src/composer/vendor/consolidation/log/LICENSE new file mode 100644 index 00000000..2078bd88 --- /dev/null +++ b/src/composer/vendor/consolidation/log/LICENSE @@ -0,0 +1,8 @@ +Copyright (c) 2016 Consolidation Org Developers + + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/src/composer/vendor/consolidation/log/README.md b/src/composer/vendor/consolidation/log/README.md new file mode 100644 index 00000000..a11a8e8e --- /dev/null +++ b/src/composer/vendor/consolidation/log/README.md @@ -0,0 +1,33 @@ +# Consolidation\Log + +Improved Psr-3 / Psr\Log logger based on Symfony Console components. + +[![Circle CI](https://circleci.com/gh/consolidation-org/log.svg?style=svg)](https://circleci.com/gh/consolidation-org/log) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/consolidation-org/log/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/consolidation-org/log/?branch=master) [![Latest Stable Version](https://poser.pugx.org/consolidation/log/v/stable)](https://packagist.org/packages/consolidation/log) [![Total Downloads](https://poser.pugx.org/consolidation/log/downloads)](https://packagist.org/packages/consolidation/log) [![Latest Unstable Version](https://poser.pugx.org/consolidation/log/v/unstable)](https://packagist.org/packages/consolidation/log) [![License](https://poser.pugx.org/consolidation/log/license)](https://packagist.org/packages/consolidation/log) + +## Component Status + +In use in https://github.com/Codegyre/Robo + +## Motivation + +Consolication\Log provides a Psr-3 compatible logger that provides styled log output to the standard error (stderr) stream. By default, styling is provided by the SymfonyStyle class from the Symfony Console component; however, alternative stylers may be provided if desired. + +## Usage +``` +$logger = new \Consolidation\Log\Logger($output); +$logger->setLogOutputStyler(new LogOutputStyler()); // optional +$logger->warning('The file {name} does not exist.', ['name' => $filename]); +``` +n.b. Substitution of replacements, such as `{name}` in the example above, is not required by Psr-3' however, this is often done (e.g. in the Symfony Console logger). + +## Comparison to Existing Solutions + +Many Symfony Console compoenents use SymfonyStyle to format their output messages. This helper class has methods named things like `success` and `warning`, making it seem like a natural choice for reporting status. + +However, in practice it is much more convenient to use an actual Psr-3 logger for logging. Doing this allows a Symfony Console component to call an external library that may not need to depend on Symfony Style. Having the Psr\Log\LoggerInterface serve as the only shared IO-related interface in common between the console tool and the libraries it depends on promots loose coupling, allowing said libraries to be re-used in other contexts which may wish to log in different ways. + +Symfony Console provides the ConsoleLogger to fill this need; however, ConsoleLogger does not provide any facility for styling output, leaving SymfonyStyle as the preferred logging mechanism for style-conscienscious console coders. + +Consolidation\Log provides the benefits of both classes, allowing for code that both behaved technically correctly (redirecting to stderr) without sacrificing on style. + +Monlog also provides a full-featured Console logger that might be applicable for some use cases. diff --git a/src/composer/vendor/consolidation/log/circle.yml b/src/composer/vendor/consolidation/log/circle.yml new file mode 100644 index 00000000..2be28fa5 --- /dev/null +++ b/src/composer/vendor/consolidation/log/circle.yml @@ -0,0 +1,12 @@ +machine: + php: + version: 5.5.11 + hosts: + localhost: 127.0.0.1 + +test: + override: + - vendor/bin/phpcs --standard=PSR2 -n src + # See: https://circleci.com/docs/test-metadata#phpunit + - mkdir -p $CIRCLE_TEST_REPORTS/phpunit + - vendor/bin/phpunit --log-junit $CIRCLE_TEST_REPORTS/phpunit/junit.xml diff --git a/src/composer/vendor/consolidation/log/composer.json b/src/composer/vendor/consolidation/log/composer.json new file mode 100644 index 00000000..b6ba0018 --- /dev/null +++ b/src/composer/vendor/consolidation/log/composer.json @@ -0,0 +1,35 @@ +{ + "name": "consolidation/log", + "description": "Improved Psr-3 / Psr\\Log logger based on Symfony Console components.", + "license": "MIT", + "authors": [ + { + "name": "Greg Anderson", + "email": "greg.1.anderson@greenknowe.org" + } + ], + "autoload":{ + "psr-4":{ + "Consolidation\\Log\\": "src" + } + }, + "autoload-dev": { + "psr-4": { + "Consolidation\\TestUtils\\": "tests/src" + } + }, + "require": { + "php": ">=5.5.0", + "psr/log": "~1.0", + "symfony/console": "~2.5|~3.0" + }, + "require-dev": { + "phpunit/phpunit": "4.*", + "squizlabs/php_codesniffer": "2.*" + }, + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + } +} diff --git a/src/composer/vendor/consolidation/log/phpunit.xml.dist b/src/composer/vendor/consolidation/log/phpunit.xml.dist new file mode 100644 index 00000000..4c5e0b93 --- /dev/null +++ b/src/composer/vendor/consolidation/log/phpunit.xml.dist @@ -0,0 +1,7 @@ + + + + tests + + + diff --git a/src/composer/vendor/consolidation/log/src/ConsoleLogLevel.php b/src/composer/vendor/consolidation/log/src/ConsoleLogLevel.php new file mode 100644 index 00000000..013e9737 --- /dev/null +++ b/src/composer/vendor/consolidation/log/src/ConsoleLogLevel.php @@ -0,0 +1,25 @@ + + */ +class ConsoleLogLevel extends \Psr\Log\LogLevel +{ + /** + * Command successfully completed some operation. + * Displayed at VERBOSITY_NORMAL. + */ + const SUCCESS = 'success'; +} diff --git a/src/composer/vendor/consolidation/log/src/LogOutputStyler.php b/src/composer/vendor/consolidation/log/src/LogOutputStyler.php new file mode 100644 index 00000000..5788215b --- /dev/null +++ b/src/composer/vendor/consolidation/log/src/LogOutputStyler.php @@ -0,0 +1,115 @@ + LogLevel::INFO, + ]; + protected $labelStyles = [ + LogLevel::EMERGENCY => self::TASK_STYLE_ERROR, + LogLevel::ALERT => self::TASK_STYLE_ERROR, + LogLevel::CRITICAL => self::TASK_STYLE_ERROR, + LogLevel::ERROR => self::TASK_STYLE_ERROR, + LogLevel::WARNING => self::TASK_STYLE_WARNING, + LogLevel::NOTICE => self::TASK_STYLE_INFO, + LogLevel::INFO => self::TASK_STYLE_INFO, + LogLevel::DEBUG => self::TASK_STYLE_INFO, + ConsoleLogLevel::SUCCESS => self::TASK_STYLE_SUCCESS, + ]; + protected $messageStyles = [ + LogLevel::EMERGENCY => self::TASK_STYLE_ERROR, + LogLevel::ALERT => self::TASK_STYLE_ERROR, + LogLevel::CRITICAL => self::TASK_STYLE_ERROR, + LogLevel::ERROR => self::TASK_STYLE_ERROR, + LogLevel::WARNING => '', + LogLevel::NOTICE => '', + LogLevel::INFO => '', + LogLevel::DEBUG => '', + ConsoleLogLevel::SUCCESS => '', + ]; + + public function __construct($labelStyles = [], $messageStyles = []) + { + $this->labelStyles = $labelStyles + $this->labelStyles; + $this->messageStyles = $messageStyles + $this->messageStyles; + } + + /** + * {@inheritdoc} + */ + public function defaultStyles() + { + return $this->defaultStyles; + } + + /** + * {@inheritdoc} + */ + public function style($context) + { + $context += ['_style' => []]; + $context['_style'] += $this->defaultStyles(); + foreach ($context as $key => $value) { + $styleKey = $key; + if (!isset($context['_style'][$styleKey])) { + $styleKey = '*'; + } + if (is_string($value) && isset($context['_style'][$styleKey])) { + $style = $context['_style'][$styleKey]; + $context[$key] = $this->wrapFormatString($context[$key], $style); + } + } + return $context; + } + + /** + * Wrap a string in a format element. + */ + protected function wrapFormatString($string, $style) + { + if ($style) { + return "<{$style}>$string"; + } + return $string; + } + + /** + * Look up the label and message styles for the specified log level, + * and use the log level as the label for the log message. + */ + protected function formatMessageByLevel($level, $message, $context) + { + $label = $level; + return $this->formatMessage($label, $message, $context, $this->labelStyles[$level], $this->messageStyles[$level]); + } + + /** + * Apply styling with the provided label and message styles. + */ + protected function formatMessage($label, $message, $context, $labelStyle, $messageStyle = '') + { + if (!empty($messageStyle)) { + $message = $this->wrapFormatString(" $message ", $messageStyle); + } + if (!empty($label)) { + $message = ' ' . $this->wrapFormatString("[$label]", $labelStyle) . ' ' . $message; + } + + return $message; + } +} diff --git a/src/composer/vendor/consolidation/log/src/LogOutputStylerInterface.php b/src/composer/vendor/consolidation/log/src/LogOutputStylerInterface.php new file mode 100644 index 00000000..ff2e420f --- /dev/null +++ b/src/composer/vendor/consolidation/log/src/LogOutputStylerInterface.php @@ -0,0 +1,105 @@ + 'pwd'] + * default styles: ['*' => 'info'] + * result: 'Running pwd' + */ + public function defaultStyles(); + + /** + * Apply styles specified in the STYLE_CONTEXT_KEY context variable to + * the other named variables stored in the context. The styles from + * the context are unioned with the default styles. + */ + public function style($context); + + /** + * Create a wrapper object for the output stream. If this styler + * does not require an output wrapper, it should just return + * its $output parameter. + */ + public function createOutputWrapper(OutputInterface $output); + + /** + * Print an ordinary log message, usually unstyled. + */ + public function log($output, $level, $message, $context); + + /** + * Print a success message. + */ + public function success($output, $level, $message, $context); + + /** + * Print an error message. Used when log level is: + * - LogLevel::EMERGENCY + * - LogLevel::ALERT + * - LogLevel::CRITICAL + * - LogLevel::ERROR + */ + public function error($output, $level, $message, $context); + + /** + * Print a warning message. Used when log level is: + * - LogLevel::WARNING + */ + public function warning($output, $level, $message, $context); + + /** + * Print a note. Similar to 'text', but may contain additional + * styling (e.g. the task name). Used when log level is: + * - LogLevel::NOTICE + * - LogLevel::INFO + * - LogLevel::DEBUG + * + * IMPORTANT: Symfony loggers only display LogLevel::NOTICE when the + * the verbosity level is VERBOSITY_VERBOSE, unless overridden in the + * constructor. Robo\Common\Logger emits LogLevel::NOTICE at + * VERBOSITY_NORMAL so that these messages will always be displayed. + */ + public function note($output, $level, $message, $context); + + /** + * Print an error message. Not used by default by StyledConsoleLogger. + */ + public function caution($output, $level, $message, $context); +} diff --git a/src/composer/vendor/consolidation/log/src/Logger.php b/src/composer/vendor/consolidation/log/src/Logger.php new file mode 100644 index 00000000..bb10d1b5 --- /dev/null +++ b/src/composer/vendor/consolidation/log/src/Logger.php @@ -0,0 +1,269 @@ + + */ +class Logger extends AbstractLogger // extends ConsoleLogger +{ + /** + * @var OutputInterface + */ + protected $output; + /** + * @var OutputInterface + */ + protected $error; + /** + * @var LogOutputStylerInterface + */ + protected $outputStyler; + /** + * @var OutputInterface|SymfonyStyle|other + */ + protected $outputStreamWrapper; + protected $errorStreamWrapper; + + protected $formatFunctionMap = [ + LogLevel::EMERGENCY => 'error', + LogLevel::ALERT => 'error', + LogLevel::CRITICAL => 'error', + LogLevel::ERROR => 'error', + LogLevel::WARNING => 'warning', + LogLevel::NOTICE => 'note', + LogLevel::INFO => 'note', + LogLevel::DEBUG => 'note', + ConsoleLogLevel::SUCCESS => 'success', + ]; + + /** + * @param OutputInterface $output + * @param array $verbosityLevelMap + * @param array $formatLevelMap + * @param array $formatFunctionMap + */ + public function __construct(OutputInterface $output, array $verbosityLevelMap = array(), array $formatLevelMap = array(), array $formatFunctionMap = array()) + { + $this->output = $output; + + $this->verbosityLevelMap = $verbosityLevelMap + $this->verbosityLevelMap; + $this->formatLevelMap = $formatLevelMap + $this->formatLevelMap; + $this->formatFunctionMap = $formatFunctionMap + $this->formatFunctionMap; + } + + public function setLogOutputStyler(LogOutputStylerInterface $outputStyler, array $formatFunctionMap = array()) + { + $this->outputStyler = $outputStyler; + $this->formatFunctionMap = $formatFunctionMap + $this->formatFunctionMap; + $this->outputStreamWrapper = null; + $this->errorStreamWrapper = null; + } + + public function getLogOutputStyler() + { + if (!isset($this->outputStyler)) { + $this->outputStyler = new SymfonyLogOutputStyler(); + } + return $this->outputStyler; + } + + protected function getOutputStream() + { + return $this->output; + } + + protected function getErrorStream() + { + if (!isset($this->error)) { + $output = $this->getOutputStream(); + if ($output instanceof ConsoleOutputInterface) { + $output = $output->getErrorOutput(); + } + $this->error = $output; + } + return $this->error; + } + + public function setOutputStream($output) + { + $this->output = $output; + $this->outputStreamWrapper = null; + } + + public function setErrorStream($error) + { + $this->error = $error; + $this->errorStreamWrapper = null; + } + + protected function getOutputStreamWrapper() + { + if (!isset($this->outputStreamWrapper)) { + $this->outputStreamWrapper = $this->getLogOutputStyler()->createOutputWrapper($this->getOutputStream()); + } + return $this->outputStreamWrapper; + } + + protected function getErrorStreamWrapper() + { + if (!isset($this->errorStreamWrapper)) { + $this->errorStreamWrapper = $this->getLogOutputStyler()->createOutputWrapper($this->getErrorStream()); + } + return $this->errorStreamWrapper; + } + + protected function getOutputStreamForLogLevel($level) + { + // Write to the error output if necessary and available. + // Usually, loggers that log to a terminal should send + // all log messages to stderr. + if (array_key_exists($level, $this->formatLevelMap) && ($this->formatLevelMap[$level] !== self::ERROR)) { + return $this->getOutputStreamWrapper(); + } + return $this->getErrorStreamWrapper(); + } + + /** + * {@inheritdoc} + */ + public function log($level, $message, array $context = array()) + { + // We use the '_level' context variable to allow log messages + // to be logged at one level (e.g. NOTICE) and formatted at another + // level (e.g. SUCCESS). This helps in instances where we want + // to style log messages at a custom log level that might not + // be available in all loggers. If the logger does not recognize + // the log level, then it is treated like the original log level. + if (array_key_exists('_level', $context) && array_key_exists($context['_level'], $this->verbosityLevelMap)) { + $level = $context['_level']; + } + // It is a runtime error if someone logs at a log level that + // we do not recognize. + if (!isset($this->verbosityLevelMap[$level])) { + throw new InvalidArgumentException(sprintf('The log level "%s" does not exist.', $level)); + } + + // Write to the error output if necessary and available. + // Usually, loggers that log to a terminal should send + // all log messages to stderr. + $outputStreamWrapper = $this->getOutputStreamForLogLevel($level); + + // Ignore messages that are not at the right verbosity level + if ($this->getOutputStream()->getVerbosity() >= $this->verbosityLevelMap[$level]) { + $this->doLog($outputStreamWrapper, $level, $message, $context); + } + } + + /** + * Interpolate and style the message, and then send it to the log. + */ + protected function doLog($outputStreamWrapper, $level, $message, $context) + { + $formatFunction = 'log'; + if (array_key_exists($level, $this->formatFunctionMap)) { + $formatFunction = $this->formatFunctionMap[$level]; + } + $interpolated = $this->interpolate( + $message, + $this->getLogOutputStyler()->style($context) + ); + $this->getLogOutputStyler()->$formatFunction( + $outputStreamWrapper, + $level, + $interpolated, + $context + ); + } + + public function success($message, array $context = array()) + { + $this->log(ConsoleLogLevel::SUCCESS, $message, $context); + } + + // The functions below could be eliminated if made `protected` intead + // of `private` in ConsoleLogger + + const INFO = 'info'; + const ERROR = 'error'; + + /** + * @var OutputInterface + */ + //private $output; + /** + * @var array + */ + private $verbosityLevelMap = [ + 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_VERBOSE, + LogLevel::INFO => OutputInterface::VERBOSITY_VERY_VERBOSE, + LogLevel::DEBUG => OutputInterface::VERBOSITY_DEBUG, + ConsoleLogLevel::SUCCESS => OutputInterface::VERBOSITY_NORMAL, + ]; + + /** + * @var array + * + * Send all log messages to stderr. Symfony should have the same default. + * See: https://en.wikipedia.org/wiki/Standard_streams + * "Standard error was added to Unix after several wasted phototypesetting runs ended with error messages being typeset instead of displayed on the user's terminal." + * + */ + private $formatLevelMap = [ + LogLevel::EMERGENCY => self::ERROR, + LogLevel::ALERT => self::ERROR, + LogLevel::CRITICAL => self::ERROR, + LogLevel::ERROR => self::ERROR, + LogLevel::WARNING => self::ERROR, + LogLevel::NOTICE => self::ERROR, + LogLevel::INFO => self::ERROR, + LogLevel::DEBUG => self::ERROR, + ConsoleLogLevel::SUCCESS => self::ERROR, + ]; + + /** + * Interpolates context values into the message placeholders. + * + * @author PHP Framework Interoperability Group + * + * @param string $message + * @param array $context + * + * @return string + */ + private function interpolate($message, array $context) + { + // build a replacement array with braces around the context keys + $replace = array(); + foreach ($context as $key => $val) { + if (!is_array($val) && (!is_object($val) || method_exists($val, '__toString'))) { + $replace[sprintf('{%s}', $key)] = $val; + } + } + + // interpolate replacement values into the message and return + return strtr($message, $replace); + } +} diff --git a/src/composer/vendor/consolidation/log/src/SymfonyLogOutputStyler.php b/src/composer/vendor/consolidation/log/src/SymfonyLogOutputStyler.php new file mode 100644 index 00000000..12ce49f3 --- /dev/null +++ b/src/composer/vendor/consolidation/log/src/SymfonyLogOutputStyler.php @@ -0,0 +1,65 @@ +text($message); + } + + public function success($symfonyStyle, $level, $message, $context) + { + $symfonyStyle->success($message); + } + + public function error($symfonyStyle, $level, $message, $context) + { + $symfonyStyle->error($message); + } + + public function warning($symfonyStyle, $level, $message, $context) + { + $symfonyStyle->warning($message); + } + + public function note($symfonyStyle, $level, $message, $context) + { + $symfonyStyle->note($message); + } + + public function caution($symfonyStyle, $level, $message, $context) + { + $symfonyStyle->caution($message); + } +} diff --git a/src/composer/vendor/consolidation/log/src/UnstyledLogOutputStyler.php b/src/composer/vendor/consolidation/log/src/UnstyledLogOutputStyler.php new file mode 100644 index 00000000..6513ce34 --- /dev/null +++ b/src/composer/vendor/consolidation/log/src/UnstyledLogOutputStyler.php @@ -0,0 +1,97 @@ +writeln($message); + } + + /** + * {@inheritdoc} + */ + public function log($output, $level, $message, $context) + { + return $this->write($output, $this->formatMessageByLevel($level, $message, $context), $context); + } + + /** + * {@inheritdoc} + */ + public function success($output, $level, $message, $context) + { + return $this->write($output, $this->formatMessageByLevel($level, $message, $context), $context); + } + + /** + * {@inheritdoc} + */ + public function error($output, $level, $message, $context) + { + return $this->write($output, $this->formatMessageByLevel($level, $message, $context), $context); + } + + /** + * {@inheritdoc} + */ + public function warning($output, $level, $message, $context) + { + return $this->write($output, $this->formatMessageByLevel($level, $message, $context), $context); + } + + /** + * {@inheritdoc} + */ + public function note($output, $level, $message, $context) + { + return $this->write($output, $this->formatMessageByLevel($level, $message, $context), $context); + } + + /** + * {@inheritdoc} + */ + public function caution($output, $level, $message, $context) + { + return $this->write($output, $this->formatMessageByLevel($level, $message, $context), $context); + } + + /** + * Look up the label and message styles for the specified log level, + * and use the log level as the label for the log message. + */ + protected function formatMessageByLevel($level, $message, $context) + { + return " [$level] $message"; + } +} diff --git a/src/composer/vendor/consolidation/log/tests/src/TestDataPermuter.php b/src/composer/vendor/consolidation/log/tests/src/TestDataPermuter.php new file mode 100644 index 00000000..c44ef53a --- /dev/null +++ b/src/composer/vendor/consolidation/log/tests/src/TestDataPermuter.php @@ -0,0 +1,81 @@ + $values) { + $tests = static::expandOneValue($tests, $substitute, $values); + } + return $tests; + } + + /** + * Given an array of test data, where each element is + * data to pass to a unit test, find any element in any + * one test item whose value is exactly $substitute. + * Make a new test item for every item in $values, using + * each as the substitution for $substitute. + */ + public static function expandOneValue($tests, $substitute, $values) + { + $result = []; + + foreach($tests as $test) { + $position = array_search($substitute, $test); + if ($position === FALSE) { + $result[] = $test; + } + else { + foreach($values as $replacement) { + $test[$position] = $replacement; + $result[] = $test; + } + } + } + + return $result; + } +} diff --git a/src/composer/vendor/consolidation/log/tests/testLogMethods.php b/src/composer/vendor/consolidation/log/tests/testLogMethods.php new file mode 100644 index 00000000..5c7e19f0 --- /dev/null +++ b/src/composer/vendor/consolidation/log/tests/testLogMethods.php @@ -0,0 +1,54 @@ +output = new BufferedOutput(); + $this->output->setVerbosity(OutputInterface::VERBOSITY_DEBUG); + $this->logger = new Logger($this->output); + $this->logger->setLogOutputStyler(new UnstyledLogOutputStyler()); + } + + function testError() { + $this->logger->error('Do not enter - wrong way.'); + $outputText = rtrim($this->output->fetch()); + $this->assertEquals(' [error] Do not enter - wrong way.', $outputText); + } + + function testWarning() { + $this->logger->warning('Steep grade.'); + $outputText = rtrim($this->output->fetch()); + $this->assertEquals(' [warning] Steep grade.', $outputText); + } + + function testNotice() { + $this->logger->notice('No loitering.'); + $outputText = rtrim($this->output->fetch()); + $this->assertEquals(' [notice] No loitering.', $outputText); + } + + function testInfo() { + $this->logger->info('Scenic route.'); + $outputText = rtrim($this->output->fetch()); + $this->assertEquals(' [info] Scenic route.', $outputText); + } + + function testDebug() { + $this->logger->debug('Counter incremented.'); + $outputText = rtrim($this->output->fetch()); + $this->assertEquals(' [debug] Counter incremented.', $outputText); + } + + function testSuccess() { + $this->logger->success('It worked!'); + $outputText = rtrim($this->output->fetch()); + $this->assertEquals(' [success] It worked!', $outputText); + } +} diff --git a/src/composer/vendor/consolidation/log/tests/testLoggerVerbosityAndStyles.php b/src/composer/vendor/consolidation/log/tests/testLoggerVerbosityAndStyles.php new file mode 100644 index 00000000..5b17fcff --- /dev/null +++ b/src/composer/vendor/consolidation/log/tests/testLoggerVerbosityAndStyles.php @@ -0,0 +1,164 @@ +output = new BufferedOutput(); + //$this->output->setVerbosity(OutputInterface::VERBOSITY_VERY_VERBOSE); + $this->logger = new Logger($this->output); + } + + public static function logTestValues() + { + /** + * Use TEST_ALL_LOG_LEVELS to ensure that output is the same + * in instances where the output does not vary by log level. + */ + $TEST_ALL_LOG_LEVELS = [ + OutputInterface::VERBOSITY_DEBUG, + OutputInterface::VERBOSITY_VERY_VERBOSE, + OutputInterface::VERBOSITY_VERBOSE, + OutputInterface::VERBOSITY_NORMAL + ]; + + // Tests that return the same value for multiple inputs + // may use the expandProviderDataArrays method, and list + // repeated scalars as array values. All permutations of + // all array items will be calculated, and one test will + // be generated for each one. + return TestDataPermuter::expandProviderDataArrays([ + [ + '\Consolidation\Log\UnstyledLogOutputStyler', + $TEST_ALL_LOG_LEVELS, + LogLevel::ERROR, + 'Do not enter - wrong way.', + ' [error] Do not enter - wrong way.', + ], + [ + '\Consolidation\Log\UnstyledLogOutputStyler', + $TEST_ALL_LOG_LEVELS, + LogLevel::WARNING, + 'Steep grade.', + ' [warning] Steep grade.', + ], + [ + '\Consolidation\Log\UnstyledLogOutputStyler', + [ + OutputInterface::VERBOSITY_DEBUG, + OutputInterface::VERBOSITY_VERY_VERBOSE, + OutputInterface::VERBOSITY_VERBOSE, + ], + LogLevel::NOTICE, + 'No loitering.', + ' [notice] No loitering.', + ], + [ + '\Consolidation\Log\UnstyledLogOutputStyler', + OutputInterface::VERBOSITY_NORMAL, + LogLevel::NOTICE, + 'No loitering.', + '', + ], + [ + '\Consolidation\Log\UnstyledLogOutputStyler', + OutputInterface::VERBOSITY_DEBUG, + LogLevel::INFO, + 'Scenic route.', + ' [info] Scenic route.', + ], + [ + '\Consolidation\Log\UnstyledLogOutputStyler', + OutputInterface::VERBOSITY_DEBUG, + LogLevel::DEBUG, + 'Counter incremented.', + ' [debug] Counter incremented.', + ], + [ + '\Consolidation\Log\UnstyledLogOutputStyler', + [ + OutputInterface::VERBOSITY_VERY_VERBOSE, + OutputInterface::VERBOSITY_VERBOSE, + OutputInterface::VERBOSITY_NORMAL + ], + LogLevel::DEBUG, + 'Counter incremented.', + '', + ], + [ + '\Consolidation\Log\UnstyledLogOutputStyler', + $TEST_ALL_LOG_LEVELS, + ConsoleLogLevel::SUCCESS, + 'It worked!', + ' [success] It worked!', + ], + [ + '\Consolidation\Log\LogOutputStyler', + OutputInterface::VERBOSITY_NORMAL, + ConsoleLogLevel::SUCCESS, + 'It worked!', + ' [success] It worked!', + ], + [ + '\Consolidation\Log\SymfonyLogOutputStyler', + OutputInterface::VERBOSITY_DEBUG, + LogLevel::WARNING, + 'Steep grade.', + "\n [WARNING] Steep grade.", + ], + [ + '\Consolidation\Log\SymfonyLogOutputStyler', + OutputInterface::VERBOSITY_DEBUG, + LogLevel::NOTICE, + 'No loitering.', + "\n ! [NOTE] No loitering.", + ], + [ + '\Consolidation\Log\SymfonyLogOutputStyler', + OutputInterface::VERBOSITY_DEBUG, + LogLevel::INFO, + 'Scenic route.', + "\n ! [NOTE] Scenic route.", + ], + [ + '\Consolidation\Log\SymfonyLogOutputStyler', + OutputInterface::VERBOSITY_DEBUG, + LogLevel::DEBUG, + 'Counter incremented.', + "\n ! [NOTE] Counter incremented.", + ], + [ + '\Consolidation\Log\SymfonyLogOutputStyler', + OutputInterface::VERBOSITY_NORMAL, + ConsoleLogLevel::SUCCESS, + 'It worked!', + "\n [OK] It worked!", + ], + ]); + } + + /** + * This is our only test method. It accepts all of the + * permuted data from the data provider, and runs one + * test on each one. + * + * @dataProvider logTestValues + */ + function testLogging($styleClass, $verbocity, $level, $message, $expected) { + $logStyler = new $styleClass; + $this->logger->setLogOutputStyler($logStyler); + $this->output->setVerbosity($verbocity); + $this->logger->log($level, $message); + $outputText = rtrim($this->output->fetch(), "\n\r\t "); + $this->assertEquals($expected, $outputText); + } +} diff --git a/src/composer/vendor/consolidation/output-formatters/.editorconfig b/src/composer/vendor/consolidation/output-formatters/.editorconfig new file mode 100644 index 00000000..095771e6 --- /dev/null +++ b/src/composer/vendor/consolidation/output-formatters/.editorconfig @@ -0,0 +1,15 @@ +# This file is for unifying the coding style for different editors and IDEs +# editorconfig.org + +root = true + +[*] +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[**.php] +indent_style = space +indent_size = 4 + diff --git a/src/composer/vendor/consolidation/output-formatters/.github/issue_template.md b/src/composer/vendor/consolidation/output-formatters/.github/issue_template.md new file mode 100644 index 00000000..97335f49 --- /dev/null +++ b/src/composer/vendor/consolidation/output-formatters/.github/issue_template.md @@ -0,0 +1,11 @@ +### Steps to reproduce +What did you do? + +### Expected behavior +Tell us what should happen + +### Actual behavior +Tell us what happens instead + +### System Configuration +Which O.S. and PHP version are you using? diff --git a/src/composer/vendor/consolidation/output-formatters/.github/pull_request_template.md b/src/composer/vendor/consolidation/output-formatters/.github/pull_request_template.md new file mode 100644 index 00000000..da95f480 --- /dev/null +++ b/src/composer/vendor/consolidation/output-formatters/.github/pull_request_template.md @@ -0,0 +1,13 @@ +### Overview +This pull request: + +- [ ] Fixes a bug +- [ ] Adds a feature +- [ ] Breaks backwards compatibility +- [ ] Has tests that cover changes + +### Summary +Short overview of what changed. + +### Description +Any additional information. diff --git a/src/composer/vendor/consolidation/output-formatters/.gitignore b/src/composer/vendor/consolidation/output-formatters/.gitignore new file mode 100644 index 00000000..ae5ae728 --- /dev/null +++ b/src/composer/vendor/consolidation/output-formatters/.gitignore @@ -0,0 +1,7 @@ +.DS_Store +.idea +phpunit.xml +build +vendor +composer.lock +main.php diff --git a/src/composer/vendor/consolidation/output-formatters/.travis.yml b/src/composer/vendor/consolidation/output-formatters/.travis.yml new file mode 100644 index 00000000..2c11c39c --- /dev/null +++ b/src/composer/vendor/consolidation/output-formatters/.travis.yml @@ -0,0 +1,30 @@ +language: php + +branches: + # Only test the master branch and SemVer tags. + only: + - master + - /^[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+.*$/ + +php: + - 7.0 + - 5.6 + - 5.5 + - 5.4 + +sudo: false + +cache: + directories: + - vendor + - $HOME/.composer/cache + +before_script: + - composer install + +script: + - vendor/bin/phpunit + - vendor/bin/phpcs --standard=PSR2 -n src + +after_success: + - travis_retry php vendor/bin/coveralls -v diff --git a/src/composer/vendor/consolidation/output-formatters/CHANGELOG.md b/src/composer/vendor/consolidation/output-formatters/CHANGELOG.md new file mode 100644 index 00000000..776c5b62 --- /dev/null +++ b/src/composer/vendor/consolidation/output-formatters/CHANGELOG.md @@ -0,0 +1,35 @@ +# Change Log + +### 3.0.0 - 14 November 2016 + +- **Breaking** The RenderCellInterface is now provided a reference to the entire row data. Existing clients need only add the new parameter to their method defnition to update. +- Rename AssociativeList to PropertyList, as many people seemed to find the former name confusing. AssociativeList is still available for use to preserve backwards compatibility, but it is deprecated. + + +### 2.1.0 - 7 November 2016 + +- Add RenderCellCollections to structured lists, so that commands may add renderers to structured data without defining a new structured data subclass. + + +### 2.0.1 - 4 October 2016 + +- Throw an exception if the client requests a field that does not exist. +- Remove unwanted extra layer of nesting when formatting an PropertyList with an array formatter (json, yaml, etc.). + + +### 2.0.0 - 30 September 2016 + +- **Breaking** The default `string` format now converts non-string results into a tab-separated-value table if possible. Commands may select a single field to emit in this instance with an annotation: `@default-string-field email`. By this means, a given command may by default emit a single value, but also provide more rich output that may be shown by selecting --format=table, --format=yaml or the like. This change might cause some commands to produce output in situations that previously were not documented as producing output. +- **Breaking** FormatterManager::addFormatter() now takes the format identifier and a FormatterInterface, rather than an identifier and a Formatter classname (string). +- --field is a synonym for --fields with a single field. +- Wildcards and regular expressions can now be used in --fields expressions. + + +### 1.1.0 - 14 September 2016 + +Add tab-separated-value (tsv) formatter. + + +### 1.0.0 - 19 May 2016 + +First stable release. diff --git a/src/composer/vendor/consolidation/output-formatters/CONTRIBUTING.md b/src/composer/vendor/consolidation/output-formatters/CONTRIBUTING.md new file mode 100644 index 00000000..4d843cf7 --- /dev/null +++ b/src/composer/vendor/consolidation/output-formatters/CONTRIBUTING.md @@ -0,0 +1,31 @@ +# Contributing to Consolidation + +Thank you for your interest in contributing to the Consolidation effort! Consolidation aims to provide reusable, loosely-coupled components useful for building command-line tools. Consolidation is built on top of Symfony Console, but aims to separate the tool from the implementation details of Symfony. + +Here are some of the guidelines you should follow to make the most of your efforts: + +## Code Style Guidelines + +Consolidation adheres to the [PSR-2 Coding Style Guide](http://www.php-fig.org/psr/psr-2/) for PHP code. + +## Pull Request Guidelines + +Every pull request is run through: + + - phpcs -n --standard=PSR2 src + - phpunit + - [Scrutinizer](https://scrutinizer-ci.com/g/consolidation/output-formatters/) + +It is easy to run the unit tests and code sniffer locally; just run: + + - composer cs + +To run the code beautifier, which will fix many of the problems reported by phpcs: + + - composer cbf + +These two commands (`composer cs` and `composer cbf`) are defined in the `scripts` section of [composer.json](composer.json). + +After submitting a pull request, please examine the Scrutinizer report. It is not required to fix all Scrutinizer issues; you may ignore recommendations that you disagree with. The spacing patches produced by Scrutinizer do not conform to PSR2 standards, and therefore should never be applied. DocBlock patches may be applied at your discression. Things that Scrutinizer identifies as a bug nearly always need to be addressed. + +Pull requests must pass phpcs and phpunit in order to be merged; ideally, new functionality will also include new unit tests. diff --git a/src/composer/vendor/consolidation/output-formatters/LICENSE b/src/composer/vendor/consolidation/output-formatters/LICENSE new file mode 100644 index 00000000..2078bd88 --- /dev/null +++ b/src/composer/vendor/consolidation/output-formatters/LICENSE @@ -0,0 +1,8 @@ +Copyright (c) 2016 Consolidation Org Developers + + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/src/composer/vendor/consolidation/output-formatters/README.md b/src/composer/vendor/consolidation/output-formatters/README.md new file mode 100644 index 00000000..7b9b912f --- /dev/null +++ b/src/composer/vendor/consolidation/output-formatters/README.md @@ -0,0 +1,130 @@ +# Consolidation\OutputFormatters + +Apply transformations to structured data to write output in different formats. + +[![Travis CI](https://travis-ci.org/consolidation/output-formatters.svg?branch=master)](https://travis-ci.org/consolidation/output-formatters) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/consolidation/output-formatters/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/consolidation/output-formatters/?branch=master) [![Coverage Status](https://coveralls.io/repos/github/consolidation/output-formatters/badge.svg?branch=master)](https://coveralls.io/github/consolidation/output-formatters?branch=master) [![License](https://poser.pugx.org/consolidation/output-formatters/license)](https://packagist.org/packages/consolidation/output-formatters) + +## Component Status + +Currently in use in [Robo](https://github.com/consolidation/Robo) (1.x+), [Drush](https://github.com/drush-ops/drush) (9.x+) and [Terminus](https://github.com/pantheon-systems/terminus) (1.x+). + +## Motivation + +Formatters are used to allow simple commandline tool commands to be implemented in a manner that is completely independent from the Symfony Console output interfaces. A command receives its input via its method parameters, and returns its result as structured data (e.g. a php standard object or array). The structured data is then formatted by a formatter, and the result is printed. + +This process is managed by the [Consolidation/AnnotationCommand](https://github.com/consolidation/annotation-command) project. + +## Library Usage + +This is a library intended to be used in some other project. Require from your composer.json file: +``` + "require": { + "consolidation/output-formatters": "~3" + }, +``` +If you require the feature that allows a data table to be automatically reduced to a single element when the `string` format is selected, then you should require version "~2" instead. In most other respects, the 1.x and 2.x versions are compatible. See the [CHANGELOG](CHANGELOG.md) for details. + +## Example Formatter + +Simple formatters are very easy to write. +```php +class YamlFormatter implements FormatterInterface +{ + public function write(OutputInterface $output, $data, FormatterOptions $options) + { + $dumper = new Dumper(); + $output->writeln($dumper->dump($data)); + } +} +``` +The formatter is passed the set of `$options` that the user provided on the command line. These may optionally be examined to alter the behavior of the formatter, if needed. + +Formatters may also implement different interfaces to alter the behavior of the rendering engine. + +- `ValidationInterface`: A formatter should implement this interface to test to see if the provided data type can be processed. Any formatter that does **not** implement this interface is presumed to operate exclusively on php arrays. The formatter manager will always convert any provided data into an array before passing it to a formatter that does not implement ValidationInterface. These formatters will not be made available when the returned data type cannot be converted into an array. +- `OverrideRestructureInterface`: A formatter that implements this interface will be given the option to act on the provided structured data object before it restructures itself. See the section below on structured data for details on data restructuring. + +## Structured Data + +Most formatters will operate on any array or ArrayObject data. Some formatters require that specific data types be used. The following data types, all of which are subclasses of ArrayObject, are available for use: + +- `RowsOfFields`: Each row contains an associative array of field:value pairs. It is also assumed that the fields of each row are the same for every row. This format is ideal for displaying in a table, with labels in the top row. +- `PropertyList`: Each row contains a field:value pair. Each field is unique. This format is ideal for displaying in a table, with labels in the first column and values in the second common. +- `DOMDocument`: The standard PHP DOM document class may be used by functions that need to be able to presicely specify the exact attributes and children when the XML output format is used. + +Commands that return table structured data with fields can be filtered and/or re-ordered by using the --fields option. These structured data types can also be formatted into a more generic type such as yaml or json, even after being filtered. This capabilities are not available if the data is returned in a bare php array. + +The formatter manager will do its best to convert from an array to a DOMDocument, or from a DOMDocument to an array. It is important to note that a DOMDocument does not have a 1-to-1 mapping with a PHP array. DOM elements contain both attributes and elements; a simple string property 'foo' may be represented either as or value. Also, there may be multiple XML elements with the same name, whereas php associative arrays must always have unique keys. When converting from an array to a DOM document, the XML formatter will default to representing the string properties of an array as attributes of the element. Sets of elements with the same name may be used only if they are wrapped in a containing parent element--e.g. onetwo. The XMLSchema class may be used to provide control over whether a property is rendered as an attribute or an element; however, in instances where the schema of the XML output is important, it is best for a function to return its result as a DOMDocument rather than an array. + +A function may also define its own structured data type to return, usually by extending one of the types mentioned above. If a custom structured data class implements an appropriate interface, then it can provide its own conversion function to one of the other data types: + +- `DomDataInterface`: The data object may produce a DOMDocument via its `getDomData()` method, which will be called in any instance where a DOM document is needed--typically with the xml formatter. +- `ListDataInterface`: Any structured data object that implements this interface may use the `getListData()` method to produce the data set that will be used with the list formatter. +- `TableDataInterface`: Any structured data object that implements this interface may use the `getTableData()` method to produce the data set that will be used with the table formatter. +- `RenderCellInterface`: Structured data can also provide fine-grain control over how each cell in a table is rendered by implementing the RenderCellInterface. See the section below for information on how this is done. +- `RestructureInterface`: The restructure interface can be implemented by a structured data object to restructure the data in response to options provided by the user. For example, the RowsOfFields and PropertyList data types use this interface to select and reorder the fields that were selected to appear in the output. Custom data types usually will not need to implement this interface, as they can inherit this behavior by extending RowsOfFields or PropertyList. + +Additionally, structured data may be simplified to arrays via an array simplification object. To provide an array simplifier, implement `SimplifyToArrayInterface`, and register the simplifier via `FormatterManager::addSimplifier()`. + +## Rendering Table Cells + +By default, both the RowsOfFields and PropertyList data types presume that the contents of each cell is a simple string. To render more complicated cell contents, create a custom structured data class by extending either RowsOfFields or PropertyList, as desired, and implement RenderCellInterface. The `renderCell()` method of your class will then be called for each cell, and you may act on it as appropriate. +```php +public function renderCell($key, $cellData, FormatterOptions $options, $rowData) +{ + // 'my-field' is always an array; convert it to a comma-separated list. + if ($key == 'my-field') { + return implode(',', $cellData); + } + // MyStructuredCellType has its own render function + if ($cellData instanceof MyStructuredCellType) { + return $cellData->myRenderfunction(); + } + // If we do not recognize the cell data, return it unchnaged. + return $cellData; +} +``` +Note that if your data structure is printed with a formatter other than one such as the table formatter, it will still be reordered per the selected fields, but cell rendering will **not** be done. + +## API Usage + +It is recommended to use [Consolidation/AnnotationCommand](https://github.com/consolidation/annotation-command) to manage commands and formatters. See the [AnnotationCommand API Usage](https://github.com/consolidation/annotation-command#api-usage) for details. + +The FormatterManager may also be used directly, if desired: +```php +/** + * @param OutputInterface $output Output stream to write to + * @param string $format Data format to output in + * @param mixed $structuredOutput Data to output + * @param FormatterOptions $options Configuration informatin and User options + */ +function doFormat( + OutputInterface $output, + string $format, + array $data, + FormatterOptions $options) +{ + $formatterManager = new FormatterManager(); + $formatterManager->write(output, $format, $data, $options); +} +``` +The FormatterOptions class is used to hold the configuration for the command output--things such as the default field list for tabular output, and so on--and also the current user-selected options to use during rendering, which may be provided using a Symfony InputInterface object: +``` +public function execute(InputInterface $input, OutputInterface $output) +{ + $options = new FormatterOptions(); + $options + ->setInput($input) + ->setFieldLabels(['id' => 'ID', 'one' => 'First', 'two' => 'Second']) + ->setDefaultStringField('id'); + + $data = new RowsOfFields($this->getSomeData($input)); + return $this->doFormat($output, $options->getFormat(), $data, $options); +} +``` +## Comparison to Existing Solutions + +Formatters have been in use in Drush since version 5. Drush allows formatters to be defined using simple classes, some of which may be configured using metadata. Furthermore, nested formatters are also allowed; for example, a list formatter may be given another formatter to use to format each of its rows. Nested formatters also require nested metadata, causing the code that constructed formatters to become very complicated and unweildy. + +Consolidation/OutputFormatters maintains the simplicity of use provided by Drush formatters, but abandons nested metadata configuration in favor of using code in the formatter to configure itself, in order to keep the code simpler. + diff --git a/src/composer/vendor/consolidation/output-formatters/composer.json b/src/composer/vendor/consolidation/output-formatters/composer.json new file mode 100644 index 00000000..4a1a92a2 --- /dev/null +++ b/src/composer/vendor/consolidation/output-formatters/composer.json @@ -0,0 +1,43 @@ +{ + "name": "consolidation/output-formatters", + "description": "Format text by applying transformations provided by plug-in formatters.", + "license": "MIT", + "authors": [ + { + "name": "Greg Anderson", + "email": "greg.1.anderson@greenknowe.org" + } + ], + "autoload":{ + "psr-4":{ + "Consolidation\\OutputFormatters\\": "src" + } + }, + "autoload-dev": { + "psr-4": { + "Consolidation\\TestUtils\\": "tests/src" + } + }, + "require": { + "php": ">=5.4.0", + "symfony/console": "~2.5|~3.0", + "symfony/finder": "~2.5|~3.0", + "victorjonsson/markdowndocs": "^1.3" + }, + "require-dev": { + "phpunit/phpunit": "4.*", + "satooshi/php-coveralls": "^1.0", + "squizlabs/php_codesniffer": "2.*" + }, + "scripts": { + "api": "phpdoc-md generate src > docs/api.md", + "cs": "phpcs --standard=PSR2 -n src", + "cbf": "phpcbf --standard=PSR2 -n src", + "test": "phpunit --colors=always" + }, + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } + } +} diff --git a/src/composer/vendor/consolidation/output-formatters/docs/api.md b/src/composer/vendor/consolidation/output-formatters/docs/api.md new file mode 100644 index 00000000..279f5c16 --- /dev/null +++ b/src/composer/vendor/consolidation/output-formatters/docs/api.md @@ -0,0 +1,658 @@ +## Table of contents + +- [\Consolidation\OutputFormatters\FormatterManager](#class-consolidationoutputformattersformattermanager) +- [\Consolidation\OutputFormatters\Exception\AbstractDataFormatException (abstract)](#class-consolidationoutputformattersexceptionabstractdataformatexception-abstract) +- [\Consolidation\OutputFormatters\Exception\IncompatibleDataException](#class-consolidationoutputformattersexceptionincompatibledataexception) +- [\Consolidation\OutputFormatters\Exception\InvalidFormatException](#class-consolidationoutputformattersexceptioninvalidformatexception) +- [\Consolidation\OutputFormatters\Exception\UnknownFieldException](#class-consolidationoutputformattersexceptionunknownfieldexception) +- [\Consolidation\OutputFormatters\Exception\UnknownFormatException](#class-consolidationoutputformattersexceptionunknownformatexception) +- [\Consolidation\OutputFormatters\Formatters\CsvFormatter](#class-consolidationoutputformattersformatterscsvformatter) +- [\Consolidation\OutputFormatters\Formatters\FormatterInterface (interface)](#interface-consolidationoutputformattersformattersformatterinterface) +- [\Consolidation\OutputFormatters\Formatters\JsonFormatter](#class-consolidationoutputformattersformattersjsonformatter) +- [\Consolidation\OutputFormatters\Formatters\ListFormatter](#class-consolidationoutputformattersformatterslistformatter) +- [\Consolidation\OutputFormatters\Formatters\PrintRFormatter](#class-consolidationoutputformattersformattersprintrformatter) +- [\Consolidation\OutputFormatters\Formatters\RenderDataInterface (interface)](#interface-consolidationoutputformattersformattersrenderdatainterface) +- [\Consolidation\OutputFormatters\Formatters\SectionsFormatter](#class-consolidationoutputformattersformatterssectionsformatter) +- [\Consolidation\OutputFormatters\Formatters\SerializeFormatter](#class-consolidationoutputformattersformattersserializeformatter) +- [\Consolidation\OutputFormatters\Formatters\StringFormatter](#class-consolidationoutputformattersformattersstringformatter) +- [\Consolidation\OutputFormatters\Formatters\TableFormatter](#class-consolidationoutputformattersformatterstableformatter) +- [\Consolidation\OutputFormatters\Formatters\TsvFormatter](#class-consolidationoutputformattersformatterstsvformatter) +- [\Consolidation\OutputFormatters\Formatters\VarExportFormatter](#class-consolidationoutputformattersformattersvarexportformatter) +- [\Consolidation\OutputFormatters\Formatters\XmlFormatter](#class-consolidationoutputformattersformattersxmlformatter) +- [\Consolidation\OutputFormatters\Formatters\YamlFormatter](#class-consolidationoutputformattersformattersyamlformatter) +- [\Consolidation\OutputFormatters\Options\FormatterOptions](#class-consolidationoutputformattersoptionsformatteroptions) +- [\Consolidation\OutputFormatters\Options\OverrideOptionsInterface (interface)](#interface-consolidationoutputformattersoptionsoverrideoptionsinterface) +- [\Consolidation\OutputFormatters\StructuredData\AbstractStructuredList (abstract)](#class-consolidationoutputformattersstructureddataabstractstructuredlist-abstract) +- [\Consolidation\OutputFormatters\StructuredData\AssociativeList](#class-consolidationoutputformattersstructureddataassociativelist) +- [\Consolidation\OutputFormatters\StructuredData\CallableRenderer](#class-consolidationoutputformattersstructureddatacallablerenderer) +- [\Consolidation\OutputFormatters\StructuredData\ListDataInterface (interface)](#interface-consolidationoutputformattersstructureddatalistdatainterface) +- [\Consolidation\OutputFormatters\StructuredData\OriginalDataInterface (interface)](#interface-consolidationoutputformattersstructureddataoriginaldatainterface) +- [\Consolidation\OutputFormatters\StructuredData\PropertyList](#class-consolidationoutputformattersstructureddatapropertylist) +- [\Consolidation\OutputFormatters\StructuredData\RenderCellCollectionInterface (interface)](#interface-consolidationoutputformattersstructureddatarendercellcollectioninterface) +- [\Consolidation\OutputFormatters\StructuredData\RenderCellInterface (interface)](#interface-consolidationoutputformattersstructureddatarendercellinterface) +- [\Consolidation\OutputFormatters\StructuredData\RestructureInterface (interface)](#interface-consolidationoutputformattersstructureddatarestructureinterface) +- [\Consolidation\OutputFormatters\StructuredData\RowsOfFields](#class-consolidationoutputformattersstructureddatarowsoffields) +- [\Consolidation\OutputFormatters\StructuredData\TableDataInterface (interface)](#interface-consolidationoutputformattersstructureddatatabledatainterface) +- [\Consolidation\OutputFormatters\StructuredData\Xml\DomDataInterface (interface)](#interface-consolidationoutputformattersstructureddataxmldomdatainterface) +- [\Consolidation\OutputFormatters\StructuredData\Xml\XmlSchema](#class-consolidationoutputformattersstructureddataxmlxmlschema) +- [\Consolidation\OutputFormatters\StructuredData\Xml\XmlSchemaInterface (interface)](#interface-consolidationoutputformattersstructureddataxmlxmlschemainterface) +- [\Consolidation\OutputFormatters\Transformations\DomToArraySimplifier](#class-consolidationoutputformatterstransformationsdomtoarraysimplifier) +- [\Consolidation\OutputFormatters\Transformations\OverrideRestructureInterface (interface)](#interface-consolidationoutputformatterstransformationsoverriderestructureinterface) +- [\Consolidation\OutputFormatters\Transformations\PropertyListTableTransformation](#class-consolidationoutputformatterstransformationspropertylisttabletransformation) +- [\Consolidation\OutputFormatters\Transformations\PropertyParser](#class-consolidationoutputformatterstransformationspropertyparser) +- [\Consolidation\OutputFormatters\Transformations\ReorderFields](#class-consolidationoutputformatterstransformationsreorderfields) +- [\Consolidation\OutputFormatters\Transformations\SimplifyToArrayInterface (interface)](#interface-consolidationoutputformatterstransformationssimplifytoarrayinterface) +- [\Consolidation\OutputFormatters\Transformations\TableTransformation](#class-consolidationoutputformatterstransformationstabletransformation) +- [\Consolidation\OutputFormatters\Transformations\WordWrapper](#class-consolidationoutputformatterstransformationswordwrapper) +- [\Consolidation\OutputFormatters\Validate\ValidationInterface (interface)](#interface-consolidationoutputformattersvalidatevalidationinterface) +- [\Consolidation\OutputFormatters\Validate\ValidDataTypesInterface (interface)](#interface-consolidationoutputformattersvalidatevaliddatatypesinterface) + +
+### Class: \Consolidation\OutputFormatters\FormatterManager + +> Manage a collection of formatters; return one on request. + +| Visibility | Function | +|:-----------|:---------| +| public | __construct() : void | +| public | addDefaultFormatters() : void | +| public | addDefaultSimplifiers() : void | +| public | addFormatter(string $key, string/[\Consolidation\OutputFormatters\Formatters\FormatterInterface](#interface-consolidationoutputformattersformattersformatterinterface) $formatter) : [\Consolidation\OutputFormatters\FormatterManager](#class-consolidationoutputformattersformattermanager)
Add a formatter | +| public | addSimplifier([\Consolidation\OutputFormatters\Transformations\SimplifyToArrayInterface](#interface-consolidationoutputformatterstransformationssimplifytoarrayinterface) $simplifier) : [\Consolidation\OutputFormatters\FormatterManager](#class-consolidationoutputformattersformattermanager)
Add a simplifier | +| public | automaticOptions([\Consolidation\OutputFormatters\Options\FormatterOptions](#class-consolidationoutputformattersoptionsformatteroptions) $options, mixed $dataType) : \Symfony\Component\Console\Input\InputOption[]
Return a set of InputOption based on the annotations of a command. | +| public | getFormatter(string $format) : [\Consolidation\OutputFormatters\Formatters\FormatterInterface](#interface-consolidationoutputformattersformattersformatterinterface)
Fetch the requested formatter. | +| public | hasFormatter(mixed $format) : bool
Test to see if the stipulated format exists | +| public | isValidDataType([\Consolidation\OutputFormatters\Formatters\FormatterInterface](#interface-consolidationoutputformattersformattersformatterinterface) $formatter, [\ReflectionClass](http://php.net/manual/en/class.reflectionclass.php) $dataType) : bool | +| public | isValidFormat([\Consolidation\OutputFormatters\Formatters\FormatterInterface](#interface-consolidationoutputformattersformattersformatterinterface) $formatter, mixed $dataType) : bool | +| public | overrideOptions([\Consolidation\OutputFormatters\Formatters\FormatterInterface](#interface-consolidationoutputformattersformattersformatterinterface) $formatter, mixed $structuredOutput, [\Consolidation\OutputFormatters\Options\FormatterOptions](#class-consolidationoutputformattersoptionsformatteroptions) $options) : [\Consolidation\OutputFormatters\Options\FormatterOptions](#class-consolidationoutputformattersoptionsformatteroptions)
Allow the formatter to mess with the configuration options before any transformations et. al. get underway. | +| public | overrideRestructure([\Consolidation\OutputFormatters\Formatters\FormatterInterface](#interface-consolidationoutputformattersformattersformatterinterface) $formatter, mixed $structuredOutput, [\Consolidation\OutputFormatters\Options\FormatterOptions](#class-consolidationoutputformattersoptionsformatteroptions) $options) : mixed
Allow the formatter access to the raw structured data prior to restructuring. For example, the 'list' formatter may wish to display the row keys when provided table output. If this function returns a result that does not evaluate to 'false', then that result will be used as-is, and restructuring and validation will not occur. | +| public | renderData([\Consolidation\OutputFormatters\Formatters\FormatterInterface](#interface-consolidationoutputformattersformattersformatterinterface) $formatter, mixed $originalData, mixed $restructuredData, [\Consolidation\OutputFormatters\Options\FormatterOptions](#class-consolidationoutputformattersoptionsformatteroptions) $options) : mixed
Render the data as necessary (e.g. to select or reorder fields). | +| public | restructureData(mixed $structuredOutput, [\Consolidation\OutputFormatters\Options\FormatterOptions](#class-consolidationoutputformattersoptionsformatteroptions) $options) : mixed
Restructure the data as necessary (e.g. to select or reorder fields). | +| public | validFormats(mixed $dataType) : array
Return the identifiers for all valid data types that have been registered. | +| public | validateData([\Consolidation\OutputFormatters\Formatters\FormatterInterface](#interface-consolidationoutputformattersformattersformatterinterface) $formatter, mixed $structuredOutput, [\Consolidation\OutputFormatters\Options\FormatterOptions](#class-consolidationoutputformattersoptionsformatteroptions) $options) : mixed
Determine if the provided data is compatible with the formatter being used. | +| public | write(\Symfony\Component\Console\Output\OutputInterface $output, string $format, mixed $structuredOutput, [\Consolidation\OutputFormatters\Options\FormatterOptions](#class-consolidationoutputformattersoptionsformatteroptions) $options) : void
Format and write output | +| protected | availableFieldsList(mixed $availableFields) : string[]
Given a list of available fields, return a list of field descriptions. | +| protected | canSimplifyToArray([\ReflectionClass](http://php.net/manual/en/class.reflectionclass.php) $structuredOutput) : bool | +| protected | simplifyToArray(mixed $structuredOutput, [\Consolidation\OutputFormatters\Options\FormatterOptions](#class-consolidationoutputformattersoptionsformatteroptions) $options) : void | +| protected | validateAndRestructure([\Consolidation\OutputFormatters\Formatters\FormatterInterface](#interface-consolidationoutputformattersformattersformatterinterface) $formatter, mixed $structuredOutput, [\Consolidation\OutputFormatters\Options\FormatterOptions](#class-consolidationoutputformattersoptionsformatteroptions) $options) : void | + +
+### Class: \Consolidation\OutputFormatters\Exception\AbstractDataFormatException (abstract) + +> Contains some helper functions used by exceptions in this project. + +| Visibility | Function | +|:-----------|:---------| +| protected static | describeAllowedTypes(mixed $allowedTypes) : void | +| protected static | describeDataType([\ReflectionClass](http://php.net/manual/en/class.reflectionclass.php) $data) : string
Return a description of the data type represented by the provided parameter. \ArrayObject is used as a proxy to mean an array primitive (or an ArrayObject). | +| protected static | describeListOfAllowedTypes(mixed $allowedTypes) : void | + +*This class extends \Exception* + +*This class implements \Throwable* + +
+### Class: \Consolidation\OutputFormatters\Exception\IncompatibleDataException + +> Represents an incompatibility between the output data and selected formatter. + +| Visibility | Function | +|:-----------|:---------| +| public | __construct([\Consolidation\OutputFormatters\Formatters\FormatterInterface](#interface-consolidationoutputformattersformattersformatterinterface) $formatter, mixed $data, mixed $allowedTypes) : void | + +*This class extends [\Consolidation\OutputFormatters\Exception\AbstractDataFormatException](#class-consolidationoutputformattersexceptionabstractdataformatexception-abstract)* + +*This class implements \Throwable* + +
+### Class: \Consolidation\OutputFormatters\Exception\InvalidFormatException + +> Represents an incompatibility between the output data and selected formatter. + +| Visibility | Function | +|:-----------|:---------| +| public | __construct(mixed $format, mixed $data, mixed $validFormats) : void | + +*This class extends [\Consolidation\OutputFormatters\Exception\AbstractDataFormatException](#class-consolidationoutputformattersexceptionabstractdataformatexception-abstract)* + +*This class implements \Throwable* + +
+### Class: \Consolidation\OutputFormatters\Exception\UnknownFieldException + +> Indicates that the requested format does not exist. + +| Visibility | Function | +|:-----------|:---------| +| public | __construct(mixed $field) : void | + +*This class extends \Exception* + +*This class implements \Throwable* + +
+### Class: \Consolidation\OutputFormatters\Exception\UnknownFormatException + +> Indicates that the requested format does not exist. + +| Visibility | Function | +|:-----------|:---------| +| public | __construct(mixed $format) : void | + +*This class extends \Exception* + +*This class implements \Throwable* + +
+### Class: \Consolidation\OutputFormatters\Formatters\CsvFormatter + +> Comma-separated value formatters Display the provided structured data in a comma-separated list. If there are multiple records provided, then they will be printed one per line. The primary data types accepted are RowsOfFields and PropertyList. The later behaves exactly like the former, save for the fact that it contains but a single row. This formmatter can also accept a PHP array; this is also interpreted as a single-row of data with no header. + +| Visibility | Function | +|:-----------|:---------| +| public | isValidDataType([\ReflectionClass](http://php.net/manual/en/class.reflectionclass.php) $dataType) : bool
Return the list of data types acceptable to this formatter | +| public | renderData(mixed $originalData, mixed $restructuredData, [\Consolidation\OutputFormatters\Options\FormatterOptions](#class-consolidationoutputformattersoptionsformatteroptions) $options) : mixed
Convert the contents of the output data just before it is to be printed, prior to output but after restructuring and validation. | +| public | validDataTypes() : void | +| public | validate(mixed $structuredData) : void | +| public | write(\Symfony\Component\Console\Output\OutputInterface $output, mixed $data, [\Consolidation\OutputFormatters\Options\FormatterOptions](#class-consolidationoutputformattersoptionsformatteroptions) $options) : string
Given structured data, apply appropriate formatting, and return a printable string. | +| protected | csvEscape(mixed $data, string $delimiter=`','`) : void | +| protected | getDefaultFormatterOptions() : array
Return default values for formatter options | +| protected | renderEachCell(mixed $originalData, mixed $restructuredData, [\Consolidation\OutputFormatters\Options\FormatterOptions](#class-consolidationoutputformattersoptionsformatteroptions) $options) : void | +| protected | writeOneLine(\Symfony\Component\Console\Output\OutputInterface $output, mixed $data, mixed $options) : void | + +*This class implements [\Consolidation\OutputFormatters\Formatters\FormatterInterface](#interface-consolidationoutputformattersformattersformatterinterface), [\Consolidation\OutputFormatters\Validate\ValidDataTypesInterface](#interface-consolidationoutputformattersvalidatevaliddatatypesinterface), [\Consolidation\OutputFormatters\Validate\ValidationInterface](#interface-consolidationoutputformattersvalidatevalidationinterface), [\Consolidation\OutputFormatters\Formatters\RenderDataInterface](#interface-consolidationoutputformattersformattersrenderdatainterface)* + +
+### Interface: \Consolidation\OutputFormatters\Formatters\FormatterInterface + +| Visibility | Function | +|:-----------|:---------| +| public | write(\Symfony\Component\Console\Output\OutputInterface $output, mixed $data, [\Consolidation\OutputFormatters\Options\FormatterOptions](#class-consolidationoutputformattersoptionsformatteroptions) $options) : string
Given structured data, apply appropriate formatting, and return a printable string. | + +
+### Class: \Consolidation\OutputFormatters\Formatters\JsonFormatter + +> Json formatter Convert an array or ArrayObject into Json. + +| Visibility | Function | +|:-----------|:---------| +| public | write(\Symfony\Component\Console\Output\OutputInterface $output, mixed $data, [\Consolidation\OutputFormatters\Options\FormatterOptions](#class-consolidationoutputformattersoptionsformatteroptions) $options) : string
Given structured data, apply appropriate formatting, and return a printable string. | + +*This class implements [\Consolidation\OutputFormatters\Formatters\FormatterInterface](#interface-consolidationoutputformattersformattersformatterinterface)* + +
+### Class: \Consolidation\OutputFormatters\Formatters\ListFormatter + +> Display the data in a simple list. This formatter prints a plain, unadorned list of data, with each data item appearing on a separate line. If you wish your list to contain headers, then use the table formatter, and wrap your data in an PropertyList. + +| Visibility | Function | +|:-----------|:---------| +| public | overrideRestructure(mixed $structuredOutput, [\Consolidation\OutputFormatters\Options\FormatterOptions](#class-consolidationoutputformattersoptionsformatteroptions) $options) : mixed
Select data to use directly from the structured output, before the restructure operation has been executed. | +| public | renderData(mixed $originalData, mixed $restructuredData, [\Consolidation\OutputFormatters\Options\FormatterOptions](#class-consolidationoutputformattersoptionsformatteroptions) $options) : mixed
Convert the contents of the output data just before it is to be printed, prior to output but after restructuring and validation. | +| public | write(\Symfony\Component\Console\Output\OutputInterface $output, mixed $data, [\Consolidation\OutputFormatters\Options\FormatterOptions](#class-consolidationoutputformattersoptionsformatteroptions) $options) : string
Given structured data, apply appropriate formatting, and return a printable string. | +| protected | renderEachCell(mixed $originalData, mixed $restructuredData, [\Consolidation\OutputFormatters\Options\FormatterOptions](#class-consolidationoutputformattersoptionsformatteroptions) $options) : void | + +*This class implements [\Consolidation\OutputFormatters\Formatters\FormatterInterface](#interface-consolidationoutputformattersformattersformatterinterface), [\Consolidation\OutputFormatters\Transformations\OverrideRestructureInterface](#interface-consolidationoutputformatterstransformationsoverriderestructureinterface), [\Consolidation\OutputFormatters\Formatters\RenderDataInterface](#interface-consolidationoutputformattersformattersrenderdatainterface)* + +
+### Class: \Consolidation\OutputFormatters\Formatters\PrintRFormatter + +> Print_r formatter Run provided date thruogh print_r. + +| Visibility | Function | +|:-----------|:---------| +| public | write(\Symfony\Component\Console\Output\OutputInterface $output, mixed $data, [\Consolidation\OutputFormatters\Options\FormatterOptions](#class-consolidationoutputformattersoptionsformatteroptions) $options) : string
Given structured data, apply appropriate formatting, and return a printable string. | + +*This class implements [\Consolidation\OutputFormatters\Formatters\FormatterInterface](#interface-consolidationoutputformattersformattersformatterinterface)* + +
+### Interface: \Consolidation\OutputFormatters\Formatters\RenderDataInterface + +| Visibility | Function | +|:-----------|:---------| +| public | renderData(mixed $originalData, mixed $restructuredData, [\Consolidation\OutputFormatters\Options\FormatterOptions](#class-consolidationoutputformattersoptionsformatteroptions) $options) : mixed
Convert the contents of the output data just before it is to be printed, prior to output but after restructuring and validation. | + +
+### Class: \Consolidation\OutputFormatters\Formatters\SectionsFormatter + +> Display sections of data. This formatter takes data in the RowsOfFields data type. Each row represents one section; the data in each section is rendered in two columns, with the key in the first column and the value in the second column. + +| Visibility | Function | +|:-----------|:---------| +| public | isValidDataType([\ReflectionClass](http://php.net/manual/en/class.reflectionclass.php) $dataType) : bool
Return the list of data types acceptable to this formatter | +| public | renderData(mixed $originalData, mixed $restructuredData, [\Consolidation\OutputFormatters\Options\FormatterOptions](#class-consolidationoutputformattersoptionsformatteroptions) $options) : mixed
Convert the contents of the output data just before it is to be printed, prior to output but after restructuring and validation. | +| public | validDataTypes() : void | +| public | validate(mixed $structuredData) : mixed
Throw an IncompatibleDataException if the provided data cannot be processed by this formatter. Return the source data if it is valid. The data may be encapsulated or converted if necessary. | +| public | write(\Symfony\Component\Console\Output\OutputInterface $output, mixed $data, [\Consolidation\OutputFormatters\Options\FormatterOptions](#class-consolidationoutputformattersoptionsformatteroptions) $options) : string
Given structured data, apply appropriate formatting, and return a printable string. | +| protected | renderEachCell(mixed $originalData, mixed $restructuredData, [\Consolidation\OutputFormatters\Options\FormatterOptions](#class-consolidationoutputformattersoptionsformatteroptions) $options) : void | + +*This class implements [\Consolidation\OutputFormatters\Formatters\FormatterInterface](#interface-consolidationoutputformattersformattersformatterinterface), [\Consolidation\OutputFormatters\Validate\ValidDataTypesInterface](#interface-consolidationoutputformattersvalidatevaliddatatypesinterface), [\Consolidation\OutputFormatters\Validate\ValidationInterface](#interface-consolidationoutputformattersvalidatevalidationinterface), [\Consolidation\OutputFormatters\Formatters\RenderDataInterface](#interface-consolidationoutputformattersformattersrenderdatainterface)* + +
+### Class: \Consolidation\OutputFormatters\Formatters\SerializeFormatter + +> Serialize formatter Run provided date thruogh serialize. + +| Visibility | Function | +|:-----------|:---------| +| public | write(\Symfony\Component\Console\Output\OutputInterface $output, mixed $data, [\Consolidation\OutputFormatters\Options\FormatterOptions](#class-consolidationoutputformattersoptionsformatteroptions) $options) : string
Given structured data, apply appropriate formatting, and return a printable string. | + +*This class implements [\Consolidation\OutputFormatters\Formatters\FormatterInterface](#interface-consolidationoutputformattersformattersformatterinterface)* + +
+### Class: \Consolidation\OutputFormatters\Formatters\StringFormatter + +> String formatter This formatter is used as the default action when no particular formatter is requested. It will print the provided data only if it is a string; if any other type is given, then nothing is printed. + +| Visibility | Function | +|:-----------|:---------| +| public | isValidDataType([\ReflectionClass](http://php.net/manual/en/class.reflectionclass.php) $dataType) : bool
All data types are acceptable. | +| public | overrideOptions(mixed $structuredOutput, [\Consolidation\OutputFormatters\Options\FormatterOptions](#class-consolidationoutputformattersoptionsformatteroptions) $options) : [\Consolidation\OutputFormatters\Options\FormatterOptions](#class-consolidationoutputformattersoptionsformatteroptions)
Allow the formatter to mess with the configuration options before any transformations et. al. get underway. | +| public | validate(mixed $structuredData) : void
Always validate any data, though. This format will never cause an error if it is selected for an incompatible data type; at worse, it simply does not print any data. | +| public | write(\Symfony\Component\Console\Output\OutputInterface $output, mixed $data, [\Consolidation\OutputFormatters\Options\FormatterOptions](#class-consolidationoutputformattersoptionsformatteroptions) $options) : string
Given structured data, apply appropriate formatting, and return a printable string. | +| protected | reduceToSigleFieldAndWrite(\Symfony\Component\Console\Output\OutputInterface $output, mixed $data, [\Consolidation\OutputFormatters\Options\FormatterOptions](#class-consolidationoutputformattersoptionsformatteroptions) $options) : void
If the data provided to a 'string' formatter is a table, then try to emit it as a TSV value. | + +*This class implements [\Consolidation\OutputFormatters\Formatters\FormatterInterface](#interface-consolidationoutputformattersformattersformatterinterface), [\Consolidation\OutputFormatters\Validate\ValidationInterface](#interface-consolidationoutputformattersvalidatevalidationinterface), [\Consolidation\OutputFormatters\Options\OverrideOptionsInterface](#interface-consolidationoutputformattersoptionsoverrideoptionsinterface)* + +
+### Class: \Consolidation\OutputFormatters\Formatters\TableFormatter + +> Display a table of data with the Symfony Table class. This formatter takes data of either the RowsOfFields or PropertyList data type. Tables can be rendered with the rows running either vertically (the normal orientation) or horizontally. By default, associative lists will be displayed as two columns, with the key in the first column and the value in the second column. + +| Visibility | Function | +|:-----------|:---------| +| public | __construct() : void | +| public | isValidDataType([\ReflectionClass](http://php.net/manual/en/class.reflectionclass.php) $dataType) : bool
Return the list of data types acceptable to this formatter | +| public | renderData(mixed $originalData, mixed $restructuredData, [\Consolidation\OutputFormatters\Options\FormatterOptions](#class-consolidationoutputformattersoptionsformatteroptions) $options) : mixed
Convert the contents of the output data just before it is to be printed, prior to output but after restructuring and validation. | +| public | validDataTypes() : void | +| public | validate(mixed $structuredData) : mixed
Throw an IncompatibleDataException if the provided data cannot be processed by this formatter. Return the source data if it is valid. The data may be encapsulated or converted if necessary. | +| public | write(\Symfony\Component\Console\Output\OutputInterface $output, mixed $data, [\Consolidation\OutputFormatters\Options\FormatterOptions](#class-consolidationoutputformattersoptionsformatteroptions) $options) : string
Given structured data, apply appropriate formatting, and return a printable string. | +| protected static | addCustomTableStyles(mixed $table) : void
Add our custom table style(s) to the table. | +| protected | renderEachCell(mixed $originalData, mixed $restructuredData, [\Consolidation\OutputFormatters\Options\FormatterOptions](#class-consolidationoutputformattersoptionsformatteroptions) $options) : void | +| protected | wrap(mixed $headers, array $data, \Symfony\Component\Console\Helper\TableStyle $tableStyle, [\Consolidation\OutputFormatters\Options\FormatterOptions](#class-consolidationoutputformattersoptionsformatteroptions) $options) : array
Wrap the table data | + +*This class implements [\Consolidation\OutputFormatters\Formatters\FormatterInterface](#interface-consolidationoutputformattersformattersformatterinterface), [\Consolidation\OutputFormatters\Validate\ValidDataTypesInterface](#interface-consolidationoutputformattersvalidatevaliddatatypesinterface), [\Consolidation\OutputFormatters\Validate\ValidationInterface](#interface-consolidationoutputformattersvalidatevalidationinterface), [\Consolidation\OutputFormatters\Formatters\RenderDataInterface](#interface-consolidationoutputformattersformattersrenderdatainterface)* + +
+### Class: \Consolidation\OutputFormatters\Formatters\TsvFormatter + +> Tab-separated value formatters Display the provided structured data in a tab-separated list. Output escaping is much lighter, since there is no allowance for altering the delimiter. + +| Visibility | Function | +|:-----------|:---------| +| public | renderData(mixed $originalData, mixed $restructuredData, [\Consolidation\OutputFormatters\Options\FormatterOptions](#class-consolidationoutputformattersoptionsformatteroptions) $options) : mixed
Convert the contents of the output data just before it is to be printed, prior to output but after restructuring and validation. | +| public | write(\Symfony\Component\Console\Output\OutputInterface $output, mixed $data, [\Consolidation\OutputFormatters\Options\FormatterOptions](#class-consolidationoutputformattersoptionsformatteroptions) $options) : string
Given structured data, apply appropriate formatting, and return a printable string. | +| protected | getDefaultFormatterOptions() : mixed | +| protected | tsvEscape(mixed $data) : void | +| protected | writeOneLine(\Symfony\Component\Console\Output\OutputInterface $output, mixed $data, mixed $options) : void | + +*This class extends [\Consolidation\OutputFormatters\Formatters\CsvFormatter](#class-consolidationoutputformattersformatterscsvformatter)* + +*This class implements [\Consolidation\OutputFormatters\Formatters\RenderDataInterface](#interface-consolidationoutputformattersformattersrenderdatainterface), [\Consolidation\OutputFormatters\Validate\ValidationInterface](#interface-consolidationoutputformattersvalidatevalidationinterface), [\Consolidation\OutputFormatters\Validate\ValidDataTypesInterface](#interface-consolidationoutputformattersvalidatevaliddatatypesinterface), [\Consolidation\OutputFormatters\Formatters\FormatterInterface](#interface-consolidationoutputformattersformattersformatterinterface)* + +
+### Class: \Consolidation\OutputFormatters\Formatters\VarExportFormatter + +> Var_export formatter Run provided date thruogh var_export. + +| Visibility | Function | +|:-----------|:---------| +| public | write(\Symfony\Component\Console\Output\OutputInterface $output, mixed $data, [\Consolidation\OutputFormatters\Options\FormatterOptions](#class-consolidationoutputformattersoptionsformatteroptions) $options) : string
Given structured data, apply appropriate formatting, and return a printable string. | + +*This class implements [\Consolidation\OutputFormatters\Formatters\FormatterInterface](#interface-consolidationoutputformattersformattersformatterinterface)* + +
+### Class: \Consolidation\OutputFormatters\Formatters\XmlFormatter + +> Display a table of data with the Symfony Table class. This formatter takes data of either the RowsOfFields or PropertyList data type. Tables can be rendered with the rows running either vertically (the normal orientation) or horizontally. By default, associative lists will be displayed as two columns, with the key in the first column and the value in the second column. + +| Visibility | Function | +|:-----------|:---------| +| public | __construct() : void | +| public | isValidDataType([\ReflectionClass](http://php.net/manual/en/class.reflectionclass.php) $dataType) : bool
Return the list of data types acceptable to this formatter | +| public | validDataTypes() : void | +| public | validate(mixed $structuredData) : mixed
Throw an IncompatibleDataException if the provided data cannot be processed by this formatter. Return the source data if it is valid. The data may be encapsulated or converted if necessary. | +| public | write(\Symfony\Component\Console\Output\OutputInterface $output, mixed $data, [\Consolidation\OutputFormatters\Options\FormatterOptions](#class-consolidationoutputformattersoptionsformatteroptions) $options) : string
Given structured data, apply appropriate formatting, and return a printable string. | + +*This class implements [\Consolidation\OutputFormatters\Formatters\FormatterInterface](#interface-consolidationoutputformattersformattersformatterinterface), [\Consolidation\OutputFormatters\Validate\ValidDataTypesInterface](#interface-consolidationoutputformattersvalidatevaliddatatypesinterface), [\Consolidation\OutputFormatters\Validate\ValidationInterface](#interface-consolidationoutputformattersvalidatevalidationinterface)* + +
+### Class: \Consolidation\OutputFormatters\Formatters\YamlFormatter + +> Yaml formatter Convert an array or ArrayObject into Yaml. + +| Visibility | Function | +|:-----------|:---------| +| public | write(\Symfony\Component\Console\Output\OutputInterface $output, mixed $data, [\Consolidation\OutputFormatters\Options\FormatterOptions](#class-consolidationoutputformattersoptionsformatteroptions) $options) : string
Given structured data, apply appropriate formatting, and return a printable string. | + +*This class implements [\Consolidation\OutputFormatters\Formatters\FormatterInterface](#interface-consolidationoutputformattersformattersformatterinterface)* + +
+### Class: \Consolidation\OutputFormatters\Options\FormatterOptions + +> FormetterOptions holds information that affects the way a formatter renders its output. There are three places where a formatter might get options from: 1. Configuration associated with the command that produced the output. This is passed in to FormatterManager::write() along with the data to format. It might originally come from annotations on the command, or it might come from another source. Examples include the field labels for a table, or the default list of fields to display. 2. Options specified by the user, e.g. by commandline options. 3. Default values associated with the formatter itself. This class caches configuration from sources (1) and (2), and expects to be provided the defaults, (3), whenever a value is requested. + +| Visibility | Function | +|:-----------|:---------| +| public | __construct(array $configurationData=array(), array $options=array()) : void
Create a new FormatterOptions with the configuration data and the user-specified options for this request. | +| public | get(string $key, array $defaults=array(), bool/mixed $default=false) : mixed
Get a formatter option | +| public | getConfigurationData() : array
Return a reference to the configuration data for this object. | +| public | getFormat(array $defaults=array()) : string
Determine the format that was requested by the caller. | +| public | getInputOptions(array $defaults) : array
Return all of the options from the provided $defaults array that exist in our InputInterface object. | +| public | getOptions() : array
Return a reference to the user-specified options for this request. | +| public | getXmlSchema() : [\Consolidation\OutputFormatters\StructuredData\Xml\XmlSchema](#class-consolidationoutputformattersstructureddataxmlxmlschema)
Return the XmlSchema to use with --format=xml for data types that support that. This is used when an array needs to be converted into xml. | +| public | override(array $configurationData) : [\Consolidation\OutputFormatters\Options\FormatterOptions](#class-consolidationoutputformattersoptionsformatteroptions)
Create a new FormatterOptions object with new configuration data (provided), and the same options data as this instance. | +| public | parsePropertyList(string $value) : array
Convert from a textual list to an array | +| public | setConfigurationData(array $configurationData) : [\Consolidation\OutputFormatters\Options\FormatterOptions](#class-consolidationoutputformattersoptionsformatteroptions)
Change the configuration data for this formatter options object. | +| public | setConfigurationDefault(string $key, mixed $value) : \Consolidation\OutputFormatters\Options\FormetterOptions
Change one configuration value for this formatter option, but only if it does not already have a value set. | +| public | setDefaultFields(mixed $fields) : void | +| public | setDefaultStringField(mixed $defaultStringField) : void | +| public | setFieldLabels(mixed $fieldLabels) : void | +| public | setIncludeFieldLables(mixed $includFieldLables) : void | +| public | setInput(\Symfony\Component\Console\Input\InputInterface $input) : \Consolidation\OutputFormatters\Options\type
Provide a Symfony Console InputInterface containing the user-specified options for this request. | +| public | setListOrientation(mixed $listOrientation) : void | +| public | setOption(string $key, mixed $value) : [\Consolidation\OutputFormatters\Options\FormatterOptions](#class-consolidationoutputformattersoptionsformatteroptions)
Change one option value specified by the user for this request. | +| public | setOptions(array $options) : [\Consolidation\OutputFormatters\Options\FormatterOptions](#class-consolidationoutputformattersoptionsformatteroptions)
Set all of the options that were specified by the user for this request. | +| public | setRowLabels(mixed $rowLabels) : void | +| public | setTableStyle(mixed $style) : void | +| public | setWidth(mixed $width) : void | +| protected | defaultsForKey(string $key, array $defaults, bool $default=false) : array
Reduce provided defaults to the single item identified by '$key', if it exists, or an empty array otherwise. | +| protected | fetch(string $key, array $defaults=array(), bool/mixed $default=false) : mixed
Look up a key, and return its raw value. | +| protected | fetchRawValues(array $defaults=array()) : array
Look up all of the items associated with the provided defaults. | +| protected | getOptionFormat(string $key) : string
Given a specific key, return the class method name of the parsing method for data stored under this key. | +| protected | parse(string $key, mixed $value) : mixed
Given the raw value for a specific key, do any type conversion (e.g. from a textual list to an array) needed for the data. | +| protected | setConfigurationValue(string $key, mixed $value) : \Consolidation\OutputFormatters\Options\FormetterOptions
Change one configuration value for this formatter option. | + +
+### Interface: \Consolidation\OutputFormatters\Options\OverrideOptionsInterface + +| Visibility | Function | +|:-----------|:---------| +| public | overrideOptions(mixed $structuredOutput, [\Consolidation\OutputFormatters\Options\FormatterOptions](#class-consolidationoutputformattersoptionsformatteroptions) $options) : [\Consolidation\OutputFormatters\Options\FormatterOptions](#class-consolidationoutputformattersoptionsformatteroptions)
Allow the formatter to mess with the configuration options before any transformations et. al. get underway. | + +
+### Class: \Consolidation\OutputFormatters\StructuredData\AbstractStructuredList (abstract) + +> Holds an array where each element of the array is one row, and each row contains an associative array where the keys are the field names, and the values are the field data. It is presumed that every row contains the same keys. + +| Visibility | Function | +|:-----------|:---------| +| public | __construct(mixed $data) : void | +| public | addRenderer([\Consolidation\OutputFormatters\StructuredData\RenderCellInterface](#interface-consolidationoutputformattersstructureddatarendercellinterface) $renderer, string $priority=`'normal'`) : \Consolidation\OutputFormatters\StructuredData\$this
Add a renderer | +| public | addRendererFunction(\callable $rendererFn, string $priority=`'normal'`) : \Consolidation\OutputFormatters\StructuredData\$this
Add a callable as a renderer | +| public | abstract getListData([\Consolidation\OutputFormatters\Options\FormatterOptions](#class-consolidationoutputformattersoptionsformatteroptions) $options) : mixed | +| public | renderCell(mixed $key, mixed $cellData, [\Consolidation\OutputFormatters\Options\FormatterOptions](#class-consolidationoutputformattersoptionsformatteroptions) $options, mixed $rowData) : void | +| public | abstract restructure([\Consolidation\OutputFormatters\Options\FormatterOptions](#class-consolidationoutputformattersoptionsformatteroptions) $options) : void | +| protected | createTableTransformation(mixed $data, mixed $options) : mixed | +| protected | defaultOptions() : array
A structured list may provide its own set of default options. These will be used in place of the command's default options (from the annotations) in instances where the user does not provide the options explicitly (on the commandline) or implicitly (via a configuration file). | +| protected | getFields(mixed $options, mixed $defaults) : mixed | +| protected | getReorderedFieldLabels(mixed $data, mixed $options, mixed $defaults) : mixed | +| protected | instantiateTableTransformation(mixed $data, mixed $fieldLabels, mixed $rowLabels) : void | + +*This class extends \ArrayObject* + +*This class implements \Countable, \Serializable, \ArrayAccess, \Traversable, \IteratorAggregate, [\Consolidation\OutputFormatters\StructuredData\RestructureInterface](#interface-consolidationoutputformattersstructureddatarestructureinterface), [\Consolidation\OutputFormatters\StructuredData\ListDataInterface](#interface-consolidationoutputformattersstructureddatalistdatainterface), [\Consolidation\OutputFormatters\StructuredData\RenderCellCollectionInterface](#interface-consolidationoutputformattersstructureddatarendercellcollectioninterface), [\Consolidation\OutputFormatters\StructuredData\RenderCellInterface](#interface-consolidationoutputformattersstructureddatarendercellinterface)* + +
+### Class: \Consolidation\OutputFormatters\StructuredData\AssociativeList + +> Old name for PropertyList class. + +| Visibility | Function | +|:-----------|:---------| + +*This class extends [\Consolidation\OutputFormatters\StructuredData\PropertyList](#class-consolidationoutputformattersstructureddatapropertylist)* + +*This class implements \Countable, \Serializable, \ArrayAccess, \Traversable, \IteratorAggregate, [\Consolidation\OutputFormatters\StructuredData\RestructureInterface](#interface-consolidationoutputformattersstructureddatarestructureinterface), [\Consolidation\OutputFormatters\StructuredData\ListDataInterface](#interface-consolidationoutputformattersstructureddatalistdatainterface), [\Consolidation\OutputFormatters\StructuredData\RenderCellCollectionInterface](#interface-consolidationoutputformattersstructureddatarendercellcollectioninterface), [\Consolidation\OutputFormatters\StructuredData\RenderCellInterface](#interface-consolidationoutputformattersstructureddatarendercellinterface)* + +
+### Class: \Consolidation\OutputFormatters\StructuredData\CallableRenderer + +| Visibility | Function | +|:-----------|:---------| +| public | __construct(\callable $renderFunction) : void | +| public | renderCell(mixed $key, mixed $cellData, [\Consolidation\OutputFormatters\Options\FormatterOptions](#class-consolidationoutputformattersoptionsformatteroptions) $options, mixed $rowData) : void | + +*This class implements [\Consolidation\OutputFormatters\StructuredData\RenderCellInterface](#interface-consolidationoutputformattersstructureddatarendercellinterface)* + +
+### Interface: \Consolidation\OutputFormatters\StructuredData\ListDataInterface + +| Visibility | Function | +|:-----------|:---------| +| public | getListData([\Consolidation\OutputFormatters\Options\FormatterOptions](#class-consolidationoutputformattersoptionsformatteroptions) $options) : array
Convert data to a format suitable for use in a list. By default, the array values will be used. Implement ListDataInterface to use some other criteria (e.g. array keys). | + +
+### Interface: \Consolidation\OutputFormatters\StructuredData\OriginalDataInterface + +| Visibility | Function | +|:-----------|:---------| +| public | getOriginalData() : mixed
Return the original data for this table. Used by any formatter that expects an array. | + +
+### Class: \Consolidation\OutputFormatters\StructuredData\PropertyList + +> Holds an array where each element of the array is one key : value pair. The keys must be unique, as is typically the case for associative arrays. + +| Visibility | Function | +|:-----------|:---------| +| public | getListData([\Consolidation\OutputFormatters\Options\FormatterOptions](#class-consolidationoutputformattersoptionsformatteroptions) $options) : mixed | +| public | restructure([\Consolidation\OutputFormatters\Options\FormatterOptions](#class-consolidationoutputformattersoptionsformatteroptions) $options) : \Consolidation\OutputFormatters\StructuredData\Consolidation\OutputFormatters\Transformations\TableTransformation
Restructure this data for output by converting it into a table transformation object. | +| protected | defaultOptions() : void | +| protected | instantiateTableTransformation(mixed $data, mixed $fieldLabels, mixed $rowLabels) : void | + +*This class extends [\Consolidation\OutputFormatters\StructuredData\AbstractStructuredList](#class-consolidationoutputformattersstructureddataabstractstructuredlist-abstract)* + +*This class implements [\Consolidation\OutputFormatters\StructuredData\RenderCellInterface](#interface-consolidationoutputformattersstructureddatarendercellinterface), [\Consolidation\OutputFormatters\StructuredData\RenderCellCollectionInterface](#interface-consolidationoutputformattersstructureddatarendercellcollectioninterface), [\Consolidation\OutputFormatters\StructuredData\ListDataInterface](#interface-consolidationoutputformattersstructureddatalistdatainterface), [\Consolidation\OutputFormatters\StructuredData\RestructureInterface](#interface-consolidationoutputformattersstructureddatarestructureinterface), \IteratorAggregate, \Traversable, \ArrayAccess, \Serializable, \Countable* + +
+### Interface: \Consolidation\OutputFormatters\StructuredData\RenderCellCollectionInterface + +| Visibility | Function | +|:-----------|:---------| +| public | addRenderer([\Consolidation\OutputFormatters\StructuredData\RenderCellInterface](#interface-consolidationoutputformattersstructureddatarendercellinterface) $renderer) : \Consolidation\OutputFormatters\StructuredData\$this
Add a renderer | + +*This class implements [\Consolidation\OutputFormatters\StructuredData\RenderCellInterface](#interface-consolidationoutputformattersstructureddatarendercellinterface)* + +
+### Interface: \Consolidation\OutputFormatters\StructuredData\RenderCellInterface + +| Visibility | Function | +|:-----------|:---------| +| public | renderCell(string $key, mixed $cellData, [\Consolidation\OutputFormatters\Options\FormatterOptions](#class-consolidationoutputformattersoptionsformatteroptions) $options, array $rowData) : mixed
Convert the contents of one table cell into a string, so that it may be placed in the table. Renderer should return the $cellData passed to it if it does not wish to process it. | + +
+### Interface: \Consolidation\OutputFormatters\StructuredData\RestructureInterface + +| Visibility | Function | +|:-----------|:---------| +| public | restructure([\Consolidation\OutputFormatters\Options\FormatterOptions](#class-consolidationoutputformattersoptionsformatteroptions) $options) : void
Allow structured data to be restructured -- i.e. to select fields to show, reorder fields, etc. | + +
+### Class: \Consolidation\OutputFormatters\StructuredData\RowsOfFields + +> Holds an array where each element of the array is one row, and each row contains an associative array where the keys are the field names, and the values are the field data. It is presumed that every row contains the same keys. + +| Visibility | Function | +|:-----------|:---------| +| public | getListData([\Consolidation\OutputFormatters\Options\FormatterOptions](#class-consolidationoutputformattersoptionsformatteroptions) $options) : mixed | +| public | restructure([\Consolidation\OutputFormatters\Options\FormatterOptions](#class-consolidationoutputformattersoptionsformatteroptions) $options) : \Consolidation\OutputFormatters\StructuredData\Consolidation\OutputFormatters\Transformations\TableTransformation
Restructure this data for output by converting it into a table transformation object. | +| protected | defaultOptions() : void | + +*This class extends [\Consolidation\OutputFormatters\StructuredData\AbstractStructuredList](#class-consolidationoutputformattersstructureddataabstractstructuredlist-abstract)* + +*This class implements [\Consolidation\OutputFormatters\StructuredData\RenderCellInterface](#interface-consolidationoutputformattersstructureddatarendercellinterface), [\Consolidation\OutputFormatters\StructuredData\RenderCellCollectionInterface](#interface-consolidationoutputformattersstructureddatarendercellcollectioninterface), [\Consolidation\OutputFormatters\StructuredData\ListDataInterface](#interface-consolidationoutputformattersstructureddatalistdatainterface), [\Consolidation\OutputFormatters\StructuredData\RestructureInterface](#interface-consolidationoutputformattersstructureddatarestructureinterface), \IteratorAggregate, \Traversable, \ArrayAccess, \Serializable, \Countable* + +
+### Interface: \Consolidation\OutputFormatters\StructuredData\TableDataInterface + +| Visibility | Function | +|:-----------|:---------| +| public | getOriginalData() : mixed
Return the original data for this table. Used by any formatter that is -not- a table. | +| public | getTableData(bool/boolean $includeRowKey=false) : array
Convert structured data into a form suitable for use by the table formatter. key from each row. | + +
+### Interface: \Consolidation\OutputFormatters\StructuredData\Xml\DomDataInterface + +| Visibility | Function | +|:-----------|:---------| +| public | getDomData() : [\DomDocument](http://php.net/manual/en/class.domdocument.php)
Convert data into a \DomDocument. | + +
+### Class: \Consolidation\OutputFormatters\StructuredData\Xml\XmlSchema + +| Visibility | Function | +|:-----------|:---------| +| public | __construct(array $elementList=array()) : void | +| public | arrayToXML(mixed $structuredData) : void | +| protected | addXmlChildren([\DOMDocument](http://php.net/manual/en/class.domdocument.php) $dom, mixed $xmlParent, mixed $elementName, mixed $structuredData) : void | +| protected | addXmlData([\DOMDocument](http://php.net/manual/en/class.domdocument.php) $dom, mixed $xmlParent, mixed $elementName, mixed $structuredData) : void | +| protected | addXmlDataOrAttribute([\DOMDocument](http://php.net/manual/en/class.domdocument.php) $dom, mixed $xmlParent, mixed $elementName, mixed $key, mixed $value) : void | +| protected | getDefaultElementName(mixed $parentElementName) : mixed | +| protected | getTopLevelElementName(mixed $structuredData) : mixed | +| protected | inElementList(mixed $parentElementName, mixed $elementName) : void | +| protected | isAssoc(mixed $data) : bool | +| protected | isAttribute(mixed $parentElementName, mixed $elementName, mixed $value) : bool | +| protected | singularForm(mixed $name) : void | + +*This class implements [\Consolidation\OutputFormatters\StructuredData\Xml\XmlSchemaInterface](#interface-consolidationoutputformattersstructureddataxmlxmlschemainterface)* + +
+### Interface: \Consolidation\OutputFormatters\StructuredData\Xml\XmlSchemaInterface + +> When using arrays, we could represent XML data in a number of different ways. For example, given the following XML data strucutre: blah a b c This could be: [ 'id' => 1, 'name' => 'doc', 'foobars' => [ [ 'id' => '123', 'name' => 'blah', 'widgets' => [ [ 'foo' => 'a', 'bar' => 'b', 'baz' => 'c', ] ], ], ] ] The challenge is more in going from an array back to the more structured xml format. Note that any given key => string mapping could represent either an attribute, or a simple XML element containing only a string value. In general, we do *not* want to add extra layers of nesting in the data structure to disambiguate between these kinds of data, as we want the source data to render cleanly into other formats, e.g. yaml, json, et. al., and we do not want to force every data provider to have to consider the optimal xml schema for their data. Our strategy, therefore, is to expect clients that wish to provide a very specific xml representation to return a DOMDocument, and, for other data structures where xml is a secondary concern, then we will use some default heuristics to convert from arrays to xml. + +| Visibility | Function | +|:-----------|:---------| +| public | arrayToXml(mixed $structuredData) : [\DOMDocument](http://php.net/manual/en/class.domdocument.php)
Convert data to a format suitable for use in a list. By default, the array values will be used. Implement ListDataInterface to use some other criteria (e.g. array keys). | + +
+### Class: \Consolidation\OutputFormatters\Transformations\DomToArraySimplifier + +> Simplify a DOMDocument to an array. + +| Visibility | Function | +|:-----------|:---------| +| public | __construct() : void | +| public | canSimplify([\ReflectionClass](http://php.net/manual/en/class.reflectionclass.php) $dataType) : bool | +| public | simplifyToArray(mixed $structuredData, [\Consolidation\OutputFormatters\Options\FormatterOptions](#class-consolidationoutputformattersoptionsformatteroptions) $options) : void | +| protected | elementToArray([\DOMNode](http://php.net/manual/en/class.domnode.php) $element) : array
Recursively convert the provided DOM element into a php array. | +| protected | getNodeAttributes([\DOMNode](http://php.net/manual/en/class.domnode.php) $element) : array
Get all of the attributes of the provided element. | +| protected | getNodeChildren([\DOMNode](http://php.net/manual/en/class.domnode.php) $element) : array
Get all of the children of the provided element, with simplification. | +| protected | getNodeChildrenData([\DOMNode](http://php.net/manual/en/class.domnode.php) $element) : array
Get the data from the children of the provided node in preliminary form. | +| protected | getUniformChildren(string $parentKey, [\DOMNode](http://php.net/manual/en/class.domnode.php) $element) : array
Convert the children of the provided DOM element into an array. Here, 'uniform' means that all of the element names of the children are identical, and further, the element name of the parent is the plural form of the child names. When the children are uniform in this way, then the parent element name will be used as the key to store the children in, and the child list will be returned as a simple list with their (duplicate) element names omitted. | +| protected | getUniqueChildren(string $parentKey, [\DOMNode](http://php.net/manual/en/class.domnode.php) $element) : array
Convert the children of the provided DOM element into an array. Here, 'unique' means that all of the element names of the children are different. Since the element names will become the key of the associative array that is returned, so duplicates are not supported. If there are any duplicates, then an exception will be thrown. | +| protected | hasUniformChildren([\DOMNode](http://php.net/manual/en/class.domnode.php) $element) : boolean
Determine whether the children of the provided element are uniform. | +| protected | valueCanBeSimplified([\DOMNode](http://php.net/manual/en/class.domnode.php) $value) : boolean
Determine whether the provided value has additional unnecessary nesting. {"color": "red"} is converted to "red". No other simplification is done. | + +*This class implements [\Consolidation\OutputFormatters\Transformations\SimplifyToArrayInterface](#interface-consolidationoutputformatterstransformationssimplifytoarrayinterface)* + +
+### Interface: \Consolidation\OutputFormatters\Transformations\OverrideRestructureInterface + +| Visibility | Function | +|:-----------|:---------| +| public | overrideRestructure(mixed $structuredOutput, [\Consolidation\OutputFormatters\Options\FormatterOptions](#class-consolidationoutputformattersoptionsformatteroptions) $options) : mixed
Select data to use directly from the structured output, before the restructure operation has been executed. | + +
+### Class: \Consolidation\OutputFormatters\Transformations\PropertyListTableTransformation + +| Visibility | Function | +|:-----------|:---------| +| public | getOriginalData() : mixed | + +*This class extends [\Consolidation\OutputFormatters\Transformations\TableTransformation](#class-consolidationoutputformatterstransformationstabletransformation)* + +*This class implements [\Consolidation\OutputFormatters\StructuredData\OriginalDataInterface](#interface-consolidationoutputformattersstructureddataoriginaldatainterface), [\Consolidation\OutputFormatters\StructuredData\TableDataInterface](#interface-consolidationoutputformattersstructureddatatabledatainterface), \IteratorAggregate, \Traversable, \ArrayAccess, \Serializable, \Countable* + +
+### Class: \Consolidation\OutputFormatters\Transformations\PropertyParser + +> Transform a string of properties into a PHP associative array. Input: one: red two: white three: blue Output: [ 'one' => 'red', 'two' => 'white', 'three' => 'blue', ] + +| Visibility | Function | +|:-----------|:---------| +| public static | parse(mixed $data) : void | + +
+### Class: \Consolidation\OutputFormatters\Transformations\ReorderFields + +> Reorder the field labels based on the user-selected fields to display. + +| Visibility | Function | +|:-----------|:---------| +| public | reorder(string/array $fields, array $fieldLabels, array $data) : array
Given a simple list of user-supplied field keys or field labels, return a reordered version of the field labels matching the user selection. key to the field label | +| protected | convertToRegex(mixed $str) : void
Convert the provided string into a regex suitable for use in preg_match. Matching occurs in the same way as the Symfony Finder component: http://symfony.com/doc/current/components/finder.html#file-name | +| protected | getSelectedFieldKeys(mixed $fields, mixed $fieldLabels) : mixed | +| protected | isRegex(string $str) : bool Whether the given string is a regex
Checks whether the string is a regex. This function is copied from MultiplePcreFilterIterator in the Symfony Finder component. | +| protected | matchFieldInLabelMap(mixed $field, mixed $fieldLabels) : void | +| protected | reorderFieldLabels(mixed $fields, mixed $fieldLabels, mixed $data) : void | + +
+### Interface: \Consolidation\OutputFormatters\Transformations\SimplifyToArrayInterface + +| Visibility | Function | +|:-----------|:---------| +| public | canSimplify([\ReflectionClass](http://php.net/manual/en/class.reflectionclass.php) $structuredOutput) : bool
Indicate whether or not the given data type can be simplified to an array | +| public | simplifyToArray(mixed $structuredOutput, [\Consolidation\OutputFormatters\Options\FormatterOptions](#class-consolidationoutputformattersoptionsformatteroptions) $options) : array
Convert structured data into a generic array, usable by generic array-based formatters. Objects that implement this interface may be attached to the FormatterManager, and will be used on any data structure that needs to be simplified into an array. An array simplifier should take no action other than to return its input data if it cannot simplify the provided data into an array. | + +
+### Class: \Consolidation\OutputFormatters\Transformations\TableTransformation + +| Visibility | Function | +|:-----------|:---------| +| public | __construct(mixed $data, mixed $fieldLabels, array $rowLabels=array()) : void | +| public | getHeader(mixed $key) : mixed | +| public | getHeaders() : mixed | +| public | getLayout() : mixed | +| public | getOriginalData() : mixed | +| public | getRowLabel(mixed $rowid) : mixed | +| public | getRowLabels() : mixed | +| public | getTableData(bool $includeRowKey=false) : mixed | +| public | isList() : bool | +| public | setLayout(mixed $layout) : void | +| protected | convertTableToList() : void | +| protected | getRowDataWithKey(mixed $data) : mixed | +| protected static | transformRow(mixed $row, mixed $fieldLabels) : void | +| protected static | transformRows(mixed $data, mixed $fieldLabels) : void | + +*This class extends \ArrayObject* + +*This class implements \Countable, \Serializable, \ArrayAccess, \Traversable, \IteratorAggregate, [\Consolidation\OutputFormatters\StructuredData\TableDataInterface](#interface-consolidationoutputformattersstructureddatatabledatainterface), [\Consolidation\OutputFormatters\StructuredData\OriginalDataInterface](#interface-consolidationoutputformattersstructureddataoriginaldatainterface)* + +
+### Class: \Consolidation\OutputFormatters\Transformations\WordWrapper + +| Visibility | Function | +|:-----------|:---------| +| public | __construct(mixed $width) : void | +| 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 | wrapCell(mixed $cell, string $cellWidth) : mixed
Wrap one cell. Guard against modifying non-strings and then call through to wordwrap(). | + +
+### Interface: \Consolidation\OutputFormatters\Validate\ValidationInterface + +> Formatters may implement ValidationInterface in order to indicate whether a particular data structure is supported. Any formatter that does not implement ValidationInterface is assumed to only operate on arrays, or data types that implement SimplifyToArrayInterface. + +| Visibility | Function | +|:-----------|:---------| +| public | isValidDataType([\ReflectionClass](http://php.net/manual/en/class.reflectionclass.php) $dataType) : bool
Return true if the specified format is valid for use with this formatter. | +| public | validate(mixed $structuredData) : mixed
Throw an IncompatibleDataException if the provided data cannot be processed by this formatter. Return the source data if it is valid. The data may be encapsulated or converted if necessary. | + +
+### Interface: \Consolidation\OutputFormatters\Validate\ValidDataTypesInterface + +> Formatters may implement ValidDataTypesInterface in order to indicate exactly which formats they support. The validDataTypes method can be called to retrieve a list of data types useful in providing hints in exception messages about which data types can be used with the formatter. Note that it is OPTIONAL for formatters to implement this interface. If a formatter implements only ValidationInterface, then clients that request the formatter via FormatterManager::write() will still get a list (via an InvalidFormatException) of all of the formats that are usable with the provided data type. Implementing ValidDataTypesInterface is benefitial to clients who instantiate a formatter directly (via `new`). Formatters that implement ValidDataTypesInterface may wish to use ValidDataTypesTrait. + +| Visibility | Function | +|:-----------|:---------| +| public | validDataTypes() : [\ReflectionClass[]](http://php.net/manual/en/class.reflectionclass.php)
Return the list of data types acceptable to this formatter | + +*This class implements [\Consolidation\OutputFormatters\Validate\ValidationInterface](#interface-consolidationoutputformattersvalidatevalidationinterface)* + diff --git a/src/composer/vendor/consolidation/output-formatters/docs/index.md b/src/composer/vendor/consolidation/output-formatters/docs/index.md new file mode 100644 index 00000000..385392d1 --- /dev/null +++ b/src/composer/vendor/consolidation/output-formatters/docs/index.md @@ -0,0 +1,3 @@ +# Consolidation Output Formatters + +This is a placeholder for the output formatters documentation. diff --git a/src/composer/vendor/consolidation/output-formatters/mkdocs.yml b/src/composer/vendor/consolidation/output-formatters/mkdocs.yml new file mode 100644 index 00000000..4f36f2fa --- /dev/null +++ b/src/composer/vendor/consolidation/output-formatters/mkdocs.yml @@ -0,0 +1,7 @@ +site_name: Consolidation Output Formatters docs +theme: readthedocs +repo_url: https://github.com/consolidation/output-formatters +include_search: true +pages: +- Home: index.md +- API: api.md diff --git a/src/composer/vendor/consolidation/output-formatters/phpunit.xml.dist b/src/composer/vendor/consolidation/output-formatters/phpunit.xml.dist new file mode 100644 index 00000000..6f1cce7d --- /dev/null +++ b/src/composer/vendor/consolidation/output-formatters/phpunit.xml.dist @@ -0,0 +1,29 @@ + + + + tests + + + + + + + + + src + + FormatterInterface.php.php + OverrideRestructureInterface.php.php + RestructureInterface.php.php + ValidationInterface.php + Formatters/RenderDataInterface.php + StructuredData/ListDataInterface.php.php + StructuredData/RenderCellInterface.php.php + StructuredData/TableDataInterface.php.php + + + + diff --git a/src/composer/vendor/consolidation/output-formatters/src/Exception/AbstractDataFormatException.php b/src/composer/vendor/consolidation/output-formatters/src/Exception/AbstractDataFormatException.php new file mode 100644 index 00000000..fa29b1dd --- /dev/null +++ b/src/composer/vendor/consolidation/output-formatters/src/Exception/AbstractDataFormatException.php @@ -0,0 +1,57 @@ +getName() == 'ArrayObject')) { + return 'an array'; + } + return 'an instance of ' . $data->getName(); + } + if (is_string($data)) { + return 'a string'; + } + if (is_object($data)) { + return 'an instance of ' . get_class($data); + } + throw new \Exception("Undescribable data error: " . var_export($data, true)); + } + + protected static function describeAllowedTypes($allowedTypes) + { + if (is_array($allowedTypes) && !empty($allowedTypes)) { + if (count($allowedTypes) > 1) { + return static::describeListOfAllowedTypes($allowedTypes); + } + $allowedTypes = $allowedTypes[0]; + } + return static::describeDataType($allowedTypes); + } + + protected static function describeListOfAllowedTypes($allowedTypes) + { + $descriptions = []; + foreach ($allowedTypes as $oneAllowedType) { + $descriptions[] = static::describeDataType($oneAllowedType); + } + if (count($descriptions) == 2) { + return "either {$descriptions[0]} or {$descriptions[1]}"; + } + $lastDescription = array_pop($descriptions); + $otherDescriptions = implode(', ', $descriptions); + return "one of $otherDescriptions or $lastDescription"; + } +} diff --git a/src/composer/vendor/consolidation/output-formatters/src/Exception/IncompatibleDataException.php b/src/composer/vendor/consolidation/output-formatters/src/Exception/IncompatibleDataException.php new file mode 100644 index 00000000..ca13a65f --- /dev/null +++ b/src/composer/vendor/consolidation/output-formatters/src/Exception/IncompatibleDataException.php @@ -0,0 +1,19 @@ + '\Consolidation\OutputFormatters\Formatters\StringFormatter', + 'yaml' => '\Consolidation\OutputFormatters\Formatters\YamlFormatter', + 'xml' => '\Consolidation\OutputFormatters\Formatters\XmlFormatter', + 'json' => '\Consolidation\OutputFormatters\Formatters\JsonFormatter', + 'print-r' => '\Consolidation\OutputFormatters\Formatters\PrintRFormatter', + 'php' => '\Consolidation\OutputFormatters\Formatters\SerializeFormatter', + 'var_export' => '\Consolidation\OutputFormatters\Formatters\VarExportFormatter', + 'list' => '\Consolidation\OutputFormatters\Formatters\ListFormatter', + 'csv' => '\Consolidation\OutputFormatters\Formatters\CsvFormatter', + 'tsv' => '\Consolidation\OutputFormatters\Formatters\TsvFormatter', + 'table' => '\Consolidation\OutputFormatters\Formatters\TableFormatter', + 'sections' => '\Consolidation\OutputFormatters\Formatters\SectionsFormatter', + ]; + foreach ($defaultFormatters as $id => $formatterClassname) { + $formatter = new $formatterClassname; + $this->addFormatter($id, $formatter); + } + $this->addFormatter('', $this->formatters['string']); + } + + public function addDefaultSimplifiers() + { + // Add our default array simplifier (DOMDocument to array) + $this->addSimplifier(new DomToArraySimplifier()); + } + + /** + * Add a formatter + * + * @param string $key the identifier of the formatter to add + * @param string $formatter the class name of the formatter to add + * @return FormatterManager + */ + public function addFormatter($key, FormatterInterface $formatter) + { + $this->formatters[$key] = $formatter; + return $this; + } + + /** + * Add a simplifier + * + * @param SimplifyToArrayInterface $simplifier the array simplifier to add + * @return FormatterManager + */ + public function addSimplifier(SimplifyToArrayInterface $simplifier) + { + $this->arraySimplifiers[] = $simplifier; + return $this; + } + + /** + * Return a set of InputOption based on the annotations of a command. + * @param FormatterOptions $options + * @return InputOption[] + */ + public function automaticOptions(FormatterOptions $options, $dataType) + { + $automaticOptions = []; + + // At the moment, we only support automatic options for --format + // and --fields, so exit if the command returns no data. + if (!isset($dataType)) { + return []; + } + + $validFormats = $this->validFormats($dataType); + if (empty($validFormats)) { + return []; + } + + $availableFields = $options->get(FormatterOptions::FIELD_LABELS); + $hasDefaultStringField = $options->get(FormatterOptions::DEFAULT_STRING_FIELD); + $defaultFormat = $hasDefaultStringField ? 'string' : ($availableFields ? 'table' : 'yaml'); + + if (count($validFormats) > 1) { + // Make an input option for --format + $description = 'Format the result data. Available formats: ' . implode(',', $validFormats); + $automaticOptions[FormatterOptions::FORMAT] = new InputOption(FormatterOptions::FORMAT, '', InputOption::VALUE_OPTIONAL, $description, $defaultFormat); + } + + if ($availableFields) { + $defaultFields = $options->get(FormatterOptions::DEFAULT_FIELDS, [], ''); + $description = 'Available fields: ' . implode(', ', $this->availableFieldsList($availableFields)); + $automaticOptions[FormatterOptions::FIELDS] = new InputOption(FormatterOptions::FIELDS, '', InputOption::VALUE_OPTIONAL, $description, $defaultFields); + $automaticOptions[FormatterOptions::FIELD] = new InputOption(FormatterOptions::FIELD, '', InputOption::VALUE_OPTIONAL, "Select just one field, and force format to 'string'.", ''); + } + + return $automaticOptions; + } + + /** + * Given a list of available fields, return a list of field descriptions. + * @return string[] + */ + protected function availableFieldsList($availableFields) + { + return array_map( + function ($key) use ($availableFields) { + return $availableFields[$key] . " ($key)"; + }, + array_keys($availableFields) + ); + } + + /** + * Return the identifiers for all valid data types that have been registered. + * + * @param mixed $dataType \ReflectionObject or other description of the produced data type + * @return array + */ + public function validFormats($dataType) + { + $validFormats = []; + foreach ($this->formatters as $formatId => $formatterName) { + $formatter = $this->getFormatter($formatId); + if (!empty($formatId) && $this->isValidFormat($formatter, $dataType)) { + $validFormats[] = $formatId; + } + } + sort($validFormats); + return $validFormats; + } + + public function isValidFormat(FormatterInterface $formatter, $dataType) + { + if (is_array($dataType)) { + $dataType = new \ReflectionClass('\ArrayObject'); + } + if (!is_object($dataType) && !class_exists($dataType)) { + return false; + } + if (!$dataType instanceof \ReflectionClass) { + $dataType = new \ReflectionClass($dataType); + } + return $this->isValidDataType($formatter, $dataType); + } + + public function isValidDataType(FormatterInterface $formatter, \ReflectionClass $dataType) + { + if ($this->canSimplifyToArray($dataType)) { + if ($this->isValidFormat($formatter, [])) { + return true; + } + } + // If the formatter does not implement ValidationInterface, then + // it is presumed that the formatter only accepts arrays. + if (!$formatter instanceof ValidationInterface) { + return $dataType->isSubclassOf('ArrayObject') || ($dataType->getName() == 'ArrayObject'); + } + return $formatter->isValidDataType($dataType); + } + + /** + * Format and write output + * + * @param OutputInterface $output Output stream to write to + * @param string $format Data format to output in + * @param mixed $structuredOutput Data to output + * @param FormatterOptions $options Formatting options + */ + public function write(OutputInterface $output, $format, $structuredOutput, FormatterOptions $options) + { + $formatter = $this->getFormatter((string)$format); + if (!is_string($structuredOutput) && !$this->isValidFormat($formatter, $structuredOutput)) { + $validFormats = $this->validFormats($structuredOutput); + throw new InvalidFormatException((string)$format, $structuredOutput, $validFormats); + } + // Give the formatter a chance to override the options + $options = $this->overrideOptions($formatter, $structuredOutput, $options); + $structuredOutput = $this->validateAndRestructure($formatter, $structuredOutput, $options); + $formatter->write($output, $structuredOutput, $options); + } + + protected function validateAndRestructure(FormatterInterface $formatter, $structuredOutput, FormatterOptions $options) + { + // Give the formatter a chance to do something with the + // raw data before it is restructured. + $overrideRestructure = $this->overrideRestructure($formatter, $structuredOutput, $options); + if ($overrideRestructure) { + return $overrideRestructure; + } + + // Restructure the output data (e.g. select fields to display, etc.). + $restructuredOutput = $this->restructureData($structuredOutput, $options); + + // Make sure that the provided data is in the correct format for the selected formatter. + $restructuredOutput = $this->validateData($formatter, $restructuredOutput, $options); + + // Give the original data a chance to re-render the structured + // output after it has been restructured and validated. + $restructuredOutput = $this->renderData($formatter, $structuredOutput, $restructuredOutput, $options); + + return $restructuredOutput; + } + + /** + * Fetch the requested formatter. + * + * @param string $format Identifier for requested formatter + * @return FormatterInterface + */ + public function getFormatter($format) + { + // The client must inject at least one formatter before asking for + // any formatters; if not, we will provide all of the usual defaults + // as a convenience. + if (empty($this->formatters)) { + $this->addDefaultFormatters(); + $this->addDefaultSimplifiers(); + } + if (!$this->hasFormatter($format)) { + throw new UnknownFormatException($format); + } + $formatter = $this->formatters[$format]; + return $formatter; + } + + /** + * Test to see if the stipulated format exists + */ + public function hasFormatter($format) + { + return array_key_exists($format, $this->formatters); + } + + /** + * Render the data as necessary (e.g. to select or reorder fields). + * + * @param FormatterInterface $formatter + * @param mixed $originalData + * @param mixed $restructuredData + * @param FormatterOptions $options Formatting options + * @return mixed + */ + public function renderData(FormatterInterface $formatter, $originalData, $restructuredData, FormatterOptions $options) + { + if ($formatter instanceof RenderDataInterface) { + return $formatter->renderData($originalData, $restructuredData, $options); + } + return $restructuredData; + } + + /** + * Determine if the provided data is compatible with the formatter being used. + * + * @param FormatterInterface $formatter Formatter being used + * @param mixed $structuredOutput Data to validate + * @return mixed + */ + public function validateData(FormatterInterface $formatter, $structuredOutput, FormatterOptions $options) + { + // If the formatter implements ValidationInterface, then let it + // test the data and throw or return an error + if ($formatter instanceof ValidationInterface) { + return $formatter->validate($structuredOutput); + } + // If the formatter does not implement ValidationInterface, then + // it will never be passed an ArrayObject; we will always give + // it a simple array. + $structuredOutput = $this->simplifyToArray($structuredOutput, $options); + // If we could not simplify to an array, then throw an exception. + // We will never give a formatter anything other than an array + // unless it validates that it can accept the data type. + if (!is_array($structuredOutput)) { + throw new IncompatibleDataException( + $formatter, + $structuredOutput, + [] + ); + } + return $structuredOutput; + } + + protected function simplifyToArray($structuredOutput, FormatterOptions $options) + { + // We can do nothing unless the provided data is an object. + if (!is_object($structuredOutput)) { + return $structuredOutput; + } + // Check to see if any of the simplifiers can convert the given data + // set to an array. + $outputDataType = new \ReflectionClass($structuredOutput); + foreach ($this->arraySimplifiers as $simplifier) { + if ($simplifier->canSimplify($outputDataType)) { + $structuredOutput = $simplifier->simplifyToArray($structuredOutput, $options); + } + } + // Convert data structure back into its original form, if necessary. + if ($structuredOutput instanceof OriginalDataInterface) { + return $structuredOutput->getOriginalData(); + } + // Convert \ArrayObjects to a simple array. + if ($structuredOutput instanceof \ArrayObject) { + return $structuredOutput->getArrayCopy(); + } + return $structuredOutput; + } + + protected function canSimplifyToArray(\ReflectionClass $structuredOutput) + { + foreach ($this->arraySimplifiers as $simplifier) { + if ($simplifier->canSimplify($structuredOutput)) { + return true; + } + } + return false; + } + + /** + * Restructure the data as necessary (e.g. to select or reorder fields). + * + * @param mixed $structuredOutput + * @param FormatterOptions $options + * @return mixed + */ + public function restructureData($structuredOutput, FormatterOptions $options) + { + if ($structuredOutput instanceof RestructureInterface) { + return $structuredOutput->restructure($options); + } + return $structuredOutput; + } + + /** + * Allow the formatter access to the raw structured data prior + * to restructuring. For example, the 'list' formatter may wish + * to display the row keys when provided table output. If this + * function returns a result that does not evaluate to 'false', + * then that result will be used as-is, and restructuring and + * validation will not occur. + * + * @param mixed $structuredOutput + * @param FormatterOptions $options + * @return mixed + */ + public function overrideRestructure(FormatterInterface $formatter, $structuredOutput, FormatterOptions $options) + { + if ($formatter instanceof OverrideRestructureInterface) { + return $formatter->overrideRestructure($structuredOutput, $options); + } + } + + /** + * Allow the formatter to mess with the configuration options before any + * transformations et. al. get underway. + * @param FormatterInterface $formatter + * @param mixed $structuredOutput + * @param FormatterOptions $options + * @return FormatterOptions + */ + public function overrideOptions(FormatterInterface $formatter, $structuredOutput, FormatterOptions $options) + { + if ($formatter instanceof OverrideOptionsInterface) { + return $formatter->overrideOptions($structuredOutput, $options); + } + return $options; + } +} diff --git a/src/composer/vendor/consolidation/output-formatters/src/Formatters/CsvFormatter.php b/src/composer/vendor/consolidation/output-formatters/src/Formatters/CsvFormatter.php new file mode 100644 index 00000000..d39c27b4 --- /dev/null +++ b/src/composer/vendor/consolidation/output-formatters/src/Formatters/CsvFormatter.php @@ -0,0 +1,107 @@ +validDataTypes() + ); + } + // If the data was provided to us as a single array, then + // convert it to a single row. + if (is_array($structuredData) && !empty($structuredData)) { + $firstRow = reset($structuredData); + if (!is_array($firstRow)) { + return [$structuredData]; + } + } + return $structuredData; + } + + /** + * Return default values for formatter options + * @return array + */ + protected function getDefaultFormatterOptions() + { + return [ + FormatterOptions::INCLUDE_FIELD_LABELS => true, + FormatterOptions::DELIMITER => ',', + ]; + } + + /** + * @inheritdoc + */ + public function write(OutputInterface $output, $data, FormatterOptions $options) + { + $defaults = $this->getDefaultFormatterOptions(); + + $includeFieldLabels = $options->get(FormatterOptions::INCLUDE_FIELD_LABELS, $defaults); + if ($includeFieldLabels && ($data instanceof TableTransformation)) { + $headers = $data->getHeaders(); + $this->writeOneLine($output, $headers, $options); + } + + foreach ($data as $line) { + $this->writeOneLine($output, $line, $options); + } + } + + protected function writeOneLine(OutputInterface $output, $data, $options) + { + $defaults = $this->getDefaultFormatterOptions(); + $delimiter = $options->get(FormatterOptions::DELIMITER, $defaults); + + $output->write($this->csvEscape($data, $delimiter)); + } + + protected function csvEscape($data, $delimiter = ',') + { + $buffer = fopen('php://temp', 'r+'); + fputcsv($buffer, $data, $delimiter); + rewind($buffer); + $csv = fgets($buffer); + fclose($buffer); + return $csv; + } +} diff --git a/src/composer/vendor/consolidation/output-formatters/src/Formatters/FormatterInterface.php b/src/composer/vendor/consolidation/output-formatters/src/Formatters/FormatterInterface.php new file mode 100644 index 00000000..c0ad0823 --- /dev/null +++ b/src/composer/vendor/consolidation/output-formatters/src/Formatters/FormatterInterface.php @@ -0,0 +1,18 @@ +writeln(json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)); + } +} diff --git a/src/composer/vendor/consolidation/output-formatters/src/Formatters/ListFormatter.php b/src/composer/vendor/consolidation/output-formatters/src/Formatters/ListFormatter.php new file mode 100644 index 00000000..01fce524 --- /dev/null +++ b/src/composer/vendor/consolidation/output-formatters/src/Formatters/ListFormatter.php @@ -0,0 +1,59 @@ +writeln(implode("\n", $data)); + } + + /** + * @inheritdoc + */ + public function overrideRestructure($structuredOutput, FormatterOptions $options) + { + // If the structured data implements ListDataInterface, + // then we will render whatever data its 'getListData' + // method provides. + if ($structuredOutput instanceof ListDataInterface) { + return $this->renderData($structuredOutput, $structuredOutput->getListData($options), $options); + } + } + + /** + * @inheritdoc + */ + public function renderData($originalData, $restructuredData, FormatterOptions $options) + { + if ($originalData instanceof RenderCellInterface) { + return $this->renderEachCell($originalData, $restructuredData, $options); + } + return $restructuredData; + } + + protected function renderEachCell($originalData, $restructuredData, FormatterOptions $options) + { + foreach ($restructuredData as $key => $cellData) { + $restructuredData[$key] = $originalData->renderCell($key, $cellData, $options, $restructuredData); + } + return $restructuredData; + } +} diff --git a/src/composer/vendor/consolidation/output-formatters/src/Formatters/PrintRFormatter.php b/src/composer/vendor/consolidation/output-formatters/src/Formatters/PrintRFormatter.php new file mode 100644 index 00000000..57dce768 --- /dev/null +++ b/src/composer/vendor/consolidation/output-formatters/src/Formatters/PrintRFormatter.php @@ -0,0 +1,21 @@ +writeln(print_r($data, true)); + } +} diff --git a/src/composer/vendor/consolidation/output-formatters/src/Formatters/RenderDataInterface.php b/src/composer/vendor/consolidation/output-formatters/src/Formatters/RenderDataInterface.php new file mode 100644 index 00000000..a4da8e0e --- /dev/null +++ b/src/composer/vendor/consolidation/output-formatters/src/Formatters/RenderDataInterface.php @@ -0,0 +1,19 @@ +renderEachCell($originalData, $restructuredData, $options); + } + return $restructuredData; + } + + protected function renderEachCell($originalData, $restructuredData, FormatterOptions $options) + { + foreach ($restructuredData as $id => $row) { + foreach ($row as $key => $cellData) { + $restructuredData[$id][$key] = $originalData->renderCell($key, $cellData, $options, $row); + } + } + return $restructuredData; + } +} diff --git a/src/composer/vendor/consolidation/output-formatters/src/Formatters/SectionsFormatter.php b/src/composer/vendor/consolidation/output-formatters/src/Formatters/SectionsFormatter.php new file mode 100644 index 00000000..89ed2707 --- /dev/null +++ b/src/composer/vendor/consolidation/output-formatters/src/Formatters/SectionsFormatter.php @@ -0,0 +1,72 @@ +validDataTypes() + ); + } + return $structuredData; + } + + /** + * @inheritdoc + */ + public function write(OutputInterface $output, $tableTransformer, FormatterOptions $options) + { + $table = new Table($output); + $table->setStyle('compact'); + foreach ($tableTransformer as $rowid => $row) { + $rowLabel = $tableTransformer->getRowLabel($rowid); + $output->writeln(''); + $output->writeln($rowLabel); + $sectionData = new PropertyList($row); + $sectionOptions = new FormatterOptions([], $options->getOptions()); + $sectionTableTransformer = $sectionData->restructure($sectionOptions); + $table->setRows($sectionTableTransformer->getTableData(true)); + $table->render(); + } + } +} diff --git a/src/composer/vendor/consolidation/output-formatters/src/Formatters/SerializeFormatter.php b/src/composer/vendor/consolidation/output-formatters/src/Formatters/SerializeFormatter.php new file mode 100644 index 00000000..f8151373 --- /dev/null +++ b/src/composer/vendor/consolidation/output-formatters/src/Formatters/SerializeFormatter.php @@ -0,0 +1,21 @@ +writeln(serialize($data)); + } +} diff --git a/src/composer/vendor/consolidation/output-formatters/src/Formatters/StringFormatter.php b/src/composer/vendor/consolidation/output-formatters/src/Formatters/StringFormatter.php new file mode 100644 index 00000000..142bee4c --- /dev/null +++ b/src/composer/vendor/consolidation/output-formatters/src/Formatters/StringFormatter.php @@ -0,0 +1,81 @@ +writeln($data); + } + return $this->reduceToSigleFieldAndWrite($output, $data, $options); + } + + /** + * @inheritdoc + */ + public function overrideOptions($structuredOutput, FormatterOptions $options) + { + $defaultField = $options->get(FormatterOptions::DEFAULT_STRING_FIELD, [], ''); + $userFields = $options->get(FormatterOptions::FIELDS, [FormatterOptions::FIELDS => $options->get(FormatterOptions::FIELD)]); + $optionsOverride = $options->override([]); + if (empty($userFields) && !empty($defaultField)) { + $optionsOverride->setOption(FormatterOptions::FIELDS, $defaultField); + } + return $optionsOverride; + } + + /** + * If the data provided to a 'string' formatter is a table, then try + * to emit it as a TSV value. + * + * @param OutputInterface $output + * @param mixed $data + * @param FormatterOptions $options + */ + protected function reduceToSigleFieldAndWrite(OutputInterface $output, $data, FormatterOptions $options) + { + $alternateFormatter = new TsvFormatter(); + try { + $data = $alternateFormatter->validate($data); + $alternateFormatter->write($output, $data, $options); + } catch (\Exception $e) { + } + } + + /** + * Always validate any data, though. This format will never + * cause an error if it is selected for an incompatible data type; at + * worse, it simply does not print any data. + */ + public function validate($structuredData) + { + return $structuredData; + } +} diff --git a/src/composer/vendor/consolidation/output-formatters/src/Formatters/TableFormatter.php b/src/composer/vendor/consolidation/output-formatters/src/Formatters/TableFormatter.php new file mode 100644 index 00000000..f7787c28 --- /dev/null +++ b/src/composer/vendor/consolidation/output-formatters/src/Formatters/TableFormatter.php @@ -0,0 +1,128 @@ +validDataTypes() + ); + } + return $structuredData; + } + + /** + * @inheritdoc + */ + public function write(OutputInterface $output, $tableTransformer, FormatterOptions $options) + { + $headers = []; + $defaults = [ + FormatterOptions::TABLE_STYLE => 'consolidation', + FormatterOptions::INCLUDE_FIELD_LABELS => true, + ]; + + $table = new Table($output); + + static::addCustomTableStyles($table); + + $table->setStyle($options->get(FormatterOptions::TABLE_STYLE, $defaults)); + $isList = $tableTransformer->isList(); + $includeHeaders = $options->get(FormatterOptions::INCLUDE_FIELD_LABELS, $defaults); + if ($includeHeaders && !$isList) { + $headers = $tableTransformer->getHeaders(); + $table->setHeaders($headers); + } + $data = $tableTransformer->getTableData($includeHeaders && $isList); + $data = $this->wrap($headers, $data, $table->getStyle(), $options); + $table->setRows($data); + $table->render(); + } + + /** + * Wrap the table data + * @param array $data + * @param TableStyle $tableStyle + * @param FormatterOptions $options + * @return array + */ + protected function wrap($headers, $data, TableStyle $tableStyle, FormatterOptions $options) + { + $wrapper = new WordWrapper($options->get(FormatterOptions::TERMINAL_WIDTH)); + $wrapper->setPaddingFromStyle($tableStyle); + if (!empty($headers)) { + $headerLengths = array_map(function ($item) { + return strlen($item); + }, $headers); + $wrapper->setMinimumWidths($headerLengths); + } + return $wrapper->wrap($data); + } + + /** + * Add our custom table style(s) to the table. + */ + protected static function addCustomTableStyles($table) + { + // The 'consolidation' style is the same as the 'symfony-style-guide' + // style, except it maintains the colored headers used in 'default'. + $consolidationStyle = new TableStyle(); + $consolidationStyle + ->setHorizontalBorderChar('-') + ->setVerticalBorderChar(' ') + ->setCrossingChar(' ') + ; + $table->setStyleDefinition('consolidation', $consolidationStyle); + } +} diff --git a/src/composer/vendor/consolidation/output-formatters/src/Formatters/TsvFormatter.php b/src/composer/vendor/consolidation/output-formatters/src/Formatters/TsvFormatter.php new file mode 100644 index 00000000..8a827424 --- /dev/null +++ b/src/composer/vendor/consolidation/output-formatters/src/Formatters/TsvFormatter.php @@ -0,0 +1,40 @@ + false, + ]; + } + + protected function writeOneLine(OutputInterface $output, $data, $options) + { + $output->writeln($this->tsvEscape($data)); + } + + protected function tsvEscape($data) + { + return implode("\t", array_map( + function ($item) { + return str_replace(["\t", "\n"], ['\t', '\n'], $item); + }, + $data + )); + } +} diff --git a/src/composer/vendor/consolidation/output-formatters/src/Formatters/VarExportFormatter.php b/src/composer/vendor/consolidation/output-formatters/src/Formatters/VarExportFormatter.php new file mode 100644 index 00000000..0303ba48 --- /dev/null +++ b/src/composer/vendor/consolidation/output-formatters/src/Formatters/VarExportFormatter.php @@ -0,0 +1,21 @@ +writeln(var_export($data, true)); + } +} diff --git a/src/composer/vendor/consolidation/output-formatters/src/Formatters/XmlFormatter.php b/src/composer/vendor/consolidation/output-formatters/src/Formatters/XmlFormatter.php new file mode 100644 index 00000000..05533f22 --- /dev/null +++ b/src/composer/vendor/consolidation/output-formatters/src/Formatters/XmlFormatter.php @@ -0,0 +1,76 @@ +getDomData(); + } + if (!is_array($structuredData)) { + throw new IncompatibleDataException( + $this, + $structuredData, + $this->validDataTypes() + ); + } + return $structuredData; + } + + /** + * @inheritdoc + */ + public function write(OutputInterface $output, $dom, FormatterOptions $options) + { + if (is_array($dom)) { + $schema = $options->getXmlSchema(); + $dom = $schema->arrayToXML($dom); + } + $dom->formatOutput = true; + $output->writeln($dom->saveXML()); + } +} diff --git a/src/composer/vendor/consolidation/output-formatters/src/Formatters/YamlFormatter.php b/src/composer/vendor/consolidation/output-formatters/src/Formatters/YamlFormatter.php new file mode 100644 index 00000000..07a8f21d --- /dev/null +++ b/src/composer/vendor/consolidation/output-formatters/src/Formatters/YamlFormatter.php @@ -0,0 +1,27 @@ +writeln(Yaml::dump($data, PHP_INT_MAX, $indent, false, true)); + } +} diff --git a/src/composer/vendor/consolidation/output-formatters/src/Options/FormatterOptions.php b/src/composer/vendor/consolidation/output-formatters/src/Options/FormatterOptions.php new file mode 100644 index 00000000..1f71cb02 --- /dev/null +++ b/src/composer/vendor/consolidation/output-formatters/src/Options/FormatterOptions.php @@ -0,0 +1,372 @@ +configurationData = $configurationData; + $this->options = $options; + } + + /** + * Create a new FormatterOptions object with new configuration data (provided), + * and the same options data as this instance. + * + * @param array $configurationData + * @return FormatterOptions + */ + public function override($configurationData) + { + $override = new self(); + $override + ->setConfigurationData($configurationData + $this->getConfigurationData()) + ->setOptions($this->getOptions()); + return $override; + } + + public function setTableStyle($style) + { + return $this->setConfigurationValue(self::TABLE_STYLE, $style); + } + + public function setIncludeFieldLables($includFieldLables) + { + return $this->setConfigurationValue(self::INCLUDE_FIELD_LABELS, $includFieldLables); + } + + public function setListOrientation($listOrientation) + { + return $this->setConfigurationValue(self::LIST_ORIENTATION, $listOrientation); + } + + public function setRowLabels($rowLabels) + { + return $this->setConfigurationValue(self::ROW_LABELS, $rowLabels); + } + + public function setDefaultFields($fields) + { + return $this->setConfigurationValue(self::DEFAULT_FIELDS, $fields); + } + + public function setFieldLabels($fieldLabels) + { + return $this->setConfigurationValue(self::FIELD_LABELS, $fieldLabels); + } + + public function setDefaultStringField($defaultStringField) + { + return $this->setConfigurationValue(self::DEFAULT_STRING_FIELD, $defaultStringField); + } + + public function setWidth($width) + { + return $this->setConfigurationValue(self::TERMINAL_WIDTH, $width); + } + + /** + * Get a formatter option + * + * @param string $key + * @param array $defaults + * @param mixed $default + * @return mixed + */ + public function get($key, $defaults = [], $default = false) + { + $value = $this->fetch($key, $defaults, $default); + return $this->parse($key, $value); + } + + /** + * Return the XmlSchema to use with --format=xml for data types that support + * that. This is used when an array needs to be converted into xml. + * + * @return XmlSchema + */ + public function getXmlSchema() + { + return new XmlSchema(); + } + + /** + * Determine the format that was requested by the caller. + * + * @param array $defaults + * @return string + */ + public function getFormat($defaults = []) + { + return $this->get(self::FORMAT, [], $this->get(self::DEFAULT_FORMAT, $defaults, '')); + } + + /** + * Look up a key, and return its raw value. + * + * @param string $key + * @param array $defaults + * @param mixed $default + * @return mixed + */ + protected function fetch($key, $defaults = [], $default = false) + { + $defaults = $this->defaultsForKey($key, $defaults, $default); + $values = $this->fetchRawValues($defaults); + return $values[$key]; + } + + /** + * Reduce provided defaults to the single item identified by '$key', + * if it exists, or an empty array otherwise. + * + * @param string $key + * @param array $defaults + * @return array + */ + protected function defaultsForKey($key, $defaults, $default = false) + { + if (array_key_exists($key, $defaults)) { + return [$key => $defaults[$key]]; + } + return [$key => $default]; + } + + /** + * Look up all of the items associated with the provided defaults. + * + * @param array $defaults + * @return array + */ + protected function fetchRawValues($defaults = []) + { + return array_merge( + $defaults, + $this->getConfigurationData(), + $this->getOptions(), + $this->getInputOptions($defaults) + ); + } + + /** + * Given the raw value for a specific key, do any type conversion + * (e.g. from a textual list to an array) needed for the data. + * + * @param string $key + * @param mixed $value + * @return mixed + */ + protected function parse($key, $value) + { + $optionFormat = $this->getOptionFormat($key); + if (!empty($optionFormat) && is_string($value)) { + return $this->$optionFormat($value); + } + return $value; + } + + /** + * Convert from a textual list to an array + * + * @param string $value + * @return array + */ + public function parsePropertyList($value) + { + return PropertyParser::parse($value); + } + + /** + * Given a specific key, return the class method name of the + * parsing method for data stored under this key. + * + * @param string $key + * @return string + */ + protected function getOptionFormat($key) + { + $propertyFormats = [ + self::ROW_LABELS => 'PropertyList', + self::FIELD_LABELS => 'PropertyList', + ]; + if (array_key_exists($key, $propertyFormats)) { + return "parse{$propertyFormats[$key]}"; + } + return ''; + } + + /** + * Change the configuration data for this formatter options object. + * + * @param array $configurationData + * @return FormatterOptions + */ + public function setConfigurationData($configurationData) + { + $this->configurationData = $configurationData; + return $this; + } + + /** + * Change one configuration value for this formatter option. + * + * @param string $key + * @param mixed $value + * @return FormetterOptions + */ + protected function setConfigurationValue($key, $value) + { + $this->configurationData[$key] = $value; + return $this; + } + + /** + * Change one configuration value for this formatter option, but only + * if it does not already have a value set. + * + * @param string $key + * @param mixed $value + * @return FormetterOptions + */ + public function setConfigurationDefault($key, $value) + { + if (!array_key_exists($key, $this->configurationData)) { + return $this->setConfigurationValue($key, $value); + } + return $this; + } + + /** + * Return a reference to the configuration data for this object. + * + * @return array + */ + public function getConfigurationData() + { + return $this->configurationData; + } + + /** + * Set all of the options that were specified by the user for this request. + * + * @param array $options + * @return FormatterOptions + */ + public function setOptions($options) + { + $this->options = $options; + return $this; + } + + /** + * Change one option value specified by the user for this request. + * + * @param string $key + * @param mixed $value + * @return FormatterOptions + */ + public function setOption($key, $value) + { + $this->options[$key] = $value; + return $this; + } + + /** + * Return a reference to the user-specified options for this request. + * + * @return array + */ + public function getOptions() + { + return $this->options; + } + + /** + * Provide a Symfony Console InputInterface containing the user-specified + * options for this request. + * + * @param InputInterface $input + * @return type + */ + public function setInput(InputInterface $input) + { + $this->input = $input; + } + + /** + * Return all of the options from the provided $defaults array that + * exist in our InputInterface object. + * + * @param array $defaults + * @return array + */ + public function getInputOptions($defaults) + { + if (!isset($this->input)) { + return []; + } + $options = []; + foreach ($defaults as $key => $value) { + if ($this->input->hasOption($key)) { + $result = $this->input->getOption($key); + if (isset($result)) { + $options[$key] = $this->input->getOption($key); + } + } + } + return $options; + } +} diff --git a/src/composer/vendor/consolidation/output-formatters/src/Options/OverrideOptionsInterface.php b/src/composer/vendor/consolidation/output-formatters/src/Options/OverrideOptionsInterface.php new file mode 100644 index 00000000..04a09e96 --- /dev/null +++ b/src/composer/vendor/consolidation/output-formatters/src/Options/OverrideOptionsInterface.php @@ -0,0 +1,17 @@ +defaultOptions(); + $fieldLabels = $this->getReorderedFieldLabels($data, $options, $defaults); + + $tableTransformer = $this->instantiateTableTransformation($data, $fieldLabels, $options->get(FormatterOptions::ROW_LABELS, $defaults)); + if ($options->get(FormatterOptions::LIST_ORIENTATION, $defaults)) { + $tableTransformer->setLayout(TableTransformation::LIST_LAYOUT); + } + + return $tableTransformer; + } + + protected function instantiateTableTransformation($data, $fieldLabels, $rowLabels) + { + return new TableTransformation($data, $fieldLabels, $rowLabels); + } + + protected function getReorderedFieldLabels($data, $options, $defaults) + { + $reorderer = new ReorderFields(); + $fieldLabels = $reorderer->reorder( + $this->getFields($options, $defaults), + $options->get(FormatterOptions::FIELD_LABELS, $defaults), + $data + ); + return $fieldLabels; + } + + protected function getFields($options, $defaults) + { + $fieldShortcut = $options->get(FormatterOptions::FIELD); + if (!empty($fieldShortcut)) { + return [$fieldShortcut]; + } + $result = $options->get(FormatterOptions::FIELDS, $defaults); + if (!empty($result)) { + return $result; + } + return $options->get(FormatterOptions::DEFAULT_FIELDS, $defaults); + } + + /** + * A structured list may provide its own set of default options. These + * will be used in place of the command's default options (from the + * annotations) in instances where the user does not provide the options + * explicitly (on the commandline) or implicitly (via a configuration file). + * + * @return array + */ + protected function defaultOptions() + { + return [ + FormatterOptions::FIELDS => [], + FormatterOptions::FIELD_LABELS => [], + FormatterOptions::ROW_LABELS => [], + FormatterOptions::DEFAULT_FIELDS => [], + ]; + } +} diff --git a/src/composer/vendor/consolidation/output-formatters/src/StructuredData/AssociativeList.php b/src/composer/vendor/consolidation/output-formatters/src/StructuredData/AssociativeList.php new file mode 100644 index 00000000..2a8b327b --- /dev/null +++ b/src/composer/vendor/consolidation/output-formatters/src/StructuredData/AssociativeList.php @@ -0,0 +1,12 @@ +renderFunction = $renderFunction; + } + + /** + * {@inheritdoc} + */ + public function renderCell($key, $cellData, FormatterOptions $options, $rowData) + { + return call_user_func($this->renderFunction, $key, $cellData, $options, $rowData); + } +} diff --git a/src/composer/vendor/consolidation/output-formatters/src/StructuredData/ListDataInterface.php b/src/composer/vendor/consolidation/output-formatters/src/StructuredData/ListDataInterface.php new file mode 100644 index 00000000..829d7753 --- /dev/null +++ b/src/composer/vendor/consolidation/output-formatters/src/StructuredData/ListDataInterface.php @@ -0,0 +1,16 @@ +getArrayCopy()]; + $options->setConfigurationDefault('list-orientation', true); + $tableTransformer = $this->createTableTransformation($data, $options); + return $tableTransformer; + } + + public function getListData(FormatterOptions $options) + { + $data = $this->getArrayCopy(); + + $defaults = $this->defaultOptions(); + $fieldLabels = $this->getReorderedFieldLabels([$data], $options, $defaults); + + $result = []; + foreach ($fieldLabels as $id => $label) { + $result[$id] = $data[$id]; + } + return $result; + } + + protected function defaultOptions() + { + return [ + FormatterOptions::LIST_ORIENTATION => true, + ] + parent::defaultOptions(); + } + + protected function instantiateTableTransformation($data, $fieldLabels, $rowLabels) + { + return new PropertyListTableTransformation($data, $fieldLabels, $rowLabels); + } +} diff --git a/src/composer/vendor/consolidation/output-formatters/src/StructuredData/RenderCellCollectionInterface.php b/src/composer/vendor/consolidation/output-formatters/src/StructuredData/RenderCellCollectionInterface.php new file mode 100644 index 00000000..8e80aff4 --- /dev/null +++ b/src/composer/vendor/consolidation/output-formatters/src/StructuredData/RenderCellCollectionInterface.php @@ -0,0 +1,16 @@ + [], + RenderCellCollectionInterface::PRIORITY_NORMAL => [], + RenderCellCollectionInterface::PRIORITY_FALLBACK => [], + ]; + + /** + * Add a renderer + * + * @return $this + */ + public function addRenderer(RenderCellInterface $renderer, $priority = RenderCellCollectionInterface::PRIORITY_NORMAL) + { + $this->rendererList[$priority][] = $renderer; + return $this; + } + + /** + * Add a callable as a renderer + * + * @return $this + */ + public function addRendererFunction(callable $rendererFn, $priority = RenderCellCollectionInterface::PRIORITY_NORMAL) + { + $renderer = new CallableRenderer($rendererFn); + return $this->addRenderer($renderer, $priority); + } + + /** + * {@inheritdoc} + */ + public function renderCell($key, $cellData, FormatterOptions $options, $rowData) + { + $flattenedRendererList = array_reduce( + $this->rendererList, + function ($carry, $item) { + return array_merge($carry, $item); + }, + [] + ); + + foreach ($flattenedRendererList as $renderer) { + $cellData = $renderer->renderCell($key, $cellData, $options, $rowData); + if (is_string($cellData)) { + return $cellData; + } + } + return $cellData; + } +} diff --git a/src/composer/vendor/consolidation/output-formatters/src/StructuredData/RenderCellInterface.php b/src/composer/vendor/consolidation/output-formatters/src/StructuredData/RenderCellInterface.php new file mode 100644 index 00000000..ff200846 --- /dev/null +++ b/src/composer/vendor/consolidation/output-formatters/src/StructuredData/RenderCellInterface.php @@ -0,0 +1,22 @@ +getArrayCopy(); + return $this->createTableTransformation($data, $options); + } + + public function getListData(FormatterOptions $options) + { + return array_keys($this->getArrayCopy()); + } + + protected function defaultOptions() + { + return [ + FormatterOptions::LIST_ORIENTATION => false, + ] + parent::defaultOptions(); + } +} diff --git a/src/composer/vendor/consolidation/output-formatters/src/StructuredData/TableDataInterface.php b/src/composer/vendor/consolidation/output-formatters/src/StructuredData/TableDataInterface.php new file mode 100644 index 00000000..341b822c --- /dev/null +++ b/src/composer/vendor/consolidation/output-formatters/src/StructuredData/TableDataInterface.php @@ -0,0 +1,22 @@ + ['description'], + ]; + $this->elementList = array_merge_recursive($elementList, $defaultElementList); + } + + public function arrayToXML($structuredData) + { + $dom = new \DOMDocument('1.0', 'UTF-8'); + $topLevelElement = $this->getTopLevelElementName($structuredData); + $this->addXmlData($dom, $dom, $topLevelElement, $structuredData); + return $dom; + } + + protected function addXmlData(\DOMDocument $dom, $xmlParent, $elementName, $structuredData) + { + $element = $dom->createElement($elementName); + $xmlParent->appendChild($element); + if (is_string($structuredData)) { + $element->appendChild($dom->createTextNode($structuredData)); + return; + } + $this->addXmlChildren($dom, $element, $elementName, $structuredData); + } + + protected function addXmlChildren(\DOMDocument $dom, $xmlParent, $elementName, $structuredData) + { + foreach ($structuredData as $key => $value) { + $this->addXmlDataOrAttribute($dom, $xmlParent, $elementName, $key, $value); + } + } + + protected function addXmlDataOrAttribute(\DOMDocument $dom, $xmlParent, $elementName, $key, $value) + { + $childElementName = $this->getDefaultElementName($elementName); + $elementName = is_numeric($key) ? $childElementName : $key; + if (($elementName != $childElementName) && $this->isAttribute($elementName, $key, $value)) { + $xmlParent->setAttribute($key, $value); + return; + } + $this->addXmlData($dom, $xmlParent, $elementName, $value); + } + + protected function getTopLevelElementName($structuredData) + { + return 'document'; + } + + protected function getDefaultElementName($parentElementName) + { + $singularName = $this->singularForm($parentElementName); + if (isset($singularName)) { + return $singularName; + } + return 'item'; + } + + protected function isAttribute($parentElementName, $elementName, $value) + { + if (!is_string($value)) { + return false; + } + return !$this->inElementList($parentElementName, $elementName) && !$this->inElementList('*', $elementName); + } + + protected function inElementList($parentElementName, $elementName) + { + if (!array_key_exists($parentElementName, $this->elementList)) { + return false; + } + return in_array($elementName, $this->elementList[$parentElementName]); + } + + protected function singularForm($name) + { + if (substr($name, strlen($name) - 1) == "s") { + return substr($name, 0, strlen($name) - 1); + } + } + + protected function isAssoc($data) + { + return array_keys($data) == range(0, count($data)); + } +} diff --git a/src/composer/vendor/consolidation/output-formatters/src/StructuredData/Xml/XmlSchemaInterface.php b/src/composer/vendor/consolidation/output-formatters/src/StructuredData/Xml/XmlSchemaInterface.php new file mode 100644 index 00000000..a1fad662 --- /dev/null +++ b/src/composer/vendor/consolidation/output-formatters/src/StructuredData/Xml/XmlSchemaInterface.php @@ -0,0 +1,73 @@ + + * + * + * blah + * + * + * a + * b + * c + * + * + * + * + * + * + * This could be: + * + * [ + * 'id' => 1, + * 'name' => 'doc', + * 'foobars' => + * [ + * [ + * 'id' => '123', + * 'name' => 'blah', + * 'widgets' => + * [ + * [ + * 'foo' => 'a', + * 'bar' => 'b', + * 'baz' => 'c', + * ] + * ], + * ], + * ] + * ] + * + * The challenge is more in going from an array back to the more + * structured xml format. Note that any given key => string mapping + * could represent either an attribute, or a simple XML element + * containing only a string value. In general, we do *not* want to add + * extra layers of nesting in the data structure to disambiguate between + * these kinds of data, as we want the source data to render cleanly + * into other formats, e.g. yaml, json, et. al., and we do not want to + * force every data provider to have to consider the optimal xml schema + * for their data. + * + * Our strategy, therefore, is to expect clients that wish to provide + * a very specific xml representation to return a DOMDocument, and, + * for other data structures where xml is a secondary concern, then we + * will use some default heuristics to convert from arrays to xml. + */ +interface XmlSchemaInterface +{ + /** + * Convert data to a format suitable for use in a list. + * By default, the array values will be used. Implement + * ListDataInterface to use some other criteria (e.g. array keys). + * + * @return \DOMDocument + */ + public function arrayToXml($structuredData); +} diff --git a/src/composer/vendor/consolidation/output-formatters/src/Transformations/DomToArraySimplifier.php b/src/composer/vendor/consolidation/output-formatters/src/Transformations/DomToArraySimplifier.php new file mode 100644 index 00000000..a9e28cfb --- /dev/null +++ b/src/composer/vendor/consolidation/output-formatters/src/Transformations/DomToArraySimplifier.php @@ -0,0 +1,212 @@ +isSubclassOf('\Consolidation\OutputFormatters\StructuredData\Xml\DomDataInterface') || + $dataType->isSubclassOf('DOMDocument') || + ($dataType->getName() == 'DOMDocument'); + } + + public function simplifyToArray($structuredData, FormatterOptions $options) + { + if ($structuredData instanceof DomDataInterface) { + $structuredData = $structuredData->getDomData(); + } + if ($structuredData instanceof \DOMDocument) { + // $schema = $options->getXmlSchema(); + $simplified = $this->elementToArray($structuredData); + $structuredData = array_shift($simplified); + } + return $structuredData; + } + + /** + * Recursively convert the provided DOM element into a php array. + * + * @param \DOMNode $element + * @return array + */ + protected function elementToArray(\DOMNode $element) + { + if ($element->nodeType == XML_TEXT_NODE) { + return $element->nodeValue; + } + $attributes = $this->getNodeAttributes($element); + $children = $this->getNodeChildren($element); + + return array_merge($attributes, $children); + } + + /** + * Get all of the attributes of the provided element. + * + * @param \DOMNode $element + * @return array + */ + protected function getNodeAttributes($element) + { + if (empty($element->attributes)) { + return []; + } + $attributes = []; + foreach ($element->attributes as $key => $attribute) { + $attributes[$key] = $attribute->nodeValue; + } + return $attributes; + } + + /** + * Get all of the children of the provided element, with simplification. + * + * @param \DOMNode $element + * @return array + */ + protected function getNodeChildren($element) + { + if (empty($element->childNodes)) { + return []; + } + $uniformChildrenName = $this->hasUniformChildren($element); + if ("{$uniformChildrenName}s" == $element->nodeName) { + $result = $this->getUniformChildren($element->nodeName, $element); + } else { + $result = $this->getUniqueChildren($element->nodeName, $element); + } + return $result; + } + + /** + * Get the data from the children of the provided node in preliminary + * form. + * + * @param \DOMNode $element + * @return array + */ + protected function getNodeChildrenData($element) + { + $children = []; + foreach ($element->childNodes as $key => $value) { + $children[$key] = $this->elementToArray($value); + } + return $children; + } + + /** + * Determine whether the children of the provided element are uniform. + * @see getUniformChildren(), below. + * + * @param \DOMNode $element + * @return boolean + */ + protected function hasUniformChildren($element) + { + $last = false; + foreach ($element->childNodes as $key => $value) { + $name = $value->nodeName; + if (!$name) { + return false; + } + if ($last && ($name != $last)) { + return false; + } + $last = $name; + } + return $last; + } + + /** + * Convert the children of the provided DOM element into an array. + * Here, 'uniform' means that all of the element names of the children + * are identical, and further, the element name of the parent is the + * plural form of the child names. When the children are uniform in + * this way, then the parent element name will be used as the key to + * store the children in, and the child list will be returned as a + * simple list with their (duplicate) element names omitted. + * + * @param string $parentKey + * @param \DOMNode $element + * @return array + */ + protected function getUniformChildren($parentKey, $element) + { + $children = $this->getNodeChildrenData($element); + $simplifiedChildren = []; + foreach ($children as $key => $value) { + if ($this->valueCanBeSimplified($value)) { + $value = array_shift($value); + } + $simplifiedChildren[$parentKey][] = $value; + } + return $simplifiedChildren; + } + + /** + * Determine whether the provided value has additional unnecessary + * nesting. {"color": "red"} is converted to "red". No other + * simplification is done. + * + * @param \DOMNode $value + * @return boolean + */ + protected function valueCanBeSimplified($value) + { + if (!is_array($value)) { + return false; + } + if (count($value) != 1) { + return false; + } + $data = array_shift($value); + return is_string($data); + } + + /** + * Convert the children of the provided DOM element into an array. + * Here, 'unique' means that all of the element names of the children are + * different. Since the element names will become the key of the + * associative array that is returned, so duplicates are not supported. + * If there are any duplicates, then an exception will be thrown. + * + * @param string $parentKey + * @param \DOMNode $element + * @return array + */ + protected function getUniqueChildren($parentKey, $element) + { + $children = $this->getNodeChildrenData($element); + if ((count($children) == 1) && (is_string($children[0]))) { + return [$element->nodeName => $children[0]]; + } + $simplifiedChildren = []; + foreach ($children as $key => $value) { + if (is_numeric($key) && is_array($value) && (count($value) == 1)) { + $valueKeys = array_keys($value); + $key = $valueKeys[0]; + $value = array_shift($value); + } + if (array_key_exists($key, $simplifiedChildren)) { + throw new \Exception("Cannot convert data from a DOM document to an array, because <$key> appears more than once, and is not wrapped in a <{$key}s> element."); + } + $simplifiedChildren[$key] = $value; + } + return $simplifiedChildren; + } +} diff --git a/src/composer/vendor/consolidation/output-formatters/src/Transformations/OverrideRestructureInterface.php b/src/composer/vendor/consolidation/output-formatters/src/Transformations/OverrideRestructureInterface.php new file mode 100644 index 00000000..51a6ea87 --- /dev/null +++ b/src/composer/vendor/consolidation/output-formatters/src/Transformations/OverrideRestructureInterface.php @@ -0,0 +1,17 @@ +getArrayCopy(); + return $data[0]; + } +} diff --git a/src/composer/vendor/consolidation/output-formatters/src/Transformations/PropertyParser.php b/src/composer/vendor/consolidation/output-formatters/src/Transformations/PropertyParser.php new file mode 100644 index 00000000..18b982ea --- /dev/null +++ b/src/composer/vendor/consolidation/output-formatters/src/Transformations/PropertyParser.php @@ -0,0 +1,36 @@ + 'red', + * 'two' => 'white', + * 'three' => 'blue', + * ] + */ +class PropertyParser +{ + public static function parse($data) + { + if (!is_string($data)) { + return $data; + } + $result = []; + $lines = explode("\n", $data); + foreach ($lines as $line) { + list($key, $value) = explode(':', trim($line), 2) + ['', '']; + $result[$key] = trim($value); + } + return $result; + } +} diff --git a/src/composer/vendor/consolidation/output-formatters/src/Transformations/ReorderFields.php b/src/composer/vendor/consolidation/output-formatters/src/Transformations/ReorderFields.php new file mode 100644 index 00000000..9e764dc3 --- /dev/null +++ b/src/composer/vendor/consolidation/output-formatters/src/Transformations/ReorderFields.php @@ -0,0 +1,123 @@ +getSelectedFieldKeys($fields, $fieldLabels); + if (empty($fields)) { + return array_intersect_key($fieldLabels, $firstRow); + } + return $this->reorderFieldLabels($fields, $fieldLabels, $data); + } + + protected function reorderFieldLabels($fields, $fieldLabels, $data) + { + $result = []; + $firstRow = reset($data); + foreach ($fields as $field) { + if (array_key_exists($field, $firstRow)) { + if (array_key_exists($field, $fieldLabels)) { + $result[$field] = $fieldLabels[$field]; + } + } + } + return $result; + } + + protected function getSelectedFieldKeys($fields, $fieldLabels) + { + if (is_string($fields)) { + $fields = explode(',', $fields); + } + $selectedFields = []; + foreach ($fields as $field) { + $matchedFields = $this->matchFieldInLabelMap($field, $fieldLabels); + if (empty($matchedFields)) { + throw new UnknownFieldException($field); + } + $selectedFields = array_merge($selectedFields, $matchedFields); + } + return $selectedFields; + } + + protected function matchFieldInLabelMap($field, $fieldLabels) + { + $fieldRegex = $this->convertToRegex($field); + return + array_filter( + array_keys($fieldLabels), + function ($key) use ($fieldRegex, $fieldLabels) { + $value = $fieldLabels[$key]; + return preg_match($fieldRegex, $value) || preg_match($fieldRegex, $key); + } + ); + } + + /** + * Convert the provided string into a regex suitable for use in + * preg_match. + * + * Matching occurs in the same way as the Symfony Finder component: + * http://symfony.com/doc/current/components/finder.html#file-name + */ + protected function convertToRegex($str) + { + return $this->isRegex($str) ? $str : Glob::toRegex($str); + } + + /** + * Checks whether the string is a regex. This function is copied from + * MultiplePcreFilterIterator in the Symfony Finder component. + * + * @param string $str + * + * @return bool Whether the given string is a regex + */ + protected function isRegex($str) + { + if (preg_match('/^(.{3,}?)[imsxuADU]*$/', $str, $m)) { + $start = substr($m[1], 0, 1); + $end = substr($m[1], -1); + + if ($start === $end) { + return !preg_match('/[*?[:alnum:] \\\\]/', $start); + } + + foreach (array(array('{', '}'), array('(', ')'), array('[', ']'), array('<', '>')) as $delimiters) { + if ($start === $delimiters[0] && $end === $delimiters[1]) { + return true; + } + } + } + + return false; + } +} diff --git a/src/composer/vendor/consolidation/output-formatters/src/Transformations/SimplifyToArrayInterface.php b/src/composer/vendor/consolidation/output-formatters/src/Transformations/SimplifyToArrayInterface.php new file mode 100644 index 00000000..7b088ae8 --- /dev/null +++ b/src/composer/vendor/consolidation/output-formatters/src/Transformations/SimplifyToArrayInterface.php @@ -0,0 +1,26 @@ +headers = $fieldLabels; + $this->rowLabels = $rowLabels; + $rows = static::transformRows($data, $fieldLabels); + $this->layout = self::TABLE_LAYOUT; + parent::__construct($rows); + } + + public function setLayout($layout) + { + $this->layout = $layout; + } + + public function getLayout() + { + return $this->layout; + } + + public function isList() + { + return $this->layout == self::LIST_LAYOUT; + } + + protected static function transformRows($data, $fieldLabels) + { + $rows = []; + foreach ($data as $rowid => $row) { + $rows[$rowid] = static::transformRow($row, $fieldLabels); + } + return $rows; + } + + protected static function transformRow($row, $fieldLabels) + { + $result = []; + foreach ($fieldLabels as $key => $label) { + $result[$key] = array_key_exists($key, $row) ? $row[$key] : ''; + } + return $result; + } + + public function getHeaders() + { + return $this->headers; + } + + public function getHeader($key) + { + if (array_key_exists($key, $this->headers)) { + return $this->headers[$key]; + } + return $key; + } + + public function getRowLabels() + { + return $this->rowLabels; + } + + public function getRowLabel($rowid) + { + if (array_key_exists($rowid, $this->rowLabels)) { + return $this->rowLabels[$rowid]; + } + return $rowid; + } + + public function getOriginalData() + { + return $this->getArrayCopy(); + } + + public function getTableData($includeRowKey = false) + { + $data = $this->getArrayCopy(); + if ($this->isList()) { + $data = $this->convertTableToList(); + } + if ($includeRowKey) { + $data = $this->getRowDataWithKey($data); + } + return $data; + } + + protected function convertTableToList() + { + $result = []; + foreach ($this as $row) { + foreach ($row as $key => $value) { + $result[$key][] = $value; + } + } + return $result; + } + + protected function getRowDataWithKey($data) + { + $result = []; + $i = 0; + foreach ($data as $key => $row) { + array_unshift($row, $this->getHeader($key)); + $i++; + $result[$key] = $row; + } + return $result; + } +} diff --git a/src/composer/vendor/consolidation/output-formatters/src/Transformations/WordWrapper.php b/src/composer/vendor/consolidation/output-formatters/src/Transformations/WordWrapper.php new file mode 100644 index 00000000..18519d07 --- /dev/null +++ b/src/composer/vendor/consolidation/output-formatters/src/Transformations/WordWrapper.php @@ -0,0 +1,227 @@ +width = $width; + } + + /** + * Calculate our padding widths from the specified table style. + * @param TableStyle $style + */ + public function setPaddingFromStyle(TableStyle $style) + { + $verticalBorderLen = strlen(sprintf($style->getBorderFormat(), $style->getVerticalBorderChar())); + $paddingLen = strlen($style->getPaddingChar()); + + $this->extraPaddingAtBeginningOfLine = 0; + $this->extraPaddingAtEndOfLine = $verticalBorderLen; + $this->paddingInEachCell = $verticalBorderLen + $paddingLen + 1; + } + + /** + * If columns have minimum widths, then set them here. + * @param array $minimumWidths + */ + public function setMinimumWidths($minimumWidths) + { + $this->minimumWidths = $minimumWidths; + } + + /** + * Wrap the cells in each part of the provided data table + * @param array $rows + * @return array + */ + public function wrap($rows, $widths = []) + { + // If the width was not set, then disable wordwrap. + if (!$this->width) { + 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]); + } + } + + return $newrows; + } + + /** + * 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. + */ + protected function columnAutowidth($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--; + } + } + } + } + + 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; + } + + // 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); + + 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; + } + + 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]; + } + + 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 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/src/composer/vendor/consolidation/output-formatters/src/Validate/ValidDataTypesInterface.php b/src/composer/vendor/consolidation/output-formatters/src/Validate/ValidDataTypesInterface.php new file mode 100644 index 00000000..88cce531 --- /dev/null +++ b/src/composer/vendor/consolidation/output-formatters/src/Validate/ValidDataTypesInterface.php @@ -0,0 +1,28 @@ +validDataTypes(), + function ($carry, $supportedType) use ($dataType) { + return + $carry || + ($dataType->getName() == $supportedType->getName()) || + ($dataType->isSubclassOf($supportedType->getName())); + }, + false + ); + } +} diff --git a/src/composer/vendor/consolidation/output-formatters/src/Validate/ValidationInterface.php b/src/composer/vendor/consolidation/output-formatters/src/Validate/ValidationInterface.php new file mode 100644 index 00000000..ad43626c --- /dev/null +++ b/src/composer/vendor/consolidation/output-formatters/src/Validate/ValidationInterface.php @@ -0,0 +1,28 @@ +markTestIncomplete( + 'API generation has slight variations when run on CI server. This test is therefore skipped on CI until we can make the test results consistent.' + ); + } + + $testDocs = tempnam(sys_get_temp_dir(), 'TestAPIDocs.md'); + $currentDocs = getcwd() . '/docs/api.md'; + passthru("vendor/bin/phpdoc-md generate src > $testDocs"); + + $testDocsContent = file_get_contents($testDocs); + $currentDocsContent = file_get_contents($currentDocs); + + $testDocsContent = str_replace (array("\r\n", "\r"), "\n", $testDocsContent); + $currentDocsContent = str_replace (array("\r\n", "\r"), "\n", $currentDocsContent); + + $this->assertEquals($testDocsContent, $currentDocsContent, "API docuementation out of date. Run 'composer api' to update."); + } +} diff --git a/src/composer/vendor/consolidation/output-formatters/tests/testFormatterOptions.php b/src/composer/vendor/consolidation/output-formatters/tests/testFormatterOptions.php new file mode 100644 index 00000000..eef7d21e --- /dev/null +++ b/src/composer/vendor/consolidation/output-formatters/tests/testFormatterOptions.php @@ -0,0 +1,112 @@ +bind($definition); + return $input; + } + + protected function getFormat(FormatterOptions $options, $defaults = []) + { + return $options->get(FormatterOptions::FORMAT, [], $options->get(FormatterOptions::DEFAULT_FORMAT, $defaults, '')); + } + + public function testFormatterOptions() { + $configurationData = [ + FormatterOptions::DEFAULT_FORMAT => 'table', + 'test' => 'one', + 'try' => 'two', + ]; + $userOptions = [ + 'try' => 'three', + ]; + $defaults = [ + FormatterOptions::DEFAULT_FORMAT => 'var_export', + 'try' => 'four', + 'default-only' => 'defaulty', + ]; + + // Create a StringInput object and ensure that Symfony Console is working right. + $input = $this->createStringInput('test --format=yaml --include-field-labels'); + $testValue = $input->getOption(FormatterOptions::INCLUDE_FIELD_LABELS); + $this->assertTrue($testValue); + $testValue = $input->getOption(FormatterOptions::FORMAT); + $this->assertEquals('yaml', $testValue); + + // $options->get() only returns the default parameter is there is + // no matching key in configuration, userOptions or defaults. + $options = new FormatterOptions($configurationData, $userOptions); + $this->assertEquals('', $options->get('default-only')); + $this->assertEquals('defaulty', $options->get('default-only', $defaults)); + $this->assertEquals('defaulty', $options->get('default-only', $defaults, 'irrelevant')); + $this->assertEquals('three', $options->get('try')); + $this->assertEquals('three', $options->get('try', $defaults)); + $this->assertEquals('three', $options->get('try', $defaults, 'irrelevant')); + $this->assertFalse($options->get('no-such-key')); + $this->assertFalse($options->get('no-such-key', $defaults)); + $this->assertEquals('last-chance', $options->get('no-such-key', $defaults, 'last-chance')); + + // Change a user option + $options = new FormatterOptions($configurationData, $userOptions); + $options->setOption('try', 'changed'); + $this->assertEquals('changed', $options->get('try')); + $this->assertEquals('changed', $options->get('try', $defaults)); + $this->assertEquals('changed', $options->get('try', $defaults, 'irrelevant')); + + // Configuration has higher priority than defaults + $options = new FormatterOptions($configurationData, $userOptions); + $this->assertEquals('table', $this->getFormat($options)); + $this->assertEquals('table', $this->getFormat($options, $defaults)); + + // Override has higher priority than configuration and defaults + $options = new FormatterOptions($configurationData, $userOptions); + $newOptions = $options->override([FormatterOptions::DEFAULT_FORMAT => 'json']); + $this->assertEquals('json', $this->getFormat($newOptions)); + $this->assertEquals('json', $this->getFormat($newOptions, $defaults)); + + $options = new FormatterOptions($configurationData, $userOptions); + $options->setConfigurationDefault(FormatterOptions::DEFAULT_FORMAT, 'php'); + $this->assertEquals('table', $this->getFormat($options)); + + $options = new FormatterOptions($configurationData, $userOptions); + $options->setConfigurationData([]); + $this->assertEquals('', $this->getFormat($options)); + + // It is only possible to override options that appear in '$default' + // with $input; if there are no defaults, then the --format=yaml + // option will not be picked up. + $options = new FormatterOptions($configurationData, $userOptions); + $options->setInput($input); + $this->assertEquals('table', $options->get(FormatterOptions::DEFAULT_FORMAT)); + $this->assertEquals('table', $options->get(FormatterOptions::DEFAULT_FORMAT, $defaults, 'irrelevant')); + + // We won't see the default value unless the configuration value is empty. + $options = new FormatterOptions([], $userOptions); + $this->assertEquals('var_export', $options->get(FormatterOptions::DEFAULT_FORMAT, $defaults, 'irrelevant')); + } +} diff --git a/src/composer/vendor/consolidation/output-formatters/tests/testFormatters.php b/src/composer/vendor/consolidation/output-formatters/tests/testFormatters.php new file mode 100644 index 00000000..d9e8710f --- /dev/null +++ b/src/composer/vendor/consolidation/output-formatters/tests/testFormatters.php @@ -0,0 +1,1332 @@ +formatterManager = new FormatterManager(); + } + + function assertFormattedOutputMatches($expected, $format, $data, FormatterOptions $options = null, $userOptions = []) { + if (!$options) { + $options = new FormatterOptions(); + } + $options->setOptions($userOptions); + $output = new BufferedOutput(); + $this->formatterManager->write($output, $format, $data, $options); + $actual = preg_replace('#[ \t]*$#sm', '', $output->fetch()); + $this->assertEquals(rtrim($expected), rtrim($actual)); + } + + function testSimpleYaml() + { + $data = [ + 'one' => 'a', + 'two' => 'b', + 'three' => 'c', + ]; + + $expected = <<assertFormattedOutputMatches($expected, 'yaml', $data); + } + + function testNestedYaml() + { + $data = [ + 'one' => [ + 'i' => ['a', 'b', 'c'], + ], + 'two' => [ + 'ii' => ['q', 'r', 's'], + ], + 'three' => [ + 'iii' => ['t', 'u', 'v'], + ], + ]; + + $expected = <<assertFormattedOutputMatches($expected, 'yaml', $data); + } + + function testSimpleJson() + { + $data = [ + 'one' => 'a', + 'two' => 'b', + 'three' => 'c', + ]; + + $expected = <<assertFormattedOutputMatches($expected, 'json', $data); + } + + function testSerializeFormat() + { + $data = [ + 'one' => 'a', + 'two' => 'b', + 'three' => 'c', + ]; + + $expected = 'a:3:{s:3:"one";s:1:"a";s:3:"two";s:1:"b";s:5:"three";s:1:"c";}'; + + $this->assertFormattedOutputMatches($expected, 'php', $data); + } + + function testNestedJson() + { + $data = [ + 'one' => [ + 'i' => ['a', 'b', 'c'], + ], + 'two' => [ + 'ii' => ['q', 'r', 's'], + ], + 'three' => [ + 'iii' => ['t', 'u', 'v'], + ], + ]; + + $expected = <<assertFormattedOutputMatches($expected, 'json', $data); + } + + function testSimplePrintR() + { + $data = [ + 'one' => 'a', + 'two' => 'b', + 'three' => 'c', + ]; + + $expected = << a + [two] => b + [three] => c +) +EOT; + + $this->assertFormattedOutputMatches($expected, 'print-r', $data); + } + + function testNestedPrintR() + { + $data = [ + 'one' => [ + 'i' => ['a', 'b', 'c'], + ], + 'two' => [ + 'ii' => ['q', 'r', 's'], + ], + 'three' => [ + 'iii' => ['t', 'u', 'v'], + ], + ]; + + $expected = << Array + ( + [i] => Array + ( + [0] => a + [1] => b + [2] => c + ) + + ) + + [two] => Array + ( + [ii] => Array + ( + [0] => q + [1] => r + [2] => s + ) + + ) + + [three] => Array + ( + [iii] => Array + ( + [0] => t + [1] => u + [2] => v + ) + + ) + +) +EOT; + + $this->assertFormattedOutputMatches($expected, 'print-r', $data); + } + + function testSimpleVarExport() + { + $data = [ + 'one' => 'a', + 'two' => 'b', + 'three' => 'c', + ]; + + $expected = << 'a', + 'two' => 'b', + 'three' => 'c', +) +EOT; + + $this->assertFormattedOutputMatches($expected, 'var_export', $data); + } + + function testNestedVarExport() + { + $data = [ + 'one' => [ + 'i' => ['a', 'b', 'c'], + ], + 'two' => [ + 'ii' => ['q', 'r', 's'], + ], + 'three' => [ + 'iii' => ['t', 'u', 'v'], + ], + ]; + + $expected = << + array ( + 'i' => + array ( + 0 => 'a', + 1 => 'b', + 2 => 'c', + ), + ), + 'two' => + array ( + 'ii' => + array ( + 0 => 'q', + 1 => 'r', + 2 => 's', + ), + ), + 'three' => + array ( + 'iii' => + array ( + 0 => 't', + 1 => 'u', + 2 => 'v', + ), + ), +) +EOT; + + $this->assertFormattedOutputMatches($expected, 'var_export', $data); + } + + function testList() + { + $data = [ + 'one' => 'a', + 'two' => 'b', + 'three' => 'c', + ]; + + $expected = <<assertFormattedOutputMatches($expected, 'list', $data); + } + + /** + * @expectedException \Consolidation\OutputFormatters\Exception\UnknownFormatException + * @expectedExceptionCode 1 + * @expectedExceptionMessage The requested format, 'no-such-format', is not available. + */ + function testBadFormat() + { + $this->assertFormattedOutputMatches('Will fail, not return', 'no-such-format', ['a' => 'b']); + } + + /** + * @expectedException \Consolidation\OutputFormatters\Exception\IncompatibleDataException + * @expectedExceptionCode 1 + * @expectedExceptionMessage Data provided to Consolidation\OutputFormatters\Formatters\CsvFormatter must be one of an instance of Consolidation\OutputFormatters\StructuredData\RowsOfFields, an instance of Consolidation\OutputFormatters\StructuredData\PropertyList or an array. Instead, a string was provided. + */ + function testBadDataTypeForCsv() + { + $this->assertFormattedOutputMatches('Will fail, not return', 'csv', 'String cannot be converted to csv'); + } + + /** + * @expectedException \Consolidation\OutputFormatters\Exception\IncompatibleDataException + * @expectedExceptionCode 1 + * @expectedExceptionMessage Data provided to Consolidation\OutputFormatters\Formatters\JsonFormatter must be an array. Instead, a string was provided. + */ + function testBadDataTypeForJson() + { + $this->assertFormattedOutputMatches('Will fail, not return', 'json', 'String cannot be converted to json'); + } + + function testNoFormatterSelected() + { + $data = 'Hello'; + $expected = $data; + $this->assertFormattedOutputMatches($expected, '', $data); + } + + function testRenderTableAsString() + { + $data = new RowsOfFields([['f1' => 'A', 'f2' => 'B', 'f3' => 'C'], ['f1' => 'x', 'f2' => 'y', 'f3' => 'z']]); + $expected = "A\tB\tC\nx\ty\tz"; + + $this->assertFormattedOutputMatches($expected, 'string', $data); + } + + function testRenderTableAsStringWithSingleField() + { + $data = new RowsOfFields([['f1' => 'q', 'f2' => 'r', 'f3' => 's'], ['f1' => 'x', 'f2' => 'y', 'f3' => 'z']]); + $expected = "q\nx"; + + $options = new FormatterOptions([FormatterOptions::DEFAULT_STRING_FIELD => 'f1']); + + $this->assertFormattedOutputMatches($expected, 'string', $data, $options); + } + + function testRenderTableAsStringWithSingleFieldAndUserSelectedField() + { + $data = new RowsOfFields([['f1' => 'q', 'f2' => 'r', 'f3' => 's'], ['f1' => 'x', 'f2' => 'y', 'f3' => 'z']]); + $expected = "r\ny"; + + $options = new FormatterOptions([FormatterOptions::DEFAULT_STRING_FIELD => 'f1']); + + $this->assertFormattedOutputMatches($expected, 'string', $data, $options, ['fields' => 'f2']); + } + + function testSimpleCsv() + { + $data = ['a', 'b', 'c']; + $expected = "a,b,c"; + + $this->assertFormattedOutputMatches($expected, 'csv', $data); + } + + function testLinesOfCsv() + { + $data = [['a', 'b', 'c'], ['x', 'y', 'z']]; + $expected = "a,b,c\nx,y,z"; + + $this->assertFormattedOutputMatches($expected, 'csv', $data); + } + + function testCsvWithEscapedValues() + { + $data = ["Red apple", "Yellow lemon"]; + $expected = '"Red apple","Yellow lemon"'; + + $this->assertFormattedOutputMatches($expected, 'csv', $data); + } + + function testCsvWithEmbeddedSingleQuote() + { + $data = ["John's book", "Mary's laptop"]; + $expected = <<assertFormattedOutputMatches($expected, 'csv', $data); + } + + function testCsvWithEmbeddedDoubleQuote() + { + $data = ['The "best" solution']; + $expected = <<assertFormattedOutputMatches($expected, 'csv', $data); + } + + function testCsvBothKindsOfQuotes() + { + $data = ["John's \"new\" book", "Mary's \"modified\" laptop"]; + $expected = <<assertFormattedOutputMatches($expected, 'csv', $data); + } + + function testSimpleTsv() + { + $data = ['a', 'b', 'c']; + $expected = "a\tb\tc"; + + $this->assertFormattedOutputMatches($expected, 'tsv', $data); + } + + function testLinesOfTsv() + { + $data = [['a', 'b', 'c'], ['x', 'y', 'z']]; + $expected = "a\tb\tc\nx\ty\tz"; + + $this->assertFormattedOutputMatches($expected, 'tsv', $data); + } + + function testTsvBothKindsOfQuotes() + { + $data = ["John's \"new\" book", "Mary's \"modified\" laptop"]; + $expected = "John's \"new\" book\tMary's \"modified\" laptop"; + + $this->assertFormattedOutputMatches($expected, 'tsv', $data); + } + + function testTsvWithEscapedValues() + { + $data = ["Red apple", "Yellow lemon", "Embedded\ttab"]; + $expected = "Red apple\tYellow lemon\tEmbedded\\ttab"; + + $this->assertFormattedOutputMatches($expected, 'tsv', $data); + } + + protected function missingCellTableExampleData() + { + $data = [ + [ + 'one' => 'a', + 'two' => 'b', + 'three' => 'c', + ], + [ + 'one' => 'x', + 'three' => 'z', + ], + ]; + return new RowsOfFields($data); + } + + function testTableWithMissingCell() + { + $data = $this->missingCellTableExampleData(); + + $expected = <<assertFormattedOutputMatches($expected, 'table', $data); + + $expectedCsv = <<assertFormattedOutputMatches($expectedCsv, 'csv', $data); + + $expectedTsv = <<assertFormattedOutputMatches($expectedTsv, 'tsv', $data); + + $expectedTsvWithHeaders = <<assertFormattedOutputMatches($expectedTsvWithHeaders, 'tsv', $data, new FormatterOptions(), ['include-field-labels' => true]); + } + + function testTableWithWordWrapping() + { + $options = new FormatterOptions(); + $options->setWidth(42); + + $data = [ + [ + 'first' => 'This is a really long cell that contains a lot of data. When it is rendered, it should be wrapped across multiple lines.', + 'second' => 'This is the second column of the same table. It is also very long, and should be wrapped across multiple lines, just like the first column.', + ] + ]; + $data = new RowsOfFields($data); + + $expected = <<assertFormattedOutputMatches($expected, 'table', $data, $options); + } + + protected function simpleTableExampleData() + { + $data = [ + 'id-123' => + [ + 'one' => 'a', + 'two' => 'b', + 'three' => 'c', + ], + 'id-456' => + [ + 'one' => 'x', + 'two' => 'y', + 'three' => 'z', + ], + ]; + return new RowsOfFields($data); + } + + /** + * @expectedException \Consolidation\OutputFormatters\Exception\InvalidFormatException + * @expectedExceptionCode 1 + * @expectedExceptionMessage The format table cannot be used with the data produced by this command, which was an array. Valid formats are: csv,json,list,php,print-r,string,tsv,var_export,xml,yaml + */ + function testIncompatibleDataForTableFormatter() + { + $data = $this->simpleTableExampleData()->getArrayCopy(); + $this->assertFormattedOutputMatches('Should throw an exception before comparing the table data', 'table', $data); + } + + /** + * @expectedException \Consolidation\OutputFormatters\Exception\InvalidFormatException + * @expectedExceptionCode 1 + * @expectedExceptionMessage The format sections cannot be used with the data produced by this command, which was an array. Valid formats are: csv,json,list,php,print-r,string,tsv,var_export,xml,yaml + */ + function testIncompatibleDataForSectionsFormatter() + { + $data = $this->simpleTableExampleData()->getArrayCopy(); + $this->assertFormattedOutputMatches('Should throw an exception before comparing the table data', 'sections', $data); + } + + function testSimpleTable() + { + $data = $this->simpleTableExampleData(); + + $expected = <<assertFormattedOutputMatches($expected, 'table', $data); + + $expectedBorderless = <<assertFormattedOutputMatches($expectedBorderless, 'table', $data, new FormatterOptions(['table-style' => 'borderless'])); + + $expectedJson = <<assertFormattedOutputMatches($expectedJson, 'json', $data); + + $expectedCsv = <<assertFormattedOutputMatches($expectedCsv, 'csv', $data); + + $expectedList = <<assertFormattedOutputMatches($expectedList, 'list', $data); + } + + protected function tableWithAlternativesExampleData() + { + $data = [ + 'id-123' => + [ + 'one' => 'a', + 'two' => ['this', 'that', 'the other thing'], + 'three' => 'c', + ], + 'id-456' => + [ + 'one' => 'x', + 'two' => 'y', + 'three' => ['apples', 'oranges'], + ], + ]; + return new RowsOfFieldsWithAlternatives($data); + } + + function testTableWithAlternatives() + { + $data = $this->tableWithAlternativesExampleData(); + + $expected = <<assertFormattedOutputMatches($expected, 'table', $data); + + $expectedBorderless = <<assertFormattedOutputMatches($expectedBorderless, 'table', $data, new FormatterOptions(['table-style' => 'borderless'])); + + $expectedJson = <<assertFormattedOutputMatches($expectedJson, 'json', $data); + + $expectedCsv = <<assertFormattedOutputMatches($expectedCsv, 'csv', $data); + + $expectedList = <<assertFormattedOutputMatches($expectedList, 'list', $data); + } + + function testSimpleTableWithFieldLabels() + { + $data = $this->simpleTableExampleData(); + $configurationData = new FormatterOptions( + [ + 'field-labels' => ['one' => 'Ichi', 'two' => 'Ni', 'three' => 'San'], + 'row-labels' => ['id-123' => 'Walrus', 'id-456' => 'Carpenter'], + ] + ); + $configurationDataAnnotationFormat = new FormatterOptions( + [ + 'field-labels' => "one: Uno\ntwo: Dos\nthree: Tres", + ] + ); + + $expected = <<assertFormattedOutputMatches($expected, 'table', $data, $configurationData); + + $expectedSidewaysTable = <<assertFormattedOutputMatches($expectedSidewaysTable, 'table', $data, $configurationData->override(['list-orientation' => true])); + + $expectedAnnotationFormatConfigData = <<assertFormattedOutputMatches($expectedAnnotationFormatConfigData, 'table', $data, $configurationDataAnnotationFormat); + + $expectedWithNoFields = <<assertFormattedOutputMatches($expectedWithNoFields, 'table', $data, $configurationData, ['include-field-labels' => false]); + + $expectedWithReorderedFields = <<assertFormattedOutputMatches($expectedWithReorderedFields, 'table', $data, $configurationData, ['fields' => ['three', 'one']]); + $this->assertFormattedOutputMatches($expectedWithReorderedFields, 'table', $data, $configurationData, ['fields' => ['San', 'Ichi']]); + $this->assertFormattedOutputMatches($expectedWithReorderedFields, 'table', $data, $configurationData, ['fields' => 'San,Ichi']); + + $expectedWithRegexField = <<assertFormattedOutputMatches($expectedWithRegexField, 'table', $data, $configurationData, ['fields' => ['/e$/']]); + $this->assertFormattedOutputMatches($expectedWithRegexField, 'table', $data, $configurationData, ['fields' => ['*e']]); + $this->assertFormattedOutputMatches($expectedWithRegexField, 'table', $data, $configurationData, ['default-fields' => ['*e']]); + + $expectedSections = <<assertFormattedOutputMatches($expectedSections, 'sections', $data, $configurationData); + + $expectedJson = <<assertFormattedOutputMatches($expectedJson, 'json', $data, $configurationData, ['fields' => ['San', 'Ichi']]); + + $expectedSingleField = <<assertFormattedOutputMatches($expectedSingleField, 'table', $data, $configurationData, ['field' => 'San']); + } + + /** + * @expectedException \Consolidation\OutputFormatters\Exception\UnknownFieldException + * @expectedExceptionCode 1 + * @expectedExceptionMessage The requested field, 'Shi', is not defined. + */ + function testNoSuchFieldException() + { + $configurationData = new FormatterOptions( + [ + 'field-labels' => ['one' => 'Ichi', 'two' => 'Ni', 'three' => 'San'], + 'row-labels' => ['id-123' => 'Walrus', 'id-456' => 'Carpenter'], + ] + ); + $data = $this->simpleTableExampleData(); + $this->assertFormattedOutputMatches('Will throw before comparing', 'table', $data, $configurationData, ['field' => 'Shi']); + } + + protected function simpleListExampleData() + { + $data = [ + 'one' => 'apple', + 'two' => 'banana', + 'three' => 'carrot', + ]; + return new PropertyList($data); + } + + // Test with the deprecated data structure + protected function simpleListExampleDataUsingAssociativeList() + { + $data = [ + 'one' => 'apple', + 'two' => 'banana', + 'three' => 'carrot', + ]; + return new AssociativeList($data); + } + + /** + * @expectedException \Consolidation\OutputFormatters\Exception\InvalidFormatException + * @expectedExceptionCode 1 + * @expectedExceptionMessage The format table cannot be used with the data produced by this command, which was an array. Valid formats are: csv,json,list,php,print-r,string,tsv,var_export,xml,yaml + */ + function testIncompatibleListDataForTableFormatter() + { + $data = $this->simpleListExampleData(); + $this->assertFormattedOutputMatches('Should throw an exception before comparing the table data', 'table', $data->getArrayCopy()); + } + + function testEmptyList() + { + $data = new RowsOfFields([]); + + $expected = <<setFieldLabels(['one' => 'I', 'two' => 'II', 'three' => 'III']); + $this->assertFormattedOutputMatches($expected, 'table', $data, $formatterOptionsWithFieldLables); + } + + function testSimpleList() + { + + $expected = <<simpleListExampleDataUsingAssociativeList(); + + $this->assertFormattedOutputMatches($expected, 'table', $data); + + $data = $this->simpleListExampleData(); + + $this->assertFormattedOutputMatches($expected, 'table', $data); + + $expected = <<setFieldLabels(['one' => 'I', 'two' => 'II', 'three' => 'III']); + $this->assertFormattedOutputMatches($expected, 'table', $data, $formatterOptionsWithFieldLables); + + // Adding an extra field that does not exist in the data set should not change the output + $formatterOptionsWithExtraFieldLables = new FormatterOptions(); + $formatterOptionsWithExtraFieldLables + ->setFieldLabels(['one' => 'I', 'two' => 'II', 'three' => 'III', 'four' => 'IV']); + $this->assertFormattedOutputMatches($expected, 'table', $data, $formatterOptionsWithExtraFieldLables); + + $expectedRotated = <<assertFormattedOutputMatches($expectedRotated, 'table', $data, new FormatterOptions(['list-orientation' => false])); + + $expectedList = <<< EOT +apple +banana +carrot +EOT; + $this->assertFormattedOutputMatches($expectedList, 'list', $data); + + $expectedReorderedList = <<< EOT +carrot +apple +EOT; + $options = new FormatterOptions([FormatterOptions::FIELDS => 'three,one']); + $this->assertFormattedOutputMatches($expectedReorderedList, 'list', $data, $options); + + $expectedCsv = <<< EOT +One,Two,Three +apple,banana,carrot +EOT; + $this->assertFormattedOutputMatches($expectedCsv, 'csv', $data); + + $expectedCsvNoHeaders = 'apple,banana,carrot'; + $this->assertFormattedOutputMatches($expectedCsvNoHeaders, 'csv', $data, new FormatterOptions(), ['include-field-labels' => false]); + + // Next, configure the formatter options with 'include-field-labels', + // but set --include-field-labels to turn the option back on again. + $options = new FormatterOptions(['include-field-labels' => false]); + $input = new StringInput('test --include-field-labels'); + $optionDefinitions = [ + new InputArgument('unused', InputArgument::REQUIRED), + new InputOption('include-field-labels', null, InputOption::VALUE_NONE), + ]; + $definition = new InputDefinition($optionDefinitions); + $input->bind($definition); + $testValue = $input->getOption('include-field-labels'); + $this->assertTrue($testValue); + $hasFieldLabels = $input->hasOption('include-field-labels'); + $this->assertTrue($hasFieldLabels); + + $this->assertFormattedOutputMatches($expectedCsvNoHeaders, 'csv', $data, $options); + $options->setInput($input); + $this->assertFormattedOutputMatches($expectedCsv, 'csv', $data, $options); + } + + protected function associativeListWithRenderer() + { + $data = [ + 'one' => 'apple', + 'two' => ['banana', 'plantain'], + 'three' => 'carrot', + 'four' => ['peaches', 'pumpkin pie'], + ]; + $list = new PropertyList($data); + + $list->addRendererFunction( + function ($key, $cellData, FormatterOptions $options) + { + if (is_array($cellData)) { + return implode(',', $cellData); + } + return $cellData; + } + ); + + return $list; + } + + protected function associativeListWithCsvCells() + { + $data = [ + 'one' => 'apple', + 'two' => ['banana', 'plantain'], + 'three' => 'carrot', + 'four' => ['peaches', 'pumpkin pie'], + ]; + return new PropertyListWithCsvCells($data); + } + + function testPropertyListWithCsvCells() + { + $this->doPropertyListWithCsvCells($this->associativeListWithRenderer()); + $this->doPropertyListWithCsvCells($this->associativeListWithCsvCells()); + } + + function doPropertyListWithCsvCells($data) + { + $expected = <<assertFormattedOutputMatches($expected, 'table', $data); + + $expectedList = <<< EOT +apple +banana,plantain +carrot +peaches,pumpkin pie +EOT; + $this->assertFormattedOutputMatches($expectedList, 'list', $data); + + $expectedCsv = <<< EOT +One,Two,Three,Four +apple,"banana,plantain",carrot,"peaches,pumpkin pie" +EOT; + $this->assertFormattedOutputMatches($expectedCsv, 'csv', $data); + + $expectedCsvNoHeaders = 'apple,"banana,plantain",carrot,"peaches,pumpkin pie"'; + $this->assertFormattedOutputMatches($expectedCsvNoHeaders, 'csv', $data, new FormatterOptions(), ['include-field-labels' => false]); + + $expectedTsv = <<< EOT +apple\tbanana,plantain\tcarrot\tpeaches,pumpkin pie +EOT; + $this->assertFormattedOutputMatches($expectedTsv, 'tsv', $data); + + } + + function testSimpleListWithFieldLabels() + { + $data = $this->simpleListExampleData(); + $configurationData = new FormatterOptions( + [ + 'field-labels' => ['one' => 'Ichi', 'two' => 'Ni', 'three' => 'San'], + ] + ); + + $expected = <<assertFormattedOutputMatches($expected, 'table', $data, $configurationData); + + $expectedWithReorderedFields = <<assertFormattedOutputMatches($expectedWithReorderedFields, 'table', $data, $configurationData, ['fields' => ['three', 'one']]); + $this->assertFormattedOutputMatches($expectedWithReorderedFields, 'table', $data, $configurationData, ['fields' => ['San', 'Ichi']]); + + $expectedJson = <<assertFormattedOutputMatches($expectedJson, 'json', $data, $configurationData, ['fields' => ['San', 'Ichi']]); + } + + function testSimpleXml() + { + $data = [ + 'name' => 'primary', + 'description' => 'The primary colors of the color wheel.', + 'colors' => + [ + 'red', + 'yellow', + 'blue', + ], + ]; + + $expected = << + + The primary colors of the color wheel. + + red + yellow + blue + + +EOT; + + $this->assertFormattedOutputMatches($expected, 'xml', $data); + } + + function domDocumentData() + { + $dom = new \DOMDocument('1.0', 'UTF-8'); + + $document = $dom->createElement('document'); + $dom->appendChild($document); + + $document->setAttribute('name', 'primary'); + $description = $dom->createElement('description'); + $document->appendChild($description); + $description->appendChild($dom->createTextNode('The primary colors of the color wheel.')); + + $this->domCreateElements($dom, $document, 'color', ['red', 'yellow', 'blue']); + + return $dom; + } + + function domCreateElements($dom, $element, $name, $data) + { + $container = $dom->createElement("{$name}s"); + $element->appendChild($container); + foreach ($data as $value) { + $child = $dom->createElement($name); + $container->appendChild($child); + $child->appendChild($dom->createTextNode($value)); + } + } + + function complexDomDocumentData() + { + $dom = new \DOMDocument('1.0', 'UTF-8'); + + $document = $dom->createElement('document'); + $dom->appendChild($document); + + $document->setAttribute('name', 'widget-collection'); + $description = $dom->createElement('description'); + $document->appendChild($description); + $description->appendChild($dom->createTextNode('A couple of widgets.')); + + $widgets = $dom->createElement('widgets'); + $document->appendChild($widgets); + + $widget = $dom->createElement('widget'); + $widgets->appendChild($widget); + $widget->setAttribute('name', 'usual'); + $this->domCreateElements($dom, $widget, 'color', ['red', 'yellow', 'blue']); + $this->domCreateElements($dom, $widget, 'shape', ['square', 'circle', 'triangle']); + + $widget = $dom->createElement('widget'); + $widgets->appendChild($widget); + $widget->setAttribute('name', 'unusual'); + $this->domCreateElements($dom, $widget, 'color', ['muave', 'puce', 'umber']); + $this->domCreateElements($dom, $widget, 'shape', ['elipse', 'rhombus', 'trapazoid']); + + return $dom; + } + + function domDocumentTestValues() + { + + $expectedXml = << + + The primary colors of the color wheel. + + red + yellow + blue + + +EOT; + + $expectedJson = << + + A couple of widgets. + + + + red + yellow + blue + + + square + circle + triangle + + + + + muave + puce + umber + + + elipse + rhombus + trapazoid + + + + +EOT; + + $expectedComplexJson = <<domDocumentData(), + $expectedXml, + $expectedJson, + ], + [ + $this->complexDomDocumentData(), + $expectedComplexXml, + $expectedComplexJson, + ], + ]; + } + + /** + * @dataProvider domDocumentTestValues + */ + function testDomData($data, $expectedXml, $expectedJson) + { + $this->assertFormattedOutputMatches($expectedXml, 'xml', $data); + $this->assertFormattedOutputMatches($expectedJson, 'json', $data); + + // Check to see if we get the same xml data if we convert from + // DOM -> array -> DOM. + $expectedJsonAsArray = (array)json_decode($expectedJson); + $this->assertFormattedOutputMatches($expectedXml, 'xml', $expectedJsonAsArray); + } + + /** + * @expectedException \Exception + * @expectedExceptionCode 1 + * @expectedExceptionMessage Data provided to Consolidation\OutputFormatters\Formatters\XmlFormatter must be either an instance of DOMDocument or an array. Instead, a string was provided. + */ + function testDataTypeForXmlFormatter() + { + $this->assertFormattedOutputMatches('Will fail, not return', 'xml', 'Strings cannot be converted to XML'); + } +} diff --git a/src/composer/vendor/consolidation/output-formatters/tests/testIncompatibleData.php b/src/composer/vendor/consolidation/output-formatters/tests/testIncompatibleData.php new file mode 100644 index 00000000..d38f9620 --- /dev/null +++ b/src/composer/vendor/consolidation/output-formatters/tests/testIncompatibleData.php @@ -0,0 +1,64 @@ +formatterManager = new FormatterManager(); + } + + protected function assertIncompatibleDataMessage($expected, $formatter, $data) + { + $e = new IncompatibleDataException($formatter, $data, $formatter->validDataTypes()); + $this->assertEquals($expected, $e->getMessage()); + } + + public function testIncompatibleData() + { + $tableFormatter = $this->formatterManager->getFormatter('table'); + + $this->assertIncompatibleDataMessage('Data provided to Consolidation\OutputFormatters\Formatters\TableFormatter must be either an instance of Consolidation\OutputFormatters\StructuredData\RowsOfFields or an instance of Consolidation\OutputFormatters\StructuredData\PropertyList. Instead, a string was provided.', $tableFormatter, 'a string'); + $this->assertIncompatibleDataMessage('Data provided to Consolidation\OutputFormatters\Formatters\TableFormatter must be either an instance of Consolidation\OutputFormatters\StructuredData\RowsOfFields or an instance of Consolidation\OutputFormatters\StructuredData\PropertyList. Instead, an instance of Consolidation\OutputFormatters\FormatterManager was provided.', $tableFormatter, $this->formatterManager); + $this->assertIncompatibleDataMessage('Data provided to Consolidation\OutputFormatters\Formatters\TableFormatter must be either an instance of Consolidation\OutputFormatters\StructuredData\RowsOfFields or an instance of Consolidation\OutputFormatters\StructuredData\PropertyList. Instead, an array was provided.', $tableFormatter, []); + $this->assertIncompatibleDataMessage('Data provided to Consolidation\OutputFormatters\Formatters\TableFormatter must be either an instance of Consolidation\OutputFormatters\StructuredData\RowsOfFields or an instance of Consolidation\OutputFormatters\StructuredData\PropertyList. Instead, an instance of Consolidation\OutputFormatters\StructuredData\PropertyList was provided.', $tableFormatter, new PropertyList([])); + } + + /** + * @expectedException \Exception + * @expectedExceptionMessage Undescribable data error: NULL + */ + public function testUndescribableData() + { + $tableFormatter = $this->formatterManager->getFormatter('table'); + $data = $tableFormatter->validate(null); + $this->assertEquals('Will throw before comparing.', $data); + } + + /** + * @expectedException \Exception + * @expectedExceptionMessage Data provided to Consolidation\OutputFormatters\Formatters\TableFormatter must be either an instance of Consolidation\OutputFormatters\StructuredData\RowsOfFields or an instance of Consolidation\OutputFormatters\StructuredData\PropertyList. Instead, a string was provided. + */ + public function testInvalidTableData() + { + $tableFormatter = $this->formatterManager->getFormatter('table'); + $data = $tableFormatter->validate('bad data type'); + $this->assertEquals('Will throw before comparing.', $data); + } + + /** + * @expectedException \Exception + * @expectedExceptionMessage Data provided to Consolidation\OutputFormatters\Formatters\SectionsFormatter must be an instance of Consolidation\OutputFormatters\StructuredData\RowsOfFields. Instead, a string was provided. + */ + public function testInvalidSectionsData() + { + $tableFormatter = $this->formatterManager->getFormatter('sections'); + $data = $tableFormatter->validate('bad data type'); + $this->assertEquals('Will throw before comparing.', $data); + } +} diff --git a/src/composer/vendor/consolidation/output-formatters/tests/testValidFormats.php b/src/composer/vendor/consolidation/output-formatters/tests/testValidFormats.php new file mode 100644 index 00000000..c02e5743 --- /dev/null +++ b/src/composer/vendor/consolidation/output-formatters/tests/testValidFormats.php @@ -0,0 +1,88 @@ +formatterManager = new FormatterManager(); + $this->formatterManager->addDefaultFormatters(); + $this->formatterManager->addDefaultSimplifiers(); + } + + function testValidFormats() + { + $arrayObjectRef = new \ReflectionClass('\ArrayObject'); + $associativeListRef = new \ReflectionClass('\Consolidation\OutputFormatters\StructuredData\PropertyList'); + $rowsOfFieldsRef = new \ReflectionClass('\Consolidation\OutputFormatters\StructuredData\RowsOfFields'); + $notADataType = new \ReflectionClass('\Consolidation\OutputFormatters\FormatterManager'); + + $jsonFormatter = $this->formatterManager->getFormatter('json'); + $isValid = $this->formatterManager->isValidFormat($jsonFormatter, $notADataType); + $this->assertFalse($isValid); + $isValid = $this->formatterManager->isValidFormat($jsonFormatter, new \ArrayObject()); + $this->assertTrue($isValid); + $isValid = $this->formatterManager->isValidFormat($jsonFormatter, $arrayObjectRef); + $this->assertTrue($isValid); + $isValid = $this->formatterManager->isValidFormat($jsonFormatter, []); + $this->assertTrue($isValid); + $isValid = $this->formatterManager->isValidFormat($jsonFormatter, $associativeListRef); + $this->assertTrue($isValid); + $isValid = $this->formatterManager->isValidFormat($jsonFormatter, $rowsOfFieldsRef); + $this->assertTrue($isValid); + + $sectionsFormatter = $this->formatterManager->getFormatter('sections'); + $isValid = $this->formatterManager->isValidFormat($sectionsFormatter, $notADataType); + $this->assertFalse($isValid); + $isValid = $this->formatterManager->isValidFormat($sectionsFormatter, []); + $this->assertFalse($isValid); + $isValid = $this->formatterManager->isValidFormat($sectionsFormatter, $arrayObjectRef); + $this->assertFalse($isValid); + $isValid = $this->formatterManager->isValidFormat($sectionsFormatter, $rowsOfFieldsRef); + $this->assertTrue($isValid); + $isValid = $this->formatterManager->isValidFormat($sectionsFormatter, $associativeListRef); + $this->assertFalse($isValid); + + // Check to see which formats can handle a simple array + $validFormats = $this->formatterManager->validFormats([]); + $this->assertEquals('csv,json,list,php,print-r,string,tsv,var_export,xml,yaml', implode(',', $validFormats)); + + // Check to see which formats can handle an PropertyList + $validFormats = $this->formatterManager->validFormats($associativeListRef); + $this->assertEquals('csv,json,list,php,print-r,string,table,tsv,var_export,xml,yaml', implode(',', $validFormats)); + + // Check to see which formats can handle an RowsOfFields + $validFormats = $this->formatterManager->validFormats($rowsOfFieldsRef); + $this->assertEquals('csv,json,list,php,print-r,sections,string,table,tsv,var_export,xml,yaml', implode(',', $validFormats)); + + // TODO: it woud be better if this returned an empty set instead of 'string'. + $validFormats = $this->formatterManager->validFormats($notADataType); + $this->assertEquals('string', implode(',', $validFormats)); + } + + function testAutomaticOptions() + { + $rowsOfFieldsRef = new \ReflectionClass('\Consolidation\OutputFormatters\StructuredData\RowsOfFields'); + $formatterOptions = new FormatterOptions( + [ + FormatterOptions::FIELD_LABELS => "name: Name\nphone_number: Phone Number", + ] + ); + $inputOptions = $this->formatterManager->automaticOptions($formatterOptions, $rowsOfFieldsRef); + $this->assertInputOptionDescriptionsEquals("Format the result data. Available formats: csv,json,list,php,print-r,sections,string,table,tsv,var_export,xml,yaml [Default: 'table']\nAvailable fields: Name (name), Phone Number (phone_number) [Default: '']\nSelect just one field, and force format to 'string'. [Default: '']", $inputOptions); + } + + function assertInputOptionDescriptionsEquals($expected, $inputOptions) + { + $descriptions = []; + foreach ($inputOptions as $inputOption) { + $descriptions[] = $inputOption->getDescription() . " [Default: '" . $inputOption->getDefault() . "']"; + } + $this->assertEquals($expected, implode("\n", $descriptions)); + } +} diff --git a/src/composer/vendor/consolidation/robo/.editorconfig b/src/composer/vendor/consolidation/robo/.editorconfig new file mode 100644 index 00000000..095771e6 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/.editorconfig @@ -0,0 +1,15 @@ +# This file is for unifying the coding style for different editors and IDEs +# editorconfig.org + +root = true + +[*] +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[**.php] +indent_style = space +indent_size = 4 + diff --git a/src/composer/vendor/consolidation/robo/.github/issue_template.md b/src/composer/vendor/consolidation/robo/.github/issue_template.md new file mode 100644 index 00000000..97335f49 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/.github/issue_template.md @@ -0,0 +1,11 @@ +### Steps to reproduce +What did you do? + +### Expected behavior +Tell us what should happen + +### Actual behavior +Tell us what happens instead + +### System Configuration +Which O.S. and PHP version are you using? diff --git a/src/composer/vendor/consolidation/robo/.github/pull_request_template.md b/src/composer/vendor/consolidation/robo/.github/pull_request_template.md new file mode 100644 index 00000000..d39b1522 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/.github/pull_request_template.md @@ -0,0 +1,13 @@ +### Overview +This pull request: + +- [ ] Fixes a bug +- [ ] Adds a feature +- [ ] Breaks backwards compatibility +- [ ] Needs tests + +### Summary +Short overview of what changed. + +### Description +Any additional information. diff --git a/src/composer/vendor/consolidation/robo/.gitignore b/src/composer/vendor/consolidation/robo/.gitignore new file mode 100644 index 00000000..bc900d2f --- /dev/null +++ b/src/composer/vendor/consolidation/robo/.gitignore @@ -0,0 +1,9 @@ +vendor/ +.idea/ +build +site/ +robotheme/ +tests/_log/* +tests/_helpers/_generated/* +composer.phar +robo.phar diff --git a/src/composer/vendor/consolidation/robo/.scrutinizer.yml b/src/composer/vendor/consolidation/robo/.scrutinizer.yml new file mode 100644 index 00000000..f84f59b4 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/.scrutinizer.yml @@ -0,0 +1,3 @@ +filter: + excluded_paths: + - "RoboFile.php" diff --git a/src/composer/vendor/consolidation/robo/.travis.yml b/src/composer/vendor/consolidation/robo/.travis.yml new file mode 100644 index 00000000..b7361a49 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/.travis.yml @@ -0,0 +1,47 @@ +language: php + +branches: + # Only test the master branch and SemVer tags. + only: + - master + - /^[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+.*$/ + +matrix: + include: + - php: 7.0 + env: dependencies=highest + - php: 5.6 + - php: 5.5 + - php: 5.5 + env: dependencies=lowest + +sudo: false + +cache: + directories: + - $HOME/.composer/cache + +before_script: + - if [ -z "$dependencies" ]; then composer install --prefer-dist; fi; + - if [ "$dependencies" = "lowest" ]; then composer update --prefer-dist --prefer-lowest -n; fi; + - if [ "$dependencies" = "highest" ]; then composer update --prefer-dist -n; fi; + +script: "./robo test --coverage" + +after_success: + - travis_retry php vendor/bin/coveralls -v + +# Prior to a deploy, build a fresh robo.phar +before_deploy: + - ./robo phar:build + +# Deploy instructions set up via `travis setup releases` per +# https://docs.travis-ci.com/user/deployment/releases +deploy: + provider: releases + api_key: + secure: EdmB1nW5gj5nggYfmHv20enSgvRIAl1PIWV5GKmkxAJwuummh3UqdI7z0ecTGdw2IBgJx9lizNvqhcWjXbpNhE9VaaT1sHFCKv4Zust6sLb9bneK3oLRdJk2wemfrrZQpdH900zA0o7b3CHVth8UhkrCB4FXVDjUW13K061EXG8= + file: robo.phar + skip_cleanup: true + on: + tags: true diff --git a/src/composer/vendor/consolidation/robo/CHANGELOG.md b/src/composer/vendor/consolidation/robo/CHANGELOG.md new file mode 100644 index 00000000..d00b18c9 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/CHANGELOG.md @@ -0,0 +1,240 @@ +# Changelog + +#### 1.0.4 + +* Updated to latest changes in `master` branch. Phar and tag issues. + +#### 1.0.0 + +* [Collection] Add tasks to a collection, and implement them as a group with rollback + * Tasks may be added to a collection via `$collection->add($task);` + * `$collection->run();` runs all tasks in the collection + * `$collection->addCode(function () { ... } );` to add arbitrary code to a collection + * `$collection->progressMessage(...);` will log a message + * `$collection->rollback($task);` and `$collection->rollbackCode($callable);` add a rollback function to clean up after a failed task + * `$collection->completion($task);` and `$collection->completionCode($callable);` add a function that is called once the collection completes or rolls back. + * `$collection->before();` and `$collection->after();` can be used to add a task or function that runs before or after (respectively) the specified named task. To use this feature, tasks must be given names via an optional `$taskName` parameter when they are added. + * Collections may be added to collections, if desired. +* [CollectionBuilder] Create tasks and add them to a collection in a single operation. + * `$this->collectionBuilder()->taskExec('pwd')->taskExec('ls')->run()` +* Add output formatters + * If a Robo command returns a string, or a `Result` object with a `$message`, then it will be printed + * Commands may be annotated to describe output formats that may be used + * Structured arrays returned from function results may be converted into different formats, such as a table, yml, json, etc. + * Tasks must `use TaskIO` for output methods. It is no longer possible to `use IO` from a task. For direct access use `Robo::output()` (not recommended). +* Use league/container to do Dependency Injection + * *Breaking* Tasks' loadTasks traits must use `$this->task(TaskClass::class);` instead of `new TaskClass();` + * *Breaking* Tasks that use other tasks must use `$this->collectionBuilder()->taskName();` instead of `new TaskClass();` when creating task objects to call. Implement `Robo\Contract\BuilderAwareInterface` and use `Robo\Contract\BuilderAwareTrait` to add the `collectionBuilder()` method to your task class. +* *Breaking* The `arg()`, `args()` and `option()` methods in CommandArguments now escape the values passed in to them. There is now a `rawArg()` method if you need to add just one argument that has already been escaped. +* *Breaking* taskWrite is now called taskWriteToFile +* [Extract] task added +* [Pack] task added +* [TmpDir], [WorkDir] and [TmpFile] tasks added +* Support Robo scripts that allows scripts starting with `#!/usr/bin/env robo` to define multiple robo commands. Use `#!/usr/bin/env robo run` to define a single robo command implemented by the `run()` method. +* Provide ProgresIndicatorAwareInterface and ProgressIndicatorAwareTrait that make it easy to add progress indicators to tasks +* Add --simulate mode that causes tasks to print what they would have done, but make no changes +* Add `robo generate:task` code-generator to make new stack-based task wrappers around existing classes +* Add `robo sniff` by @dustinleblanc. Runs the PHP code sniffer followed by the code beautifier, if needed. +* Implement ArrayInterface for Result class, so result data may be accessed like an array +* Defer execution of operations in taskWriteToFile until the run() method +* Add Write::textIfMatch() for taskWriteToFile +* ResourceExistenceChecker used for error checking in DeleteDir, CopyDir, CleanDir and Concat tasks by @burzum +* Provide ResultData base class for Result; ResultData may be used in instances where a specific `$task` instance is not available (e.g. in a Robo command) +* ArgvInput now available via $this->getInput() in RoboFile by Thomas Spigel +* Add optional message to git tag task by Tim Tegeler +* Rename 'FileSystem' to 'Filesystem' wherever it occurs. +* Current directory is changed with `chdir` only if specified via the `--load-from` option (RC2) + +#### 0.6.0 + +* Added `--load-from` option to make Robo start RoboFiles from other directories. Use it like `robo --load-from /path/to/where/RobFile/located`. +* Robo will not ask to create RoboFile if it does not exist, `init` command should be used. +* [ImageMinify] task added by @gabor-udvari +* [OpenBrowser] task added by @oscarotero +* [FlattenDir] task added by @gabor-udvari +* Robo Runner can easily extended for custom runner by passing RoboClass and RoboFile parameters to constructor. By @rdeutz See #232 + +#### 0.5.4 + +* [WriteToFile] Fixed by @gabor-udvari: always writing to file regardless whether any changes were made or not. This can bring the taskrunner into an inifinite loop if a replaced file is being watched. +* [Scss] task added, requires `leafo/scssphp` library to compile by @gabor-udvari +* [PhpSpec] TAP formatter added by @orls +* [Less] Added ability to set import dir for less compilers by @MAXakaWIZARD +* [Less] fixed passing closure as compiler by @pr0nbaer +* [Sass] task added by *2015-08-31* + +#### 0.5.3 + + * [Rsync] Ability to use remote shell with identity file by @Mihailoff + * [Less] Task added by @burzum + * [PHPUnit] allow to test specific files with `files` parameter by @burzum. + * [GitStack] `tag` added by @SebSept + * [Concat] Fixing concat, it breaks some files if there is no new line. @burzum *2015-03-03-13* + * [Minify] BC fix to support Jsqueeze 1.x and 2.x @burzum *2015-03-12* + * [PHPUnit] Replace log-xml with log-junit @vkunz *2015-03-06* + * [Minify] Making it possible to pass options to the JS minification @burzum *2015-03-05* + * [CopyDir] Create destination recursively @boedah *2015-02-28* + +#### 0.5.2 + +* [Phar] do not compress phar if more than 1000 files included (causes internal PHP error) *2015-02-24* +* _copyDir and _mirrorDir shortcuts fixed by @boedah *2015-02-24* +* [File\Write] methods replace() and regexReplace() added by @asterixcapri *2015-02-24* +* [Codecept] Allow to set custom name of coverage file raw name by @raistlin *2015-02-24* +* [Ssh] Added property `remoteDir` by @boedah *2015-02-24* +* [PhpServer] fixed passing arguments to server *2015-02-24* + + +#### 0.5.1 + +* [Exec] fixed execution of background jobs, processes persist till the end of PHP script *2015-01-27* +* [Ssh] Fixed SSH task by @Butochnikov *2015-01-27* +* [CopyDir] fixed shortcut usage by @boedah *2015-01-27* +* Added default value options for Configuration trait by @TamasBarta *2015-01-27* + +#### 0.5.0 + +Refactored core + +* All traits moved to `Robo\Common` namespace +* Interfaces moved to `Robo\Contract` namespace +* All task extend `Robo\Task\BaseTask` to use common IO. +* All classes follow PSR-4 standard +* Tasks are loaded into RoboFile with `loadTasks` trait +* One-line tasks are available as shortcuts loaded by `loadShortucts` and used like `$this->_exec('ls')` +* Robo runner is less coupled. Output can be set by `\Robo\Config::setOutput`, `RoboFile` can be changed to any provided class. +* Tasks can be used outside of Robo runner (inside a project) +* Timer for long-running tasks added +* Tasks can be globally configured (WIP) via `Robo\Config` class. +* Updated to Symfony >= 2.5 +* IO methods added `askHidden`, `askDefault`, `confirm` +* TaskIO methods added `printTaskError`, `printTaskSuccess` with different formatting. +* [Docker] Tasks added +* [Gulp] Task added by @schorsch3000 + +#### 0.4.7 + +* [Minify] Task added by @Rarst. Requires additional dependencies installed *2014-12-26* +* [Help command is populated from annotation](https://github.com/consolidation-org/Robo/pull/71) by @jonsa *2014-12-26* +* Allow empty values as defaults to optional options by @jonsa *2014-12-26* +* `PHP_WINDOWS_VERSION_BUILD` constant is used to check for Windows in tasks by @boedah *2014-12-26* +* [Copy][EmptyDir] Fixed infinite loop by @boedah *2014-12-26* +* [ApiGen] Task added by @drobert *2014-12-26* +* [FileSystem] Equalized `copy` and `chmod` argument to defaults by @Rarst (BC break) *2014-12-26* +* [FileSystem] Added missing umask argument to chmod() method of FileSystemStack by @Rarst +* [SemVer] Fixed file read and exit code +* [Codeception] fixed codeception coverageHtml option by @gunfrank *2014-12-26* +* [phpspec] Task added by @SebSept *2014-12-26* +* Shortcut options: if option name is like foo|f, assign f as shortcut by @jschnare *2014-12-26* +* [Rsync] Shell escape rsync exclude pattern by @boedah. Fixes #77 (BC break) *2014-12-26* +* [Npm] Task added by @AAlakkad *2014-12-26* + +#### 0.4.6 + +* [Exec] Output from buffer is not spoiled by special chars *2014-10-17* +* [PHPUnit] detect PHPUnit on Windows or when is globally installed with Composer *2014-10-17* +* Output: added methods askDefault and confirm by @bkawakami *2014-10-17* +* [Svn] Task added by @anvi *2014-08-13* +* [Stack] added dir and printed options *2014-08-12* +* [ExecTask] now uses Executable trait with printed, dir, arg, option methods added *2014-08-12* + + +#### 0.4.5 + +* [Watch] bugfix: Watch only tracks last file if given array of files #46 *2014-08-05* +* All executable tasks can configure working directory with `dir` option +* If no value for an option is provided, assume it's a VALUE_NONE option. #47 by @pfaocle +* [Changelog] changed style *2014-06-27* +* [GenMarkDown] fixed formatting annotations *2014-06-27* + +#### 0.4.4 06/05/2014 + +* Output can be disabled in all executable tasks by ->printed(false) +* disabled timeouts by default in ParallelExec +* better descriptions for Result output +* changed ParallelTask to display failed process in list +* Changed Output to be stored globally in Robo\Runner class +* Added **SshTask** by @boedah +* Added **RsyncTask** by @boedah +* false option added to proceess* callbacks in GenMarkDownTask to skip processing + + +#### 0.4.3 05/21/2014 + +* added `SemVer` task by **@jadb** +* `yell` output method added +* task `FileSystemStack` added +* `MirrorDirTask` added by **@devster** +* switched to Symfony Filesystem component +* options can be used to commands +* array arguments can be used in commands + +#### 0.4.2 05/09/2014 + +* ask can now hide answers +* Trait Executable added to provide standard way for passing arguments and options +* added ComposerDumpAutoload task by **@pmcjury** +* added FileSystem task by **@jadb** +* added CommonStack metatsk to have similar interface for all stacked tasks by **@jadb** +* arguments and options can be passed into variable and used in exec task +* passing options into commands + + +#### 0.4.1 05/05/2014 + +* [BC] `taskGit` task renamed to `taskGitStack` for compatibility +* unit and functional tests added +* all command tasks now use Symfony\Process to execute them +* enabled Bower and Concat tasks +* added `printed` param to Exec task +* codeception `suite` method now returns `$this` +* timeout options added to Exec task + + +#### 0.4.0 04/27/2014 + +* Codeception task added +* PHPUnit task improved +* Bower task added by @jadb +* ParallelExec task added +* Symfony Process component used for execution +* Task descriptions taken from first line of annotations +* `CommandInterface` added to use tasks as parameters + +#### 0.3.3 02/25/2014 + +* PHPUnit basic task +* fixed doc generation + +#### 0.3.5 02/21/2014 + +* changed generated init template + + +#### 0.3.4 02/21/2014 + +* [PackPhar] ->executable command will remove hashbang when generated stub file +* [Git][Exec] stopOnFail option for Git and Exec stack +* [ExecStack] shortcut for executing bash commands in stack + +#### 0.3.2 02/20/2014 + +* release process now includes phar +* phar executable method added +* git checkout added +* phar pack created + + +#### 0.3.0 02/11/2014 + +* Dynamic configuration via magic methods +* added WriteToFile task +* Result class for managing exit codes and error messages + +#### 0.2.0 01/29/2014 + +* Merged Tasks and Traits to same file +* Added Watcher task +* Added GitHubRelease task +* Added Changelog task +* Added ReplaceInFile task diff --git a/src/composer/vendor/consolidation/robo/CONTRIBUTING.md b/src/composer/vendor/consolidation/robo/CONTRIBUTING.md new file mode 100644 index 00000000..43868146 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/CONTRIBUTING.md @@ -0,0 +1,15 @@ +# Contributing to Robo + +Thank you for your interest in contributing to Robo! Here are some of the guidelines you should follow to make the most of your efforts: + +## Code Style Guidelines + +Robo adheres to the [PSR-2 Coding Style Guide](http://www.php-fig.org/psr/psr-2/) for PHP code. An `.editorconfig` file is included with the repository to help you get up and running quickly. Most modern editors support this standard, but if yours does not or you would like to configure your editor manually, follow the guidelines in the document linked above. + +You can run the PHP Codesniffer on your work using a convenient command built into this project's own `RoboFile.php`: +``` +robo sniff src/Foo.php --autofix +``` +The above will run the PHP Codesniffer on the `src/Foo.php` file and automatically correct variances from the PSR-2 standard. Please ensure all contributions are compliant _before_ submitting a pull request. + + diff --git a/src/composer/vendor/consolidation/robo/LICENSE b/src/composer/vendor/consolidation/robo/LICENSE new file mode 100644 index 00000000..63e051a6 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2014 Codegyre Developers Team, Consolidation Team + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/src/composer/vendor/consolidation/robo/README.md b/src/composer/vendor/consolidation/robo/README.md new file mode 100644 index 00000000..8c807591 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/README.md @@ -0,0 +1,174 @@ +# RoboTask + +**Modern and simple PHP task runner** inspired by Gulp and Rake aimed to automate common tasks: + +[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/consolidation-org/Robo?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +[![Latest Stable Version](https://poser.pugx.org/consolidation/robo/v/stable.png)](https://packagist.org/packages/consolidation/robo) +[![Latest Unstable Version](https://poser.pugx.org/consolidation/robo/v/unstable.png)](https://packagist.org/packages/consolidation/robo) +[![Total Downloads](https://poser.pugx.org/consolidation/robo/downloads.png)](https://packagist.org/packages/consolidation/robo) +[![PHP 7 ready](http://php7ready.timesplinter.ch/consolidation/Robo/badge.svg)](https://travis-ci.org/consolidation/Robo) +[![License](https://poser.pugx.org/consolidation/robo/license.png)](https://www.versioneye.com/user/projects/57c4a6fe968d64004d97620a?child=57c4a6fe968d64004d97620a#tab-licenses) + +[![Build Status](https://travis-ci.org/consolidation/Robo.svg?branch=master)](https://travis-ci.org/consolidation/Robo) +[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/consolidation/Robo/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/consolidation/Robo/?branch=master) +[![Dependency Status](https://www.versioneye.com/user/projects/57c4a6fe968d64004d97620a/badge.svg?style=flat-square)](https://www.versioneye.com/user/projects/57c4a6fe968d64004d97620a) + +* writing cross-platform scripts +* processing assets (less, sass, minification) +* running tests +* executing daemons (and workers) +* watching filesystem changes +* deployment with sftp/ssh/docker + +## Installing + +### Phar + +[Download robo.phar >](http://robo.li/robo.phar) + +``` +wget http://robo.li/robo.phar +``` + +To install globally put `robo.phar` in `/usr/bin`. + +``` +chmod +x robo.phar && sudo mv robo.phar /usr/bin/robo +``` + +Now you can use it just like `robo`. + +### Composer + +* Run `composer require consolidation/robo:~1` +* Use `vendor/bin/robo` to execute Robo tasks. + +## Usage + +All tasks are defined as **public methods** in `RoboFile.php`. It can be created by running `robo`. +All protected methods in traits that start with `task` prefix are tasks and can be configured and executed in your tasks. + +## Examples + +The best way to learn Robo by example is to take a look into [its own RoboFile](https://github.com/consolidation-org/Robo/blob/master/RoboFile.php) + or [RoboFile of Codeception project](https://github.com/Codeception/Codeception/blob/master/RoboFile.php). There are also some basic example commands in examples/RoboFile.php. + +Here are some snippets from them: + +--- + +Run acceptance test with local server and selenium server started. + + +``` php +taskServer(8000) + ->background() + ->dir('web') + ->run(); + + // running Selenium server in background + $this->taskExec('java -jar ' . $seleniumPath) + ->background() + ->run(); + + // loading Symfony Command and running with passed argument + $this->taskSymfonyCommand(new \Codeception\Command\Run('run')) + ->arg('suite','acceptance') + ->run(); + } +} +``` + +If you execute `robo` you will see this task added to list of available task with name: `test:acceptance`. +To execute it you shoud run `robo test:acceptance`. You may change path to selenium server by passing new path as a argument: + +``` +robo test:acceptance "C:\Downloads\selenium.jar" +``` + +Using `watch` task so you can use it for running tests or building assets. + +``` php +taskWatch()->monitor('composer.json', function() { + $this->taskComposerUpdate()->run(); + })->run(); + } +} +``` + +--- + +Cleaning logs and cache + +``` php +taskCleanDir([ + 'app/cache', + 'app/logs' + ])->run(); + + $this->taskDeleteDir([ + 'web/assets/tmp_uploads', + ])->run(); + } +} +``` + +This task cleans `app/cache` and `app/logs` dirs (ignoring .gitignore and .gitkeep files) +Can be executed by running: + +``` +robo clean +``` + +---- + +Creating Phar archive + +``` php +function buildPhar() +{ + $files = Finder::create()->ignoreVCS(true)->files()->name('*.php')->in(__DIR__); + $packer = $this->taskPackPhar('robo.phar'); + foreach ($files as $file) { + $packer->addFile($file->getRelativePathname(), $file->getRealPath()); + } + $packer->addFile('robo','robo') + ->executable('robo') + ->run(); +} +``` + +--- + +## We need more tasks! + +Create your own tasks and send them as Pull Requests or create packages prefixed with `robo-` on Packagist. + +## Credits + +Follow [@robo_php](http://twitter.com/robo_php) for updates. + +Brought to you by [Consolidation Team](https://github.com/orgs/consolidation/people) and our [awesome contributors](https://github.com/consolidation/Robo/graphs/contributors). + +## License + +[MIT](https://github.com/consolidation/Robo/blob/master/LICENSE) diff --git a/src/composer/vendor/consolidation/robo/RoboFile.php b/src/composer/vendor/consolidation/robo/RoboFile.php new file mode 100644 index 00000000..b9a2810d --- /dev/null +++ b/src/composer/vendor/consolidation/robo/RoboFile.php @@ -0,0 +1,377 @@ + false, + 'coverage' => false + ]) + { + $taskCodecept = $this->taskCodecept() + ->args($args); + + if ($options['coverage']) { + $taskCodecept->coverageXml('../../build/logs/clover.xml'); + } + if ($options['coverage-html']) { + $taskCodecept->coverageHtml('../../build/logs/coverage'); + } + + return $taskCodecept->run(); + } + + /** + * Code sniffer. + * + * Run the PHP Codesniffer on a file or directory. + * + * @param string $file + * A file or directory to analyze. + * @option $autofix Whether to run the automatic fixer or not. + * @option $strict Show warnings as well as errors. + * Default is to show only errors. + */ + public function sniff( + $file = 'src/', + $options = [ + 'autofix' => false, + 'strict' => false, + ] + ) { + $strict = $options['strict'] ? '' : '-n'; + $result = $this->taskExec("./vendor/bin/phpcs --standard=PSR2 {$strict} {$file}")->run(); + if (!$result->wasSuccessful()) { + if (!$options['autofix']) { + $options['autofix'] = $this->confirm('Would you like to run phpcbf to fix the reported errors?'); + } + if ($options['autofix']) { + $result = $this->taskExec("./vendor/bin/phpcbf --standard=PSR2 {$file}")->run(); + } + } + return $result; + } + + /** + * Generate a new Robo task that wraps an existing utility class. + * + * @param $className The name of the existing utility class to wrap. + * @param $wrapperClassName The name of the wrapper class to create. Optional. + * @usage generate:task 'Symfony\Component\Filesystem\Filesystem' FilesystemStack + */ + public function generateTask($className, $wrapperClassName = "") + { + return $this->taskGenTask($className, $wrapperClassName)->run(); + } + + /** + * Release Robo. + */ + public function release($opts = ['beta' => false]) + { + $this->yell("Releasing Robo"); + $stable = true; + if ($opts['beta']) { + $stable = false; + $this->say('non-stable release'); + } + + $this->docs(); + $this->taskGitStack() + ->add('-A') + ->commit("auto-update") + ->pull() + ->push() + ->run(); + + if ($stable) $this->pharPublish(); + $this->publish(); + + $this->taskGitStack() + ->tag(\Robo\Robo::VERSION) + ->push('origin master --tags') + ->run(); + + if ($stable) $this->versionBump(); + } + + /** + * Update changelog. + * + * Add an entry to the Robo CHANGELOG.md file. + * + * @param string $addition The text to add to the change log. + */ + public function changed($addition) + { + return $this->taskChangelog() + ->version(\Robo\Robo::VERSION) + ->change($addition) + ->run(); + } + + /** + * Update the version of Robo. + * + * @param string $version The new verison for Robo. + * Defaults to the next minor (bugfix) version after the current relelase. + */ + public function versionBump($version = '') + { + if (empty($version)) { + $versionParts = explode('.', \Robo\Robo::VERSION); + $versionParts[count($versionParts)-1]++; + $version = implode('.', $versionParts); + } + return $this->taskReplaceInFile(__DIR__.'/src/Robo.php') + ->from("VERSION = '".\Robo\Robo::VERSION."'") + ->to("VERSION = '".$version."'") + ->run(); + } + + /** + * Generate the Robo documentation files. + */ + public function docs() + { + $collection = $this->collectionBuilder(); + $collection->progressMessage('Generate documentation from source code.'); + $files = Finder::create()->files()->name('*.php')->in('src/Task'); + $docs = []; + foreach ($files as $file) { + if ($file->getFileName() == 'loadTasks.php') { + continue; + } + if ($file->getFileName() == 'loadShortcuts.php') { + continue; + } + $ns = $file->getRelativePath(); + if (!$ns) { + continue; + } + $class = basename(substr($file, 0, -4)); + class_exists($class = "Robo\\Task\\$ns\\$class"); + $docs[$ns][] = $class; + } + ksort($docs); + + foreach ($docs as $ns => $tasks) { + $taskGenerator = $collection->taskGenDoc("docs/tasks/$ns.md"); + $taskGenerator->filterClasses(function (\ReflectionClass $r) { + return !($r->isAbstract() || $r->isTrait()) && $r->implementsInterface('Robo\Contract\TaskInterface'); + })->prepend("# $ns Tasks"); + sort($tasks); + foreach ($tasks as $class) { + $taskGenerator->docClass($class); + } + + $taskGenerator->filterMethods( + function (\ReflectionMethod $m) { + if ($m->isConstructor() || $m->isDestructor() || $m->isStatic()) { + return false; + } + $undocumentedMethods = + [ + '', + 'run', + '__call', + 'inflect', + 'injectDependencies', + 'getCommand', + 'getPrinted', + 'getConfig', + 'setConfig', + 'logger', + 'setLogger', + 'setProgressIndicator', + 'progressIndicatorSteps', + 'setBuilder', + 'getBuilder', + 'collectionBuilder', + ]; + return !in_array($m->name, $undocumentedMethods) && $m->isPublic(); // methods are not documented + } + )->processClassSignature( + function ($c) { + return "## " . preg_replace('~Task$~', '', $c->getShortName()) . "\n"; + } + )->processClassDocBlock( + function (\ReflectionClass $c, $doc) { + $doc = preg_replace('~@method .*?(.*?)\)~', '* `$1)` ', $doc); + $doc = str_replace('\\'.$c->name, '', $doc); + return $doc; + } + )->processMethodSignature( + function (\ReflectionMethod $m, $text) { + return str_replace('#### *public* ', '* `', $text) . '`'; + } + )->processMethodDocBlock( + function (\ReflectionMethod $m, $text) { + + return $text ? ' ' . trim(strtok($text, "\n"), "\n") : ''; + } + ); + } + $collection->progressMessage('Documentation generation complete.'); + return $collection->run(); + } + + /** + * Publish Robo. + * + * Builds a site in gh-pages branch. Uses mkdocs + */ + public function publish() + { + $current_branch = exec('git rev-parse --abbrev-ref HEAD'); + + return $this->collectionBuilder() + ->taskGitStack() + ->checkout('site') + ->merge('master') + ->completion($this->taskGitStack()->checkout($current_branch)) + ->taskFilesystemStack() + ->copy('CHANGELOG.md', 'docs/changelog.md') + ->completion($this->taskFilesystemStack()->remove('docs/changelog.md')) + ->taskExec('mkdocs gh-deploy') + ->run(); + } + + /** + * Build the Robo phar executable. + */ + public function pharBuild() + { + // Create a collection builder to hold the temporary + // directory until the pack phar task runs. + $collection = $this->collectionBuilder(); + + $workDir = $collection->tmpDir(); + $roboBuildDir = "$workDir/robo"; + + // Before we run `composer install`, we will remove the dev + // dependencies that we only use in the unit tests. Any dev dependency + // that is in the 'suggested' section is used by a core task; + // we will include all of those in the phar. + $devProjectsToRemove = $this->devDependenciesToRemoveFromPhar(); + + // We need to create our work dir and run `composer install` + // before we prepare the pack phar task, so create a separate + // collection builder to do this step in. + $prepTasks = $this->collectionBuilder(); + + $preparationResult = $prepTasks + ->taskFilesystemStack() + ->mkdir($workDir) + ->taskRsync() + ->fromPath( + [ + __DIR__ . '/composer.json', + __DIR__ . '/scripts', + __DIR__ . '/src', + __DIR__ . '/data' + ] + ) + ->toPath($roboBuildDir) + ->recursive() + ->progress() + ->stats() + ->taskComposerRemove() + ->dir($roboBuildDir) + ->dev() + ->noUpdate() + ->args($devProjectsToRemove) + ->taskComposerInstall() + ->dir($roboBuildDir) + ->printed(false) + ->run(); + + // Exit if the preparation step failed + if (!$preparationResult->wasSuccessful()) { + return $preparationResult; + } + + // Decide which files we're going to pack + $files = Finder::create()->ignoreVCS(true) + ->files() + ->name('*.php') + ->name('*.exe') // for 1symfony/console/Resources/bin/hiddeninput.exe + ->name('GeneratedWrapper.tmpl') + ->path('src') + ->path('vendor') + ->notPath('docs') + ->notPath('/vendor\/.*\/[Tt]est/') + ->in(is_dir($roboBuildDir) ? $roboBuildDir : __DIR__); + + // Build the phar + return $collection + ->taskPackPhar('robo.phar') + ->addFiles($files) + ->addFile('robo', 'robo') + ->executable('robo') + ->taskFilesystemStack() + ->chmod('robo.phar', 0777) + ->run(); + } + + /** + * The phar:build command removes the project requirements from the + * 'require-dev' section that are not in the 'suggest' section. + * + * @return array + */ + protected function devDependenciesToRemoveFromPhar() + { + $composerInfo = (array) json_decode(file_get_contents(__DIR__ . '/composer.json')); + + $devDependencies = array_keys((array)$composerInfo['require-dev']); + $suggestedProjects = array_keys((array)$composerInfo['suggest']); + + return array_diff($devDependencies, $suggestedProjects); + } + + /** + * Install Robo phar. + * + * Installs the Robo phar executable in /usr/bin. Uses 'sudo'. + */ + public function pharInstall() + { + return $this->taskExec('sudo cp') + ->arg('robo.phar') + ->arg('/usr/bin/robo') + ->run(); + } + + /** + * Publish Robo phar. + * + * Commits the phar executable to Robo's GitHub pages site. + */ + public function pharPublish() + { + $this->pharBuild(); + + $this->collectionBuilder() + ->taskFilesystemStack() + ->rename('robo.phar', 'robo-release.phar') + ->taskGitStack() + ->checkout('site') + ->pull('origin site') + ->taskFilesystemStack() + ->remove('robotheme/robo.phar') + ->rename('robo-release.phar', 'robotheme/robo.phar') + ->taskGitStack() + ->add('robotheme/robo.phar') + ->commit('Update robo.phar to ' . \Robo\Robo::VERSION) + ->push('origin site') + ->checkout('master') + ->run(); + } +} diff --git a/src/composer/vendor/consolidation/robo/codeception.yml b/src/composer/vendor/consolidation/robo/codeception.yml new file mode 100644 index 00000000..09763ea7 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/codeception.yml @@ -0,0 +1,21 @@ +actor: Guy +paths: + tests: tests + log: tests/_log + data: tests/_data + helpers: tests/_helpers +settings: + bootstrap: _bootstrap.php + colors: true + memory_limit: 1024M +modules: + config: + Db: + dsn: '' + user: '' + password: '' + dump: tests/_data/dump.sql +coverage: + enabled: true + include: + - src/* diff --git a/src/composer/vendor/consolidation/robo/composer.json b/src/composer/vendor/consolidation/robo/composer.json new file mode 100644 index 00000000..adc54130 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/composer.json @@ -0,0 +1,70 @@ +{ + "name": "consolidation/robo", + "description": "Modern task runner", + "license": "MIT", + "authors": [ + { + "name": "Davert", + "email": "davert.php@resend.cc" + } + ], + "autoload":{ + "classmap": [ + "scripts/composer/ScriptHandler.php" + ], + "psr-4":{ + "Robo\\":"src" + } + }, + "autoload-dev":{ + "psr-4":{ + "Robo\\":"tests/src" + } + }, + "bin":["robo"], + "require": { + "php": ">=5.5.0", + "league/container": "^2.2", + "consolidation/log": "~1", + "consolidation/annotated-command": "^2.0.1", + "consolidation/output-formatters": "^2.1.2|~3", + "symfony/finder": "~2.5|~3.0", + "symfony/console": "~2.8|~3.0", + "symfony/process": "~2.5|~3.0", + "symfony/filesystem": "~2.5|~3.0", + "symfony/event-dispatcher": "~2.5|~3.0" + }, + "require-dev": { + "patchwork/jsqueeze": "~2", + "henrikbjorn/lurker": "~1", + "natxet/CssMin": "~3", + "pear/archive_tar": "^1.4.2", + "codeception/base": "^2.2.6", + "codeception/verify": "^0.3.2", + "codeception/aspect-mock": "~1", + "satooshi/php-coveralls": "~1", + "squizlabs/php_codesniffer": "~2", + "phpunit/php-code-coverage": "~2|~4" + }, + "scripts": { + "pre-install-cmd": [ + "Robo\\composer\\ScriptHandler::checkDependencies" + ], + "cs": "/robo sniff", + "test": "./robo test" + }, + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "suggest": { + "pear/archive_tar": "Allows tar archives to be created and extracted in taskPack and taskExtract, respectively.", + "henrikbjorn/lurker": "For monitoring filesystem changes in taskWatch", + "patchwork/jsqueeze": "For minifying JS files in taskMinify", + "natxet/CssMin": "For minifying JS files in taskMinify" + }, + "replace": { + "codegyre/robo": "< 1.0" + } +} diff --git a/src/composer/vendor/consolidation/robo/composer.lock b/src/composer/vendor/consolidation/robo/composer.lock new file mode 100644 index 00000000..d3f4b7e9 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/composer.lock @@ -0,0 +1,3518 @@ +{ + "_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": "01e04acee2b5eae505aa21f88465a6a4", + "content-hash": "ebfcda102135166d31ae314f4dfec7da", + "packages": [ + { + "name": "consolidation/annotated-command", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/consolidation/annotated-command.git", + "reference": "0bcb15e86b8bfbb1972fc6bc31b7d9c3fa40285d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/consolidation/annotated-command/zipball/0bcb15e86b8bfbb1972fc6bc31b7d9c3fa40285d", + "reference": "0bcb15e86b8bfbb1972fc6bc31b7d9c3fa40285d", + "shasum": "" + }, + "require": { + "consolidation/output-formatters": "~2|~3", + "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": { + "phpunit/phpunit": "4.*", + "satooshi/php-coveralls": "^1.0", + "squizlabs/php_codesniffer": "^2.7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Consolidation\\AnnotatedCommand\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Greg Anderson", + "email": "greg.1.anderson@greenknowe.org" + } + ], + "description": "Initialize Symfony Console commands from annotated command class methods.", + "time": "2016-11-14 23:51:12" + }, + { + "name": "consolidation/log", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/consolidation/log.git", + "reference": "74ba81b4edc585616747cc5c5309ce56fec41254" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/consolidation/log/zipball/74ba81b4edc585616747cc5c5309ce56fec41254", + "reference": "74ba81b4edc585616747cc5c5309ce56fec41254", + "shasum": "" + }, + "require": { + "php": ">=5.5.0", + "psr/log": "~1.0", + "symfony/console": "~2.5|~3.0" + }, + "require-dev": { + "phpunit/phpunit": "4.*", + "squizlabs/php_codesniffer": "2.*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Consolidation\\Log\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Greg Anderson", + "email": "greg.1.anderson@greenknowe.org" + } + ], + "description": "Improved Psr-3 / Psr\\Log logger based on Symfony Console components.", + "time": "2016-03-23 23:46:42" + }, + { + "name": "consolidation/output-formatters", + "version": "3.0.1", + "source": { + "type": "git", + "url": "https://github.com/consolidation/output-formatters.git", + "reference": "31aac0f6ffd76833a70a12ba7fb3e428f78b55ef" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/consolidation/output-formatters/zipball/31aac0f6ffd76833a70a12ba7fb3e428f78b55ef", + "reference": "31aac0f6ffd76833a70a12ba7fb3e428f78b55ef", + "shasum": "" + }, + "require": { + "php": ">=5.4.0", + "symfony/console": "~2.5|~3.0", + "symfony/finder": "~2.5|~3.0", + "victorjonsson/markdowndocs": "^1.3" + }, + "require-dev": { + "phpunit/phpunit": "4.*", + "satooshi/php-coveralls": "^1.0", + "squizlabs/php_codesniffer": "2.*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Consolidation\\OutputFormatters\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Greg Anderson", + "email": "greg.1.anderson@greenknowe.org" + } + ], + "description": "Format text by applying transformations provided by plug-in formatters.", + "time": "2016-11-14 18:44:33" + }, + { + "name": "container-interop/container-interop", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/container-interop/container-interop.git", + "reference": "fc08354828f8fd3245f77a66b9e23a6bca48297e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/container-interop/container-interop/zipball/fc08354828f8fd3245f77a66b9e23a6bca48297e", + "reference": "fc08354828f8fd3245f77a66b9e23a6bca48297e", + "shasum": "" + }, + "type": "library", + "autoload": { + "psr-4": { + "Interop\\Container\\": "src/Interop/Container/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Promoting the interoperability of container objects (DIC, SL, etc.)", + "time": "2014-12-30 15:22:37" + }, + { + "name": "league/container", + "version": "2.2.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/container.git", + "reference": "c0e7d947b690891f700dc4967ead7bdb3d6708c1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/container/zipball/c0e7d947b690891f700dc4967ead7bdb3d6708c1", + "reference": "c0e7d947b690891f700dc4967ead7bdb3d6708c1", + "shasum": "" + }, + "require": { + "container-interop/container-interop": "^1.1", + "php": ">=5.4.0" + }, + "provide": { + "container-interop/container-interop-implementation": "^1.1" + }, + "replace": { + "orno/di": "~2.0" + }, + "require-dev": { + "phpunit/phpunit": "4.*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev", + "dev-1.x": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Container\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Phil Bennett", + "email": "philipobenito@gmail.com", + "homepage": "http://www.philipobenito.com", + "role": "Developer" + } + ], + "description": "A fast and intuitive dependency injection container.", + "homepage": "https://github.com/thephpleague/container", + "keywords": [ + "container", + "dependency", + "di", + "injection", + "league", + "provider", + "service" + ], + "time": "2016-03-17 11:07:59" + }, + { + "name": "phpdocumentor/reflection-common", + "version": "1.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/144c307535e82c8fdcaacbcfc1d6d8eeb896687c", + "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "phpunit/phpunit": "^4.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ], + "time": "2015-12-27 11:43:31" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "3.1.1", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "8331b5efe816ae05461b7ca1e721c01b46bafb3e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/8331b5efe816ae05461b7ca1e721c01b46bafb3e", + "reference": "8331b5efe816ae05461b7ca1e721c01b46bafb3e", + "shasum": "" + }, + "require": { + "php": ">=5.5", + "phpdocumentor/reflection-common": "^1.0@dev", + "phpdocumentor/type-resolver": "^0.2.0", + "webmozart/assert": "^1.0" + }, + "require-dev": { + "mockery/mockery": "^0.9.4", + "phpunit/phpunit": "^4.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "time": "2016-09-30 07:12:33" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "0.2", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "b39c7a5b194f9ed7bd0dd345c751007a41862443" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/b39c7a5b194f9ed7bd0dd345c751007a41862443", + "reference": "b39c7a5b194f9ed7bd0dd345c751007a41862443", + "shasum": "" + }, + "require": { + "php": ">=5.5", + "phpdocumentor/reflection-common": "^1.0" + }, + "require-dev": { + "mockery/mockery": "^0.9.4", + "phpunit/phpunit": "^5.2||^4.8.24" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "time": "2016-06-10 07:14:17" + }, + { + "name": "psr/log", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", + "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "time": "2016-10-10 12:19:37" + }, + { + "name": "symfony/console", + "version": "v3.1.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "c99da1119ae61e15de0e4829196b9fba6f73d065" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/c99da1119ae61e15de0e4829196b9fba6f73d065", + "reference": "c99da1119ae61e15de0e4829196b9fba6f73d065", + "shasum": "" + }, + "require": { + "php": ">=5.5.9", + "symfony/debug": "~2.8|~3.0", + "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.1-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-10-06 01:44:51" + }, + { + "name": "symfony/debug", + "version": "v3.1.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/debug.git", + "reference": "e2b3f74a67fc928adc3c1b9027f73e1bc01190a8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/debug/zipball/e2b3f74a67fc928adc3c1b9027f73e1bc01190a8", + "reference": "e2b3f74a67fc928adc3c1b9027f73e1bc01190a8", + "shasum": "" + }, + "require": { + "php": ">=5.5.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.8|~3.0", + "symfony/http-kernel": "~2.8|~3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Debug\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Debug Component", + "homepage": "https://symfony.com", + "time": "2016-09-06 11:02:40" + }, + { + "name": "symfony/event-dispatcher", + "version": "v3.1.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "28b0832b2553ffb80cabef6a7a812ff1e670c0bc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/28b0832b2553ffb80cabef6a7a812ff1e670c0bc", + "reference": "28b0832b2553ffb80cabef6a7a812ff1e670c0bc", + "shasum": "" + }, + "require": { + "php": ">=5.5.9" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "~2.8|~3.0", + "symfony/dependency-injection": "~2.8|~3.0", + "symfony/expression-language": "~2.8|~3.0", + "symfony/stopwatch": "~2.8|~3.0" + }, + "suggest": { + "symfony/dependency-injection": "", + "symfony/http-kernel": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony EventDispatcher Component", + "homepage": "https://symfony.com", + "time": "2016-10-13 06:28:43" + }, + { + "name": "symfony/filesystem", + "version": "v3.1.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "0565b61bf098cb4dc09f4f103f033138ae4f42c6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/0565b61bf098cb4dc09f4f103f033138ae4f42c6", + "reference": "0565b61bf098cb4dc09f4f103f033138ae4f42c6", + "shasum": "" + }, + "require": { + "php": ">=5.5.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-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-10-18 04:30:12" + }, + { + "name": "symfony/finder", + "version": "v3.1.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "205b5ffbb518a98ba2ae60a52656c4a31ab00c6f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/205b5ffbb518a98ba2ae60a52656c4a31ab00c6f", + "reference": "205b5ffbb518a98ba2ae60a52656c4a31ab00c6f", + "shasum": "" + }, + "require": { + "php": ">=5.5.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-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-09-28 00:11:12" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.3.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" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3-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-11-14 01:06:16" + }, + { + "name": "symfony/process", + "version": "v3.1.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "66de154ae86b1a07001da9fbffd620206e4faf94" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/66de154ae86b1a07001da9fbffd620206e4faf94", + "reference": "66de154ae86b1a07001da9fbffd620206e4faf94", + "shasum": "" + }, + "require": { + "php": ">=5.5.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-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-09-29 14:13:09" + }, + { + "name": "victorjonsson/markdowndocs", + "version": "1.3.7", + "source": { + "type": "git", + "url": "https://github.com/victorjonsson/PHP-Markdown-Documentation-Generator.git", + "reference": "a8244617cdce4804cd94ea508c82e8d7e29a273a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/victorjonsson/PHP-Markdown-Documentation-Generator/zipball/a8244617cdce4804cd94ea508c82e8d7e29a273a", + "reference": "a8244617cdce4804cd94ea508c82e8d7e29a273a", + "shasum": "" + }, + "require": { + "php": ">=5.5.0", + "symfony/console": ">=2.6" + }, + "require-dev": { + "phpunit/phpunit": "3.7.23" + }, + "bin": [ + "bin/phpdoc-md" + ], + "type": "library", + "autoload": { + "psr-0": { + "PHPDocsMD": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Victor Jonsson", + "email": "kontakt@victorjonsson.se" + } + ], + "description": "Command line tool for generating markdown-formatted class documentation", + "homepage": "https://github.com/victorjonsson/PHP-Markdown-Documentation-Generator", + "time": "2016-10-11 21:10:19" + }, + { + "name": "webmozart/assert", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/webmozart/assert.git", + "reference": "bb2d123231c095735130cc8f6d31385a44c7b308" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozart/assert/zipball/bb2d123231c095735130cc8f6d31385a44c7b308", + "reference": "bb2d123231c095735130cc8f6d31385a44c7b308", + "shasum": "" + }, + "require": { + "php": "^5.3.3|^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.6", + "sebastian/version": "^1.0.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "time": "2016-08-09 15:02:57" + } + ], + "packages-dev": [ + { + "name": "andrewsville/php-token-reflection", + "version": "1.4.0", + "source": { + "type": "git", + "url": "https://github.com/Andrewsville/PHP-Token-Reflection.git", + "reference": "e6d0ac2baf66cdf154be34c3d2a2aa1bd4b426ee" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Andrewsville/PHP-Token-Reflection/zipball/e6d0ac2baf66cdf154be34c3d2a2aa1bd4b426ee", + "reference": "e6d0ac2baf66cdf154be34c3d2a2aa1bd4b426ee", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=5.3.0" + }, + "type": "library", + "autoload": { + "psr-0": { + "TokenReflection": "./" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3" + ], + "authors": [ + { + "name": "Ondřej Nešpor", + "homepage": "https://github.com/andrewsville" + }, + { + "name": "Jaroslav Hanslík", + "homepage": "https://github.com/kukulich" + } + ], + "description": "Library emulating the PHP internal reflection using just the tokenized source code.", + "homepage": "http://andrewsville.github.com/PHP-Token-Reflection/", + "keywords": [ + "library", + "reflection", + "tokenizer" + ], + "time": "2014-08-06 16:37:08" + }, + { + "name": "behat/gherkin", + "version": "v4.4.5", + "source": { + "type": "git", + "url": "https://github.com/Behat/Gherkin.git", + "reference": "5c14cff4f955b17d20d088dec1bde61c0539ec74" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Behat/Gherkin/zipball/5c14cff4f955b17d20d088dec1bde61c0539ec74", + "reference": "5c14cff4f955b17d20d088dec1bde61c0539ec74", + "shasum": "" + }, + "require": { + "php": ">=5.3.1" + }, + "require-dev": { + "phpunit/phpunit": "~4.5|~5", + "symfony/phpunit-bridge": "~2.7|~3", + "symfony/yaml": "~2.3|~3" + }, + "suggest": { + "symfony/yaml": "If you want to parse features, represented in YAML files" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.4-dev" + } + }, + "autoload": { + "psr-0": { + "Behat\\Gherkin": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + } + ], + "description": "Gherkin DSL parser for PHP 5.3", + "homepage": "http://behat.org/", + "keywords": [ + "BDD", + "Behat", + "Cucumber", + "DSL", + "gherkin", + "parser" + ], + "time": "2016-10-30 11:50:56" + }, + { + "name": "codeception/aspect-mock", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/Codeception/AspectMock.git", + "reference": "666d0a80239eeda1e2a31219d83fce4f17529b7f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Codeception/AspectMock/zipball/666d0a80239eeda1e2a31219d83fce4f17529b7f", + "reference": "666d0a80239eeda1e2a31219d83fce4f17529b7f", + "shasum": "" + }, + "require": { + "goaop/framework": "~1.0", + "php": ">=5.4.0", + "symfony/finder": "~2.4|~3.0" + }, + "require-dev": { + "codeception/base": "~2.1", + "codeception/specify": "~0.3", + "codeception/verify": "~0.2" + }, + "type": "library", + "autoload": { + "psr-0": { + "AspectMock": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Bodnarchuk", + "email": "davert.php@mailican.com" + } + ], + "description": "Experimental Mocking Framework powered by Aspects", + "time": "2016-03-14 20:52:23" + }, + { + "name": "codeception/base", + "version": "2.2.6", + "source": { + "type": "git", + "url": "https://github.com/Codeception/base.git", + "reference": "f70c77fe9941c41f567fe62b1e96e1ed33235ac7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Codeception/base/zipball/f70c77fe9941c41f567fe62b1e96e1ed33235ac7", + "reference": "f70c77fe9941c41f567fe62b1e96e1ed33235ac7", + "shasum": "" + }, + "require": { + "behat/gherkin": "~4.4.0", + "ext-json": "*", + "ext-mbstring": "*", + "guzzlehttp/psr7": "~1.0", + "php": ">=5.4.0 <8.0", + "phpunit/php-code-coverage": ">=2.1.3 <5.0", + "phpunit/phpunit": ">4.8.20 <6.0", + "sebastian/comparator": "~1.1", + "sebastian/diff": "^1.4", + "symfony/browser-kit": ">=2.7 <4.0", + "symfony/console": ">=2.7 <4.0", + "symfony/css-selector": ">=2.7 <4.0", + "symfony/dom-crawler": ">=2.7 <4.0", + "symfony/event-dispatcher": ">=2.7 <4.0", + "symfony/finder": ">=2.7 <4.0", + "symfony/yaml": ">=2.7 <4.0" + }, + "require-dev": { + "codeception/specify": "~0.3", + "facebook/graph-sdk": "~5.3", + "flow/jsonpath": "~0.2", + "league/factory-muffin": "^3.0", + "league/factory-muffin-faker": "^1.0", + "mongodb/mongodb": "^1.0", + "monolog/monolog": "~1.8", + "pda/pheanstalk": "~3.0", + "php-amqplib/php-amqplib": "~2.4", + "predis/predis": "^1.0", + "squizlabs/php_codesniffer": "~2.0" + }, + "suggest": { + "codeception/specify": "BDD-style code blocks", + "codeception/verify": "BDD-style assertions", + "flow/jsonpath": "For using JSONPath in REST module", + "league/factory-muffin": "For DataFactory module", + "league/factory-muffin-faker": "For Faker support in DataFactory module", + "phpseclib/phpseclib": "for SFTP option in FTP Module", + "symfony/phpunit-bridge": "For phpunit-bridge support" + }, + "bin": [ + "codecept" + ], + "type": "library", + "extra": { + "branch-alias": [] + }, + "autoload": { + "psr-4": { + "Codeception\\": "src\\Codeception", + "Codeception\\Extension\\": "ext" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Bodnarchuk", + "email": "davert@mail.ua", + "homepage": "http://codegyre.com" + } + ], + "description": "BDD-style testing framework", + "homepage": "http://codeception.com/", + "keywords": [ + "BDD", + "TDD", + "acceptance testing", + "functional testing", + "unit testing" + ], + "time": "2016-10-27 00:07:01" + }, + { + "name": "codeception/verify", + "version": "0.3.2", + "source": { + "type": "git", + "url": "https://github.com/Codeception/Verify.git", + "reference": "b06d706261d1fee0cc312bacc5c1b7c506e5213a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Codeception/Verify/zipball/b06d706261d1fee0cc312bacc5c1b7c506e5213a", + "reference": "b06d706261d1fee0cc312bacc5c1b7c506e5213a", + "shasum": "" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "type": "library", + "autoload": { + "files": [ + "src/Codeception/function.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Bodnarchuk", + "email": "davert.php@mailican.com" + } + ], + "description": "BDD assertion library for PHPUnit", + "time": "2016-08-29 22:49:25" + }, + { + "name": "doctrine/annotations", + "version": "v1.3.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/annotations.git", + "reference": "30e07cf03edc3cd3ef579d0dd4dd8c58250799a5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/30e07cf03edc3cd3ef579d0dd4dd8c58250799a5", + "reference": "30e07cf03edc3cd3ef579d0dd4dd8c58250799a5", + "shasum": "" + }, + "require": { + "doctrine/lexer": "1.*", + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "doctrine/cache": "1.*", + "phpunit/phpunit": "^5.6.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Docblock Annotations Parser", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "annotations", + "docblock", + "parser" + ], + "time": "2016-10-24 11:45:47" + }, + { + "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": "doctrine/lexer", + "version": "v1.0.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/lexer.git", + "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/83893c552fd2045dd78aef794c31e694c37c0b8c", + "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "Doctrine\\Common\\Lexer\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Base library for a lexer that can be used in Top-Down, Recursive Descent Parsers.", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "lexer", + "parser" + ], + "time": "2014-09-09 13:34:57" + }, + { + "name": "goaop/framework", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://github.com/goaop/framework.git", + "reference": "05b51a6ddc58ace85a31f9d2dc885a6550898fd5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/goaop/framework/zipball/05b51a6ddc58ace85a31f9d2dc885a6550898fd5", + "reference": "05b51a6ddc58ace85a31f9d2dc885a6550898fd5", + "shasum": "" + }, + "require": { + "andrewsville/php-token-reflection": "~1.4", + "doctrine/annotations": "~1.0", + "jakubledl/dissect": "~1.0", + "php": ">=5.5.0" + }, + "require-dev": { + "symfony/console": "~2.1|~3.0" + }, + "suggest": { + "symfony/console": "Enables the usage of the command-line tool." + }, + "bin": [ + "bin/warmup" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "Go\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Lisachenko Alexander", + "homepage": "https://github.com/lisachenko" + } + ], + "description": "Framework for aspect-oriented programming in PHP.", + "homepage": "http://go.aopphp.com/", + "keywords": [ + "aop", + "aspect", + "library", + "php" + ], + "time": "2016-05-23 11:19:17" + }, + { + "name": "guzzle/guzzle", + "version": "v3.8.1", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "4de0618a01b34aa1c8c33a3f13f396dcd3882eba" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/4de0618a01b34aa1c8c33a3f13f396dcd3882eba", + "reference": "4de0618a01b34aa1c8c33a3f13f396dcd3882eba", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "php": ">=5.3.3", + "symfony/event-dispatcher": ">=2.1" + }, + "replace": { + "guzzle/batch": "self.version", + "guzzle/cache": "self.version", + "guzzle/common": "self.version", + "guzzle/http": "self.version", + "guzzle/inflection": "self.version", + "guzzle/iterator": "self.version", + "guzzle/log": "self.version", + "guzzle/parser": "self.version", + "guzzle/plugin": "self.version", + "guzzle/plugin-async": "self.version", + "guzzle/plugin-backoff": "self.version", + "guzzle/plugin-cache": "self.version", + "guzzle/plugin-cookie": "self.version", + "guzzle/plugin-curlauth": "self.version", + "guzzle/plugin-error-response": "self.version", + "guzzle/plugin-history": "self.version", + "guzzle/plugin-log": "self.version", + "guzzle/plugin-md5": "self.version", + "guzzle/plugin-mock": "self.version", + "guzzle/plugin-oauth": "self.version", + "guzzle/service": "self.version", + "guzzle/stream": "self.version" + }, + "require-dev": { + "doctrine/cache": "*", + "monolog/monolog": "1.*", + "phpunit/phpunit": "3.7.*", + "psr/log": "1.0.*", + "symfony/class-loader": "*", + "zendframework/zend-cache": "<2.3", + "zendframework/zend-log": "<2.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.8-dev" + } + }, + "autoload": { + "psr-0": { + "Guzzle": "src/", + "Guzzle\\Tests": "tests/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Guzzle Community", + "homepage": "https://github.com/guzzle/guzzle/contributors" + } + ], + "description": "Guzzle is a PHP HTTP client library and framework for building RESTful web service clients", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "rest", + "web service" + ], + "abandoned": "guzzlehttp/guzzle", + "time": "2014-01-28 22:29:15" + }, + { + "name": "guzzlehttp/psr7", + "version": "1.3.1", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "5c6447c9df362e8f8093bda8f5d8873fe5c7f65b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/5c6447c9df362e8f8093bda8f5d8873fe5c7f65b", + "reference": "5c6447c9df362e8f8093bda8f5d8873fe5c7f65b", + "shasum": "" + }, + "require": { + "php": ">=5.4.0", + "psr/http-message": "~1.0" + }, + "provide": { + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Psr7\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "PSR-7 message implementation", + "keywords": [ + "http", + "message", + "stream", + "uri" + ], + "time": "2016-06-24 23:00:38" + }, + { + "name": "henrikbjorn/lurker", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/flint/Lurker.git", + "reference": "712d3ef19bef161daa2ba0e0237c6b875587a089" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/flint/Lurker/zipball/712d3ef19bef161daa2ba0e0237c6b875587a089", + "reference": "712d3ef19bef161daa2ba0e0237c6b875587a089", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "symfony/config": "^2.2|^3.0", + "symfony/event-dispatcher": "^2.2|^3.0" + }, + "suggest": { + "ext-inotify": ">=0.1.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "Lurker": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Yaroslav Kiliba", + "email": "om.dattaya@gmail.com" + }, + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com" + }, + { + "name": "Henrik Bjrnskov", + "email": "henrik@bjrnskov.dk" + } + ], + "description": "Resource Watcher.", + "keywords": [ + "filesystem", + "resource", + "watching" + ], + "time": "2016-03-16 15:22:20" + }, + { + "name": "jakubledl/dissect", + "version": "v1.0.1", + "source": { + "type": "git", + "url": "https://github.com/jakubledl/dissect.git", + "reference": "d3a391de31e45a247e95cef6cf58a91c05af67c4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/jakubledl/dissect/zipball/d3a391de31e45a247e95cef6cf58a91c05af67c4", + "reference": "d3a391de31e45a247e95cef6cf58a91c05af67c4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "symfony/console": "~2.1" + }, + "suggest": { + "symfony/console": "for the command-line tool" + }, + "bin": [ + "bin/dissect.php", + "bin/dissect" + ], + "type": "library", + "autoload": { + "psr-0": { + "Dissect": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "unlicense" + ], + "authors": [ + { + "name": "Jakub Lédl", + "email": "jakubledl@gmail.com" + } + ], + "description": "Lexing and parsing in pure PHP", + "homepage": "https://github.com/jakubledl/dissect", + "keywords": [ + "ast", + "lexing", + "parser", + "parsing" + ], + "time": "2013-01-29 21:29:14" + }, + { + "name": "myclabs/deep-copy", + "version": "1.5.5", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "399c1f9781e222f6eb6cc238796f5200d1b7f108" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/399c1f9781e222f6eb6cc238796f5200d1b7f108", + "reference": "399c1f9781e222f6eb6cc238796f5200d1b7f108", + "shasum": "" + }, + "require": { + "php": ">=5.4.0" + }, + "require-dev": { + "doctrine/collections": "1.*", + "phpunit/phpunit": "~4.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "homepage": "https://github.com/myclabs/DeepCopy", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "time": "2016-10-31 17:19:45" + }, + { + "name": "natxet/CssMin", + "version": "v3.0.4", + "source": { + "type": "git", + "url": "https://github.com/natxet/CssMin.git", + "reference": "92de3fe3ccb4f8298d31952490ef7d5395855c39" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/natxet/CssMin/zipball/92de3fe3ccb4f8298d31952490ef7d5395855c39", + "reference": "92de3fe3ccb4f8298d31952490ef7d5395855c39", + "shasum": "" + }, + "require": { + "php": ">=5.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Joe Scylla", + "email": "joe.scylla@gmail.com", + "homepage": "https://profiles.google.com/joe.scylla" + } + ], + "description": "Minifying CSS", + "homepage": "http://code.google.com/p/cssmin/", + "keywords": [ + "css", + "minify" + ], + "time": "2015-09-25 11:13:11" + }, + { + "name": "patchwork/jsqueeze", + "version": "v2.0.5", + "source": { + "type": "git", + "url": "https://github.com/tchwork/jsqueeze.git", + "reference": "693d64850eab2ce6a7c8f7cf547e1ab46e69d542" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/tchwork/jsqueeze/zipball/693d64850eab2ce6a7c8f7cf547e1ab46e69d542", + "reference": "693d64850eab2ce6a7c8f7cf547e1ab46e69d542", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "psr-4": { + "Patchwork\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "(Apache-2.0 or GPL-2.0)" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + } + ], + "description": "Efficient JavaScript minification in PHP", + "homepage": "https://github.com/tchwork/jsqueeze", + "keywords": [ + "compression", + "javascript", + "minification" + ], + "time": "2016-04-19 09:28:22" + }, + { + "name": "pear/archive_tar", + "version": "1.4.2", + "source": { + "type": "git", + "url": "https://github.com/pear/Archive_Tar.git", + "reference": "bdd47347df76dbaa89227c5e1afd6f6809985b4c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pear/Archive_Tar/zipball/bdd47347df76dbaa89227c5e1afd6f6809985b4c", + "reference": "bdd47347df76dbaa89227c5e1afd6f6809985b4c", + "shasum": "" + }, + "require": { + "pear/pear-core-minimal": "^1.10.0alpha2", + "php": ">=5.2.0" + }, + "require-dev": { + "phpunit/phpunit": "*" + }, + "suggest": { + "ext-bz2": "bz2 compression support.", + "ext-xz": "lzma2 compression support.", + "ext-zlib": "Gzip compression support." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, + "autoload": { + "psr-0": { + "Archive_Tar": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "./" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Vincent Blavet", + "email": "vincent@phpconcept.net" + }, + { + "name": "Greg Beaver", + "email": "greg@chiaraquartet.net" + }, + { + "name": "Michiel Rook", + "email": "mrook@php.net" + } + ], + "description": "Tar file management class", + "homepage": "https://github.com/pear/Archive_Tar", + "keywords": [ + "archive", + "tar" + ], + "time": "2016-02-25 10:30:39" + }, + { + "name": "pear/console_getopt", + "version": "v1.4.1", + "source": { + "type": "git", + "url": "https://github.com/pear/Console_Getopt.git", + "reference": "82f05cd1aa3edf34e19aa7c8ca312ce13a6a577f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pear/Console_Getopt/zipball/82f05cd1aa3edf34e19aa7c8ca312ce13a6a577f", + "reference": "82f05cd1aa3edf34e19aa7c8ca312ce13a6a577f", + "shasum": "" + }, + "type": "library", + "autoload": { + "psr-0": { + "Console": "./" + } + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "./" + ], + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "Greg Beaver", + "email": "cellog@php.net", + "role": "Helper" + }, + { + "name": "Andrei Zmievski", + "email": "andrei@php.net", + "role": "Lead" + }, + { + "name": "Stig Bakken", + "email": "stig@php.net", + "role": "Developer" + } + ], + "description": "More info available on: http://pear.php.net/package/Console_Getopt", + "time": "2015-07-20 20:28:12" + }, + { + "name": "pear/pear-core-minimal", + "version": "v1.10.1", + "source": { + "type": "git", + "url": "https://github.com/pear/pear-core-minimal.git", + "reference": "cae0f1ce0cb5bddb611b0a652d322905a65a5896" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pear/pear-core-minimal/zipball/cae0f1ce0cb5bddb611b0a652d322905a65a5896", + "reference": "cae0f1ce0cb5bddb611b0a652d322905a65a5896", + "shasum": "" + }, + "require": { + "pear/console_getopt": "~1.3", + "pear/pear_exception": "~1.0" + }, + "replace": { + "rsky/pear-core-min": "self.version" + }, + "type": "library", + "autoload": { + "psr-0": { + "": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "src/" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Christian Weiske", + "email": "cweiske@php.net", + "role": "Lead" + } + ], + "description": "Minimal set of PEAR core files to be used as composer dependency", + "time": "2015-10-17 11:41:19" + }, + { + "name": "pear/pear_exception", + "version": "v1.0.0", + "source": { + "type": "git", + "url": "https://github.com/pear/PEAR_Exception.git", + "reference": "8c18719fdae000b690e3912be401c76e406dd13b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pear/PEAR_Exception/zipball/8c18719fdae000b690e3912be401c76e406dd13b", + "reference": "8c18719fdae000b690e3912be401c76e406dd13b", + "shasum": "" + }, + "require": { + "php": ">=4.4.0" + }, + "require-dev": { + "phpunit/phpunit": "*" + }, + "type": "class", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "PEAR": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "." + ], + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "Helgi Thormar", + "email": "dufuz@php.net" + }, + { + "name": "Greg Beaver", + "email": "cellog@php.net" + } + ], + "description": "The PEAR Exception base class.", + "homepage": "https://github.com/pear/PEAR_Exception", + "keywords": [ + "exception" + ], + "time": "2015-02-10 20:07:52" + }, + { + "name": "phpspec/prophecy", + "version": "v1.6.1", + "source": { + "type": "git", + "url": "https://github.com/phpspec/prophecy.git", + "reference": "58a8137754bc24b25740d4281399a4a3596058e0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/58a8137754bc24b25740d4281399a4a3596058e0", + "reference": "58a8137754bc24b25740d4281399a4a3596058e0", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.2", + "php": "^5.3|^7.0", + "phpdocumentor/reflection-docblock": "^2.0|^3.0.2", + "sebastian/comparator": "^1.1", + "sebastian/recursion-context": "^1.0" + }, + "require-dev": { + "phpspec/phpspec": "^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.6.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-06-07 08:13:47" + }, + { + "name": "phpunit/php-code-coverage", + "version": "4.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "6cba06ff75a1a63a71033e1a01b89056f3af1e8d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/6cba06ff75a1a63a71033e1a01b89056f3af1e8d", + "reference": "6cba06ff75a1a63a71033e1a01b89056f3af1e8d", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0", + "phpunit/php-file-iterator": "~1.3", + "phpunit/php-text-template": "~1.2", + "phpunit/php-token-stream": "^1.4.2", + "sebastian/code-unit-reverse-lookup": "~1.0", + "sebastian/environment": "^1.3.2 || ^2.0", + "sebastian/version": "~1.0|~2.0" + }, + "require-dev": { + "ext-xdebug": ">=2.1.4", + "phpunit/phpunit": "^5.4" + }, + "suggest": { + "ext-dom": "*", + "ext-xdebug": ">=2.4.0", + "ext-xmlwriter": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0.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": "2016-11-01 05:06:24" + }, + { + "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": "5.6.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "a9de0dbafeb6b1391b391fbb034734cb0af9f67c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/a9de0dbafeb6b1391b391fbb034734cb0af9f67c", + "reference": "a9de0dbafeb6b1391b391fbb034734cb0af9f67c", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "myclabs/deep-copy": "~1.3", + "php": "^5.6 || ^7.0", + "phpspec/prophecy": "^1.3.1", + "phpunit/php-code-coverage": "^4.0.1", + "phpunit/php-file-iterator": "~1.4", + "phpunit/php-text-template": "~1.2", + "phpunit/php-timer": "^1.0.6", + "phpunit/phpunit-mock-objects": "^3.2", + "sebastian/comparator": "~1.1", + "sebastian/diff": "~1.2", + "sebastian/environment": "^1.3 || ^2.0", + "sebastian/exporter": "~1.2", + "sebastian/global-state": "~1.0", + "sebastian/object-enumerator": "~1.0", + "sebastian/resource-operations": "~1.0", + "sebastian/version": "~1.0|~2.0", + "symfony/yaml": "~2.1|~3.0" + }, + "conflict": { + "phpdocumentor/reflection-docblock": "3.0.2" + }, + "require-dev": { + "ext-pdo": "*" + }, + "suggest": { + "ext-xdebug": "*", + "phpunit/php-invoker": "~1.1" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.6.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-11-14 06:39:40" + }, + { + "name": "phpunit/phpunit-mock-objects", + "version": "3.4.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", + "reference": "238d7a2723bce689c79eeac9c7d5e1d623bb9dc2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/238d7a2723bce689c79eeac9c7d5e1d623bb9dc2", + "reference": "238d7a2723bce689c79eeac9c7d5e1d623bb9dc2", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.2", + "php": "^5.6 || ^7.0", + "phpunit/php-text-template": "^1.2", + "sebastian/exporter": "^1.2" + }, + "conflict": { + "phpunit/phpunit": "<5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.4" + }, + "suggest": { + "ext-soap": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.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": "Mock Object library for PHPUnit", + "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", + "keywords": [ + "mock", + "xunit" + ], + "time": "2016-10-09 07:01:45" + }, + { + "name": "psr/http-message", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "time": "2016-08-06 14:39:51" + }, + { + "name": "satooshi/php-coveralls", + "version": "v1.0.1", + "source": { + "type": "git", + "url": "https://github.com/satooshi/php-coveralls.git", + "reference": "da51d304fe8622bf9a6da39a8446e7afd432115c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/satooshi/php-coveralls/zipball/da51d304fe8622bf9a6da39a8446e7afd432115c", + "reference": "da51d304fe8622bf9a6da39a8446e7afd432115c", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-simplexml": "*", + "guzzle/guzzle": "^2.8|^3.0", + "php": ">=5.3.3", + "psr/log": "^1.0", + "symfony/config": "^2.1|^3.0", + "symfony/console": "^2.1|^3.0", + "symfony/stopwatch": "^2.0|^3.0", + "symfony/yaml": "^2.0|^3.0" + }, + "suggest": { + "symfony/http-kernel": "Allows Symfony integration" + }, + "bin": [ + "bin/coveralls" + ], + "type": "library", + "autoload": { + "psr-4": { + "Satooshi\\": "src/Satooshi/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kitamura Satoshi", + "email": "with.no.parachute@gmail.com", + "homepage": "https://www.facebook.com/satooshi.jp" + } + ], + "description": "PHP client library for Coveralls API", + "homepage": "https://github.com/satooshi/php-coveralls", + "keywords": [ + "ci", + "coverage", + "github", + "test" + ], + "time": "2016-01-20 17:35:46" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "c36f5e7cfce482fde5bf8d10d41a53591e0198fe" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/c36f5e7cfce482fde5bf8d10d41a53591e0198fe", + "reference": "c36f5e7cfce482fde5bf8d10d41a53591e0198fe", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "require-dev": { + "phpunit/phpunit": "~5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "time": "2016-02-13 06:45:14" + }, + { + "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.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/be2c607e43ce4c89ecd60e75c6a85c126e754aea", + "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8 || ^5.0" + }, + "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-08-18 05:49:44" + }, + { + "name": "sebastian/exporter", + "version": "1.2.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/42c4c2eec485ee3e159ec9884f95b431287edde4", + "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "sebastian/recursion-context": "~1.0" + }, + "require-dev": { + "ext-mbstring": "*", + "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": "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": "2016-06-17 09:04:28" + }, + { + "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/object-enumerator", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "d4ca2fb70344987502567bc50081c03e6192fb26" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/d4ca2fb70344987502567bc50081c03e6192fb26", + "reference": "d4ca2fb70344987502567bc50081c03e6192fb26", + "shasum": "" + }, + "require": { + "php": ">=5.6", + "sebastian/recursion-context": "~1.0" + }, + "require-dev": { + "phpunit/phpunit": "~5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "time": "2016-01-28 13:25:10" + }, + { + "name": "sebastian/recursion-context", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "79860854756415e1cec8d186c9cf261cafd87dfc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/79860854756415e1cec8d186c9cf261cafd87dfc", + "reference": "79860854756415e1cec8d186c9cf261cafd87dfc", + "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": "2016-11-14 15:54:23" + }, + { + "name": "sebastian/resource-operations", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/resource-operations.git", + "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "shasum": "" + }, + "require": { + "php": ">=5.6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides a list of PHP built-in functions that operate on resources", + "homepage": "https://www.github.com/sebastianbergmann/resource-operations", + "time": "2015-07-28 20:34:47" + }, + { + "name": "sebastian/version", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "c829badbd8fdf16a0bad8aa7fa7971c029f1b9c5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c829badbd8fdf16a0bad8aa7fa7971c029f1b9c5", + "reference": "c829badbd8fdf16a0bad8aa7fa7971c029f1b9c5", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "time": "2016-02-04 12:56:52" + }, + { + "name": "squizlabs/php_codesniffer", + "version": "2.7.0", + "source": { + "type": "git", + "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", + "reference": "571e27b6348e5b3a637b2abc82ac0d01e6d7bbed" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/571e27b6348e5b3a637b2abc82ac0d01e6d7bbed", + "reference": "571e27b6348e5b3a637b2abc82ac0d01e6d7bbed", + "shasum": "" + }, + "require": { + "ext-simplexml": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": ">=5.1.2" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "bin": [ + "scripts/phpcs", + "scripts/phpcbf" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "autoload": { + "classmap": [ + "CodeSniffer.php", + "CodeSniffer/CLI.php", + "CodeSniffer/Exception.php", + "CodeSniffer/File.php", + "CodeSniffer/Fixer.php", + "CodeSniffer/Report.php", + "CodeSniffer/Reporting.php", + "CodeSniffer/Sniff.php", + "CodeSniffer/Tokens.php", + "CodeSniffer/Reports/", + "CodeSniffer/Tokenizers/", + "CodeSniffer/DocGenerators/", + "CodeSniffer/Standards/AbstractPatternSniff.php", + "CodeSniffer/Standards/AbstractScopeSniff.php", + "CodeSniffer/Standards/AbstractVariableSniff.php", + "CodeSniffer/Standards/IncorrectPatternException.php", + "CodeSniffer/Standards/Generic/Sniffs/", + "CodeSniffer/Standards/MySource/Sniffs/", + "CodeSniffer/Standards/PEAR/Sniffs/", + "CodeSniffer/Standards/PSR1/Sniffs/", + "CodeSniffer/Standards/PSR2/Sniffs/", + "CodeSniffer/Standards/Squiz/Sniffs/", + "CodeSniffer/Standards/Zend/Sniffs/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Greg Sherwood", + "role": "lead" + } + ], + "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", + "homepage": "http://www.squizlabs.com/php-codesniffer", + "keywords": [ + "phpcs", + "standards" + ], + "time": "2016-09-01 23:53:02" + }, + { + "name": "symfony/browser-kit", + "version": "v3.1.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/browser-kit.git", + "reference": "901319a31c9b3cee7857b4aeeb81b5d64dfa34fc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/browser-kit/zipball/901319a31c9b3cee7857b4aeeb81b5d64dfa34fc", + "reference": "901319a31c9b3cee7857b4aeeb81b5d64dfa34fc", + "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": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\BrowserKit\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony BrowserKit Component", + "homepage": "https://symfony.com", + "time": "2016-09-06 11:02:40" + }, + { + "name": "symfony/config", + "version": "v3.1.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/config.git", + "reference": "949e7e846743a7f9e46dc50eb639d5fde1f53341" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/config/zipball/949e7e846743a7f9e46dc50eb639d5fde1f53341", + "reference": "949e7e846743a7f9e46dc50eb639d5fde1f53341", + "shasum": "" + }, + "require": { + "php": ">=5.5.9", + "symfony/filesystem": "~2.8|~3.0" + }, + "suggest": { + "symfony/yaml": "To use the yaml reference dumper" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Config\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Config Component", + "homepage": "https://symfony.com", + "time": "2016-09-25 08:27:07" + }, + { + "name": "symfony/css-selector", + "version": "v3.1.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/css-selector.git", + "reference": "ca809c64072e0fe61c1c7fb3c76cdc32265042ac" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/ca809c64072e0fe61c1c7fb3c76cdc32265042ac", + "reference": "ca809c64072e0fe61c1c7fb3c76cdc32265042ac", + "shasum": "" + }, + "require": { + "php": ">=5.5.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\CssSelector\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jean-François Simon", + "email": "jeanfrancois.simon@sensiolabs.com" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony CssSelector Component", + "homepage": "https://symfony.com", + "time": "2016-09-06 11:02:40" + }, + { + "name": "symfony/dom-crawler", + "version": "v3.1.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/dom-crawler.git", + "reference": "59eee3c76eb89f21857798620ebdad7a05ad14f4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/59eee3c76eb89f21857798620ebdad7a05ad14f4", + "reference": "59eee3c76eb89f21857798620ebdad7a05ad14f4", + "shasum": "" + }, + "require": { + "php": ">=5.5.9", + "symfony/polyfill-mbstring": "~1.0" + }, + "require-dev": { + "symfony/css-selector": "~2.8|~3.0" + }, + "suggest": { + "symfony/css-selector": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\DomCrawler\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony DomCrawler Component", + "homepage": "https://symfony.com", + "time": "2016-10-18 15:46:07" + }, + { + "name": "symfony/stopwatch", + "version": "v3.1.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/stopwatch.git", + "reference": "bb42806b12c5f89db4ebf64af6741afe6d8457e1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/bb42806b12c5f89db4ebf64af6741afe6d8457e1", + "reference": "bb42806b12c5f89db4ebf64af6741afe6d8457e1", + "shasum": "" + }, + "require": { + "php": ">=5.5.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Stopwatch\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Stopwatch Component", + "homepage": "https://symfony.com", + "time": "2016-06-29 05:41:56" + }, + { + "name": "symfony/yaml", + "version": "v3.1.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "7ff51b06c6c3d5cc6686df69004a42c69df09e27" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/7ff51b06c6c3d5cc6686df69004a42c69df09e27", + "reference": "7ff51b06c6c3d5cc6686df69004a42c69df09e27", + "shasum": "" + }, + "require": { + "php": ">=5.5.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-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-10-24 18:41:13" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": ">=5.5.0" + }, + "platform-dev": [] +} diff --git a/src/composer/vendor/consolidation/robo/data/Task/Development/GeneratedWrapper.tmpl b/src/composer/vendor/consolidation/robo/data/Task/Development/GeneratedWrapper.tmpl new file mode 100644 index 00000000..6682748f --- /dev/null +++ b/src/composer/vendor/consolidation/robo/data/Task/Development/GeneratedWrapper.tmpl @@ -0,0 +1,39 @@ +task{wrapperClassName}() + * ... + * ->run(); + * + * // one line + * ... + * + * ?> + * ``` + * +{methodList} + */ +class {wrapperClassName} extends StackBasedTask +{ + protected $delegate; + + public function __construct() + { + $this->delegate = new {delegate}(); + } + + protected function getDelegate() + { + return $this->delegate; + }{immediateMethods}{methodImplementations} +} diff --git a/src/composer/vendor/consolidation/robo/docs/collections.md b/src/composer/vendor/consolidation/robo/docs/collections.md new file mode 100644 index 00000000..fc027daa --- /dev/null +++ b/src/composer/vendor/consolidation/robo/docs/collections.md @@ -0,0 +1,250 @@ +# Collection Builders + +Robo provides task collections as a means of making error detection and recovery easier. When Robo tasks are added to a collection, their execution is deferred until the `$collection->run()` method is called. If one of the tasks fail, then the operation will be aborted; rollback tasks may also be defined to restore the system to its original condition. + +When using collections, a Robo script will go through three phases: + +1. Determine which tasks will need to be run, and create a task builder. + - Assign values to variables. + - Do not alter the state of the system. +2. Create the necessary tasks via the task builder. + - Use variables calculated in the first phase in task parameters. +3. Run the tasks via the `run()` method. + - Check and report errors once after `run()` returns. + +Following this pattern will keep your code linear and easy to understand. + +## Collections API + +Collections are made up of a combination of tasks and/or `callable` functions / method pointers, such as: + + - A task (implements TaskInterface) + - A function name (string) + - A closure (inline function) + - A method reference (array with object and method name) + +Examples of adding different kinds of tasks to a collection are provided below. + +### TaskInterface Objects + +```php +add( + $this->taskExec('ls') + ); +?> +``` + +### Functions + +```php +addCode('mytaskfunction'); +?> +``` + +### Closures + +```php +addCode( + function() use ($work) + { + // do something with $work + }); +?> +``` + +### Methods + +```php +addCode([$myobject, 'mymethod']); +?> +``` + +## Using a Collection Builder + +To manage a collection of tasks, a collection builder. Collection builders allow tasks to be created via chained methods. All of the tasks created by the same builder are added to a collection; when the `run()` method is called, all of the tasks in the collection run. + +The 'publish' command from Robo's own RoboFile is shown below. It uses a collection builder to run some git and filesystem operations. The "completion" tasks are run after all other tasks complete, or during rollback processing when an operation fails. + +``` php +collectionBuilder(); + $collection->taskGitStack() + ->checkout('site') + ->merge('master') + ->completion($this->taskGitStack()->checkout($current_branch)) + ->taskFilesystemStack() + ->copy('CHANGELOG.md', 'docs/changelog.md') + ->completion($this->taskFilesystemStack()->remove('docs/changelog.md')) + ->taskExec('mkdocs gh-deploy'); + + return $collection; + } +} +?> +``` + +The example above also adds a couple of tasks as "completions"; these are run when the collection completes execution, as explained below. + +## Rollbacks and Completions + +Robo also provides rollbacks and completions, special tasks that are eligible to run only if all of the tasks added to the collection before them succeed. The section below explains the circumstances under which these tasks will run. + +### Completion Tasks + +Completions run whenever their collection completes or fails, but only if all of the tasks that come before it succeed. An example of this is shown in the first example above. A filesystem stack task copies CHANDELOG.md to docs/changelog.md; after this task is added to the collection, another filesystem stack task is added as a completion to delete docs/changelog.md. This is done because docs/changelog.md is only intended to exist long enough to be used by the `mkdocs` task, which is added later. + +### Rollback Tasks + +In addition to completions, Robo also supports rollbacks. Rollback tasks can be used to clean up after failures, so the state of the system does not change when execution is interrupted by an error. A rollback task is executed if all of the tasks that come before it succeed, and at least one of the tasks that come after it fails. If all tasks succeed, then no rollback tasks are executed. + +### Rollback and Completion Methods + +Any task may also implement \Robo\Contract\RollbackInterface; if this is done, then its `rollback()` method will be called if the task is `run()` on a collection that later fails. + +Use `addAsCompletion($collection)` in place of `addAsRollback($collection)`, or implement \Robo\Contract\CompletionInterface. Completions otherwise work exactly like rollbacks. + +## Temporary Objects + +Since the concept of temporary objects that are cleaned up on failure is a common pattern, Robo provides built-in support for them. Temporary directories and files are provided out of the box; other kinds of temporary objects can be easily created using the Temporary global collection. + +### Temporary Directories + +It is recommended that operations that perform multiple filesystem operations should, whenever possible, do most of their work in a temporary directory. Temporary directories are created by `$this->taskTmpDir()`, and are automatically be removed when the collection completes or rolls back. As an added convenience, the CollectionBuilder class has a `tmpDir()` method that creates a temporary directory via `taskTmpDir()`, and then returns the path to the temporary directory. + +``` php +collectionBuilder(); + + // Create a temporary directory, and fetch its path. + $work = $collection->tmpDir(); + + $collection + ->taskWriteToFile("$work/README.md") + ->line('-----') + ->line(date('Y-m-d').' Generated file: do not edit.') + ->line('----'); + + // If all of the preceding tasks succeed, then rename the temporary + // directory to its final name. + $collection->taskFilesystemStack() + ->rename($work, 'destination'); + + return $collection->run(); + } +} +?> +``` + +In the previous example, the path to the temporary directory is stored in the variable `$work`, and is passed as needed to the parameters of the other tasks as they are added to the collection. After the task collection is run, the temporary directory will be automatically deleted. In the example above, the temporary directory is renamed by the last task in the collection. This allows the working directory to persist; the collection will still attempt to remove the working directory, but no errors will be thrown if it no longer exists in its original location. Following this pattern allows Robo scripts to easily and safely do work that cleans up after itself on failure, without introducing a lot of branching or additional error recovery code. This paradigm is common enough to warrant a shortcut method of accomplishing the same thing. The example below is identical to the one above, save for the fact that it uses the `workDir()` method instead of `tmpDir()`. `workDir()` renames the temporary directory to its final name if the collection completes; any directory that exists in the same location will be overwritten at that time, but will persist if the collection roles back. + +``` php +collectionBuilder(); + + // Create a temporary directory, and fetch its path. + // If all of the tasks succeed, then rename the temporary directory + // to its final name. + $work = $collection->workDir('destination'); + + $collection + ->taskWriteToFile("$work/README.md") + ->line('-----') + ->line(date('Y-m-d').' Generated file: do not edit.') + ->line('----'); + + return $collection->run(); + } +} +?> +``` + +Temporary directories may also be created via the shortcut `$this->_tmpDir();`. Temporary directories created in this way are deleted when the script terminates. + +### Temporary Files + +Robo also provides an API for creating temporary files. They may be created via `$this->taskTmpFile()`; they are used exactly like `$this->taskWrite()`, except they are given a random name on creation, and are deleted when their collection completes. If they are not added to a collection, then they are deleted when the script terminates. + +### The Temporary Global Collection + +Robo maintains a special collection called the Temporary global collection. This collection is used to keep track of temporary objects that are not part of any collection. For example, Robo temporary directories and temporary files are managed by the Temporary global collection. These temporary objects are cleaned up automatically when the script terminates. + +It is easy to create your own temporary tasks that behave in the same way as the provided temporary directory and temporary file tasks. There are two steps required: + +- Implement \Robo\Contract\CompletionInterface +- Wrap the task via Temporary::wrap() + +For example, the implementation of taskTmpFile() looks like this: + +``` php + +``` + +The `complete()` method of the task will be called once the Collection the temporary object is attached to finishes running. If the temporary is not added to a collection, then its `complete()` method will be called when the script terminates. + +## Named Tasks + +It is also possible to provide names for the tasks added to a collection. This has two primary benefits: + +1. Any result data returned from a named task is stored in the Result object under the task name. +2. It is possible for other code to add more tasks before or after any named task. + +This feature is useful if you have functions that create task collections, and return them as a function results. The original caller can then use the `$collection->before()` or `$collection->after()` to insert sequenced tasks into the set of operations to be performed. One reason this might be done would be to define a base set of operations to perform (e.g. in a deploy), and then apply modifications for other environments (e.g. dev or stage). + +```php +addCode( + function() use ($work) + { + // do something with $work + }, + "taskname"); +?> +``` + +Given a collection with named tasks, it is possible to insert more tasks before or after a task of a given name. + +```php +after("taskname", + function() use ($work) + { + // do something with $work after "taskname" executes, if it succeeds. + }); +?> +``` + +```php +before("taskname", + function() use ($work) + { + // do something with $work before "taskname" executes. + }); +?> +``` + +It is recommended that named tasks be avoided unless specifically needed. + diff --git a/src/composer/vendor/consolidation/robo/docs/extending.md b/src/composer/vendor/consolidation/robo/docs/extending.md new file mode 100644 index 00000000..c71b7bc8 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/docs/extending.md @@ -0,0 +1,191 @@ +# Extending + +Robo tasks can be added to your Robo application by using Composer to suppliment the set of built-in tasks that Robo provides by default. To find existing Robo task extensions, search in Packagist for projects of type [robo-tasks](https://packagist.org/search/?type=robo-tasks). + +The convention used to add new tasks for use in your RoboFiles is to create a wrapper trait named `loadTasks` that instantiates the implementation class for each task. Each task method in the trait should start with the prefix `task`, and should use **chained method calls** for configuration. Task execution should be triggered by the method `run`. + +To include additional tasks in your RoboFile, you must `use` the appropriate `loadTasks` in your RoboFile. See the section [Including Additional Tasks](#including-additional-tasks) below. To create your own Robo extension that provides tasks for use in RoboFiles, then you must write your own class that implements TaskInterface, and create a `loadTasks` trait for it as described in the section [Creating a Robo Extension](#creating-a-robo-extension). + +## Including Additional Tasks + +Additional tasks may be installed into projects that have included Robo via Composer. For example: +``` +$ cd myproject +$ composer require boedah/robo-drush +``` +If any of the tasks you include require external Composer projects themselves, then you must `composer require` these as well. See the `suggests` section of Robo's composer.json file for a list of some projects you might need to require. + +Once the extension you wish to use has been added to your vendor directory, you may then include it from your RoboFile: +``` php +class RoboFile extends \Robo\Tasks +{ + use \Boedah\Robo\Task\Drush\loadTasks; + + public function test() + { + // ... + } +} +``` +Once you have done this, all of the tasks defined in the extension you selected will be available for use in your commands. + +Note that at the moment, it is not possible to extend Robo when using the robo.phar. This capability may be added in the future via [embedded composer](https://github.com/dflydev/dflydev-embedded-composer). + +## Creating a Robo Extension + +A Robo tasks extension is created by advertising a Composer package of type `robo-tasks` on [Packagist](https://packagist.org/). For an overview on how this is done, see the article [Creating your very own Composer Package](https://knpuniversity.com/screencast/question-answer-day/create-composer-package). Specific instructions for creating Robo task extensions are provided below. + +### Create your composer.json File + +Your composer.json file should look something like the example below: +``` +{ + "name": "boedah/robo-drush", + "description": "Drush CommandStack for Robo Task Runner", + "type": "robo-tasks", + "autoload": { + "psr-4": { + "Boedah\\Robo\\Task\\Drush\\": "src" + } + }, + "require": { + "php": ">=5.5.0", + "consolidation/robo": "~1" + } +} +``` +Customize the name and autoload paths as necessary, and add any additional required projects needed by the tasks that your extensions will provide. The type of your project should always be `robo-tasks`. Robo only supports php >= 5.5.0; you may require a higher version of php if necessary. + +### Create the loadTasks.php Trait + +It is recommended to place your trait-loading task in a `loadTasks` file in the same namespace as the task implementation. +``` +namespace Boedah\Robo\Task\Drush; + +use Robo\Container\SimpleServiceProvider; + +trait loadTasks +{ + /** + * @param string $pathToDrush + * @return DrushStack + */ + protected function taskDrushStack($pathToDrush = 'drush') + { + return $this->task(__FUNCTION__, $pathToDrush); + } +} +``` +Note that the name of the service for a given task must start with the word "task", and must have the same name as the function used to call the task. `$this->task()` looks up the service by name; using the PHP built-in constant __FUNCTION__ for this parameter ensures that the names of these items remain in alignment. + +### Task implementation + +The implementation of each task class should extend \Robo\Task\BaseTask, or some class that extends the same, and should used chained initializer methods and defer all operations that alter the state of the system until its `run()` method. If you follow these patterns, then your task extensions will be usable via Robo collection builders, as explained in the [collections](collections.md) documentation. + +There are many examples of task implementations in the Robo\Task namespace. A very basic task example is provided below. The namespace is `MyAssetTasks`, and the example task is `CompileAssets`. To customize to your purposes, choose an appropriate namespace, and then define as many tasks as you need. + +``` php +task(CompileAssets::class, $path); + } +} + +class CompileAssets implements \Robo\Contract\TaskInterface +{ + // configuration params + protected $path; + protected $to; + function __construct($path) + { + $this->path = $path; + } + + function to($filename) + { + $this->to = $filename; + // must return $this + return $this; + } + + // must implement Run + function run() + { + //.... + } +} +?> +``` + +To use the tasks you define in a RoboFile, use its `loadTasks` trait as explained in the section [Including Additional Tasks](#including-additional-tasks), above. + +### TaskIO + +To allow tasks access IO, use the `Robo\Common\TaskIO` trait, or inherit your task class from `Robo\Task\BaseTask` (recommended). + +Inside tasks you should print process details with `printTaskInfo`, `printTaskSuccess`, and `printTaskError`. +``` +$this->printTaskInfo('Processing...'); +``` +The Task IO methods send all output through a PSR-3 logger. Tasks should use task IO exclusively; methods such as 'say' and 'ask' should reside in the command method. This allows tasks to be usable in any context that has a PSR-3 logger, including background or server processes where it is not possible to directly query the user. + +### Tasks That Use Tasks + +If one task implementation needs to use other tasks while it is running, it should do so via a `CollectionBuilder` object, as explained in the [Collections](collections.md) documentation. + +To obtain access to a `CollectionBuilder`, a task should implement `BuilderAwareInterface` and use `BuilderAwareTrait`. It will then have access to a collection builder via the `$this->collectionBuilder()` method. + +### Testing Extensions + +If you wish to use the `task()` methods from your `loadTasks` trait in your unit tests, it is necessary to also use the Robo `TaskAccessor` trait, and define a `collectionBuilder()` method to provide a builder. Collection builders are used to initialize all Robo tasks. The easiest way to get a usable collection builder in your tests is to initialize Robo's default dependency injection container, and use it to request a new builder. + +An example of how to do this in a PHPUnit test is shown below. +``` +use League\Container\ContainerAwareInterface; +use League\Container\ContainerAwareTrait; +use Symfony\Component\Console\Output\NullOutput; +use Robo\TaskAccessor; +use Robo\Robo; + +class DrushStackTest extends \PHPUnit_Framework_TestCase implements ContainerAwareInterface +{ + use \Boedah\Robo\Task\Drush\loadTasks; + use TaskAccessor; + use ContainerAwareTrait; + + // Set up the Robo container so that we can create tasks in our tests. + function setup() + { + $container = Robo::createDefaultContainer(null, new NullOutput()); + $this->setContainer($container); + } + + // Scaffold the collection builder + public function collectionBuilder() + { + $emptyRobofile = new \Robo\Tasks; + return $this->getContainer()->get('collectionBuilder', [$emptyRobofile]); + } + + public function testYesIsAssumed() + { + $command = $this->taskDrushStack() + ->drush('command') + ->getCommand(); + $this->assertEquals('drush command -y', $command); + } +} +``` +To assert that the output of a command contains some value, use a `Symfony\Component\Console\Output\BufferedOutput` in place of null output when calling Robo::createDefaultContainer(). diff --git a/src/composer/vendor/consolidation/robo/docs/framework.md b/src/composer/vendor/consolidation/robo/docs/framework.md new file mode 100644 index 00000000..d0ae942f --- /dev/null +++ b/src/composer/vendor/consolidation/robo/docs/framework.md @@ -0,0 +1,89 @@ +# Robo as a Framework + +There are multiple ways to use and package Robo scripts; a few of the alternatives are presented below. + +## Creating a Standalone Phar with Robo + +It is possible to create a standalone phar that is implemented with Robo; doing this does not require the RoboFile to be located in the current working directory, or any particular location within your project. To achieve this, first set up your project as shown in the section [Implementing Composer Scripts with Robo](getting-started.md#implementing-composer-scripts-with-robo). Use of the "scripts" section is optional. + +Next, add an "autoload" section to your composer.json to provide a namespace for your Robo commands: +``` +{ + "name": "myorg/myproject", + "require": { + "consolidation/Robo": "~1" + }, + "autoload":{ + "psr-4":{ + "MyProject\\":"src" + } + } +} +``` +Create a new file for your Robo commands, e.g. `class RoboFile` in `namespace MyProject\Commands;` in the file `src\Commands\RoboFile.php`. Optionally, add more task libraries as described in the [extending](extending.md) document. + +Create a startup script similar to the one below, and add it to the root of your project, or some other location of your choosing: + +``` php +#!/usr/bin/env php +setSearchPattern('*Command.php'); +$commandClasses = $discovery->discover('php/MyProject/Commands', '\MyProject\Commands'); +``` +Pass the resulting `$commandClasses` to the `Runner()` constructor as shown above. See the annotated-commands project for more information about the different options that the discovery command takes. + +## Using Your Own Dependency Injection Container with Robo (Advanced) + +It is also possible to completely replace the Robo application with your own. To do this, set up your project as described in the sections above, but replace the Robo runner with your own main event loop. + +Create the Robo dependency injection container: +``` +use League\Container\Container; + +$input = new \Symfony\Component\Console\Input\ArgvInput($argv); +$output = new \Symfony\Component\Console\Output\ConsoleOutput(); +$conf = new \Robo\Config(); \\ or use your own subclass +$app = new \My\Application(); +$container = \Robo\Robo::createDefaultContainer($input, $output, $app, $conf); +``` +If you are using League\Container (recommended), then you may simply add and share your own classes to the same container. If you are using some other DI container, then you should use [delegate lookup](https://github.com/container-interop/fig-standards/blob/master/proposed/container.md#14-additional-feature-delegate-lookup) to combine them. diff --git a/src/composer/vendor/consolidation/robo/docs/getting-started.md b/src/composer/vendor/consolidation/robo/docs/getting-started.md new file mode 100644 index 00000000..673f688d --- /dev/null +++ b/src/composer/vendor/consolidation/robo/docs/getting-started.md @@ -0,0 +1,418 @@ +# Getting Started + +To begin you need to create a RoboFile. Just run `robo init` in your project directory: + +``` +cd myproject +robo init +``` + +Your project directory may start out empty; Robo will create a new `RoboFile.php` for you. There will be RoboFile class which extends `\Robo\Tasks`, which includes all bundled tasks of Robo. + +``` php + +``` + +## Commands + +All public methods of the RoboFile class will be treated as **commands**. You can run them from the CLI and pass arguments. + +``` php +say("Hello, $world"); + } +} +?> +``` + +When we run: + +``` +robo hello davert +➜ Hello, davert +``` + +Method names should be camelCased. In CLI `camelCased` method will be available as `camel:cased` command. +`longCamelCased` method will be transformed to `long:camel-cased` command. + +**Note:** This assumes you have installed Robo by downloading the [robo.phar](http://robo.li/robo.phar) file and copied it to a directory in your $PATH. For example, `cp robo.phar ~/bin/robo`. + +### Arguments + +All method parameters without default values are treated as required arguments. In our example command `hello` requires one argument. +If you pass a default value to parameter the argument becomes optional: + +``` php +say("Hello, $world"); + } +?> +``` + +``` +robo hello +➜ Hello, world +``` + +To accept multiple, variable arguments, define a parameter as an `array`; Robo will then pass all CLI arguments in this variable: + +``` php +say("Hello, " . implode(', ', $world)); + } +?> +``` + +``` +robo hello davert jon bill bob +➜ Hello, davert, jon, bill, bob +``` + +### Options + +To define command options you should define the last method parameter as an associative array where the keys define the option names and the values provide each option's default values: + +``` php + false]) + { + if (!$opts['silent']) $this->say("Hello, world"); + } +?> +``` + +``` +robo hello +➜ Hello, world + +robo hello --silent +``` + +A one-character shortcut can be specified for option: + +``` php + false]) + { + if (!$opts['silent']) $this->say("Hello, world"); + } +?> +``` + +Now command can be executed with '-s' to run in silent mode: + +``` +robo hello -s +``` + +### Load From Other Directories + +Robo can execute commands from a RoboFile located in different directory. +You can specify the path to another RoboFile by including the `--load-from` option: + +``` +robo run --load-from /path/to/my/other/project +``` + +### Pass-Through Arguments + +Sometimes you need to pass arguments from your command into a task. A command line after the `--` characters is treated as one argument. +Any special character like `-` will be passed into without change. + +``` php +taskExec('ls')->args($args)->run(); + } +?> +``` + +``` +robo ls -- Robo -c --all + [Robo\Task\ExecTask] running ls Robo -c --all + . .. CHANGELOG.md codeception.yml composer.json composer.lock docs .git .gitignore .idea LICENSE README.md robo RoboFile.php robo.phar src tests .travis.yml vendor +``` + +### Help + +The help text for a command in a RoboFile may be provided in Doc-Block comments. An example help Doc-Block comment is shown below: + +``` php + false]) +{ +} +?> +``` + +The corresponding help text produced is: + +``` +robo fibonacci --help +Usage: + fibonacci [--graphic] start steps + +Arguments: + start Number to start from + steps Number of steps to perform + +Options: + --graphic Display the sequence graphically using cube representation + +Help: + Graphic output will look like + +----+---+-------------+ + | | | | + | |-+-| | + |----+-+-+ | + | | | + | | | + | | | + +--------+-------------+ +``` + +Arguments and options are populated from annotations. + +Initially added with [PR by @jonsa](https://github.com/consolidation/Robo/pull/71); now provided by the [consolidation/annotated-command](https://github.com/consolidation/annotated-command) project, which was factored out from Robo. + +### Ignored methods + +Robo ignores any method of your RoboFile that begins with `get` or `set`. These methods are presumed to be data accessors, not commands. To implement a command whose name contains `get` or `set`, use the `@command` annotation. + +``` php + +``` + +## Tasks + +Robo commands typically divide the work they need to accomplish into **tasks**. The command first determines what needs to be done, inspecting current state if necessary, and then sets up and executes one or more tasks that make the actual changes needed by the command. (See also the documentation on [Collections](collections.md), which allow you to combine groups of tasks which can provide rollback functions to recover from failure situations.) + +For details on how to add custom tasks to Robo, see the [extending](extending.md) document. + +### Shortcuts + +Some tasks may have shortcuts. If a task does not require multi-step configuration, it can be executed with a single line: + +```php +_exec('ps aux'); +$this->_copy('config/env.example.yml','config/env.yml'); +?> +``` + +### Result + +Each task must return an instance of `Robo\Result`. A Robo Result contains the task instance, exit code, message, and any variable data that the task may wish to return. + +The `run` method of `CompileAssets` class may look like this: + +``` +return new Robo\Result($this, $exitCode, "Assets compiled"); +``` + +or + +``` +return Robo\Result::success($this, "Assets compiled"); +return Robo\Result::error($this, "Failed to compile assets"); +``` + +You can use this results to check if execution was successful, either using the `wasSuccessful()` method, or via the `invoke` shortcut. We will use the `Exec` task in next example to illustrate this: + +``` php +_exec('phpunit tests/integration'); + $res2 = $this->_exec('phpunit tests/unit'); + + // print message when tests passed + if ($res1->wasSuccessful() and $res2->wasSuccessful()) $this->say("All tests passed"); + } +} +?> +``` +When making multi-step commands that call one task after another, it is best to use a collection to group the tasks together. The collection will handle error detection and rollback, and will return a single Result object when done. For more information, see the [Collections](collections.md) documentation. + +Some tasks may also attach data to the Result object. If this is done, the data may be accessed as an array; for example, `$result['path'];`. This is not common. + +Commands should return a Result object obtained from a task; this will ensure that the command exit code is set correctly. If a command does not have a Result object available, then it may use a ResultData object. ResultData objects are just like Result objects, except the do not contain a reference to a task. + +return new Robo\ResultData($exitcode, 'Error message.'); + +If the command returns a TaskInterface instead of a result, then the task will be executed, and the result from that task will be used as the final result of the command. See also `Formatters`, below. + +### Stack + +Some tasks contain `Stack` in their name. These are called "stack" tasks, and they execute similar tasks one after the other. Each of the primary methods in a stack class executes an operation. + +Stack tasks also contain a `stopOnFail` method which can be used to stop task execution if one of its commands was unsuccessful. + +### Global StopOnFail + +There is a global `stopOnFail` method as well, that can be used to stop a command on first failure of a task. + +``` +$this->stopOnFail(true); +``` + +### IO + +As you noticed, you can print text via the `say` method, which is taken from the `Robo\Output` trait. + +``` +$this->say("Hello"); +``` + +Also, you can ask for input from console: + +``` +$name = $this->ask("What is your name?"); +``` + +There are also `askDefault`, `askHidden`, and `confirm` methods. + +In addition, Robo makes all of the methods of Symfony Style available throgh the `io()` method: + +$this->io()->title("Build all site assets"); + +This allows Robo scripts to follow the [Symfony Console Style Guide](http://symfony.com/blog/new-in-symfony-2-8-console-style-guide) if desired. + +### Formatters + +It is preferable for commands that look up and display information should avoid doing IO directly, and should instead return the data they wish to display as an array. This data can then be converted into different data formats, such as "table" and "json". The user may select which formatter to use via the --format option. For details on formatters, see the [consolidation/output-formatters](https://github.com/consolidation/output-formatters) project. + +### Progress + +Robo supports progress indicators via the Symfony ProgressBar class. Long-running tasks that wish to display the progress indicator may do so via four simple steps: + +- Override the `progressIndicatorSteps()` method and return the number of "steps" in the operation. +- Call `$this->startProgressIndicator()` to begin the progress indicator running. +- Call `$this->advanceProgressIndicator()` a number of times equal to the result returned by `progressIndicatorSteps()` +- Call `$this->stopProgressIndicator()` when the operation is completed. + +An example of this is shown below: + +``` php +steps; + } + + public function run() + { + $exitCode = 0; + $errorMessage = ""; + + $this->startProgressIndicator(); + for ($i = 0; $i < $this->steps; ++$i) { + $this->advanceProgressIndicator(); + } + $this->stopProgressIndicator(); + + return new Result($this, $exitCode, $errorMessage, ['time' => $this->getExecutionTime()]); + } +} +?> +``` +Tasks should not attempt to use a specific progress indicator (e.g. the Symfony ProgressBar class) directly, as the ProgressIndicatorAwareTrait allows for an appropriate progress indicator to be used (or omitted) as best suits the application. + +Note that when using [Collections](collections.md), the progress bar will automatically be shown if the collection takes longer than two seconds to run. Each task in the collection will count for one "step"; if the task supports progress indicators as shown above, then it will add an additional number of steps as indicated by its `progressIndicatorSteps()` method. + +## Working with Composer + +### Adding a RoboFile to your Project + +Robo is designed to work well with Composer. To use Robo scripts in your Composer-based project, simply add `robo` to your composer.json file: +``` +$ cd myproject +$ composer require consolidation/Robo:~1 +$ ./vendor/bin/robo mycommand +``` +If you do not want to type the whole path to Robo, you may add `./vendor/bin` to your $PATH (relative paths work), or use `composer exec` to find and run Robo: +``` +$ composer exec robo mycommand +``` + +### Implementing Composer Scripts with Robo + +When using Robo in your project, it is convenient to define Composer scripts that call your Robo commands. Simply add the following to your composer.json file: +``` +{ + "name": "myorg/myproject", + "require": { + "consolidation/Robo": "~1" + }, + "scripts": { + "test": "composer robo test", + "phar": "composer robo phar:build", + "robo": "robo --ansi --load-from $(pwd)/scripts/BuildCommands.php" + } +} +``` +*Note*: When you include Robo as a library like this, some external projects used by certain core Robo tasks are not automatically included in your project. See the `"suggest":` section of Robo's composer.json for a list of external projects you might also want to require in your project. + +Once you have set up your composer.json file (and ran `composer update` if you manually changed the `require` or `require-dev` sections), Composer will ensure that your project-local copy of Robo in the `vendor/bin` dir is in your $PATH when you run the additional Composer scripts that you declared: +``` +$ cd myproject +$ composer test +$ composer phar +``` +This will call the public methods `test()` and `phar()` in your RoboFile.php when using `composer test` and `composer phar`, respectively. + +Advertising your build commands as Composer scripts is a useful way to provide the key commands used for testing, building or packaging your application. Also, if your application should happen to provide a commandline tool to perform the operations of the application itself, then defining your build commands in their own RoboFile provides desirable separation, keeping your build commands out of the help and list commands of your primary script. + +If you would like to simplify the output of your script (e.g. when running on a CI service), replace the `--ansi` option in the example above with `--no-ansi`, and colored terminal output and progress bars will be disabled. + +## Robo as a Framework + +For an overview on how to turn your Robo scripts into standalone tools, see the example [robo.script](https://github.com/consolidation/Robo/blob/master/examples/robo.script), and the section [Robo as a Framework](framework.md). diff --git a/src/composer/vendor/consolidation/robo/docs/index.md b/src/composer/vendor/consolidation/robo/docs/index.md new file mode 100644 index 00000000..cdb6d099 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/docs/index.md @@ -0,0 +1,24 @@ +# Robo Documentation + +* [Getting Started](getting-started.md) +* [Collections](collections.md) +* [Extending](extending.md) +* [Robo as a Framework](framework.md) + +## Tasks + +* [ApiGen](tasks/ApiGen.md) +* [Archive](tasks/Archive.md) +* [Assets](tasks/Assets.md) +* [Base](tasks/Base.md) +* [Bower](tasks/Bower.md) +* [Composer](tasks/Composer.md) +* [Development](tasks/Development.md) +* [Docker](tasks/Docker.md) +* [File](tasks/File.md) +* [Filesystem](tasks/Filesystem.md) +* [Gulp](tasks/Gulp.md) +* [Npm](tasks/Npm.md) +* [Remote](tasks/Remote.md) +* [Testing](tasks/Testing.md) +* [Vcs](tasks/Vcs.md) diff --git a/src/composer/vendor/consolidation/robo/docs/tasks/ApiGen.md b/src/composer/vendor/consolidation/robo/docs/tasks/ApiGen.md new file mode 100644 index 00000000..255404b8 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/docs/tasks/ApiGen.md @@ -0,0 +1,56 @@ +# ApiGen Tasks +## ApiGen + + +Executes ApiGen command to generate documentation + +``` php +taskApiGen('./apigen.neon') + ->templateConfig('vendor/apigen/apigen/templates/bootstrap/config.neon') + ->wipeout(true) + ->run(); +?> +``` + +* `config($config)` * `param string` $config +* `source($src)` * `param array|string|Traversable` $src one or more source values +* `destination($dest)` * `param string` $dest +* `extensions($exts)` * `param array|string` $exts one or more extensions +* `exclude($exclude)` * `param array|string` $exclude one or more exclusions +* `skipDocPath($path)` * `param array|string|Traversable` $path one or more skip-doc-path values +* `skipDocPrefix($prefix)` * `param array|string|Traversable` $prefix one or more skip-doc-prefix values +* `charset($charset)` * `param array|string` $charset one or more charsets +* `mainProjectNamePrefix($name)` * `param string` $name +* `title($title)` * `param string` $title +* `baseUrl($baseUrl)` * `param string` $baseUrl +* `googleCseId($id)` * `param string` $id +* `googleAnalytics($trackingCode)` * `param string` $trackingCode +* `templateConfig($templateConfig)` * `param mixed` $templateConfig +* `allowedHtml($tags)` * `param array|string` $tags one or more supported html tags +* `groups($groups)` * `param string` $groups +* `autocomplete($types)` * `param array|string` $types or more supported autocomplete types +* `accessLevels($levels)` * `param array|string` $levels one or more access levels +* `internal($internal)` * `param boolean|string` $internal 'yes' or true if internal, 'no' or false if not +* `php($php)` * `param boolean|string` $php 'yes' or true to generate documentation for internal php classes, +* `tree($tree)` * `param bool|string` $tree 'yes' or true to generate a tree view of classes, 'no' or false otherwise +* `deprecated($dep)` * `param bool|string` $dep 'yes' or true to generate documentation for deprecated classes, 'no' or false otherwise +* `todo($todo)` * `param bool|string` $todo 'yes' or true to document tasks, 'no' or false otherwise +* `sourceCode($src)` * `param bool|string` $src 'yes' or true to generate highlighted source code, 'no' or false otherwise +* `download($zipped)` * `param bool|string` $zipped 'yes' or true to generate downloadable documentation, 'no' or false otherwise +* `report($path)` +* `wipeout($wipeout)` * `param bool|string` $wipeout 'yes' or true to clear out the destination directory, 'no' or false otherwise +* `quiet($quiet)` * `param bool|string` $quiet 'yes' or true for quiet, 'no' or false otherwise +* `progressbar($bar)` * `param bool|string` $bar 'yes' or true to display a progress bar, 'no' or false otherwise +* `colors($colors)` * `param bool|string` $colors 'yes' or true colorize the output, 'no' or false otherwise +* `updateCheck($check)` * `param bool|string` $check 'yes' or true to check for updates, 'no' or false otherwise +* `debug($debug)` * `param bool|string` $debug 'yes' or true to enable debug mode, 'no' or false otherwise +* `dir($dir)` Changes working directory of command +* `printed($arg)` Should command output be printed +* `arg($arg)` Pass argument to executable. Its value will be automatically escaped. +* `args($args)` Pass methods parameters as arguments to executable. Argument values +* `rawArg($arg)` Pass the provided string in its raw (as provided) form as an argument to executable. +* `option($option, $value = null)` Pass option to executable. Options are prefixed with `--` , value can be provided in second parameter. +* `optionList($option, $value = null)` Pass multiple options to executable. Value can be a string or array. + diff --git a/src/composer/vendor/consolidation/robo/docs/tasks/Archive.md b/src/composer/vendor/consolidation/robo/docs/tasks/Archive.md new file mode 100644 index 00000000..103845d2 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/docs/tasks/Archive.md @@ -0,0 +1,52 @@ +# Archive Tasks +## Extract + + +Extracts an archive. + +Note that often, distributions are packaged in tar or zip archives +where the topmost folder may contain variable information, such as +the release date, or the version of the package. This information +is very useful when unpacking by hand, but arbitrarily-named directories +are much less useful to scripts. Therefore, by default, Extract will +remove the top-level directory, and instead store all extracted files +into the directory specified by $archivePath. + +To keep the top-level directory when extracting, use +`preserveTopDirectory(true)`. + +``` php +taskExtract($archivePath) + ->to($destination) + ->preserveTopDirectory(false) // the default + ->run(); +?> +``` + +* `to(string)` location to store extracted files + +* `to($to)` Location to store extracted files. +* `preserveTopDirectory($preserve = null)` * `param bool` $preserve + +## Pack + + +Creates a zip or tar archive. + +``` php +taskPack( +) +->add('README') // Puts file 'README' in archive at the root +->add('project') // Puts entire contents of directory 'project' in archinve inside 'project' +->addFile('dir/file.txt', 'file.txt') // Takes 'file.txt' from cwd and puts it in archive inside 'dir'. +->run(); +?> +``` + +* `archiveFile($archiveFile)` * `param string` $archiveFile +* `addFile($placementLocation, $filesystemLocation)` Add an item to the archive. Like file_exists(), the parameter +* `addDir($placementLocation, $filesystemLocation)` Alias for addFile, in case anyone has angst about using +* `add($item)` Add a file or directory, or list of same to the archive. + diff --git a/src/composer/vendor/consolidation/robo/docs/tasks/Assets.md b/src/composer/vendor/consolidation/robo/docs/tasks/Assets.md new file mode 100644 index 00000000..54fc2110 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/docs/tasks/Assets.md @@ -0,0 +1,163 @@ +# Assets Tasks + +## ImageMinify + + +Minifies images. When the required minifier is not installed on the system +the task will try to download it from the [imagemin](https://github.com/imagemin) repository. + +When the task is run without any specified minifier it will compress the images +based on the extension. + +```php +$this->taskImageMinify('assets/images/*') + ->to('dist/images/') + ->run(); +``` + +This will use the following minifiers: + +- PNG: optipng +- GIF: gifsicle +- JPG, JPEG: jpegtran +- SVG: svgo + +When the minifier is specified the task will use that for all the input files. In that case +it is useful to filter the files with the extension: + +```php +$this->taskImageMinify('assets/images/*.png') + ->to('dist/images/') + ->minifier('pngcrush'); + ->run(); +``` + +The task supports the following minifiers: + +- optipng +- pngquant +- advpng +- pngout +- zopflipng +- pngcrush +- gifsicle +- jpegoptim +- jpeg-recompress +- jpegtran +- svgo (only minification, no downloading) + +You can also specifiy extra options for the minifiers: + +```php +$this->taskImageMinify('assets/images/*.jpg') + ->to('dist/images/') + ->minifier('jpegtran', ['-progressive' => null, '-copy' => 'none']) + ->run(); +``` + +This will execute as: +`jpegtran -copy none -progressive -optimize -outfile "dist/images/test.jpg" "/var/www/test/assets/images/test.jpg"` + +* `to($target)` Sets the target directory where the files will be copied to. +* `minifier($minifier, array $options = Array ( ) )` Sets the minifier. + +## Less + + +Compiles less files. + +```php +taskLess([ + 'less/default.less' => 'css/default.css' +]) +->run(); +?> +``` + +Use one of both less compilers in your project: + +``` +"leafo/lessphp": "~0.5", +"oyejorge/less.php": "~1.5" +``` + +Specify directory (string or array) for less imports lookup: + +```php +taskLess([ + 'less/default.less' => 'css/default.css' +]) +->importDir('less') +->compiler('lessphp') +->run(); +?> +``` + +You can implement additional compilers by extending this task and adding a +method named after them and overloading the lessCompilers() method to +inject the name there. + +* `importDir($dirs)` Sets import directories +* `addImportPath($dir)` Adds import directory +* `setImportPaths($dirs)` Sets import directories +* `setFormatter($formatterName)` * `param string` $formatterName +* `compiler($compiler, array $options = Array ( ) )` Sets the compiler. + +## Minify + + +Minifies asset file (CSS or JS). + +``` php +taskMinify( 'web/assets/theme.css' ) + ->run() +?> +``` +Please install additional dependencies to use: + +``` +"patchwork/jsqueeze": "~1.0", +"natxet/CssMin": "~3.0" +``` + +* `to($dst)` Sets destination. Tries to guess type from it. +* `type($type)` Sets type with validation. +* `singleLine($singleLine)` Single line option for the JS minimisation. +* `keepImportantComments($keepImportantComments)` keepImportantComments option for the JS minimisation. +* `specialVarRx($specialVarRx)` specialVarRx option for the JS minimisation. +* `__toString()` @return string + +## Scss + + +Compiles scss files. + +```php +taskScss([ + 'scss/default.scss' => 'css/default.css' +]) +->importDir('assets/styles') +->run(); +?> +``` + +Use the following scss compiler in your project: + +``` +"leafo/scssphp": "~0.1", +``` + +You can implement additional compilers by extending this task and adding a +method named after them and overloading the scssCompilers() method to +inject the name there. + +* `setFormatter($formatterName)` Sets the formatter for scssphp +* `importDir($dirs)` Sets import directories +* `addImportPath($dir)` Adds import directory +* `setImportPaths($dirs)` Sets import directories +* `compiler($compiler, array $options = Array ( ) )` Sets the compiler. + diff --git a/src/composer/vendor/consolidation/robo/docs/tasks/Base.md b/src/composer/vendor/consolidation/robo/docs/tasks/Base.md new file mode 100644 index 00000000..3dc5fcd8 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/docs/tasks/Base.md @@ -0,0 +1,126 @@ +# Base Tasks +## Exec + + +Executes shell script. Closes it when running in background mode. + +``` php +taskExec('compass')->arg('watch')->run(); +// or use shortcut +$this->_exec('compass watch'); + +$this->taskExec('compass watch')->background()->run(); + +if ($this->taskExec('phpunit .')->run()->wasSuccessful()) { + $this->say('tests passed'); +} + +?> +``` + +* `background()` Executes command in background mode (asynchronously) +* `timeout($timeout)` Stop command if it runs longer then $timeout in seconds +* `idleTimeout($timeout)` Stops command if it does not output something for a while +* `env(array $env)` Sets the environment variables for the command +* `simulate($context)` {@inheritdoc} +* `dir($dir)` Changes working directory of command +* `printed($arg)` Should command output be printed +* `arg($arg)` Pass argument to executable. Its value will be automatically escaped. +* `args($args)` Pass methods parameters as arguments to executable. Argument values +* `rawArg($arg)` Pass the provided string in its raw (as provided) form as an argument to executable. +* `option($option, $value = null)` Pass option to executable. Options are prefixed with `--` , value can be provided in second parameter. +* `optionList($option, $value = null)` Pass multiple options to executable. Value can be a string or array. + +## ExecStack + + +Execute commands one by one in stack. +Stack can be stopped on first fail if you call `stopOnFail()`. + +```php +taskExecStack() + ->stopOnFail() + ->exec('mkdir site') + ->exec('cd site') + ->run(); + +?> +``` + +* `$this stopOnFail()` + +* `executable($executable)` * `param string` $executable +* `exec($command)` * `param string|string[]` $command +* `stopOnFail($stopOnFail = null)` * `param bool` $stopOnFail +* `result($result)` +* `dir($dir)` Changes working directory of command +* `printed($arg)` Should command output be printed + +## ParallelExec + + +Class ParallelExecTask + +``` php +taskParallelExec() + ->process('php ~/demos/script.php hey') + ->process('php ~/demos/script.php hoy') + ->process('php ~/demos/script.php gou') + ->run(); +?> +``` + + +* ` timeout(int $timeout)` stops process if it runs longer then `$timeout` (seconds) +* ` idleTimeout(int $timeout)` stops process if it does not output for time longer then `$timeout` (seconds) + +* `printed($isPrinted = null)` * `param bool` $isPrinted +* `process($command)` * `param string|\Robo\Contract\CommandInterface` $command +* `timeout($timeout)` * `param int` $timeout +* `idleTimeout($idleTimeout)` * `param int` $idleTimeout + +## SymfonyCommand + + +Executes Symfony Command + +``` php +taskSymfonyCommand(new \Codeception\Command\Run('run')) + ->arg('suite','acceptance') + ->opt('debug') + ->run(); + +// Artisan Command +$this->taskSymfonyCommand(new ModelGeneratorCommand()) + ->arg('name', 'User') + ->run(); +?> +``` + +* `arg($arg, $value)` * `param string` $arg +* `opt($option, $value = null)` + +## Watch + + +Runs task when specified file or dir was changed. +Uses Lurker library. + +``` php +taskWatch() + ->monitor('composer.json', function() { + $this->taskComposerUpdate()->run(); +})->monitor('src', function() { + $this->taskExec('phpunit')->run(); +})->run(); +?> +``` + +* `monitor($paths, $callable)` * `param string|string[]` $paths + diff --git a/src/composer/vendor/consolidation/robo/docs/tasks/Bower.md b/src/composer/vendor/consolidation/robo/docs/tasks/Bower.md new file mode 100644 index 00000000..c54d6015 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/docs/tasks/Bower.md @@ -0,0 +1,60 @@ +# Bower Tasks + +## Install + + +Bower Install + +``` php +taskBowerInstall()->run(); + +// prefer dist with custom path +$this->taskBowerInstall('path/to/my/bower') + ->noDev() + ->run(); +?> +``` + +* `allowRoot()` adds `allow-root` option to bower +* `forceLatest()` adds `force-latest` option to bower +* `noDev()` adds `production` option to bower +* `offline()` adds `offline` option to bower +* `dir($dir)` Changes working directory of command +* `printed($arg)` Should command output be printed +* `arg($arg)` Pass argument to executable. Its value will be automatically escaped. +* `args($args)` Pass methods parameters as arguments to executable. Argument values +* `rawArg($arg)` Pass the provided string in its raw (as provided) form as an argument to executable. +* `option($option, $value = null)` Pass option to executable. Options are prefixed with `--` , value can be provided in second parameter. +* `optionList($option, $value = null)` Pass multiple options to executable. Value can be a string or array. + +## Update + + +Bower Update + +``` php +taskBowerUpdate->run(); + +// prefer dist with custom path +$this->taskBowerUpdate('path/to/my/bower') + ->noDev() + ->run(); +?> +``` + +* `allowRoot()` adds `allow-root` option to bower +* `forceLatest()` adds `force-latest` option to bower +* `noDev()` adds `production` option to bower +* `offline()` adds `offline` option to bower +* `dir($dir)` Changes working directory of command +* `printed($arg)` Should command output be printed +* `arg($arg)` Pass argument to executable. Its value will be automatically escaped. +* `args($args)` Pass methods parameters as arguments to executable. Argument values +* `rawArg($arg)` Pass the provided string in its raw (as provided) form as an argument to executable. +* `option($option, $value = null)` Pass option to executable. Options are prefixed with `--` , value can be provided in second parameter. +* `optionList($option, $value = null)` Pass multiple options to executable. Value can be a string or array. + diff --git a/src/composer/vendor/consolidation/robo/docs/tasks/Composer.md b/src/composer/vendor/consolidation/robo/docs/tasks/Composer.md new file mode 100644 index 00000000..310c3ef3 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/docs/tasks/Composer.md @@ -0,0 +1,179 @@ +# Composer Tasks + +## DumpAutoload + + +Composer Dump Autoload + +``` php +taskComposerDumpAutoload()->run(); + +// dump auto loader with custom path +$this->taskComposerDumpAutoload('path/to/my/composer.phar') + ->preferDist() + ->run(); + +// optimize autoloader dump with custom path +$this->taskComposerDumpAutoload('path/to/my/composer.phar') + ->optimize() + ->run(); + +// optimize autoloader dump with custom path and no dev +$this->taskComposerDumpAutoload('path/to/my/composer.phar') + ->optimize() + ->noDev() + ->run(); +?> +``` + +* `optimize()` * `return` $this +* `preferDist()` adds `prefer-dist` option to composer +* `preferSource()` adds `prefer-source` option to composer +* `noDev()` adds `no-dev` option to composer +* `noAnsi()` adds `no-ansi` option to composer +* `ansi()` adds `ansi` option to composer +* `optimizeAutoloader()` adds `optimize-autoloader` option to composer +* `dir($dir)` Changes working directory of command +* `printed($arg)` Should command output be printed +* `arg($arg)` Pass argument to executable. Its value will be automatically escaped. +* `args($args)` Pass methods parameters as arguments to executable. Argument values +* `rawArg($arg)` Pass the provided string in its raw (as provided) form as an argument to executable. +* `option($option, $value = null)` Pass option to executable. Options are prefixed with `--` , value can be provided in second parameter. +* `optionList($option, $value = null)` Pass multiple options to executable. Value can be a string or array. + +## Install + + +Composer Install + +``` php +taskComposerInstall()->run(); + +// prefer dist with custom path +$this->taskComposerInstall('path/to/my/composer.phar') + ->preferDist() + ->run(); + +// optimize autoloader with custom path +$this->taskComposerInstall('path/to/my/composer.phar') + ->optimizeAutoloader() + ->run(); +?> +``` + +* `preferDist()` adds `prefer-dist` option to composer +* `preferSource()` adds `prefer-source` option to composer +* `noDev()` adds `no-dev` option to composer +* `noAnsi()` adds `no-ansi` option to composer +* `ansi()` adds `ansi` option to composer +* `optimizeAutoloader()` adds `optimize-autoloader` option to composer +* `dir($dir)` Changes working directory of command +* `printed($arg)` Should command output be printed +* `arg($arg)` Pass argument to executable. Its value will be automatically escaped. +* `args($args)` Pass methods parameters as arguments to executable. Argument values +* `rawArg($arg)` Pass the provided string in its raw (as provided) form as an argument to executable. +* `option($option, $value = null)` Pass option to executable. Options are prefixed with `--` , value can be provided in second parameter. +* `optionList($option, $value = null)` Pass multiple options to executable. Value can be a string or array. + +## Remove + + +Composer Validate + +``` php +taskComposerValidate()->run(); +?> +``` + +* `dev()` * `return` $this +* `noProgress()` * `return` $this +* `noUpdate()` * `return` $this +* `updateNoDev()` * `return` $this +* `noUpdateWithDependencies()` * `return` $this +* `preferDist()` adds `prefer-dist` option to composer +* `preferSource()` adds `prefer-source` option to composer +* `noDev()` adds `no-dev` option to composer +* `noAnsi()` adds `no-ansi` option to composer +* `ansi()` adds `ansi` option to composer +* `optimizeAutoloader()` adds `optimize-autoloader` option to composer +* `dir($dir)` Changes working directory of command +* `printed($arg)` Should command output be printed +* `arg($arg)` Pass argument to executable. Its value will be automatically escaped. +* `args($args)` Pass methods parameters as arguments to executable. Argument values +* `rawArg($arg)` Pass the provided string in its raw (as provided) form as an argument to executable. +* `option($option, $value = null)` Pass option to executable. Options are prefixed with `--` , value can be provided in second parameter. +* `optionList($option, $value = null)` Pass multiple options to executable. Value can be a string or array. + +## Update + + +Composer Update + +``` php +taskComposerUpdate()->run(); + +// prefer dist with custom path +$this->taskComposerUpdate('path/to/my/composer.phar') + ->preferDist() + ->run(); + +// optimize autoloader with custom path +$this->taskComposerUpdate('path/to/my/composer.phar') + ->optimizeAutoloader() + ->run(); +?> +``` + +* `preferDist()` adds `prefer-dist` option to composer +* `preferSource()` adds `prefer-source` option to composer +* `noDev()` adds `no-dev` option to composer +* `noAnsi()` adds `no-ansi` option to composer +* `ansi()` adds `ansi` option to composer +* `optimizeAutoloader()` adds `optimize-autoloader` option to composer +* `dir($dir)` Changes working directory of command +* `printed($arg)` Should command output be printed +* `arg($arg)` Pass argument to executable. Its value will be automatically escaped. +* `args($args)` Pass methods parameters as arguments to executable. Argument values +* `rawArg($arg)` Pass the provided string in its raw (as provided) form as an argument to executable. +* `option($option, $value = null)` Pass option to executable. Options are prefixed with `--` , value can be provided in second parameter. +* `optionList($option, $value = null)` Pass multiple options to executable. Value can be a string or array. + +## Validate + + +Composer Validate + +``` php +taskComposerValidate()->run(); +?> +``` + +* `noCheckAll()` * `return` $this +* `noCheckLock()` * `return` $this +* `noCheckPublish()` * `return` $this +* `withDependencies()` * `return` $this +* `strict()` * `return` $this +* `preferDist()` adds `prefer-dist` option to composer +* `preferSource()` adds `prefer-source` option to composer +* `noDev()` adds `no-dev` option to composer +* `noAnsi()` adds `no-ansi` option to composer +* `ansi()` adds `ansi` option to composer +* `optimizeAutoloader()` adds `optimize-autoloader` option to composer +* `dir($dir)` Changes working directory of command +* `printed($arg)` Should command output be printed +* `arg($arg)` Pass argument to executable. Its value will be automatically escaped. +* `args($args)` Pass methods parameters as arguments to executable. Argument values +* `rawArg($arg)` Pass the provided string in its raw (as provided) form as an argument to executable. +* `option($option, $value = null)` Pass option to executable. Options are prefixed with `--` , value can be provided in second parameter. +* `optionList($option, $value = null)` Pass multiple options to executable. Value can be a string or array. + diff --git a/src/composer/vendor/consolidation/robo/docs/tasks/Development.md b/src/composer/vendor/consolidation/robo/docs/tasks/Development.md new file mode 100644 index 00000000..f5c71557 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/docs/tasks/Development.md @@ -0,0 +1,282 @@ +# Development Tasks +## Changelog + + +Helps to manage changelog file. +Creates or updates `changelog.md` file with recent changes in current version. + +``` php +taskChangelog() + ->version($version) + ->change("released to github") + ->run(); +?> +``` + +Changes can be asked from Console + +``` php +taskChangelog() + ->version($version) + ->askForChanges() + ->run(); +?> +``` + +* `Development\Changelog filename(string $filename)` +* `Development\Changelog anchor(string $anchor)` +* `Development\Changelog version(string $version)` + +* `filename($filename)` * `param string` $filename +* `log($item)` * `param string` $item +* `anchor($anchor)` * `param string` $anchor +* `version($version)` * `param string` $version +* `changes(array $data)` * `param array` $data +* `change($change)` * `param string` $change +* `getChanges()` @return array + +## GenerateMarkdownDoc + + +Simple documentation generator from source files. +Takes classes, properties and methods with their docblocks and writes down a markdown file. + +``` php +taskGenDoc('models.md') + ->docClass('Model\User') // take class Model\User + ->docClass('Model\Post') // take class Model\Post + ->filterMethods(function(\ReflectionMethod $r) { + return $r->isPublic() or $r->isProtected(); // process public and protected methods + })->processClass(function(\ReflectionClass $r, $text) { + return "Class ".$r->getName()."\n\n$text\n\n###Methods\n"; + })->run(); +``` + +By default this task generates a documentation for each public method of a class. +It combines method signature with a docblock. Both can be post-processed. + +``` php +taskGenDoc('models.md') + ->docClass('Model\User') + ->processClassSignature(false) // false can be passed to not include class signature + ->processClassDocBlock(function(\ReflectionClass $r, $text) { + return "[This is part of application model]\n" . $text; + })->processMethodSignature(function(\ReflectionMethod $r, $text) { + return "#### {$r->name}()"; + })->processMethodDocBlock(function(\ReflectionMethod $r, $text) { + return strpos($r->name, 'save')===0 ? "[Saves to the database]\n" . $text : $text; + })->run(); +``` + +* ` docClass(string $classname)` put a class you want to be documented +* ` filterMethods(\Closure $func)` using callback function filter out methods that won't be documented +* ` filterClasses(\Closure $func)` using callback function filter out classes that won't be documented +* ` filterProperties(\Closure $func)` using callback function filter out properties that won't be documented +* ` processClass(\Closure $func)` post-process class documentation +* ` processClassSignature(\Closure $func)` post-process class signature. Provide *false* to skip. +* ` processClassDocBlock(\Closure $func)` post-process class docblock contents. Provide *false* to skip. +* ` processMethod(\Closure $func)` post-process method documentation. Provide *false* to skip. +* ` processMethodSignature(\Closure $func)` post-process method signature. Provide *false* to skip. +* ` processMethodDocBlock(\Closure $func)` post-process method docblock contents. Provide *false* to skip. +* ` processProperty(\Closure $func)` post-process property documentation. Provide *false* to skip. +* ` processPropertySignature(\Closure $func)` post-process property signature. Provide *false* to skip. +* ` processPropertyDocBlock(\Closure $func)` post-process property docblock contents. Provide *false* to skip. +* ` reorder(\Closure $func)` use a function to reorder classes +* ` reorderMethods(\Closure $func)` use a function to reorder methods in class +* ` prepend($text)` inserts text into beginning of markdown file +* ` append($text)` inserts text in the end of markdown file + +* `docClass($item)` * `param string` $item +* `filterMethods($filterMethods)` * `param callable` $filterMethods +* `filterClasses($filterClasses)` * `param callable` $filterClasses +* `filterProperties($filterProperties)` * `param callable` $filterProperties +* `processClass($processClass)` * `param callable` $processClass +* `processClassSignature($processClassSignature)` * `param callable|false` $processClassSignature +* `processClassDocBlock($processClassDocBlock)` * `param callable|false` $processClassDocBlock +* `processMethod($processMethod)` * `param callable|false` $processMethod +* `processMethodSignature($processMethodSignature)` * `param callable|false` $processMethodSignature +* `processMethodDocBlock($processMethodDocBlock)` * `param callable|false` $processMethodDocBlock +* `processProperty($processProperty)` * `param callable|false` $processProperty +* `processPropertySignature($processPropertySignature)` * `param callable|false` $processPropertySignature +* `processPropertyDocBlock($processPropertyDocBlock)` * `param callable|false` $processPropertyDocBlock +* `reorder($reorder)` * `param callable` $reorder +* `reorderMethods($reorderMethods)` * `param callable` $reorderMethods +* `reorderProperties($reorderProperties)` * `param callable` $reorderProperties +* `filename($filename)` * `param string` $filename +* `prepend($prepend)` * `param string` $prepend +* `append($append)` * `param string` $append +* `text($text)` * `param string` $text +* `textForClass($item)` * `param string` $item + +## Generate + + +Generate a Robo Task that is a wrapper around an existing class. + +``` php +taskGenerateTask('Symfony\Component\Filesystem\Filesystem', 'FilesystemStack') + ->run(); +``` + + + + +## GitHubRelease + + +Publishes new GitHub release. + +``` php +taskGitHubRelease('0.1.0') + ->uri('consolidation-org/Robo') + ->description('Add stuff people need.') + ->change('Fix #123') + ->change('Add frobulation method to all widgets') + ->run(); +?> +``` + +* `tag($tag)` * `param string` $tag +* `draft($draft)` * `param bool` $draft +* `name($name)` * `param string` $name +* `description($description)` * `param string` $description +* `prerelease($prerelease)` * `param bool` $prerelease +* `comittish($comittish)` * `param string` $comittish +* `appendDescription($description)` * `param string` $description +* `changes(array $changes)` +* `change($change)` * `param string` $change +* `repo($repo)` * `param string` $repo +* `owner($owner)` * `param string` $owner +* `uri($uri)` * `param string` $uri +* `user($user)` * `param string` $user +* `password($password)` * `param` $password + +## OpenBrowser + + +Opens the default's user browser +code inspired from openBrowser() function in https://github.com/composer/composer/blob/master/src/Composer/Command/HomeCommand.php + +``` php +taskOpenBrowser('http://localhost') + ->run(); + +// open two browser windows +$this->taskOpenBrowser([ + 'http://localhost/mysite', + 'http://localhost/mysite2' + ]) + ->run(); +``` + + + +## PackPhar + + +Creates Phar. + +``` php +taskPackPhar('package/codecept.phar') + ->compress() + ->stub('package/stub.php'); + + $finder = Finder::create() + ->name('*.php') + ->in('src'); + + foreach ($finder as $file) { + $pharTask->addFile('src/'.$file->getRelativePathname(), $file->getRealPath()); + } + + $finder = Finder::create()->files() + ->name('*.php') + ->in('vendor'); + + foreach ($finder as $file) { + $pharTask->addStripped('vendor/'.$file->getRelativePathname(), $file->getRealPath()); + } + $pharTask->run(); + + // verify Phar is packed correctly + $code = $this->_exec('php package/codecept.phar'); +?> +``` + +* `compress($compress = null)` * `param bool` $compress +* `stub($stub)` * `param string` $stub +* `addStripped($path, $file)` * `param string` $path +* `addFile($path, $file)` * `param string` $path +* `addFiles($files)` * `param \Symfony\Component\Finder\SplFileInfo[]` $files +* `executable($file)` * `param string` $file + +## PhpServer + + +Runs PHP server and stops it when task finishes. + +``` php +taskServer(8000) + ->dir('public') + ->run(); + +// run with IP 0.0.0.0 +$this->taskServer(8000) + ->host('0.0.0.0') + ->run(); + +// execute server in background +$this->taskServer(8000) + ->background() + ->run(); +?> +``` + +* `host($host)` * `param string` $host +* `dir($path)` * `param string` $path +* `background()` Executes command in background mode (asynchronously) +* `timeout($timeout)` Stop command if it runs longer then $timeout in seconds +* `idleTimeout($timeout)` Stops command if it does not output something for a while +* `env(array $env)` Sets the environment variables for the command +* `simulate($context)` {@inheritdoc} +* `printed($arg)` Should command output be printed +* `arg($arg)` Pass argument to executable. Its value will be automatically escaped. +* `args($args)` Pass methods parameters as arguments to executable. Argument values +* `rawArg($arg)` Pass the provided string in its raw (as provided) form as an argument to executable. +* `option($option, $value = null)` Pass option to executable. Options are prefixed with `--` , value can be provided in second parameter. +* `optionList($option, $value = null)` Pass multiple options to executable. Value can be a string or array. + +## SemVer + + +Helps to maintain `.semver` file. + +```php +taskSemVer('.semver') + ->increment() + ->run(); +?> +``` + + +* `__toString()` @return string +* `setFormat($format)` * `param string` $format +* `setMetadataSeparator($separator)` * `param string` $separator +* `setPrereleaseSeparator($separator)` * `param string` $separator +* `increment($what = null)` * `param string` $what +* `prerelease($tag = null)` * `param string` $tag +* `metadata($data)` * `param array|string` $data + diff --git a/src/composer/vendor/consolidation/robo/docs/tasks/Docker.md b/src/composer/vendor/consolidation/robo/docs/tasks/Docker.md new file mode 100644 index 00000000..712b236e --- /dev/null +++ b/src/composer/vendor/consolidation/robo/docs/tasks/Docker.md @@ -0,0 +1,249 @@ +# Docker Tasks + +## Build + + +Builds Docker image + +```php +taskDockerBuild()->run(); + +$this->taskDockerBuild('path/to/dir') + ->tag('database') + ->run(); + +?> + +``` + +Class Build +@package Robo\Task\Docker + +* `tag($tag)` * `param string` $tag +* `dir($dir)` Changes working directory of command +* `printed($arg)` Should command output be printed +* `arg($arg)` Pass argument to executable. Its value will be automatically escaped. +* `args($args)` Pass methods parameters as arguments to executable. Argument values +* `rawArg($arg)` Pass the provided string in its raw (as provided) form as an argument to executable. +* `option($option, $value = null)` Pass option to executable. Options are prefixed with `--` , value can be provided in second parameter. +* `optionList($option, $value = null)` Pass multiple options to executable. Value can be a string or array. + +## Commit + + +Commits docker container to an image + +``` +$this->taskDockerCommit($containerId) + ->name('my/database') + ->run(); + +// alternatively you can take the result from DockerRun task: + +$result = $this->taskDockerRun('db') + ->exec('./prepare_database.sh') + ->run(); + +$task->dockerCommit($result) + ->name('my/database') + ->run(); +``` + +* `name($name)` * `param` $name +* `dir($dir)` Changes working directory of command +* `printed($arg)` Should command output be printed +* `arg($arg)` Pass argument to executable. Its value will be automatically escaped. +* `args($args)` Pass methods parameters as arguments to executable. Argument values +* `rawArg($arg)` Pass the provided string in its raw (as provided) form as an argument to executable. +* `option($option, $value = null)` Pass option to executable. Options are prefixed with `--` , value can be provided in second parameter. +* `optionList($option, $value = null)` Pass multiple options to executable. Value can be a string or array. + +## Exec + + +Executes command inside running Docker container + +```php +taskDockerRun('test_env') + ->detached() + ->run(); + +$this->taskDockerExec($test) + ->interactive() + ->exec('./runtests') + ->run(); + +// alternatively use commands from other tasks + +$this->taskDockerExec($test) + ->interactive() + ->exec($this->taskCodecept()->suite('acceptance')) + ->run(); +?> +``` + + +* `detached()` * `return` $this +* `interactive()` * `return` $this +* `exec($command)` * `param string|\Robo\Contract\CommandInterface` $command +* `dir($dir)` Changes working directory of command +* `printed($arg)` Should command output be printed +* `arg($arg)` Pass argument to executable. Its value will be automatically escaped. +* `args($args)` Pass methods parameters as arguments to executable. Argument values +* `rawArg($arg)` Pass the provided string in its raw (as provided) form as an argument to executable. +* `option($option, $value = null)` Pass option to executable. Options are prefixed with `--` , value can be provided in second parameter. +* `optionList($option, $value = null)` Pass multiple options to executable. Value can be a string or array. + +## Pull + + +Pulls an image from DockerHub + +```php +taskDockerPull('wordpress') + ->run(); + +?> +``` + + +* `dir($dir)` Changes working directory of command +* `printed($arg)` Should command output be printed +* `arg($arg)` Pass argument to executable. Its value will be automatically escaped. +* `args($args)` Pass methods parameters as arguments to executable. Argument values +* `rawArg($arg)` Pass the provided string in its raw (as provided) form as an argument to executable. +* `option($option, $value = null)` Pass option to executable. Options are prefixed with `--` , value can be provided in second parameter. +* `optionList($option, $value = null)` Pass multiple options to executable. Value can be a string or array. + +## Remove + + +Remove docker container + +```php +taskDockerRemove($container) + ->run(); +?> +``` + + +* `dir($dir)` Changes working directory of command +* `printed($arg)` Should command output be printed +* `arg($arg)` Pass argument to executable. Its value will be automatically escaped. +* `args($args)` Pass methods parameters as arguments to executable. Argument values +* `rawArg($arg)` Pass the provided string in its raw (as provided) form as an argument to executable. +* `option($option, $value = null)` Pass option to executable. Options are prefixed with `--` , value can be provided in second parameter. +* `optionList($option, $value = null)` Pass multiple options to executable. Value can be a string or array. + + +## Run + + +Performs `docker run` on a container. + +```php +taskDockerRun('mysql')->run(); + +$result = $this->taskDockerRun('my_db_image') + ->env('DB', 'database_name') + ->volume('/path/to/data', '/data') + ->detached() + ->publish(3306) + ->name('my_mysql') + ->run(); + +// retrieve container's cid: +$this->say("Running container ".$result->getCid()); + +// execute script inside container +$result = $this->taskDockerRun('db') + ->exec('prepare_test_data.sh') + ->run(); + +$this->taskDockerCommit($result) + ->name('test_db') + ->run(); + +// link containers +$mysql = $this->taskDockerRun('mysql') + ->name('wp_db') // important to set name for linked container + ->env('MYSQL_ROOT_PASSWORD', '123456') + ->run(); + +$this->taskDockerRun('wordpress') + ->link($mysql) + ->publish(80, 8080) + ->detached() + ->run(); + +?> +``` + + +* `detached()` * `return` $this +* `interactive()` * `return` $this +* `exec($run)` * `param string|\Robo\Contract\CommandInterface` $run +* `volume($from, $to = null)` * `param string` $from +* `env($variable, $value = null)` * `param string` $variable +* `publish($port = null, $portTo = null)` * `param null|int` $port +* `containerWorkdir($dir)` * `param string` $dir +* `user($user)` * `param string` $user +* `privileged()` * `return` $this +* `name($name)` * `param string` $name +* `link($name, $alias)` * `param string|\Robo\Task\Docker\Result` $name +* `tmpDir($dir)` * `param string` $dir +* `getTmpDir()` @return string +* `getUniqId()` @return string +* `dir($dir)` Changes working directory of command +* `printed($arg)` Should command output be printed +* `arg($arg)` Pass argument to executable. Its value will be automatically escaped. +* `args($args)` Pass methods parameters as arguments to executable. Argument values +* `rawArg($arg)` Pass the provided string in its raw (as provided) form as an argument to executable. +* `option($option, $value = null)` Pass option to executable. Options are prefixed with `--` , value can be provided in second parameter. +* `optionList($option, $value = null)` Pass multiple options to executable. Value can be a string or array. + +## Start + + +Starts Docker container + +```php +taskDockerStart($cidOrResult) + ->run(); +?> +``` + +* `dir($dir)` Changes working directory of command +* `printed($arg)` Should command output be printed +* `arg($arg)` Pass argument to executable. Its value will be automatically escaped. +* `args($args)` Pass methods parameters as arguments to executable. Argument values +* `rawArg($arg)` Pass the provided string in its raw (as provided) form as an argument to executable. +* `option($option, $value = null)` Pass option to executable. Options are prefixed with `--` , value can be provided in second parameter. +* `optionList($option, $value = null)` Pass multiple options to executable. Value can be a string or array. + +## Stop + + +Stops Docker container + +```php +taskDockerStop($cidOrResult) + ->run(); +?> +``` + +* `dir($dir)` Changes working directory of command +* `printed($arg)` Should command output be printed +* `arg($arg)` Pass argument to executable. Its value will be automatically escaped. +* `args($args)` Pass methods parameters as arguments to executable. Argument values +* `rawArg($arg)` Pass the provided string in its raw (as provided) form as an argument to executable. +* `option($option, $value = null)` Pass option to executable. Options are prefixed with `--` , value can be provided in second parameter. +* `optionList($option, $value = null)` Pass multiple options to executable. Value can be a string or array. + diff --git a/src/composer/vendor/consolidation/robo/docs/tasks/File.md b/src/composer/vendor/consolidation/robo/docs/tasks/File.md new file mode 100644 index 00000000..7cb86a3a --- /dev/null +++ b/src/composer/vendor/consolidation/robo/docs/tasks/File.md @@ -0,0 +1,129 @@ +# File Tasks +## Concat + + +Merges files into one. Used for preparing assets. + +``` php +taskConcat([ + 'web/assets/screen.css', + 'web/assets/print.css', + 'web/assets/theme.css' + ]) + ->to('web/assets/style.css') + ->run() +?> +``` + +* `to($dst)` set the destination file + +## Replace + + +Performs search and replace inside a files. + +``` php +taskReplaceInFile('VERSION') + ->from('0.2.0') + ->to('0.3.0') + ->run(); + +$this->taskReplaceInFile('README.md') + ->from(date('Y')-1) + ->to(date('Y')) + ->run(); + +$this->taskReplaceInFile('config.yml') + ->regex('~^service:~') + ->to('services:') + ->run(); + +$this->taskReplaceInFile('box/robo.txt') + ->from(array('##dbname##', '##dbhost##')) + ->to(array('robo', 'localhost')) + ->run(); +?> +``` + +* `regex(string)` regex to match string to be replaced +* `from(string|array)` string(s) to be replaced +* `to(string|array)` value(s) to be set as a replacement + +* `filename($filename)` * `param string` $filename +* `from($from)` * `param string` $from +* `to($to)` * `param string` $to +* `regex($regex)` * `param string` $regex + +## TmpFile + + +Create a temporary file that is automatically cleaned up +once the task collection is is part of completes. When created, +it is given a random filename. + +This temporary file may be manipulated exacatly like taskWrite(). +It is deleted as soon as the collection it is a part of completes +or rolls back. + +``` php +collectionBuilder(); +$tmpFilePath = $collection->taskTmpFile() + ->line('-----') + ->line(date('Y-m-d').' '.$title) + ->line('----') + ->getPath(); +$collection->run(); +?> +``` + +* `complete()` Delete this file when our collection completes. +* `filename($filename)` * `param string` $filename +* `append($append = null)` * `param bool` $append +* `line($line)` add a line. +* `lines(array $lines)` add more lines. +* `text($text)` add a text. +* `textFromFile($filename)` add a text from a file. +* `place($name, $val)` substitute a placeholder with value, placeholder must be enclosed by `{}`. +* `replace($string, $replacement)` replace any string with value. +* `regexReplace($pattern, $replacement)` replace any string with value using regular expression. +* `appendIfMatches($pattern, $text)` Append the provided text to the end of the buffer if the provided +* `appendUnlessMatches($pattern, $text)` Append the provided text to the end of the buffer unless the provided +* `originalContents()` @return string +* `wouldChange()` @return bool +* `getPath()` @return string + +## Write + + +Writes to file. + +``` php +taskWriteToFile('blogpost.md') + ->line('-----') + ->line(date('Y-m-d').' '.$title) + ->line('----') + ->run(); +?> +``` + +* `append()` + +* `filename($filename)` * `param string` $filename +* `append($append = null)` * `param bool` $append +* `line($line)` add a line. +* `lines(array $lines)` add more lines. +* `text($text)` add a text. +* `textFromFile($filename)` add a text from a file. +* `place($name, $val)` substitute a placeholder with value, placeholder must be enclosed by `{}`. +* `replace($string, $replacement)` replace any string with value. +* `regexReplace($pattern, $replacement)` replace any string with value using regular expression. +* `appendIfMatches($pattern, $text)` Append the provided text to the end of the buffer if the provided +* `appendUnlessMatches($pattern, $text)` Append the provided text to the end of the buffer unless the provided +* `originalContents()` @return string +* `wouldChange()` @return bool +* `getPath()` @return string + diff --git a/src/composer/vendor/consolidation/robo/docs/tasks/Filesystem.md b/src/composer/vendor/consolidation/robo/docs/tasks/Filesystem.md new file mode 100644 index 00000000..20bc0170 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/docs/tasks/Filesystem.md @@ -0,0 +1,217 @@ +# Filesystem Tasks + +## CleanDir + + +Deletes all files from specified dir, ignoring git files. + +``` php +taskCleanDir(['tmp','logs'])->run(); +// as shortcut +$this->_cleanDir('app/cache'); +?> +``` + + + +## CopyDir + + +Copies one dir into another + +``` php +taskCopyDir(['dist/config' => 'config'])->run(); +// as shortcut +$this->_copyDir('dist/config', 'config'); +?> +``` + +* `dirPermissions($value)` Sets the default folder permissions for the destination if it doesn't exist +* `exclude($exclude = null)` List files to exclude. + +## DeleteDir + + +Deletes dir + +``` php +taskDeleteDir('tmp')->run(); +// as shortcut +$this->_deleteDir(['tmp', 'log']); +?> +``` + + + +## FilesystemStack + + +Wrapper for [Symfony Filesystem](http://symfony.com/doc/current/components/filesystem.html) Component. +Comands are executed in stack and can be stopped on first fail with `stopOnFail` option. + +``` php +taskFilesystemStack() + ->mkdir('logs') + ->touch('logs/.gitignore') + ->chgrp('www', 'www-data') + ->symlink('/var/log/nginx/error.log', 'logs/error.log') + ->run(); + +// one line +$this->_touch('.gitignore'); +$this->_mkdir('logs'); + +?> +``` + +* `$this mkdir($dir)` +* `$this touch($file)` +* `$this copy($from, $to, $force = null)` +* `$this chmod($file, $permissions, $umask = null, $recursive = null)` +* `$this chgrp($file, $group, $recursive = null)` +* `$this chown($file, $user, $recursive = null)` +* `$this remove($file)` +* `$this rename($from, $to)` +* `$this symlink($from, $to)` +* `$this mirror($from, $to)` + +* `stopOnFail($stop = null)` * `param bool` $stop + +## FlattenDir + + +Searches for files in a nested directory structure and copies them to +a target directory with or without the parent directories. The task was +inspired by [gulp-flatten](https://www.npmjs.com/package/gulp-flatten). + +Example directory structure: + +``` +└── assets + ├── asset-library1 + │ ├── README.md + │ └── asset-library1.min.js + └── asset-library2 + ├── README.md + └── asset-library2.min.js +``` + +The following code will search the `*.min.js` files and copy them +inside a new `dist` folder: + +``` php +taskFlattenDir(['assets/*.min.js' => 'dist'])->run(); +// or use shortcut +$this->_flattenDir('assets/*.min.js', 'dist'); +?> +``` + +You can also define the target directory with an additional method, instead of +key/value pairs. More similar to the gulp-flatten syntax: + +``` php +taskFlattenDir(['assets/*.min.js']) + ->to('dist') + ->run(); +?> +``` + +You can also append parts of the parent directories to the target path. If you give +the value `1` to the `includeParents()` method, then the top parent will be appended +to the target directory resulting in a path such as `dist/assets/asset-library1.min.js`. + +If you give a negative number, such as `-1` (the same as specifying `array(0, 1)` then +the bottom parent will be appended, resulting in a path such as +`dist/asset-library1/asset-library1.min.js`. + +The top parent directory will always be starting from the relative path to the current +directory. You can override that with the `parentDir()` method. If in the above example +you would specify `assets`, then the top parent directory would be `asset-library1`. + +``` php +taskFlattenDir(['assets/*.min.js' => 'dist']) + ->parentDir('assets') + ->includeParents(1) + ->run(); +?> +``` + +* `dirPermissions($permission)` Sets the default folder permissions for the destination if it does not exist. +* `includeParents($parents)` Sets the value from which direction and how much parent dirs should be included. +* `parentDir($dir)` Sets the parent directory from which the relative parent directories will be calculated. +* `to($target)` Sets the target directory where the files will be copied to. + +## MirrorDir + + +Mirrors a directory to another + +``` php +taskMirrorDir(['dist/config/' => 'config/'])->run(); +// or use shortcut +$this->_mirrorDir('dist/config/', 'config/'); + +?> +``` + + + +## TmpDir + + +Create a temporary directory that is automatically cleaned up +once the task collection is is part of completes. + +Use WorkDir if you do not want the directory to be deleted. + +``` php +run(). +$collection = $this->collectionBuilder(); +$tmpPath = $collection->tmpDir()->getPath(); +$collection->taskFilesystemStack() + ->mkdir("$tmpPath/log") + ->touch("$tmpPath/log/error.txt"); +$collection->run(); +// as shortcut (deleted when program exits) +$tmpPath = $this->_tmpDir(); +?> +``` + +* `cwd($shouldChangeWorkingDirectory = null)` Flag that we should cwd to the temporary directory when it is +* `complete()` Delete this directory when our collection completes. +* `getPath()` Get a reference to the path to the temporary directory, so that + +## WorkDir + + +Create a temporary working directory that is automatically renamed to its +final desired location if all of the tasks in the collection succeed. If +there is a rollback, then the working directory is deleted. + +``` php +collectionBuilder(); +$workingPath = $collection->workDir("build")->getPath(); +$collection->taskFilesystemStack() + ->mkdir("$workingPath/log") + ->touch("$workingPath/log/error.txt"); +$collection->run(); +?> +``` + +* `complete()` Move our working directory into its final destination once the +* `rollback()` Delete our working directory +* `getPath()` Get a reference to the path to the temporary directory, so that +* `cwd($shouldChangeWorkingDirectory = null)` Flag that we should cwd to the temporary directory when it is + diff --git a/src/composer/vendor/consolidation/robo/docs/tasks/Gulp.md b/src/composer/vendor/consolidation/robo/docs/tasks/Gulp.md new file mode 100644 index 00000000..fd387cc4 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/docs/tasks/Gulp.md @@ -0,0 +1,31 @@ +# Gulp Tasks + +## Run + + +Gulp Run + +``` php +taskGulpRun()->run(); + +// run task 'clean' with --silent option +$this->taskGulpRun('clean') + ->silent() + ->run(); +?> +``` + +* `silent()` adds `silent` option to gulp +* `noColor()` adds `--no-color` option to gulp +* `color()` adds `--color` option to gulp +* `simple()` adds `--tasks-simple` option to gulp +* `dir($dir)` Changes working directory of command +* `printed($arg)` Should command output be printed +* `arg($arg)` Pass argument to executable. Its value will be automatically escaped. +* `args($args)` Pass methods parameters as arguments to executable. Argument values +* `rawArg($arg)` Pass the provided string in its raw (as provided) form as an argument to executable. +* `option($option, $value = null)` Pass option to executable. Options are prefixed with `--` , value can be provided in second parameter. +* `optionList($option, $value = null)` Pass multiple options to executable. Value can be a string or array. + diff --git a/src/composer/vendor/consolidation/robo/docs/tasks/Npm.md b/src/composer/vendor/consolidation/robo/docs/tasks/Npm.md new file mode 100644 index 00000000..2a60f2af --- /dev/null +++ b/src/composer/vendor/consolidation/robo/docs/tasks/Npm.md @@ -0,0 +1,54 @@ +# Npm Tasks + +## Install + + +Npm Install + +``` php +taskNpmInstall()->run(); + +// prefer dist with custom path +$this->taskNpmInstall('path/to/my/npm') + ->noDev() + ->run(); +?> +``` + +* `noDev()` adds `production` option to npm +* `dir($dir)` Changes working directory of command +* `printed($arg)` Should command output be printed +* `arg($arg)` Pass argument to executable. Its value will be automatically escaped. +* `args($args)` Pass methods parameters as arguments to executable. Argument values +* `rawArg($arg)` Pass the provided string in its raw (as provided) form as an argument to executable. +* `option($option, $value = null)` Pass option to executable. Options are prefixed with `--` , value can be provided in second parameter. +* `optionList($option, $value = null)` Pass multiple options to executable. Value can be a string or array. + +## Update + + +Npm Update + +```php +taskNpmUpdate()->run(); + +// prefer dist with custom path +$this->taskNpmUpdate('path/to/my/npm') + ->noDev() + ->run(); +?> +``` + +* `noDev()` adds `production` option to npm +* `dir($dir)` Changes working directory of command +* `printed($arg)` Should command output be printed +* `arg($arg)` Pass argument to executable. Its value will be automatically escaped. +* `args($args)` Pass methods parameters as arguments to executable. Argument values +* `rawArg($arg)` Pass the provided string in its raw (as provided) form as an argument to executable. +* `option($option, $value = null)` Pass option to executable. Options are prefixed with `--` , value can be provided in second parameter. +* `optionList($option, $value = null)` Pass multiple options to executable. Value can be a string or array. + diff --git a/src/composer/vendor/consolidation/robo/docs/tasks/Remote.md b/src/composer/vendor/consolidation/robo/docs/tasks/Remote.md new file mode 100644 index 00000000..7121b7c8 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/docs/tasks/Remote.md @@ -0,0 +1,143 @@ +# Remote Tasks +## Rsync + + +Executes rsync in a flexible manner. + +``` php +$this->taskRsync() + ->fromPath('src/') + ->toHost('localhost') + ->toUser('dev') + ->toPath('/var/www/html/app/') + ->remoteShell('ssh -i public_key') + ->recursive() + ->excludeVcs() + ->checksum() + ->wholeFile() + ->verbose() + ->progress() + ->humanReadable() + ->stats() + ->run(); +``` + +You could also clone the task and do a dry-run first: + +``` php +$rsync = $this->taskRsync() + ->fromPath('src/') + ->toPath('example.com:/var/www/html/app/') + ->archive() + ->excludeVcs() + ->progress() + ->stats(); + +$dryRun = clone $rsync; +$dryRun->dryRun()->run(); +if ('y' === $this->ask('Do you want to run (y/n)')) { + $rsync->run(); +} +``` + +* ` fromUser(string $user)` +* ` fromHost(string $hostname)` +* ` toUser(string $user)` +* ` toHost(string $hostname)` + +* `fromPath($path)` This can either be a full rsync path spec (user@host:path) or just a path. +* `toPath($path)` This can either be a full rsync path spec (user@host:path) or just a path. +* `fromUser($fromUser)` * `param string` $fromUser +* `fromHost($fromHost)` * `param string` $fromHost +* `toUser($toUser)` * `param string` $toUser +* `toHost($toHost)` * `param string` $toHost +* `progress()` * `return` $this +* `stats()` * `return` $this +* `recursive()` * `return` $this +* `verbose()` * `return` $this +* `checksum()` * `return` $this +* `archive()` * `return` $this +* `compress()` * `return` $this +* `owner()` * `return` $this +* `group()` * `return` $this +* `times()` * `return` $this +* `delete()` * `return` $this +* `timeout($seconds)` * `param int` $seconds +* `humanReadable()` * `return` $this +* `wholeFile()` * `return` $this +* `dryRun()` * `return` $this +* `itemizeChanges()` * `return` $this +* `excludeVcs()` Excludes .git, .svn and .hg items at any depth. +* `exclude($pattern)` * `param array|string` $pattern +* `excludeFrom($file)` * `param string` $file +* `includeFilter($pattern)` * `param array|string` $pattern +* `filter($pattern)` * `param array|string` $pattern +* `filesFrom($file)` * `param string` $file +* `remoteShell($command)` * `param string` $command +* `dir($dir)` Changes working directory of command +* `printed($arg)` Should command output be printed +* `arg($arg)` Pass argument to executable. Its value will be automatically escaped. +* `args($args)` Pass methods parameters as arguments to executable. Argument values +* `rawArg($arg)` Pass the provided string in its raw (as provided) form as an argument to executable. +* `option($option, $value = null)` Pass option to executable. Options are prefixed with `--` , value can be provided in second parameter. +* `optionList($option, $value = null)` Pass multiple options to executable. Value can be a string or array. + +## Ssh + + +Runs multiple commands on a remote server. +Per default, commands are combined with &&, unless stopOnFail is false. + +```php +taskSshExec('remote.example.com', 'user') + ->remoteDir('/var/www/html') + ->exec('ls -la') + ->exec('chmod g+x logs') + ->run(); + +``` + +You can even exec other tasks (which implement CommandInterface): + +```php +$gitTask = $this->taskGitStack() + ->checkout('master') + ->pull(); + +$this->taskSshExec('remote.example.com') + ->remoteDir('/var/www/html/site') + ->exec($gitTask) + ->run(); +``` + +You can configure the remote directory for all future calls: + +```php +::configure('remoteDir', '/some-dir'); +``` + +* `$this stopOnFail(bool $stopOnFail)` Whether or not to chain commands together with && + and stop the chain if one command fails +* `$this remoteDir(string $remoteWorkingDirectory)` Changes to the given directory before running commands + +* `hostname($hostname)` * `param string` $hostname +* `user($user)` * `param string` $user +* `stopOnFail($stopOnFail = null)` * `param bool` $stopOnFail +* `remoteDir($remoteDir)` * `param string` $remoteDir +* `identityFile($filename)` * `param string` $filename +* `port($port)` * `param int` $port +* `forcePseudoTty()` * `return` $this +* `quiet()` * `return` $this +* `verbose()` * `return` $this +* `exec($command)` * `param string|string[]|CommandInterface` $command +* `simulate($context)` {@inheritdoc} +* `dir($dir)` Changes working directory of command +* `printed($arg)` Should command output be printed +* `arg($arg)` Pass argument to executable. Its value will be automatically escaped. +* `args($args)` Pass methods parameters as arguments to executable. Argument values +* `rawArg($arg)` Pass the provided string in its raw (as provided) form as an argument to executable. +* `option($option, $value = null)` Pass option to executable. Options are prefixed with `--` , value can be provided in second parameter. +* `optionList($option, $value = null)` Pass multiple options to executable. Value can be a string or array. + diff --git a/src/composer/vendor/consolidation/robo/docs/tasks/Testing.md b/src/composer/vendor/consolidation/robo/docs/tasks/Testing.md new file mode 100644 index 00000000..c9fd5196 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/docs/tasks/Testing.md @@ -0,0 +1,171 @@ +# Testing Tasks +## Atoum + + +Runs [atoum](http://atoum.org/) tests + +``` php +taskAtoum() + ->files('path/to/test.php') + ->configFile('config/dev.php') + ->run() + +?> +``` + +* `tags($tags)` Tag or Tags to filter. +* `lightReport()` Display result using the light reporter. +* `tap()` Display result using the tap reporter. +* `bootstrap($file)` Path to the bootstrap file. +* `configFile($file)` Path to the config file. +* `debug()` Use atoum's debug mode. +* `files($files)` Test file or test files to run. +* `directories($directories)` Test directory or directories to run. +* `dir($dir)` Changes working directory of command +* `printed($arg)` Should command output be printed +* `arg($arg)` Pass argument to executable. Its value will be automatically escaped. +* `args($args)` Pass methods parameters as arguments to executable. Argument values +* `rawArg($arg)` Pass the provided string in its raw (as provided) form as an argument to executable. +* `option($option, $value = null)` Pass option to executable. Options are prefixed with `--` , value can be provided in second parameter. +* `optionList($option, $value = null)` Pass multiple options to executable. Value can be a string or array. + +## Behat + + +Executes Behat tests + +``` php +taskBehat() + ->format('pretty') + ->noInteraction() + ->run(); +?> +``` + + +* `stopOnFail()` * `return` $this +* `noInteraction()` * `return` $this +* `config($config_file)` * `param` $config_file +* `colors()` * `return` $this +* `noColors()` * `return` $this +* `suite($suite)` * `param string` $suite +* `verbose($level = null)` * `param string` $level +* `format($formater)` * `param string` $formater +* `dir($dir)` Changes working directory of command +* `printed($arg)` Should command output be printed +* `arg($arg)` Pass argument to executable. Its value will be automatically escaped. +* `args($args)` Pass methods parameters as arguments to executable. Argument values +* `rawArg($arg)` Pass the provided string in its raw (as provided) form as an argument to executable. +* `option($option, $value = null)` Pass option to executable. Options are prefixed with `--` , value can be provided in second parameter. +* `optionList($option, $value = null)` Pass multiple options to executable. Value can be a string or array. + +## Codecept + + +Executes Codeception tests + +``` php +taskCodecept() + ->suite('acceptance') + ->env('chrome') + ->group('admin') + ->xml() + ->html() + ->run(); + +?> +``` + + +* `suite($suite)` * `param string` $suite +* `test($testName)` * `param string` $testName +* `group($group)` set group option. Can be called multiple times +* `excludeGroup($group)` * `param string` $group +* `json($file = null)` generate json report +* `xml($file = null)` generate xml JUnit report +* `html($dir = null)` Generate html report +* `tap($file = null)` generate tap report +* `configFile($file)` provides config file other then default `codeception.yml` with `-c` option +* `coverage($cov = null)` collect codecoverage in raw format. You may pass name of cov file to save results +* `silent()` execute in silent mode +* `coverageXml($xml = null)` collect code coverage in xml format. You may pass name of xml file to save results +* `coverageHtml($html = null)` collect code coverage and generate html report. You may pass +* `env($env)` * `param string` $env +* `debug()` * `return` $this +* `dir($dir)` Changes working directory of command +* `printed($arg)` Should command output be printed +* `arg($arg)` Pass argument to executable. Its value will be automatically escaped. +* `args($args)` Pass methods parameters as arguments to executable. Argument values +* `rawArg($arg)` Pass the provided string in its raw (as provided) form as an argument to executable. +* `option($option, $value = null)` Pass option to executable. Options are prefixed with `--` , value can be provided in second parameter. +* `optionList($option, $value = null)` Pass multiple options to executable. Value can be a string or array. + +## PHPUnit + + +Runs PHPUnit tests + +``` php +taskPHPUnit() + ->group('core') + ->bootstrap('test/bootstrap.php') + ->run() + +?> +``` + +* `filter($filter)` * `param string` $filter +* `group($group)` * `param string` $group +* `excludeGroup($group)` * `param string` $group +* `json($file = null)` adds `log-json` option to runner +* `xml($file = null)` adds `log-junit` option +* `tap($file = null)` * `param string` $file +* `bootstrap($file)` * `param string` $file +* `configFile($file)` * `param string` $file +* `debug()` * `return` $this +* `files($files)` Directory of test files or single test file to run. +* `file($file)` Test the provided file. +* `dir($dir)` Changes working directory of command +* `printed($arg)` Should command output be printed +* `arg($arg)` Pass argument to executable. Its value will be automatically escaped. +* `args($args)` Pass methods parameters as arguments to executable. Argument values +* `rawArg($arg)` Pass the provided string in its raw (as provided) form as an argument to executable. +* `option($option, $value = null)` Pass option to executable. Options are prefixed with `--` , value can be provided in second parameter. +* `optionList($option, $value = null)` Pass multiple options to executable. Value can be a string or array. + +## Phpspec + + +Executes Phpspec tests + +``` php +taskPhpspec() + ->format('pretty') + ->noInteraction() + ->run(); +?> +``` + + +* `stopOnFail()` +* `noCodeGeneration()` +* `quiet()` +* `verbose($level = null)` +* `noAnsi()` +* `noInteraction()` +* `config($config_file)` +* `format($formater)` +* `dir($dir)` Changes working directory of command +* `printed($arg)` Should command output be printed +* `arg($arg)` Pass argument to executable. Its value will be automatically escaped. +* `args($args)` Pass methods parameters as arguments to executable. Argument values +* `rawArg($arg)` Pass the provided string in its raw (as provided) form as an argument to executable. +* `option($option, $value = null)` Pass option to executable. Options are prefixed with `--` , value can be provided in second parameter. +* `optionList($option, $value = null)` Pass multiple options to executable. Value can be a string or array. + diff --git a/src/composer/vendor/consolidation/robo/docs/tasks/Vcs.md b/src/composer/vendor/consolidation/robo/docs/tasks/Vcs.md new file mode 100644 index 00000000..69465c0d --- /dev/null +++ b/src/composer/vendor/consolidation/robo/docs/tasks/Vcs.md @@ -0,0 +1,108 @@ +# Vcs Tasks +## GitStack + + +Runs Git commands in stack. You can use `stopOnFail()` to point that stack should be terminated on first fail. + +``` php +taskGitStack() + ->stopOnFail() + ->add('-A') + ->commit('adding everything') + ->push('origin','master') + ->tag('0.6.0') + ->push('origin','0.6.0') + ->run() + +$this->taskGitStack() + ->stopOnFail() + ->add('doc/*') + ->commit('doc updated') + ->push() + ->run(); +?> +``` + +* `cloneRepo($repo, $to = null)` Executes `git clone` +* `add($pattern)` Executes `git add` command with files to add pattern +* `commit($message, $options = null)` Executes `git commit` command with a message +* `pull($origin = null, $branch = null)` Executes `git pull` command. +* `push($origin = null, $branch = null)` Executes `git push` command +* `merge($branch)` Performs git merge +* `checkout($branch)` Executes `git checkout` command +* `tag($tag_name, $message = null)` Executes `git tag` command +* `executable($executable)` * `param string` $executable +* `exec($command)` * `param string|string[]` $command +* `stopOnFail($stopOnFail = null)` * `param bool` $stopOnFail +* `result($result)` +* `dir($dir)` Changes working directory of command +* `printed($arg)` Should command output be printed + +## HgStack + + +Runs hg commands in stack. You can use `stopOnFail()` to point that stack should be terminated on first fail. + +``` php +hgStack + ->cloneRepo('https://bitbucket.org/durin42/hgsubversion') + ->pull() + ->add() + ->commit('changed') + ->push() + ->tag('0.6.0') + ->push('0.6.0') + ->run(); +?> +``` + +* `cloneRepo($repo, $to = null)` Executes `hg clone` +* `add($include = null, $exclude = null)` Executes `hg add` command with files to add by pattern +* `commit($message, $options = null)` Executes `hg commit` command with a message +* `pull($branch = null)` Executes `hg pull` command. +* `push($branch = null)` Executes `hg push` command +* `merge($revision = null)` Performs hg merge +* `tag($tag_name, $message = null)` Executes `hg tag` command +* `executable($executable)` * `param string` $executable +* `exec($command)` * `param string|string[]` $command +* `stopOnFail($stopOnFail = null)` * `param bool` $stopOnFail +* `result($result)` +* `dir($dir)` Changes working directory of command +* `printed($arg)` Should command output be printed + +## SvnStack + + +Runs Svn commands in stack. You can use `stopOnFail()` to point that stack should be terminated on first fail. + +``` php +taskSvnStack() + ->checkout('http://svn.collab.net/repos/svn/trunk') + ->run() + +// alternatively +$this->_svnCheckout('http://svn.collab.net/repos/svn/trunk'); + +$this->taskSvnStack('username', 'password') + ->stopOnFail() + ->update() + ->add('doc/*') + ->commit('doc updated') + ->run(); +?> +``` + +* `update($path = null)` Updates `svn update` command +* `add($pattern = null)` Executes `svn add` command with files to add pattern +* `commit($message, $options = null)` Executes `svn commit` command with a message +* `checkout($branch)` Executes `svn checkout` command +* `executable($executable)` * `param string` $executable +* `exec($command)` * `param string|string[]` $command +* `stopOnFail($stopOnFail = null)` * `param bool` $stopOnFail +* `result($result)` +* `dir($dir)` Changes working directory of command +* `printed($arg)` Should command output be printed + diff --git a/src/composer/vendor/consolidation/robo/examples/RoboFile.php b/src/composer/vendor/consolidation/robo/examples/RoboFile.php new file mode 100644 index 00000000..8e057f6f --- /dev/null +++ b/src/composer/vendor/consolidation/robo/examples/RoboFile.php @@ -0,0 +1,425 @@ +taskWatch()->monitor(['composer.json', 'composer.lock'], function () { + $this->taskComposerUpdate()->run(); + })->run(); + } + + /** + * Demonstrates Robo input APIs. + */ + public function tryInput() + { + $answer = $this->ask('how are you?'); + $this->say('You are '.$answer); + $yes = $this->confirm('Do you want one more question?'); + if (!$yes) { + return Result::cancelled(); + } + $lang = $this->askDefault('what is your favorite scripting language?', 'PHP'); + $this->say($lang); + $pin = $this->askHidden('Ok, now tell your PIN code (it is hidden)'); + $this->yell('Ha-ha, your pin code is: '.$pin); + $this->say('Bye!'); + } + + /** + * Demonstrates parallel execution. + * + * @option $printed Print the output of each process. + * @option $error Include an extra process that fails. + */ + public function tryPara($options = ['printed' => false, 'error' => false]) + { + $dir = __DIR__; + $para = $this->taskParallelExec() + ->printed($options['printed']) + ->process("php $dir/tests/_data/parascript.php hey 4") + ->process("php $dir/tests/_data/parascript.php hoy 3") + ->process("php $dir/tests/_data/parascript.php gou 2") + ->process("php $dir/tests/_data/parascript.php die 1"); + if ($options['error']) { + $para->process("ls $dir/tests/_data/filenotfound"); + } + return $para->run(); + } + + /** + * Demonstrates Robo argument passing. + * + * @param string $a The first parameter. Required. + * @param string $b The second parameter. Optional. + */ + public function tryArgs($a, $b = 'default') + { + $this->say("The parameter a is $a and b is $b"); + } + + /** + * Demonstrate Robo variable argument passing. + * + * @param $a A list of commandline parameters. + */ + public function tryArrayArgs(array $a) + { + $this->say("The parameters passed are:\n" . var_export($a, true)); + } + + /** + * Demonstrate Robo boolean options. + * + * @param $opts The options. + * @option boolean $silent Supress output. + */ + public function tryOptbool($opts = ['silent|s' => false]) + { + if (!$opts['silent']) { + $this->say("Hello, world"); + } + } + + /** + * Demonstrate the use of the PHP built-in webserver. + */ + public function tryServer() + { + return $this->taskServer(8000) + ->dir('site') + ->arg('site/index.php') + ->run(); + } + + /** + * Demonstrate the use of the Robo open-browser task. + */ + public function tryOpenBrowser() + { + return $this->taskOpenBrowser([ + 'http://robo.li', + 'https://github.com/consolidation-org/Robo' + ])->run(); + } + + /** + * Demonstrate Robo error output and command failure. + */ + public function tryError() + { + return $this->taskExec('ls xyzzy' . date('U'))->dir('/tmp')->run(); + } + + /** + * Demonstrate Robo standard output and command success. + */ + public function trySuccess() + { + return $this->_exec('pwd'); + } + + /** + * @field-labels + * name: Name + * species: Species + * legs: Legs + * food: Favorite Food + * id: Id + * @return PropertyList + */ + public function tryInfo() + { + $outputData = [ + 'name' => 'fluffy', + 'species' => 'cat', + 'legs' => 4, + 'food' => 'salmon', + 'id' => 389245032, + ]; + + $data = new PropertyList($outputData); + + // Add a render function to transform cell data when the output + // format is a table, or similar. This allows us to add color + // information to the output without modifying the data cells when + // using yaml or json output formats. + $data->addRendererFunction( + // n.b. There is a fourth parameter $rowData that may be added here. + function ($key, $cellData, FormatterOptions $options) { + if ($key == 'name') { + return "$cellData"; + } + return $cellData; + } + ); + + return $data; + } + + /** + * Demonstrate Robo formatters. Default format is 'table'. + * + * @field-labels + * first: I + * second: II + * third: III + * @default-string-field second + * @usage try:formatters --format=yaml + * @usage try:formatters --format=csv + * @usage try:formatters --fields=first,third + * @usage try:formatters --fields=III,II + * @aliases tf + * + * @return \Consolidation\OutputFormatters\StructuredData\RowsOfFields + */ + public function tryFormatters($somthing = 'default', $options = ['format' => 'table', 'fields' => '']) + { + $outputData = [ + 'en' => [ 'first' => 'One', 'second' => 'Two', 'third' => 'Three' ], + 'de' => [ 'first' => 'Eins', 'second' => 'Zwei', 'third' => 'Drei' ], + 'jp' => [ 'first' => 'Ichi', 'second' => 'Ni', 'third' => 'San' ], + 'es' => [ 'first' => 'Uno', 'second' => 'Dos', 'third' => 'Tres' ], + ]; + return new RowsOfFields($outputData); + } + + /** + * Demonstrate an alter hook with an option + * + * @hook alter try:formatters + * @option $french Add a row with French numbers. + * @usage try:formatters --french + */ + public function alterFormatters($result, CommandData $commandData) + { + if ($commandData->input()->getOption('french')) { + $result['fr'] = [ 'first' => 'Un', 'second' => 'Deux', 'third' => 'Trois' ]; + } + + return $result; + } + + /** + * Demonstrate what happens when a command or a task + * throws an exception. Note that typically, Robo commands + * should return Result objects rather than throw exceptions. + */ + public function tryException($options = ['task' => false]) + { + if (!$options['task']) { + throw new RuntimeException('Command failed with an exception.'); + } + return new ExceptionTask('Task failed with an exception.'); + } + + /** + * Demonstrate deprecated task behavior. + * + * Demonstrate what happens when using a task that is created via + * direct instantiation, which omits initialization done by the + * container. Emits a warning message. + */ + public function tryDeprecated() + { + // Calling 'new' directly without manually setting + // up dependencies will result in a deprecation warning. + // @see RoboFile::trySuccess() + return (new \Robo\Task\Base\Exec('pwd'))->run(); + } + + /** + * Demonstrate the use of a collection builder to chain multiple tasks + * together into a collection, which is executed once constructed. + * + * For demonstration purposes only; this could, of course, be done + * with a single FilesystemStack. + */ + public function tryBuilder() + { + return $this->collectionBuilder() + ->taskFilesystemStack() + ->mkdir('a') + ->touch('a/a.txt') + ->taskFilesystemStack() + ->mkdir('a/b') + ->touch('a/b/b.txt') + ->taskFilesystemStack() + ->mkdir('a/b/c') + ->touch('a/b/c/c.txt') + ->run(); + } + + public function tryBuilderRollback() + { + // This example will create two builders, and add + // the first one as a child of the second in order + // to demonstrate nested rollbacks. + $collection = $this->collectionBuilder() + ->taskFilesystemStack() + ->mkdir('g') + ->touch('g/g.txt') + ->rollback( + $this->taskDeleteDir('g') + ) + ->taskFilesystemStack() + ->mkdir('g/h') + ->touch('g/h/h.txt') + ->taskFilesystemStack() + ->mkdir('g/h/i/c') + ->touch('g/h/i/i.txt'); + + return $this->collectionBuilder() + ->progressMessage('Start recursive collection') + ->addTask($collection) + ->progressMessage('Done with recursive collection') + ->taskExec('ls xyzzy' . date('U')) + ->dir('/tmp') + ->run(); + } + + public function tryWorkdir() + { + // This example works like tryBuilderRollback, + // but does equivalent operations using a working + // directory. The working directory is deleted on rollback + $collection = $this->collectionBuilder(); + + $workdir = $collection->workDir('w'); + + $collection + ->taskFilesystemStack() + ->touch("$workdir/g.txt") + ->taskFilesystemStack() + ->mkdir("$workdir/h") + ->touch("$workdir/h/h.txt") + ->taskFilesystemStack() + ->mkdir("$workdir/h/i/c") + ->touch("$workdir/h/i/i.txt"); + + return $this->collectionBuilder() + ->progressMessage('Start recursive collection') + ->addTask($collection) + ->progressMessage('Done with recursive collection') + ->taskExec('ls xyzzy' . date('U')) + ->dir('/tmp') + ->run(); + } + + /** + * Demonstrates Robo temporary directory usage. + */ + public function tryTmpDir() + { + // Set up a collection to add tasks to + $collection = $this->collectionBuilder(); + + // Get a temporary directory to work in. Note that we get a path + // back, but the directory is not created until the task runs. + $tmpPath = $collection->tmpDir(); + + $result = $collection + ->taskWriteToFile("$tmpPath/file.txt") + ->line('Example file') + ->run(); + + if (is_dir($tmpPath)) { + $this->say("The temporary directory at $tmpPath was not cleaned up after the collection completed."); + } else { + $this->say("The temporary directory at $tmpPath was automatically deleted."); + } + + return $result; + } + + /** + * Description + * @param $options + * @option delay Miliseconds delay + * @return type + */ + public function tryProgress($options = ['delay' => 500]) + { + $delay = $options['delay']; + $delayUntilProgressStart = \Robo\Robo::config()->get(\Robo\Config::PROGRESS_BAR_AUTO_DISPLAY_INTERVAL); + $this->say("Progress bar will display after $delayUntilProgressStart seconds of activity."); + + $processList = range(1, 10); + return $this->collectionBuilder() + ->taskForEach($processList) + ->iterationMessage('Processing {value}') + ->call( + function ($value) use($delay) { + // TaskForEach::call should only be used to do + // non-Robo operations. To use Robo tasks in an + // iterator, @see TaskForEach::withBuilder. + usleep($delay * 1000); // delay units: msec, usleep units: usec + } + ) + ->run(); + } + + public function tryIter() + { + $workdir = 'build/iter-example'; + $this->say("Creating sample direcories in $workdir."); + + $processList = ['cats', 'dogs', 'sheep', 'fish', 'horses', 'cows']; + return $this->collectionBuilder() + ->taskFilesystemStack() + ->mkdir($workdir) + ->taskCleanDir($workdir) + ->taskForEach($processList) + ->withBuilder( + function ($builder, $key, $value) use ($workdir) { + return $builder + ->taskFilesystemStack() + ->mkdir("$workdir/$value"); + } + ) + ->run(); + } +} + +class ExceptionTask extends \Robo\Task\BaseTask +{ + protected $message; + + public function __construct($message) + { + $this->message = $message; + } + + public function run() + { + throw new RuntimeException($this->message); + } +} diff --git a/src/composer/vendor/consolidation/robo/examples/robo.script b/src/composer/vendor/consolidation/robo/examples/robo.script new file mode 100755 index 00000000..bfec26a9 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/examples/robo.script @@ -0,0 +1,44 @@ +#!/usr/bin/env robo +say("This is a Robo script, $name"); + } +} diff --git a/src/composer/vendor/consolidation/robo/robo b/src/composer/vendor/consolidation/robo/robo new file mode 100755 index 00000000..ce4d9dfa --- /dev/null +++ b/src/composer/vendor/consolidation/robo/robo @@ -0,0 +1,21 @@ +#!/usr/bin/env php +execute($_SERVER['argv']); +exit($statusCode); diff --git a/src/composer/vendor/consolidation/robo/scripts/composer/ScriptHandler.php b/src/composer/vendor/consolidation/robo/scripts/composer/ScriptHandler.php new file mode 100644 index 00000000..ddf1111f --- /dev/null +++ b/src/composer/vendor/consolidation/robo/scripts/composer/ScriptHandler.php @@ -0,0 +1,58 @@ +exists('composer.lock')) { + return; + } + + $composerLockContents = file_get_contents('composer.lock'); + if (preg_match('#"php":.*(5\.6)#', $composerLockContents)) { + static::fixDependenciesFor55(); + } + } + + protected static function fixDependenciesFor55() + { + $fs = new Filesystem(); + $status = 0; + + $fs->remove('composer.lock'); + + // Composer has already read our composer.json file, so we will + // need to run in a new process to fix things up. + passthru('composer install --ansi', $status); + + // Don't continue with the initial 'composer install' command + exit($status); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Application.php b/src/composer/vendor/consolidation/robo/src/Application.php new file mode 100644 index 00000000..e6664b5d --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Application.php @@ -0,0 +1,56 @@ +getDefinition() + ->addOption( + new InputOption('--simulate', null, InputOption::VALUE_NONE, 'Run in simulated mode (show what would have happened).') + ); + $this->getDefinition() + ->addOption( + new InputOption('--progress-delay', null, InputOption::VALUE_REQUIRED, 'Number of seconds before progress bar is displayed in long-running task collections. Default: 2s.', Config::DEFAULT_PROGRESS_DELAY) + ); + } + + /** + * @param string $roboFile + * @param string $roboClass + */ + public function addInitRoboFileCommand($roboFile, $roboClass) + { + $createRoboFile = new Command('init'); + $createRoboFile->setDescription("Intitalizes basic RoboFile in current dir"); + $createRoboFile->setCode(function () use ($roboClass, $roboFile) { + $output = Robo::output(); + $output->writeln(" ~~~ Welcome to Robo! ~~~~ "); + $output->writeln(" ". basename($roboFile) ." will be created in the current directory "); + file_put_contents( + $roboFile, + 'writeln(" Edit this file to add your commands! "); + }); + $this->add($createRoboFile); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Collection/CallableTask.php b/src/composer/vendor/consolidation/robo/src/Collection/CallableTask.php new file mode 100644 index 00000000..8ae3a330 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Collection/CallableTask.php @@ -0,0 +1,53 @@ +fn = $fn; + $this->reference = $reference; + } + + /** + * @return \Robo\Result + */ + public function run() + { + $result = call_user_func($this->fn); + // If the function returns no result, then count it + // as a success. + if (!isset($result)) { + $result = Result::success($this->reference); + } + // If the function returns a result, it must either return + // a \Robo\Result or an exit code. In the later case, we + // convert it to a \Robo\Result. + if (!$result instanceof Result) { + $result = new Result($this->reference, $result); + } + + return $result; + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Collection/Collection.php b/src/composer/vendor/consolidation/robo/src/Collection/Collection.php new file mode 100644 index 00000000..5458c8a5 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Collection/Collection.php @@ -0,0 +1,683 @@ +progressIndicator) { + return; + } + return $this->progressIndicator->setProgressBarAutoDisplayInterval($interval); + } + + /** + * {@inheritdoc} + */ + public function add(TaskInterface $task, $name = self::UNNAMEDTASK) + { + $task = new CompletionWrapper($this, $task); + $this->addToTaskList($name, $task); + return $this; + } + + /** + * {@inheritdoc} + */ + public function addCode(callable $code, $name = self::UNNAMEDTASK) + { + return $this->add(new CallableTask($code, $this), $name); + } + + /** + * {@inheritdoc} + */ + public function addIterable($iterable, callable $code) + { + $callbackTask = (new IterationTask($iterable, $code, $this))->inflect($this); + return $this->add($callbackTask); + } + + /** + * {@inheritdoc} + */ + public function rollback(TaskInterface $rollbackTask) + { + // Rollback tasks always try as hard as they can, and never report failures. + $rollbackTask = $this->ignoreErrorsTaskWrapper($rollbackTask); + return $this->wrapAndRegisterRollback($rollbackTask); + } + + /** + * {@inheritdoc} + */ + public function rollbackCode(callable $rollbackCode) + { + // Rollback tasks always try as hard as they can, and never report failures. + $rollbackTask = $this->ignoreErrorsCodeWrapper($rollbackCode); + return $this->wrapAndRegisterRollback($rollbackTask); + } + + /** + * {@inheritdoc} + */ + public function completion(TaskInterface $completionTask) + { + $collection = $this; + $completionRegistrationTask = new CallableTask( + function () use ($collection, $completionTask) { + + $collection->registerCompletion($completionTask); + }, + $this + ); + $this->addToTaskList(self::UNNAMEDTASK, $completionRegistrationTask); + return $this; + } + + /** + * {@inheritdoc} + */ + public function completionCode(callable $completionTask) + { + $completionTask = new CallableTask($completionTask, $this); + return $this->completion($completionTask); + } + + /** + * {@inheritdoc} + */ + public function before($name, $task, $nameOfTaskToAdd = self::UNNAMEDTASK) + { + return $this->addBeforeOrAfter(__FUNCTION__, $name, $task, $nameOfTaskToAdd); + } + + /** + * {@inheritdoc} + */ + public function after($name, $task, $nameOfTaskToAdd = self::UNNAMEDTASK) + { + return $this->addBeforeOrAfter(__FUNCTION__, $name, $task, $nameOfTaskToAdd); + } + + /** + * {@inheritdoc} + */ + public function progressMessage($text, $context = [], $level = LogLevel::NOTICE) + { + $context += ['name' => 'Progress']; + $context += TaskInfo::getTaskContext($this); + return $this->addCode( + function () use ($level, $text, $context) { + $this->printTaskOutput($level, $text, $context); + } + ); + } + + /** + * @param \Robo\Contract\TaskInterface $rollbackTask + * + * @return $this + */ + protected function wrapAndRegisterRollback(TaskInterface $rollbackTask) + { + $collection = $this; + $rollbackRegistrationTask = new CallableTask( + function () use ($collection, $rollbackTask) { + $collection->registerRollback($rollbackTask); + }, + $this + ); + $this->addToTaskList(self::UNNAMEDTASK, $rollbackRegistrationTask); + return $this; + } + + /** + * Add either a 'before' or 'after' function or task. + * + * @param string $method + * @param string $name + * @param callable|TaskInterface $task + * @param string $nameOfTaskToAdd + * + * @return $this + */ + protected function addBeforeOrAfter($method, $name, $task, $nameOfTaskToAdd) + { + if (is_callable($task)) { + $task = new CallableTask($task, $this); + } + $existingTask = $this->namedTask($name); + $fn = [$existingTask, $method]; + call_user_func($fn, $task, $nameOfTaskToAdd); + return $this; + } + + /** + * Wrap the provided task in a wrapper that will ignore + * any errors or exceptions that may be produced. This + * is useful, for example, in adding optional cleanup tasks + * at the beginning of a task collection, to remove previous + * results which may or may not exist. + * + * TODO: Provide some way to specify which sort of errors + * are ignored, so that 'file not found' may be ignored, + * but 'permission denied' reported? + * + * @param \Robo\Contract\TaskInterface $task + * + * @return \Robo\Collection\CallableTask + */ + public function ignoreErrorsTaskWrapper(TaskInterface $task) + { + // If the task is a stack-based task, then tell it + // to try to run all of its operations, even if some + // of them fail. + if ($task instanceof StackBasedTask) { + $task->stopOnFail(false); + } + $ignoreErrorsInTask = function () use ($task) { + $data = []; + try { + $result = $this->runSubtask($task); + $message = $result->getMessage(); + $data = $result->getData(); + $data['exitcode'] = $result->getExitCode(); + } catch (\Exception $e) { + $message = $e->getMessage(); + } + + return Result::success($task, $message, $data); + }; + // Wrap our ignore errors callable in a task. + return new CallableTask($ignoreErrorsInTask, $this); + } + + /** + * @param callable $task + * + * @return \Robo\Collection\CallableTask + */ + public function ignoreErrorsCodeWrapper(callable $task) + { + return $this->ignoreErrorsTaskWrapper(new CallableTask($task, $this)); + } + + /** + * Return the list of task names added to this collection. + * + * @return array + */ + public function taskNames() + { + return array_keys($this->taskList); + } + + /** + * Test to see if a specified task name exists. + * n.b. before() and after() require that the named + * task exist; use this function to test first, if + * unsure. + * + * @param string $name + * + * @return bool + */ + public function hasTask($name) + { + return array_key_exists($name, $this->taskList); + } + + /** + * Find an existing named task. + * + * @param string $name + * The name of the task to insert before. The named task MUST exist. + * + * @return Element + * The task group for the named task. Generally this is only + * used to call 'before()' and 'after()'. + */ + protected function namedTask($name) + { + if (!$this->hasTask($name)) { + throw new \RuntimeException("Could not find task named $name"); + } + return $this->taskList[$name]; + } + + /** + * Add a list of tasks to our task collection. + * + * @param TaskInterface[] $tasks + * An array of tasks to run with rollback protection + * + * @return $this + */ + public function addTaskList(array $tasks) + { + foreach ($tasks as $name => $task) { + $this->add($task, $name); + } + return $this; + } + + /** + * Add the provided task to our task list. + * + * @param string $name + * @param \Robo\Contract\TaskInterface $task + * + * @return \Robo\Collection\Collection + */ + protected function addToTaskList($name, TaskInterface $task) + { + // All tasks are stored in a task group so that we have a place + // to hang 'before' and 'after' tasks. + $taskGroup = new Element($task); + return $this->addCollectionElementToTaskList($name, $taskGroup); + } + + /** + * @param int|string $name + * @param \Robo\Collection\Element $taskGroup + * + * @return $this + */ + protected function addCollectionElementToTaskList($name, Element $taskGroup) + { + // If a task name is not provided, then we'll let php pick + // the array index. + if (Result::isUnnamed($name)) { + $this->taskList[] = $taskGroup; + return $this; + } + // If we are replacing an existing task with the + // same name, ensure that our new task is added to + // the end. + $this->taskList[$name] = $taskGroup; + return $this; + } + + /** + * Set the parent collection. This is necessary so that nested + * collections' rollback and completion tasks can be added to the + * top-level collection, ensuring that the rollbacks for a collection + * will run if any later task fails. + * + * @param \Robo\Collection\NestedCollectionInterface $parentCollection + * + * @return $this + */ + public function setParentCollection(NestedCollectionInterface $parentCollection) + { + $this->parentCollection = $parentCollection; + return $this; + } + + /** + * Get the appropriate parent collection to use + * + * @return CollectionInterface + */ + public function getParentCollection() + { + return $this->parentCollection ? $this->parentCollection : $this; + } + + /** + * Register a rollback task to run if there is any failure. + * + * Clients are free to add tasks to the rollback stack as + * desired; however, usually it is preferable to call + * Collection::rollback() instead. With that function, + * the rollback function will only be called if all of the + * tasks added before it complete successfully, AND some later + * task fails. + * + * One example of a good use-case for registering a callback + * function directly is to add a task that sends notification + * when a task fails. + * + * @param TaskInterface $rollbackTask + * The rollback task to run on failure. + */ + public function registerRollback(TaskInterface $rollbackTask) + { + if ($this->parentCollection) { + return $this->parentCollection->registerRollback($rollbackTask); + } + if ($rollbackTask) { + $this->rollbackStack[] = $rollbackTask; + } + } + + /** + * Register a completion task to run once all other tasks finish. + * Completion tasks run whether or not a rollback operation was + * triggered. They do not trigger rollbacks if they fail. + * + * The typical use-case for a completion function is to clean up + * temporary objects (e.g. temporary folders). The preferred + * way to do that, though, is to use Temporary::wrap(). + * + * On failures, completion tasks will run after all rollback tasks. + * If one task collection is nested inside another task collection, + * then the nested collection's completion tasks will run as soon as + * the nested task completes; they are not deferred to the end of + * the containing collection's execution. + * + * @param TaskInterface $completionTask + * The completion task to run at the end of all other operations. + */ + public function registerCompletion(TaskInterface $completionTask) + { + if ($this->parentCollection) { + return $this->parentCollection->registerCompletion($completionTask); + } + if ($completionTask) { + // Completion tasks always try as hard as they can, and never report failures. + $completionTask = $this->ignoreErrorsTaskWrapper($completionTask); + $this->completionStack[] = $completionTask; + } + } + + /** + * Return the count of steps in this collection + * + * @return int + */ + public function progressIndicatorSteps() + { + $steps = 0; + foreach ($this->taskList as $name => $taskGroup) { + $steps += $taskGroup->progressIndicatorSteps(); + } + return $steps; + } + + /** + * A Collection of tasks can provide a command via `getCommand()` + * if it contains a single task, and that task implements CommandInterface. + * + * @return string + * + * @throws \Robo\Exception\TaskException + */ + public function getCommand() + { + if (empty($this->taskList)) { + return ''; + } + + if (count($this->taskList) > 1) { + // TODO: We could potentially iterate over the items in the collection + // and concatenate the result of getCommand() from each one, and fail + // only if we encounter a command that is not a CommandInterface. + throw new TaskException($this, "getCommand() does not work on arbitrary collections of tasks."); + } + + $taskElement = reset($this->taskList); + $task = $taskElement->getTask(); + $task = ($task instanceof WrappedTaskInterface) ? $task->original() : $task; + if ($task instanceof CommandInterface) { + return $task->getCommand(); + } + + throw new TaskException($task, get_class($task) . " does not implement CommandInterface, so can't be used to provide a command"); + } + + /** + * Run our tasks, and roll back if necessary. + * + * @return \Robo\Result + */ + public function run() + { + $result = $this->runWithoutCompletion(); + $this->complete(); + return $result; + } + + /** + * @return \Robo\Result + */ + private function runWithoutCompletion() + { + $result = Result::success($this); + + if (empty($this->taskList)) { + return $result; + } + + $this->startProgressIndicator(); + if ($result->wasSuccessful()) { + foreach ($this->taskList as $name => $taskGroup) { + $taskList = $taskGroup->getTaskList(); + $result = $this->runTaskList($name, $taskList, $result); + if (!$result->wasSuccessful()) { + $this->fail(); + return $result; + } + } + $this->taskList = []; + } + $this->stopProgressIndicator(); + $result['time'] = $this->getExecutionTime(); + + return $result; + } + + /** + * Run every task in a list, but only up to the first failure. + * Return the failing result, or success if all tasks run. + * + * @param string $name + * @param TaskInterface[] $taskList + * @param \Robo\Result $result + * + * @return \Robo\Result + * + * @throws \Robo\Exception\TaskExitException + */ + private function runTaskList($name, array $taskList, Result $result) + { + try { + foreach ($taskList as $taskName => $task) { + $taskResult = $this->runSubtask($task); + $this->advanceProgressIndicator(); + // If the current task returns an error code, then stop + // execution and signal a rollback. + if (!$taskResult->wasSuccessful()) { + return $taskResult; + } + // We accumulate our results into a field so that tasks that + // have a reference to the collection may examine and modify + // the incremental results, if they wish. + $key = Result::isUnnamed($taskName) ? $name : $taskName; + $result->accumulate($key, $taskResult); + } + } catch (TaskExitException $exitException) { + $this->fail(); + throw $exitException; + } catch (\Exception $e) { + // Tasks typically should not throw, but if one does, we will + // convert it into an error and roll back. + return Result::fromException($task, $e, $result->getData()); + } + return $result; + } + + /** + * Force the rollback functions to run + * + * @return $this + */ + public function fail() + { + $this->disableProgressIndicator(); + $this->runRollbackTasks(); + $this->complete(); + return $this; + } + + /** + * Force the completion functions to run + * + * @return $this + */ + public function complete() + { + $this->detatchProgressIndicator(); + $this->runTaskListIgnoringFailures($this->completionStack); + $this->reset(); + return $this; + } + + /** + * Reset this collection, removing all tasks. + * + * @return $this + */ + public function reset() + { + $this->taskList = []; + $this->completionStack = []; + $this->rollbackStack = []; + return $this; + } + + /** + * Run all of our rollback tasks. + * + * Note that Collection does not implement RollbackInterface, but + * it may still be used as a task inside another task collection + * (i.e. you can nest task collections, if desired). + */ + protected function runRollbackTasks() + { + $this->runTaskListIgnoringFailures($this->rollbackStack); + // Erase our rollback stack once we have finished rolling + // everything back. This will allow us to potentially use + // a command collection more than once (e.g. to retry a + // failed operation after doing some error recovery). + $this->rollbackStack = []; + } + + /** + * @param TaskInterface|NestedCollectionInterface|WrappedTaskInterface $task + * + * @return \Robo\Result + */ + protected function runSubtask($task) + { + $original = ($task instanceof WrappedTaskInterface) ? $task->original() : $task; + $this->setParentCollectionForTask($original, $this->getParentCollection()); + if ($original instanceof InflectionInterface) { + $original->inflect($this); + } + $taskResult = $task->run(); + return $taskResult; + } + + /** + * @param TaskInterface|NestedCollectionInterface|WrappedTaskInterface $task + * @param $parentCollection + */ + protected function setParentCollectionForTask($task, $parentCollection) + { + if ($task instanceof NestedCollectionInterface) { + $task->setParentCollection($parentCollection); + } + } + + /** + * Run all of the tasks in a provided list, ignoring failures. + * This is used to roll back or complete. + * + * @param TaskInterface[] $taskList + */ + protected function runTaskListIgnoringFailures(array $taskList) + { + foreach ($taskList as $task) { + try { + $this->runSubtask($task); + } catch (\Exception $e) { + // Ignore rollback failures. + } + } + } + + /** + * Give all of our tasks to the provided collection builder. + * + * @param CollectionBuilder $builder + */ + public function transferTasks($builder) + { + foreach ($this->taskList as $name => $taskGroup) { + // TODO: We are abandoning all of our before and after tasks here. + // At the moment, transferTasks is only called under conditions where + // there will be none of these, but care should be taken if that changes. + $task = $taskGroup->getTask(); + $builder->addTaskToCollection($task); + } + $this->reset(); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Collection/CollectionBuilder.php b/src/composer/vendor/consolidation/robo/src/Collection/CollectionBuilder.php new file mode 100644 index 00000000..9b4d5180 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Collection/CollectionBuilder.php @@ -0,0 +1,475 @@ +collectionBuilder() + * ->taskFilesystemStack() + * ->mkdir('g') + * ->touch('g/g.txt') + * ->rollback( + * $this->taskDeleteDir('g') + * ) + * ->taskFilesystemStack() + * ->mkdir('g/h') + * ->touch('g/h/h.txt') + * ->taskFilesystemStack() + * ->mkdir('g/h/i/c') + * ->touch('g/h/i/i.txt') + * ->run() + * ?> + * + * In the example above, the `taskDeleteDir` will be called if + * ``` + */ +class CollectionBuilder extends BaseTask implements NestedCollectionInterface, WrappedTaskInterface, CommandInterface +{ + /** + * @var \Robo\Tasks + */ + protected $commandFile; + + /** + * @var CollectionInterface + */ + protected $collection; + + /** + * @var TaskInterface + */ + protected $currentTask; + + /** + * @var bool + */ + protected $simulated; + + /** + * @param \Robo\Tasks $commandFile + */ + public function __construct($commandFile) + { + $this->commandFile = $commandFile; + } + + /** + * @param bool $simulated + * + * @return $this + */ + public function simulated($simulated = true) + { + $this->simulated = $simulated; + return $this; + } + + /** + * @return bool + */ + public function isSimulated() + { + if (!isset($this->simulated)) { + $this->simulated = $this->getConfig()->get(Config::SIMULATE); + } + return $this->simulated; + } + + /** + * Create a temporary directory to work in. When the collection + * completes or rolls back, the temporary directory will be deleted. + * Returns the path to the location where the directory will be + * created. + * + * @param string $prefix + * @param string $base + * @param bool $includeRandomPart + * + * @return string + */ + public function tmpDir($prefix = 'tmp', $base = '', $includeRandomPart = true) + { + // n.b. Any task that the builder is asked to create is + // automatically added to the builder's collection, and + // wrapped in the builder object. Therefore, the result + // of any call to `taskFoo()` from within the builder will + // always be `$this`. + return $this->taskTmpDir($prefix, $base, $includeRandomPart)->getPath(); + } + + /** + * Create a working directory to hold results. A temporary directory + * is first created to hold the intermediate results. After the + * builder finishes, the work directory is moved into its final location; + * any results already in place will be moved out of the way and + * then deleted. + * + * @param string $finalDestination The path where the working directory + * will be moved once the task collection completes. + * + * @return string + */ + public function workDir($finalDestination) + { + // Creating the work dir task in this context adds it to our task collection. + return $this->taskWorkDir($finalDestination)->getPath(); + } + + public function addTask(TaskInterface $task) + { + $this->getCollection()->add($task); + return $this; + } + + public function addCode(callable $code) + { + $this->getCollection()->addCode($code); + return $this; + } + + /** + * Add a list of tasks to our task collection. + * + * @param TaskInterface[] $tasks + * An array of tasks to run with rollback protection + * + * @return $this + */ + public function addTaskList(array $tasks) + { + $this->getCollection()->addTaskList($tasks); + return $this; + } + + public function rollback(TaskInterface $task) + { + // Ensure that we have a collection if we are going to add + // a rollback function. + $this->getCollection()->rollback($task); + return $this; + } + + public function rollbackCode(callable $rollbackCode) + { + $this->getCollection()->rollbackCode($rollbackCode); + return $this; + } + + public function completion(TaskInterface $task) + { + $this->getCollection()->completion($task); + return $this; + } + + public function completionCode(callable $completionCode) + { + $this->getCollection()->completionCode($completionCode); + return $this; + } + + /** + * @param string $text + * @param array $context + * @param string $level + * + * @return $this + */ + public function progressMessage($text, $context = [], $level = LogLevel::NOTICE) + { + $this->getCollection()->progressMessage($text, $context, $level); + return $this; + } + + /** + * @param \Robo\Collection\NestedCollectionInterface $parentCollection + * + * @return $this + */ + public function setParentCollection(NestedCollectionInterface $parentCollection) + { + $this->getCollection()->setParentCollection($parentCollection); + return $this; + } + + /** + * Called by the factory method of each task; adds the current + * task to the task builder. + * + * TODO: protected + * + * @param TaskInterface $task + * + * @return $this + */ + public function addTaskToCollection($task) + { + // Postpone creation of the collection until the second time + // we are called. At that time, $this->currentTask will already + // be populated. We call 'getCollection()' so that it will + // create the collection and add the current task to it. + // Note, however, that if our only tasks implements NestedCollectionInterface, + // then we should force this builder to use a collection. + if (!$this->collection && (isset($this->currentTask) || ($task instanceof NestedCollectionInterface))) { + $this->getCollection(); + } + $this->currentTask = $task; + if ($this->collection) { + $this->collection->add($task); + } + return $this; + } + + /** + * Return the current task for this collection builder. + * TODO: Not needed? + * + * @return \Robo\Contract\TaskInterface + */ + public function getCollectionBuilderCurrentTask() + { + return $this->currentTask; + } + + /** + * Create a new builder with its own task collection + * + * @return CollectionBuilder + */ + public function newBuilder() + { + $collectionBuilder = new self($this->commandFile); + $collectionBuilder->inflect($this); + $collectionBuilder->simulated($this->isSimulated()); + return $collectionBuilder; + } + + /** + * Calling the task builder with methods of the current + * task calls through to that method of the task. + * + * There is extra complexity in this function that could be + * simplified if we attached the 'LoadAllTasks' and custom tasks + * to the collection builder instead of the RoboFile. While that + * change would be a better design overall, it would require that + * the user do a lot more work to set up and use custom tasks. + * We therefore take on some additional complexity here in order + * to allow users to maintain their tasks in their RoboFile, which + * is much more convenient. + * + * Calls to $this->collectionBuilder()->taskFoo() cannot be made + * directly because all of the task methods are protected. These + * calls will therefore end up here. If the method name begins + * with 'task', then it is eligible to be used with the builder. + * + * When we call getBuiltTask, below, it will use the builder attached + * to the commandfile to build the task. However, this is not what we + * want: the task needs to be built from THIS collection builder, so that + * it will be affected by whatever state is active in this builder. + * To do this, we have two choices: 1) save and restore the builder + * in the commandfile, or 2) clone the commandfile and set this builder + * on the copy. 1) is vulnerable to failure in multithreaded environments + * (currently not supported), while 2) might cause confusion if there + * is shared state maintained in the commandfile, which is in the + * domain of the user. + * + * Note that even though we are setting up the commandFile to + * use this builder, getBuiltTask always creates a new builder + * (which is constructed using all of the settings from the + * commandFile's builder), and the new task is added to that. + * We therefore need to transfer the newly built task into this + * builder. The temporary builder is discarded. + * + * @param string $fn + * @param array $args + * + * @return $this|mixed + */ + public function __call($fn, $args) + { + if (preg_match('#^task[A-Z]#', $fn) && (method_exists($this->commandFile, 'getBuiltTask'))) { + $saveBuilder = $this->commandFile->getBuilder(); + $this->commandFile->setBuilder($this); + $temporaryBuilder = $this->commandFile->getBuiltTask($fn, $args); + $this->commandFile->setBuilder($saveBuilder); + if (!$temporaryBuilder) { + throw new \BadMethodCallException("No such method $fn: task does not exist in " . get_class($this->commandFile)); + } + $temporaryBuilder->getCollection()->transferTasks($this); + return $this; + } + if (!isset($this->currentTask)) { + throw new \BadMethodCallException("No such method $fn: current task undefined in collection builder."); + } + // If the method called is a method of the current task, + // then call through to the current task's setter method. + $result = call_user_func_array([$this->currentTask, $fn], $args); + + // If something other than a setter method is called, then return its result. + $currentTask = ($this->currentTask instanceof WrappedTaskInterface) ? $this->currentTask->original() : $this->currentTask; + if (isset($result) && ($result !== $currentTask)) { + return $result; + } + + return $this; + } + + /** + * Construct the desired task and add it to this builder. + * + * @param string|object $name + * @param array $args + * + * @return \Robo\Collection\CollectionBuilder + */ + public function build($name, $args) + { + $reflection = new ReflectionClass($name); + $task = $reflection->newInstanceArgs($args); + if (!$task) { + throw new RuntimeException("Can not construct task $name"); + } + $task = $this->fixTask($task, $args); + return $this->addTaskToCollection($task); + } + + /** + * @param InflectionInterface $task + * @param array $args + * + * @return \Robo\Collection\CompletionWrapper|\Robo\Task\Simulator + */ + protected function fixTask($task, $args) + { + $task->inflect($this); + if ($task instanceof BuilderAwareInterface) { + $task->setBuilder($this); + } + + // Do not wrap our wrappers. + if ($task instanceof CompletionWrapper || $task instanceof Simulator) { + return $task; + } + + // Remember whether or not this is a task before + // it gets wrapped in any decorator. + $isTask = $task instanceof TaskInterface; + $isCollection = $task instanceof NestedCollectionInterface; + + // If the task implements CompletionInterface, ensure + // that its 'complete' method is called when the application + // terminates -- but only if its 'run' method is called + // first. If the task is added to a collection, then the + // task will be unwrapped via its `original` method, and + // it will be re-wrapped with a new completion wrapper for + // its new collection. + if ($task instanceof CompletionInterface) { + $task = new CompletionWrapper(Temporary::getCollection(), $task); + } + + // If we are in simulated mode, then wrap any task in + // a TaskSimulator. + if ($isTask && !$isCollection && ($this->isSimulated())) { + $task = new \Robo\Task\Simulator($task, $args); + $task->inflect($this); + } + + return $task; + } + + /** + * When we run the collection builder, run everything in the collection. + * + * @return \Robo\Result + */ + public function run() + { + $this->startTimer(); + $result = $this->runTasks(); + $this->stopTimer(); + $result['time'] = $this->getExecutionTime(); + return $result; + } + + /** + * If there is a single task, run it; if there is a collection, run + * all of its tasks. + * + * @return \Robo\Result + */ + protected function runTasks() + { + if (!$this->collection && $this->currentTask) { + return $this->currentTask->run(); + } + return $this->getCollection()->run(); + } + + /** + * @return string + */ + public function getCommand() + { + if (!$this->collection && $this->currentTask) { + $task = $this->currentTask; + $task = ($task instanceof WrappedTaskInterface) ? $task->original() : $task; + if ($task instanceof CommandInterface) { + return $task->getCommand(); + } + } + + return $this->getCollection()->getCommand(); + } + + /** + * @return \Robo\Collection\Collection + */ + public function original() + { + return $this->getCollection(); + } + + /** + * Return the collection of tasks associated with this builder. + * + * @return CollectionInterface + */ + public function getCollection() + { + if (!isset($this->collection)) { + $this->collection = new Collection(); + $this->collection->inflect($this); + $this->collection->setProgressBarAutoDisplayInterval($this->getConfig()->get(Config::PROGRESS_BAR_AUTO_DISPLAY_INTERVAL)); + + if (isset($this->currentTask)) { + $this->collection->add($this->currentTask); + } + } + return $this->collection; + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Collection/CollectionInterface.php b/src/composer/vendor/consolidation/robo/src/Collection/CollectionInterface.php new file mode 100644 index 00000000..b3a34f4e --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Collection/CollectionInterface.php @@ -0,0 +1,150 @@ +run(); + } catch (\Exception $e) { + return Result::fromException($result, $e); + } + } + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Collection/CompletionWrapper.php b/src/composer/vendor/consolidation/robo/src/Collection/CompletionWrapper.php new file mode 100644 index 00000000..3e81bd91 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Collection/CompletionWrapper.php @@ -0,0 +1,106 @@ +collection = $collection; + $this->task = ($task instanceof WrappedTaskInterface) ? $task->original() : $task; + $this->rollbackTask = $rollbackTask; + } + + /** + * {@inheritdoc} + */ + public function original() + { + return $this->task; + } + + /** + * Before running this task, register its rollback and completion + * handlers on its collection. The reason this class exists is to + * defer registration of rollback and completion tasks until 'run()' time. + * + * @return \Robo\Result + */ + public function run() + { + if ($this->rollbackTask) { + $this->collection->registerRollback($this->rollbackTask); + } + if ($this->task instanceof RollbackInterface) { + $this->collection->registerRollback(new CallableTask([$this->task, 'rollback'], $this->task)); + } + if ($this->task instanceof CompletionInterface) { + $this->collection->registerCompletion(new CallableTask([$this->task, 'complete'], $this->task)); + } + + return $this->task->run(); + } + + /** + * Make this wrapper object act like the class it wraps. + * + * @param string $function + * @param array $args + * + * @return mixed + */ + public function __call($function, $args) + { + return call_user_func_array(array($this->task, $function), $args); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Collection/Element.php b/src/composer/vendor/consolidation/robo/src/Collection/Element.php new file mode 100644 index 00000000..b67b56bb --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Collection/Element.php @@ -0,0 +1,116 @@ +task = $task; + } + + /** + * @param mixed $before + * @param string $name + */ + public function before($before, $name) + { + if ($name) { + $this->before[$name] = $before; + } else { + $this->before[] = $before; + } + } + + /** + * @param mixed $after + * @param string $name + */ + public function after($after, $name) + { + if ($name) { + $this->after[$name] = $after; + } else { + $this->after[] = $after; + } + } + + /** + * @return array + */ + public function getBefore() + { + return $this->before; + } + + /** + * @return array + */ + public function getAfter() + { + return $this->after; + } + + /** + * @return \Robo\Contract\TaskInterface + */ + public function getTask() + { + return $this->task; + } + + /** + * @return array + */ + public function getTaskList() + { + return array_merge($this->getBefore(), [$this->getTask()], $this->getAfter()); + } + + /** + * @return int + */ + public function progressIndicatorSteps() + { + $steps = 0; + foreach ($this->getTaskList() as $task) { + if ($task instanceof WrappedTaskInterface) { + $task = $task->original(); + } + // If the task is a ProgressIndicatorAwareInterface, then it + // will advance the progress indicator a number of times. + if ($task instanceof ProgressIndicatorAwareInterface) { + $steps += $task->progressIndicatorSteps(); + } + // We also advance the progress indicator once regardless + // of whether it is progress-indicator aware or not. + $steps++; + } + return $steps; + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Collection/NestedCollectionInterface.php b/src/composer/vendor/consolidation/robo/src/Collection/NestedCollectionInterface.php new file mode 100644 index 00000000..73d26282 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Collection/NestedCollectionInterface.php @@ -0,0 +1,15 @@ +iterable = $iterable; + } + + /** + * @param string $message + * @param array $context + * + * @return $this + */ + public function iterationMessage($message, $context = []) + { + $this->message = $message; + $this->context = $context + ['name' => 'Progress']; + return $this; + } + + /** + * @param int|string $key + * @param mixed $value + */ + protected function showIterationMessage($key, $value) + { + if ($this->message) { + $context = ['key' => $key, 'value' => $value]; + $context += $this->context; + $context += TaskInfo::getTaskContext($this); + $this->printTaskInfo($this->message, $context); + } + } + + /** + * @param callable $fn + * + * @return $this + */ + public function withEachKeyValueCall(callable $fn) + { + $this->functionStack[] = $fn; + return $this; + } + + /** + * @param callable $fn + * + * @return \Robo\Collection\TaskForEach + */ + public function call(callable $fn) + { + return $this->withEachKeyValueCall( + function ($key, $value) use ($fn) { + return call_user_func($fn, $value); + } + ); + } + + /** + * @param callable $fn + * + * @return \Robo\Collection\TaskForEach + */ + public function withBuilder(callable $fn) + { + $this->countingStack[] = + function ($key, $value) use ($fn) { + // Create a new builder for every iteration + $builder = $this->collectionBuilder(); + // The user function should build task operations using + // the $key / $value parameters; we will call run() on + // the builder thus constructed. + call_user_func($fn, $builder, $key, $value); + return $builder->getCollection()->progressIndicatorSteps(); + }; + return $this->withEachKeyValueCall( + function ($key, $value) use ($fn) { + // Create a new builder for every iteration + $builder = $this->collectionBuilder() + ->setParentCollection($this->parentCollection); + // The user function should build task operations using + // the $key / $value parameters; we will call run() on + // the builder thus constructed. + call_user_func($fn, $builder, $key, $value); + return $builder->run(); + } + ); + } + + /** + * {@inheritdoc} + */ + public function setParentCollection(NestedCollectionInterface $parentCollection) + { + $this->parentCollection = $parentCollection; + return $this; + } + + /** + * {@inheritdoc} + */ + public function progressIndicatorSteps() + { + $multiplier = count($this->functionStack); + if (!empty($this->countingStack)) { + $value = reset($this->iterable); + $key = key($this->iterable); + foreach ($this->countingStack as $fn) { + $multiplier += call_user_func($fn, $key, $value); + } + } + return count($this->iterable) * $multiplier; + } + + /** + * {@inheritdoc} + */ + public function run() + { + $finalResult = Result::success($this); + $this->startProgressIndicator(); + foreach ($this->iterable as $key => $value) { + $this->showIterationMessage($key, $value); + try { + foreach ($this->functionStack as $fn) { + $result = call_user_func($fn, $key, $value); + $this->advanceProgressIndicator(); + if (!isset($result)) { + $result = Result::success($this); + } + // If the function returns a result, it must either return + // a \Robo\Result or an exit code. In the later case, we + // convert it to a \Robo\Result. + if (!$result instanceof Result) { + $result = new Result($this, $result); + } + if (!$result->wasSuccessful()) { + return $result; + } + $finalResult = $result->merge($finalResult); + } + } catch (\Exception $e) { + return Result::fromException($result, $e); + } + } + $this->stopProgressIndicator(); + return $finalResult; + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Collection/Temporary.php b/src/composer/vendor/consolidation/robo/src/Collection/Temporary.php new file mode 100644 index 00000000..b179acab --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Collection/Temporary.php @@ -0,0 +1,59 @@ +get('collection'); + register_shutdown_function(function () { + static::complete(); + }); + } + + return static::$collection; + } + + /** + * Call the complete method of all of the registered objects. + */ + public static function complete() + { + // Run the collection of tasks. This will also run the + // completion tasks. + $collection = static::getCollection(); + $collection->run(); + // Make sure that our completion functions do not run twice. + $collection->reset(); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Collection/loadTasks.php b/src/composer/vendor/consolidation/robo/src/Collection/loadTasks.php new file mode 100644 index 00000000..03f68823 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Collection/loadTasks.php @@ -0,0 +1,17 @@ +task(TaskForEach::class, $collection); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Common/BuilderAwareTrait.php b/src/composer/vendor/consolidation/robo/src/Common/BuilderAwareTrait.php new file mode 100644 index 00000000..5a7b6533 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Common/BuilderAwareTrait.php @@ -0,0 +1,46 @@ +builder = $builder; + + return $this; + } + + /** + * @see \Robo\Contract\BuilderAwareInterface::getBuilder() + * + * @return \Robo\Collection\CollectionBuilder + */ + public function getBuilder() + { + return $this->builder; + } + + /** + * @return \Robo\Collection\CollectionBuilder + */ + protected function collectionBuilder() + { + return $this->getBuilder()->newBuilder(); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Common/CommandArguments.php b/src/composer/vendor/consolidation/robo/src/Common/CommandArguments.php new file mode 100644 index 00000000..2ed2bc91 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Common/CommandArguments.php @@ -0,0 +1,111 @@ +args($arg); + } + + /** + * Pass methods parameters as arguments to executable. Argument values + * are automatically escaped. + * + * @param string|string[] $args + * + * @return $this + */ + public function args($args) + { + if (!is_array($args)) { + $args = func_get_args(); + } + $this->arguments .= ' ' . implode(' ', array_map('static::escape', $args)); + return $this; + } + + /** + * Pass the provided string in its raw (as provided) form as an argument to executable. + * + * @param string $arg + */ + public function rawArg($arg) + { + $this->arguments .= " $arg"; + } + + /** + * Escape the provided value, unless it contains only alphanumeric + * plus a few other basic characters. + * + * @param string $value + * + * @return string + */ + public static function escape($value) + { + if (preg_match('/^[a-zA-Z0-9\/\.@~_-]+$/', $value)) { + return $value; + } + return ProcessUtils::escapeArgument($value); + } + + /** + * Pass option to executable. Options are prefixed with `--` , value can be provided in second parameter. + * Option values are automatically escaped. + * + * @param string $option + * @param string $value + * + * @return $this + */ + public function option($option, $value = null) + { + if ($option !== null and strpos($option, '-') !== 0) { + $option = "--$option"; + } + $this->arguments .= null == $option ? '' : " " . $option; + $this->arguments .= null == $value ? '' : " " . static::escape($value); + return $this; + } + + /** + * Pass multiple options to executable. Value can be a string or array. + * Option values are automatically escaped. + * + * @param string $option + * @param string|array $value + * + * @return $this + */ + public function optionList($option, $value = array()) + { + if (is_array($value)) { + foreach ($value as $item) { + $this->optionList($option, $item); + } + } else { + $this->option($option, $value); + } + + return $this; + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Common/CommandReceiver.php b/src/composer/vendor/consolidation/robo/src/Common/CommandReceiver.php new file mode 100644 index 00000000..03b20fce --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Common/CommandReceiver.php @@ -0,0 +1,30 @@ +getCommand(); + } else { + throw new TaskException($this, get_class($command) . " does not implement CommandInterface, so can't be passed into this task"); + } + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Common/ConfigAwareTrait.php b/src/composer/vendor/consolidation/robo/src/Common/ConfigAwareTrait.php new file mode 100644 index 00000000..8f8ba48c --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Common/ConfigAwareTrait.php @@ -0,0 +1,77 @@ +config = $config; + + return $this; + } + + /** + * Get the config management object. + * + * @return \Robo\Config + * + * @see \Robo\Contract\ConfigAwareInterface::getConfig() + */ + public function getConfig() + { + return $this->config; + } + + /** + * @param string $key + * + * @return string + */ + private static function getClassKey($key) + { + return sprintf('%s.%s', get_called_class(), $key); + } + + /** + * @param string $key + * @param mixed $value + * + * @deprecated + */ + public static function configure($key, $value) + { + Robo::config()->set(static::getClassKey($key), $value); + } + + /** + * @param string $key + * @param mixed|null $default + * + * @return mixed|null + */ + protected function getConfigValue($key, $default = null) + { + if (!$this->getConfig()) { + return $default; + } + return $this->getConfig()->get(static::getClassKey($key), $default); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Common/DynamicParams.php b/src/composer/vendor/consolidation/robo/src/Common/DynamicParams.php new file mode 100644 index 00000000..28a1d150 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Common/DynamicParams.php @@ -0,0 +1,45 @@ +$property))) { + $this->$property = !$this->$property; + return $this; + } + + // append item to array + if (is_array($this->$property)) { + if (is_array($args[0])) { + $this->$property = $args[0]; + } else { + array_push($this->$property, $args[0]); + } + return $this; + } + + $this->$property = $args[0]; + return $this; + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Common/ExecCommand.php b/src/composer/vendor/consolidation/robo/src/Common/ExecCommand.php new file mode 100644 index 00000000..ad4c4093 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Common/ExecCommand.php @@ -0,0 +1,197 @@ +execTimer)) { + $this->execTimer = new TimeKeeper(); + } + return $this->execTimer; + } + + /** + * Is command printing its output to screen + * + * @return bool + */ + public function getPrinted() + { + return $this->isPrinted; + } + + /** + * Changes working directory of command + * + * @param string $dir + * + * @return $this + */ + public function dir($dir) + { + $this->workingDirectory = $dir; + return $this; + } + + + /** + * Should command output be printed + * + * @param bool $arg + * + * @return $this + */ + public function printed($arg) + { + if (is_bool($arg)) { + $this->isPrinted = $arg; + } + return $this; + } + + /** + * Look for a "{$cmd}.phar" in the current working + * directory; return a string to exec it if it is + * found. Otherwise, look for an executable command + * of the same name via findExecutable. + * + * @param string $cmd + * + * @return bool|string + */ + protected function findExecutablePhar($cmd) + { + if (file_exists("{$cmd}.phar")) { + return "php {$cmd}.phar"; + } + return $this->findExecutable($cmd); + } + + /** + * Return the best path to the executable program + * with the provided name. Favor vendor/bin in the + * current project. If not found there, use + * whatever is on the $PATH. + * + * @param string $cmd + * + * @return bool|string + */ + protected function findExecutable($cmd) + { + $pathToCmd = $this->searchForExecutable($cmd); + if ($pathToCmd) { + return $this->useCallOnWindows($pathToCmd); + } + return false; + } + + /** + * @param string $cmd + * + * @return string + */ + private function searchForExecutable($cmd) + { + $projectBin = $this->findProjectBin(); + + $localComposerInstallation = $projectBin . DIRECTORY_SEPARATOR . $cmd; + if (file_exists($localComposerInstallation)) { + return $localComposerInstallation; + } + $finder = new ExecutableFinder(); + return $finder->find($cmd, null, []); + } + + /** + * @return bool|string + */ + protected function findProjectBin() + { + $candidates = [ __DIR__ . '/../../vendor/bin', __DIR__ . '/../../bin' ]; + + // If this project is inside a vendor directory, give highest priority + // to that directory. + $vendorDirContainingUs = realpath(__DIR__ . '/../../../..'); + if (is_dir($vendorDirContainingUs) && (basename($vendorDirContainingUs) == 'vendor')) { + array_unshift($candidates, $vendorDirContainingUs . '/bin'); + } + + foreach ($candidates as $dir) { + if (is_dir("$dir")) { + return realpath($dir); + } + } + return false; + } + + /** + * Wrap Windows executables in 'call' per 7a88757d + * + * @param string $cmd + * + * @return string + */ + protected function useCallOnWindows($cmd) + { + if (defined('PHP_WINDOWS_VERSION_BUILD')) { + if (file_exists("{$cmd}.bat")) { + $cmd = "{$cmd}.bat"; + } + return "call $cmd"; + } + return $cmd; + } + + /** + * @param string $command + * + * @return \Robo\Result + */ + protected function executeCommand($command) + { + $process = new Process($command); + $process->setTimeout(null); + if ($this->workingDirectory) { + $process->setWorkingDirectory($this->workingDirectory); + } + $this->getExecTimer()->start(); + if ($this->isPrinted) { + $process->run(function ($type, $buffer) { + print $buffer; + }); + } else { + $process->run(); + } + $this->getExecTimer()->stop(); + + return new Result($this, $process->getExitCode(), $process->getOutput(), ['time' => $this->getExecTimer()->elapsed()]); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Common/ExecOneCommand.php b/src/composer/vendor/consolidation/robo/src/Common/ExecOneCommand.php new file mode 100644 index 00000000..60137514 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Common/ExecOneCommand.php @@ -0,0 +1,12 @@ +io) { + $this->io = new SymfonyStyle($this->input(), $this->output()); + } + return $this->io; + } + + /** + * @param string $nonDecorated + * @param string $decorated + * + * @return string + */ + protected function decorationCharacter($nonDecorated, $decorated) + { + if (!$this->output()->isDecorated() || (strncasecmp(PHP_OS, 'WIN', 3) == 0)) { + return $nonDecorated; + } + return $decorated; + } + + /** + * @param string $text + */ + protected function say($text) + { + $char = $this->decorationCharacter('>', '➜'); + $this->writeln("$char $text"); + } + + /** + * @param string $text + * @param int $length + * @param string $color + */ + protected function yell($text, $length = 40, $color = 'green') + { + $char = $this->decorationCharacter(' ', '➜'); + $format = "$char %s"; + $this->formattedOutput($text, $length, $format); + } + + /** + * @param string $text + * @param int $length + * @param string $format + */ + private function formattedOutput($text, $length, $format) + { + $lines = explode("\n", trim($text, "\n")); + $maxLineLength = array_reduce(array_map('strlen', $lines), 'max'); + $length = max($length, $maxLineLength); + $len = $length + 2; + $space = str_repeat(' ', $len); + $this->writeln(sprintf($format, $space)); + foreach ($lines as $line) { + $line = str_pad($line, $length, ' ', STR_PAD_BOTH); + $this->writeln(sprintf($format, " $line ")); + } + $this->writeln(sprintf($format, $space)); + } + + /** + * @param string $question + * @param bool $hideAnswer + * + * @return string + */ + protected function ask($question, $hideAnswer = false) + { + if ($hideAnswer) { + return $this->askHidden($question); + } + return $this->doAsk(new Question($this->formatQuestion($question))); + } + + /** + * @param string $question + * + * @return string + */ + protected function askHidden($question) + { + $question = new Question($this->formatQuestion($question)); + $question->setHidden(true); + return $this->doAsk($question); + } + + /** + * @param string $question + * @param string $default + * + * @return string + */ + protected function askDefault($question, $default) + { + return $this->doAsk(new Question($this->formatQuestion("$question [$default]"), $default)); + } + + /** + * @param string $question + * + * @return string + */ + protected function confirm($question) + { + return $this->doAsk(new ConfirmationQuestion($this->formatQuestion($question . ' (y/n)'), false)); + } + + /** + * @param \Symfony\Component\Console\Question\Question $question + * + * @return string + */ + private function doAsk(Question $question) + { + return $this->getDialog()->ask($this->input(), $this->output(), $question); + } + + /** + * @param string $message + * + * @return string + */ + private function formatQuestion($message) + { + return "? $message "; + } + + /** + * @return \Symfony\Component\Console\Helper\QuestionHelper + */ + protected function getDialog() + { + return new QuestionHelper(); + } + + /** + * @param $text + */ + private function writeln($text) + { + $this->output()->writeln($text); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Common/InflectionTrait.php b/src/composer/vendor/consolidation/robo/src/Common/InflectionTrait.php new file mode 100644 index 00000000..8bc4e831 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Common/InflectionTrait.php @@ -0,0 +1,21 @@ +injectDependencies($this); + return $this; + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Common/InputAwareTrait.php b/src/composer/vendor/consolidation/robo/src/Common/InputAwareTrait.php new file mode 100644 index 00000000..bae58c17 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Common/InputAwareTrait.php @@ -0,0 +1,51 @@ +input = $input; + + return $this; + } + + /** + * @return \Symfony\Component\Console\Input\InputInterface + */ + protected function input() + { + if (!isset($this->input)) { + $this->setInput(new ArgvInput()); + } + return $this->input; + } + + /** + * Backwards compatibility. + * + * @return \Symfony\Component\Console\Input\InputInterface + * + * @deprecated + */ + protected function getInput() + { + return $this->input(); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Common/OutputAwareTrait.php b/src/composer/vendor/consolidation/robo/src/Common/OutputAwareTrait.php new file mode 100644 index 00000000..48082cb3 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Common/OutputAwareTrait.php @@ -0,0 +1,51 @@ +output = $output; + + return $this; + } + + /** + * @return \Symfony\Component\Console\Output\OutputInterface + */ + protected function output() + { + if (!isset($this->output)) { + $this->setOutput(new NullOutput()); + } + return $this->output; + } + + /** + * Backwards compatibility + * + * @return \Symfony\Component\Console\Output\OutputInterface + * + * @deprecated + */ + protected function getOutput() + { + return $this->output(); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Common/ProgressIndicator.php b/src/composer/vendor/consolidation/robo/src/Common/ProgressIndicator.php new file mode 100644 index 00000000..050250e5 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Common/ProgressIndicator.php @@ -0,0 +1,201 @@ +progressBar = $progressBar; + $this->output = $output; + } + + /** + * @param int $interval + */ + public function setProgressBarAutoDisplayInterval($interval) + { + if ($this->progressIndicatorRunning) { + return; + } + $this->autoDisplayInterval = $interval; + } + + /** + * @return bool + */ + public function hideProgressIndicator() + { + $result = $this->progressBarDisplayed; + if ($this->progressIndicatorRunning && $this->progressBarDisplayed) { + $this->progressBar->clear(); + // Hack: progress indicator does not reset cursor to beginning of line on 'clear' + $this->output->write("\x0D"); + $this->progressBarDisplayed = false; + } + return $result; + } + + public function showProgressIndicator() + { + if ($this->progressIndicatorRunning && !$this->progressBarDisplayed && isset($this->progressBar)) { + $this->progressBar->display(); + $this->progressBarDisplayed = true; + $this->advanceProgressIndicatorCachedSteps(); + } + } + + /** + * @param bool $visible + */ + public function restoreProgressIndicator($visible) + { + if ($visible) { + $this->showProgressIndicator(); + } + } + + /** + * @param int $totalSteps + * @param \Robo\Contract\TaskInterface $owner + */ + public function startProgressIndicator($totalSteps, $owner) + { + if (!isset($this->progressBar)) { + return; + } + + $this->progressIndicatorRunning = true; + if (!isset($this->owner)) { + $this->owner = $owner; + $this->startTimer(); + $this->totalSteps = $totalSteps; + $this->autoShowProgressIndicator(); + } + } + + public function autoShowProgressIndicator() + { + if (($this->autoDisplayInterval < 0) || !isset($this->progressBar) || !$this->output->isDecorated()) { + return; + } + if ($this->autoDisplayInterval <= $this->getExecutionTime()) { + $this->autoDisplayInterval = -1; + $this->progressBar->start($this->totalSteps); + $this->showProgressIndicator(); + } + } + + /** + * @return bool + */ + public function inProgress() + { + return $this->progressIndicatorRunning; + } + + /** + * @param \Robo\Contract\TaskInterface $owner + */ + public function stopProgressIndicator($owner) + { + if ($this->progressIndicatorRunning && ($this->owner === $owner)) { + $this->cleanup(); + } + } + + protected function cleanup() + { + $this->progressIndicatorRunning = false; + $this->owner = null; + if ($this->progressBarDisplayed) { + $this->progressBar->finish(); + // Hack: progress indicator does not always finish cleanly + $this->output->writeln(''); + $this->progressBarDisplayed = false; + } + $this->stopTimer(); + } + + /** + * Erase progress indicator and ensure it never returns. Used + * only during error handlers. + */ + public function disableProgressIndicator() + { + $this->cleanup(); + // ProgressIndicator is shared, so this permanently removes + // the program's ability to display progress bars. + $this->progressBar = null; + } + + /** + * @param int $steps + */ + public function advanceProgressIndicator($steps = 1) + { + $this->cachedSteps += $steps; + if ($this->progressIndicatorRunning) { + $this->autoShowProgressIndicator(); + // We only want to call `advance` if the progress bar is visible, + // because it always displays itself when it is advanced. + if ($this->progressBarDisplayed) { + return $this->advanceProgressIndicatorCachedSteps(); + } + } + } + + protected function advanceProgressIndicatorCachedSteps() + { + $this->progressBar->advance($this->cachedSteps); + $this->cachedSteps = 0; + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Common/ProgressIndicatorAwareTrait.php b/src/composer/vendor/consolidation/robo/src/Common/ProgressIndicatorAwareTrait.php new file mode 100644 index 00000000..5d33e6d0 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Common/ProgressIndicatorAwareTrait.php @@ -0,0 +1,124 @@ +progressIndicator = $progressIndicator; + } + + /** + * @return null|bool + */ + protected function hideProgressIndicator() + { + if (!$this->progressIndicator) { + return; + } + return $this->progressIndicator->hideProgressIndicator(); + } + + protected function showProgressIndicator() + { + if (!$this->progressIndicator) { + return; + } + $this->progressIndicator->showProgressIndicator(); + } + + /** + * @param bool $visible + */ + protected function restoreProgressIndicator($visible) + { + if (!$this->progressIndicator) { + return; + } + $this->progressIndicator->restoreProgressIndicator($visible); + } + + /** + * @return int + */ + protected function getTotalExecutionTime() + { + if (!$this->progressIndicator) { + return 0; + } + return $this->progressIndicator->getExecutionTime(); + } + + protected function startProgressIndicator() + { + $this->startTimer(); + if (!$this->progressIndicator) { + return; + } + $totalSteps = $this->progressIndicatorSteps(); + $this->progressIndicator->startProgressIndicator($totalSteps, $this); + } + + /** + * @return bool + */ + protected function inProgress() + { + if (!$this->progressIndicator) { + return false; + } + return $this->progressIndicator->inProgress(); + } + + protected function stopProgressIndicator() + { + $this->stopTimer(); + if (!$this->progressIndicator) { + return; + } + $this->progressIndicator->stopProgressIndicator($this); + } + + protected function disableProgressIndicator() + { + $this->stopTimer(); + if (!$this->progressIndicator) { + return; + } + $this->progressIndicator->disableProgressIndicator(); + } + + protected function detatchProgressIndicator() + { + $this->setProgressIndicator(null); + } + + /** + * @param int $steps + */ + protected function advanceProgressIndicator($steps = 1) + { + if (!$this->progressIndicator) { + return; + } + $this->progressIndicator->advanceProgressIndicator($steps); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Common/ResourceExistenceChecker.php b/src/composer/vendor/consolidation/robo/src/Common/ResourceExistenceChecker.php new file mode 100644 index 00000000..233f90a9 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Common/ResourceExistenceChecker.php @@ -0,0 +1,116 @@ +printTaskError(sprintf('Invalid glob "%s"!', $resource), $this); + $success = false; + continue; + } + foreach ($glob as $resource) { + if (!$this->checkResource($resource, $type)) { + $success = false; + } + } + } + return $success; + } + + /** + * Checks a single resource, file or directory. + * + * It will print an error as well on the console. + * + * @param string $resource File or folder. + * @param string $type "file", "dir", "fileAndDir" + * + * @return bool + */ + protected function checkResource($resource, $type) + { + switch ($type) { + case 'file': + if (!$this->isFile($resource)) { + $this->printTaskError(sprintf('File "%s" does not exist!', $resource), $this); + return false; + } + return true; + case 'dir': + if (!$this->isDir($resource)) { + $this->printTaskError(sprintf('Directory "%s" does not exist!', $resource), $this); + return false; + } + return true; + case 'fileAndDir': + if (!$this->isDir($resource) && !$this->isFile($resource)) { + $this->printTaskError(sprintf('File or directory "%s" does not exist!', $resource), $this); + return false; + } + return true; + } + } + + /** + * Convenience method to check the often uses "source => target" file / folder arrays. + * + * @param string|array $resources + */ + protected function checkSourceAndTargetResource($resources) + { + if (is_string($resources)) { + $resources = [$resources]; + } + $sources = []; + $targets = []; + foreach ($resources as $source => $target) { + $sources[] = $source; + $target[] = $target; + } + $this->checkResources($sources); + $this->checkResources($targets); + } + + /** + * Wrapper method around phps is_dir() + * + * @param string $directory + * + * @return bool + */ + protected function isDir($directory) + { + return is_dir($directory); + } + + /** + * Wrapper method around phps file_exists() + * + * @param string $file + * + * @return bool + */ + protected function isFile($file) + { + return file_exists($file); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Common/TaskIO.php b/src/composer/vendor/consolidation/robo/src/Common/TaskIO.php new file mode 100644 index 00000000..57ebb6fe --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Common/TaskIO.php @@ -0,0 +1,235 @@ +logger should always be set in Robo core tasks. + if ($this->logger) { + return $this->logger; + } + + // TODO: Remove call to Robo::logger() once maintaining backwards + // compatibility with legacy external Robo tasks is no longer desired. + if (!Robo::logger()) { + return null; + } + + static $gaveDeprecationWarning = false; + if (!$gaveDeprecationWarning) { + trigger_error('No logger set for ' . get_class($this) . '. Use $this->task(Foo::class) rather than new Foo() in loadTasks to ensure the builder can initialize task the task, or use $this->collectionBuilder()->taskFoo() if creating one task from within another.', E_USER_DEPRECATED); + $gaveDeprecationWarning = true; + } + return Robo::logger(); + } + + /** + * Print information about a task in progress. + * + * With the Symfony Console logger, NOTICE is displayed at VERBOSITY_VERBOSE + * and INFO is displayed at VERBOSITY_VERY_VERBOSE. + * + * Robo overrides the default such that NOTICE is displayed at + * VERBOSITY_NORMAL and INFO is displayed at VERBOSITY_VERBOSE. + * + * n.b. We should probably have printTaskNotice for our ordinary + * output, and use printTaskInfo for less interesting messages. + * + * @param string $text + * @param null|array $context + */ + protected function printTaskInfo($text, $context = null) + { + // The 'note' style is used for both 'notice' and 'info' log levels; + // However, 'notice' is printed at VERBOSITY_NORMAL, whereas 'info' + // is only printed at VERBOSITY_VERBOSE. + $this->printTaskOutput(LogLevel::NOTICE, $text, $this->getTaskContext($context)); + } + + /** + * Provide notification that some part of the task succeeded. + * + * With the Symfony Console logger, success messages are remapped to NOTICE, + * and displayed in VERBOSITY_VERBOSE. When used with the Robo logger, + * success messages are displayed at VERBOSITY_NORMAL. + * + * @param string $text + * @param null|array $context + */ + protected function printTaskSuccess($text, $context = null) + { + // Not all loggers will recognize ConsoleLogLevel::SUCCESS. + // We therefore log as LogLevel::NOTICE, and apply a '_level' + // override in the context so that this message will be + // logged as SUCCESS if that log level is recognized. + $context['_level'] = ConsoleLogLevel::SUCCESS; + $this->printTaskOutput(LogLevel::NOTICE, $text, $this->getTaskContext($context)); + } + + /** + * Provide notification that there is something wrong, but + * execution can continue. + * + * Warning messages are displayed at VERBOSITY_NORMAL. + * + * @param string $text + * @param null|array $context + */ + protected function printTaskWarning($text, $context = null) + { + $this->printTaskOutput(LogLevel::WARNING, $text, $this->getTaskContext($context)); + } + + /** + * Provide notification that some operation in the task failed, + * and the task cannot continue. + * + * Error messages are displayed at VERBOSITY_NORMAL. + * + * @param string $text + * @param null|array $context + */ + protected function printTaskError($text, $context = null) + { + $this->printTaskOutput(LogLevel::ERROR, $text, $this->getTaskContext($context)); + } + + /** + * Provide debugging notification. These messages are only + * displayed if the log level is VERBOSITY_DEBUG. + * + * @param string$text + * @param null|array $context + */ + protected function printTaskDebug($text, $context = null) + { + $this->printTaskOutput(LogLevel::DEBUG, $text, $this->getTaskContext($context)); + } + + /** + * @param string $level + * One of the \Psr\Log\LogLevel constant + * @param string $text + * @param null|array $context + */ + protected function printTaskOutput($level, $text, $context) + { + $logger = $this->logger(); + if (!$logger) { + return; + } + // Hide the progress indicator, if it is visible. + $inProgress = $this->hideTaskProgress(); + $logger->log($level, $text, $this->getTaskContext($context)); + // After we have printed our log message, redraw the progress indicator. + $this->showTaskProgress($inProgress); + } + + /** + * @return bool + */ + protected function hideTaskProgress() + { + $inProgress = false; + if ($this instanceof ProgressIndicatorAwareInterface) { + $inProgress = $this->inProgress(); + } + + // If a progress indicator is running on this task, then we mush + // hide it before we print anything, or its display will be overwritten. + if ($inProgress) { + $inProgress = $this->hideProgressIndicator(); + } + return $inProgress; + } + + /** + * @param $inProgress + */ + protected function showTaskProgress($inProgress) + { + if ($inProgress) { + $this->restoreProgressIndicator($inProgress); + } + } + + /** + * Format a quantity of bytes. + * + * @param int $size + * @param int $precision + * + * @return string + */ + protected function formatBytes($size, $precision = 2) + { + if ($size === 0) { + return 0; + } + $base = log($size, 1024); + $suffixes = array('', 'k', 'M', 'G', 'T'); + return round(pow(1024, $base - floor($base)), $precision) . $suffixes[floor($base)]; + } + + /** + * Get the formatted task name for use in task output. + * This is placed in the task context under 'name', and + * used as the log label by Robo\Common\RoboLogStyle, + * which is inserted at the head of log messages by + * Robo\Common\CustomLogStyle::formatMessage(). + * + * @param null|object $task + * + * @return string + */ + protected function getPrintedTaskName($task = null) + { + if (!$task) { + $task = $this; + } + return TaskInfo::formatTaskName($task); + } + + /** + * @param null|array $context + * + * @return array with context information + */ + protected function getTaskContext($context = null) + { + if (!$context) { + $context = []; + } + if (!is_array($context)) { + $context = ['task' => $context]; + } + if (!array_key_exists('task', $context)) { + $context['task'] = $this; + } + + return $context + TaskInfo::getTaskContext($context['task']); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Common/TimeKeeper.php b/src/composer/vendor/consolidation/robo/src/Common/TimeKeeper.php new file mode 100644 index 00000000..1cd3e334 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Common/TimeKeeper.php @@ -0,0 +1,69 @@ +startedAt) { + return; + } + // Get time in seconds as a float, accurate to the microsecond. + $this->startedAt = microtime(true); + } + + public function stop() + { + $this->finishedAt = microtime(true); + } + + /** + * @return float|null + */ + public function elapsed() + { + $finished = $this->finishedAt ? $this->finishedAt : microtime(true); + if ($finished - $this->startedAt <= 0) { + return null; + } + return $finished - $this->startedAt; + } + + /** + * Format a duration into a human-readable time + * + * @param float $duration Duration in seconds, with fractional component + * + * @return string + */ + public static function formatDuration($duration) + { + if ($duration >= self::DAY * 2) { + return gmdate('z \d\a\y\s H:i:s', $duration); + } + if ($duration > self::DAY) { + return gmdate('\1 \d\a\y H:i:s', $duration); + } + if ($duration > self::HOUR) { + return gmdate("H:i:s", $duration); + } + if ($duration > self::MINUTE) { + return gmdate("i:s", $duration); + } + return round($duration, 3).'s'; + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Common/Timer.php b/src/composer/vendor/consolidation/robo/src/Common/Timer.php new file mode 100644 index 00000000..955eb5bb --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Common/Timer.php @@ -0,0 +1,37 @@ +timer)) { + $this->timer = new TimeKeeper(); + } + $this->timer->start(); + } + + protected function stopTimer() + { + if (!isset($this->timer)) { + return; + } + $this->timer->stop(); + } + + /** + * @return float|null + */ + protected function getExecutionTime() + { + if (!isset($this->timer)) { + return null; + } + return $this->timer->elapsed(); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Config.php b/src/composer/vendor/consolidation/robo/src/Config.php new file mode 100644 index 00000000..10e29eff --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Config.php @@ -0,0 +1,122 @@ +config[$key])) { + return $this->config[$key]; + } + return $this->getDefault($key, $defaultOverride); + } + + /** + * Set a config value + * + * @param string $key + * @param mixed $value + * + * @return $this + */ + public function set($key, $value) + { + $this->config[$key] = $value; + return $this; + } + + /** + * Return an associative array containing all of the global configuration + * options and their default values. + * + * @return array + */ + public function getGlobalOptionDefaultValues() + { + $globalOptions = + [ + self::PROGRESS_BAR_AUTO_DISPLAY_INTERVAL => self::DEFAULT_PROGRESS_DELAY, + self::SIMULATE => false, + ]; + + return $globalOptions; + } + + /** + * Return the default value for a given configuration item. + * + * @param string $key + * @param mixed $defaultOverride + * + * @return mixed + */ + public function getDefault($key, $defaultOverride = null) + { + $globalOptions = $this->getGlobalOptionDefaultValues(); + return isset($globalOptions[$key]) ? $globalOptions[$key] : $defaultOverride; + } + + /** + * @return bool + */ + public function isSimulated() + { + return $this->get(self::SIMULATE); + } + + /** + * @param bool $simulated + * + * @return $this + */ + public function setSimulated($simulated = true) + { + return $this->set(self::SIMULATE, $simulated); + } + + /** + * @return bool + */ + public function isDecorated() + { + return $this->get(self::DECORATED); + } + + /** + * @param bool $decorated + * + * @return $this + */ + public function setDecorated($decorated = true) + { + return $this->set(self::DECORATED, $decorated); + } + + /** + * @param int $interval + * + * @return $this + */ + public function setProgressBarAutoDisplayInterval($interval) + { + return $this->set(self::PROGRESS_BAR_AUTO_DISPLAY_INTERVAL, $interval); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Contract/BuilderAwareInterface.php b/src/composer/vendor/consolidation/robo/src/Contract/BuilderAwareInterface.php new file mode 100644 index 00000000..d67796fe --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Contract/BuilderAwareInterface.php @@ -0,0 +1,22 @@ +inflect($this) + * ->initializer() + * ->... + * + * Instead of: + * + * (new SomeTask($args)) + * ->setLogger($this->logger) + * ->initializer() + * ->... + * + * The reason `inflect` is better than the more explicit alternative is + * that subclasses of BaseTask that implement a new FooAwareInterface + * can override injectDependencies() as explained below, and add more + * dependencies that can be injected as needed. + * + * @param \Robo\Contract\InflectionInterface $parent + */ + public function inflect(InflectionInterface $parent); + + /** + * Take all dependencies availble to this task and inject any that are + * needed into the provided task. The general pattern is that, for every + * FooAwareInterface that this class implements, it should test to see + * if the child also implements the same interface, and if so, should call + * $child->setFoo($this->foo). + * + * The benefits of this are pretty large. Any time an object that implements + * InflectionInterface is created, just call `$child->inflect($this)`, and + * any available optional dependencies will be hooked up via setter injection. + * + * The required dependencies of an object should be provided via constructor + * injection, not inflection. + * + * @param InflectionInterface $child An object created by this class that + * should have its dependencies injected. + * + * @see https://mwop.net/blog/2016-04-26-on-locators.html + */ + public function injectDependencies(InflectionInterface $child); +} diff --git a/src/composer/vendor/consolidation/robo/src/Contract/OutputAwareInterface.php b/src/composer/vendor/consolidation/robo/src/Contract/OutputAwareInterface.php new file mode 100644 index 00000000..570afed2 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Contract/OutputAwareInterface.php @@ -0,0 +1,19 @@ + 'setGlobalOptions']; + } + + /** + * Before a Console command runs, examine the global + * commandline options from the event Input, and set + * configuration values as appropriate. + * + * @param \Symfony\Component\Console\Event\ConsoleCommandEvent $event + */ + public function setGlobalOptions(ConsoleCommandEvent $event) + { + $config = $this->getConfig(); + $input = $event->getInput(); + $globalOptions = $config->getGlobalOptionDefaultValues(); + + foreach ($globalOptions as $option => $default) { + $value = $input->hasOption($option) ? $input->getOption($option) : null; + // Unfortunately, the `?:` operator does not differentate between `0` and `null` + if (!isset($value)) { + $value = $default; + } + $config->set($option, $value); + } + } +} diff --git a/src/composer/vendor/consolidation/robo/src/LoadAllTasks.php b/src/composer/vendor/consolidation/robo/src/LoadAllTasks.php new file mode 100644 index 00000000..3183d5b6 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/LoadAllTasks.php @@ -0,0 +1,39 @@ +wasSuccessful()) { + return $this->printError($result); + } else { + return $this->printSuccess($result); + } + } + + /** + * Log that we are about to abort due to an error being encountered + * in 'stop on fail' mode. + * + * @param \Robo\Result $result + */ + public function printStopOnFail($result) + { + $this->printMessage(LogLevel::NOTICE, 'Stopping on fail. Exiting....'); + $this->printMessage(LogLevel::ERROR, 'Exit Code: {code}', ['code' => $result->getExitCode()]); + } + + /** + * Log the result of a Robo task that returned an error. + * + * @param \Robo\Result $result + * + * @return bool + */ + protected function printError(Result $result) + { + $task = $result->getTask(); + $context = $result->getContext() + ['timer-label' => 'Time', '_style' => []]; + $context['_style']['message'] = ''; + + $printOutput = true; + if ($task instanceof PrintedInterface) { + $printOutput = !$task->getPrinted(); + } + if ($printOutput) { + $this->printMessage(LogLevel::ERROR, "{message}", $context); + } + $this->printMessage(LogLevel::ERROR, 'Exit code {code}', $context); + return true; + } + + /** + * Log the result of a Robo task that was successful. + * + * @param \Robo\Result $result + * + * @return bool + */ + protected function printSuccess(Result $result) + { + $task = $result->getTask(); + $context = $result->getContext() + ['timer-label' => 'in']; + $time = $result->getExecutionTime(); + if ($time) { + $this->printMessage(ConsoleLogLevel::SUCCESS, 'Done', $context); + } + return false; + } + + /** + * @param string $level + * @param string $message + * @param array $context + */ + protected function printMessage($level, $message, $context = []) + { + $inProgress = $this->hideProgressIndicator(); + $this->logger->log($level, $message, $context); + if ($inProgress) { + $this->restoreProgressIndicator($inProgress); + } + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Log/RoboLogLevel.php b/src/composer/vendor/consolidation/robo/src/Log/RoboLogLevel.php new file mode 100644 index 00000000..d7d5eb0a --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Log/RoboLogLevel.php @@ -0,0 +1,11 @@ +labelStyles += [ + RoboLogLevel::SIMULATED_ACTION => self::TASK_STYLE_SIMULATED, + ]; + $this->messageStyles += [ + RoboLogLevel::SIMULATED_ACTION => '', + ]; + } + + /** + * Log style customization for Robo: replace the log level with + * the task name. + * + * @param string $level + * @param string $message + * @param array $context + * + * @return string + */ + protected function formatMessageByLevel($level, $message, $context) + { + $label = $level; + if (array_key_exists('name', $context)) { + $label = $context['name']; + } + return $this->formatMessage($label, $message, $context, $this->labelStyles[$level], $this->messageStyles[$level]); + } + + /** + * Log style customization for Robo: add the time indicator to the + * end of the log message if it exists in the context. + * + * @param string $label + * @param string $message + * @param array $context + * @param string $taskNameStyle + * @param string $messageStyle + * + * @return string + */ + protected function formatMessage($label, $message, $context, $taskNameStyle, $messageStyle = '') + { + $message = parent::formatMessage($label, $message, $context, $taskNameStyle, $messageStyle); + + if (array_key_exists('time', $context) && !empty($context['time']) && array_key_exists('timer-label', $context)) { + $duration = TimeKeeper::formatDuration($context['time']); + $message .= ' ' . $context['timer-label'] . ' ' . $this->wrapFormatString($duration, 'fg=yellow'); + } + + return $message; + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Log/RoboLogger.php b/src/composer/vendor/consolidation/robo/src/Log/RoboLogger.php new file mode 100644 index 00000000..c3e223fd --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Log/RoboLogger.php @@ -0,0 +1,36 @@ + OutputInterface::VERBOSITY_NORMAL, // Default is "verbose" + LogLevel::NOTICE => OutputInterface::VERBOSITY_NORMAL, // Default is "verbose" + LogLevel::INFO => OutputInterface::VERBOSITY_VERBOSE, // Default is "very verbose" + ]; + parent::__construct($output, $roboVerbosityOverrides); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Result.php b/src/composer/vendor/consolidation/robo/src/Result.php new file mode 100644 index 00000000..7032a90d --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Result.php @@ -0,0 +1,234 @@ +task = $task; + $this->printResult(); + + if (self::$stopOnFail) { + $this->stopOnFail(); + } + } + + protected function printResult() + { + // For historic reasons, the Result constructor is responsible + // for printing task results. + // TODO: Make IO the responsibility of some other class. Maintaining + // existing behavior for backwards compatibility. This is undesirable + // in the long run, though, as it can result in unwanted repeated input + // in task collections et. al. + $resultPrinter = Robo::resultPrinter(); + if ($resultPrinter) { + if ($resultPrinter->printResult($this)) { + $this->data['already-printed'] = true; + } + } + } + + /** + * @param \Robo\Contract\TaskInterface $task + * @param string $extension + * @param string $service + * + * @return \Robo\Result + */ + public static function errorMissingExtension(TaskInterface $task, $extension, $service) + { + $messageTpl = 'PHP extension required for %s. Please enable %s'; + $message = sprintf($messageTpl, $service, $extension); + + return self::error($task, $message); + } + + /** + * @param \Robo\Contract\TaskInterface $task + * @param string $class + * @param string $package + * + * @return \Robo\Result + */ + public static function errorMissingPackage(TaskInterface $task, $class, $package) + { + $messageTpl = 'Class %s not found. Please install %s Composer package'; + $message = sprintf($messageTpl, $class, $package); + + return self::error($task, $message); + } + + /** + * @param \Robo\Contract\TaskInterface $task + * @param string $message + * @param array $data + * + * @return \Robo\Result + */ + public static function error(TaskInterface $task, $message, $data = []) + { + return new self($task, self::EXITCODE_ERROR, $message, $data); + } + + /** + * @param \Robo\Contract\TaskInterface $task + * @param \Exception $e + * @param array $data + * + * @return \Robo\Result + */ + public static function fromException(TaskInterface $task, \Exception $e, $data = []) + { + $exitCode = $e->getCode(); + if (!$exitCode) { + $exitCode = self::EXITCODE_ERROR; + } + return new self($task, $exitCode, $e->getMessage(), $data); + } + + /** + * @param \Robo\Contract\TaskInterface $task + * @param string $message + * @param array $data + * + * @return \Robo\Result + */ + public static function success(TaskInterface $task, $message = '', $data = []) + { + return new self($task, self::EXITCODE_OK, $message, $data); + } + + /** + * Return a context useful for logging messages. + * + * @return array + */ + public function getContext() + { + $task = $this->getTask(); + + return TaskInfo::getTaskContext($task) + [ + 'code' => $this->getExitCode(), + 'data' => $this->getArrayCopy(), + 'time' => $this->getExecutionTime(), + 'message' => $this->getMessage(), + ]; + } + + /** + * Add the results from the most recent task to the accumulated + * results from all tasks that have run so far, merging data + * as necessary. + * + * @param int|string $key + * @param \Robo\Result $taskResult + */ + public function accumulate($key, Result $taskResult) + { + // If the task is unnamed, then all of its data elements + // just get merged in at the top-level of the final Result object. + if (static::isUnnamed($key)) { + $this->merge($taskResult); + } elseif (isset($this[$key])) { + // There can only be one task with a given name; however, if + // there are tasks added 'before' or 'after' the named task, + // then the results from these will be stored under the same + // name unless they are given a name of their own when added. + $current = $this[$key]; + $this[$key] = $taskResult->merge($current); + } else { + $this[$key] = $taskResult; + } + } + + /** + * We assume that named values (e.g. for associative array keys) + * are non-numeric; numeric keys are presumed to simply be the + * index of an array, and therefore insignificant. + * + * @param int|string $key + * + * @return bool + */ + public static function isUnnamed($key) + { + return is_numeric($key); + } + + /** + * @return \Robo\Contract\TaskInterface + */ + public function getTask() + { + return $this->task; + } + + /** + * @return \Robo\Contract\TaskInterface + */ + public function cloneTask() + { + $reflect = new \ReflectionClass(get_class($this->task)); + return $reflect->newInstanceArgs(func_get_args()); + } + + /** + * @return bool + * + * @deprecated since 1.0. + * + * @see wasSuccessful() + */ + public function __invoke() + { + trigger_error(__METHOD__ . ' is deprecated: use wasSuccessful() instead.', E_USER_DEPRECATED); + return $this->wasSuccessful(); + } + + /** + * @return $this + */ + public function stopOnFail() + { + if (!$this->wasSuccessful()) { + $resultPrinter = Robo::resultPrinter(); + if ($resultPrinter) { + $resultPrinter->printStopOnFail($this); + } + $this->exitEarly($this->getExitCode()); + } + return $this; + } + + /** + * @param int $status + * + * @throws \Robo\Exception\TaskExitException + */ + private function exitEarly($status) + { + throw new TaskExitException($this->getTask(), $this->getMessage(), $status); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/ResultData.php b/src/composer/vendor/consolidation/robo/src/ResultData.php new file mode 100644 index 00000000..be7b5c63 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/ResultData.php @@ -0,0 +1,152 @@ +exitCode = $exitCode; + $this->message = $message; + + parent::__construct($data); + } + + /** + * @param string $message + * @param array $data + * + * @return \Robo\ResultData + */ + public static function message($message, $data = []) + { + return new self(self::EXITCODE_OK, $message, $data); + } + + /** + * @param string $message + * @param array $data + * + * @return \Robo\ResultData + */ + public static function cancelled($message = '', $data = []) + { + return new ResultData(self::EXITCODE_USER_CANCEL, $message, $data); + } + + /** + * @return array + */ + public function getData() + { + return $this->getArrayCopy(); + } + + /** + * @return int + */ + public function getExitCode() + { + return $this->exitCode; + } + + /** + * @return null|string + */ + public function getOutputData() + { + if (!empty($this->message) && !isset($this['already-printed'])) { + return $this->message; + } + } + + /** + * @return string + */ + public function getMessage() + { + return $this->message; + } + + /** + * @return bool + */ + public function wasSuccessful() + { + return $this->exitCode === self::EXITCODE_OK; + } + + /** + * @return bool + */ + public function wasCancelled() + { + return $this->exitCode == self::EXITCODE_USER_CANCEL; + } + + /** + * Merge another result into this result. Data already + * existing in this result takes precedence over the + * data in the Result being merged. + * + * @param \Robo\ResultData $result + * + * @return $this + */ + public function merge(ResultData $result) + { + $mergedData = $this->getArrayCopy() + $result->getArrayCopy(); + $this->exchangeArray($mergedData); + return $this; + } + + /** + * @return bool + */ + public function hasExecutionTime() + { + return isset($this['time']); + } + + /** + * @return null|float + */ + public function getExecutionTime() + { + if (!$this->hasExecutionTime()) { + return null; + } + return $this['time']; + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Robo.php b/src/composer/vendor/consolidation/robo/src/Robo.php new file mode 100644 index 00000000..7c350db7 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Robo.php @@ -0,0 +1,337 @@ +execute($argv, $appName, $appVersion, $output); + return $statusCode; + } + + /** + * Sets a new global container. + * + * @param ContainerInterface $container + * A new container instance to replace the current. + */ + public static function setContainer(ContainerInterface $container) + { + static::$container = $container; + } + + /** + * Unsets the global container. + */ + public static function unsetContainer() + { + static::$container = null; + } + + /** + * Returns the currently active global container. + * + * @return \League\Container\ContainerInterface + * + * @throws \RuntimeException + */ + public static function getContainer() + { + if (static::$container === null) { + throw new \RuntimeException('container is not initialized yet. \Robo\Robo::setContainer() must be called with a real container.'); + } + return static::$container; + } + + /** + * Returns TRUE if the container has been initialized, FALSE otherwise. + * + * @return bool + */ + public static function hasContainer() + { + return static::$container !== null; + } + + /** + * Create a container and initiailze it. If you wish to *change* + * anything defined in the container, then you should call + * \Robo::configureContainer() instead of this function. + * + * @param null|\Symfony\Component\Console\Input\InputInterface $input + * @param null|\Symfony\Component\Console\Output\OutputInterface $output + * @param null|\Robo\Application $app + * @param null|\Robo\Config $config + * + * @return \League\Container\Container|\League\Container\ContainerInterface + */ + public static function createDefaultContainer($input = null, $output = null, $app = null, $config = null) + { + // Do not allow this function to be called more than once. + if (static::hasContainer()) { + return static::getContainer(); + } + + if (!$app) { + $app = static::createDefaultApplication(); + } + + if (!$config) { + $config = new Config(); + } + + // Set up our dependency injection container. + $container = new Container(); + static::configureContainer($container, $app, $config, $input, $output); + + // Set the application dispatcher + $app->setDispatcher($container->get('eventDispatcher')); + + return $container; + } + + /** + * Initialize a container with all of the default Robo services. + * IMPORTANT: after calling this method, clients MUST call: + * + * $dispatcher = $container->get('eventDispatcher'); + * $app->setDispatcher($dispatcher); + * + * Any modification to the container should be done prior to fetching + * objects from it. + * + * It is recommended to use \Robo::createDefaultContainer() + * instead, which does all required setup for the caller, but has + * the limitation that the container it creates can only be + * extended, not modified. + * + * @param \League\Container\ContainerInterface $container + * @param \Symfony\Component\Console\Application $app + * @param \Robo\Config $config + * @param null|\Symfony\Component\Console\Input\InputInterface $input + * @param null|\Symfony\Component\Console\Output\OutputInterface $output + */ + public static function configureContainer(ContainerInterface $container, SymfonyApplication $app, Config $config, $input = null, $output = null) + { + // Self-referential container refernce for the inflector + $container->add('container', $container); + static::setContainer($container); + + // Create default input and output objects if they were not provided + if (!$input) { + $input = new StringInput(''); + } + if (!$output) { + $output = new \Symfony\Component\Console\Output\ConsoleOutput(); + } + $config->setDecorated($output->isDecorated()); + + $container->share('application', $app); + $container->share('config', $config); + $container->share('input', $input); + $container->share('output', $output); + + // Register logging and related services. + $container->share('logStyler', \Robo\Log\RoboLogStyle::class); + $container->share('logger', \Robo\Log\RoboLogger::class) + ->withArgument('output') + ->withMethodCall('setLogOutputStyler', ['logStyler']); + $container->add('progressBar', \Symfony\Component\Console\Helper\ProgressBar::class) + ->withArgument('output'); + $container->share('progressIndicator', \Robo\Common\ProgressIndicator::class) + ->withArgument('progressBar') + ->withArgument('output'); + $container->share('resultPrinter', \Robo\Log\ResultPrinter::class); + $container->add('simulator', \Robo\Task\Simulator::class); + $container->share('globalOptionsEventListener', \Robo\GlobalOptionsEventListener::class); + $container->share('collectionProcessHook', \Robo\Collection\CollectionProcessHook::class); + $container->share('hookManager', \Consolidation\AnnotatedCommand\Hooks\HookManager::class) + ->withMethodCall('addResultProcessor', ['collectionProcessHook', '*']); + $container->share('alterOptionsCommandEvent', \Consolidation\AnnotatedCommand\Options\AlterOptionsCommandEvent::class) + ->withArgument('application'); + $container->share('eventDispatcher', \Symfony\Component\EventDispatcher\EventDispatcher::class) + ->withMethodCall('addSubscriber', ['globalOptionsEventListener']) + ->withMethodCall('addSubscriber', ['alterOptionsCommandEvent']) + ->withMethodCall('addSubscriber', ['hookManager']); + $container->share('formatterManager', \Consolidation\OutputFormatters\FormatterManager::class) + ->withMethodCall('addDefaultFormatters', []) + ->withMethodCall('addDefaultSimplifiers', []); + $container->share('commandProcessor', \Consolidation\AnnotatedCommand\CommandProcessor::class) + ->withArgument('hookManager') + ->withMethodCall('setFormatterManager', ['formatterManager']) + ->withMethodCall( + 'setDisplayErrorFunction', + [ + function ($output, $message) use ($container) { + $logger = $container->get('logger'); + $logger->error($message); + } + ] + ); + $container->share('commandFactory', \Consolidation\AnnotatedCommand\AnnotatedCommandFactory::class) + ->withMethodCall('setCommandProcessor', ['commandProcessor']); + $container->add('collection', \Robo\Collection\Collection::class); + $container->add('collectionBuilder', \Robo\Collection\CollectionBuilder::class); + static::addInflectors($container); + + // Make sure the application is appropriately initialized. + $app->setAutoExit(false); + } + + /** + * @param null|string $appName + * @param null|string $appVersion + * + * @return \Robo\Application + */ + public static function createDefaultApplication($appName = null, $appVersion = null) + { + $appName = $appName ?: self::APPLICATION_NAME; + $appVersion = $appVersion ?: self::VERSION; + + $app = new \Robo\Application($appName, $appVersion); + $app->setAutoExit(false); + return $app; + } + + /** + * Add the Robo League\Container inflectors to the container + * + * @param \League\Container\ContainerInterface $container + */ + public static function addInflectors($container) + { + // Register our various inflectors. + $container->inflector(\Robo\Contract\ConfigAwareInterface::class) + ->invokeMethod('setConfig', ['config']); + $container->inflector(\Psr\Log\LoggerAwareInterface::class) + ->invokeMethod('setLogger', ['logger']); + $container->inflector(\League\Container\ContainerAwareInterface::class) + ->invokeMethod('setContainer', ['container']); + $container->inflector(\Symfony\Component\Console\Input\InputAwareInterface::class) + ->invokeMethod('setInput', ['input']); + $container->inflector(\Robo\Contract\OutputAwareInterface::class) + ->invokeMethod('setOutput', ['output']); + $container->inflector(\Robo\Contract\ProgressIndicatorAwareInterface::class) + ->invokeMethod('setProgressIndicator', ['progressIndicator']); + } + + /** + * Retrieves a service from the container. + * + * Use this method if the desired service is not one of those with a dedicated + * accessor method below. If it is listed below, those methods are preferred + * as they can return useful type hints. + * + * @param string $id + * The ID of the service to retrieve. + * + * @return mixed + * The specified service. + */ + public static function service($id) + { + return static::getContainer()->get($id); + } + + /** + * Indicates if a service is defined in the container. + * + * @param string $id + * The ID of the service to check. + * + * @return bool + * TRUE if the specified service exists, FALSE otherwise. + */ + public static function hasService($id) + { + // Check hasContainer() first in order to always return a Boolean. + return static::hasContainer() && static::getContainer()->has($id); + } + + /** + * Return the result printer object. + * + * @return \Robo\Log\ResultPrinter + */ + public static function resultPrinter() + { + return static::service('resultPrinter'); + } + + /** + * @return \Robo\Config + */ + public static function config() + { + return static::service('config'); + } + + /** + * @return \Consolidation\Log\Logger + */ + public static function logger() + { + return static::service('logger'); + } + + /** + * @return \Robo\Application + */ + public static function application() + { + return static::service('application'); + } + + /** + * Return the output object. + * + * @return \Symfony\Component\Console\Output\OutputInterface + */ + public static function output() + { + return static::service('output'); + } + + /** + * Return the input object. + * + * @return \Symfony\Component\Console\Input\InputInterface + */ + public static function input() + { + return static::service('input'); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Runner.php b/src/composer/vendor/consolidation/robo/src/Runner.php new file mode 100644 index 00000000..06218ec1 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Runner.php @@ -0,0 +1,419 @@ +roboClass = $roboClass ? $roboClass : self::ROBOCLASS ; + $this->roboFile = $roboFile ? $roboFile : self::ROBOFILE; + $this->dir = getcwd(); + } + + /** + * @param \Symfony\Component\Console\Output\OutputInterface $output + * + * @return bool + */ + protected function loadRoboFile($output) + { + // If we have not been provided an output object, make a temporary one. + if (!$output) { + $output = new \Symfony\Component\Console\Output\ConsoleOutput(); + } + + // If $this->roboClass is a single class that has not already + // been loaded, then we will try to obtain it from $this->roboFile. + // If $this->roboClass is an array, we presume all classes requested + // are available via the autoloader. + if (is_array($this->roboClass) || class_exists($this->roboClass)) { + return true; + } + if (!file_exists($this->dir)) { + $output->writeln("Path `{$this->dir}` is invalid; please provide a valid absolute path to the Robofile to load."); + return false; + } + + $realDir = realpath($this->dir); + + $roboFilePath = $realDir . DIRECTORY_SEPARATOR . $this->roboFile; + if (!file_exists($roboFilePath)) { + $requestedRoboFilePath = $this->dir . DIRECTORY_SEPARATOR . $this->roboFile; + $output->writeln("Requested RoboFile `$requestedRoboFilePath` is invalid, please provide valid absolute path to load Robofile"); + return false; + } + require_once $roboFilePath; + + if (!class_exists($this->roboClass)) { + $output->writeln("Class ".$this->roboClass." was not loaded"); + return false; + } + return true; + } + + /** + * @param array $argv + * @param null|string $appName + * @param null|string $appVersion + * @param null|\Symfony\Component\Console\Output\OutputInterface $output + * + * @return int + */ + public function execute($argv, $appName = null, $appVersion = null, $output = null) + { + $argv = $this->shebang($argv); + $argv = $this->processRoboOptions($argv); + $app = null; + if ($appName && $appVersion) { + $app = Robo::createDefaultApplication($appName, $appVersion); + } + $commandFiles = $this->getRoboFileCommands($output); + return $this->run($argv, $output, $app, $commandFiles); + } + + /** + * @param null|\Symfony\Component\Console\Input\InputInterface $input + * @param null|\Symfony\Component\Console\Output\OutputInterface $output + * @param null|\Robo\Application $app + * @param array[] $commandFiles + * + * @return int + */ + public function run($input = null, $output = null, $app = null, $commandFiles = []) + { + // Create default input and output objects if they were not provided + if (!$input) { + $input = new StringInput(''); + } + if (is_array($input)) { + $input = new ArgvInput($input); + } + if (!$output) { + $output = new \Symfony\Component\Console\Output\ConsoleOutput(); + } + $this->setInput($input); + $this->setOutput($output); + + // If we were not provided a container, then create one + if (!$this->getContainer()) { + $container = Robo::createDefaultContainer($input, $output, $app); + $this->setContainer($container); + // Automatically register a shutdown function and + // an error handler when we provide the container. + $this->installRoboHandlers(); + } + + if (!$app) { + $app = Robo::application(); + } + if (!isset($commandFiles)) { + $this->yell("Robo is not initialized here. Please run `robo init` to create a new RoboFile", 40, 'yellow'); + $app->addInitRoboFileCommand($this->roboFile, $this->roboClass); + $commandFiles = []; + } + $this->registerCommandClasses($app, $commandFiles); + + try { + $statusCode = $app->run($input, $output); + } catch (TaskExitException $e) { + $statusCode = $e->getCode() ?: 1; + } + return $statusCode; + } + + /** + * @param \Symfony\Component\Console\Output\OutputInterface $output + * + * @return null|string + */ + protected function getRoboFileCommands($output) + { + if (!$this->loadRoboFile($output)) { + return; + } + return $this->roboClass; + } + + /** + * @param \Robo\Application $app + * @param array $commandClasses + */ + public function registerCommandClasses($app, $commandClasses) + { + foreach ((array)$commandClasses as $commandClass) { + $this->registerCommandClass($app, $commandClass); + } + } + + /** + * @param \Robo\Application $app + * @param string|BuilderAwareInterface|ContainerAwareInterface $commandClass + * + * @return mixed|void + */ + public function registerCommandClass($app, $commandClass) + { + $container = Robo::getContainer(); + $roboCommandFileInstance = $this->instantiateCommandClass($commandClass); + if (!$roboCommandFileInstance) { + return; + } + + // Register commands for all of the public methods in the RoboFile. + $commandFactory = $container->get('commandFactory'); + $commandList = $commandFactory->createCommandsFromClass($roboCommandFileInstance); + foreach ($commandList as $command) { + $app->add($command); + } + return $roboCommandFileInstance; + } + + /** + * @param string|BuilderAwareInterface|ContainerAwareInterface $commandClass + * + * @return null|object + */ + protected function instantiateCommandClass($commandClass) + { + $container = Robo::getContainer(); + + // Register the RoboFile with the container and then immediately + // fetch it; this ensures that all of the inflectors will run. + // If the command class is already an instantiated object, then + // just use it exactly as it was provided to us. + if (is_string($commandClass)) { + $reflectionClass = new \ReflectionClass($commandClass); + if ($reflectionClass->isAbstract()) { + return; + } + + $commandFileName = "{$commandClass}Commands"; + $container->share($commandFileName, $commandClass); + $commandClass = $container->get($commandFileName); + } + // If the command class is a Builder Aware Interface, then + // ensure that it has a builder. Every command class needs + // its own collection builder, as they have references to each other. + if ($commandClass instanceof BuilderAwareInterface) { + $builder = $container->get('collectionBuilder', [$commandClass]); + $commandClass->setBuilder($builder); + } + if ($commandClass instanceof ContainerAwareInterface) { + $commandClass->setContainer($container); + } + return $commandClass; + } + + public function installRoboHandlers() + { + register_shutdown_function(array($this, 'shutdown')); + set_error_handler(array($this, 'handleError')); + } + + /** + * Process a shebang script, if one was used to launch this Runner. + * + * @param array $args + * + * @return array $args with shebang script removed + */ + protected function shebang($args) + { + // Option 1: Shebang line names Robo, but includes no parameters. + // #!/bin/env robo + // The robo class may contain multiple commands; the user may + // select which one to run, or even get a list of commands or + // run 'help' on any of the available commands as usual. + if ((count($args) > 1) && $this->isShebangFile($args[1])) { + return array_merge([$args[0]], array_slice($args, 2)); + } + // Option 2: Shebang line stipulates which command to run. + // #!/bin/env robo mycommand + // The robo class must contain a public method named 'mycommand'. + // This command will be executed every time. Arguments and options + // may be provided on the commandline as usual. + if ((count($args) > 2) && $this->isShebangFile($args[2])) { + return array_merge([$args[0]], explode(' ', $args[1]), array_slice($args, 3)); + } + return $args; + } + + /** + * Determine if the specified argument is a path to a shebang script. + * If so, load it. + * + * @param string $filepath file to check + * + * @return bool Returns TRUE if shebang script was processed + */ + protected function isShebangFile($filepath) + { + if (!is_file($filepath)) { + return false; + } + $fp = fopen($filepath, "r"); + if ($fp === false) { + return false; + } + $line = fgets($fp); + $result = $this->isShebangLine($line); + if ($result) { + while ($line = fgets($fp)) { + $line = trim($line); + if ($line == 'roboClass = $matches[1]; + eval($script); + $result = true; + } + } + } + } + fclose($fp); + + return $result; + } + + /** + * Test to see if the provided line is a robo 'shebang' line. + * + * @param string $line + * + * @return bool + */ + protected function isShebangLine($line) + { + return ((substr($line, 0, 2) == '#!') && (strstr($line, 'robo') !== false)); + } + + /** + * Check for Robo-specific arguments such as --load-from, process them, + * and remove them from the array. We have to process --load-from before + * we set up Symfony Console. + * + * @param array $argv + * + * @return array + */ + protected function processRoboOptions($argv) + { + // loading from other directory + $pos = $this->arraySearchBeginsWith('--load-from', $argv) ?: array_search('-f', $argv); + if ($pos === false) { + return $argv; + } + + $passThru = array_search('--', $argv); + if (($passThru !== false) && ($passThru < $pos)) { + return $argv; + } + + if (substr($argv[$pos], 0, 12) == '--load-from=') { + $this->dir = substr($argv[$pos], 12); + } elseif (isset($argv[$pos +1])) { + $this->dir = $argv[$pos +1]; + unset($argv[$pos +1]); + } + unset($argv[$pos]); + // Make adjustments if '--load-from' points at a file. + if (is_file($this->dir) || (substr($this->dir, -4) == '.php')) { + $this->roboFile = basename($this->dir); + $this->dir = dirname($this->dir); + $className = basename($this->roboFile, '.php'); + if ($className != $this->roboFile) { + $this->roboClass = $className; + } + } + // Convert directory to a real path, but only if the + // path exists. We do not want to lose the original + // directory if the user supplied a bad value. + $realDir = realpath($this->dir); + if ($realDir) { + chdir($realDir); + $this->dir = $realDir; + } + + return $argv; + } + + /** + * @param string $needle + * @param string[] $haystack + * + * @return bool|int + */ + protected function arraySearchBeginsWith($needle, $haystack) + { + for ($i = 0; $i < count($haystack); ++$i) { + if (substr($haystack[$i], 0, strlen($needle)) == $needle) { + return $i; + } + } + return false; + } + + public function shutdown() + { + $error = error_get_last(); + if (!is_array($error)) { + return; + } + $this->writeln(sprintf("ERROR: %s \nin %s:%d\n", $error['message'], $error['file'], $error['line'])); + } + + /** + * This is just a proxy error handler that checks the current error_reporting level. + * In case error_reporting is disabled the error is marked as handled, otherwise + * the normal internal error handling resumes. + * + * @return bool + */ + public function handleError() + { + if (error_reporting() === 0) { + return true; + } + return false; + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/ApiGen/ApiGen.php b/src/composer/vendor/consolidation/robo/src/Task/ApiGen/ApiGen.php new file mode 100644 index 00000000..0d1b35a0 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/ApiGen/ApiGen.php @@ -0,0 +1,482 @@ +taskApiGen('./apigen.neon') + * ->templateConfig('vendor/apigen/apigen/templates/bootstrap/config.neon') + * ->wipeout(true) + * ->run(); + * ?> + * ``` + */ +class ApiGen extends BaseTask implements CommandInterface +{ + use \Robo\Common\ExecOneCommand; + + const BOOL_NO = 'no'; + const BOOL_YES = 'yes'; + + /** + * @var string + */ + protected $command; + + /** + * @param null|string $pathToApiGen + * + * @throws \Robo\Exception\TaskException + */ + public function __construct($pathToApiGen = null) + { + $this->command = $pathToApiGen; + if (!$this->command) { + $this->command = $this->findExecutablePhar('apigen'); + } + if (!$this->command) { + throw new TaskException(__CLASS__, "No apigen installation found"); + } + } + + /** + * @param array|Traversable|string $arg a single object or something traversable + * + * @return array|Traversable the provided argument if it was already traversable, or the given + * argument returned as a one-element array + */ + protected static function forceTraversable($arg) + { + $traversable = $arg; + if (!is_array($traversable) && !($traversable instanceof \Traversable)) { + $traversable = array($traversable); + } + return $traversable; + } + + /** + * @param array|string $arg a single argument or an array of multiple string values + * + * @return string a comma-separated string of all of the provided arguments, suitable + * as a command-line "list" type argument for ApiGen + */ + protected static function asList($arg) + { + $normalized = is_array($arg) ? $arg : array($arg); + return implode(',', $normalized); + } + + /** + * @param bool|string $val an argument to be normalized + * @param string $default one of self::BOOL_YES or self::BOOK_NO if the provided + * value could not deterministically be converted to a + * yes or no value + * + * @return string the given value as a command-line "yes|no" type of argument for ApiGen, + * or the default value if none could be determined + */ + protected static function asTextBool($val, $default) + { + if ($val === self::BOOL_YES || $val === self::BOOL_NO) { + return $val; + } + if (!$val) { + return self::BOOL_NO; + } + if ($val === true) { + return self::BOOL_YES; + } + if (is_numeric($val) && $val != 0) { + return self::BOOL_YES; + } + if (strcasecmp($val[0], 'y') === 0) { + return self::BOOL_YES; + } + if (strcasecmp($val[0], 'n') === 0) { + return self::BOOL_NO; + } + // meh, good enough, let apigen sort it out + return $default; + } + + /** + * @param string $config + * + * @return $this + */ + public function config($config) + { + $this->option('config', $config); + return $this; + } + + /** + * @param array|string|Traversable $src one or more source values + * + * @return $this + */ + public function source($src) + { + foreach (self::forceTraversable($src) as $source) { + $this->option('source', $source); + } + return $this; + } + + /** + * @param string $dest + * + * @return $this + */ + public function destination($dest) + { + $this->option('destination', $dest); + return $this; + } + + /** + * @param array|string $exts one or more extensions + * + * @return $this + */ + public function extensions($exts) + { + $this->option('extensions', self::asList($exts)); + return $this; + } + + /** + * @param array|string $exclude one or more exclusions + * + * @return $this + */ + public function exclude($exclude) + { + foreach (self::forceTraversable($exclude) as $excl) { + $this->option('exclude', $excl); + } + return $this; + } + + /** + * @param array|string|Traversable $path one or more skip-doc-path values + * + * @return $this + */ + public function skipDocPath($path) + { + foreach (self::forceTraversable($path) as $skip) { + $this->option('skip-doc-path', $skip); + } + return $this; + } + + /** + * @param array|string|Traversable $prefix one or more skip-doc-prefix values + * + * @return $this + */ + public function skipDocPrefix($prefix) + { + foreach (self::forceTraversable($prefix) as $skip) { + $this->option('skip-doc-prefix', $skip); + } + return $this; + } + + /** + * @param array|string $charset one or more charsets + * + * @return $this + */ + public function charset($charset) + { + $this->option('charset', self::asList($charset)); + return $this; + } + + /** + * @param string $name + * + * @return $this + */ + public function mainProjectNamePrefix($name) + { + $this->option('main', $name); + return $this; + } + + /** + * @param string $title + * + * @return $this + */ + public function title($title) + { + $this->option('title', $title); + return $this; + } + + /** + * @param string $baseUrl + * + * @return $this + */ + public function baseUrl($baseUrl) + { + $this->option('base-url', $baseUrl); + return $this; + } + + /** + * @param string $id + * + * @return $this + */ + public function googleCseId($id) + { + $this->option('google-cse-id', $id); + return $this; + } + + /** + * @param string $trackingCode + * + * @return $this + */ + public function googleAnalytics($trackingCode) + { + $this->option('google-analytics', $trackingCode); + return $this; + } + + /** + * @param mixed $templateConfig + * + * @return $this + */ + public function templateConfig($templateConfig) + { + $this->option('template-config', $templateConfig); + return $this; + } + + /** + * @param array|string $tags one or more supported html tags + * + * @return $this + */ + public function allowedHtml($tags) + { + $this->option('allowed-html', self::asList($tags)); + return $this; + } + + /** + * @param string $groups + * + * @return $this + */ + public function groups($groups) + { + $this->option('groups', $groups); + return $this; + } + + /** + * @param array|string $types or more supported autocomplete types + * + * @return $this + */ + public function autocomplete($types) + { + $this->option('autocomplete', self::asList($types)); + return $this; + } + + /** + * @param array|string $levels one or more access levels + * + * @return $this + */ + public function accessLevels($levels) + { + $this->option('access-levels', self::asList($levels)); + return $this; + } + + /** + * @param boolean|string $internal 'yes' or true if internal, 'no' or false if not + * + * @return $this + */ + public function internal($internal) + { + $this->option('internal', self::asTextBool($internal, self::BOOL_NO)); + return $this; + } + + /** + * @param boolean|string $php 'yes' or true to generate documentation for internal php classes, + * 'no' or false otherwise + * + * @return $this + */ + public function php($php) + { + $this->option('php', self::asTextBool($php, self::BOOL_YES)); + return $this; + } + + /** + * @param bool|string $tree 'yes' or true to generate a tree view of classes, 'no' or false otherwise + * + * @return $this + */ + public function tree($tree) + { + $this->option('tree', self::asTextBool($tree, self::BOOL_YES)); + return $this; + } + + /** + * @param bool|string $dep 'yes' or true to generate documentation for deprecated classes, 'no' or false otherwise + * + * @return $this + */ + public function deprecated($dep) + { + $this->option('deprecated', self::asTextBool($dep, self::BOOL_NO)); + return $this; + } + + /** + * @param bool|string $todo 'yes' or true to document tasks, 'no' or false otherwise + * + * @return $this + */ + public function todo($todo) + { + $this->option('todo', self::asTextBool($todo, self::BOOL_NO)); + return $this; + } + + /** + * @param bool|string $src 'yes' or true to generate highlighted source code, 'no' or false otherwise + * + * @return $this + */ + public function sourceCode($src) + { + $this->option('source-code', self::asTextBool($src, self::BOOL_YES)); + return $this; + } + + /** + * @param bool|string $zipped 'yes' or true to generate downloadable documentation, 'no' or false otherwise + * + * @return $this + */ + public function download($zipped) + { + $this->option('download', self::asTextBool($zipped, self::BOOL_NO)); + return $this; + } + + public function report($path) + { + $this->option('report', $path); + return $this; + } + + /** + * @param bool|string $wipeout 'yes' or true to clear out the destination directory, 'no' or false otherwise + * + * @return $this + */ + public function wipeout($wipeout) + { + $this->option('wipeout', self::asTextBool($wipeout, self::BOOL_YES)); + return $this; + } + + /** + * @param bool|string $quiet 'yes' or true for quiet, 'no' or false otherwise + * + * @return $this + */ + public function quiet($quiet) + { + $this->option('quiet', self::asTextBool($quiet, self::BOOL_NO)); + return $this; + } + + /** + * @param bool|string $bar 'yes' or true to display a progress bar, 'no' or false otherwise + * + * @return $this + */ + public function progressbar($bar) + { + $this->option('progressbar', self::asTextBool($bar, self::BOOL_YES)); + return $this; + } + + /** + * @param bool|string $colors 'yes' or true colorize the output, 'no' or false otherwise + * + * @return $this + */ + public function colors($colors) + { + $this->option('colors', self::asTextBool($colors, self::BOOL_YES)); + return $this; + } + + /** + * @param bool|string $check 'yes' or true to check for updates, 'no' or false otherwise + * + * @return $this + */ + public function updateCheck($check) + { + $this->option('update-check', self::asTextBool($check, self::BOOL_YES)); + return $this; + } + + /** + * @param bool|string $debug 'yes' or true to enable debug mode, 'no' or false otherwise + * + * @return $this + */ + public function debug($debug) + { + $this->option('debug', self::asTextBool($debug, self::BOOL_NO)); + return $this; + } + + /** + * {@inheritdoc} + */ + public function getCommand() + { + return $this->command . $this->arguments; + } + + /** + * {@inheritdoc} + */ + public function run() + { + $this->printTaskInfo('Running ApiGen {args}', ['args' => $this->arguments]); + return $this->executeCommand($this->getCommand()); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/ApiGen/loadTasks.php b/src/composer/vendor/consolidation/robo/src/Task/ApiGen/loadTasks.php new file mode 100644 index 00000000..e8cd372a --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/ApiGen/loadTasks.php @@ -0,0 +1,15 @@ +task(ApiGen::class, $pathToApiGen); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Archive/Extract.php b/src/composer/vendor/consolidation/robo/src/Task/Archive/Extract.php new file mode 100644 index 00000000..add5397f --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Archive/Extract.php @@ -0,0 +1,281 @@ +taskExtract($archivePath) + * ->to($destination) + * ->preserveTopDirectory(false) // the default + * ->run(); + * ?> + * ``` + * + * @method to(string) location to store extracted files + */ +class Extract extends BaseTask implements BuilderAwareInterface +{ + use BuilderAwareTrait; + + /** + * @var string + */ + protected $filename; + + /** + * @var string + */ + protected $to; + + /** + * @var bool + */ + private $preserveTopDirectory = false; + + /** + * @param string $filename + */ + public function __construct($filename) + { + $this->filename = $filename; + } + + /** + * Location to store extracted files. + * + * @param string $to + * + * @return $this + */ + public function to($to) + { + $this->to = $to; + return $this; + } + + /** + * @param bool $preserve + * + * @return $this + */ + public function preserveTopDirectory($preserve = true) + { + $this->preserveTopDirectory = $preserve; + return $this; + } + + /** + * {@inheritdoc} + */ + public function run() + { + if (!file_exists($this->filename)) { + $this->printTaskError("File {filename} does not exist", ['filename' => $this->filename]); + + return false; + } + if (!($mimetype = static::archiveType($this->filename))) { + $this->printTaskError("Could not determine type of archive for {filename}", ['filename' => $this->filename]); + + return false; + } + + // We will first extract to $extractLocation and then move to $this->to + $extractLocation = static::getTmpDir(); + @mkdir($extractLocation); + @mkdir(dirname($this->to)); + + $this->startTimer(); + + $this->printTaskInfo("Extracting {filename}", ['filename' => $this->filename]); + + $result = $this->extractAppropriateType($mimetype, $extractLocation); + if ($result->wasSuccessful()) { + $this->printTaskInfo("{filename} extracted", ['filename' => $this->filename]); + // Now, we want to move the extracted files to $this->to. There + // are two possibilities that we must consider: + // + // (1) Archived files were encapsulated in a folder with an arbitrary name + // (2) There was no encapsulating folder, and all the files in the archive + // were extracted into $extractLocation + // + // In the case of (1), we want to move and rename the encapsulating folder + // to $this->to. + // + // In the case of (2), we will just move and rename $extractLocation. + $filesInExtractLocation = glob("$extractLocation/*"); + $hasEncapsulatingFolder = ((count($filesInExtractLocation) == 1) && is_dir($filesInExtractLocation[0])); + if ($hasEncapsulatingFolder && !$this->preserveTopDirectory) { + $result = (new FilesystemStack()) + ->inflect($this) + ->rename($filesInExtractLocation[0], $this->to) + ->run(); + (new DeleteDir($extractLocation)) + ->inflect($this) + ->run(); + } else { + $result = (new FilesystemStack()) + ->inflect($this) + ->rename($extractLocation, $this->to) + ->run(); + } + } + $this->stopTimer(); + $result['time'] = $this->getExecutionTime(); + + return $result; + } + + /** + * @param string $mimetype + * @param string $extractLocation + * + * @return \Robo\Result + */ + protected function extractAppropriateType($mimetype, $extractLocation) + { + // Perform the extraction of a zip file. + if (($mimetype == 'application/zip') || ($mimetype == 'application/x-zip')) { + return $this->extractZip($extractLocation); + } + return $this->extractTar($extractLocation); + } + + /** + * @param string $extractLocation + * + * @return \Robo\Result + */ + protected function extractZip($extractLocation) + { + if (!extension_loaded('zlib')) { + return Result::errorMissingExtension($this, 'zlib', 'zip extracting'); + } + + $zip = new \ZipArchive(); + if (($status = $zip->open($this->filename)) !== true) { + return Result::error($this, "Could not open zip archive {$this->filename}"); + } + if (!$zip->extractTo($extractLocation)) { + return Result::error($this, "Could not extract zip archive {$this->filename}"); + } + $zip->close(); + + return Result::success($this); + } + + /** + * @param string $extractLocation + * + * @return \Robo\Result + */ + protected function extractTar($extractLocation) + { + if (!class_exists('Archive_Tar')) { + return Result::errorMissingPackage($this, 'Archive_Tar', 'pear/archive_tar'); + } + $tar_object = new \Archive_Tar($this->filename); + if (!$tar_object->extract($extractLocation)) { + return Result::error($this, "Could not extract tar archive {$this->filename}"); + } + + return Result::success($this); + } + + /** + * @param string $filename + * + * @return bool|string + */ + protected static function archiveType($filename) + { + $content_type = false; + if (class_exists('finfo')) { + $finfo = new \finfo(FILEINFO_MIME_TYPE); + $content_type = $finfo->file($filename); + // If finfo cannot determine the content type, then we will try other methods + if ($content_type == 'application/octet-stream') { + $content_type = false; + } + } + // Examing the file's magic header bytes. + if (!$content_type) { + if ($file = fopen($filename, 'rb')) { + $first = fread($file, 2); + fclose($file); + if ($first !== false) { + // Interpret the two bytes as a little endian 16-bit unsigned int. + $data = unpack('v', $first); + switch ($data[1]) { + case 0x8b1f: + // First two bytes of gzip files are 0x1f, 0x8b (little-endian). + // See http://www.gzip.org/zlib/rfc-gzip.html#header-trailer + $content_type = 'application/x-gzip'; + break; + + case 0x4b50: + // First two bytes of zip files are 0x50, 0x4b ('PK') (little-endian). + // See http://en.wikipedia.org/wiki/Zip_(file_format)#File_headers + $content_type = 'application/zip'; + break; + + case 0x5a42: + // First two bytes of bzip2 files are 0x5a, 0x42 ('BZ') (big-endian). + // See http://en.wikipedia.org/wiki/Bzip2#File_format + $content_type = 'application/x-bzip2'; + break; + } + } + } + } + // 3. Lastly if above methods didn't work, try to guess the mime type from + // the file extension. This is useful if the file has no identificable magic + // header bytes (for example tarballs). + if (!$content_type) { + // Remove querystring from the filename, if present. + $filename = basename(current(explode('?', $filename, 2))); + $extension_mimetype = array( + '.tar.gz' => 'application/x-gzip', + '.tgz' => 'application/x-gzip', + '.tar' => 'application/x-tar', + ); + foreach ($extension_mimetype as $extension => $ct) { + if (substr($filename, -strlen($extension)) === $extension) { + $content_type = $ct; + break; + } + } + } + + return $content_type; + } + + /** + * @return string + */ + protected static function getTmpDir() + { + return getcwd().'/tmp'.rand().time(); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Archive/Pack.php b/src/composer/vendor/consolidation/robo/src/Task/Archive/Pack.php new file mode 100644 index 00000000..0970f8e8 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Archive/Pack.php @@ -0,0 +1,257 @@ +taskPack( + * ) + * ->add('README') // Puts file 'README' in archive at the root + * ->add('project') // Puts entire contents of directory 'project' in archinve inside 'project' + * ->addFile('dir/file.txt', 'file.txt') // Takes 'file.txt' from cwd and puts it in archive inside 'dir'. + * ->run(); + * ?> + * ``` + */ +class Pack extends BaseTask implements PrintedInterface +{ + /** + * The list of items to be packed into the archive. + * + * @var array + */ + private $items = []; + + /** + * The full path to the archive to be created. + * + * @var string + */ + private $archiveFile; + + /** + * Construct the class. + * + * @param string $archiveFile The full path and name of the archive file to create. + * + * @since 1.0 + */ + public function __construct($archiveFile) + { + $this->archiveFile = $archiveFile; + } + + /** + * Satisfy the parent requirement. + * + * @return bool Always returns true. + * + * @since 1.0 + */ + public function getPrinted() + { + return true; + } + + /** + * @param string $archiveFile + * + * @return $this + */ + public function archiveFile($archiveFile) + { + $this->archiveFile = $archiveFile; + return $this; + } + + /** + * Add an item to the archive. Like file_exists(), the parameter + * may be a file or a directory. + * + * @var string + * Relative path and name of item to store in archive + * @var string + * Absolute or relative path to file or directory's location in filesystem + * + * @return $this + */ + public function addFile($placementLocation, $filesystemLocation) + { + $this->items[$placementLocation] = $filesystemLocation; + + return $this; + } + + /** + * Alias for addFile, in case anyone has angst about using + * addFile with a directory. + * + * @var string + * Relative path and name of directory to store in archive + * @var string + * Absolute or relative path to directory or directory's location in filesystem + * + * @return $this + */ + public function addDir($placementLocation, $filesystemLocation) + { + $this->addFile($placementLocation, $filesystemLocation); + + return $this; + } + + /** + * Add a file or directory, or list of same to the archive. + * + * @var string|array + * If given a string, should contain the relative filesystem path to the + * the item to store in archive; this will also be used as the item's + * path in the archive, so absolute paths should not be used here. + * If given an array, the key of each item should be the path to store + * in the archive, and the value should be the filesystem path to the + * item to store. + * @return $this + */ + public function add($item) + { + if (is_array($item)) { + $this->items = array_merge($this->items, $item); + } else { + $this->addFile($item, $item); + } + + return $this; + } + + /** + * Create a zip archive for distribution. + * + * @return \Robo\Result + * + * @since 1.0 + */ + public function run() + { + $this->startTimer(); + + // Use the file extension to determine what kind of archive to create. + $fileInfo = new \SplFileInfo($this->archiveFile); + $extension = strtolower($fileInfo->getExtension()); + if (empty($extension)) { + return Result::error($this, "Archive filename must use an extension (e.g. '.zip') to specify the kind of archive to create."); + } + + try { + // Inform the user which archive we are creating + $this->printTaskInfo("Creating archive {filename}", ['filename' => $this->archiveFile]); + if ($extension == 'zip') { + $result = $this->archiveZip($this->archiveFile, $this->items); + } else { + $result = $this->archiveTar($this->archiveFile, $this->items); + } + $this->printTaskSuccess("{filename} created.", ['filename' => $this->archiveFile]); + } catch (\Exception $e) { + $this->printTaskError("Could not create {filename}. {exception}", ['filename' => $this->archiveFile, 'exception' => $e->getMessage(), '_style' => ['exception' => '']]); + $result = Result::error($this, sprintf('Could not create %s. %s', $this->archiveFile, $e->getMessage())); + } + $this->stopTimer(); + $result['time'] = $this->getExecutionTime(); + + return $result; + } + + /** + * @param string $archiveFile + * @param array $items + * + * @return \Robo\Result + */ + protected function archiveTar($archiveFile, $items) + { + if (!class_exists('Archive_Tar')) { + return Result::errorMissingPackage($this, 'Archive_Tar', 'pear/archive_tar'); + } + + $tar_object = new \Archive_Tar($archiveFile); + foreach ($items as $placementLocation => $filesystemLocation) { + $p_remove_dir = $filesystemLocation; + $p_add_dir = $placementLocation; + if (is_file($filesystemLocation)) { + $p_remove_dir = dirname($filesystemLocation); + $p_add_dir = dirname($placementLocation); + if (basename($filesystemLocation) != basename($placementLocation)) { + return Result::error($this, "Tar archiver does not support renaming files during extraction; could not add $filesystemLocation as $placementLocation."); + } + } + + if (!$tar_object->addModify([$filesystemLocation], $p_add_dir, $p_remove_dir)) { + return Result::error($this, "Could not add $filesystemLocation to the archive."); + } + } + + return Result::success($this); + } + + /** + * @param string $archiveFile + * @param array $items + * + * @return \Robo\Result + */ + protected function archiveZip($archiveFile, $items) + { + if (!extension_loaded('zlib')) { + return Result::errorMissingExtension($this, 'zlib', 'zip packing'); + } + + $zip = new \ZipArchive($archiveFile, \ZipArchive::CREATE); + if (!$zip->open($archiveFile, \ZipArchive::CREATE)) { + return Result::error($this, "Could not create zip archive {$archiveFile}"); + } + $result = $this->addItemsToZip($zip, $items); + $zip->close(); + + return $result; + } + + /** + * @param \ZipArchive $zip + * @param array $items + * + * @return \Robo\Result + */ + protected function addItemsToZip($zip, $items) + { + foreach ($items as $placementLocation => $filesystemLocation) { + if (is_dir($filesystemLocation)) { + $finder = new Finder(); + $finder->files()->in($filesystemLocation)->ignoreDotFiles(false); + + foreach ($finder as $file) { + // Replace Windows slashes or resulting zip will have issues on *nixes. + $relativePathname = str_replace('\\', '/', $file->getRelativePathname()); + + if (!$zip->addFile($file->getRealpath(), "{$placementLocation}/{$relativePathname}")) { + return Result::error($this, "Could not add directory $filesystemLocation to the archive; error adding {$file->getRealpath()}."); + } + } + } elseif (is_file($filesystemLocation)) { + if (!$zip->addFile($filesystemLocation, $placementLocation)) { + return Result::error($this, "Could not add file $filesystemLocation to the archive."); + } + } else { + return Result::error($this, "Could not find $filesystemLocation for the archive."); + } + } + + return Result::success($this); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Archive/loadTasks.php b/src/composer/vendor/consolidation/robo/src/Task/Archive/loadTasks.php new file mode 100644 index 00000000..cf846fdf --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Archive/loadTasks.php @@ -0,0 +1,25 @@ +task(Pack::class, $filename); + } + + /** + * @param $filename + * + * @return Extract + */ + protected function taskExtract($filename) + { + return $this->task(Extract::class, $filename); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Assets/CssPreprocessor.php b/src/composer/vendor/consolidation/robo/src/Task/Assets/CssPreprocessor.php new file mode 100644 index 00000000..a15d2078 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Assets/CssPreprocessor.php @@ -0,0 +1,214 @@ +files = $input; + + $this->setDefaultCompiler(); + } + + protected function setDefaultCompiler() + { + if (isset($this->compilers[0])) { + //set first compiler as default + $this->compiler = $this->compilers[0]; + } + } + + /** + * Sets import directories + * Alias for setImportPaths + * @see CssPreprocessor::setImportPaths + * + * @param array|string $dirs + * + * @return $this + */ + public function importDir($dirs) + { + return $this->setImportPaths($dirs); + } + + /** + * Adds import directory + * + * @param string $dir + * + * @return $this + */ + public function addImportPath($dir) + { + if (!isset($this->compilerOptions['importDirs'])) { + $this->compilerOptions['importDirs'] = []; + } + + if (!in_array($dir, $this->compilerOptions['importDirs'], true)) { + $this->compilerOptions['importDirs'][] = $dir; + } + + return $this; + } + + /** + * Sets import directories + * + * @param array|string $dirs + * + * @return $this + */ + public function setImportPaths($dirs) + { + if (!is_array($dirs)) { + $dirs = [$dirs]; + } + + $this->compilerOptions['importDirs'] = $dirs; + + return $this; + } + + /** + * @param string $formatterName + * + * @return $this + */ + public function setFormatter($formatterName) + { + $this->compilerOptions['formatter'] = $formatterName; + + return $this; + } + + /** + * Sets the compiler. + * + * @param string $compiler + * @param array $options + * + * @return $this + */ + public function compiler($compiler, array $options = []) + { + $this->compiler = $compiler; + $this->compilerOptions = array_merge($this->compilerOptions, $options); + + return $this; + } + + /** + * Compiles file + * + * @param $file + * + * @return bool|mixed + */ + protected function compile($file) + { + if (is_callable($this->compiler)) { + return call_user_func($this->compiler, $file, $this->compilerOptions); + } + + if (method_exists($this, $this->compiler)) { + return $this->{$this->compiler}($file); + } + + return false; + } + + /** + * {@inheritdoc} + */ + public function run() + { + if (!in_array($this->compiler, $this->compilers, true) + && !is_callable($this->compiler) + ) { + $message = sprintf('Invalid ' . static::FORMAT_NAME . ' compiler %s!', $this->compiler); + + return Result::error($this, $message); + } + + foreach ($this->files as $in => $out) { + if (!file_exists($in)) { + $message = sprintf('File %s not found.', $in); + + return Result::error($this, $message); + } + if (file_exists($out) && !is_writable($out)) { + return Result::error($this, 'Destination already exists and cannot be overwritten.'); + } + } + + foreach ($this->files as $in => $out) { + $css = $this->compile($in); + + if ($css instanceof Result) { + return $css; + } elseif (false === $css) { + $message = sprintf( + ucfirst(static::FORMAT_NAME) . ' compilation failed for %s.', + $in + ); + + return Result::error($this, $message); + } + + $dst = $out . '.part'; + $write_result = file_put_contents($dst, $css); + + if (false === $write_result) { + $message = sprintf('File write failed: %s', $out); + + @unlink($dst); + return Result::error($this, $message); + } + + // Cannot be cross-volume: should always succeed + @rename($dst, $out); + + $this->printTaskSuccess('Wrote CSS to {filename}', ['filename' => $out]); + } + + return Result::success($this, 'All ' . static::FORMAT_NAME . ' files compiled.'); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Assets/ImageMinify.php b/src/composer/vendor/consolidation/robo/src/Task/Assets/ImageMinify.php new file mode 100644 index 00000000..1aa62593 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Assets/ImageMinify.php @@ -0,0 +1,716 @@ +taskImageMinify('assets/images/*') + * ->to('dist/images/') + * ->run(); + * ``` + * + * This will use the following minifiers: + * + * - PNG: optipng + * - GIF: gifsicle + * - JPG, JPEG: jpegtran + * - SVG: svgo + * + * When the minifier is specified the task will use that for all the input files. In that case + * it is useful to filter the files with the extension: + * + * ```php + * $this->taskImageMinify('assets/images/*.png') + * ->to('dist/images/') + * ->minifier('pngcrush'); + * ->run(); + * ``` + * + * The task supports the following minifiers: + * + * - optipng + * - pngquant + * - advpng + * - pngout + * - zopflipng + * - pngcrush + * - gifsicle + * - jpegoptim + * - jpeg-recompress + * - jpegtran + * - svgo (only minification, no downloading) + * + * You can also specifiy extra options for the minifiers: + * + * ```php + * $this->taskImageMinify('assets/images/*.jpg') + * ->to('dist/images/') + * ->minifier('jpegtran', ['-progressive' => null, '-copy' => 'none']) + * ->run(); + * ``` + * + * This will execute as: + * `jpegtran -copy none -progressive -optimize -outfile "dist/images/test.jpg" "/var/www/test/assets/images/test.jpg"` + */ +class ImageMinify extends BaseTask +{ + /** + * Destination directory for the minified images. + * + * @var string + */ + protected $to; + + /** + * Array of the source files. + * + * @var array + */ + protected $dirs = []; + + /** + * Symfony 2 filesystem. + * + * @var sfFilesystem + */ + protected $fs; + + /** + * Target directory for the downloaded binary executables. + * + * @var string + */ + protected $executableTargetDir; + + /** + * Array for the downloaded binary executables. + * + * @var array + */ + protected $executablePaths = []; + + /** + * Array for the individual results of all the files. + * + * @var array + */ + protected $results = []; + + /** + * Default minifier to use. + * + * @var string + */ + protected $minifier; + + /** + * Array for minifier options. + * + * @var array + */ + protected $minifierOptions = []; + + /** + * Supported minifiers. + * + * @var array + */ + protected $minifiers = [ + // Default 4 + 'optipng', + 'gifsicle', + 'jpegtran', + 'svgo', + // PNG + 'pngquant', + 'advpng', + 'pngout', + 'zopflipng', + 'pngcrush', + // JPG + 'jpegoptim', + 'jpeg-recompress', + ]; + + /** + * Binary repositories of Imagemin. + * + * @link https://github.com/imagemin + * + * @var array + */ + protected $imageminRepos = [ + // PNG + 'optipng' => 'https://github.com/imagemin/optipng-bin', + 'pngquant' => 'https://github.com/imagemin/pngquant-bin', + 'advpng' => 'https://github.com/imagemin/advpng-bin', + 'pngout' => 'https://github.com/imagemin/pngout-bin', + 'zopflipng' => 'https://github.com/imagemin/zopflipng-bin', + 'pngcrush' => 'https://github.com/imagemin/pngcrush-bin', + // Gif + 'gifsicle' => 'https://github.com/imagemin/gifsicle-bin', + // JPG + 'jpegtran' => 'https://github.com/imagemin/jpegtran-bin', + 'jpegoptim' => 'https://github.com/imagemin/jpegoptim-bin', + 'cjpeg' => 'https://github.com/imagemin/mozjpeg-bin', // note: we do not support this minifier because it creates JPG from non-JPG files + 'jpeg-recompress' => 'https://github.com/imagemin/jpeg-recompress-bin', + // WebP + 'cwebp' => 'https://github.com/imagemin/cwebp-bin', // note: we do not support this minifier because it creates WebP from non-WebP files + ]; + + public function __construct($dirs) + { + is_array($dirs) + ? $this->dirs = $dirs + : $this->dirs[] = $dirs; + + $this->fs = new sfFilesystem(); + + // guess the best path for the executables based on __DIR__ + if (($pos = strpos(__DIR__, 'consolidation/robo')) !== false) { + // the executables should be stored in vendor/bin + $this->executableTargetDir = substr(__DIR__, 0, $pos).'bin'; + } + + // check if the executables are already available + foreach ($this->imageminRepos as $exec => $url) { + $path = $this->executableTargetDir.'/'.$exec; + // if this is Windows add a .exe extension + if (substr($this->getOS(), 0, 3) == 'win') { + $path .= '.exe'; + } + if (is_file($path)) { + $this->executablePaths[$exec] = $path; + } + } + } + + /** + * {@inheritdoc} + */ + public function run() + { + // find the files + $files = $this->findFiles($this->dirs); + + // minify the files + $result = $this->minify($files); + // check if there was an error + if ($result instanceof Result) { + return $result; + } + + $amount = (count($files) == 1 ? 'image' : 'images'); + $message = "Minified {filecount} out of {filetotal} $amount into {destination}"; + $context = ['filecount' => count($this->results['success']), 'filetotal' => count($files), 'destination' => $this->to]; + + if (count($this->results['success']) == count($files)) { + $this->printTaskSuccess($message, $context); + + return Result::success($this, $message, $context); + } else { + return Result::error($this, $message, $context); + } + } + + /** + * Sets the target directory where the files will be copied to. + * + * @param string $target + * + * @return $this + */ + public function to($target) + { + $this->to = rtrim($target, '/'); + + return $this; + } + + /** + * Sets the minifier. + * + * @param string $minifier + * @param array $options + * + * @return $this + */ + public function minifier($minifier, array $options = []) + { + $this->minifier = $minifier; + $this->minifierOptions = array_merge($this->minifierOptions, $options); + + return $this; + } + + /** + * @param array $dirs + * + * @return array|\Robo\Result + * + * @throws \Robo\Exception\TaskException + */ + protected function findFiles($dirs) + { + $files = array(); + + // find the files + foreach ($dirs as $k => $v) { + // reset finder + $finder = new Finder(); + + $dir = $k; + $to = $v; + // check if target was given with the to() method instead of key/value pairs + if (is_int($k)) { + $dir = $v; + if (isset($this->to)) { + $to = $this->to; + } else { + throw new TaskException($this, 'target directory is not defined'); + } + } + + try { + $finder->files()->in($dir); + } catch (\InvalidArgumentException $e) { + // if finder cannot handle it, try with in()->name() + if (strpos($dir, '/') === false) { + $dir = './'.$dir; + } + $parts = explode('/', $dir); + $new_dir = implode('/', array_slice($parts, 0, -1)); + try { + $finder->files()->in($new_dir)->name(array_pop($parts)); + } catch (\InvalidArgumentException $e) { + return Result::fromException($this, $e); + } + } + + foreach ($finder as $file) { + // store the absolute path as key and target as value in the files array + $files[$file->getRealpath()] = $this->getTarget($file->getRealPath(), $to); + } + $fileNoun = count($finder) == 1 ? ' file' : ' files'; + $this->printTaskInfo("Found {filecount} $fileNoun in {dir}", ['filecount' => count($finder), 'dir' => $dir]); + } + + return $files; + } + + /** + * @param string $file + * @param string $to + * + * @return string + */ + protected function getTarget($file, $to) + { + $target = $to.'/'.basename($file); + + return $target; + } + + /** + * @param array $files + * + * @return \Robo\Result + */ + protected function minify($files) + { + // store the individual results into the results array + $this->results = [ + 'success' => [], + 'error' => [], + ]; + + // loop through the files + foreach ($files as $from => $to) { + if (!isset($this->minifier)) { + // check filetype based on the extension + $extension = strtolower(pathinfo($from, PATHINFO_EXTENSION)); + + // set the default minifiers based on the extension + switch ($extension) { + case 'png': + $minifier = 'optipng'; + break; + case 'jpg': + case 'jpeg': + $minifier = 'jpegtran'; + break; + case 'gif': + $minifier = 'gifsicle'; + break; + case 'svg': + $minifier = 'svgo'; + break; + } + } else { + if (!in_array($this->minifier, $this->minifiers, true) + && !is_callable(strtr($this->minifier, '-', '_')) + ) { + $message = sprintf('Invalid minifier %s!', $this->minifier); + + return Result::error($this, $message); + } + $minifier = $this->minifier; + } + + // Convert minifier name to camelCase (e.g. jpeg-recompress) + $funcMinifier = $this->camelCase($minifier); + + // call the minifier method which prepares the command + if (is_callable($funcMinifier)) { + $command = call_user_func($funcMinifier, $from, $to, $this->minifierOptions); + } elseif (method_exists($this, $funcMinifier)) { + $command = $this->{$funcMinifier}($from, $to); + } else { + $message = sprintf('Minifier method %s cannot be found!', $funcMinifier); + + return Result::error($this, $message); + } + + // launch the command + $this->printTaskInfo('Minifying {filepath} with {minifier}', ['filepath' => $from, 'minifier' => $minifier]); + $result = $this->executeCommand($command); + + // check the return code + if ($result->getExitCode() == 127) { + $this->printTaskError('The {minifier} executable cannot be found', ['minifier' => $minifier]); + // try to install from imagemin repository + if (array_key_exists($minifier, $this->imageminRepos)) { + $result = $this->installFromImagemin($minifier); + if ($result instanceof Result) { + if ($result->wasSuccessful()) { + $this->printTaskSuccess($result->getMessage()); + // retry the conversion with the downloaded executable + if (is_callable($minifier)) { + $command = call_user_func($minifier, $from, $to, $minifierOptions); + } elseif (method_exists($this, $minifier)) { + $command = $this->{$minifier}($from, $to); + } + // launch the command + $this->printTaskInfo('Minifying {filepath} with {minifier}', ['filepath' => $from, 'minifier' => $minifier]); + $result = $this->executeCommand($command); + } else { + $this->printTaskError($result->getMessage()); + // the download was not successful + return $result; + } + } + } else { + return $result; + } + } + + // check the success of the conversion + if ($result->getExitCode() !== 0) { + $this->results['error'][] = $from; + } else { + $this->results['success'][] = $from; + } + } + } + + /** + * @return string + */ + protected function getOS() + { + $os = php_uname('s'); + $os .= '/'.php_uname('m'); + // replace x86_64 to x64, because the imagemin repo uses that + $os = str_replace('x86_64', 'x64', $os); + // replace i386, i686, etc to x86, because of imagemin + $os = preg_replace('/i[0-9]86/', 'x86', $os); + // turn info to lowercase, because of imagemin + $os = strtolower($os); + + return $os; + } + + /** + * @param string $command + * + * @return \Robo\Result + */ + protected function executeCommand($command) + { + // insert the options into the command + $a = explode(' ', $command); + $executable = array_shift($a); + foreach ($this->minifierOptions as $key => $value) { + // first prepend the value + if (!empty($value)) { + array_unshift($a, $value); + } + // then add the key + if (!is_numeric($key)) { + array_unshift($a, $key); + } + } + // check if the executable can be replaced with the downloaded one + if (array_key_exists($executable, $this->executablePaths)) { + $executable = $this->executablePaths[$executable]; + } + array_unshift($a, $executable); + $command = implode(' ', $a); + + // execute the command + $exec = new Exec($command); + + return $exec->inflect($this)->printed(false)->run(); + } + + /** + * @param string $executable + * + * @return \Robo\Result + */ + protected function installFromImagemin($executable) + { + // check if there is an url defined for the executable + if (!array_key_exists($executable, $this->imageminRepos)) { + $message = sprintf('The executable %s cannot be found in the defined imagemin repositories', $executable); + + return Result::error($this, $message); + } + $this->printTaskInfo('Downloading the {executable} executable from the imagemin repository', ['executable' => $executable]); + + $os = $this->getOS(); + $url = $this->imageminRepos[$executable].'/blob/master/vendor/'.$os.'/'.$executable.'?raw=true'; + if (substr($os, 0, 3) == 'win') { + // if it is win, add a .exe extension + $url = $this->imageminRepos[$executable].'/blob/master/vendor/'.$os.'/'.$executable.'.exe?raw=true'; + } + $data = @file_get_contents($url, false, null); + if ($data === false) { + // there is something wrong with the url, try it without the version info + $url = preg_replace('/x[68][64]\//', '', $url); + $data = @file_get_contents($url, false, null); + if ($data === false) { + // there is still something wrong with the url if it is win, try with win32 + if (substr($os, 0, 3) == 'win') { + $url = preg_replace('win/', 'win32/', $url); + $data = @file_get_contents($url, false, null); + if ($data === false) { + // there is nothing more we can do + $message = sprintf('Could not download the executable %s', $executable); + + return Result::error($this, $message); + } + } + // if it is not windows there is nothing we can do + $message = sprintf('Could not download the executable %s', $executable); + + return Result::error($this, $message); + } + } + // check if target directory exists + if (!is_dir($this->executableTargetDir)) { + mkdir($this->executableTargetDir); + } + // save the executable into the target dir + $path = $this->executableTargetDir.'/'.$executable; + if (substr($os, 0, 3) == 'win') { + // if it is win, add a .exe extension + $path = $this->executableTargetDir.'/'.$executable.'.exe'; + } + $result = file_put_contents($path, $data); + if ($result === false) { + $message = sprintf('Could not copy the executable %s to %s', $executable, $target_dir); + + return Result::error($this, $message); + } + // set the binary to executable + chmod($path, 0755); + + // if everything successful, store the executable path + $this->executablePaths[$executable] = $this->executableTargetDir.'/'.$executable; + // if it is win, add a .exe extension + if (substr($os, 0, 3) == 'win') { + $this->executablePaths[$executable] .= '.exe'; + } + + $message = sprintf('Executable %s successfully downloaded', $executable); + + return Result::success($this, $message); + } + + /** + * @param string $from + * @param string $to + * + * @return string + */ + protected function optipng($from, $to) + { + $command = sprintf('optipng -quiet -out "%s" -- "%s"', $to, $from); + if ($from != $to && is_file($to)) { + // earlier versions of optipng do not overwrite the target without a backup + // http://sourceforge.net/p/optipng/bugs/37/ + unlink($to); + } + + return $command; + } + + /** + * @param string $from + * @param string $to + * + * @return string + */ + protected function jpegtran($from, $to) + { + $command = sprintf('jpegtran -optimize -outfile "%s" "%s"', $to, $from); + + return $command; + } + + protected function gifsicle($from, $to) + { + $command = sprintf('gifsicle -o "%s" "%s"', $to, $from); + + return $command; + } + + /** + * @param string $from + * @param string $to + * + * @return string + */ + protected function svgo($from, $to) + { + $command = sprintf('svgo "%s" "%s"', $from, $to); + + return $command; + } + + /** + * @param string $from + * @param string $to + * + * @return string + */ + protected function pngquant($from, $to) + { + $command = sprintf('pngquant --force --output "%s" "%s"', $to, $from); + + return $command; + } + + /** + * @param string $from + * @param string $to + * + * @return string + */ + protected function advpng($from, $to) + { + // advpng does not have any output parameters, copy the file and then compress the copy + $command = sprintf('advpng --recompress --quiet "%s"', $to); + $this->fs->copy($from, $to, true); + + return $command; + } + + /** + * @param string $from + * @param string $to + * + * @return string + */ + protected function pngout($from, $to) + { + $command = sprintf('pngout -y -q "%s" "%s"', $from, $to); + + return $command; + } + + /** + * @param string $from + * @param string $to + * + * @return string + */ + protected function zopflipng($from, $to) + { + $command = sprintf('zopflipng -y "%s" "%s"', $from, $to); + + return $command; + } + + /** + * @param string $from + * @param string $to + * + * @return string + */ + protected function pngcrush($from, $to) + { + $command = sprintf('pngcrush -q -ow "%s" "%s"', $from, $to); + + return $command; + } + + /** + * @param string $from + * @param string $to + * + * @return string + */ + protected function jpegoptim($from, $to) + { + // jpegoptim only takes the destination directory as an argument + $command = sprintf('jpegoptim --quiet -o --dest "%s" "%s"', dirname($to), $from); + + return $command; + } + + /** + * @param string $from + * @param string $to + * + * @return string + */ + protected function jpegRecompress($from, $to) + { + $command = sprintf('jpeg-recompress --quiet "%s" "%s"', $from, $to); + + return $command; + } + + /** + * @param string $text + * + * @return string + */ + public static function camelCase($text) + { + // non-alpha and non-numeric characters become spaces + $text = preg_replace('/[^a-z0-9]+/i', ' ', $text); + $text = trim($text); + // uppercase the first character of each word + $text = ucwords($text); + $text = str_replace(" ", "", $text); + $text = lcfirst($text); + + return $text; + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Assets/Less.php b/src/composer/vendor/consolidation/robo/src/Task/Assets/Less.php new file mode 100644 index 00000000..4cfa0978 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Assets/Less.php @@ -0,0 +1,108 @@ +taskLess([ + * 'less/default.less' => 'css/default.css' + * ]) + * ->run(); + * ?> + * ``` + * + * Use one of both less compilers in your project: + * + * ``` + * "leafo/lessphp": "~0.5", + * "oyejorge/less.php": "~1.5" + * ``` + * + * Specify directory (string or array) for less imports lookup: + * + * ```php + * taskLess([ + * 'less/default.less' => 'css/default.css' + * ]) + * ->importDir('less') + * ->compiler('lessphp') + * ->run(); + * ?> + * ``` + * + * You can implement additional compilers by extending this task and adding a + * method named after them and overloading the lessCompilers() method to + * inject the name there. + */ +class Less extends CssPreprocessor +{ + const FORMAT_NAME = 'less'; + + /** + * @var string[] + */ + protected $compilers = [ + 'less', // https://github.com/oyejorge/less.php + 'lessphp', //https://github.com/leafo/lessphp + ]; + + /** + * lessphp compiler + * @link https://github.com/leafo/lessphp + * + * @param string $file + * + * @return string + */ + protected function lessphp($file) + { + if (!class_exists('\lessc')) { + return Result::errorMissingPackage($this, 'lessc', 'leafo/lessphp'); + } + + $lessCode = file_get_contents($file); + + $less = new \lessc(); + if (isset($this->compilerOptions['importDirs'])) { + $less->setImportDir($this->compilerOptions['importDirs']); + } + + return $less->compile($lessCode); + } + + /** + * less compiler + * @link https://github.com/oyejorge/less.php + * + * @param string $file + * + * @return string + */ + protected function less($file) + { + if (!class_exists('\Less_Parser')) { + return Result::errorMissingPackage($this, 'Less_Parser', 'oyejorge/less.php'); + } + + $lessCode = file_get_contents($file); + + $parser = new \Less_Parser(); + $parser->SetOptions($this->compilerOptions); + if (isset($this->compilerOptions['importDirs'])) { + $importDirs = []; + foreach ($this->compilerOptions['importDirs'] as $dir) { + $importDirs[$dir] = $dir; + } + $parser->SetImportDirs($importDirs); + } + + $parser->parse($lessCode); + + return $parser->getCss(); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Assets/Minify.php b/src/composer/vendor/consolidation/robo/src/Task/Assets/Minify.php new file mode 100644 index 00000000..3187714e --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Assets/Minify.php @@ -0,0 +1,297 @@ +taskMinify( 'web/assets/theme.css' ) + * ->run() + * ?> + * ``` + * Please install additional dependencies to use: + * + * ``` + * "patchwork/jsqueeze": "~1.0", + * "natxet/CssMin": "~3.0" + * ``` + */ +class Minify extends BaseTask +{ + /** + * @var array + */ + protected $types = ['css', 'js']; + + /** + * @var string + */ + protected $text; + + /** + * @var string + */ + protected $dst; + + /** + * @var string + */ + protected $type; + + /** + * @var array + */ + protected $squeezeOptions = [ + 'singleLine' => true, + 'keepImportantComments' => true, + 'specialVarRx' => false, + ]; + + /** + * Constructor. Accepts asset file path or string source. + * + * @param string $input + */ + public function __construct($input) + { + if (file_exists($input)) { + $this->fromFile($input); + return; + } + + $this->fromText($input); + } + + /** + * Sets destination. Tries to guess type from it. + * + * @param string $dst + * + * @return $this + */ + public function to($dst) + { + $this->dst = $dst; + + if (!empty($this->dst) && empty($this->type)) { + $this->type($this->getExtension($this->dst)); + } + + return $this; + } + + /** + * Sets type with validation. + * + * @param string $type css|js + * + * @return $this + */ + public function type($type) + { + $type = strtolower($type); + + if (in_array($type, $this->types)) { + $this->type = $type; + } + + return $this; + } + + /** + * Sets text from string source. + * + * @param string $text + * + * @return $this + */ + protected function fromText($text) + { + $this->text = (string)$text; + unset($this->type); + + return $this; + } + + /** + * Sets text from asset file path. Tries to guess type and set default destination. + * + * @param string $path + * + * @return $this + */ + protected function fromFile($path) + { + $this->text = file_get_contents($path); + + unset($this->type); + $this->type($this->getExtension($path)); + + if (empty($this->dst) && !empty($this->type)) { + $ext_length = strlen($this->type) + 1; + $this->dst = substr($path, 0, -$ext_length) . '.min.' . $this->type; + } + + return $this; + } + + /** + * Gets file extension from path. + * + * @param string $path + * + * @return string + */ + protected function getExtension($path) + { + return pathinfo($path, PATHINFO_EXTENSION); + } + + /** + * Minifies and returns text. + * + * @return string|bool + */ + protected function getMinifiedText() + { + switch ($this->type) { + case 'css': + if (!class_exists('\CssMin')) { + return Result::errorMissingPackage($this, 'CssMin', 'natxet/CssMin'); + } + + return \CssMin::minify($this->text); + break; + + case 'js': + if (!class_exists('\JSqueeze') && !class_exists('\Patchwork\JSqueeze')) { + return Result::errorMissingPackage($this, 'Patchwork\JSqueeze', 'patchwork/jsqueeze'); + } + + if (class_exists('\JSqueeze')) { + $jsqueeze = new \JSqueeze(); + } else { + $jsqueeze = new \Patchwork\JSqueeze(); + } + + return $jsqueeze->squeeze( + $this->text, + $this->squeezeOptions['singleLine'], + $this->squeezeOptions['keepImportantComments'], + $this->squeezeOptions['specialVarRx'] + ); + break; + } + + return false; + } + + /** + * Single line option for the JS minimisation. + * + * @param bool $singleLine + * + * @return $this + */ + public function singleLine($singleLine) + { + $this->squeezeOptions['singleLine'] = (bool)$singleLine; + return $this; + } + + /** + * keepImportantComments option for the JS minimisation. + * + * @param bool $keepImportantComments + * + * @return $this + */ + public function keepImportantComments($keepImportantComments) + { + $this->squeezeOptions['keepImportantComments'] = (bool)$keepImportantComments; + return $this; + } + + /** + * specialVarRx option for the JS minimisation. + * + * @param bool $specialVarRx + * + * @return $this ; + */ + public function specialVarRx($specialVarRx) + { + $this->squeezeOptions['specialVarRx'] = (bool)$specialVarRx; + return $this; + } + + /** + * @return string + */ + public function __toString() + { + return (string) $this->getMinifiedText(); + } + + /** + * {@inheritdoc} + */ + public function run() + { + if (empty($this->type)) { + return Result::error($this, 'Unknown asset type.'); + } + + if (empty($this->dst)) { + return Result::error($this, 'Unknown file destination.'); + } + + if (file_exists($this->dst) && !is_writable($this->dst)) { + return Result::error($this, 'Destination already exists and cannot be overwritten.'); + } + + $size_before = strlen($this->text); + $minified = $this->getMinifiedText(); + + if ($minified instanceof Result) { + return $minified; + } elseif (false === $minified) { + return Result::error($this, 'Minification failed.'); + } + + $size_after = strlen($minified); + + // Minification did not reduce file size, so use original file. + if ($size_after > $size_before) { + $minified = $this->text; + $size_after = $size_before; + } + + $dst = $this->dst . '.part'; + $write_result = file_put_contents($dst, $minified); + + if (false === $write_result) { + @unlink($dst); + return Result::error($this, 'File write failed.'); + } + // Cannot be cross-volume; should always succeed. + @rename($dst, $this->dst); + if ($size_before === 0) { + $minified_percent = 0; + } else { + $minified_percent = number_format(100 - ($size_after / $size_before * 100), 1); + } + $this->printTaskSuccess('Wrote {filepath}', ['filepath' => $this->dst]); + $context = [ + 'bytes' => $this->formatBytes($size_after), + 'reduction' => $this->formatBytes(($size_before - $size_after)), + 'percentage' => $minified_percent, + ]; + $this->printTaskSuccess('Wrote {bytes} (reduced by {reduction} / {percentage})', $context); + return Result::success($this, 'Asset minified.'); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Assets/Scss.php b/src/composer/vendor/consolidation/robo/src/Task/Assets/Scss.php new file mode 100644 index 00000000..ffd39345 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Assets/Scss.php @@ -0,0 +1,93 @@ +taskScss([ + * 'scss/default.scss' => 'css/default.css' + * ]) + * ->importDir('assets/styles') + * ->run(); + * ?> + * ``` + * + * Use the following scss compiler in your project: + * + * ``` + * "leafo/scssphp": "~0.1", + * ``` + * + * You can implement additional compilers by extending this task and adding a + * method named after them and overloading the scssCompilers() method to + * inject the name there. + */ +class Scss extends CssPreprocessor +{ + const FORMAT_NAME = 'scss'; + + /** + * @var string[] + */ + protected $compilers = [ + 'scssphp', // https://github.com/leafo/scssphp + ]; + + /** + * scssphp compiler + * @link https://github.com/leafo/scssphp + * + * @param string $file + * + * @return string + */ + protected function scssphp($file) + { + if (!class_exists('\Leafo\ScssPhp\Compiler')) { + return Result::errorMissingPackage($this, 'scssphp', 'leafo/scssphp'); + } + + $scssCode = file_get_contents($file); + $scss = new \Leafo\ScssPhp\Compiler(); + + // set options for the scssphp compiler + if (isset($this->compilerOptions['importDirs'])) { + $scss->setImportPaths($this->compilerOptions['importDirs']); + } + + if (isset($this->compilerOptions['formatter'])) { + $scss->setFormatter($this->compilerOptions['formatter']); + } + + return $scss->compile($scssCode); + } + + /** + * Sets the formatter for scssphp + * + * The method setFormatter($formatterName) sets the current formatter to $formatterName, + * the name of a class as a string that implements the formatting interface. See the source + * for Leafo\ScssPhp\Formatter\Expanded for an example. + * + * Five formatters are included with leafo/scssphp: + * - Leafo\ScssPhp\Formatter\Expanded + * - Leafo\ScssPhp\Formatter\Nested (default) + * - Leafo\ScssPhp\Formatter\Compressed + * - Leafo\ScssPhp\Formatter\Compact + * - Leafo\ScssPhp\Formatter\Crunched + * + * @link http://leafo.github.io/scssphp/docs/#output-formatting + * + * @param string $formatterName + * + * @return $this + */ + public function setFormatter($formatterName) + { + return parent::setFormatter($formatterName); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Assets/loadTasks.php b/src/composer/vendor/consolidation/robo/src/Task/Assets/loadTasks.php new file mode 100644 index 00000000..12192dd8 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Assets/loadTasks.php @@ -0,0 +1,45 @@ +task(Minify::class, $input); + } + + /** + * @param string|string[] $input + * + * @return \Robo\Task\Assets\ImageMinify + */ + protected function taskImageMinify($input) + { + return $this->task(ImageMinify::class, $input); + } + + /** + * @param array $input + * + * @return \Robo\Task\Assets\Less + */ + protected function taskLess($input) + { + return $this->task(Less::class, $input); + } + + /** + * @param array $input + * + * @return \Robo\Task\Assets\Scss + */ + protected function taskScss($input) + { + return $this->task(Scss::class, $input); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Base/Exec.php b/src/composer/vendor/consolidation/robo/src/Task/Base/Exec.php new file mode 100644 index 00000000..5baccedd --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Base/Exec.php @@ -0,0 +1,224 @@ +taskExec('compass')->arg('watch')->run(); + * // or use shortcut + * $this->_exec('compass watch'); + * + * $this->taskExec('compass watch')->background()->run(); + * + * if ($this->taskExec('phpunit .')->run()->wasSuccessful()) { + * $this->say('tests passed'); + * } + * + * ?> + * ``` + */ +class Exec extends BaseTask implements CommandInterface, PrintedInterface, SimulatedInterface +{ + use \Robo\Common\CommandReceiver; + use \Robo\Common\ExecOneCommand; + + /** + * @var static[] + */ + protected static $instances = []; + + /** + * @var string|\Robo\Contract\CommandInterface + */ + protected $command; + + /** + * @var bool + */ + protected $background = false; + + /** + * @var null|int + */ + protected $timeout = null; + + /** + * @var null|int + */ + protected $idleTimeout = null; + + /** + * @var null|array + */ + protected $env = null; + + /** + * @var Process + */ + protected $process; + + /** + * @param string|\Robo\Contract\CommandInterface $command + */ + public function __construct($command) + { + $this->command = $this->receiveCommand($command); + } + + /** + * {@inheritdoc} + */ + public function getCommand() + { + return trim($this->command . $this->arguments); + } + + /** + * Executes command in background mode (asynchronously) + * + * @return $this + */ + public function background() + { + self::$instances[] = $this; + $this->background = true; + return $this; + } + + /** + * Stop command if it runs longer then $timeout in seconds + * + * @param int $timeout + * + * @return $this + */ + public function timeout($timeout) + { + $this->timeout = $timeout; + return $this; + } + + /** + * Stops command if it does not output something for a while + * + * @param int $timeout + * + * @return $this + */ + public function idleTimeout($timeout) + { + $this->idleTimeout = $timeout; + return $this; + } + + /** + * Sets the environment variables for the command + * + * @param array $env + * + * @return $this + */ + public function env(array $env) + { + $this->env = $env; + return $this; + } + + public function __destruct() + { + $this->stop(); + } + + protected function stop() + { + if ($this->background && $this->process->isRunning()) { + $this->process->stop(); + $this->printTaskInfo("Stopped {command}", ['command' => $this->getCommand()]); + } + } + + /** + * @param array $context + */ + protected function printAction($context = []) + { + $command = $this->getCommand(); + $dir = $this->workingDirectory ? " in {dir}" : ""; + $this->printTaskInfo("Running {command}$dir", ['command' => $command, 'dir' => $this->workingDirectory] + $context); + } + + /** + * {@inheritdoc} + */ + public function run() + { + $this->printAction(); + $this->process = new Process($this->getCommand()); + $this->process->setTimeout($this->timeout); + $this->process->setIdleTimeout($this->idleTimeout); + $this->process->setWorkingDirectory($this->workingDirectory); + + if (isset($this->env)) { + $this->process->setEnv($this->env); + } + + if (!$this->background and !$this->isPrinted) { + $this->startTimer(); + $this->process->run(); + $this->stopTimer(); + return new Result($this, $this->process->getExitCode(), $this->process->getOutput(), ['time' => $this->getExecutionTime()]); + } + + if (!$this->background and $this->isPrinted) { + $this->startTimer(); + $this->process->run( + function ($type, $buffer) { + $progressWasVisible = $this->hideTaskProgress(); + print($buffer); + $this->showTaskProgress($progressWasVisible); + } + ); + $this->stopTimer(); + return new Result($this, $this->process->getExitCode(), $this->process->getOutput(), ['time' => $this->getExecutionTime()]); + } + + try { + $this->process->start(); + } catch (\Exception $e) { + return Result::fromException($this, $e); + } + return Result::success($this); + } + + /** + * {@inheritdoc} + */ + public function simulate($context) + { + $this->printAction($context); + } + + public static function stopRunningJobs() + { + foreach (self::$instances as $instance) { + if ($instance) { + unset($instance); + } + } + } +} + +if (function_exists('pcntl_signal')) { + pcntl_signal(SIGTERM, ['Robo\Task\Base\Exec', 'stopRunningJobs']); +} + +register_shutdown_function(['Robo\Task\Base\Exec', 'stopRunningJobs']); diff --git a/src/composer/vendor/consolidation/robo/src/Task/Base/ExecStack.php b/src/composer/vendor/consolidation/robo/src/Task/Base/ExecStack.php new file mode 100644 index 00000000..b5855dee --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Base/ExecStack.php @@ -0,0 +1,26 @@ +taskExecStack() + * ->stopOnFail() + * ->exec('mkdir site') + * ->exec('cd site') + * ->run(); + * + * ?> + * ``` + * + * @method $this stopOnFail() + */ +class ExecStack extends CommandStack +{ +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Base/ParallelExec.php b/src/composer/vendor/consolidation/robo/src/Task/Base/ParallelExec.php new file mode 100644 index 00000000..2cd1ebc6 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Base/ParallelExec.php @@ -0,0 +1,177 @@ +taskParallelExec() + * ->process('php ~/demos/script.php hey') + * ->process('php ~/demos/script.php hoy') + * ->process('php ~/demos/script.php gou') + * ->run(); + * ?> + * ``` + * + * + * @method \Robo\Task\Base\ParallelExec timeout(int $timeout) stops process if it runs longer then `$timeout` (seconds) + * @method \Robo\Task\Base\ParallelExec idleTimeout(int $timeout) stops process if it does not output for time longer then `$timeout` (seconds) + */ +class ParallelExec extends BaseTask implements CommandInterface, PrintedInterface +{ + use \Robo\Common\CommandReceiver; + + /** + * @var Process[] + */ + protected $processes = []; + + /** + * @var null|int + */ + protected $timeout = null; + + /** + * @var null|int + */ + protected $idleTimeout = null; + + /** + * @var bool + */ + protected $isPrinted = false; + + /** + * {@inheritdoc} + */ + public function getPrinted() + { + return $this->isPrinted; + } + + /** + * @param bool $isPrinted + * + * @return $this + */ + public function printed($isPrinted = true) + { + $this->isPrinted = $isPrinted; + return $this; + } + + /** + * @param string|\Robo\Contract\CommandInterface $command + * + * @return $this + */ + public function process($command) + { + $this->processes[] = new Process($this->receiveCommand($command)); + return $this; + } + + /** + * @param int $timeout + * + * @return $this + */ + public function timeout($timeout) + { + $this->timeout = $timeout; + return $this; + } + + /** + * @param int $idleTimeout + * + * @return $this + */ + public function idleTimeout($idleTimeout) + { + $this->idleTimeout = $idleTimeout; + return $this; + } + + /** + * {@inheritdoc} + */ + public function getCommand() + { + return implode(' && ', $this->processes); + } + + /** + * @return int + */ + public function progressIndicatorSteps() + { + return count($this->processes); + } + + /** + * {@inheritdoc} + */ + public function run() + { + foreach ($this->processes as $process) { + $process->setIdleTimeout($this->idleTimeout); + $process->setTimeout($this->timeout); + $process->start(); + $this->printTaskInfo($process->getCommandLine()); + } + + $this->startProgressIndicator(); + $running = $this->processes; + while (true) { + foreach ($running as $k => $process) { + try { + $process->checkTimeout(); + } catch (ProcessTimedOutException $e) { + $this->printTaskWarning("Process timed out for {command}", ['command' => $process->getCommandLine(), '_style' => ['command' => 'fg=white;bg=magenta']]); + } + if (!$process->isRunning()) { + $this->advanceProgressIndicator(); + if ($this->isPrinted) { + $this->printTaskInfo("Output for {command}:\n\n{output}", ['command' => $process->getCommandLine(), 'output' => $process->getOutput(), '_style' => ['command' => 'fg=white;bg=magenta']]); + $errorOutput = $process->getErrorOutput(); + if ($errorOutput) { + $this->printTaskError(rtrim($errorOutput)); + } + } + unset($running[$k]); + } + } + if (empty($running)) { + break; + } + usleep(1000); + } + $this->stopProgressIndicator(); + + $errorMessage = ''; + $exitCode = 0; + foreach ($this->processes as $p) { + if ($p->getExitCode() === 0) { + continue; + } + $errorMessage .= "'" . $p->getCommandLine() . "' exited with code ". $p->getExitCode()." \n"; + $exitCode = max($exitCode, $p->getExitCode()); + } + if (!$errorMessage) { + $this->printTaskSuccess('{process-count} processes finished running', ['process-count' => count($this->processes)]); + } + + return new Result($this, $exitCode, $errorMessage, ['time' => $this->getExecutionTime()]); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Base/SymfonyCommand.php b/src/composer/vendor/consolidation/robo/src/Task/Base/SymfonyCommand.php new file mode 100644 index 00000000..51c81d6d --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Base/SymfonyCommand.php @@ -0,0 +1,76 @@ +taskSymfonyCommand(new \Codeception\Command\Run('run')) + * ->arg('suite','acceptance') + * ->opt('debug') + * ->run(); + * + * // Artisan Command + * $this->taskSymfonyCommand(new ModelGeneratorCommand()) + * ->arg('name', 'User') + * ->run(); + * ?> + * ``` + */ +class SymfonyCommand extends BaseTask +{ + /** + * @var \Symfony\Component\Console\Command\Command + */ + protected $command; + + /** + * @var string[] + */ + protected $input; + + public function __construct(Command $command) + { + $this->command = $command; + $this->input = []; + } + + /** + * @param string $arg + * @param string $value + * + * @return $this + */ + public function arg($arg, $value) + { + $this->input[$arg] = $value; + return $this; + } + + public function opt($option, $value = null) + { + $this->input["--$option"] = $value; + return $this; + } + + /** + * {@inheritdoc} + */ + public function run() + { + $this->printTaskInfo('Running command {command}', ['command' => $this->command->getName()]); + return new Result( + $this, + $this->command->run(new ArrayInput($this->input), Robo::output()) + ); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Base/Watch.php b/src/composer/vendor/consolidation/robo/src/Task/Base/Watch.php new file mode 100644 index 00000000..d7940ac9 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Base/Watch.php @@ -0,0 +1,89 @@ +taskWatch() + * ->monitor('composer.json', function() { + * $this->taskComposerUpdate()->run(); + * })->monitor('src', function() { + * $this->taskExec('phpunit')->run(); + * })->run(); + * ?> + * ``` + */ +class Watch extends BaseTask +{ + /** + * @var \Closure + */ + protected $closure; + + /** + * @var array + */ + protected $monitor = []; + + /** + * @var object + */ + protected $bindTo; + + /** + * @param $bindTo + */ + public function __construct($bindTo) + { + $this->bindTo = $bindTo; + } + + /** + * @param string|string[] $paths + * @param \Closure $callable + * + * @return $this + */ + public function monitor($paths, \Closure $callable) + { + if (!is_array($paths)) { + $paths = [$paths]; + } + $this->monitor[] = [$paths, $callable]; + return $this; + } + + /** + * {@inheritdoc} + */ + public function run() + { + if (!class_exists('Lurker\\ResourceWatcher')) { + return Result::errorMissingPackage($this, 'ResourceWatcher', 'henrikbjorn/lurker'); + } + + $watcher = new ResourceWatcher(); + + foreach ($this->monitor as $k => $monitor) { + /** @var \Closure $closure */ + $closure = $monitor[1]; + $closure->bindTo($this->bindTo); + foreach ($monitor[0] as $i => $dir) { + $watcher->track("fs.$k.$i", $dir, FilesystemEvent::MODIFY); + $this->printTaskInfo('Watching {dir} for changes...', ['dir' => $dir]); + $watcher->addListener("fs.$k.$i", $closure); + } + } + + $watcher->start(); + return Result::success($this); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Base/loadShortcuts.php b/src/composer/vendor/consolidation/robo/src/Task/Base/loadShortcuts.php new file mode 100644 index 00000000..dba0af66 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Base/loadShortcuts.php @@ -0,0 +1,17 @@ +taskExec($command)->run(); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Base/loadTasks.php b/src/composer/vendor/consolidation/robo/src/Task/Base/loadTasks.php new file mode 100644 index 00000000..530fbcd5 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Base/loadTasks.php @@ -0,0 +1,45 @@ +task(Exec::class, $command); + } + + protected function taskExecStack() + { + return $this->task(ExecStack::class); + } + + /** + * @return ParallelExec + */ + protected function taskParallelExec() + { + return $this->task(ParallelExec::class); + } + + /** + * @param $command + * @return SymfonyCommand + */ + protected function taskSymfonyCommand($command) + { + return $this->task(SymfonyCommand::class, $command); + } + + /** + * @return Watch + */ + protected function taskWatch() + { + return $this->task(Watch::class, $this); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/BaseTask.php b/src/composer/vendor/consolidation/robo/src/Task/BaseTask.php new file mode 100644 index 00000000..36c9fa8c --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/BaseTask.php @@ -0,0 +1,35 @@ +logger) { + $child->setLogger($this->logger); + } + if ($child instanceof ProgressIndicatorAwareInterface && $this->progressIndicator) { + $child->setProgressIndicator($this->progressIndicator); + } + if ($child instanceof ConfigAwareInterface && $this->getConfig()) { + $child->setConfig($this->getConfig()); + } + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Bower/Base.php b/src/composer/vendor/consolidation/robo/src/Task/Bower/Base.php new file mode 100644 index 00000000..9bc614c6 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Bower/Base.php @@ -0,0 +1,88 @@ +option('allow-root'); + return $this; + } + + /** + * adds `force-latest` option to bower + * + * @return $this + */ + public function forceLatest() + { + $this->option('force-latest'); + return $this; + } + + /** + * adds `production` option to bower + * + * @return $this + */ + public function noDev() + { + $this->option('production'); + return $this; + } + + /** + * adds `offline` option to bower + * + * @return $this + */ + public function offline() + { + $this->option('offline'); + return $this; + } + + /** + * Base constructor. + * + * @param null|string $pathToBower + * + * @throws \Robo\Exception\TaskException + */ + public function __construct($pathToBower = null) + { + $this->command = $pathToBower; + if (!$this->command) { + $this->command = $this->findExecutable('bower'); + } + if (!$this->command) { + throw new TaskException(__CLASS__, "Bower executable not found."); + } + } + + /** + * @return string + */ + public function getCommand() + { + return "{$this->command} {$this->action}{$this->arguments}"; + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Bower/Install.php b/src/composer/vendor/consolidation/robo/src/Task/Bower/Install.php new file mode 100644 index 00000000..d7fb57dd --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Bower/Install.php @@ -0,0 +1,37 @@ +taskBowerInstall()->run(); + * + * // prefer dist with custom path + * $this->taskBowerInstall('path/to/my/bower') + * ->noDev() + * ->run(); + * ?> + * ``` + */ +class Install extends Base implements CommandInterface +{ + /** + * {@inheritdoc} + */ + protected $action = 'install'; + + /** + * {@inheritdoc} + */ + public function run() + { + $this->printTaskInfo('Install Bower packages: {arguments}', ['arguments' => $this->arguments]); + return $this->executeCommand($this->getCommand()); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Bower/Update.php b/src/composer/vendor/consolidation/robo/src/Task/Bower/Update.php new file mode 100644 index 00000000..1d2c53f9 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Bower/Update.php @@ -0,0 +1,36 @@ +taskBowerUpdate->run(); + * + * // prefer dist with custom path + * $this->taskBowerUpdate('path/to/my/bower') + * ->noDev() + * ->run(); + * ?> + * ``` + */ +class Update extends Base +{ + /** + * {@inheritdoc} + */ + protected $action = 'update'; + + /** + * {@inheritdoc} + */ + public function run() + { + $this->printTaskInfo('Update Bower packages: {arguments}', ['arguments' => $this->arguments]); + return $this->executeCommand($this->getCommand()); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Bower/loadTasks.php b/src/composer/vendor/consolidation/robo/src/Task/Bower/loadTasks.php new file mode 100644 index 00000000..6e33f8ac --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Bower/loadTasks.php @@ -0,0 +1,25 @@ +task(Install::class, $pathToBower); + } + + /** + * @param null|string $pathToBower + * + * @return Update + */ + protected function taskBowerUpdate($pathToBower = null) + { + return $this->task(Update::class, $pathToBower); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/CommandStack.php b/src/composer/vendor/consolidation/robo/src/Task/CommandStack.php new file mode 100644 index 00000000..542bf6d8 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/CommandStack.php @@ -0,0 +1,123 @@ +exec); + } + + /** + * @param string $executable + * + * @return $this + */ + public function executable($executable) + { + $this->executable = $executable; + return $this; + } + + /** + * @param string|string[] $command + * + * @return $this + */ + public function exec($command) + { + if (is_array($command)) { + $command = implode(' ', array_filter($command)); + } + + $command = $this->executable . ' ' . $this->stripExecutableFromCommand($command); + array_push($this->exec, trim($command)); + return $this; + } + + /** + * @param bool $stopOnFail + * + * @return $this + */ + public function stopOnFail($stopOnFail = true) + { + $this->stopOnFail = $stopOnFail; + return $this; + } + + public function result($result) + { + $this->result = $result; + return $this; + } + + /** + * @param string $command + * + * @return string + */ + protected function stripExecutableFromCommand($command) + { + $command = trim($command); + $executable = $this->executable . ' '; + if (strpos($command, $executable) === 0) { + $command = substr($command, strlen($executable)); + } + return $command; + } + + /** + * {@inheritdoc} + */ + public function run() + { + if (empty($this->exec)) { + throw new TaskException($this, 'You must add at least one command'); + } + if (!$this->stopOnFail) { + $this->printTaskInfo('{command}', ['command' => $this->getCommand()]); + return $this->executeCommand($this->getCommand()); + } + + foreach ($this->exec as $command) { + $this->printTaskInfo("Executing {command}", ['command' => $command]); + $result = $this->executeCommand($command); + if (!$result->wasSuccessful()) { + return $result; + } + } + + return Result::success($this); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Composer/Base.php b/src/composer/vendor/consolidation/robo/src/Task/Composer/Base.php new file mode 100644 index 00000000..4f6597b7 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Composer/Base.php @@ -0,0 +1,145 @@ +prefer = '--prefer-dist'; + return $this; + } + + /** + * adds `prefer-source` option to composer + * + * @return $this + */ + public function preferSource() + { + $this->prefer = '--prefer-source'; + return $this; + } + + /** + * adds `no-dev` option to composer + * + * @return $this + */ + public function noDev() + { + $this->dev = '--no-dev'; + return $this; + } + + /** + * adds `no-ansi` option to composer + * + * @return $this + */ + public function noAnsi() + { + $this->ansi = '--no-ansi'; + return $this; + } + + /** + * adds `ansi` option to composer + * + * @return $this + */ + public function ansi() + { + $this->ansi = '--ansi'; + return $this; + } + + /** + * adds `optimize-autoloader` option to composer + * + * @return $this + */ + public function optimizeAutoloader() + { + $this->optimizeAutoloader = '--optimize-autoloader'; + return $this; + } + + /** + * @param null|string $pathToComposer + * + * @throws \Robo\Exception\TaskException + */ + public function __construct($pathToComposer = null) + { + $this->command = $pathToComposer; + if (!$this->command) { + $this->command = $this->findExecutablePhar('composer'); + } + if (!$this->command) { + throw new TaskException(__CLASS__, "Neither local composer.phar nor global composer installation could be found."); + } + } + + /** + * {@inheritdoc} + */ + public function getCommand() + { + if (!isset($this->ansi) && $this->getConfig()->isDecorated()) { + $this->ansi(); + } + $this->option($this->prefer) + ->option($this->dev) + ->option($this->optimizeAutoloader) + ->option($this->ansi); + return "{$this->command} {$this->action}{$this->arguments}"; + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Composer/DumpAutoload.php b/src/composer/vendor/consolidation/robo/src/Task/Composer/DumpAutoload.php new file mode 100644 index 00000000..6297a2b4 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Composer/DumpAutoload.php @@ -0,0 +1,69 @@ +taskComposerDumpAutoload()->run(); + * + * // dump auto loader with custom path + * $this->taskComposerDumpAutoload('path/to/my/composer.phar') + * ->preferDist() + * ->run(); + * + * // optimize autoloader dump with custom path + * $this->taskComposerDumpAutoload('path/to/my/composer.phar') + * ->optimize() + * ->run(); + * + * // optimize autoloader dump with custom path and no dev + * $this->taskComposerDumpAutoload('path/to/my/composer.phar') + * ->optimize() + * ->noDev() + * ->run(); + * ?> + * ``` + */ +class DumpAutoload extends Base +{ + /** + * {@inheritdoc} + */ + protected $action = 'dump-autoload'; + + /** + * @var string + */ + protected $optimize; + + /** + * @return $this + */ + public function optimize() + { + $this->optimize = "--optimize"; + return $this; + } + + /** + * {@inheritdoc} + */ + public function getCommand() + { + $this->option($this->optimize); + return parent::getCommand(); + } + + /** + * {@inheritdoc} + */ + public function run() + { + $command = $this->getCommand(); + $this->printTaskInfo('Dumping Autoloader: {command}', ['command' => $command]); + return $this->executeCommand($command); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Composer/Install.php b/src/composer/vendor/consolidation/robo/src/Task/Composer/Install.php new file mode 100644 index 00000000..76cb9861 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Composer/Install.php @@ -0,0 +1,40 @@ +taskComposerInstall()->run(); + * + * // prefer dist with custom path + * $this->taskComposerInstall('path/to/my/composer.phar') + * ->preferDist() + * ->run(); + * + * // optimize autoloader with custom path + * $this->taskComposerInstall('path/to/my/composer.phar') + * ->optimizeAutoloader() + * ->run(); + * ?> + * ``` + */ +class Install extends Base +{ + /** + * {@inheritdoc} + */ + protected $action = 'install'; + + /** + * {@inheritdoc} + */ + public function run() + { + $command = $this->getCommand(); + $this->printTaskInfo('Installing Packages: {command}', ['command' => $command]); + return $this->executeCommand($command); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Composer/Remove.php b/src/composer/vendor/consolidation/robo/src/Task/Composer/Remove.php new file mode 100644 index 00000000..0011055a --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Composer/Remove.php @@ -0,0 +1,75 @@ +taskComposerValidate()->run(); + * ?> + * ``` + */ +class Remove extends Base +{ + /** + * {@inheritdoc} + */ + protected $action = 'remove'; + + /** + * @return $this + */ + public function dev() + { + $this->option('--dev'); + return $this; + } + + /** + * @return $this + */ + public function noProgress() + { + $this->option('--no-progress'); + return $this; + } + + /** + * @return $this + */ + public function noUpdate() + { + $this->option('--no-update'); + return $this; + } + + /** + * @return $this + */ + public function updateNoDev() + { + $this->option('--update-no-dev'); + return $this; + } + + /** + * @return $this + */ + public function noUpdateWithDependencies() + { + $this->option('--no-update-with-dependencies'); + return $this; + } + + /** + * {@inheritdoc} + */ + public function run() + { + $command = $this->getCommand(); + $this->printTaskInfo('Removing packages: {command}', ['command' => $command]); + return $this->executeCommand($command); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Composer/Update.php b/src/composer/vendor/consolidation/robo/src/Task/Composer/Update.php new file mode 100644 index 00000000..3a0a64af --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Composer/Update.php @@ -0,0 +1,40 @@ +taskComposerUpdate()->run(); + * + * // prefer dist with custom path + * $this->taskComposerUpdate('path/to/my/composer.phar') + * ->preferDist() + * ->run(); + * + * // optimize autoloader with custom path + * $this->taskComposerUpdate('path/to/my/composer.phar') + * ->optimizeAutoloader() + * ->run(); + * ?> + * ``` + */ +class Update extends Base +{ + /** + * {@inheritdoc} + */ + protected $action = 'update'; + + /** + * {@inheritdoc} + */ + public function run() + { + $command = $this->getCommand(); + $this->printTaskInfo('Updating Packages: {command}', ['command' => $command]); + return $this->executeCommand($command); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Composer/Validate.php b/src/composer/vendor/consolidation/robo/src/Task/Composer/Validate.php new file mode 100644 index 00000000..6db6fdd1 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Composer/Validate.php @@ -0,0 +1,114 @@ +taskComposerValidate()->run(); + * ?> + * ``` + */ +class Validate extends Base +{ + /** + * {@inheritdoc} + */ + protected $action = 'validate'; + + /** + * @var string + */ + protected $noCheckAll; + + /** + * @var string + */ + protected $noCheckLock; + + /** + * @var string + */ + protected $noCheckPublish; + + /** + * @var string + */ + protected $withDependencies; + + /** + * @var string + */ + protected $strict; + + /** + * @return $this + */ + public function noCheckAll() + { + $this->noCheckAll = '--no-check-all'; + return $this; + } + + /** + * @return $this + */ + public function noCheckLock() + { + $this->noCheckLock = '--no-check-lock'; + return $this; + } + + /** + * @return $this + */ + public function noCheckPublish() + { + $this->noCheckPublish = '--no-check-publish'; + return $this; + } + + /** + * @return $this + */ + public function withDependencies() + { + $this->withDependencies = '--with-dependencies'; + return $this; + } + + /** + * @return $this + */ + public function strict() + { + $this->strict = '--strict'; + return $this; + } + + /** + * {@inheritdoc} + */ + public function getCommand() + { + $this->option($this->noCheckAll); + $this->option($this->noCheckLock); + $this->option($this->noCheckPublish); + $this->option($this->withDependencies); + $this->option($this->strict); + + return parent::getCommand(); + } + + /** + * {@inheritdoc} + */ + public function run() + { + $command = $this->getCommand(); + $this->printTaskInfo('Validating composer.json: {command}', ['command' => $command]); + return $this->executeCommand($command); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Composer/loadTasks.php b/src/composer/vendor/consolidation/robo/src/Task/Composer/loadTasks.php new file mode 100644 index 00000000..50dab2ec --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Composer/loadTasks.php @@ -0,0 +1,55 @@ +task(Install::class, $pathToComposer); + } + + /** + * @param null|string $pathToComposer + * + * @return Update + */ + protected function taskComposerUpdate($pathToComposer = null) + { + return $this->task(Update::class, $pathToComposer); + } + + /** + * @param null|string $pathToComposer + * + * @return DumpAutoload + */ + protected function taskComposerDumpAutoload($pathToComposer = null) + { + return $this->task(DumpAutoload::class, $pathToComposer); + } + + /** + * @param null|string $pathToComposer + * + * @return Validate + */ + protected function taskComposerValidate($pathToComposer = null) + { + return $this->task(Validate::class, $pathToComposer); + } + + /** + * @param null|string $pathToComposer + * + * @return Remove + */ + protected function taskComposerRemove($pathToComposer = null) + { + return $this->task(Remove::class, $pathToComposer); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Development/Changelog.php b/src/composer/vendor/consolidation/robo/src/Task/Development/Changelog.php new file mode 100644 index 00000000..ce281852 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Development/Changelog.php @@ -0,0 +1,191 @@ +taskChangelog() + * ->version($version) + * ->change("released to github") + * ->run(); + * ?> + * ``` + * + * Changes can be asked from Console + * + * ``` php + * taskChangelog() + * ->version($version) + * ->askForChanges() + * ->run(); + * ?> + * ``` + * + * @method Development\Changelog filename(string $filename) + * @method Development\Changelog anchor(string $anchor) + * @method Development\Changelog version(string $version) + */ +class Changelog extends BaseTask implements BuilderAwareInterface +{ + use BuilderAwareTrait; + + /** + * @var string + */ + protected $filename; + + /** + * @var array + */ + protected $log = []; + + /** + * @var string + */ + protected $anchor = "# Changelog"; + + /** + * @var string + */ + protected $version = ""; + + /** + * @param string $filename + * + * @return $this + */ + public function filename($filename) + { + $this->filename = $filename; + return $this; + } + + /** + * @param string $item + * + * @return $this + */ + public function log($item) + { + $this->log[] = $item; + return $this; + } + + /** + * @param string $anchor + * + * @return $this + */ + public function anchor($anchor) + { + $this->anchor = $anchor; + return $this; + } + + /** + * @param string $version + * + * @return $this + */ + public function version($version) + { + $this->version = $version; + return $this; + } + + /** + * @param string $filename + */ + public function __construct($filename) + { + $this->filename = $filename; + } + + /** + * @param array $data + * + * @return $this + */ + public function changes(array $data) + { + $this->log = array_merge($this->log, $data); + return $this; + } + + /** + * @param string $change + * + * @return $this + */ + public function change($change) + { + $this->log[] = $change; + return $this; + } + + /** + * @return array + */ + public function getChanges() + { + return $this->log; + } + + /** + * {@inheritdoc} + */ + public function run() + { + if (empty($this->log)) { + return Result::error($this, "Changelog is empty"); + } + $text = implode( + "\n", + array_map( + function ($i) { + return "* $i *" . date('Y-m-d') . "*"; + }, + $this->log + ) + ) . "\n"; + $ver = "#### {$this->version}\n\n"; + $text = $ver . $text; + + if (!file_exists($this->filename)) { + $this->printTaskInfo('Creating {filename}', ['filename' => $this->filename]); + $res = file_put_contents($this->filename, $this->anchor); + if ($res === false) { + return Result::error($this, "File {filename} cant be created", ['filename' => $this->filename]); + } + } + + /** @var \Robo\Result $result */ + // trying to append to changelog for today + $result = $this->collectionBuilder()->taskReplace($this->filename) + ->from($ver) + ->to($text) + ->run(); + + if (!isset($result['replaced']) || !$result['replaced']) { + $result = $this->collectionBuilder()->taskReplace($this->filename) + ->from($this->anchor) + ->to($this->anchor . "\n\n" . $text) + ->run(); + } + + return new Result($this, $result->getExitCode(), $result->getMessage(), $this->log); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Development/GenerateMarkdownDoc.php b/src/composer/vendor/consolidation/robo/src/Task/Development/GenerateMarkdownDoc.php new file mode 100644 index 00000000..2387199f --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Development/GenerateMarkdownDoc.php @@ -0,0 +1,769 @@ +taskGenDoc('models.md') + * ->docClass('Model\User') // take class Model\User + * ->docClass('Model\Post') // take class Model\Post + * ->filterMethods(function(\ReflectionMethod $r) { + * return $r->isPublic() or $r->isProtected(); // process public and protected methods + * })->processClass(function(\ReflectionClass $r, $text) { + * return "Class ".$r->getName()."\n\n$text\n\n###Methods\n"; + * })->run(); + * ``` + * + * By default this task generates a documentation for each public method of a class. + * It combines method signature with a docblock. Both can be post-processed. + * + * ``` php + * taskGenDoc('models.md') + * ->docClass('Model\User') + * ->processClassSignature(false) // false can be passed to not include class signature + * ->processClassDocBlock(function(\ReflectionClass $r, $text) { + * return "[This is part of application model]\n" . $text; + * })->processMethodSignature(function(\ReflectionMethod $r, $text) { + * return "#### {$r->name}()"; + * })->processMethodDocBlock(function(\ReflectionMethod $r, $text) { + * return strpos($r->name, 'save')===0 ? "[Saves to the database]\n" . $text : $text; + * })->run(); + * ``` + * + * @method \Robo\Task\Development\GenerateMarkdownDoc docClass(string $classname) put a class you want to be documented + * @method \Robo\Task\Development\GenerateMarkdownDoc filterMethods(\Closure $func) using callback function filter out methods that won't be documented + * @method \Robo\Task\Development\GenerateMarkdownDoc filterClasses(\Closure $func) using callback function filter out classes that won't be documented + * @method \Robo\Task\Development\GenerateMarkdownDoc filterProperties(\Closure $func) using callback function filter out properties that won't be documented + * @method \Robo\Task\Development\GenerateMarkdownDoc processClass(\Closure $func) post-process class documentation + * @method \Robo\Task\Development\GenerateMarkdownDoc processClassSignature(\Closure $func) post-process class signature. Provide *false* to skip. + * @method \Robo\Task\Development\GenerateMarkdownDoc processClassDocBlock(\Closure $func) post-process class docblock contents. Provide *false* to skip. + * @method \Robo\Task\Development\GenerateMarkdownDoc processMethod(\Closure $func) post-process method documentation. Provide *false* to skip. + * @method \Robo\Task\Development\GenerateMarkdownDoc processMethodSignature(\Closure $func) post-process method signature. Provide *false* to skip. + * @method \Robo\Task\Development\GenerateMarkdownDoc processMethodDocBlock(\Closure $func) post-process method docblock contents. Provide *false* to skip. + * @method \Robo\Task\Development\GenerateMarkdownDoc processProperty(\Closure $func) post-process property documentation. Provide *false* to skip. + * @method \Robo\Task\Development\GenerateMarkdownDoc processPropertySignature(\Closure $func) post-process property signature. Provide *false* to skip. + * @method \Robo\Task\Development\GenerateMarkdownDoc processPropertyDocBlock(\Closure $func) post-process property docblock contents. Provide *false* to skip. + * @method \Robo\Task\Development\GenerateMarkdownDoc reorder(\Closure $func) use a function to reorder classes + * @method \Robo\Task\Development\GenerateMarkdownDoc reorderMethods(\Closure $func) use a function to reorder methods in class + * @method \Robo\Task\Development\GenerateMarkdownDoc prepend($text) inserts text into beginning of markdown file + * @method \Robo\Task\Development\GenerateMarkdownDoc append($text) inserts text in the end of markdown file + */ +class GenerateMarkdownDoc extends BaseTask implements BuilderAwareInterface +{ + use BuilderAwareTrait; + + /** + * @var string[] + */ + protected $docClass = []; + + /** + * @var callable + */ + protected $filterMethods; + + /** + * @var callable + */ + protected $filterClasses; + + /** + * @var callable + */ + protected $filterProperties; + + /** + * @var callable + */ + protected $processClass; + + /** + * @var callable|false + */ + protected $processClassSignature; + + /** + * @var callable|false + */ + protected $processClassDocBlock; + + /** + * @var callable|false + */ + protected $processMethod; + + /** + * @var callable|false + */ + protected $processMethodSignature; + + /** + * @var callable|false + */ + protected $processMethodDocBlock; + + /** + * @var callable|false + */ + protected $processProperty; + + /** + * @var callable|false + */ + protected $processPropertySignature; + + /** + * @var callable|false + */ + protected $processPropertyDocBlock; + + /** + * @var callable + */ + protected $reorder; + + /** + * @var callable + */ + protected $reorderMethods; + + /** + * @todo Unused property. + * + * @var callable + */ + protected $reorderProperties; + + /** + * @var string + */ + protected $filename; + + /** + * @var string + */ + protected $prepend = ""; + + /** + * @var string + */ + protected $append = ""; + + /** + * @var string + */ + protected $text; + + /** + * @var string[] + */ + protected $textForClass = []; + + /** + * @param string $filename + * + * @return static + */ + public static function init($filename) + { + return new static($filename); + } + + /** + * @param string $filename + */ + public function __construct($filename) + { + $this->filename = $filename; + } + + /** + * @param string $item + * + * @return $this + */ + public function docClass($item) + { + $this->docClass[] = $item; + return $this; + } + + /** + * @param callable $filterMethods + * + * @return $this + */ + public function filterMethods($filterMethods) + { + $this->filterMethods = $filterMethods; + return $this; + } + + /** + * @param callable $filterClasses + * + * @return $this + */ + public function filterClasses($filterClasses) + { + $this->filterClasses = $filterClasses; + return $this; + } + + /** + * @param callable $filterProperties + * + * @return $this + */ + public function filterProperties($filterProperties) + { + $this->filterProperties = $filterProperties; + return $this; + } + + /** + * @param callable $processClass + * + * @return $this + */ + public function processClass($processClass) + { + $this->processClass = $processClass; + return $this; + } + + /** + * @param callable|false $processClassSignature + * + * @return $this + */ + public function processClassSignature($processClassSignature) + { + $this->processClassSignature = $processClassSignature; + return $this; + } + + /** + * @param callable|false $processClassDocBlock + * + * @return $this + */ + public function processClassDocBlock($processClassDocBlock) + { + $this->processClassDocBlock = $processClassDocBlock; + return $this; + } + + /** + * @param callable|false $processMethod + * + * @return $this + */ + public function processMethod($processMethod) + { + $this->processMethod = $processMethod; + return $this; + } + + /** + * @param callable|false $processMethodSignature + * + * @return $this + */ + public function processMethodSignature($processMethodSignature) + { + $this->processMethodSignature = $processMethodSignature; + return $this; + } + + /** + * @param callable|false $processMethodDocBlock + * + * @return $this + */ + public function processMethodDocBlock($processMethodDocBlock) + { + $this->processMethodDocBlock = $processMethodDocBlock; + return $this; + } + + /** + * @param callable|false $processProperty + * + * @return $this + */ + public function processProperty($processProperty) + { + $this->processProperty = $processProperty; + return $this; + } + + /** + * @param callable|false $processPropertySignature + * + * @return $this + */ + public function processPropertySignature($processPropertySignature) + { + $this->processPropertySignature = $processPropertySignature; + return $this; + } + + /** + * @param callable|false $processPropertyDocBlock + * + * @return $this + */ + public function processPropertyDocBlock($processPropertyDocBlock) + { + $this->processPropertyDocBlock = $processPropertyDocBlock; + return $this; + } + + /** + * @param callable $reorder + * + * @return $this + */ + public function reorder($reorder) + { + $this->reorder = $reorder; + return $this; + } + + /** + * @param callable $reorderMethods + * + * @return $this + */ + public function reorderMethods($reorderMethods) + { + $this->reorderMethods = $reorderMethods; + return $this; + } + + /** + * @param callable $reorderProperties + * + * @return $this + */ + public function reorderProperties($reorderProperties) + { + $this->reorderProperties = $reorderProperties; + return $this; + } + + /** + * @param string $filename + * + * @return $this + */ + public function filename($filename) + { + $this->filename = $filename; + return $this; + } + + /** + * @param string $prepend + * + * @return $this + */ + public function prepend($prepend) + { + $this->prepend = $prepend; + return $this; + } + + /** + * @param string $append + * + * @return $this + */ + public function append($append) + { + $this->append = $append; + return $this; + } + + /** + * @param string $text + * + * @return $this + */ + public function text($text) + { + $this->text = $text; + return $this; + } + + /** + * @param string $item + * + * @return $this + */ + public function textForClass($item) + { + $this->textForClass[] = $item; + return $this; + } + + /** + * {@inheritdoc} + */ + public function run() + { + foreach ($this->docClass as $class) { + $this->printTaskInfo("Processing {class}", ['class' => $class]); + $this->textForClass[$class] = $this->documentClass($class); + } + + if (is_callable($this->reorder)) { + $this->printTaskInfo("Applying reorder function"); + call_user_func_array($this->reorder, [$this->textForClass]); + } + + $this->text = implode("\n", $this->textForClass); + + /** @var \Robo\Result $result */ + $result = $this->collectionBuilder()->taskWriteToFile($this->filename) + ->line($this->prepend) + ->text($this->text) + ->line($this->append) + ->run(); + + $this->printTaskSuccess('{filename} created. {class-count} classes documented', ['filename' => $this->filename, 'class-count' => count($this->docClass)]); + + return new Result($this, $result->getExitCode(), $result->getMessage(), $this->textForClass); + } + + /** + * @param string $class + * + * @return null|string + */ + protected function documentClass($class) + { + if (!class_exists($class)) { + return ""; + } + $refl = new \ReflectionClass($class); + + if (is_callable($this->filterClasses)) { + $ret = call_user_func($this->filterClasses, $refl); + if (!$ret) { + return; + } + } + $doc = $this->documentClassSignature($refl); + $doc .= "\n" . $this->documentClassDocBlock($refl); + $doc .= "\n"; + + if (is_callable($this->processClass)) { + $doc = call_user_func($this->processClass, $refl, $doc); + } + + $properties = []; + foreach ($refl->getProperties() as $reflProperty) { + $properties[] = $this->documentProperty($reflProperty); + } + + $properties = array_filter($properties); + $doc .= implode("\n", $properties); + + $methods = []; + foreach ($refl->getMethods() as $reflMethod) { + $methods[$reflMethod->name] = $this->documentMethod($reflMethod); + } + if (is_callable($this->reorderMethods)) { + call_user_func_array($this->reorderMethods, [&$methods]); + } + + $methods = array_filter($methods); + + $doc .= implode("\n", $methods)."\n"; + + return $doc; + } + + /** + * @param \ReflectionClass $reflectionClass + * + * @return string + */ + protected function documentClassSignature(\ReflectionClass $reflectionClass) + { + if ($this->processClassSignature === false) { + return ""; + } + + $signature = "## {$reflectionClass->name}\n\n"; + + if ($parent = $reflectionClass->getParentClass()) { + $signature .= "* *Extends* `{$parent->name}`"; + } + $interfaces = $reflectionClass->getInterfaceNames(); + if (count($interfaces)) { + $signature .= "\n* *Implements* `" . implode('`, `', $interfaces) . '`'; + } + $traits = $reflectionClass->getTraitNames(); + if (count($traits)) { + $signature .= "\n* *Uses* `" . implode('`, `', $traits) . '`'; + } + if (is_callable($this->processClassSignature)) { + $signature = call_user_func($this->processClassSignature, $reflectionClass, $signature); + } + + return $signature; + } + + /** + * @param \ReflectionClass $reflectionClass + * + * @return string + */ + protected function documentClassDocBlock(\ReflectionClass $reflectionClass) + { + if ($this->processClassDocBlock === false) { + return ""; + } + $doc = self::indentDoc($reflectionClass->getDocComment()); + if (is_callable($this->processClassDocBlock)) { + $doc = call_user_func($this->processClassDocBlock, $reflectionClass, $doc); + } + return $doc; + } + + /** + * @param \ReflectionMethod $reflectedMethod + * + * @return string + */ + protected function documentMethod(\ReflectionMethod $reflectedMethod) + { + if ($this->processMethod === false) { + return ""; + } + if (is_callable($this->filterMethods)) { + $ret = call_user_func($this->filterMethods, $reflectedMethod); + if (!$ret) { + return ""; + } + } else { + if (!$reflectedMethod->isPublic()) { + return ""; + } + } + + $signature = $this->documentMethodSignature($reflectedMethod); + $docblock = $this->documentMethodDocBlock($reflectedMethod); + $methodDoc = "$signature $docblock"; + if (is_callable($this->processMethod)) { + $methodDoc = call_user_func($this->processMethod, $reflectedMethod, $methodDoc); + } + return $methodDoc; + } + + /** + * @param \ReflectionProperty $reflectedProperty + * + * @return string + */ + protected function documentProperty(\ReflectionProperty $reflectedProperty) + { + if ($this->processProperty === false) { + return ""; + } + if (is_callable($this->filterProperties)) { + $ret = call_user_func($this->filterProperties, $reflectedProperty); + if (!$ret) { + return ""; + } + } else { + if (!$reflectedProperty->isPublic()) { + return ""; + } + } + $signature = $this->documentPropertySignature($reflectedProperty); + $docblock = $this->documentPropertyDocBlock($reflectedProperty); + $propertyDoc = $signature . $docblock; + if (is_callable($this->processProperty)) { + $propertyDoc = call_user_func($this->processProperty, $reflectedProperty, $propertyDoc); + } + return $propertyDoc; + } + + /** + * @param \ReflectionProperty $reflectedProperty + * + * @return string + */ + protected function documentPropertySignature(\ReflectionProperty $reflectedProperty) + { + if ($this->processPropertySignature === false) { + return ""; + } + $modifiers = implode(' ', \Reflection::getModifierNames($reflectedProperty->getModifiers())); + $signature = "#### *$modifiers* {$reflectedProperty->name}"; + if (is_callable($this->processPropertySignature)) { + $signature = call_user_func($this->processPropertySignature, $reflectedProperty, $signature); + } + return $signature; + } + + /** + * @param \ReflectionProperty $reflectedProperty + * + * @return string + */ + protected function documentPropertyDocBlock(\ReflectionProperty $reflectedProperty) + { + if ($this->processPropertyDocBlock === false) { + return ""; + } + $propertyDoc = $reflectedProperty->getDocComment(); + // take from parent + if (!$propertyDoc) { + $parent = $reflectedProperty->getDeclaringClass(); + while ($parent = $parent->getParentClass()) { + if ($parent->hasProperty($reflectedProperty->name)) { + $propertyDoc = $parent->getProperty($reflectedProperty->name)->getDocComment(); + } + } + } + $propertyDoc = self::indentDoc($propertyDoc, 7); + $propertyDoc = preg_replace("~^@(.*?)([$\s])~", ' * `$1` $2', $propertyDoc); // format annotations + if (is_callable($this->processPropertyDocBlock)) { + $propertyDoc = call_user_func($this->processPropertyDocBlock, $reflectedProperty, $propertyDoc); + } + return ltrim($propertyDoc); + } + + /** + * @param \ReflectionParameter $param + * + * @return string + */ + protected function documentParam(\ReflectionParameter $param) + { + $text = ""; + if ($param->isArray()) { + $text .= 'array '; + } + if ($param->isCallable()) { + $text .= 'callable '; + } + $text .= '$' . $param->name; + if ($param->isDefaultValueAvailable()) { + if ($param->allowsNull()) { + $text .= ' = null'; + } else { + $text .= ' = ' . str_replace("\n", ' ', print_r($param->getDefaultValue(), true)); + } + } + + return $text; + } + + /** + * @param string $doc + * @param int $indent + * + * @return string + */ + public static function indentDoc($doc, $indent = 3) + { + if (!$doc) { + return $doc; + } + return implode( + "\n", + array_map( + function ($line) use ($indent) { + return substr($line, $indent); + }, + explode("\n", $doc) + ) + ); + } + + /** + * @param \ReflectionMethod $reflectedMethod + * + * @return string + */ + protected function documentMethodSignature(\ReflectionMethod $reflectedMethod) + { + if ($this->processMethodSignature === false) { + return ""; + } + $modifiers = implode(' ', \Reflection::getModifierNames($reflectedMethod->getModifiers())); + $params = implode( + ', ', + array_map( + function ($p) { + return $this->documentParam($p); + }, + $reflectedMethod->getParameters() + ) + ); + $signature = "#### *$modifiers* {$reflectedMethod->name}($params)"; + if (is_callable($this->processMethodSignature)) { + $signature = call_user_func($this->processMethodSignature, $reflectedMethod, $signature); + } + return $signature; + } + + /** + * @param \ReflectionMethod $reflectedMethod + * + * @return string + */ + protected function documentMethodDocBlock(\ReflectionMethod $reflectedMethod) + { + if ($this->processMethodDocBlock === false) { + return ""; + } + $methodDoc = $reflectedMethod->getDocComment(); + // take from parent + if (!$methodDoc) { + $parent = $reflectedMethod->getDeclaringClass(); + while ($parent = $parent->getParentClass()) { + if ($parent->hasMethod($reflectedMethod->name)) { + $methodDoc = $parent->getMethod($reflectedMethod->name)->getDocComment(); + } + } + } + // take from interface + if (!$methodDoc) { + $interfaces = $reflectedMethod->getDeclaringClass()->getInterfaces(); + foreach ($interfaces as $interface) { + $i = new \ReflectionClass($interface->name); + if ($i->hasMethod($reflectedMethod->name)) { + $methodDoc = $i->getMethod($reflectedMethod->name)->getDocComment(); + break; + } + } + } + + $methodDoc = self::indentDoc($methodDoc, 7); + $methodDoc = preg_replace("~^@(.*?) ([$\s])~m", ' * `$1` $2', $methodDoc); // format annotations + if (is_callable($this->processMethodDocBlock)) { + $methodDoc = call_user_func($this->processMethodDocBlock, $reflectedMethod, $methodDoc); + } + + return $methodDoc; + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Development/GenerateTask.php b/src/composer/vendor/consolidation/robo/src/Task/Development/GenerateTask.php new file mode 100644 index 00000000..e5040575 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Development/GenerateTask.php @@ -0,0 +1,108 @@ +taskGenerateTask('Symfony\Component\Filesystem\Filesystem', 'FilesystemStack') + * ->run(); + * ``` + */ +class GenerateTask extends BaseTask +{ + /** + * @var string + */ + protected $className; + + /** + * @var string + */ + protected $wrapperClassName; + + /** + * @param string $className + * @param string $wrapperClassName + */ + public function __construct($className, $wrapperClassName = '') + { + $this->className = $className; + $this->wrapperClassName = $wrapperClassName; + } + + /** + * {@inheritdoc} + */ + public function run() + { + $delegate = new \ReflectionClass($this->className); + $replacements = []; + + $leadingCommentChars = " * "; + $methodDescriptions = []; + $methodImplementations = []; + $immediateMethods = []; + foreach ($delegate->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) { + $methodName = $method->name; + $getter = preg_match('/^(get|has|is)/', $methodName); + $setter = preg_match('/^(set|unset)/', $methodName); + $argPrototypeList = []; + $argNameList = []; + $needsImplementation = false; + foreach ($method->getParameters() as $arg) { + $argDescription = '$' . $arg->name; + $argNameList[] = $argDescription; + if ($arg->isOptional()) { + $argDescription = $argDescription . ' = ' . str_replace("\n", "", var_export($arg->getDefaultValue(), true)); + // We will create wrapper methods for any method that + // has default parameters. + $needsImplementation = true; + } + $argPrototypeList[] = $argDescription; + } + $argPrototypeString = implode(', ', $argPrototypeList); + $argNameListString = implode(', ', $argNameList); + + if ($methodName[0] != '_') { + $methodDescriptions[] = "@method $methodName($argPrototypeString)"; + + if ($getter) { + $immediateMethods[] = " public function $methodName($argPrototypeString)\n {\n return \$this->delegate->$methodName($argNameListString);\n }"; + } elseif ($setter) { + $immediateMethods[] = " public function $methodName($argPrototypeString)\n {\n \$this->delegate->$methodName($argNameListString);\n return \$this;\n }"; + } elseif ($needsImplementation) { + // Include an implementation for the wrapper method if necessary + $methodImplementations[] = " protected function _$methodName($argPrototypeString)\n {\n \$this->delegate->$methodName($argNameListString);\n }"; + } + } + } + + $classNameParts = explode('\\', $this->className); + $delegate = array_pop($classNameParts); + $delegateNamespace = implode('\\', $classNameParts); + + if (empty($this->wrapperClassName)) { + $this->wrapperClassName = $delegate; + } + + $replacements['{delegateNamespace}'] = $delegateNamespace; + $replacements['{delegate}'] = $delegate; + $replacements['{wrapperClassName}'] = $this->wrapperClassName; + $replacements['{taskname}'] = "task$delegate"; + $replacements['{methodList}'] = $leadingCommentChars . implode("\n$leadingCommentChars", $methodDescriptions); + $replacements['{immediateMethods}'] = "\n\n" . implode("\n\n", $immediateMethods); + $replacements['{methodImplementations}'] = "\n\n" . implode("\n\n", $methodImplementations); + + $template = file_get_contents(__DIR__ . '/../../../data/Task/Development/GeneratedWrapper.tmpl'); + $template = str_replace(array_keys($replacements), array_values($replacements), $template); + + // Returning data in the $message will cause it to be printed. + return Result::success($this, $template); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Development/GitHub.php b/src/composer/vendor/consolidation/robo/src/Task/Development/GitHub.php new file mode 100644 index 00000000..62407241 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Development/GitHub.php @@ -0,0 +1,141 @@ +repo = $repo; + return $this; + } + + /** + * @param string $owner + * + * @return $this + */ + public function owner($owner) + { + $this->owner = $owner; + return $this; + } + + /** + * @param string $uri + * + * @return $this + */ + public function uri($uri) + { + list($this->owner, $this->repo) = explode('/', $uri); + return $this; + } + + /** + * @return string + */ + protected function getUri() + { + return $this->owner . '/' . $this->repo; + } + + /** + * @param string $user + * + * @return $this + */ + public function user($user) + { + $this->user = $user; + return $this; + } + + /** + * @param $password + * + * @return $this + */ + public function password($password) + { + $this->password = $password; + return $this; + } + + /** + * @param string $uri + * @param array $params + * @param string $method + * + * @return array + * + * @throws \Robo\Exception\TaskException + */ + protected function sendRequest($uri, $params = [], $method = 'POST') + { + if (!$this->owner or !$this->repo) { + throw new TaskException($this, 'Repo URI is not set'); + } + + $ch = curl_init(); + $url = sprintf('%s/repos/%s/%s', self::GITHUB_URL, $this->getUri(), $uri); + $this->printTaskInfo($url); + $this->printTaskInfo('{method} {url}', ['method' => $method, 'url' => $url]); + + if (!empty($this->user)) { + curl_setopt($ch, CURLOPT_USERPWD, $this->user . ':' . $this->password); + } + + curl_setopt_array( + $ch, + array( + CURLOPT_URL => $url, + CURLOPT_RETURNTRANSFER => true, + CURLOPT_POST => $method != 'GET', + CURLOPT_POSTFIELDS => json_encode($params), + CURLOPT_FOLLOWLOCATION => true, + CURLOPT_USERAGENT => "Robo" + ) + ); + + $output = curl_exec($ch); + $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); + $response = json_decode($output); + + $this->printTaskInfo($output); + return [$code, $response]; + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Development/GitHubRelease.php b/src/composer/vendor/consolidation/robo/src/Task/Development/GitHubRelease.php new file mode 100644 index 00000000..ac9743e0 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Development/GitHubRelease.php @@ -0,0 +1,208 @@ +taskGitHubRelease('0.1.0') + * ->uri('consolidation-org/Robo') + * ->description('Add stuff people need.') + * ->change('Fix #123') + * ->change('Add frobulation method to all widgets') + * ->run(); + * ?> + * ``` + */ +class GitHubRelease extends GitHub +{ + /** + * @var string + */ + protected $tag; + + /** + * @var string + */ + protected $name; + + /** + * @var string + */ + protected $description = ''; + + /** + * @var string[] + */ + protected $changes = []; + + /** + * @var bool + */ + protected $draft = false; + + /** + * @var bool + */ + protected $prerelease = false; + + /** + * @var string + */ + protected $comittish = 'master'; + + /** + * @param string $tag + */ + public function __construct($tag) + { + $this->tag = $tag; + } + + /** + * @param string $tag + * + * @return $this + */ + public function tag($tag) + { + $this->tag = $tag; + return $this; + } + + /** + * @param bool $draft + * + * @return $this + */ + public function draft($draft) + { + $this->draft = $draft; + return $this; + } + + /** + * @param string $name + * + * @return $this + */ + public function name($name) + { + $this->name = $name; + return $this; + } + + /** + * @param string $description + * + * @return $this + */ + public function description($description) + { + $this->description = $description; + return $this; + } + + /** + * @param bool $prerelease + * + * @return $this + */ + public function prerelease($prerelease) + { + $this->prerelease = $prerelease; + return $this; + } + + /** + * @param string $comittish + * + * @return $this + */ + public function comittish($comittish) + { + $this->comittish = $comittish; + return $this; + } + + /** + * @param string $description + * + * @return $this + */ + public function appendDescription($description) + { + if (!empty($this->description)) { + $this->description .= "\n\n"; + } + $this->description .= $description; + return $this; + } + + public function changes(array $changes) + { + $this->changes = array_merge($this->changes, $changes); + return $this; + } + + /** + * @param string $change + * + * @return $this + */ + public function change($change) + { + $this->changes[] = $change; + return $this; + } + + /** + * @return string + */ + protected function getBody() + { + $body = $this->description; + if (!empty($this->changes)) { + $changes = array_map( + function ($line) { + return "* $line"; + }, + $this->changes + ); + $changesText = implode("\n", $changes); + $body .= "### Changelog \n\n$changesText"; + } + return $body; + } + + /** + * {@inheritdoc} + */ + public function run() + { + $this->printTaskInfo('Releasing {tag}', ['tag' => $this->tag]); + $this->startTimer(); + list($code, $data) = $this->sendRequest( + 'releases', + [ + "tag_name" => $this->tag, + "target_commitish" => $this->comittish, + "name" => $this->tag, + "body" => $this->getBody(), + "draft" => $this->draft, + "prerelease" => $this->prerelease + ] + ); + $this->stopTimer(); + + return new Result( + $this, + in_array($code, [200, 201]) ? 0 : 1, + isset($data->message) ? $data->message : '', + ['response' => $data, 'time' => $this->getExecutionTime()] + ); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Development/OpenBrowser.php b/src/composer/vendor/consolidation/robo/src/Task/Development/OpenBrowser.php new file mode 100644 index 00000000..867216ea --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Development/OpenBrowser.php @@ -0,0 +1,80 @@ +taskOpenBrowser('http://localhost') + * ->run(); + * + * // open two browser windows + * $this->taskOpenBrowser([ + * 'http://localhost/mysite', + * 'http://localhost/mysite2' + * ]) + * ->run(); + * ``` + */ +class OpenBrowser extends BaseTask +{ + /** + * @var string[] + */ + protected $urls = []; + + /** + * @param string|array $url + */ + public function __construct($url) + { + $this->urls = (array) $url; + } + + /** + * {@inheritdoc} + */ + public function run() + { + $openCommand = $this->getOpenCommand(); + + if (empty($openCommand)) { + return Result::error($this, 'no suitable browser opening command found'); + } + + foreach ($this->urls as $url) { + passthru(sprintf($openCommand, ProcessUtils::escapeArgument($url))); + $this->printTaskInfo('Opened {url}', ['url' => $url]); + } + + return Result::success($this); + } + + /** + * @return null|string + */ + private function getOpenCommand() + { + if (defined('PHP_WINDOWS_VERSION_MAJOR')) { + return 'start "web" explorer "%s"'; + } + + passthru('which xdg-open', $linux); + passthru('which open', $osx); + + if (0 === $linux) { + return 'xdg-open %s'; + } + + if (0 === $osx) { + return 'open %s'; + } + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Development/PackPhar.php b/src/composer/vendor/consolidation/robo/src/Task/Development/PackPhar.php new file mode 100644 index 00000000..3565dcbc --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Development/PackPhar.php @@ -0,0 +1,253 @@ +taskPackPhar('package/codecept.phar') + * ->compress() + * ->stub('package/stub.php'); + * + * $finder = Finder::create() + * ->name('*.php') + * ->in('src'); + * + * foreach ($finder as $file) { + * $pharTask->addFile('src/'.$file->getRelativePathname(), $file->getRealPath()); + * } + * + * $finder = Finder::create()->files() + * ->name('*.php') + * ->in('vendor'); + * + * foreach ($finder as $file) { + * $pharTask->addStripped('vendor/'.$file->getRelativePathname(), $file->getRealPath()); + * } + * $pharTask->run(); + * + * // verify Phar is packed correctly + * $code = $this->_exec('php package/codecept.phar'); + * ?> + * ``` + */ +class PackPhar extends BaseTask implements PrintedInterface, ProgressIndicatorAwareInterface +{ + /** + * @var \Phar + */ + protected $phar; + + /** + * @var null|string + */ + protected $compileDir = null; + + /** + * @var string + */ + protected $filename; + + /** + * @var bool + */ + protected $compress = false; + + protected $stub; + + protected $bin; + + /** + * @var string + */ + protected $stubTemplate = <<filename = $filename; + if (file_exists($file->getRealPath())) { + @unlink($file->getRealPath()); + } + $this->phar = new \Phar($file->getPathname(), 0, $file->getFilename()); + } + + /** + * @param bool $compress + * + * @return $this + */ + public function compress($compress = true) + { + $this->compress = $compress; + return $this; + } + + /** + * @param string $stub + * + * @return $this + */ + public function stub($stub) + { + $this->phar->setStub(file_get_contents($stub)); + return $this; + } + + /** + * {@inheritdoc} + */ + public function progressIndicatorSteps() + { + // run() will call advanceProgressIndicator() once for each + // file, one after calling stopBuffering, and again after compression. + return count($this->files)+2; + } + + /** + * {@inheritdoc} + */ + public function run() + { + $this->printTaskInfo('Creating {filename}', ['filename' => $this->filename]); + $this->phar->setSignatureAlgorithm(\Phar::SHA1); + $this->phar->startBuffering(); + + $this->printTaskInfo('Packing {file-count} files into phar', ['file-count' => count($this->files)]); + + $this->startProgressIndicator(); + foreach ($this->files as $path => $content) { + $this->phar->addFromString($path, $content); + $this->advanceProgressIndicator(); + } + $this->phar->stopBuffering(); + $this->advanceProgressIndicator(); + + if ($this->compress and in_array('GZ', \Phar::getSupportedCompression())) { + if (count($this->files) > 1000) { + $this->printTaskInfo('Too many files. Compression DISABLED'); + } else { + $this->printTaskInfo('{filename} compressed', ['filename' => $this->filename]); + $this->phar = $this->phar->compressFiles(\Phar::GZ); + } + } + $this->advanceProgressIndicator(); + $this->stopProgressIndicator(); + $this->printTaskSuccess('{filename} produced', ['filename' => $this->filename]); + return Result::success($this, '', ['time' => $this->getExecutionTime()]); + } + + /** + * @param string $path + * @param string $file + * + * @return $this + */ + public function addStripped($path, $file) + { + $this->files[$path] = $this->stripWhitespace(file_get_contents($file)); + return $this; + } + + /** + * @param string $path + * @param string $file + * + * @return $this + */ + public function addFile($path, $file) + { + $this->files[$path] = file_get_contents($file); + return $this; + } + + /** + * @param \Symfony\Component\Finder\SplFileInfo[] $files + */ + public function addFiles($files) + { + foreach ($files as $file) { + $this->addFile($file->getRelativePathname(), $file->getRealPath()); + } + } + + /** + * @param string $file + * + * @return $this + */ + public function executable($file) + { + $source = file_get_contents($file); + if (strpos($source, '#!/usr/bin/env php') === 0) { + $source = substr($source, strpos($source, 'phar->setStub(sprintf($this->stubTemplate, $source)); + return $this; + } + + /** + * Strips whitespace from source. Taken from composer + * + * @param string $source + * + * @return string + */ + private function stripWhitespace($source) + { + if (!function_exists('token_get_all')) { + return $source; + } + + $output = ''; + foreach (token_get_all($source) as $token) { + if (is_string($token)) { + $output .= $token; + } elseif (in_array($token[0], array(T_COMMENT, T_DOC_COMMENT))) { + // $output .= $token[1]; + $output .= str_repeat("\n", substr_count($token[1], "\n")); + } elseif (T_WHITESPACE === $token[0]) { + // reduce wide spaces + $whitespace = preg_replace('{[ \t]+}', ' ', $token[1]); + // normalize newlines to \n + $whitespace = preg_replace('{(?:\r\n|\r|\n)}', "\n", $whitespace); + // trim leading spaces + $whitespace = preg_replace('{\n +}', "\n", $whitespace); + $output .= $whitespace; + } else { + $output .= $token[1]; + } + } + + return $output; + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Development/PhpServer.php b/src/composer/vendor/consolidation/robo/src/Task/Development/PhpServer.php new file mode 100644 index 00000000..6dd36680 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Development/PhpServer.php @@ -0,0 +1,86 @@ +taskServer(8000) + * ->dir('public') + * ->run(); + * + * // run with IP 0.0.0.0 + * $this->taskServer(8000) + * ->host('0.0.0.0') + * ->run(); + * + * // execute server in background + * $this->taskServer(8000) + * ->background() + * ->run(); + * ?> + * ``` + */ +class PhpServer extends Exec +{ + /** + * @var int + */ + protected $port; + + /** + * @var string + */ + protected $host = '127.0.0.1'; + + /** + * {@inheritdoc} + */ + protected $command = 'php -S %s:%d '; + + /** + * @param int $port + */ + public function __construct($port) + { + $this->port = $port; + + if (strtolower(PHP_OS) === 'linux') { + $this->command = 'exec php -S %s:%d '; + } + } + + /** + * @param string $host + * + * @return $this + */ + public function host($host) + { + $this->host = $host; + return $this; + } + + /** + * @param string $path + * + * @return $this + */ + public function dir($path) + { + $this->command .= "-t $path"; + return $this; + } + + /** + * {@inheritdoc} + */ + public function getCommand() + { + return sprintf($this->command . $this->arguments, $this->host, $this->port); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Development/SemVer.php b/src/composer/vendor/consolidation/robo/src/Task/Development/SemVer.php new file mode 100644 index 00000000..b9fb5929 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Development/SemVer.php @@ -0,0 +1,233 @@ +taskSemVer('.semver') + * ->increment() + * ->run(); + * ?> + * ``` + * + */ +class SemVer implements TaskInterface +{ + const SEMVER = "---\n:major: %d\n:minor: %d\n:patch: %d\n:special: '%s'\n:metadata: '%s'"; + + const REGEX = "/^\-\-\-\n:major:\s(0|[1-9]\d*)\n:minor:\s(0|[1-9]\d*)\n:patch:\s(0|[1-9]\d*)\n:special:\s'([a-zA-z0-9]*\.?(?:0|[1-9]\d*)?)'\n:metadata:\s'((?:0|[1-9]\d*)?(?:\.[a-zA-z0-9\.]*)?)'/"; + + /** + * @var string + */ + protected $format = 'v%M.%m.%p%s'; + + /** + * @var string + */ + protected $specialSeparator = '-'; + + /** + * @var string + */ + protected $metadataSeparator = '+'; + + /** + * @var string + */ + protected $path; + + /** + * @var array + */ + protected $version = [ + 'major' => 0, + 'minor' => 0, + 'patch' => 0, + 'special' => '', + 'metadata' => '' + ]; + + /** + * @param string $filename + */ + public function __construct($filename = '') + { + $this->path = $filename; + + if (file_exists($this->path)) { + $this->parse(); + } + } + + /** + * @return string + */ + public function __toString() + { + $search = ['%M', '%m', '%p', '%s']; + $replace = $this->version + ['extra' => '']; + + foreach (['special', 'metadata'] as $key) { + if (!empty($replace[$key])) { + $separator = $key . 'Separator'; + $replace['extra'] .= $this->{$separator} . $replace[$key]; + } + unset($replace[$key]); + } + + return str_replace($search, $replace, $this->format); + } + + /** + * @param string $format + * + * @return $this + */ + public function setFormat($format) + { + $this->format = $format; + return $this; + } + + /** + * @param string $separator + * + * @return $this + */ + public function setMetadataSeparator($separator) + { + $this->metadataSeparator = $separator; + return $this; + } + + /** + * @param string $separator + * + * @return $this + */ + public function setPrereleaseSeparator($separator) + { + $this->specialSeparator = $separator; + return $this; + } + + /** + * @param string $what + * + * @return $this + * + * @throws \Robo\Exception\TaskException + */ + public function increment($what = 'patch') + { + switch ($what) { + case 'major': + $this->version['major']++; + $this->version['minor'] = 0; + $this->version['patch'] = 0; + break; + case 'minor': + $this->version['minor']++; + $this->version['patch'] = 0; + break; + case 'patch': + $this->version['patch']++; + break; + default: + throw new TaskException( + $this, + 'Bad argument, only one of the following is allowed: major, minor, patch' + ); + } + return $this; + } + + /** + * @param string $tag + * + * @return $this + * + * @throws \Robo\Exception\TaskException + */ + public function prerelease($tag = 'RC') + { + if (!is_string($tag)) { + throw new TaskException($this, 'Bad argument, only strings allowed.'); + } + + $number = 0; + + if (!empty($this->version['special'])) { + list($current, $number) = explode('.', $this->version['special']); + if ($tag != $current) { + $number = 0; + } + } + + $number++; + + $this->version['special'] = implode('.', [$tag, $number]); + return $this; + } + + /** + * @param array|string $data + * + * @return $this + */ + public function metadata($data) + { + if (is_array($data)) { + $data = implode('.', $data); + } + + $this->version['metadata'] = $data; + return $this; + } + + /** + * {@inheritdoc} + */ + public function run() + { + $written = $this->dump(); + return new Result($this, (int)($written === false), $this->__toString()); + } + + /** + * @return bool + * + * @throws \Robo\Exception\TaskException + */ + protected function dump() + { + extract($this->version); + $semver = sprintf(self::SEMVER, $major, $minor, $patch, $special, $metadata); + if (is_writeable($this->path) === false || file_put_contents($this->path, $semver) === false) { + throw new TaskException($this, 'Failed to write semver file.'); + } + return true; + } + + /** + * @throws \Robo\Exception\TaskException + */ + protected function parse() + { + $output = file_get_contents($this->path); + + if (!preg_match_all(self::REGEX, $output, $matches)) { + throw new TaskException($this, 'Bad semver file.'); + } + + list(, $major, $minor, $patch, $special, $metadata) = array_map('current', $matches); + $this->version = compact('major', 'minor', 'patch', 'special', 'metadata'); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Development/loadTasks.php b/src/composer/vendor/consolidation/robo/src/Task/Development/loadTasks.php new file mode 100644 index 00000000..e3dc49a3 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Development/loadTasks.php @@ -0,0 +1,86 @@ +task(Changelog::class, $filename); + } + + /** + * @param string $filename + * + * @return GenerateMarkdownDoc + */ + protected function taskGenDoc($filename) + { + return $this->task(GenerateMarkdownDoc::class, $filename); + } + + /** + * @param string $className + * @param string $wrapperClassName + * + * @return \Robo\Task\Development\GenerateTask + */ + protected function taskGenTask($className, $wrapperClassName = '') + { + return $this->task(GenerateTask::class, $className, $wrapperClassName); + } + + /** + * @param string $pathToSemVer + * + * @return SemVer + */ + protected function taskSemVer($pathToSemVer = '.semver') + { + return $this->task(SemVer::class, $pathToSemVer); + } + + /** + * @param int $port + * + * @return PhpServer + */ + protected function taskServer($port = 8000) + { + return $this->task(PhpServer::class, $port); + } + + /** + * @param string $filename + * + * @return PackPhar + */ + protected function taskPackPhar($filename) + { + return $this->task(PackPhar::class, $filename); + } + + /** + * @param string $tag + * + * @return GitHubRelease + */ + protected function taskGitHubRelease($tag) + { + return $this->task(GitHubRelease::class, $tag); + } + + /** + * @param string|array $url + * + * @return OpenBrowser + */ + protected function taskOpenBrowser($url) + { + return $this->task(OpenBrowser::class, $url); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Docker/Base.php b/src/composer/vendor/consolidation/robo/src/Task/Docker/Base.php new file mode 100644 index 00000000..9ecc3b6b --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Docker/Base.php @@ -0,0 +1,28 @@ +getCommand(); + $this->printTaskInfo('Running {command}', ['command' => $command]); + return $this->executeCommand($command); + } + + abstract public function getCommand(); +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Docker/Build.php b/src/composer/vendor/consolidation/robo/src/Task/Docker/Build.php new file mode 100644 index 00000000..11eb92ab --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Docker/Build.php @@ -0,0 +1,55 @@ +taskDockerBuild()->run(); + * + * $this->taskDockerBuild('path/to/dir') + * ->tag('database') + * ->run(); + * + * ?> + * + * ``` + * + * Class Build + * @package Robo\Task\Docker + */ +class Build extends Base +{ + /** + * @var string + */ + protected $path; + + /** + * @param string $path + */ + public function __construct($path = '.') + { + $this->command = "docker build"; + $this->path = $path; + } + + /** + * {@inheritdoc} + */ + public function getCommand() + { + return $this->command . ' ' . $this->arguments . ' ' . $this->path; + } + + /** + * @param string $tag + * + * @return $this + */ + public function tag($tag) + { + return $this->option('-t', $tag); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Docker/Commit.php b/src/composer/vendor/consolidation/robo/src/Task/Docker/Commit.php new file mode 100644 index 00000000..302f1920 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Docker/Commit.php @@ -0,0 +1,66 @@ +taskDockerCommit($containerId) + * ->name('my/database') + * ->run(); + * + * // alternatively you can take the result from DockerRun task: + * + * $result = $this->taskDockerRun('db') + * ->exec('./prepare_database.sh') + * ->run(); + * + * $task->dockerCommit($result) + * ->name('my/database') + * ->run(); + * ``` + */ +class Commit extends Base +{ + /** + * @var string + */ + protected $command = "docker commit"; + + /** + * @var string + */ + protected $name; + + /** + * @var string + */ + protected $cid; + + /** + * @param string|\Robo\Task\Docker\Result $cidOrResult + */ + public function __construct($cidOrResult) + { + $this->cid = $cidOrResult instanceof Result ? $cidOrResult->getCid() : $cidOrResult; + } + + /** + * {@inheritdoc} + */ + public function getCommand() + { + return $this->command . ' ' . $this->cid . ' ' . $this->name . ' ' . $this->arguments; + } + + /** + * @param $name + * + * @return $this + */ + public function name($name) + { + $this->name = $name; + return $this; + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Docker/Exec.php b/src/composer/vendor/consolidation/robo/src/Task/Docker/Exec.php new file mode 100644 index 00000000..f26942e3 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Docker/Exec.php @@ -0,0 +1,93 @@ +taskDockerRun('test_env') + * ->detached() + * ->run(); + * + * $this->taskDockerExec($test) + * ->interactive() + * ->exec('./runtests') + * ->run(); + * + * // alternatively use commands from other tasks + * + * $this->taskDockerExec($test) + * ->interactive() + * ->exec($this->taskCodecept()->suite('acceptance')) + * ->run(); + * ?> + * ``` + * + */ +class Exec extends Base +{ + use CommandReceiver; + + /** + * @var string + */ + protected $command = "docker exec"; + + /** + * @var string + */ + protected $cid; + + /** + * @var string + */ + protected $run = ''; + + /** + * @param string|\Robo\Result $cidOrResult + */ + public function __construct($cidOrResult) + { + $this->cid = $cidOrResult instanceof Result ? $cidOrResult->getCid() : $cidOrResult; + } + + /** + * @return $this + */ + public function detached() + { + $this->option('-d'); + return $this; + } + + /** + * @return $this + */ + public function interactive() + { + $this->option('-i'); + return $this; + } + + /** + * @param string|\Robo\Contract\CommandInterface $command + * + * @return $this + */ + public function exec($command) + { + $this->run = $this->receiveCommand($command); + return $this; + } + + /** + * {@inheritdoc} + */ + public function getCommand() + { + return $this->command . ' ' . $this->arguments . ' ' . $this->cid.' '.$this->run; + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Docker/Pull.php b/src/composer/vendor/consolidation/robo/src/Task/Docker/Pull.php new file mode 100644 index 00000000..32ba5b40 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Docker/Pull.php @@ -0,0 +1,33 @@ +taskDockerPull('wordpress') + * ->run(); + * + * ?> + * ``` + * + */ +class Pull extends Base +{ + /** + * @param string $image + */ + public function __construct($image) + { + $this->command = "docker pull $image "; + } + + /** + * {@inheritdoc} + */ + public function getCommand() + { + return $this->command . ' ' . $this->arguments; + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Docker/Remove.php b/src/composer/vendor/consolidation/robo/src/Task/Docker/Remove.php new file mode 100644 index 00000000..0a8c0ac6 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Docker/Remove.php @@ -0,0 +1,32 @@ +taskDockerRemove($container) + * ->run(); + * ?> + * ``` + * + */ +class Remove extends Base +{ + /** + * @param string $container + */ + public function __construct($container) + { + $this->command = "docker rm $container "; + } + + /** + * {@inheritdoc} + */ + public function getCommand() + { + return $this->command . ' ' . $this->arguments; + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Docker/Result.php b/src/composer/vendor/consolidation/robo/src/Task/Docker/Result.php new file mode 100644 index 00000000..0533159a --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Docker/Result.php @@ -0,0 +1,35 @@ +taskDockerRun('mysql')->run(); + * + * $result = $this->taskDockerRun('my_db_image') + * ->env('DB', 'database_name') + * ->volume('/path/to/data', '/data') + * ->detached() + * ->publish(3306) + * ->name('my_mysql') + * ->run(); + * + * // retrieve container's cid: + * $this->say("Running container ".$result->getCid()); + * + * // execute script inside container + * $result = $this->taskDockerRun('db') + * ->exec('prepare_test_data.sh') + * ->run(); + * + * $this->taskDockerCommit($result) + * ->name('test_db') + * ->run(); + * + * // link containers + * $mysql = $this->taskDockerRun('mysql') + * ->name('wp_db') // important to set name for linked container + * ->env('MYSQL_ROOT_PASSWORD', '123456') + * ->run(); + * + * $this->taskDockerRun('wordpress') + * ->link($mysql) + * ->publish(80, 8080) + * ->detached() + * ->run(); + * + * ?> + * ``` + * + */ +class Run extends Base +{ + use CommandReceiver; + + /** + * @var string + */ + protected $image = ''; + + /** + * @var string + */ + protected $run = ''; + + /** + * @var string + */ + protected $cidFile; + + /** + * @var string + */ + protected $name; + + /** + * @var string + */ + protected $dir; + + /** + * @param string $image + */ + public function __construct($image) + { + $this->image = $image; + } + + /** + * {@inheritdoc} + */ + public function getPrinted() + { + return $this->isPrinted; + } + + /** + * {@inheritdoc} + */ + public function getCommand() + { + if ($this->isPrinted) { + $this->option('-i'); + } + if ($this->cidFile) { + $this->option('cidfile', $this->cidFile); + } + return trim('docker run ' . $this->arguments . ' ' . $this->image . ' ' . $this->run); + } + + /** + * @return $this + */ + public function detached() + { + $this->option('-d'); + return $this; + } + + /** + * @return $this + */ + public function interactive() + { + $this->option('-i'); + return $this; + } + + /** + * @param string|\Robo\Contract\CommandInterface $run + * + * @return $this + */ + public function exec($run) + { + $this->run = $this->receiveCommand($run); + return $this; + } + + /** + * @param string $from + * @param null|string $to + * + * @return $this + */ + public function volume($from, $to = null) + { + $volume = $to ? "$from:$to" : $from; + $this->option('-v', $volume); + return $this; + } + + /** + * @param string $variable + * @param null|string $value + * + * @return $this + */ + public function env($variable, $value = null) + { + $env = $value ? "$variable=$value" : $variable; + return $this->option("-e", $env); + } + + /** + * @param null|int $port + * @param null|int $portTo + * + * @return $this + */ + public function publish($port = null, $portTo = null) + { + if (!$port) { + return $this->option('-P'); + } + if ($portTo) { + $port = "$port:$portTo"; + } + return $this->option('-p', $port); + } + + /** + * @param string $dir + * + * @return $this + */ + public function containerWorkdir($dir) + { + return $this->option('-w', $dir); + } + + /** + * @param string $user + * + * @return $this + */ + public function user($user) + { + return $this->option('-u', $user); + } + + /** + * @return $this + */ + public function privileged() + { + return $this->option('--privileged'); + } + + /** + * @param string $name + * + * @return $this + */ + public function name($name) + { + $this->name = $name; + return $this->option('name', $name); + } + + /** + * @param string|\Robo\Task\Docker\Result $name + * @param string $alias + * + * @return $this + */ + public function link($name, $alias) + { + if ($name instanceof Result) { + $name = $name->getContainerName(); + } + $this->option('link', "$name:$alias"); + return $this; + } + + /** + * @param string $dir + * + * @return $this + */ + public function tmpDir($dir) + { + $this->dir = $dir; + return $this; + } + + /** + * @return string + */ + public function getTmpDir() + { + return $this->dir ? $this->dir : sys_get_temp_dir(); + } + + /** + * @return string + */ + public function getUniqId() + { + return uniqid(); + } + + /** + * {@inheritdoc} + */ + public function run() + { + $this->cidFile = $this->getTmpDir() . '/docker_' . $this->getUniqId() . '.cid'; + $result = parent::run(); + $result['cid'] = $this->getCid(); + return $result; + } + + /** + * @return null|string + */ + protected function getCid() + { + if (!$this->cidFile || !file_exists($this->cidFile)) { + return null; + } + $cid = trim(file_get_contents($this->cidFile)); + @unlink($this->cidFile); + return $cid; + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Docker/Start.php b/src/composer/vendor/consolidation/robo/src/Task/Docker/Start.php new file mode 100644 index 00000000..ef19d74d --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Docker/Start.php @@ -0,0 +1,41 @@ +taskDockerStart($cidOrResult) + * ->run(); + * ?> + * ``` + */ +class Start extends Base +{ + /** + * @var string + */ + protected $command = "docker start"; + + /** + * @var null|string + */ + protected $cid; + + /** + * @param string|\Robo\Task\Docker\Result $cidOrResult + */ + public function __construct($cidOrResult) + { + $this->cid = $cidOrResult instanceof Result ? $cidOrResult->getCid() : $cidOrResult; + } + + /** + * {@inheritdoc} + */ + public function getCommand() + { + return $this->command . ' ' . $this->arguments . ' ' . $this->cid; + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Docker/Stop.php b/src/composer/vendor/consolidation/robo/src/Task/Docker/Stop.php new file mode 100644 index 00000000..4d0d436d --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Docker/Stop.php @@ -0,0 +1,41 @@ +taskDockerStop($cidOrResult) + * ->run(); + * ?> + * ``` + */ +class Stop extends Base +{ + /** + * @var string + */ + protected $command = "docker stop"; + + /** + * @var null|string + */ + protected $cid; + + /** + * @param string|\Robo\Task\Docker\Result $cidOrResult + */ + public function __construct($cidOrResult) + { + $this->cid = $cidOrResult instanceof Result ? $cidOrResult->getCid() : $cidOrResult; + } + + /** + * {@inheritdoc} + */ + public function getCommand() + { + return $this->command . ' ' . $this->arguments . ' ' . $this->cid; + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Docker/loadTasks.php b/src/composer/vendor/consolidation/robo/src/Task/Docker/loadTasks.php new file mode 100644 index 00000000..e58f5ef0 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Docker/loadTasks.php @@ -0,0 +1,85 @@ +task(Run::class, $image); + } + + /** + * @param string $image + * + * @return \Robo\Task\Docker\Pull + */ + protected function taskDockerPull($image) + { + return $this->task(Pull::class, $image); + } + + /** + * @param string $path + * + * @return \Robo\Task\Docker\Build + */ + protected function taskDockerBuild($path = '.') + { + return $this->task(Build::class, $path); + } + + /** + * @param string|\Robo\Task\Docker\Result $cidOrResult + * + * @return \Robo\Task\Docker\Stop + */ + protected function taskDockerStop($cidOrResult) + { + return $this->task(Stop::class, $cidOrResult); + } + + /** + * @param string|\Robo\Task\Docker\Result $cidOrResult + * + * @return \Robo\Task\Docker\Commit + */ + protected function taskDockerCommit($cidOrResult) + { + return $this->task(Commit::class, $cidOrResult); + } + + /** + * @param string|\Robo\Task\Docker\Result $cidOrResult + * + * @return \Robo\Task\Docker\Start + */ + protected function taskDockerStart($cidOrResult) + { + return $this->task(Start::class, $cidOrResult); + } + + /** + * @param string|\Robo\Task\Docker\Result $cidOrResult + * + * @return \Robo\Task\Docker\Remove + */ + protected function taskDockerRemove($cidOrResult) + { + return $this->task(Remove::class, $cidOrResult); + } + + /** + * @param string|\Robo\Task\Docker\Result $cidOrResult + * + * @return \Robo\Task\Docker\Exec + */ + protected function taskDockerExec($cidOrResult) + { + return $this->task(Exec::class, $cidOrResult); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/File/Concat.php b/src/composer/vendor/consolidation/robo/src/Task/File/Concat.php new file mode 100644 index 00000000..12b1eca0 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/File/Concat.php @@ -0,0 +1,101 @@ +taskConcat([ + * 'web/assets/screen.css', + * 'web/assets/print.css', + * 'web/assets/theme.css' + * ]) + * ->to('web/assets/style.css') + * ->run() + * ?> + * ``` + */ +class Concat extends BaseTask +{ + use ResourceExistenceChecker; + + /** + * @var array|Iterator + */ + protected $files; + + /** + * @var string + */ + protected $dst; + + /** + * Constructor. + * + * @param array|Iterator $files + */ + public function __construct($files) + { + $this->files = $files; + } + + /** + * set the destination file + * + * @param string $dst + * + * @return $this + */ + public function to($dst) + { + $this->dst = $dst; + + return $this; + } + + /** + * {@inheritdoc} + */ + public function run() + { + if (is_null($this->dst) || "" === $this->dst) { + return Result::error($this, 'You must specify a destination file with to() method.'); + } + + if (!$this->checkResources($this->files, 'file')) { + return Result::error($this, 'Source files are missing!'); + } + + if (file_exists($this->dst) && !is_writable($this->dst)) { + return Result::error($this, 'Destination already exists and cannot be overwritten.'); + } + + $dump = ''; + + foreach ($this->files as $path) { + foreach (glob($path) as $file) { + $dump .= file_get_contents($file) . "\n"; + } + } + + $this->printTaskInfo('Writing {destination}', ['destination' => $this->dst]); + + $dst = $this->dst . '.part'; + $write_result = file_put_contents($dst, $dump); + + if (false === $write_result) { + @unlink($dst); + return Result::error($this, 'File write failed.'); + } + // Cannot be cross-volume; should always succeed. + @rename($dst, $this->dst); + + return Result::success($this); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/File/Replace.php b/src/composer/vendor/consolidation/robo/src/Task/File/Replace.php new file mode 100644 index 00000000..1c7f16a1 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/File/Replace.php @@ -0,0 +1,139 @@ +taskReplaceInFile('VERSION') + * ->from('0.2.0') + * ->to('0.3.0') + * ->run(); + * + * $this->taskReplaceInFile('README.md') + * ->from(date('Y')-1) + * ->to(date('Y')) + * ->run(); + * + * $this->taskReplaceInFile('config.yml') + * ->regex('~^service:~') + * ->to('services:') + * ->run(); + * + * $this->taskReplaceInFile('box/robo.txt') + * ->from(array('##dbname##', '##dbhost##')) + * ->to(array('robo', 'localhost')) + * ->run(); + * ?> + * ``` + * + * @method regex(string) regex to match string to be replaced + * @method from(string|array) string(s) to be replaced + * @method to(string|array) value(s) to be set as a replacement + */ +class Replace extends BaseTask +{ + /** + * @var string + */ + protected $filename; + + /** + * @var string[] + */ + protected $from; + + /** + * @var string[] + */ + protected $to; + + /** + * @var string + */ + protected $regex; + + /** + * @param string $filename + */ + public function __construct($filename) + { + $this->filename = $filename; + } + + /** + * @param string $filename + * + * @return $this + */ + public function filename($filename) + { + $this->filename = $filename; + return $this; + } + + /** + * @param string $from + * + * @return $this + */ + public function from($from) + { + $this->from = $from; + return $this; + } + + /** + * @param string $to + * + * @return $this + */ + public function to($to) + { + $this->to = $to; + return $this; + } + + /** + * @param string $regex + * + * @return $this + */ + public function regex($regex) + { + $this->regex = $regex; + return $this; + } + + /** + * {@inheritdoc} + */ + public function run() + { + if (!file_exists($this->filename)) { + $this->printTaskError('File {filename} does not exist', ['filename' => $this->filename]); + return false; + } + + $text = file_get_contents($this->filename); + if ($this->regex) { + $text = preg_replace($this->regex, $this->to, $text, -1, $count); + } else { + $text = str_replace($this->from, $this->to, $text, $count); + } + if ($count > 0) { + $res = file_put_contents($this->filename, $text); + if ($res === false) { + return Result::error($this, "Error writing to file {filename}.", ['filename' => $this->filename]); + } + $this->printTaskSuccess("{filename} updated. {count} items replaced", ['filename' => $this->filename, 'count' => $count]); + } else { + $this->printTaskInfo("{filename} unchanged. {count} items replaced", ['filename' => $this->filename, 'count' => $count]); + } + return Result::success($this, '', ['replaced' => $count]); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/File/TmpFile.php b/src/composer/vendor/consolidation/robo/src/Task/File/TmpFile.php new file mode 100644 index 00000000..7c796d4c --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/File/TmpFile.php @@ -0,0 +1,73 @@ +collectionBuilder(); + * $tmpFilePath = $collection->taskTmpFile() + * ->line('-----') + * ->line(date('Y-m-d').' '.$title) + * ->line('----') + * ->getPath(); + * $collection->run(); + * ?> + * ``` + */ +class TmpFile extends Write implements CompletionInterface +{ + /** + * @param string $filename + * @param string $extension + * @param string $baseDir + * @param bool $includeRandomPart + */ + public function __construct($filename = 'tmp', $extension = '', $baseDir = '', $includeRandomPart = true) + { + if (empty($base)) { + $base = sys_get_temp_dir(); + } + if ($includeRandomPart) { + $random = static::randomString(); + $filename = "{$filename}_{$random}"; + } + $filename .= $extension; + parent::__construct("{$base}/{$filename}"); + } + + /** + * Generate a suitably random string to use as the suffix for our + * temporary file. + * + * @param int $length + * + * @return string + */ + private static function randomString($length = 12) + { + return substr(str_shuffle('23456789abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ'), 0, $length); + } + + /** + * Delete this file when our collection completes. + * If this temporary file is not part of a collection, + * then it will be deleted when the program terminates, + * presuming that it was created by taskTmpFile() or _tmpFile(). + */ + public function complete() + { + unlink($this->getPath()); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/File/Write.php b/src/composer/vendor/consolidation/robo/src/Task/File/Write.php new file mode 100644 index 00000000..6f0dae3a --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/File/Write.php @@ -0,0 +1,337 @@ +taskWriteToFile('blogpost.md') + * ->line('-----') + * ->line(date('Y-m-d').' '.$title) + * ->line('----') + * ->run(); + * ?> + * ``` + * + * @method append() + */ +class Write extends BaseTask +{ + /** + * @var array + */ + protected $stack = []; + + /** + * @var string + */ + protected $filename; + + /** + * @var bool + */ + protected $append = false; + + /** + * @var null|string + */ + protected $originalContents = null; + + /** + * @param string $filename + */ + public function __construct($filename) + { + $this->filename = $filename; + } + + /** + * @param string $filename + * + * @return $this + */ + public function filename($filename) + { + $this->filename = $filename; + return $this; + } + + /** + * @param bool $append + * + * @return $this + */ + public function append($append = true) + { + $this->append = $append; + return $this; + } + + /** + * add a line. + * + * @param string $line + * + * @return $this The current instance + */ + public function line($line) + { + $this->text($line . "\n"); + return $this; + } + + /** + * add more lines. + * + * @param array $lines + * + * @return $this The current instance + */ + public function lines(array $lines) + { + $this->text(implode("\n", $lines) . "\n"); + return $this; + } + + /** + * add a text. + * + * @param string $text + * + * @return $this The current instance + */ + public function text($text) + { + $this->stack[] = array_merge([__FUNCTION__ . 'Collect'], func_get_args()); + return $this; + } + + /** + * add a text from a file. + * + * Note that the file is read in the run() method of this task. + * To load text from the current state of a file (e.g. one that may + * be deleted or altered by other tasks prior the execution of this one), + * use: + * $task->text(file_get_contents($filename)); + * + * @param string $filename + * + * @return $this The current instance + */ + public function textFromFile($filename) + { + $this->stack[] = array_merge([__FUNCTION__ . 'Collect'], func_get_args()); + return $this; + } + + /** + * substitute a placeholder with value, placeholder must be enclosed by `{}`. + * + * @param string $name + * @param string $val + * + * @return $this The current instance + */ + public function place($name, $val) + { + $this->replace('{'.$name.'}', $val); + + return $this; + } + + /** + * replace any string with value. + * + * @param string $string + * @param string $replacement + * + * @return $this The current instance + */ + public function replace($string, $replacement) + { + $this->stack[] = array_merge([__FUNCTION__ . 'Collect'], func_get_args()); + return $this; + } + + /** + * replace any string with value using regular expression. + * + * @param string $pattern + * @param string $replacement + * + * @return $this The current instance + */ + public function regexReplace($pattern, $replacement) + { + $this->stack[] = array_merge([__FUNCTION__ . 'Collect'], func_get_args()); + return $this; + } + + /** + * Append the provided text to the end of the buffer if the provided + * regex pattern matches any text already in the buffer. + * + * @param string $pattern + * @param string $text + * + * @return $this + */ + public function appendIfMatches($pattern, $text) + { + $this->stack[] = array_merge(['appendIfMatchesCollect'], [$pattern, $text, true]); + return $this; + } + + /** + * Append the provided text to the end of the buffer unless the provided + * regex pattern matches any text already in the buffer. + * + * @param string $pattern + * @param string $text + * + * @return $this + */ + public function appendUnlessMatches($pattern, $text) + { + $this->stack[] = array_merge(['appendIfMatchesCollect'], [$pattern, $text, false]); + return $this; + } + + /** + * @param $contents string + * @param $filename string + * + * @return string + */ + protected function textFromFileCollect($contents, $filename) + { + if (file_exists($filename)) { + $contents .= file_get_contents($filename); + } + return $contents; + } + + /** + * @param string|string[] $contents + * @param string|string[] $string + * @param string|string[] $replacement + * + * @return string|string[] + */ + protected function replaceCollect($contents, $string, $replacement) + { + return str_replace($string, $replacement, $contents); + } + + /** + * @param string|string[] $contents + * @param string|string[] $pattern + * @param string|string[] $replacement + * + * @return string|string[] + */ + protected function regexReplaceCollect($contents, $pattern, $replacement) + { + return preg_replace($pattern, $replacement, $contents); + } + + /** + * @param string $contents + * @param string $text + * + * @return string + */ + protected function textCollect($contents, $text) + { + return $contents . $text; + } + + /** + * @param string $contents + * @param string $pattern + * @param string $text + * @param bool $shouldMatch + * + * @return string + */ + protected function appendIfMatchesCollect($contents, $pattern, $text, $shouldMatch) + { + if (preg_match($pattern, $contents) == $shouldMatch) { + $contents .= $text; + } + return $contents; + } + + /** + * @return string + */ + public function originalContents() + { + if (!isset($this->originalContents)) { + $this->originalContents = ''; + if (file_exists($this->filename)) { + $this->originalContents = file_get_contents($this->filename); + } + } + return $this->originalContents; + } + + /** + * @return bool + */ + public function wouldChange() + { + return $this->originalContents() != $this->getContentsToWrite(); + } + + /** + * @return string + */ + protected function getContentsToWrite() + { + $contents = ""; + if ($this->append) { + $contents = $this->originalContents(); + } + foreach ($this->stack as $action) { + $command = array_shift($action); + if (method_exists($this, $command)) { + array_unshift($action, $contents); + $contents = call_user_func_array([$this, $command], $action); + } + } + return $contents; + } + + /** + * {@inheritdoc} + */ + public function run() + { + $this->printTaskInfo("Writing to {filename}.", ['filename' => $this->filename]); + $contents = $this->getContentsToWrite(); + if (!file_exists(dirname($this->filename))) { + mkdir(dirname($this->filename), 0777, true); + } + $res = file_put_contents($this->filename, $contents); + if ($res === false) { + return Result::error($this, "File {$this->filename} couldn't be created"); + } + + return Result::success($this); + } + + /** + * @return string + */ + public function getPath() + { + return $this->filename; + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/File/loadTasks.php b/src/composer/vendor/consolidation/robo/src/Task/File/loadTasks.php new file mode 100644 index 00000000..76ef7230 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/File/loadTasks.php @@ -0,0 +1,50 @@ +task(Concat::class, $files); + } + + /** + * @param string $file + * + * @return \Robo\Task\File\Replace + */ + protected function taskReplaceInFile($file) + { + return $this->task(Replace::class, $file); + } + + /** + * @param string $file + * + * @return \Robo\Task\File\Write + */ + protected function taskWriteToFile($file) + { + return $this->task(Write::class, $file); + } + + /** + * @param string $filename + * @param string $extension + * @param string $baseDir + * @param bool $includeRandomPart + * + * @return \Robo\Task\File\TmpFile + */ + protected function taskTmpFile($filename = 'tmp', $extension = '', $baseDir = '', $includeRandomPart = true) + { + return $this->task(TmpFile::class, $filename, $extension, $baseDir, $includeRandomPart); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Filesystem/BaseDir.php b/src/composer/vendor/consolidation/robo/src/Task/Filesystem/BaseDir.php new file mode 100644 index 00000000..434334d7 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Filesystem/BaseDir.php @@ -0,0 +1,30 @@ +dirs = $dirs + : $this->dirs[] = $dirs; + + $this->fs = new sfFilesystem(); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Filesystem/CleanDir.php b/src/composer/vendor/consolidation/robo/src/Task/Filesystem/CleanDir.php new file mode 100644 index 00000000..762f8550 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Filesystem/CleanDir.php @@ -0,0 +1,63 @@ +taskCleanDir(['tmp','logs'])->run(); + * // as shortcut + * $this->_cleanDir('app/cache'); + * ?> + * ``` + */ +class CleanDir extends BaseDir +{ + use ResourceExistenceChecker; + + /** + * {@inheritdoc} + */ + public function run() + { + if (!$this->checkResources($this->dirs, 'dir')) { + return Result::error($this, 'Source directories are missing!'); + } + foreach ($this->dirs as $dir) { + $this->emptyDir($dir); + $this->printTaskInfo("Cleaned {dir}", ['dir' => $dir]); + } + return Result::success($this); + } + + /** + * @param string $path + */ + protected function emptyDir($path) + { + $iterator = new \RecursiveIteratorIterator( + new \RecursiveDirectoryIterator($path), + \RecursiveIteratorIterator::CHILD_FIRST + ); + + foreach ($iterator as $path) { + if ($path->isDir()) { + $dir = (string)$path; + if (basename($dir) === '.' || basename($dir) === '..') { + continue; + } + $this->fs->remove($dir); + } else { + $file = (string)$path; + if (basename($file) === '.gitignore' || basename($file) === '.gitkeep') { + continue; + } + $this->fs->remove($file); + } + } + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Filesystem/CopyDir.php b/src/composer/vendor/consolidation/robo/src/Task/Filesystem/CopyDir.php new file mode 100644 index 00000000..e65639aa --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Filesystem/CopyDir.php @@ -0,0 +1,113 @@ +taskCopyDir(['dist/config' => 'config'])->run(); + * // as shortcut + * $this->_copyDir('dist/config', 'config'); + * ?> + * ``` + */ +class CopyDir extends BaseDir +{ + use ResourceExistenceChecker; + + /** + * @var int + */ + protected $chmod = 0755; + + /** + * Files to exclude on copying. + * + * @var string[] + */ + protected $exclude = []; + + /** + * {@inheritdoc} + */ + public function run() + { + if (!$this->checkResources($this->dirs, 'dir')) { + return Result::error($this, 'Source directories are missing!'); + } + foreach ($this->dirs as $src => $dst) { + $this->copyDir($src, $dst); + $this->printTaskInfo('Copied from {source} to {destination}', ['source' => $src, 'destination' => $dst]); + } + return Result::success($this); + } + + /** + * Sets the default folder permissions for the destination if it doesn't exist + * + * @link http://en.wikipedia.org/wiki/Chmod + * @link http://php.net/manual/en/function.mkdir.php + * @link http://php.net/manual/en/function.chmod.php + * + * @param int $value + * + * @return $this + */ + public function dirPermissions($value) + { + $this->chmod = (int)$value; + return $this; + } + + /** + * List files to exclude. + * + * @param string[] $exclude + * + * @return $this + */ + public function exclude($exclude = []) + { + $this->exclude = $exclude; + return $this; + } + + /** + * Copies a directory to another location. + * + * @param string $src Source directory + * @param string $dst Destination directory + * + * @throws \Robo\Exception\TaskException + */ + protected function copyDir($src, $dst) + { + $dir = @opendir($src); + if (false === $dir) { + throw new TaskException($this, "Cannot open source directory '" . $src . "'"); + } + if (!is_dir($dst)) { + mkdir($dst, $this->chmod, true); + } + while (false !== ($file = readdir($dir))) { + if (in_array($file, $this->exclude)) { + continue; + } + if (($file !== '.') && ($file !== '..')) { + $srcFile = $src . '/' . $file; + $destFile = $dst . '/' . $file; + if (is_dir($srcFile)) { + $this->copyDir($srcFile, $destFile); + } else { + copy($srcFile, $destFile); + } + } + } + closedir($dir); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Filesystem/DeleteDir.php b/src/composer/vendor/consolidation/robo/src/Task/Filesystem/DeleteDir.php new file mode 100644 index 00000000..25cf007b --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Filesystem/DeleteDir.php @@ -0,0 +1,36 @@ +taskDeleteDir('tmp')->run(); + * // as shortcut + * $this->_deleteDir(['tmp', 'log']); + * ?> + * ``` + */ +class DeleteDir extends BaseDir +{ + use ResourceExistenceChecker; + + /** + * {@inheritdoc} + */ + public function run() + { + if (!$this->checkResources($this->dirs, 'dir')) { + return Result::error($this, 'Source directories are missing!'); + } + foreach ($this->dirs as $dir) { + $this->fs->remove($dir); + $this->printTaskInfo("Deleted {dir}...", ['dir' => $dir]); + } + return Result::success($this); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Filesystem/FilesystemStack.php b/src/composer/vendor/consolidation/robo/src/Task/Filesystem/FilesystemStack.php new file mode 100644 index 00000000..2a0e115a --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Filesystem/FilesystemStack.php @@ -0,0 +1,156 @@ +taskFilesystemStack() + * ->mkdir('logs') + * ->touch('logs/.gitignore') + * ->chgrp('www', 'www-data') + * ->symlink('/var/log/nginx/error.log', 'logs/error.log') + * ->run(); + * + * // one line + * $this->_touch('.gitignore'); + * $this->_mkdir('logs'); + * + * ?> + * ``` + * + * @method $this mkdir($dir) + * @method $this touch($file) + * @method $this copy($from, $to, $force = null) + * @method $this chmod($file, $permissions, $umask = null, $recursive = null) + * @method $this chgrp($file, $group, $recursive = null) + * @method $this chown($file, $user, $recursive = null) + * @method $this remove($file) + * @method $this rename($from, $to) + * @method $this symlink($from, $to) + * @method $this mirror($from, $to) + */ +class FilesystemStack extends StackBasedTask implements BuilderAwareInterface +{ + use BuilderAwareTrait; + + /** + * @var \Symfony\Component\Filesystem\Filesystem + */ + protected $fs; + + public function __construct() + { + $this->fs = new sfFilesystem(); + } + + /** + * @return \Symfony\Component\Filesystem\Filesystem + */ + protected function getDelegate() + { + return $this->fs; + } + + /** + * @param string $from + * @param string $to + * @param bool $force + */ + protected function _copy($from, $to, $force = false) + { + $this->fs->copy($from, $to, $force); + } + + /** + * @param string|string[]|\Traversable $file + * @param int $permissions + * @param int $umask + * @param bool $recursive + */ + protected function _chmod($file, $permissions, $umask = 0000, $recursive = false) + { + $this->fs->chmod($file, $permissions, $umask, $recursive); + } + + /** + * @param string|string[]|\Traversable $file + * @param string $group + * @param bool $recursive + */ + protected function _chgrp($file, $group, $recursive = null) + { + $this->fs->chgrp($file, $group, $recursive); + } + + /** + * @param string|string[]|\Traversable $file + * @param string $user + * @param bool $recursive + */ + protected function _chown($file, $user, $recursive = null) + { + $this->fs->chown($file, $user, $recursive); + } + + /** + * @param string $origin + * @param string $target + * @param bool $overwrite + * + * @return null|true|\Robo\Result + */ + protected function _rename($origin, $target, $overwrite = false) + { + // we check that target does not exist + if ((!$overwrite && is_readable($target)) || (file_exists($target) && !is_writable($target))) { + throw new IOException(sprintf('Cannot rename because the target "%s" already exists.', $target), 0, null, $target); + } + + // Due to a bug (limitation) in PHP, cross-volume renames do not work. + // See: https://bugs.php.net/bug.php?id=54097 + if (true !== @rename($origin, $target)) { + return $this->crossVolumeRename($origin, $target); + } + return true; + } + + /** + * @param string $origin + * @param string $target + * + * @return null|\Robo\Result + */ + protected function crossVolumeRename($origin, $target) + { + // First step is to try to get rid of the target. If there + // is a single, deletable file, then we will just unlink it. + if (is_file($target)) { + unlink($target); + } + // If the target still exists, we will try to delete it. + // TODO: Note that if this fails partway through, then we cannot + // adequately rollback. Perhaps we need to preflight the operation + // and determine if everything inside of $target is writable. + if (file_exists($target)) { + $this->fs->remove($target); + } + + /** @var \Robo\Result $result */ + $result = $this->collectionBuilder()->taskCopyDir([$origin => $target])->run(); + if (!$result->wasSuccessful()) { + return $result; + } + $this->fs->remove($origin); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Filesystem/FlattenDir.php b/src/composer/vendor/consolidation/robo/src/Task/Filesystem/FlattenDir.php new file mode 100644 index 00000000..6e885112 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Filesystem/FlattenDir.php @@ -0,0 +1,294 @@ +taskFlattenDir(['assets/*.min.js' => 'dist'])->run(); + * // or use shortcut + * $this->_flattenDir('assets/*.min.js', 'dist'); + * ?> + * ``` + * + * You can also define the target directory with an additional method, instead of + * key/value pairs. More similar to the gulp-flatten syntax: + * + * ``` php + * taskFlattenDir(['assets/*.min.js']) + * ->to('dist') + * ->run(); + * ?> + * ``` + * + * You can also append parts of the parent directories to the target path. If you give + * the value `1` to the `includeParents()` method, then the top parent will be appended + * to the target directory resulting in a path such as `dist/assets/asset-library1.min.js`. + * + * If you give a negative number, such as `-1` (the same as specifying `array(0, 1)` then + * the bottom parent will be appended, resulting in a path such as + * `dist/asset-library1/asset-library1.min.js`. + * + * The top parent directory will always be starting from the relative path to the current + * directory. You can override that with the `parentDir()` method. If in the above example + * you would specify `assets`, then the top parent directory would be `asset-library1`. + * + * ``` php + * taskFlattenDir(['assets/*.min.js' => 'dist']) + * ->parentDir('assets') + * ->includeParents(1) + * ->run(); + * ?> + * ``` + */ +class FlattenDir extends BaseDir +{ + /** + * @var int + */ + protected $chmod = 0755; + + /** + * @var int[] + */ + protected $parents = array(0, 0); + + /** + * @var string + */ + protected $parentDir = ''; + + /** + * @var string + */ + protected $to; + + /** + * {@inheritdoc} + */ + public function __construct($dirs) + { + parent::__construct($dirs); + $this->parentDir = getcwd(); + } + + /** + * {@inheritdoc} + */ + public function run() + { + // find the files + $files = $this->findFiles($this->dirs); + + // copy the files + $this->copyFiles($files); + + $fileNoun = count($files) == 1 ? ' file' : ' files'; + $this->printTaskSuccess("Copied {count} $fileNoun to {destination}", ['count' => count($files), 'destination' => $this->to]); + + return Result::success($this); + } + + /** + * Sets the default folder permissions for the destination if it does not exist. + * + * @link http://en.wikipedia.org/wiki/Chmod + * @link http://php.net/manual/en/function.mkdir.php + * @link http://php.net/manual/en/function.chmod.php + * + * @param int $permission + * + * @return $this + */ + public function dirPermissions($permission) + { + $this->chmod = (int) $permission; + + return $this; + } + + /** + * Sets the value from which direction and how much parent dirs should be included. + * Accepts a positive or negative integer or an array with two integer values. + * + * @param int|int[] $parents + * + * @return $this + * + * @throws TaskException + */ + public function includeParents($parents) + { + if (is_int($parents)) { + // if an integer is given check whether it is for top or bottom parent + if ($parents >= 0) { + $this->parents[0] = $parents; + return $this; + } + $this->parents[1] = 0 - $parents; + return $this; + } + + if (is_array($parents)) { + // check if the array has two values no more, no less + if (count($parents) == 2) { + $this->parents = $parents; + return $this; + } + } + + throw new TaskException($this, 'includeParents expects an integer or an array with two values'); + } + + /** + * Sets the parent directory from which the relative parent directories will be calculated. + * + * @param string $dir + * + * @return $this + */ + public function parentDir($dir) + { + if (!$this->fs->isAbsolutePath($dir)) { + // attach the relative path to current working directory + $dir = getcwd().'/'.$dir; + } + $this->parentDir = $dir; + + return $this; + } + + /** + * Sets the target directory where the files will be copied to. + * + * @param string $target + * + * @return $this + */ + public function to($target) + { + $this->to = rtrim($target, '/'); + + return $this; + } + + /** + * @param array $dirs + * + * @return array|\Robo\Result + * + * @throws \Robo\Exception\TaskException + */ + protected function findFiles($dirs) + { + $files = array(); + + // find the files + foreach ($dirs as $k => $v) { + // reset finder + $finder = new Finder(); + + $dir = $k; + $to = $v; + // check if target was given with the to() method instead of key/value pairs + if (is_int($k)) { + $dir = $v; + if (isset($this->to)) { + $to = $this->to; + } else { + throw new TaskException($this, 'target directory is not defined'); + } + } + + try { + $finder->files()->in($dir); + } catch (\InvalidArgumentException $e) { + // if finder cannot handle it, try with in()->name() + if (strpos($dir, '/') === false) { + $dir = './'.$dir; + } + $parts = explode('/', $dir); + $new_dir = implode('/', array_slice($parts, 0, -1)); + try { + $finder->files()->in($new_dir)->name(array_pop($parts)); + } catch (\InvalidArgumentException $e) { + return Result::fromException($this, $e); + } + } + + foreach ($finder as $file) { + // store the absolute path as key and target as value in the files array + $files[$file->getRealpath()] = $this->getTarget($file->getRealPath(), $to); + } + $fileNoun = count($files) == 1 ? ' file' : ' files'; + $this->printTaskInfo("Found {count} $fileNoun in {dir}", ['count' => count($files), 'dir' => $dir]); + } + + return $files; + } + + /** + * @param string $file + * @param string $to + * + * @return string + */ + protected function getTarget($file, $to) + { + $target = $to.'/'.basename($file); + if ($this->parents !== array(0, 0)) { + // if the parent is set, create additional directories inside target + // get relative path to parentDir + $rel_path = $this->fs->makePathRelative(dirname($file), $this->parentDir); + // get top parents and bottom parents + $parts = explode('/', rtrim($rel_path, '/')); + $prefix_dir = ''; + $prefix_dir .= ($this->parents[0] > 0 ? implode('/', array_slice($parts, 0, $this->parents[0])).'/' : ''); + $prefix_dir .= ($this->parents[1] > 0 ? implode('/', array_slice($parts, (0 - $this->parents[1]), $this->parents[1])) : ''); + $prefix_dir = rtrim($prefix_dir, '/'); + $target = $to.'/'.$prefix_dir.'/'.basename($file); + } + + return $target; + } + + /** + * @param array $files + */ + protected function copyFiles($files) + { + // copy the files + foreach ($files as $from => $to) { + // check if target dir exists + if (!is_dir(dirname($to))) { + $this->fs->mkdir(dirname($to), $this->chmod); + } + $this->fs->copy($from, $to); + } + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Filesystem/MirrorDir.php b/src/composer/vendor/consolidation/robo/src/Task/Filesystem/MirrorDir.php new file mode 100644 index 00000000..4eda9097 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Filesystem/MirrorDir.php @@ -0,0 +1,40 @@ +taskMirrorDir(['dist/config/' => 'config/'])->run(); + * // or use shortcut + * $this->_mirrorDir('dist/config/', 'config/'); + * + * ?> + * ``` + */ +class MirrorDir extends BaseDir +{ + /** + * {@inheritdoc} + */ + public function run() + { + foreach ($this->dirs as $src => $dst) { + $this->fs->mirror( + $src, + $dst, + null, + [ + 'override' => true, + 'copy_on_windows' => true, + 'delete' => true + ] + ); + $this->printTaskInfo("Mirrored from {source} to {destination}", ['source' => $src, 'destination' => $dst]); + } + return Result::success($this); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Filesystem/TmpDir.php b/src/composer/vendor/consolidation/robo/src/Task/Filesystem/TmpDir.php new file mode 100644 index 00000000..8cf44f89 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Filesystem/TmpDir.php @@ -0,0 +1,174 @@ +run(). + * $collection = $this->collectionBuilder(); + * $tmpPath = $collection->tmpDir()->getPath(); + * $collection->taskFilesystemStack() + * ->mkdir("$tmpPath/log") + * ->touch("$tmpPath/log/error.txt"); + * $collection->run(); + * // as shortcut (deleted when program exits) + * $tmpPath = $this->_tmpDir(); + * ?> + * ``` + */ +class TmpDir extends BaseDir implements CompletionInterface +{ + /** + * @var string + */ + protected $base; + + /** + * @var string + */ + protected $prefix; + + /** + * @var bool + */ + protected $cwd; + + /** + * @var string + */ + protected $savedWorkingDirectory; + + /** + * @param string $prefix + * @param string $base + * @param bool $includeRandomPart + */ + public function __construct($prefix = 'tmp', $base = '', $includeRandomPart = true) + { + if (empty($base)) { + $base = sys_get_temp_dir(); + } + $path = "{$base}/{$prefix}"; + if ($includeRandomPart) { + $path = static::randomLocation($path); + } + parent::__construct(["$path"]); + } + + /** + * Add a random part to a path, ensuring that the directory does + * not (currently) exist. + * + * @param string $path The base/prefix path to add a random component to + * @param int $length Number of digits in the random part + * + * @return string + */ + protected static function randomLocation($path, $length = 12) + { + $random = static::randomString($length); + while (is_dir("{$path}_{$random}")) { + $random = static::randomString($length); + } + return "{$path}_{$random}"; + } + + /** + * Generate a suitably random string to use as the suffix for our + * temporary directory. + * + * @param int $length + * + * @return string + */ + protected static function randomString($length = 12) + { + return substr(str_shuffle('23456789abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ'), 0, max($length, 3)); + } + + /** + * Flag that we should cwd to the temporary directory when it is + * created, and restore the old working directory when it is deleted. + * + * @param bool $shouldChangeWorkingDirectory + * + * @return $this + */ + public function cwd($shouldChangeWorkingDirectory = true) + { + $this->cwd = $shouldChangeWorkingDirectory; + + return $this; + } + + /** + * {@inheritdoc} + */ + public function run() + { + // Save the current working directory + $this->savedWorkingDirectory = getcwd(); + foreach ($this->dirs as $dir) { + $this->fs->mkdir($dir); + $this->printTaskInfo("Created {dir}...", ['dir' => $dir]); + + // Change the current working directory, if requested + if ($this->cwd) { + chdir($dir); + } + } + + return Result::success($this, '', ['path' => $this->getPath()]); + } + + protected function restoreWorkingDirectory() + { + // Restore the current working directory, if we redirected it. + if ($this->cwd) { + chdir($this->savedWorkingDirectory); + } + } + + protected function deleteTmpDir() + { + foreach ($this->dirs as $dir) { + $this->fs->remove($dir); + } + } + + /** + * Delete this directory when our collection completes. + * If this temporary directory is not part of a collection, + * then it will be deleted when the program terminates, + * presuming that it was created by taskTmpDir() or _tmpDir(). + */ + public function complete() + { + $this->restoreWorkingDirectory(); + $this->deleteTmpDir(); + } + + /** + * Get a reference to the path to the temporary directory, so that + * it may be used to create other tasks. Note that the directory + * is not actually created until the task runs. + * + * @return string + */ + public function getPath() + { + return $this->dirs[0]; + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Filesystem/WorkDir.php b/src/composer/vendor/consolidation/robo/src/Task/Filesystem/WorkDir.php new file mode 100644 index 00000000..3c445b8b --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Filesystem/WorkDir.php @@ -0,0 +1,128 @@ +collectionBuilder(); + * $workingPath = $collection->workDir("build")->getPath(); + * $collection->taskFilesystemStack() + * ->mkdir("$workingPath/log") + * ->touch("$workingPath/log/error.txt"); + * $collection->run(); + * ?> + * ``` + */ +class WorkDir extends TmpDir implements RollbackInterface, BuilderAwareInterface +{ + use BuilderAwareTrait; + + /** + * @var string + */ + protected $finalDestination; + + /** + * @param string $finalDestination + */ + public function __construct($finalDestination) + { + $this->finalDestination = $finalDestination; + + // Create a temporary directory to work in. We will place our + // temporary directory in the same location as the final destination + // directory, so that the work directory can be moved into place + // without having to be copied, e.g. in a cross-volume rename scenario. + parent::__construct(basename($finalDestination), dirname($finalDestination)); + } + + /** + * Create our working directory. + * + * @return \Robo\Result + */ + public function run() + { + // Destination cannot be empty + if (empty($this->finalDestination)) { + return Result::error($this, "Destination directory not specified."); + } + + // Before we do anything else, ensure that any directory in the + // final destination is writable, so that we can at a minimum + // move it out of the way before placing our results there. + if (is_dir($this->finalDestination)) { + if (!is_writable($this->finalDestination)) { + return Result::error($this, "Destination directory {dir} exists and cannot be overwritten.", ['dir' => $this->finalDestination]); + } + } + + return parent::run(); + } + + /** + * Move our working directory into its final destination once the + * collection it belongs to completes. + */ + public function complete() + { + $this->restoreWorkingDirectory(); + + // Delete the final destination, if it exists. + // Move it out of the way first, in case it cannot + // be completely deleted. + if (file_exists($this->finalDestination)) { + $temporaryLocation = static::randomLocation($this->finalDestination . '_TO_DELETE_'); + // This should always work, because we already created a temporary + // folder in the parent directory of the final destination, and we + // have already checked to confirm that the final destination is + // writable. + rename($this->finalDestination, $temporaryLocation); + // This may silently fail, leaving artifacts behind, if there + // are permissions problems with some items somewhere inside + // the folder being deleted. + $this->fs->remove($temporaryLocation); + } + + // Move our working directory over the final destination. + // This should never be a cross-volume rename, so this should + // always succeed. + $workDir = reset($this->dirs); + if (file_exists($workDir)) { + rename($workDir, $this->finalDestination); + } + } + + /** + * Delete our working directory + */ + public function rollback() + { + $this->restoreWorkingDirectory(); + $this->deleteTmpDir(); + } + + /** + * Get a reference to the path to the temporary directory, so that + * it may be used to create other tasks. Note that the directory + * is not actually created until the task runs. + * + * @return string + */ + public function getPath() + { + return $this->dirs[0]; + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Filesystem/loadShortcuts.php b/src/composer/vendor/consolidation/robo/src/Task/Filesystem/loadShortcuts.php new file mode 100644 index 00000000..3a670a93 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Filesystem/loadShortcuts.php @@ -0,0 +1,160 @@ +taskCopyDir([$src => $dst])->run(); + } + + /** + * @param string $src + * @param string $dst + * + * @return \Robo\Result + */ + protected function _mirrorDir($src, $dst) + { + return $this->taskMirrorDir([$src => $dst])->run(); + } + + /** + * @param string|string[] $dir + * + * @return \Robo\Result + */ + protected function _deleteDir($dir) + { + return $this->taskDeleteDir($dir)->run(); + } + + /** + * @param string|string[] $dir + * + * @return \Robo\Result + */ + protected function _cleanDir($dir) + { + return $this->taskCleanDir($dir)->run(); + } + + /** + * @param string $from + * @param string $to + * + * @return \Robo\Result + */ + protected function _rename($from, $to) + { + return $this->taskFilesystemStack()->rename($from, $to)->run(); + } + + /** + * @param string|string[] $dir + * + * @return \Robo\Result + */ + protected function _mkdir($dir) + { + return $this->taskFilesystemStack()->mkdir($dir)->run(); + } + + /** + * @param string $prefix + * @param string $base + * @param bool $includeRandomPart + * + * @return string + */ + protected function _tmpDir($prefix = 'tmp', $base = '', $includeRandomPart = true) + { + $result = $this->taskTmpDir($prefix, $base, $includeRandomPart)->run(); + return isset($result['path']) ? $result['path'] : ''; + } + + /** + * @param string $file + * + * @return \Robo\Result + */ + protected function _touch($file) + { + return $this->taskFilesystemStack()->touch($file)->run(); + } + + /** + * @param string|string[] $file + * + * @return \Robo\Result + */ + protected function _remove($file) + { + return $this->taskFilesystemStack()->remove($file)->run(); + } + + /** + * @param string|string[] $file + * @param string $group + * + * @return \Robo\Result + */ + protected function _chgrp($file, $group) + { + return $this->taskFilesystemStack()->chgrp($file, $group)->run(); + } + + /** + * @param string|string[] $file + * @param int $permissions + * @param int $umask + * @param bool $recursive + * + * @return \Robo\Result + */ + protected function _chmod($file, $permissions, $umask = 0000, $recursive = false) + { + return $this->taskFilesystemStack()->chmod($file, $permissions, $umask, $recursive)->run(); + } + + /** + * @param string $from + * @param string $to + * + * @return \Robo\Result + */ + protected function _symlink($from, $to) + { + return $this->taskFilesystemStack()->symlink($from, $to)->run(); + } + + /** + * @param string $from + * @param string $to + * + * @return \Robo\Result + */ + protected function _copy($from, $to) + { + return $this->taskFilesystemStack()->copy($from, $to)->run(); + } + + /** + * @param string $from + * @param string $to + * + * @return \Robo\Result + */ + protected function _flattenDir($from, $to) + { + return $this->taskFlattenDir([$from => $to])->run(); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Filesystem/loadTasks.php b/src/composer/vendor/consolidation/robo/src/Task/Filesystem/loadTasks.php new file mode 100644 index 00000000..932e8332 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Filesystem/loadTasks.php @@ -0,0 +1,87 @@ +task(CleanDir::class, $dirs); + } + + /** + * @param string|string[] $dirs + * + * @return \Robo\Task\Filesystem\DeleteDir + */ + protected function taskDeleteDir($dirs) + { + return $this->task(DeleteDir::class, $dirs); + } + + /** + * @param string $prefix + * @param string $base + * @param bool $includeRandomPart + * + * @return \Robo\Task\Filesystem\WorkDir + */ + protected function taskTmpDir($prefix = 'tmp', $base = '', $includeRandomPart = true) + { + return $this->task(TmpDir::class, $prefix, $base, $includeRandomPart); + } + + /** + * @param string $finalDestination + * + * @return \Robo\Task\Filesystem\TmpDir + */ + protected function taskWorkDir($finalDestination) + { + return $this->task(WorkDir::class, $finalDestination); + } + + /** + * @param string|string[] $dirs + * + * @return \Robo\Task\Filesystem\CopyDir + */ + protected function taskCopyDir($dirs) + { + return $this->task(CopyDir::class, $dirs); + } + + /** + * @param string|string[] $dirs + * + * @return \Robo\Task\Filesystem\MirrorDir + */ + protected function taskMirrorDir($dirs) + { + return $this->task(MirrorDir::class, $dirs); + } + + /** + * @param string|string[] $dirs + * + * @return \Robo\Task\Filesystem\FlattenDir + */ + protected function taskFlattenDir($dirs) + { + return $this->task(FlattenDir::class, $dirs); + } + + /** + * @return \Robo\Task\Filesystem\FilesystemStack + */ + protected function taskFilesystemStack() + { + return $this->task(FilesystemStack::class); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Gulp/Base.php b/src/composer/vendor/consolidation/robo/src/Task/Gulp/Base.php new file mode 100644 index 00000000..c1cf8ae2 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Gulp/Base.php @@ -0,0 +1,97 @@ +option('silent'); + return $this; + } + + /** + * adds `--no-color` option to gulp + * + * @return $this + */ + public function noColor() + { + $this->option('no-color'); + return $this; + } + + /** + * adds `--color` option to gulp + * + * @return $this + */ + public function color() + { + $this->option('color'); + return $this; + } + + /** + * adds `--tasks-simple` option to gulp + * + * @return $this + */ + public function simple() + { + $this->option('tasks-simple'); + return $this; + } + + /** + * @param string $task + * @param null|string $pathToGulp + * + * @throws \Robo\Exception\TaskException + */ + public function __construct($task, $pathToGulp = null) + { + $this->task = $task; + $this->command = $pathToGulp; + if (!$this->command) { + $this->command = $this->findExecutable('gulp'); + } + if (!$this->command) { + throw new TaskException(__CLASS__, "Gulp executable not found."); + } + } + + /** + * @return string + */ + public function getCommand() + { + return "{$this->command} " . ProcessUtils::escapeArgument($this->task) . "{$this->arguments}"; + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Gulp/Run.php b/src/composer/vendor/consolidation/robo/src/Task/Gulp/Run.php new file mode 100644 index 00000000..dde81cc7 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Gulp/Run.php @@ -0,0 +1,36 @@ +taskGulpRun()->run(); + * + * // run task 'clean' with --silent option + * $this->taskGulpRun('clean') + * ->silent() + * ->run(); + * ?> + * ``` + */ +class Run extends Base implements CommandInterface +{ + /** + * {@inheritdoc} + */ + public function run() + { + if (strlen($this->arguments)) { + $this->printTaskInfo('Running Gulp task: {gulp_task} with arguments: {arguments}', ['gulp_task' => $this->task, 'arguments' => $this->arguments]); + } else { + $this->printTaskInfo('Running Gulp task: {gulp_task} without arguments', ['gulp_task' => $this->task]); + } + return $this->executeCommand($this->getCommand()); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Gulp/loadTasks.php b/src/composer/vendor/consolidation/robo/src/Task/Gulp/loadTasks.php new file mode 100644 index 00000000..6fdc6ca7 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Gulp/loadTasks.php @@ -0,0 +1,16 @@ +task(Run::class, $task, $pathToGulp); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Npm/Base.php b/src/composer/vendor/consolidation/robo/src/Task/Npm/Base.php new file mode 100644 index 00000000..35ff9c48 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Npm/Base.php @@ -0,0 +1,60 @@ +option('production'); + return $this; + } + + /** + * @param null|string $pathToNpm + * + * @throws \Robo\Exception\TaskException + */ + public function __construct($pathToNpm = null) + { + $this->command = $pathToNpm; + if (!$this->command) { + $this->command = $this->findExecutable('npm'); + } + if (!$this->command) { + throw new TaskException(__CLASS__, "Npm executable not found."); + } + } + + /** + * @return string + */ + public function getCommand() + { + return "{$this->command} {$this->action}{$this->arguments}"; + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Npm/Install.php b/src/composer/vendor/consolidation/robo/src/Task/Npm/Install.php new file mode 100644 index 00000000..65cbe618 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Npm/Install.php @@ -0,0 +1,36 @@ +taskNpmInstall()->run(); + * + * // prefer dist with custom path + * $this->taskNpmInstall('path/to/my/npm') + * ->noDev() + * ->run(); + * ?> + * ``` + */ +class Install extends Base implements CommandInterface +{ + /** + * @var string + */ + protected $action = 'install'; + + /** + * {@inheritdoc} + */ + public function run() + { + $this->printTaskInfo('Install Npm packages: {arguments}', ['arguments' => $this->arguments]); + return $this->executeCommand($this->getCommand()); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Npm/Update.php b/src/composer/vendor/consolidation/robo/src/Task/Npm/Update.php new file mode 100644 index 00000000..75421b30 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Npm/Update.php @@ -0,0 +1,34 @@ +taskNpmUpdate()->run(); + * + * // prefer dist with custom path + * $this->taskNpmUpdate('path/to/my/npm') + * ->noDev() + * ->run(); + * ?> + * ``` + */ +class Update extends Base +{ + /** + * @var string + */ + protected $action = 'update'; + + /** + * {@inheritdoc} + */ + public function run() + { + $this->printTaskInfo('Update Npm packages: {arguments}', ['arguments' => $this->arguments]); + return $this->executeCommand($this->getCommand()); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Npm/loadTasks.php b/src/composer/vendor/consolidation/robo/src/Task/Npm/loadTasks.php new file mode 100644 index 00000000..4d9a26eb --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Npm/loadTasks.php @@ -0,0 +1,25 @@ +task(Install::class, $pathToNpm); + } + + /** + * @param null|string $pathToNpm + * + * @return \Robo\Task\Npm\Update + */ + protected function taskNpmUpdate($pathToNpm = null) + { + return $this->task(Update::class, $pathToNpm); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Remote/Rsync.php b/src/composer/vendor/consolidation/robo/src/Task/Remote/Rsync.php new file mode 100644 index 00000000..33ed3a0e --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Remote/Rsync.php @@ -0,0 +1,491 @@ +taskRsync() + * ->fromPath('src/') + * ->toHost('localhost') + * ->toUser('dev') + * ->toPath('/var/www/html/app/') + * ->remoteShell('ssh -i public_key') + * ->recursive() + * ->excludeVcs() + * ->checksum() + * ->wholeFile() + * ->verbose() + * ->progress() + * ->humanReadable() + * ->stats() + * ->run(); + * ``` + * + * You could also clone the task and do a dry-run first: + * + * ``` php + * $rsync = $this->taskRsync() + * ->fromPath('src/') + * ->toPath('example.com:/var/www/html/app/') + * ->archive() + * ->excludeVcs() + * ->progress() + * ->stats(); + * + * $dryRun = clone $rsync; + * $dryRun->dryRun()->run(); + * if ('y' === $this->ask('Do you want to run (y/n)')) { + * $rsync->run(); + * } + * ``` + * + * @method \Robo\Task\Remote\Rsync fromUser(string $user) + * @method \Robo\Task\Remote\Rsync fromHost(string $hostname) + * @method \Robo\Task\Remote\Rsync toUser(string $user) + * @method \Robo\Task\Remote\Rsync toHost(string $hostname) + */ +class Rsync extends BaseTask implements CommandInterface +{ + use \Robo\Common\ExecOneCommand; + + /** + * @var string + */ + protected $command; + + /** + * @var string + */ + protected $fromUser; + + /** + * @var string + */ + protected $fromHost; + + /** + * @var string + */ + protected $fromPath; + + /** + * @var string + */ + protected $toUser; + + /** + * @var string + */ + protected $toHost; + + /** + * @var string + */ + protected $toPath; + + /** + * @return static + */ + public static function init() + { + return new static(); + } + + public function __construct() + { + $this->command = 'rsync'; + } + + /** + * This can either be a full rsync path spec (user@host:path) or just a path. + * In case of the former do not specify host and user. + * + * @param string|array $path + * + * @return $this + */ + public function fromPath($path) + { + $this->fromPath = $path; + + return $this; + } + + /** + * This can either be a full rsync path spec (user@host:path) or just a path. + * In case of the former do not specify host and user. + * + * @param string $path + * + * @return $this + */ + public function toPath($path) + { + $this->toPath = $path; + + return $this; + } + + /** + * @param string $fromUser + * + * @return $this + */ + public function fromUser($fromUser) + { + $this->fromUser = $fromUser; + return $this; + } + + /** + * @param string $fromHost + * + * @return $this + */ + public function fromHost($fromHost) + { + $this->fromHost = $fromHost; + return $this; + } + + /** + * @param string $toUser + * + * @return $this + */ + public function toUser($toUser) + { + $this->toUser = $toUser; + return $this; + } + + /** + * @param string $toHost + * + * @return $this + */ + public function toHost($toHost) + { + $this->toHost = $toHost; + return $this; + } + + /** + * @return $this + */ + public function progress() + { + $this->option(__FUNCTION__); + + return $this; + } + + /** + * @return $this + */ + public function stats() + { + $this->option(__FUNCTION__); + + return $this; + } + + /** + * @return $this + */ + public function recursive() + { + $this->option(__FUNCTION__); + + return $this; + } + + /** + * @return $this + */ + public function verbose() + { + $this->option(__FUNCTION__); + + return $this; + } + + /** + * @return $this + */ + public function checksum() + { + $this->option(__FUNCTION__); + + return $this; + } + + /** + * @return $this + */ + public function archive() + { + $this->option(__FUNCTION__); + + return $this; + } + + /** + * @return $this + */ + public function compress() + { + $this->option(__FUNCTION__); + + return $this; + } + + /** + * @return $this + */ + public function owner() + { + $this->option(__FUNCTION__); + + return $this; + } + + /** + * @return $this + */ + public function group() + { + $this->option(__FUNCTION__); + + return $this; + } + + /** + * @return $this + */ + public function times() + { + $this->option(__FUNCTION__); + + return $this; + } + + /** + * @return $this + */ + public function delete() + { + $this->option(__FUNCTION__); + + return $this; + } + + /** + * @param int $seconds + * + * @return $this + */ + public function timeout($seconds) + { + $this->option(__FUNCTION__, $seconds); + + return $this; + } + + /** + * @return $this + */ + public function humanReadable() + { + $this->option('human-readable'); + + return $this; + } + + /** + * @return $this + */ + public function wholeFile() + { + $this->option('whole-file'); + + return $this; + } + + /** + * @return $this + */ + public function dryRun() + { + $this->option('dry-run'); + + return $this; + } + + /** + * @return $this + */ + public function itemizeChanges() + { + $this->option('itemize-changes'); + + return $this; + } + + /** + * Excludes .git, .svn and .hg items at any depth. + * + * @return $this + */ + public function excludeVcs() + { + return $this->exclude([ + '.git', + '.svn', + '.hg', + ]); + } + + /** + * @param array|string $pattern + * + * @return $this + */ + public function exclude($pattern) + { + return $this->optionList(__FUNCTION__, $pattern); + } + + /** + * @param string $file + * + * @return $this + * + * @throws \Robo\Exception\TaskException + */ + public function excludeFrom($file) + { + if (!is_readable($file)) { + throw new TaskException($this, "Exclude file $file is not readable"); + } + + return $this->option('exclude-from', $file); + } + + /** + * @param array|string $pattern + * + * @return $this + */ + public function includeFilter($pattern) + { + return $this->optionList('include', $pattern); + } + + /** + * @param array|string $pattern + * + * @return $this + */ + public function filter($pattern) + { + return $this->optionList(__FUNCTION__, $pattern); + } + + /** + * @param string $file + * + * @return $this + * + * @throws \Robo\Exception\TaskException + */ + public function filesFrom($file) + { + if (!is_readable($file)) { + throw new TaskException($this, "Files-from file $file is not readable"); + } + + return $this->option('files-from', $file); + } + + /** + * @param string $command + * + * @return $this + */ + public function remoteShell($command) + { + $this->option('rsh', "'$command'"); + + return $this; + } + + /** + * {@inheritdoc} + */ + public function run() + { + $command = $this->getCommand(); + $this->printTaskInfo("Running {command}", ['command' => $command]); + + return $this->executeCommand($command); + } + + /** + * Returns command that can be executed. + * This method is used to pass generated command from one task to another. + * + * @return string + */ + public function getCommand() + { + foreach ((array)$this->fromPath as $from) { + $this->option(null, $this->getFromPathSpec($from)); + } + $this->option(null, $this->getToPathSpec()); + + return $this->command . $this->arguments; + } + + /** + * @return string + */ + protected function getFromPathSpec($from) + { + return $this->getPathSpec($this->fromHost, $this->fromUser, $from); + } + + /** + * @return string + */ + protected function getToPathSpec() + { + return $this->getPathSpec($this->toHost, $this->toUser, $this->toPath); + } + + /** + * @param string $host + * @param string $user + * @param string $path + * + * @return string + */ + protected function getPathSpec($host, $user, $path) + { + $spec = isset($path) ? $path : ''; + if (!empty($host)) { + $spec = "{$host}:{$spec}"; + } + if (!empty($user)) { + $spec = "{$user}@{$spec}"; + } + + return $spec; + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Remote/Ssh.php b/src/composer/vendor/consolidation/robo/src/Task/Remote/Ssh.php new file mode 100644 index 00000000..500e29fc --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Remote/Ssh.php @@ -0,0 +1,274 @@ +taskSshExec('remote.example.com', 'user') + * ->remoteDir('/var/www/html') + * ->exec('ls -la') + * ->exec('chmod g+x logs') + * ->run(); + * + * ``` + * + * You can even exec other tasks (which implement CommandInterface): + * + * ```php + * $gitTask = $this->taskGitStack() + * ->checkout('master') + * ->pull(); + * + * $this->taskSshExec('remote.example.com') + * ->remoteDir('/var/www/html/site') + * ->exec($gitTask) + * ->run(); + * ``` + * + * You can configure the remote directory for all future calls: + * + * ```php + * \Robo\Task\Remote\Ssh::configure('remoteDir', '/some-dir'); + * ``` + * + * @method $this stopOnFail(bool $stopOnFail) Whether or not to chain commands together with && + * and stop the chain if one command fails + * @method $this remoteDir(string $remoteWorkingDirectory) Changes to the given directory before running commands + */ +class Ssh extends BaseTask implements CommandInterface, SimulatedInterface +{ + use \Robo\Common\CommandReceiver; + use \Robo\Common\ExecOneCommand; + + /** + * @var null|string + */ + protected $hostname; + + /** + * @var null|string + */ + protected $user; + + /** + * @var bool + */ + protected $stopOnFail = true; + + /** + * @var array + */ + protected $exec = []; + + /** + * Changes to the given directory before running commands. + * + * @var string + */ + protected $remoteDir; + + /** + * @param null|string $hostname + * @param null|string $user + */ + public function __construct($hostname = null, $user = null) + { + $this->hostname = $hostname; + $this->user = $user; + } + + /** + * @param string $hostname + * + * @return $this + */ + public function hostname($hostname) + { + $this->hostname = $hostname; + return $this; + } + + /** + * @param string $user + * + * @return $this + */ + public function user($user) + { + $this->user = $user; + return $this; + } + + /** + * @param bool $stopOnFail + * + * @return $this + */ + public function stopOnFail($stopOnFail = true) + { + $this->stopOnFail = $stopOnFail; + return $this; + } + + /** + * @param string $remoteDir + * + * @return $this + */ + public function remoteDir($remoteDir) + { + $this->remoteDir = $remoteDir; + return $this; + } + + /** + * @param string $filename + * + * @return $this + */ + public function identityFile($filename) + { + $this->option('-i', $filename); + + return $this; + } + + /** + * @param int $port + * + * @return $this + */ + public function port($port) + { + $this->option('-p', $port); + + return $this; + } + + /** + * @return $this + */ + public function forcePseudoTty() + { + $this->option('-t'); + + return $this; + } + + /** + * @return $this + */ + public function quiet() + { + $this->option('-q'); + + return $this; + } + + /** + * @return $this + */ + public function verbose() + { + $this->option('-v'); + + return $this; + } + + /** + * @param string|string[]|CommandInterface $command + * + * @return $this + */ + public function exec($command) + { + if (is_array($command)) { + $command = implode(' ', array_filter($command)); + } + + $this->exec[] = $command; + + return $this; + } + + /** + * Returns command that can be executed. + * This method is used to pass generated command from one task to another. + * + * @return string + */ + public function getCommand() + { + $commands = []; + foreach ($this->exec as $command) { + $commands[] = $this->receiveCommand($command); + } + + $remoteDir = $this->remoteDir ? $this->remoteDir : $this->getConfigValue('remoteDir'); + if (!empty($remoteDir)) { + array_unshift($commands, sprintf('cd "%s"', $remoteDir)); + } + $command = implode($this->stopOnFail ? ' && ' : ' ; ', $commands); + + return $this->sshCommand($command); + } + + /** + * {@inheritdoc} + */ + public function run() + { + $this->validateParameters(); + $command = $this->getCommand(); + return $this->executeCommand($command); + } + + /** + * {@inheritdoc} + */ + public function simulate($context) + { + $command = $this->getCommand(); + $this->printTaskInfo("Running {command}", ['command' => $command] + $context); + } + + protected function validateParameters() + { + if (empty($this->hostname)) { + throw new TaskException($this, 'Please set a hostname'); + } + if (empty($this->exec)) { + throw new TaskException($this, 'Please add at least one command'); + } + } + + /** + * Returns an ssh command string running $command on the remote. + * + * @param string|CommandInterface $command + * + * @return string + */ + protected function sshCommand($command) + { + $command = $this->receiveCommand($command); + $sshOptions = $this->arguments; + $hostSpec = $this->hostname; + if ($this->user) { + $hostSpec = $this->user . '@' . $hostSpec; + } + + return sprintf("ssh{$sshOptions} {$hostSpec} '{$command}'"); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Remote/loadTasks.php b/src/composer/vendor/consolidation/robo/src/Task/Remote/loadTasks.php new file mode 100644 index 00000000..092d2a55 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Remote/loadTasks.php @@ -0,0 +1,24 @@ +task(Rsync::class); + } + + /** + * @param null|string $hostname + * @param null|string $user + * + * @return \Robo\Task\Remote\Ssh + */ + protected function taskSshExec($hostname = null, $user = null) + { + return $this->task(Ssh::class, $hostname, $user); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Simulator.php b/src/composer/vendor/consolidation/robo/src/Task/Simulator.php new file mode 100644 index 00000000..bc5f555b --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Simulator.php @@ -0,0 +1,169 @@ +task = ($task instanceof WrappedTaskInterface) ? $task->original() : $task; + $this->constructorParameters = $constructorParameters; + } + + /** + * @param string $function + * @param array $args + * + * @return \Robo\Result|\Robo\Task\Simulator + */ + public function __call($function, $args) + { + $this->stack[] = array_merge([$function], $args); + $result = call_user_func_array([$this->task, $function], $args); + return $result == $this->task ? $this : $result; + } + + /** + * {@inheritdoc} + */ + public function run() + { + $callchain = ''; + foreach ($this->stack as $action) { + $command = array_shift($action); + $parameters = $this->formatParameters($action); + $callchain .= "\n ->$command($parameters)"; + } + $context = $this->getTaskContext( + [ + '_level' => RoboLogLevel::SIMULATED_ACTION, + 'simulated' => TaskInfo::formatTaskName($this->task), + 'parameters' => $this->formatParameters($this->constructorParameters), + '_style' => ['simulated' => 'fg=blue;options=bold'], + ] + ); + + // RoboLogLevel::SIMULATED_ACTION + $this->printTaskInfo( + "Simulating {simulated}({parameters})$callchain", + $context + ); + + $result = null; + if ($this->task instanceof SimulatedInterface) { + $result = $this->task->simulate($context); + } + if (!isset($result)) { + $result = Result::success($this); + } + + return $result; + } + + /** + * Danger: reach through the simulated wrapper and pull out the command + * to be executed. This is used when using a simulated task with another + * simulated task that runs commands, e.g. the Remote\Ssh task. Using + * a simulated CommandInterface task with a non-simulated task may produce + * unexpected results (e.g. execution!). + * + * @return string + * + * @throws \Robo\Exception\TaskException + */ + public function getCommand() + { + if (!$this->task instanceof CommandInterface) { + throw new TaskException($this->task, 'Simulated task that is not a CommandInterface used as a CommandInterface.'); + } + return $this->task->getCommand(); + } + + /** + * @param string $action + * + * @return string + */ + protected function formatParameters($action) + { + $parameterList = array_map([$this, 'convertParameter'], $action); + return implode(', ', $parameterList); + } + + /** + * @param mixed $item + * + * @return string + */ + protected function convertParameter($item) + { + if (is_callable($item)) { + return 'inline_function(...)'; + } + if (is_array($item)) { + return $this->shortenParameter(var_export($item, true)); + } + if (is_object($item)) { + return '[' . get_class($item). ' object]'; + } + if (is_string($item)) { + return $this->shortenParameter("'$item'"); + } + if (is_null($item)) { + return 'null'; + } + return $item; + } + + /** + * @param string $item + * @param string $shortForm + * + * @return string + */ + protected function shortenParameter($item, $shortForm = '') + { + $maxLength = 80; + $tailLength = 20; + if (strlen($item) < $maxLength) { + return $item; + } + if (!empty($shortForm)) { + return $shortForm; + } + $item = trim($item); + $tail = preg_replace("#.*\n#ms", '', substr($item, -$tailLength)); + $head = preg_replace("#\n.*#ms", '', substr($item, 0, $maxLength - (strlen($tail) + 5))); + return "$head ... $tail"; + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/StackBasedTask.php b/src/composer/vendor/consolidation/robo/src/Task/StackBasedTask.php new file mode 100644 index 00000000..868fead8 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/StackBasedTask.php @@ -0,0 +1,238 @@ +friz() + * ->fraz() + * ->frob(); + * + * We presume that the existing library throws an exception on error. + * + * You want: + * + * $result = $this->taskFrobinator($a, $b, $c) + * ->friz() + * ->fraz() + * ->frob() + * ->run(); + * + * Execution is deferred until run(), and a Robo\Result instance is + * returned. Additionally, using Robo will covert Exceptions + * into RoboResult objects. + * + * To create a new Robo task: + * + * - Make a new class that extends StackBasedTask + * - Give it a constructor that creates a new Frobinator + * - Override getDelegate(), and return the Frobinator instance + * + * Finally, add your new class to loadTasks.php as usual, + * and you are all done. + * + * If you need to add any methods to your task that should run + * immediately (e.g. to set parameters used at run() time), just + * implement them in your derived class. + * + * If you need additional methods that should run deferred, just + * define them as 'protected function _foo()'. Then, users may + * call $this->taskFrobinator()->foo() to get deferred execution + * of _foo(). + */ +abstract class StackBasedTask extends BaseTask +{ + /** + * @var array + */ + protected $stack = []; + + /** + * @var bool + */ + protected $stopOnFail = true; + + /** + * @param bool $stop + * + * @return $this + */ + public function stopOnFail($stop = true) + { + $this->stopOnFail = $stop; + return $this; + } + + /** + * Derived classes should override the getDelegate() method, and + * return an instance of the API class being wrapped. When this + * is done, any method of the delegate is available as a method of + * this class. Calling one of the delegate's methods will defer + * execution until the run() method is called. + * + * @return null + */ + protected function getDelegate() + { + return null; + } + + /** + * Derived classes that have more than one delegate may override + * getCommandList to add as many delegate commands as desired to + * the list of potential functions that __call() tried to find. + * + * @param string $function + * + * @return array + */ + protected function getDelegateCommandList($function) + { + return [[$this, "_$function"], [$this->getDelegate(), $function]]; + } + + /** + * Print progress about the commands being executed + * + * @param string $command + * @param string $action + */ + protected function printTaskProgress($command, $action) + { + $this->printTaskInfo('{command} {action}', ['command' => "{$command[1]}", 'action' => json_encode($action)]); + } + + /** + * Derived classes can override processResult to add more + * logic to result handling from functions. By default, it + * is assumed that if a function returns in int, then + * 0 == success, and any other value is the error code. + * + * @param int|\Robo\Result $function_result + * + * @return \Robo\Result + */ + protected function processResult($function_result) + { + if (is_int($function_result)) { + if ($function_result) { + return Result::error($this, $function_result); + } + } + return Result::success($this); + } + + /** + * Record a function to call later. + * + * @param string $command + * @param array $args + * + * @return $this + */ + protected function addToCommandStack($command, $args) + { + $this->stack[] = array_merge([$command], $args); + return $this; + } + + /** + * Any API function provided by the delegate that executes immediately + * may be handled by __call automatically. These operations will all + * be deferred until this task's run() method is called. + * + * @param string $function + * @param array $args + * + * @return $this + */ + public function __call($function, $args) + { + foreach ($this->getDelegateCommandList($function) as $command) { + if (method_exists($command[0], $command[1])) { + // Otherwise, we'll defer calling this function + // until run(), and return $this. + $this->addToCommandStack($command, $args); + return $this; + } + } + + $message = "Method $function does not exist.\n"; + throw new \BadMethodCallException($message); + } + + /** + * @return int + */ + public function progressIndicatorSteps() + { + // run() will call advanceProgressIndicator() once for each + // file, one after calling stopBuffering, and again after compression. + return count($this->stack); + } + + /** + * Run all of the queued objects on the stack + * + * @return \Robo\Result + */ + public function run() + { + $this->startProgressIndicator(); + $result = Result::success($this); + + foreach ($this->stack as $action) { + $command = array_shift($action); + $this->printTaskProgress($command, $action); + $this->advanceProgressIndicator(); + // TODO: merge data from the result on this call + // with data from the result on the previous call? + // For now, the result always comes from the last function. + $result = $this->callTaskMethod($command, $action); + if ($this->stopOnFail && $result && !$result->wasSuccessful()) { + break; + } + } + + $this->stopProgressIndicator(); + + // todo: add timing information to the result + return $result; + } + + /** + * Execute one task method + * + * @param string $command + * @param string $action + * + * @return \Robo\Result + */ + protected function callTaskMethod($command, $action) + { + try { + $function_result = call_user_func_array($command, $action); + return $this->processResult($function_result); + } catch (\Exception $e) { + $this->printTaskError($e->getMessage()); + return Result::fromException($this, $e); + } + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Testing/Atoum.php b/src/composer/vendor/consolidation/robo/src/Task/Testing/Atoum.php new file mode 100644 index 00000000..56b47d84 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Testing/Atoum.php @@ -0,0 +1,184 @@ +taskAtoum() + * ->files('path/to/test.php') + * ->configFile('config/dev.php') + * ->run() + * + * ?> + * ``` + */ +class Atoum extends BaseTask implements CommandInterface, PrintedInterface +{ + use \Robo\Common\ExecOneCommand; + + /** + * @var string + */ + protected $command; + + /** + * Atoum constructor. + * + * @param null|string $pathToAtoum + * + * @throws \Robo\Exception\TaskException + */ + public function __construct($pathToAtoum = null) + { + $this->command = $pathToAtoum; + if (!$this->command) { + $this->command = $this->findExecutable('atoum'); + } + if (!$this->command) { + throw new \Robo\Exception\TaskException(__CLASS__, "Neither local atoum nor global composer installation not found"); + } + } + + /** + * Tag or Tags to filter. + * + * @param string|array $tags + * + * @return $this + */ + public function tags($tags) + { + return $this->addMultipleOption('tags', $tags); + } + + /** + * Display result using the light reporter. + * + * @return $this + */ + public function lightReport() + { + $this->option("--use-light-report"); + + return $this; + } + + /** + * Display result using the tap reporter. + * + * @return $this + */ + public function tap() + { + $this->option("use-tap-report"); + + return $this; + } + + /** + * Path to the bootstrap file. + + * @param string $file + * + * @return $this + */ + public function bootstrap($file) + { + $this->option("bootstrap", $file); + + return $this; + } + + /** + * Path to the config file. + * + * @param string $file + * + * @return $this + */ + public function configFile($file) + { + $this->option('-c', $file); + + return $this; + } + + /** + * Use atoum's debug mode. + * + * @return $this + */ + public function debug() + { + $this->option("debug"); + + return $this; + } + + /** + * Test file or test files to run. + * + * @param string|array + * + * @return $this + */ + public function files($files) + { + return $this->addMultipleOption('f', $files); + } + + /** + * Test directory or directories to run. + * + * @param string|array A single directory or a list of directories. + * + * @return $this + */ + public function directories($directories) + { + return $this->addMultipleOption('directories', $directories); + } + + /** + * @param string $option + * @param string|array $values + * + * @return $this + */ + protected function addMultipleOption($option, $values) + { + if (is_string($values)) { + $values = [$values]; + } + + foreach ($values as $value) { + $this->option($option, $value); + } + + return $this; + } + + /** + * {@inheritdoc} + */ + public function getCommand() + { + return $this->command . $this->arguments; + } + + /** + * {@inheritdoc} + */ + public function run() + { + $this->printTaskInfo('Running atoum ' . $this->arguments); + + return $this->executeCommand($this->getCommand()); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Testing/Behat.php b/src/composer/vendor/consolidation/robo/src/Task/Testing/Behat.php new file mode 100644 index 00000000..a5d9ea0a --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Testing/Behat.php @@ -0,0 +1,164 @@ +taskBehat() + * ->format('pretty') + * ->noInteraction() + * ->run(); + * ?> + * ``` + * + */ +class Behat extends BaseTask implements CommandInterface, PrintedInterface +{ + use \Robo\Common\ExecOneCommand; + + /** + * @var string + */ + protected $command; + + /** + * @var string[] $formaters available formaters for format option + */ + protected $formaters = ['progress', 'pretty', 'junit']; + + /** + * @var string[] $verbose_levels available verbose levels + */ + protected $verbose_levels = ['v', 'vv']; + + /** + * Behat constructor. + * + * @param null|string $pathToBehat + * + * @throws \Robo\Exception\TaskException + */ + public function __construct($pathToBehat = null) + { + $this->command = $pathToBehat; + if (!$this->command) { + $this->command = $this->findExecutable('behat'); + } + if (!$this->command) { + throw new \Robo\Exception\TaskException(__CLASS__, "Neither composer nor phar installation of Behat found"); + } + $this->arg('run'); + } + + /** + * @return $this + */ + public function stopOnFail() + { + $this->option('stop-on-failure'); + return $this; + } + + /** + * @return $this + */ + public function noInteraction() + { + $this->option('no-interaction'); + return $this; + } + + /** + * @param $config_file + * + * @return $this + */ + public function config($config_file) + { + $this->option('config', $config_file); + return $this; + } + + /** + * @return $this + */ + public function colors() + { + $this->option('colors'); + return $this; + } + + /** + * @return $this + */ + public function noColors() + { + $this->option('no-colors'); + return $this; + } + + /** + * @param string $suite + * + * @return $this + */ + public function suite($suite) + { + $this->option('suite', $suite); + return $this; + } + + /** + * @param string $level + * + * @return $this + */ + public function verbose($level = 'v') + { + if (!in_array($level, $this->verbose_levels)) { + throw new \InvalidArgumentException('expected ' . implode(',', $this->verbose_levels)); + } + $this->option('-' . $level); + return $this; + } + + /** + * @param string $formater + * + * @return $this + */ + public function format($formater) + { + if (!in_array($formater, $this->formaters)) { + throw new \InvalidArgumentException('expected ' . implode(',', $this->formaters)); + } + $this->option('format', $formater); + return $this; + } + + /** + * Returns command that can be executed. + * This method is used to pass generated command from one task to another. + * + * @return string + */ + public function getCommand() + { + return $this->command . $this->arguments; + } + + /** + * {@inheritdoc} + */ + public function run() + { + $this->printTaskInfo('Running behat {arguments}', ['arguments' => $this->arguments]); + return $this->executeCommand($this->getCommand()); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Testing/Codecept.php b/src/composer/vendor/consolidation/robo/src/Task/Testing/Codecept.php new file mode 100644 index 00000000..442540a1 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Testing/Codecept.php @@ -0,0 +1,263 @@ +taskCodecept() + * ->suite('acceptance') + * ->env('chrome') + * ->group('admin') + * ->xml() + * ->html() + * ->run(); + * + * ?> + * ``` + * + */ +class Codecept extends BaseTask implements CommandInterface, PrintedInterface +{ + use \Robo\Common\ExecOneCommand; + + /** + * @var string + */ + protected $suite = ''; + + /** + * @var string + */ + protected $test = ''; + + /** + * @var string + */ + protected $command; + + /** + * @param string $pathToCodeception + * + * @throws \Robo\Exception\TaskException + */ + public function __construct($pathToCodeception = '') + { + $this->command = $pathToCodeception; + if (!$this->command) { + $this->command = $this->findExecutable('codecept'); + } + if (!$this->command) { + throw new TaskException(__CLASS__, "Neither composer nor phar installation of Codeception found."); + } + $this->command .= ' run'; + } + + /** + * @param string $suite + * + * @return $this + */ + public function suite($suite) + { + $this->suite = $suite; + return $this; + } + + /** + * @param string $testName + * + * @return $this + */ + public function test($testName) + { + $this->test = $testName; + return $this; + } + + /** + * set group option. Can be called multiple times + * + * @param string $group + * + * @return $this + */ + public function group($group) + { + $this->option("group", $group); + return $this; + } + + /** + * @param string $group + * + * @return $this + */ + public function excludeGroup($group) + { + $this->option("skip-group", $group); + return $this; + } + + /** + * generate json report + * + * @param string $file + * + * @return $this + */ + public function json($file = null) + { + $this->option("json", $file); + return $this; + } + + /** + * generate xml JUnit report + * + * @param string $file + * + * @return $this + */ + public function xml($file = null) + { + $this->option("xml", $file); + return $this; + } + + /** + * Generate html report + * + * @param string $dir + * + * @return $this + */ + public function html($dir = null) + { + $this->option("html", $dir); + return $this; + } + + /** + * generate tap report + * + * @param string $file + * + * @return $this + */ + public function tap($file = null) + { + $this->option("tap", $file); + return $this; + } + + /** + * provides config file other then default `codeception.yml` with `-c` option + * + * @param string $file + * + * @return $this + */ + public function configFile($file) + { + $this->option("-c", $file); + return $this; + } + + /** + * collect codecoverage in raw format. You may pass name of cov file to save results + * + * @param null|string $cov + * + * @return $this + */ + public function coverage($cov = null) + { + $this->option("coverage", $cov); + return $this; + } + + /** + * execute in silent mode + * + * @return $this + */ + public function silent() + { + $this->option("silent"); + return $this; + } + + /** + * collect code coverage in xml format. You may pass name of xml file to save results + * + * @param string $xml + * + * @return $this + */ + public function coverageXml($xml = null) + { + $this->option("coverage-xml", $xml); + return $this; + } + + /** + * collect code coverage and generate html report. You may pass + * + * @param string $html + * + * @return $this + */ + public function coverageHtml($html = null) + { + $this->option("coverage-html", $html); + return $this; + } + + /** + * @param string $env + * + * @return $this + */ + public function env($env) + { + $this->option("env", $env); + return $this; + } + + /** + * @return $this + */ + public function debug() + { + $this->option("debug"); + return $this; + } + + /** + * {@inheritdoc} + */ + public function getCommand() + { + $this->option(null, $this->suite) + ->option(null, $this->test); + return $this->command . $this->arguments; + } + + /** + * {@inheritdoc} + */ + public function run() + { + $command = $this->getCommand(); + $this->printTaskInfo('Executing {command}', ['command' => $command]); + return $this->executeCommand($command); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Testing/PHPUnit.php b/src/composer/vendor/consolidation/robo/src/Task/Testing/PHPUnit.php new file mode 100644 index 00000000..df67e1c7 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Testing/PHPUnit.php @@ -0,0 +1,199 @@ +taskPHPUnit() + * ->group('core') + * ->bootstrap('test/bootstrap.php') + * ->run() + * + * ?> + * ``` + */ +class PHPUnit extends BaseTask implements CommandInterface, PrintedInterface +{ + use \Robo\Common\ExecOneCommand; + + /** + * @var string + */ + protected $command; + + /** + * Directory of test files or single test file to run. Appended to + * the command and arguments. + * + * @var string + */ + protected $files = ''; + + public function __construct($pathToPhpUnit = null) + { + $this->command = $pathToPhpUnit; + if (!$this->command) { + $this->command = $this->findExecutablePhar('phpunit'); + } + if (!$this->command) { + throw new \Robo\Exception\TaskException(__CLASS__, "Neither local phpunit nor global composer installation not found"); + } + } + + /** + * @param string $filter + * + * @return $this + */ + public function filter($filter) + { + $this->option('filter', $filter); + return $this; + } + + /** + * @param string $group + * + * @return $this + */ + public function group($group) + { + $this->option("group", $group); + return $this; + } + + /** + * @param string $group + * + * @return $this + */ + public function excludeGroup($group) + { + $this->option("exclude-group", $group); + return $this; + } + + /** + * adds `log-json` option to runner + * + * @param string $file + * + * @return $this + */ + public function json($file = null) + { + $this->option("log-json", $file); + return $this; + } + + /** + * adds `log-junit` option + * + * @param string $file + * + * @return $this + */ + public function xml($file = null) + { + $this->option("log-junit", $file); + return $this; + } + + /** + * @param string $file + * + * @return $this + */ + public function tap($file = "") + { + $this->option("log-tap", $file); + return $this; + } + + /** + * @param string $file + * + * @return $this + */ + public function bootstrap($file) + { + $this->option("bootstrap", $file); + return $this; + } + + /** + * @param string $file + * + * @return $this + */ + public function configFile($file) + { + $this->option('-c', $file); + return $this; + } + + /** + * @return $this + */ + public function debug() + { + $this->option("debug"); + return $this; + } + + /** + * Directory of test files or single test file to run. + * + * @param string $files A single test file or a directory containing test files. + * + * @return $this + * + * @throws \Robo\Exception\TaskException + * + * @deprecated Use file() or dir() method instead + */ + public function files($files) + { + if (!empty($this->files) || is_array($files)) { + throw new \Robo\Exception\TaskException(__CLASS__, "Only one file or directory may be provided."); + } + $this->files = ' ' . $files; + + return $this; + } + + /** + * Test the provided file. + * + * @param string $file path to file to test + * + * @return $this + */ + public function file($file) + { + return $this->files($file); + } + + /** + * {@inheritdoc} + */ + public function getCommand() + { + return $this->command . $this->arguments . $this->files; + } + + /** + * {@inheritdoc} + */ + public function run() + { + $this->printTaskInfo('Running PHPUnit {arguments}', ['arguments' => $this->arguments]); + return $this->executeCommand($this->getCommand()); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Testing/Phpspec.php b/src/composer/vendor/consolidation/robo/src/Task/Testing/Phpspec.php new file mode 100644 index 00000000..dd6a5ae7 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Testing/Phpspec.php @@ -0,0 +1,116 @@ +taskPhpspec() + * ->format('pretty') + * ->noInteraction() + * ->run(); + * ?> + * ``` + * + */ +class Phpspec extends BaseTask implements CommandInterface, PrintedInterface +{ + use \Robo\Common\ExecOneCommand; + + /** + * @var string + */ + protected $command; + + /** + * @var string[] $formaters available formaters for format option + */ + protected $formaters = ['progress', 'html', 'pretty', 'junit', 'dot', 'tap']; + + /** + * @var array $verbose_levels available verbose levels + */ + protected $verbose_levels = ['v', 'vv', 'vvv']; + + public function __construct($pathToPhpspec = null) + { + $this->command = $pathToPhpspec; + if (!$this->command) { + $this->command = $this->findExecutable('phpspec'); + } + if (!$this->command) { + throw new \Robo\Exception\TaskException(__CLASS__, "Neither composer nor phar installation of Phpspec found"); + } + $this->arg('run'); + } + + public function stopOnFail() + { + $this->option('stop-on-failure'); + return $this; + } + + public function noCodeGeneration() + { + $this->option('no-code-generation'); + return $this; + } + + public function quiet() + { + $this->option('quiet'); + return $this; + } + + public function verbose($level = 'v') + { + if (!in_array($level, $this->verbose_levels)) { + throw new \InvalidArgumentException('expected ' . implode(',', $this->verbose_levels)); + } + $this->option('-' . $level); + return $this; + } + + public function noAnsi() + { + $this->option('no-ansi'); + return $this; + } + + public function noInteraction() + { + $this->option('no-interaction'); + return $this; + } + + public function config($config_file) + { + $this->option('config', $config_file); + return $this; + } + + public function format($formater) + { + if (!in_array($formater, $this->formaters)) { + throw new \InvalidArgumentException('expected ' . implode(',', $this->formaters)); + } + $this->option('format', $formater); + return $this; + } + + public function getCommand() + { + return $this->command . $this->arguments; + } + + public function run() + { + $this->printTaskInfo('Running phpspec {arguments}', ['arguments' => $this->arguments]); + return $this->executeCommand($this->getCommand()); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Testing/loadTasks.php b/src/composer/vendor/consolidation/robo/src/Task/Testing/loadTasks.php new file mode 100644 index 00000000..43145b9b --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Testing/loadTasks.php @@ -0,0 +1,55 @@ +task(Codecept::class, $pathToCodeception); + } + + /** + * @param null|string $pathToPhpUnit + * + * @return \Robo\Task\Testing\PHPUnit + */ + protected function taskPhpUnit($pathToPhpUnit = null) + { + return $this->task(PHPUnit::class, $pathToPhpUnit); + } + + /** + * @param null $pathToPhpspec + * + * @return \Robo\Task\Testing\Phpspec + */ + protected function taskPhpspec($pathToPhpspec = null) + { + return $this->task(Phpspec::class, $pathToPhpspec); + } + + /** + * @param null $pathToAtoum + * + * @return \Robo\Task\Testing\Atoum + */ + protected function taskAtoum($pathToAtoum = null) + { + return $this->task(Atoum::class, $pathToAtoum); + } + + /** + * @param null $pathToBehat + * + * @return \Robo\Task\Testing\Behat + */ + protected function taskBehat($pathToBehat = null) + { + return $this->task(Behat::class, $pathToBehat); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Vcs/GitStack.php b/src/composer/vendor/consolidation/robo/src/Task/Vcs/GitStack.php new file mode 100644 index 00000000..9210bfec --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Vcs/GitStack.php @@ -0,0 +1,153 @@ +taskGitStack() + * ->stopOnFail() + * ->add('-A') + * ->commit('adding everything') + * ->push('origin','master') + * ->tag('0.6.0') + * ->push('origin','0.6.0') + * ->run() + * + * $this->taskGitStack() + * ->stopOnFail() + * ->add('doc/*') + * ->commit('doc updated') + * ->push() + * ->run(); + * ?> + * ``` + */ +class GitStack extends CommandStack +{ + /** + * @param string $pathToGit + */ + public function __construct($pathToGit = 'git') + { + $this->executable = $pathToGit; + } + + /** + * Executes `git clone` + * + * @param string $repo + * @param string $to + * + * @return $this + */ + public function cloneRepo($repo, $to = "") + { + return $this->exec(['clone', $repo, $to]); + } + + /** + * Executes `git add` command with files to add pattern + * + * @param string $pattern + * + * @return $this + */ + public function add($pattern) + { + return $this->exec([__FUNCTION__, $pattern]); + } + + /** + * Executes `git commit` command with a message + * + * @param string $message + * @param string $options + * + * @return $this + */ + public function commit($message, $options = "") + { + $message = ProcessUtils::escapeArgument($message); + return $this->exec([__FUNCTION__, "-m $message", $options]); + } + + /** + * Executes `git pull` command. + * + * @param string $origin + * @param string $branch + * + * @return $this + */ + public function pull($origin = '', $branch = '') + { + return $this->exec([__FUNCTION__, $origin, $branch]); + } + + /** + * Executes `git push` command + * + * @param string $origin + * @param string $branch + * + * @return $this + */ + public function push($origin = '', $branch = '') + { + return $this->exec([__FUNCTION__, $origin, $branch]); + } + + /** + * Performs git merge + * + * @param string $branch + * + * @return $this + */ + public function merge($branch) + { + return $this->exec([__FUNCTION__, $branch]); + } + + /** + * Executes `git checkout` command + * + * @param string $branch + * + * @return $this + */ + public function checkout($branch) + { + return $this->exec([__FUNCTION__, $branch]); + } + + /** + * Executes `git tag` command + * + * @param string $tag_name + * @param string $message + * + * @return $this + */ + public function tag($tag_name, $message = "") + { + if ($message != "") { + $message = "-m '$message'"; + } + return $this->exec([__FUNCTION__, $message, $tag_name]); + } + + /** + * {@inheritdoc} + */ + public function run() + { + $this->printTaskInfo("Running git commands..."); + return parent::run(); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Vcs/HgStack.php b/src/composer/vendor/consolidation/robo/src/Task/Vcs/HgStack.php new file mode 100644 index 00000000..71cc0ca9 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Vcs/HgStack.php @@ -0,0 +1,153 @@ +hgStack + * ->cloneRepo('https://bitbucket.org/durin42/hgsubversion') + * ->pull() + * ->add() + * ->commit('changed') + * ->push() + * ->tag('0.6.0') + * ->push('0.6.0') + * ->run(); + * ?> + * ``` + */ +class HgStack extends CommandStack +{ + + /** + * @param string $pathToHg + */ + public function __construct($pathToHg = 'hg') + { + $this->executable = $pathToHg; + } + + /** + * Executes `hg clone` + * + * @param string $repo + * @param string $to + * + * @return $this + */ + public function cloneRepo($repo, $to = '') + { + return $this->exec(['clone', $repo, $to]); + } + + /** + * Executes `hg add` command with files to add by pattern + * + * @param string $include + * @param string $exclude + * + * @return $this + */ + public function add($include = '', $exclude = '') + { + if (strlen($include) > 0) { + $include = "-I {$include}"; + } + + if (strlen($exclude) > 0) { + $exclude = "-X {$exclude}"; + } + + return $this->exec([__FUNCTION__, $include, $exclude]); + } + + /** + * Executes `hg commit` command with a message + * + * @param string $message + * @param string $options + * + * @return $this + */ + public function commit($message, $options = '') + { + return $this->exec([__FUNCTION__, "-m '{$message}'", $options]); + } + + /** + * Executes `hg pull` command. + * + * @param string $branch + * + * @return $this + */ + public function pull($branch = '') + { + if (strlen($branch) > 0) { + $branch = "-b '{$branch}''"; + } + + return $this->exec([__FUNCTION__, $branch]); + } + + /** + * Executes `hg push` command + * + * @param string $branch + * + * @return $this + */ + public function push($branch = '') + { + if (strlen($branch) > 0) { + $branch = "-b '{$branch}'"; + } + + return $this->exec([__FUNCTION__, $branch]); + } + + /** + * Performs hg merge + * + * @param string $revision + * + * @return $this + */ + public function merge($revision = '') + { + if (strlen($revision) > 0) { + $revision = "-r {$revision}"; + } + + return $this->exec([__FUNCTION__, $revision]); + } + + /** + * Executes `hg tag` command + * + * @param string $tag_name + * @param string $message + * + * @return $this + */ + public function tag($tag_name, $message = '') + { + if ($message !== '') { + $message = "-m '{$message}'"; + } + return $this->exec([__FUNCTION__, $message, $tag_name]); + } + + /** + * {@inheritdoc} + */ + public function run() + { + $this->printTaskInfo('Running hg commands...'); + return parent::run(); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Vcs/SvnStack.php b/src/composer/vendor/consolidation/robo/src/Task/Vcs/SvnStack.php new file mode 100644 index 00000000..ec719b53 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Vcs/SvnStack.php @@ -0,0 +1,106 @@ +taskSvnStack() + * ->checkout('http://svn.collab.net/repos/svn/trunk') + * ->run() + * + * // alternatively + * $this->_svnCheckout('http://svn.collab.net/repos/svn/trunk'); + * + * $this->taskSvnStack('username', 'password') + * ->stopOnFail() + * ->update() + * ->add('doc/*') + * ->commit('doc updated') + * ->run(); + * ?> + * ``` + */ +class SvnStack extends CommandStack implements CommandInterface +{ + /** + * @var bool + */ + protected $stopOnFail = false; + + /** + * @var \Robo\Result + */ + protected $result; + + /** + * @param string $username + * @param string $password + * @param string $pathToSvn + */ + public function __construct($username = '', $password = '', $pathToSvn = 'svn') + { + $this->executable = $pathToSvn; + if (!empty($username)) { + $this->executable .= " --username $username"; + } + if (!empty($password)) { + $this->executable .= " --password $password"; + } + $this->result = Result::success($this); + } + + /** + * Updates `svn update` command + * + * @param string $path + * + * @return $this; + */ + public function update($path = '') + { + return $this->exec("update $path"); + } + + /** + * Executes `svn add` command with files to add pattern + * + * @param string $pattern + * + * @return $this + */ + public function add($pattern = '') + { + return $this->exec("add $pattern"); + } + + /** + * Executes `svn commit` command with a message + * + * @param string $message + * @param string $options + * + * @return $this + */ + public function commit($message, $options = "") + { + return $this->exec("commit -m '$message' $options"); + } + + /** + * Executes `svn checkout` command + * + * @param string $branch + * + * @return $this + */ + public function checkout($branch) + { + return $this->exec("checkout $branch"); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Vcs/loadShortcuts.php b/src/composer/vendor/consolidation/robo/src/Task/Vcs/loadShortcuts.php new file mode 100644 index 00000000..7d64ab58 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Vcs/loadShortcuts.php @@ -0,0 +1,35 @@ +taskSvnStack()->checkout($url)->run(); + } + + /** + * @param string $url + * + * @return \Robo\Result + */ + protected function _gitClone($url) + { + return $this->taskGitStack()->cloneRepo($url)->run(); + } + + /** + * @param string $url + * + * @return \Robo\Result + */ + protected function _hgClone($url) + { + return $this->taskHgStack()->cloneRepo($url)->run(); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Task/Vcs/loadTasks.php b/src/composer/vendor/consolidation/robo/src/Task/Vcs/loadTasks.php new file mode 100644 index 00000000..6dd06228 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Task/Vcs/loadTasks.php @@ -0,0 +1,37 @@ +task(SvnStack::class, $username, $password, $pathToSvn); + } + + /** + * @param string $pathToGit + * + * @return \Robo\Task\Vcs\GitStack + */ + protected function taskGitStack($pathToGit = 'git') + { + return $this->task(GitStack::class, $pathToGit); + } + + /** + * @param string $pathToHg + * + * @return \Robo\Task\Vcs\HgStack + */ + protected function taskHgStack($pathToHg = 'hg') + { + return $this->task(HgStack::class, $pathToHg); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/TaskAccessor.php b/src/composer/vendor/consolidation/robo/src/TaskAccessor.php new file mode 100644 index 00000000..e65cd3eb --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/TaskAccessor.php @@ -0,0 +1,47 @@ +task(Foo::class, $a, $b); + * + * instead of: + * + * $this->taskFoo($a, $b); + * + * The later form is preferred. + * + * @return \Robo\Collection\CollectionBuilder + */ + protected function task() + { + $args = func_get_args(); + $name = array_shift($args); + + $collectionBuilder = $this->collectionBuilder(); + return $collectionBuilder->build($name, $args); + } +} diff --git a/src/composer/vendor/consolidation/robo/src/TaskInfo.php b/src/composer/vendor/consolidation/robo/src/TaskInfo.php new file mode 100644 index 00000000..ce59c2d5 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/TaskInfo.php @@ -0,0 +1,35 @@ + TaskInfo::formatTaskName($task), + 'task' => $task, + ]; + } + + /** + * @param object $task + * + * @return string + */ + public static function formatTaskName($task) + { + $name = get_class($task); + $name = preg_replace('~Stack^~', '', $name); + $name = str_replace('Robo\\Task\Base\\', '', $name); + $name = str_replace('Robo\\Task\\', '', $name); + $name = str_replace('Robo\\Collection\\', '', $name); + return $name; + } +} diff --git a/src/composer/vendor/consolidation/robo/src/Tasks.php b/src/composer/vendor/consolidation/robo/src/Tasks.php new file mode 100644 index 00000000..2822d7d5 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/src/Tasks.php @@ -0,0 +1,23 @@ +init([ + 'debug' => true, + 'includePaths' => [ + __DIR__.'/../src', + __DIR__.'/../vendor/symfony/process', + __DIR__.'/../vendor/symfony/console', + ] +]); diff --git a/src/composer/vendor/consolidation/robo/tests/_data/TestedRoboFile.php b/src/composer/vendor/consolidation/robo/tests/_data/TestedRoboFile.php new file mode 100644 index 00000000..bc11796f --- /dev/null +++ b/src/composer/vendor/consolidation/robo/tests/_data/TestedRoboFile.php @@ -0,0 +1,38 @@ + false, 'to' => null]) { + } + + /** + * Calculate the fibonacci sequence between two numbers. + * + * Graphic output will look like + * +----+---+-------------+ + * | | | | + * | |-+-| | + * |----+-+-+ | + * | | | + * | | | + * | | | + * +--------+-------------+ + * + * @param int $start Number to start from + * @param int $steps Number of steps to perform + * @param array $opts + * @option $graphic Display the sequence graphically using cube + * representation + */ + public function fibonacci($start, $steps, $opts = ['graphic' => false]) + { + } + + /** Compact doc comment */ + public function compact() + { + } +} diff --git a/src/composer/vendor/consolidation/robo/tests/_data/TestedRoboTask.php b/src/composer/vendor/consolidation/robo/tests/_data/TestedRoboTask.php new file mode 100644 index 00000000..c1c5efba --- /dev/null +++ b/src/composer/vendor/consolidation/robo/tests/_data/TestedRoboTask.php @@ -0,0 +1,61 @@ +taskTestedRoboTask([ + * 'web/assets/screen.css', + * 'web/assets/print.css', + * 'web/assets/theme.css' + * ]) + * ->to('web/assets/style.css') + * ->run() + * ?> + * ``` + */ +class TestedRoboTask extends BaseTask +{ + /** + * @var array|Iterator files + */ + protected $files; + + /** + * @var string dst + */ + protected $dst; + + /** + * Constructor. This should not be documented + * + * @param array|Iterator $files + */ + public function __construct() + { + } + + /** + * Set the destination file + * + * @param string $dst + * + * @return Concat The current instance + */ + public function to($dst) + { + return $this; + } + + /** + * {@inheritdoc} + */ + public function run() + { + return Result::success($this); + } +} diff --git a/src/composer/vendor/consolidation/robo/tests/_data/claypit/a.txt b/src/composer/vendor/consolidation/robo/tests/_data/claypit/a.txt new file mode 100644 index 00000000..8c7e5a66 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/tests/_data/claypit/a.txt @@ -0,0 +1 @@ +A \ No newline at end of file diff --git a/src/composer/vendor/consolidation/robo/tests/_data/claypit/b.txt b/src/composer/vendor/consolidation/robo/tests/_data/claypit/b.txt new file mode 100644 index 00000000..7371f47a --- /dev/null +++ b/src/composer/vendor/consolidation/robo/tests/_data/claypit/b.txt @@ -0,0 +1 @@ +B \ No newline at end of file diff --git a/src/composer/vendor/consolidation/robo/tests/_data/claypit/box/robo.txt b/src/composer/vendor/consolidation/robo/tests/_data/claypit/box/robo.txt new file mode 100644 index 00000000..3ba64572 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/tests/_data/claypit/box/robo.txt @@ -0,0 +1 @@ +HELLOROBO \ No newline at end of file diff --git a/src/composer/vendor/consolidation/robo/tests/_data/claypit/some/deeply/existing_file b/src/composer/vendor/consolidation/robo/tests/_data/claypit/some/deeply/existing_file new file mode 100644 index 00000000..37cfa282 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/tests/_data/claypit/some/deeply/existing_file @@ -0,0 +1 @@ +some existing file diff --git a/src/composer/vendor/consolidation/robo/tests/_data/claypit/some/deeply/nested/structu.re b/src/composer/vendor/consolidation/robo/tests/_data/claypit/some/deeply/nested/structu.re new file mode 100644 index 00000000..98a202cb --- /dev/null +++ b/src/composer/vendor/consolidation/robo/tests/_data/claypit/some/deeply/nested/structu.re @@ -0,0 +1 @@ +Just a file diff --git a/src/composer/vendor/consolidation/robo/tests/_data/claypit/some_destination/deeply/existing_file b/src/composer/vendor/consolidation/robo/tests/_data/claypit/some_destination/deeply/existing_file new file mode 100644 index 00000000..1765b73b --- /dev/null +++ b/src/composer/vendor/consolidation/robo/tests/_data/claypit/some_destination/deeply/existing_file @@ -0,0 +1 @@ +some_destination existing file diff --git a/src/composer/vendor/consolidation/robo/tests/_data/dump.sql b/src/composer/vendor/consolidation/robo/tests/_data/dump.sql new file mode 100644 index 00000000..4bc742ce --- /dev/null +++ b/src/composer/vendor/consolidation/robo/tests/_data/dump.sql @@ -0,0 +1 @@ +/* Replace this file with actual dump of your database */ \ No newline at end of file diff --git a/src/composer/vendor/consolidation/robo/tests/_data/parascript.php b/src/composer/vendor/consolidation/robo/tests/_data/parascript.php new file mode 100644 index 00000000..403e2f1c --- /dev/null +++ b/src/composer/vendor/consolidation/robo/tests/_data/parascript.php @@ -0,0 +1,8 @@ +getContainer()->get('collectionBuilder', [$tasks]); + $tasks->setBuilder($builder); + return $builder; + } + + public function seeDirFound($dir) + { + $this->assertTrue(is_dir($dir) && file_exists($dir), "Directory does not exist"); + } + + public function _before(\Codeception\TestCase $test) { + $container = new \League\Container\Container(); + $this->initSeeInOutputTrait($container); + Robo::setContainer($container); + $this->setContainer($container); + + $this->getModule('Filesystem')->copyDir(codecept_data_dir().'claypit', codecept_data_dir().'sandbox'); + } + + public function _after(\Codeception\TestCase $test) { + $this->getModule('Filesystem')->deleteDir(codecept_data_dir().'sandbox'); + $this->getContainer()->add('output', new ConsoleOutput()); + chdir(codecept_root_dir()); + } +} diff --git a/src/composer/vendor/consolidation/robo/tests/_helpers/CodeGuy.php b/src/composer/vendor/consolidation/robo/tests/_helpers/CodeGuy.php new file mode 100644 index 00000000..e7ce5917 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/tests/_helpers/CodeGuy.php @@ -0,0 +1,26 @@ +initSeeInOutputTrait(static::$container); + } + + public function _after(\Codeception\TestCase $test) + { + // Ensure that $stopOnFail global static is reset, as tests + // that set it to true will force an exception, and therefor + // will not have a chance to clean this up. + \Robo\Result::$stopOnFail = false; + + \AspectMock\Test::clean(); + $consoleOutput = new ConsoleOutput(); + static::$container->add('output', $consoleOutput); + static::$container->add('logger', new \Consolidation\Log\Logger($consoleOutput)); + } +} diff --git a/src/composer/vendor/consolidation/robo/tests/_helpers/SeeInOutputTrait.php b/src/composer/vendor/consolidation/robo/tests/_helpers/SeeInOutputTrait.php new file mode 100644 index 00000000..85ae5335 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/tests/_helpers/SeeInOutputTrait.php @@ -0,0 +1,62 @@ +capturedOutput = ''; + $this->testPrinter = new BufferedOutput(OutputInterface::VERBOSITY_DEBUG); + + $app = Robo::createDefaultApplication(); + $config = new \Robo\Config(); + \Robo\Robo::configureContainer($container, $app, $config, $input, $this->testPrinter); + + // Set the application dispatcher + $app->setDispatcher($container->get('eventDispatcher')); + $this->logger = $container->get('logger'); + } + + public function capturedOutputStream() + { + return $this->testPrinter; + } + + public function logger() + { + return $this->logger; + } + + protected function accumulate() + { + $this->capturedOutput .= $this->testPrinter->fetch(); + return $this->capturedOutput; + } + + public function seeInOutput($value) + { + $output = $this->accumulate(); + $this->assertContains($value, $output); + } + + public function doNotSeeInOutput($value) + { + $output = $this->accumulate(); + $this->assertNotContains($value, $output); + } + + public function seeOutputEquals($value) + { + $output = $this->accumulate(); + $this->assertEquals($value, $output); + } +} diff --git a/src/composer/vendor/consolidation/robo/tests/_helpers/TestHelper.php b/src/composer/vendor/consolidation/robo/tests/_helpers/TestHelper.php new file mode 100644 index 00000000..d25d90b7 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/tests/_helpers/TestHelper.php @@ -0,0 +1,10 @@ +wantTo('minify a css file'); +$I->amInPath(codecept_data_dir().'sandbox'); + +$sampleCss = dirname(__DIR__) . '/_data/sample.css'; +$outputCss = 'minifiedSample.css'; + +$initialFileSize = filesize($sampleCss); + +$I->taskMinify($sampleCss) + ->to('minifiedSample.css') + ->run(); + +$I->seeFileFound($outputCss); +$minifiedFileSize = filesize($outputCss); +$outputCssContents = file_get_contents($outputCss); + +$I->assertLessThan($initialFileSize, $minifiedFileSize, 'Minified file is smaller than the source file'); +$I->assertGreaterThan(0, $minifiedFileSize, 'Minified file is not empty'); +$I->assertContains('body', $outputCssContents, 'Minified file has some content from the source file'); +$I->assertNotContains('Sample css file', $outputCssContents, 'Minified file does not contain comment from source file'); diff --git a/src/composer/vendor/consolidation/robo/tests/cli/CleanDirCept.php b/src/composer/vendor/consolidation/robo/tests/cli/CleanDirCept.php new file mode 100644 index 00000000..041f8b69 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/tests/cli/CleanDirCept.php @@ -0,0 +1,13 @@ +wantTo('clean dir with DeleteDirTask'); +$I->amInPath(codecept_data_dir()); +$I->seeFileFound('robo.txt', 'sandbox'); +$I->taskCleanDir(['sandbox']) + ->run(); +$I->dontSeeFileFound('box', 'sandbox'); +$I->dontSeeFileFound('robo.txt', 'sandbox'); +$I->dontSeeFileFound('a.txt' , 'sandbox'); + + diff --git a/src/composer/vendor/consolidation/robo/tests/cli/CollectionCest.php b/src/composer/vendor/consolidation/robo/tests/cli/CollectionCest.php new file mode 100644 index 00000000..493daf09 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/tests/cli/CollectionCest.php @@ -0,0 +1,409 @@ +amInPath(codecept_data_dir().'sandbox'); + } + + public function toRunMultipleTasksViaACollectionBuilder(CliGuy $I) + { + // This tests creating multiple tasks in a single builder, + // which implicitly adds them to a collection. To keep things + // simple, we are only going to use taskFilesystemStack. It + // would be possible, of course, to do these operations with + // a single FilesystemStack, but our goal is to test creating + // multiple tasks with a builder, and ensure that a propper + // collection is built. + $collection = $I->collectionBuilder(); + $result = $collection->taskFilesystemStack() + ->mkdir('a') + ->touch('a/a.txt') + ->rollback( + $I->taskDeleteDir('a') + ) + ->taskFilesystemStack() + ->mkdir('a/b') + ->touch('a/b/b.txt') + ->taskFilesystemStack() + ->mkdir('a/c') + ->touch('a/c/c.txt') + ->run(); + + $I->assertEquals(0, $result->getExitCode(), $result->getMessage()); + + // All of the tasks created by the builder should be added + // to a collection, and `run()` should run them all. + $I->seeDirFound('a'); + $I->seeFileFound('a/a.txt'); + $I->seeDirFound('a/b'); + $I->seeFileFound('a/b/b.txt'); + $I->seeDirFound('a/c'); + $I->seeFileFound('a/c/c.txt'); + } + + public function toUseAWorkingDirWithACollectionBuilder(CliGuy $I) + { + // Run the same test with a working directory. The working + // directory path will point to a temporary directory which + // will be moved into place once the tasks complete. + $collection = $I->collectionBuilder(); + $workDirPath = $collection->workDir("build"); + $I->assertNotEquals("build", basename($workDirPath)); + $result = $collection->taskFilesystemStack() + ->mkdir("{$workDirPath}/a") + ->touch("{$workDirPath}/a/a.txt") + ->taskFilesystemStack() + ->mkdir("{$workDirPath}/a/b") + ->touch("{$workDirPath}/a/b/b.txt") + ->taskFilesystemStack() + ->mkdir("{$workDirPath}/a/c") + ->touch("{$workDirPath}/a/c/c.txt") + ->run(); + + $I->assertEquals(0, $result->getExitCode(), $result->getMessage()); + + // All of the tasks created by the builder should be added + // to a collection, and `run()` should run them all. + $I->seeDirFound('build/a'); + $I->seeFileFound('build/a/a.txt'); + $I->seeDirFound('build/a/b'); + $I->seeFileFound('build/a/b/b.txt'); + $I->seeDirFound('build/a/c'); + $I->seeFileFound('build/a/c/c.txt'); + } + + public function toRollbackAfterFailureViaACollectionBuilder(CliGuy $I) + { + // This is like the previous test, toRunMultipleTasksViaACollectionBuilder, + // except we force an error at the end, and confirm that the + // rollback function is called. + $collection = $I->collectionBuilder(); + $result = $collection->taskFilesystemStack() + ->mkdir('j') + ->touch('j/j.txt') + ->rollback( + $I->taskDeleteDir('j') + ) + ->taskFilesystemStack() + ->mkdir('j/k') + ->touch('j/k/k.txt') + ->taskFilesystemStack() + ->mkdir('j/k/m') + ->touch('j/k/m/m.txt') + ->taskCopyDir(['doesNotExist' => 'copied']) + ->run(); + + $I->assertEquals(1, $result->getExitCode(), $result->getMessage()); + + // All of the tasks created by the builder should be added + // to a collection, and `run()` should run them all. + $I->dontSeeFileFound('q/q.txt'); + $I->dontSeeFileFound('j/j.txt'); + $I->dontSeeFileFound('j/k/k.txt'); + $I->dontSeeFileFound('j/k/m/m.txt'); + } + + public function toRollbackAWorkingDir(CliGuy $I) + { + // Run the same test with a working directory. The working + // directory path will point to a temporary directory which + // will be moved into place once the tasks complete. + $collection = $I->collectionBuilder(); + $workDirPath = $collection->workDir("build"); + $I->assertNotEquals("build", basename($workDirPath)); + $result = $collection->taskFilesystemStack() + ->mkdir("{$workDirPath}/a") + ->touch("{$workDirPath}/a/a.txt") + ->taskFilesystemStack() + ->mkdir("{$workDirPath}/a/b") + ->touch("{$workDirPath}/a/b/b.txt") + ->taskFilesystemStack() + ->mkdir("{$workDirPath}/a/c") + ->touch("{$workDirPath}/a/c/c.txt") + ->taskCopyDir(['doesNotExist' => 'copied']) + ->run(); + + $I->assertEquals(1, $result->getExitCode(), $result->getMessage()); + + // All of the tasks created by the builder should be added + // to a collection, and `run()` should run them all. + $I->dontSeeFileFound('build/a'); + $I->dontSeeFileFound($workDirPath); + } + + public function toBuildFilesViaAddIterable(CliGuy $I) + { + $processList = ['cats', 'dogs', 'sheep', 'fish', 'horses', 'cows']; + + $collection = $I->collectionBuilder(); + $result = $collection + ->taskFilesystemStack() + ->mkdir('stuff') + ->taskForEach($processList) + ->withBuilder( + function ($builder, $key, $value) { + return $builder + ->taskFilesystemStack() + ->touch("stuff/{$value}.txt"); + } + ) + ->run(); + + $I->assertEquals(0, $result->getExitCode(), $result->getMessage()); + + $I->seeFileFound('stuff/cats.txt'); + $I->seeFileFound('stuff/dogs.txt'); + $I->seeFileFound('stuff/sheep.txt'); + $I->seeFileFound('stuff/fish.txt'); + $I->seeFileFound('stuff/horses.txt'); + $I->seeFileFound('stuff/cows.txt'); + } + + public function toRollbackANestedCollection(CliGuy $I) + { + // This is like the previous test, toRunMultipleTasksViaACollectionBuilder, + // except we force an error at the end, and confirm that the + // rollback function is called. + $collection = $I->collectionBuilder(); + $collection->taskFilesystemStack() + ->mkdir('j') + ->touch('j/j.txt') + ->rollback( + $I->taskDeleteDir('j') + ) + ->taskFilesystemStack() + ->mkdir('j/k') + ->touch('j/k/k.txt') + ->taskFilesystemStack() + ->mkdir('j/k/m') + ->touch('j/k/m/m.txt'); + + $result = $I->collectionBuilder() + ->taskFilesystemStack() + ->mkdir('q') + ->touch('q/q.txt') + ->addTask($collection) + ->taskCopyDir(['doesNotExist' => 'copied']) + ->run(); + + $I->assertEquals(1, $result->getExitCode(), $result->getMessage()); + + // All of the tasks created by the builder should be added + // to a collection, and `run()` should run them all. + $I->seeFileFound('q/q.txt'); + $I->dontSeeFileFound('j/j.txt'); + $I->dontSeeFileFound('j/k/k.txt'); + $I->dontSeeFileFound('j/k/m/m.txt'); + } + + public function toCreateDirViaCollection(CliGuy $I) + { + // Set up a collection to add tasks to + $collection = $I->collectionBuilder(); + + // Set up a filesystem stack + $collection->taskFilesystemStack() + ->mkdir('log') + ->touch('log/error.txt'); + + // FilesystemStack has not run yet, so file should not be found. + $I->dontSeeFileFound('log/error.txt'); + + // Run the task collection; now the files should be present + $collection->run(); + $I->seeFileFound('log/error.txt'); + $I->seeDirFound('log'); + } + + public function toUseATmpDirAndConfirmItIsDeleted(CliGuy $I) + { + // Set up a collection to add tasks to + $collection = $I->collectionBuilder(); + + // Get a temporary directory to work in. Note that we get a + // name back, but the directory is not created until the task + // runs. This technically is not thread-safe, but we create + // a random name, so it is unlikely to conflict. + $tmpPath = $collection->tmpDir(); + + // Set up a filesystem stack, but use a collection to defer execution + $collection->taskFilesystemStack() + ->mkdir("$tmpPath/tmp") + ->touch("$tmpPath/tmp/error.txt") + ->rename("$tmpPath/tmp", "$tmpPath/log"); + + // Copy our tmp directory to a location that is not transient + $collection->taskCopyDir([$tmpPath => 'copied']); + + // FilesystemStack has not run yet, so no files should be found. + $I->dontSeeFileFound("$tmpPath/tmp/error.txt"); + $I->dontSeeFileFound("$tmpPath/log/error.txt"); + $I->dontSeeFileFound('copied/log/error.txt'); + + // Run the task collection + $result = $collection->run(); + $I->assertEquals(0, $result->getExitCode(), $result->getMessage()); + $I->assertEquals($result['path'], $tmpPath, "Tmp dir result matches accessor."); + + // The file 'error.txt' should have been copied into the "copied" dir. + // This also proves that the tmp directory was created. + $I->seeFileFound('copied/log/error.txt'); + // $tmpPath should be deleted after $collection->run() completes. + $I->dontSeeFileFound("$tmpPath/tmp/error.txt"); + $I->dontSeeFileFound("$tmpPath/log/error.txt"); + $I->dontSeeFileFound("$tmpPath"); + } + + public function toUseATmpDirAndChangeWorkingDirectory(CliGuy $I) + { + // Set up a collection to add tasks to + $collection = $I->collectionBuilder(); + + $cwd = getcwd(); + + $tmpPath = $collection->taskTmpDir() + ->cwd() + ->getPath(); + + // Set up a filesystem stack, but use a collection to defer execution. + // Note that since we used 'cwd()' above, the relative file paths + // used below will be inside the temporary directory. + $collection->taskFilesystemStack() + ->mkdir("log") + ->touch("log/error.txt"); + + // Copy our tmp directory to a location that is not transient + $collection->taskCopyDir(['log' => "$cwd/copied2"]); + + // FilesystemStack has not run yet, so no files should be found. + $I->dontSeeFileFound("$tmpPath/log/error.txt"); + $I->dontSeeFileFound('$cwd/copied2/log/error.txt'); + + // Run the task collection + $result = $collection->run(); + $I->assertEquals(0, $result->getExitCode(), $result->getMessage()); + + // The file 'error.txt' should have been copied into the "copied" dir + $I->seeFileFound("$cwd/copied2/error.txt"); + // $tmpPath should be deleted after $collection->run() completes. + $I->dontSeeFileFound("$tmpPath/log/error.txt"); + // Make sure that 'log' was created in the temporary directory, not + // at the current working directory. + $I->dontSeeFileFound("$cwd/log/error.txt"); + + // Make sure that our working directory was restored. + $finalWorkingDir = getcwd(); + $I->assertEquals($cwd, $finalWorkingDir); + } + + public function toCreateATmpFileAndConfirmItIsDeleted(CliGuy $I) + { + // Set up a collection to add tasks to + $collection = $I->collectionBuilder(); + + // Write to a temporary file. Note that we can get the path + // to the tempoary file that will be created, even though the + // the file is not created until the task collecction runs. + $tmpPath = $collection->taskTmpFile('tmp', '.txt') + ->line("This is a test file") + ->getPath(); + + // Copy our tmp directory to a location that is not transient + $collection->taskFilesystemStack() + ->copy($tmpPath, 'copied.txt'); + + // FilesystemStack has not run yet, so no files should be found. + $I->dontSeeFileFound("$tmpPath"); + $I->dontSeeFileFound('copied.txt'); + + // Run the task collection + $result = $collection->run(); + $I->assertEquals(0, $result->getExitCode(), $result->getMessage()); + + // The file 'copied.txt' should have been copied from the tmp file + $I->seeFileFound('copied.txt'); + // $tmpPath should be deleted after $collection->run() completes. + $I->dontSeeFileFound("$tmpPath"); + } + + public function toUseATmpDirWithAlternateSyntax(CliGuy $I) + { + $collection = $I->collectionBuilder(); + + // This test is equivalent to toUseATmpDirAndConfirmItIsDeleted, + // but uses a different technique to create a collection of tasks. + $tmpPath = $collection->tmpDir(); + + // Now, rather than creating the tasks with a collection builder, + // which automatically adds the tasks to the collection as they are + // created, we will instead create them individually and then add + // them to the collection via the addTaskList() method. + $result = $collection->addTaskList( + [ + $I->taskFilesystemStack()->mkdir("$tmpPath/log")->touch("$tmpPath/log/error.txt"), + $I->taskCopyDir([$tmpPath => 'copied3']), + ] + )->run(); + + // The results of this operation should be the same. + $I->assertEquals(0, $result->getExitCode(), $result->getMessage()); + $I->seeFileFound('copied3/log/error.txt'); + $I->dontSeeFileFound("$tmpPath/log/error.txt"); + } + + public function toCreateATmpDirWithoutACollection(CliGuy $I) + { + // Create a temporary directory, using our function name as + // the prefix for the directory name. + $tmpDirTask = $I->taskTmpDir(__FUNCTION__); + $tmpPath = $tmpDirTask->getPath(); + $I->dontSeeFileFound($tmpPath); + $tmpDirTask->run(); + $I->seeDirFound($tmpPath); + // Creating a temporary directory without a task collection will + // cause the temporary directory to be deleted when the program + // terminates. We can force it to clean up sooner by calling + // TransientManager::complete(); note that this deletes ALL global tmp + // directories, so this is not thread-safe! Useful in tests, though. + Temporary::complete(); + $I->dontSeeFileFound($tmpPath); + } + + public function toCreateATmpDirUsingShortcut(CliGuy $I) + { + // Create a temporary directory, using our function name as + // the prefix for the directory name. + $tmpPath = $I->shortcutTmpDir(__FUNCTION__); + $I->seeDirFound($tmpPath); + // Creating a temporary directory without a task collection will + // cause the temporary directory to be deleted when the program + // terminates. We can force it to clean up sooner by calling + // TransientManager::complete(); note that this deletes ALL global tmp + // directories, so this is not thread-safe! Useful in tests, though. + Temporary::complete(); + $I->dontSeeFileFound($tmpPath); + } + + public function toThrowAnExceptionAndConfirmItIsCaught(CliGuy $I) + { + $collection = $I->getContainer()->get('collection'); + + $collection->addCode( + function () { + throw new \RuntimeException('Error'); + } + ); + $result = $collection->run(); + $I->assertEquals('Error', $result->getMessage()); + $I->assertEquals(1, $result->getExitCode()); + } +} diff --git a/src/composer/vendor/consolidation/robo/tests/cli/ConcatCept.php b/src/composer/vendor/consolidation/robo/tests/cli/ConcatCept.php new file mode 100644 index 00000000..d68798a5 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/tests/cli/ConcatCept.php @@ -0,0 +1,11 @@ +wantTo('concat files using Concat Task'); +$I->amInPath(codecept_data_dir() . 'sandbox'); +$I->taskConcat(['a.txt', 'b.txt']) + ->to('merged.txt') + ->run(); +$I->seeFileFound('merged.txt'); +$I->seeFileContentsEqual("A\nB\n"); + diff --git a/src/composer/vendor/consolidation/robo/tests/cli/CopyDirCept.php b/src/composer/vendor/consolidation/robo/tests/cli/CopyDirCept.php new file mode 100644 index 00000000..1022ca2b --- /dev/null +++ b/src/composer/vendor/consolidation/robo/tests/cli/CopyDirCept.php @@ -0,0 +1,10 @@ +wantTo('copy dir with CopyDir task'); +$I->amInPath(codecept_data_dir().'sandbox'); +$I->taskCopyDir(['box' => 'bin']) + ->run(); +$I->seeDirFound('bin'); +$I->seeFileFound('robo.txt', 'bin'); + diff --git a/src/composer/vendor/consolidation/robo/tests/cli/CopyDirOverwritesFilesCept.php b/src/composer/vendor/consolidation/robo/tests/cli/CopyDirOverwritesFilesCept.php new file mode 100644 index 00000000..03b02394 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/tests/cli/CopyDirOverwritesFilesCept.php @@ -0,0 +1,12 @@ +wantTo('overwrite a file with CopyDir task'); +$I->amInPath(codecept_data_dir() . 'sandbox'); +$I->seeDirFound('some'); +$I->seeFileFound('existing_file', 'some'); +$I->taskCopyDir(['some' => 'some_destination']) + ->run(); +$I->seeFileFound('existing_file', 'some_destination/deeply'); +$I->openFile('some_destination/deeply/existing_file'); +$I->seeInThisFile('some existing file'); diff --git a/src/composer/vendor/consolidation/robo/tests/cli/CopyDirRecursiveCept.php b/src/composer/vendor/consolidation/robo/tests/cli/CopyDirRecursiveCept.php new file mode 100644 index 00000000..a793faa2 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/tests/cli/CopyDirRecursiveCept.php @@ -0,0 +1,11 @@ +wantTo('copy dir recursively with CopyDir task'); +$I->amInPath(codecept_data_dir() . 'sandbox'); +$I->seeDirFound('some/deeply/nested'); +$I->seeFileFound('structu.re', 'some/deeply/nested'); +$I->taskCopyDir(['some/deeply' => 'some_destination/deeply']) + ->run(); +$I->seeDirFound('some_destination/deeply/nested'); +$I->seeFileFound('structu.re', 'some_destination/deeply/nested'); diff --git a/src/composer/vendor/consolidation/robo/tests/cli/DeleteDirCept.php b/src/composer/vendor/consolidation/robo/tests/cli/DeleteDirCept.php new file mode 100644 index 00000000..ead565ff --- /dev/null +++ b/src/composer/vendor/consolidation/robo/tests/cli/DeleteDirCept.php @@ -0,0 +1,11 @@ +wantTo('delete dir with DeleteDirTask'); +$I->amInPath(codecept_data_dir()); +$I->seeFileFound('robo.txt', 'sandbox'); +$I->taskDeleteDir(['sandbox/box']) + ->run(); +$I->dontSeeFileFound('box', 'sandbox'); +$I->dontSeeFileFound('robo.txt', 'sandbox'); diff --git a/src/composer/vendor/consolidation/robo/tests/cli/ExecCest.php b/src/composer/vendor/consolidation/robo/tests/cli/ExecCest.php new file mode 100644 index 00000000..b8769246 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/tests/cli/ExecCest.php @@ -0,0 +1,13 @@ +taskExec($command)->run(); + verify($res->getMessage())->contains('src'); + verify($res->getMessage())->contains('codeception.yml'); + } +} diff --git a/src/composer/vendor/consolidation/robo/tests/cli/FilesystemStackCest.php b/src/composer/vendor/consolidation/robo/tests/cli/FilesystemStackCest.php new file mode 100644 index 00000000..b9e68043 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/tests/cli/FilesystemStackCest.php @@ -0,0 +1,50 @@ +amInPath(codecept_data_dir().'sandbox'); + } + + public function toCreateDir(CliGuy $I) + { + $I->taskFilesystemStack() + ->mkdir('log') + ->touch('log/error.txt') + ->run(); + $I->seeFileFound('log/error.txt'); + } + + public function toDeleteFile(CliGuy $I) + { + $I->taskFilesystemStack() + ->stopOnFail() + ->remove('a.txt') + ->run(); + $I->dontSeeFileFound('a.txt'); + } + + public function toTestCrossVolumeRename(CliGuy $I) + { + $fsStack = $I->taskFilesystemStack() + ->mkdir('log') + ->touch('log/error.txt'); + $fsStack->run(); + + // We can't force _rename to run the cross-volume + // code path, so we will directly call the protected + // method crossVolumeRename to test to ensure it works. + // We will get a reference to it via reflection, set + // the reflected method object to public, and then + // call it via reflection. + $class = new ReflectionClass('\Robo\Task\Filesystem\FilesystemStack'); + $method = $class->getMethod('crossVolumeRename'); + $method->setAccessible(true); + $actualFsStackTask = $fsStack->getCollectionBuilderCurrentTask(); + $method->invokeArgs($actualFsStackTask, ['log', 'logfiles']); + + $I->dontSeeFileFound('log/error.txt'); + $I->seeFileFound('logfiles/error.txt'); + } +} diff --git a/src/composer/vendor/consolidation/robo/tests/cli/FlattenDirCept.php b/src/composer/vendor/consolidation/robo/tests/cli/FlattenDirCept.php new file mode 100644 index 00000000..fbb27a56 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/tests/cli/FlattenDirCept.php @@ -0,0 +1,14 @@ +wantTo('flatten dir with FlattenDir task'); +$I->amInPath(codecept_data_dir().'sandbox'); +$I->taskFlattenDir([ + 'some/deeply/nested/*.re' => 'flattened', + '*.txt' => 'flattened' + ]) + ->run(); +$I->seeDirFound('flattened'); +$I->seeFileFound('structu.re', 'flattened'); +$I->seeFileFound('a.txt', 'flattened'); +$I->seeFileFound('b.txt', 'flattened'); diff --git a/src/composer/vendor/consolidation/robo/tests/cli/FlattenDirParentsCept.php b/src/composer/vendor/consolidation/robo/tests/cli/FlattenDirParentsCept.php new file mode 100644 index 00000000..d1d0504d --- /dev/null +++ b/src/composer/vendor/consolidation/robo/tests/cli/FlattenDirParentsCept.php @@ -0,0 +1,12 @@ +wantTo('flatten dir with FlattenDir task including parents'); +$I->amInPath(codecept_data_dir().'sandbox'); +$I->taskFlattenDir('some/deeply/nested/*.re') + ->includeParents(array(1,1)) + ->parentDir('some') + ->to('flattened') + ->run(); +$I->seeDirFound('flattened/deeply/nested'); +$I->seeFileFound('structu.re', 'flattened/deeply/nested'); diff --git a/src/composer/vendor/consolidation/robo/tests/cli/GenTaskCest.php b/src/composer/vendor/consolidation/robo/tests/cli/GenTaskCest.php new file mode 100644 index 00000000..ce892874 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/tests/cli/GenTaskCest.php @@ -0,0 +1,11 @@ +taskGenTask('Symfony\Component\Filesystem\Filesystem', 'FilesystemStack')->run(); + verify($result->getMessage())->contains('protected function _chgrp($files, $group, $recursive = false)'); + } +} diff --git a/src/composer/vendor/consolidation/robo/tests/cli/GenerateMarkdownDocCest.php b/src/composer/vendor/consolidation/robo/tests/cli/GenerateMarkdownDocCest.php new file mode 100644 index 00000000..de2b40e4 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/tests/cli/GenerateMarkdownDocCest.php @@ -0,0 +1,86 @@ +amInPath(codecept_data_dir().'sandbox'); + } + + public function toGenerateDocumentation(CliGuy $I) + { + $sourceFile = codecept_data_dir() . 'TestedRoboTask.php'; + $I->seeFileFound($sourceFile); + include $sourceFile; + $I->assertTrue(class_exists('TestedRoboTask')); + + $collection = $I->collectionBuilder(); + $taskGenerator = $collection->taskGenDoc("TestedRoboTask.md"); + $taskGenerator->filterClasses(function (\ReflectionClass $r) { + return !($r->isAbstract() || $r->isTrait()) && $r->implementsInterface('Robo\Contract\TaskInterface'); + })->prepend("# TestedRoboTask Tasks"); + $taskGenerator->docClass('TestedRoboTask'); + + $taskGenerator->filterMethods( + function (\ReflectionMethod $m) { + if ($m->isConstructor() || $m->isDestructor() || $m->isStatic()) { + return false; + } + $undocumentedMethods = + [ + '', + 'run', + '__call', + 'inflect', + 'injectDependencies', + 'getCommand', + 'getPrinted', + 'getConfig', + 'setConfig', + 'logger', + 'setLogger', + 'setProgressIndicator', + 'progressIndicatorSteps', + 'setBuilder', + 'getBuilder', + 'collectionBuilder', + ]; + return !in_array($m->name, $undocumentedMethods) && $m->isPublic(); // methods are not documented + } + )->processClassSignature( + function ($c) { + return "## " . preg_replace('~Task$~', '', $c->getShortName()) . "\n"; + } + )->processClassDocBlock( + function (\ReflectionClass $c, $doc) { + $doc = preg_replace('~@method .*?(.*?)\)~', '* `$1)` ', $doc); + $doc = str_replace('\\'.$c->name, '', $doc); + return $doc; + } + )->processMethodSignature( + function (\ReflectionMethod $m, $text) { + return str_replace('#### *public* ', '* `', $text) . '`'; + } + )->processMethodDocBlock( + function (\ReflectionMethod $m, $text) { + + return $text ? ' ' . trim(strtok($text, "\n"), "\n") : ''; + } + ); + + $collection->run(); + $I->seeFileFound('TestedRoboTask.md'); + + $contents = file_get_contents('TestedRoboTask.md'); + $I->assertContains('A test task file. Used for testig documentation generation.', $contents); + $I->assertContains('taskTestedRoboTask', $contents); + $I->assertContains('Set the destination file', $contents); + } +} diff --git a/src/composer/vendor/consolidation/robo/tests/cli/PackExtractCept.php b/src/composer/vendor/consolidation/robo/tests/cli/PackExtractCept.php new file mode 100644 index 00000000..a280c0cb --- /dev/null +++ b/src/composer/vendor/consolidation/robo/tests/cli/PackExtractCept.php @@ -0,0 +1,57 @@ +wantTo('archive directory and then extract it again with Archive and Extract tasks'); +$I->amInPath(codecept_data_dir().'sandbox'); +$I->seeDirFound('some/deeply/nested'); +$I->seeFileFound('structu.re', 'some/deeply/nested'); +$I->seeFileFound('existing_file', 'some/deeply'); + +// Test a bunch of archive types that we support +foreach (['zip', 'tar', 'tar.gz', 'tar.bz2', 'tgz'] as $archiveType) { + // First, take everything from the folder 'some/deeply' and make + // an archive for it located in 'deep' + $I->taskPack("deeply.$archiveType") + ->add(['deep' => 'some/deeply']) + ->run(); + $I->seeFileFound("deeply.$archiveType"); + // We are next going to extract the archive we created, this time + // putting it into a folder called "extracted-$archiveType" (different + // for each archive type we test). We rely on the default behavior + // of our extractor to remove the top-level directory in the archive + // ("deeply"). + $I->taskExtract("deeply.$archiveType") + ->to("extracted-$archiveType") + ->preserveTopDirectory(false) // this is the default + ->run(); + $I->seeDirFound("extracted-$archiveType"); + $I->seeDirFound("extracted-$archiveType/nested"); + $I->seeFileFound('structu.re', "extracted-$archiveType/nested"); + // Next, we'll extract the same archive again, this time preserving + // the top-level folder. + $I->taskExtract("deeply.$archiveType") + ->to("preserved-$archiveType") + ->preserveTopDirectory() + ->run(); + $I->seeDirFound("preserved-$archiveType"); + $I->seeDirFound("preserved-$archiveType/deep/nested"); + $I->seeFileFound('structu.re', "preserved-$archiveType/deep/nested"); + // Make another archive, this time composed of fanciful locations + $I->taskPack("composed.$archiveType") + ->add(['a/b/existing_file' => 'some/deeply/existing_file']) + ->add(['x/y/z/structu.re' => 'some/deeply/nested/structu.re']) + ->run(); + $I->seeFileFound("composed.$archiveType"); + // Extract our composed archive, and see if the resulting file + // structure matches expectations. + $I->taskExtract("composed.$archiveType") + ->to("decomposed-$archiveType") + ->preserveTopDirectory() + ->run(); + $I->seeDirFound("decomposed-$archiveType"); + $I->seeDirFound("decomposed-$archiveType/x/y/z"); + $I->seeFileFound('structu.re', "decomposed-$archiveType/x/y/z"); + $I->seeDirFound("decomposed-$archiveType/a/b"); + $I->seeFileFound('existing_file', "decomposed-$archiveType/a/b"); +} diff --git a/src/composer/vendor/consolidation/robo/tests/cli/ShortcutsCest.php b/src/composer/vendor/consolidation/robo/tests/cli/ShortcutsCest.php new file mode 100644 index 00000000..addfb27c --- /dev/null +++ b/src/composer/vendor/consolidation/robo/tests/cli/ShortcutsCest.php @@ -0,0 +1,25 @@ +amInPath(codecept_data_dir('sandbox')); + } + + public function useTheCopyDirShortcut(CliGuy $I) + { + $I->wantTo('copy dir with _copyDir shortcut'); + $I->shortcutCopyDir('box', 'bin'); + $I->seeDirFound('bin'); + $I->seeFileFound('robo.txt', 'bin'); + } + + public function useTheMirrorDirShortcut(CliGuy $I) + { + $I->wantTo('mirror dir with _mirrorDir shortcut'); + $I->shortcutMirrorDir('box', 'bin'); + $I->seeDirFound('bin'); + $I->seeFileFound('robo.txt', 'bin'); + } +} diff --git a/src/composer/vendor/consolidation/robo/tests/cli/SimulatedCest.php b/src/composer/vendor/consolidation/robo/tests/cli/SimulatedCest.php new file mode 100644 index 00000000..fde6cc79 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/tests/cli/SimulatedCest.php @@ -0,0 +1,34 @@ +amInPath(codecept_data_dir().'sandbox'); + } + + public function toSimulateDirCreation(CliGuy $I) + { + // Set up a collection to add tasks to + $collection = $I->collectionBuilder(); + $collection->simulated(true); + + // Set up a filesystem stack + $collection->taskFilesystemStack() + ->mkdir('simulatedir') + ->touch('simulatedir/error.txt'); + + // Run the task collection; now the files should be present + $collection->run(); + // Nothing should be created in simulated mode + $I->dontSeeFileFound('simulatedir/error.txt'); + $I->seeInOutput('[Simulator] Simulating Filesystem\FilesystemStack()'); + } +} diff --git a/src/composer/vendor/consolidation/robo/tests/cli/WriteFileCest.php b/src/composer/vendor/consolidation/robo/tests/cli/WriteFileCest.php new file mode 100644 index 00000000..b9ede453 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/tests/cli/WriteFileCest.php @@ -0,0 +1,111 @@ +amInPath(codecept_data_dir('sandbox')); + } + + public function writeFewLines(CliGuy $I) + { + $I->wantTo('write lines with WriteToFile task'); + $I->taskWriteToFile('blogpost.md') + ->line('****') + ->line('hello world') + ->line('****') + ->run(); + $I->seeFileFound('blogpost.md'); + $I->seeFileContentsEqual(<<taskWriteToFile('a.txt') + ->append() + ->line('hello world') + ->run(); + $I->seeFileFound('a.txt'); + $I->seeFileContentsEqual(<<taskWriteToFile('a.txt') + ->append(); + $I->assertEquals(false, $writeTask->wouldChange(), "No changes to test file."); + $writeTask->line('hello world'); + $I->assertEquals(true, $writeTask->wouldChange(), "Test file would change."); + } + + public function insertFile(CliGuy $I) + { + $I->taskWriteToFile('a.txt') + ->line('****') + ->textFromFile('b.txt') + ->line("C") + ->run(); + $I->seeFileFound('a.txt'); + $I->seeFileContentsEqual(<<wantTo('append lines with WriteToFile task, but only if pattern does not match'); + $I->taskWriteToFile('blogpost.md') + ->line('****') + ->line('hello world') + ->line('****') + ->appendUnlessMatches('/hello/', 'Should not add this') + ->appendUnlessMatches('/goodbye/', 'Should add this') + ->appendIfMatches('/hello/', ' and should also add this') + ->appendIfMatches('/goodbye/', ' but should not add this') + ->appendIfMatches('/should/', '!') + ->run(); + $I->seeFileFound('blogpost.md'); + $I->seeFileContentsEqual(<<taskReplaceInFile('a.txt') + ->from('A') + ->to('B') + ->run(); + $I->seeFileFound('a.txt'); + $I->seeFileContentsEqual('B'); + + } + + public function replaceMultipleInFile(CliGuy $I) + { + $I->taskReplaceInFile('box/robo.txt') + ->from(array('HELLO', 'ROBO')) + ->to(array('Hello ', 'robo.li!')) + ->run(); + $I->seeFileFound('box/robo.txt'); + $I->seeFileContentsEqual('Hello robo.li!'); + } +} + diff --git a/src/composer/vendor/consolidation/robo/tests/cli/_bootstrap.php b/src/composer/vendor/consolidation/robo/tests/cli/_bootstrap.php new file mode 100644 index 00000000..c481d9b4 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/tests/cli/_bootstrap.php @@ -0,0 +1,9 @@ +say("The parameters passed are:\n" . var_export($a, true)); + } + + /** + * Demonstrate use of SymfonyStyle + */ + public function testSymfonyStyle() + { + $this->io()->title('My Title'); + $this->io()->section('Section 1'); + $this->io()->text('Some text in section one.'); + $this->io()->comment('This is just an example of different styles.'); + $this->io()->section('Section 2'); + $this->io()->text('Some text in section two.'); + } + + /** + * @hook command-event test:command-event + */ + public function hookCommandEvent() + { + $this->io()->text('This is the command-event hook for the test:command-event command.'); + } + + public function testCommandEvent() + { + $this->io()->text('This is the main method for the test:command-event command.'); + } + + /** + * @hook post-command test:command-event + */ + public function hookPostCommand() + { + $this->io()->text('This is the post-command hook for the test:command-event command.'); + } + + /** + * Demonstrate Robo error output and command failure. + */ + public function testError() + { + return $this->taskExec('ls xyzzy' . date('U'))->dir('/tmp')->run(); + } + + /** + * Demonstrate what happens when a command or a task + * throws an exception. Note that typically, Robo commands + * should return Result objects rather than throw exceptions. + */ + public function testException($options = ['task' => false]) + { + if (!$options['task']) { + throw new \RuntimeException('Command failed with an exception.'); + } + throw new \RuntimeException('Task failed with an exception.'); + } + + public function testStopOnFail() + { + $this->stopOnFail(); + $this->collectionBuilder() + ->taskExec('ls xyzzy' . date('U')) + ->dir('/tmp') + ->run(); + + // stopOnFail() should cause the failed task to throw an exception, + // so we should not get here, and instead exit the program with a + // non-zero status. + return 0; + } + + public function testVerbosity() + { + $this->output()->writeln('This command will print more information at higher verbosity levels.'); + $this->output()->writeln('Try running with -v, -vv or -vvv'); + $this->output()->writeln('The current verbosity level is ' . $this->output()->getVerbosity()); + $this->output()->writeln('This is a verbose message (-v).', OutputInterface::VERBOSITY_VERBOSE); + $this->output()->writeln('This is a very verbose message (-vv).', OutputInterface::VERBOSITY_VERY_VERBOSE); + $this->output()->writeln('This is a debug message (-vvv).', OutputInterface::VERBOSITY_DEBUG); + $this->logger->warning('This is a warning log message.'); + $this->logger->notice('This is a notice log message.'); + $this->logger->debug('This is a debug log message.'); + } + + public function testDeploy() + { + $gitTask = $this->taskGitStack() + ->pull(); + + $this->taskSshExec('mysite.com') + ->remoteDir('/var/www/somesite') + ->exec($gitTask) + ->run(); + } +} diff --git a/src/composer/vendor/consolidation/robo/tests/src/Traits/Common/CommandArgumentsHost.php b/src/composer/vendor/consolidation/robo/tests/src/Traits/Common/CommandArgumentsHost.php new file mode 100644 index 00000000..363764dc --- /dev/null +++ b/src/composer/vendor/consolidation/robo/tests/src/Traits/Common/CommandArgumentsHost.php @@ -0,0 +1,18 @@ +arguments; + } +} diff --git a/src/composer/vendor/consolidation/robo/tests/unit.suite.yml b/src/composer/vendor/consolidation/robo/tests/unit.suite.yml new file mode 100644 index 00000000..bb94af02 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/tests/unit.suite.yml @@ -0,0 +1,8 @@ +# Codeception Test Suite Configuration + +# suite for unit (internal) tests. +# RUN `build` COMMAND AFTER ADDING/REMOVING MODULES. + +class_name: CodeGuy +modules: + enabled: [Asserts, CodeHelper] diff --git a/src/composer/vendor/consolidation/robo/tests/unit/ApplicationTest.php b/src/composer/vendor/consolidation/robo/tests/unit/ApplicationTest.php new file mode 100644 index 00000000..bdb6c90a --- /dev/null +++ b/src/composer/vendor/consolidation/robo/tests/unit/ApplicationTest.php @@ -0,0 +1,140 @@ +app = $container->get('application'); + $config = $container->get('config'); + $this->commandFactory = $container->get('commandFactory'); + $this->roboCommandFileInstance = new TestedRoboFile; + $builder = $container->get('collectionBuilder', [$this->roboCommandFileInstance]); + $this->roboCommandFileInstance->setBuilder($builder); + $commandList = $this->commandFactory->createCommandsFromClass($this->roboCommandFileInstance); + foreach ($commandList as $command) { + $this->app->add($command); + } + } + + public function testTaskAccessor() + { + // Get a reference to the protected 'task' method, as + // this is normally only callable by methods of the + // commandfile instance. + $method = new ReflectionMethod($this->roboCommandFileInstance, 'task'); + $method->setAccessible(true); + $collectionBuilder = $method->invoke($this->roboCommandFileInstance, 'Robo\Task\Base\Exec', ['ls']); + verify(get_class($collectionBuilder))->equals('Robo\Collection\CollectionBuilder'); + $task = $collectionBuilder->getCollectionBuilderCurrentTask(); + verify(get_class($task))->equals('Robo\Task\Base\Exec'); + verify(get_class($task))->equals('Robo\Task\Base\Exec'); + } + + public function testAllowEmptyValuesAsDefaultsToOptionalOptions() + { + $command = $this->createCommand('hello'); + + $yell = $command->getDefinition()->getOption('yell'); + + verify($yell->isValueOptional()) + ->equals(false); + verify($yell->getDefault()) + ->equals(false); + + $to = $command->getDefinition()->getOption('to'); + + verify($to->isValueOptional()) + ->equals(true); + verify($to->getDefault()) + ->equals(null); + } + + public function testCommandDocumentation() + { + $command = $this->createCommand('fibonacci'); + + verify($command->getDescription()) + ->equals('Calculate the fibonacci sequence between two numbers.'); + } + + public function testCommandCompactDocumentation() + { + $command = $this->createCommand('compact'); + + verify($command->getDescription()) + ->equals('Compact doc comment'); + } + + public function testCommandArgumentDocumentation() + { + $command = $this->createCommand('fibonacci'); + + $start = $command->getDefinition()->getArgument('start'); + + verify($start->getDescription()) + ->equals('Number to start from'); + + $steps = $command->getDefinition()->getArgument('steps'); + + verify($steps->getDescription()) + ->equals('Number of steps to perform'); + } + + public function testCommandOptionDocumentation() + { + $command = $this->createCommand('fibonacci'); + + $graphic = $command->getDefinition()->getOption('graphic'); + + verify($graphic->getDescription()) + ->equals('Display the sequence graphically using cube representation'); + } + + public function testCommandHelpDocumentation() + { + $command = $this->createCommand('fibonacci'); + + verify($command->getHelp()) + ->contains('+----+---+'); + } + + public function testCommandNaming() + { + $this->assertNotNull($this->app->find('generate:user-avatar')); + } + + protected function createCommand($name) + { + $commandInfo = new CommandInfo($this->roboCommandFileInstance, $name); + return $this->commandFactory->createCommand($commandInfo, $this->roboCommandFileInstance); + } +} diff --git a/src/composer/vendor/consolidation/robo/tests/unit/Common/CommandArgumentsTest.php b/src/composer/vendor/consolidation/robo/tests/unit/Common/CommandArgumentsTest.php new file mode 100644 index 00000000..c30672f1 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/tests/unit/Common/CommandArgumentsTest.php @@ -0,0 +1,86 @@ + [ + ' ', + [], + ], + 'empty string' => [ + " ''", + [''], + ], + 'space' => [ + " ' '", + [' '], + ], + 'no escape - a' => [ + " a", + ['a'], + ], + 'no escape - A' => [ + " A", + ['A'], + ], + 'no escape - 0' => [ + " 0", + ['0'], + ], + 'no escape - --' => [ + " --", + ['--'], + ], + 'no escape - @_~.' => [ + " @_~.", + ['@_~.'], + ], + '$' => [ + " 'a\$b'", + ['a$b'], + ], + '*' => [ + " 'a*b'", + ['a*b'], + ], + 'multi' => [ + " '' a '\$PATH'", + ['', 'a', '$PATH'], + ], + ]; + } + + /** + * @dataProvider casesArgs + * + * @covers ::args + * + * @param string $expected + * @param array $args + */ + public function testArgs($expected, $args) + { + $commandArguments = new CommandArgumentsHost(); + $commandArguments->args($args); + $this->guy->assertEquals($expected, $commandArguments->getArguments()); + + if ($args) { + $commandArguments = new CommandArgumentsHost(); + call_user_func_array([$commandArguments, 'args'], $args); + $this->guy->assertEquals($expected, $commandArguments->getArguments()); + } + } +} diff --git a/src/composer/vendor/consolidation/robo/tests/unit/Common/ResourceExistenceChecker.php b/src/composer/vendor/consolidation/robo/tests/unit/Common/ResourceExistenceChecker.php new file mode 100644 index 00000000..e45f1df0 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/tests/unit/Common/ResourceExistenceChecker.php @@ -0,0 +1,80 @@ +apigen = test::double('Robo\Task\ApiGen\ApiGen', [ + 'executeCommand' => null, + 'output' => new \Symfony\Component\Console\Output\NullOutput() + ]); + if (!defined('DS')) { + define('DS', DIRECTORY_SEPARATOR); + } + $this->testDir = __DIR__ . '..' . DS . '..' . DS . 'data' . DS; + $this->testFile = $this->testDir . 'dump.sql'; + } + + /** + * testCheckResources + */ + public function testCheckResources() + { + $this->assertTrue($this->checkResources($this->testDir, 'dir')); + $this->assertTrue($this->checkResources([ + $this->testDir, + $this->testFile + ])); + } + + /** + * @expectException \InvalidArgumentException + */ + public function testCheckResourcesException() + { + $this->checkResources('does not exist', 'invalid type'); + } + + /** + * testCheckResource + */ + public function testCheckResource() + { + $this->assertTrue($this->checkResource($this->testDir, 'dir')); + $this->assertTrue($this->checkResource($this->testDir, 'fileAndDir')); + $this->assertTrue($this->checkResource($this->testFile, 'file')); + $this->assertTrue($this->checkResource($this->testFile, 'fileAndDir')); + + $this->assertFalse($this->checkResource('does-not-exist', 'dir')); + $this->assertFalse($this->checkResource('does-not-exist', 'fileAndDir')); + $this->assertFalse($this->checkResource('does-not-exist', 'file')); + $this->assertFalse($this->checkResource('does-not-exist', 'fileAndDir')); + } + + /** + * testIsDir + */ + public function testIsDir() + { + $this->assertTrue($this->isDir($this->testDir)); + $this->assertFalse($this->isDir('does-not-exist')); + } + + /** + * testIsFile + */ + public function testIsFile() + { + $this->assertTrue($this->isFile($this->testFile)); + $this->assertFalse($this->isFile($this->testDir . 'does-not-exist')); + } +} diff --git a/src/composer/vendor/consolidation/robo/tests/unit/ConfigurationTest.php b/src/composer/vendor/consolidation/robo/tests/unit/ConfigurationTest.php new file mode 100644 index 00000000..7c29ea4f --- /dev/null +++ b/src/composer/vendor/consolidation/robo/tests/unit/ConfigurationTest.php @@ -0,0 +1,40 @@ +setConfig(Robo::config()); + verify($taskA->run())->equals('value-a'); + + $taskB = new ConfigurationTestTaskB(); + $taskB->setConfig(Robo::config()); + verify($taskB->run())->equals('value-b'); + } + +} + +class ConfigurationTestTaskA extends BaseTask +{ + public function run() + { + return $this->getConfigValue('key'); + } +} + +class ConfigurationTestTaskB extends BaseTask +{ + public function run() + { + return $this->getConfigValue('key'); + } +} diff --git a/src/composer/vendor/consolidation/robo/tests/unit/OutputTest.php b/src/composer/vendor/consolidation/robo/tests/unit/OutputTest.php new file mode 100644 index 00000000..0e1468d6 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/tests/unit/OutputTest.php @@ -0,0 +1,81 @@ +dialog = new Symfony\Component\Console\Helper\QuestionHelper; + $this->setOutput(Robo::service('output')); + } + + public function testSay() + { + $this->say('Hello, world!'); + $this->guy->seeInOutput('> Hello, world!'); + } + + public function testAskReply() + { + $this->expectedAnswer = 'jon'; + verify($this->ask('What is your name?'))->equals('jon'); + $this->guy->seeOutputEquals('? What is your name? '); + } + public function testAskMethod() + { + if (method_exists($this, 'createMock')) { + $this->dialog = $this->createMock('\Symfony\Component\Console\Helper\QuestionHelper', ['ask']); + } else { + $this->dialog = $this->getMock('\Symfony\Component\Console\Helper\QuestionHelper', ['ask']); + } + $this->dialog->expects($this->once()) + ->method('ask'); + $this->ask('What is your name?'); + } + public function testAskHiddenMethod() + { + if (method_exists($this, 'createMock')) { + $this->dialog = $this->createMock('\Symfony\Component\Console\Helper\QuestionHelper', ['ask']); + } else { + $this->dialog = $this->getMock('\Symfony\Component\Console\Helper\QuestionHelper', ['ask']); + } + $this->dialog->expects($this->once()) + ->method('ask'); + $this->ask('What is your name?', true); + } + public function testYell() + { + $this->yell('Buuuu!'); + $this->guy->seeInOutput('Buuuu!'); + } + protected function getDialog() + { + $stream = fopen('php://memory', 'r+', false); + fputs($stream, $this->expectedAnswer); + rewind($stream); + $this->dialog->setInputStream($stream); + return $this->dialog; + } + +} diff --git a/src/composer/vendor/consolidation/robo/tests/unit/ResultTest.php b/src/composer/vendor/consolidation/robo/tests/unit/ResultTest.php new file mode 100644 index 00000000..02fc322e --- /dev/null +++ b/src/composer/vendor/consolidation/robo/tests/unit/ResultTest.php @@ -0,0 +1,79 @@ + 10]); + + $this->guy->seeInOutput('The foo barred'); + $this->guy->seeInOutput('Exit code 1'); + $this->guy->seeInOutput('10s'); + $this->guy->seeInOutput('[ResultDummyTask]'); + + $this->assertSame($task, $result->getTask()); + $this->assertEquals(1, $result->getExitCode()); + $this->assertEquals('The foo barred', $result->getMessage()); + $data = $result->getData(); + $this->assertEquals(10, $data['time']); + + $taskClone = $result->cloneTask(); + $this->assertNotSame($task, $taskClone); + $this->assertInstanceOf('Robo\Contract\TaskInterface', $taskClone); + } + + public function testArrayAccess() + { + $task = new ResultDummyTask(); + $result = new Result($task, 1, 'The foo barred', ['time' => 10]); + $this->assertEquals($result['time'], 10); + } + + public function testStopOnFail() + { + $exceptionClass = false; + $task = new ResultDummyTask(); + + Result::$stopOnFail = true; + $result = Result::success($task, "Something that worked"); + try { + $result = Result::error($task, "Something that did not work"); + // stopOnFail will cause Result::error() to throw an exception, + // so we will never get here. If we did, the assert below would fail. + $this->assertTrue($result->wasSuccessful()); + $this->assertTrue(false); + } catch (\Exception $e) { + $exceptionClass = get_class($e); + } + $this->assertEquals(TaskExitException::class, $exceptionClass); + $this->assertTrue($result->wasSuccessful()); + + /* + // This gives an error: + // Exception of class Robo\Exception\TaskExitException expected to + // be thrown, but PHPUnit_Framework_Exception caught + // This happens whether or not the expected exception is thrown + $this->guy->expectException(TaskExitException::class, function() { + // $result = Result::error($task, "Something that did not work"); + $result = Result::success($task, "Something that worked"); + }); + */ + + Result::$stopOnFail = false; + } +} + +class ResultDummyTask implements \Robo\Contract\TaskInterface +{ + public function run() + { + } +} diff --git a/src/composer/vendor/consolidation/robo/tests/unit/RunnerTest.php b/src/composer/vendor/consolidation/robo/tests/unit/RunnerTest.php new file mode 100644 index 00000000..9a871c93 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/tests/unit/RunnerTest.php @@ -0,0 +1,279 @@ +runner = new \Robo\Runner('\Robo\RoboFileFixture'); + } + + public function testHandleError() + { + $tmpLevel = error_reporting(); + + $this->assertFalse($this->runner->handleError()); + error_reporting(0); + $this->assertTrue($this->runner->handleError()); + + error_reporting($tmpLevel); + } + + public function testErrorIsHandled() + { + $tmpLevel = error_reporting(); + + // Set error_get_last to a known state. Note that it can never be + // reset; see http://php.net/manual/en/function.error-get-last.php + @trigger_error('control'); + $error_description = error_get_last(); + $this->assertEquals('control', $error_description['message']); + @trigger_error(''); + $error_description = error_get_last(); + $this->assertEquals('', $error_description['message']); + + // Set error_reporting to a non-zero value. In this instance, + // 'trigger_error' would abort our test script, so we use + // @trigger_error so that execution will continue. With our + // error handler in place, the value of error_get_last() does + // not change. + error_reporting(E_USER_ERROR); + set_error_handler(array($this->runner, 'handleError')); + @trigger_error('test error', E_USER_ERROR); + $error_description = error_get_last(); + $this->assertEquals('', $error_description['message']); + + // Set error_reporting to zero. Now, even 'trigger_error' + // does not abort execution. The value of error_get_last() + // still does not change. + error_reporting(0); + trigger_error('test error 2', E_USER_ERROR); + $error_description = error_get_last(); + $this->assertEquals('', $error_description['message']); + + error_reporting($tmpLevel); + } + + public function testThrowsExceptionWhenNoContainerAvailable() + { + \PHPUnit_Framework_TestCase::setExpectedExceptionRegExp( + '\RuntimeException', + '/container is not initialized yet.*/' + ); + Robo::unsetContainer(); + Robo::getContainer(); + } + + public function testRunnerNoSuchCommand() + { + $argv = ['placeholder', 'no-such-command']; + $this->runner->execute($argv, null, null, $this->guy->capturedOutputStream()); + $this->guy->seeInOutput('Command "no-such-command" is not defined.'); + } + + public function testRunnerList() + { + $argv = ['placeholder', 'list']; + $this->runner->execute($argv, null, null, $this->guy->capturedOutputStream()); + $this->guy->seeInOutput('test:array-args'); + } + + public function testRunnerTryArgs() + { + $argv = ['placeholder', 'test:array-args', 'a', 'b', 'c']; + $this->runner->execute($argv, null, null, $this->guy->capturedOutputStream()); + + $expected = << The parameters passed are: +array ( + 0 => 'a', + 1 => 'b', + 2 => 'c', +) + +EOT; + $this->guy->seeOutputEquals($expected); + } + + public function testSymfonyStyle() + { + $argv = ['placeholder', 'test:symfony-style']; + $this->runner->execute($argv, null, null, $this->guy->capturedOutputStream()); + $this->guy->seeInOutput('Some text in section one.'); + } + + public function testCommandEventHook() + { + $argv = ['placeholder', 'test:command-event']; + $this->runner->execute($argv, null, null, $this->guy->capturedOutputStream()); + + $expected = <<guy->seeInOutput($expected); + } + + public function testRoboStaticRunMethod() + { + $argv = ['placeholder', 'test:symfony-style']; + $commandFiles = ['\Robo\RoboFileFixture']; + Robo::run($argv, $commandFiles, 'MyApp', '1.2.3', $this->guy->capturedOutputStream()); + $this->guy->seeInOutput('Some text in section one.'); + } + + public function testDeploy() + { + $argv = ['placeholder', 'test:deploy', '--simulate']; + $this->runner->execute($argv, null, null, $this->guy->capturedOutputStream()); + $this->guy->seeInOutput('[Simulator] Simulating Remote\\Ssh(\'mysite.com\', null)'); + $this->guy->seeInOutput('[Simulator] Running ssh mysite.com \'cd "/var/www/somesite" && git pull\''); + } + + public function testRunnerTryError() + { + $argv = ['placeholder', 'test:error']; + $result = $this->runner->execute($argv, null, null, $this->guy->capturedOutputStream()); + + $this->guy->seeInOutput('[Exec] Running ls xyzzy'); + $this->assertTrue($result > 0); + } + + public function testRunnerTrySimulatedError() + { + $argv = ['placeholder', 'test:error', '--simulate']; + $result = $this->runner->execute($argv, null, null, $this->guy->capturedOutputStream()); + + $this->guy->seeInOutput('Simulating Exec'); + $this->assertEquals(0, $result); + } + + public function testRunnerTryException() + { + $argv = ['placeholder', 'test:exception', '--task']; + $result = $this->runner->execute($argv, null, null, $this->guy->capturedOutputStream()); + + $this->guy->seeInOutput('Task failed with an exception'); + $this->assertEquals(1, $result); + } + + public function testInitCommand() + { + $container = \Robo\Robo::getContainer(); + $app = $container->get('application'); + $app->addInitRoboFileCommand(getcwd() . '/testRoboFile.php', 'RoboTestClass'); + + $argv = ['placeholder', 'init']; + $status = $this->runner->run($argv, $this->guy->capturedOutputStream(), $app); + $this->guy->seeInOutput('testRoboFile.php will be created in the current directory'); + $this->assertEquals(0, $status); + + $this->assertTrue(file_exists('testRoboFile.php')); + $commandContents = file_get_contents('testRoboFile.php'); + unlink('testRoboFile.php'); + $this->assertContains('class RoboTestClass', $commandContents); + } + + public function testTasksStopOnFail() + { + $argv = ['placeholder', 'test:stop-on-fail']; + $result = $this->runner->execute($argv, null, null, $this->guy->capturedOutputStream()); + + $this->guy->seeInOutput('['); + $this->assertTrue($result > 0); + } + + public function testInvalidRoboDirectory() + { + $runnerWithNoRoboFile = new \Robo\Runner(); + + $argv = ['placeholder', 'list', '-f', 'no-such-directory']; + $result = $runnerWithNoRoboFile->execute($argv, null, null, $this->guy->capturedOutputStream()); + + $this->guy->seeInOutput('Path `no-such-directory` is invalid; please provide a valid absolute path to the Robofile to load.'); + } + + public function testUnloadableRoboFile() + { + $runnerWithNoRoboFile = new \Robo\Runner(); + + $argv = ['placeholder', 'list', '-f', dirname(__DIR__) . '/src/RoboFileFixture.php']; + $result = $runnerWithNoRoboFile->execute($argv, null, null, $this->guy->capturedOutputStream()); + + // We cannot load RoboFileFixture.php via -f / --load-from because + // it has a namespace, and --load-from does not support that. + $this->guy->seeInOutput('Class RoboFileFixture was not loaded'); + } + + public function testRunnerQuietOutput() + { + $argv = ['placeholder', 'test:verbosity', '--quiet']; + $result = $this->runner->execute($argv, null, null, $this->guy->capturedOutputStream()); + + $this->guy->doNotSeeInOutput('This command will print more information at higher verbosity levels'); + $this->guy->doNotSeeInOutput('This is a verbose message (-v).'); + $this->guy->doNotSeeInOutput('This is a very verbose message (-vv).'); + $this->guy->doNotSeeInOutput('This is a debug message (-vvv).'); + $this->guy->doNotSeeInOutput(' [warning] This is a warning log message.'); + $this->guy->doNotSeeInOutput(' [notice] This is a notice log message.'); + $this->guy->doNotSeeInOutput(' [debug] This is a debug log message.'); + $this->assertEquals(0, $result); + } + + public function testRunnerVerboseOutput() + { + $argv = ['placeholder', 'test:verbosity', '-v']; + $result = $this->runner->execute($argv, null, null, $this->guy->capturedOutputStream()); + + $this->guy->seeInOutput('This command will print more information at higher verbosity levels'); + $this->guy->seeInOutput('This is a verbose message (-v).'); + $this->guy->doNotSeeInOutput('This is a very verbose message (-vv).'); + $this->guy->doNotSeeInOutput('This is a debug message (-vvv).'); + $this->guy->seeInOutput(' [warning] This is a warning log message.'); + $this->guy->seeInOutput(' [notice] This is a notice log message.'); + $this->guy->doNotSeeInOutput(' [debug] This is a debug log message.'); + $this->assertEquals(0, $result); + } + + public function testRunnerVeryVerboseOutput() + { + $argv = ['placeholder', 'test:verbosity', '-vv']; + $result = $this->runner->execute($argv, null, null, $this->guy->capturedOutputStream()); + + $this->guy->seeInOutput('This command will print more information at higher verbosity levels'); + $this->guy->seeInOutput('This is a verbose message (-v).'); + $this->guy->seeInOutput('This is a very verbose message (-vv).'); + $this->guy->doNotSeeInOutput('This is a debug message (-vvv).'); + $this->guy->seeInOutput(' [warning] This is a warning log message.'); + $this->guy->seeInOutput(' [notice] This is a notice log message.'); + $this->guy->doNotSeeInOutput(' [debug] This is a debug log message.'); + $this->assertEquals(0, $result); + } + + public function testRunnerDebugOutput() + { + $argv = ['placeholder', 'test:verbosity', '-vvv']; + $result = $this->runner->execute($argv, null, null, $this->guy->capturedOutputStream()); + + $this->guy->seeInOutput('This command will print more information at higher verbosity levels'); + $this->guy->seeInOutput('This is a verbose message (-v).'); + $this->guy->seeInOutput('This is a very verbose message (-vv).'); + $this->guy->seeInOutput('This is a debug message (-vvv).'); + $this->guy->seeInOutput(' [warning] This is a warning log message.'); + $this->guy->seeInOutput(' [notice] This is a notice log message.'); + $this->guy->seeInOutput(' [debug] This is a debug log message.'); + $this->assertEquals(0, $result); + } +} diff --git a/src/composer/vendor/consolidation/robo/tests/unit/Task/ApiGenTest.php b/src/composer/vendor/consolidation/robo/tests/unit/Task/ApiGenTest.php new file mode 100644 index 00000000..cc21850e --- /dev/null +++ b/src/composer/vendor/consolidation/robo/tests/unit/Task/ApiGenTest.php @@ -0,0 +1,52 @@ +apigen = test::double('Robo\Task\ApiGen\ApiGen', [ + 'executeCommand' => null, + 'output' => new \Symfony\Component\Console\Output\NullOutput(), + 'logger' => new \Psr\Log\NullLogger(), + ]); + + $this->container = Robo::getContainer(); + } + + // tests + public function testPHPUnitCommand() + { + // need an explicit Traversable + $skippedPaths = new \SplDoublyLinkedList(); + $skippedPaths->push('a'); + $skippedPaths->push('b'); + + // going for 'bang for the buck' here re: test converage + $task = (new \Robo\Task\ApiGen\ApiGen('apigen')) + ->config('./apigen.neon') + ->source('src') // single string value of Traversable + ->extensions('php') // single string value of List + ->exclude(array('test', 'tmp')) // array value of Traversable + ->skipDocPath($skippedPaths) // multi-value of Traversable + ->charset(array('utf8','iso88591')) // array of List + ->internal('no') // boolean as supported "no" + ->php(true) // boolean as boolean + ->tree('Y') // boolean as string + ->debug('n'); + + $cmd = 'apigen --config ./apigen.neon --source src --extensions php --exclude test --exclude tmp --skip-doc-path a --skip-doc-path b --charset \'utf8,iso88591\' --internal no --php yes --tree yes --debug no'; + verify($task->getCommand())->equals($cmd); + + $task->run(); + $this->apigen->verifyInvoked('executeCommand', [$cmd]); + } +} diff --git a/src/composer/vendor/consolidation/robo/tests/unit/Task/AtoumTest.php b/src/composer/vendor/consolidation/robo/tests/unit/Task/AtoumTest.php new file mode 100644 index 00000000..0bd71a34 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/tests/unit/Task/AtoumTest.php @@ -0,0 +1,38 @@ +atoum = test::double('Robo\Task\Testing\Atoum', [ + 'executeCommand' => null, + 'output' => new \Symfony\Component\Console\Output\NullOutput(), + 'logger' => new \Psr\Log\NullLogger(), + ]); + } + + public function testAtoumCommand() + { + $task = (new \Robo\Task\Testing\Atoum('atoum')) + ->bootstrap('bootstrap.php') + ->tags("needDb") + ->lightReport() + ->tap() + ->bootstrap('tests/bootstrap.php') + ->configFile("config/dev.php") + ->debug() + ->files(array("path/to/file1.php", "path/to/file2.php")) + ->directories("tests/units") + ; + verify($task->getCommand())->equals('atoum --bootstrap bootstrap.php --tags needDb --use-light-report --use-tap-report --bootstrap tests/bootstrap.php -c config/dev.php --debug --f path/to/file1.php --f path/to/file2.php --directories tests/units'); + $task->run(); + $this->atoum->verifyInvoked('executeCommand', ['atoum --bootstrap bootstrap.php --tags needDb --use-light-report --use-tap-report --bootstrap tests/bootstrap.php -c config/dev.php --debug --f path/to/file1.php --f path/to/file2.php --directories tests/units']); + } +} diff --git a/src/composer/vendor/consolidation/robo/tests/unit/Task/BehatTest.php b/src/composer/vendor/consolidation/robo/tests/unit/Task/BehatTest.php new file mode 100644 index 00000000..d08e1570 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/tests/unit/Task/BehatTest.php @@ -0,0 +1,43 @@ +behat = test::double('Robo\Task\Testing\Behat', [ + 'executeCommand' => null, + 'output' => new \Symfony\Component\Console\Output\NullOutput(), + 'logger' => new \Psr\Log\NullLogger(), + ]); + } + + // tests + public function testBehatRun() + { + $behat = test::double('Robo\Task\Testing\Behat', ['executeCommand' => null, 'getConfig' => new \Robo\Config(), 'logger' => new \Psr\Log\NullLogger()]); + + (new \Robo\Task\Testing\Behat('behat'))->run(); + $behat->verifyInvoked('executeCommand'); + } + + public function testBehatCommand() + { + $behat = test::double('Robo\Task\Testing\Behat', ['executeCommand' => null, 'getConfig' => new \Robo\Config(), 'logger' => new \Psr\Log\NullLogger()]); + + $task = (new \Robo\Task\Testing\Behat('behat')) + ->stopOnFail() + ->noInteraction() + ->colors(); + verify($task->getCommand())->equals('behat run --stop-on-failure --no-interaction --colors'); + $task->run(); + $behat->verifyInvoked('executeCommand', ['behat run --stop-on-failure --no-interaction --colors']); + } + +} diff --git a/src/composer/vendor/consolidation/robo/tests/unit/Task/BowerTest.php b/src/composer/vendor/consolidation/robo/tests/unit/Task/BowerTest.php new file mode 100644 index 00000000..f656d753 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/tests/unit/Task/BowerTest.php @@ -0,0 +1,59 @@ +baseBower = test::double('Robo\Task\Bower\Base', [ + 'output' => new \Symfony\Component\Console\Output\NullOutput(), + 'logger' => new \Psr\Log\NullLogger(), + ]); + } + // tests + public function testBowerInstall() + { + $bower = test::double('Robo\Task\Bower\Install', ['executeCommand' => null, 'logger' => new \Psr\Log\NullLogger(),]); + (new \Robo\Task\Bower\Install('bower'))->run(); + $bower->verifyInvoked('executeCommand', ['bower install']); + } + + public function testBowerUpdate() + { + $bower = test::double('Robo\Task\Bower\Update', ['executeCommand' => null]); + $task = new \Robo\Task\Bower\Update('bower'); + $task->setLogger(new \Psr\Log\NullLogger()); + + $task->run(); + $bower->verifyInvoked('executeCommand', ['bower update']); + } + + public function testBowerInstallCommand() + { + verify( + (new \Robo\Task\Bower\Install('bower'))->getCommand() + )->equals('bower install'); + + verify( + (new \Robo\Task\Bower\Update('bower'))->getCommand() + )->equals('bower update'); + + verify( + (new \Robo\Task\Bower\Install('bower')) + ->allowRoot() + ->forceLatest() + ->offline() + ->noDev() + ->getCommand() + )->equals('bower install --allow-root --force-latest --offline --production'); + } + +} diff --git a/src/composer/vendor/consolidation/robo/tests/unit/Task/CodeceptionTest.php b/src/composer/vendor/consolidation/robo/tests/unit/Task/CodeceptionTest.php new file mode 100644 index 00000000..d2c637b0 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/tests/unit/Task/CodeceptionTest.php @@ -0,0 +1,63 @@ +codecept = test::double('Robo\Task\Testing\Codecept', [ + 'executeCommand' => null, + 'output' => new \Symfony\Component\Console\Output\NullOutput() + ]); + } + + // tests + public function testCodeceptionCommand() + { + verify(trim((new \Robo\Task\Testing\Codecept('codecept.phar'))->getCommand()))->equals('codecept.phar run'); + } + + public function testCodeceptionRun() + { + $task = new \Robo\Task\Testing\Codecept('codecept.phar'); + $task->setLogger(new \Psr\Log\NullLogger()); + + $task->run(); + $this->codecept->verifyInvoked('executeCommand'); + } + + public function testCodeceptOptions() + { + verify((new \Robo\Task\Testing\Codecept('codecept')) + ->suite('unit') + ->test('Codeception/Command') + ->group('core') + ->env('process1') + ->coverage() + ->getCommand() + )->equals('codecept run --group core --env process1 --coverage unit Codeception/Command'); + + verify((new \Robo\Task\Testing\Codecept('codecept')) + ->test('tests/unit/Codeception') + ->configFile('~/Codeception') + ->xml('result.xml') + ->html() + ->getCommand() + )->equals('codecept run -c ~/Codeception --xml result.xml --html tests/unit/Codeception'); + + verify((new \Robo\Task\Testing\Codecept('codecept.phar'))->debug()->getCommand())->contains(' --debug'); + verify((new \Robo\Task\Testing\Codecept('codecept.phar'))->silent()->getCommand())->contains(' --silent'); + verify((new \Robo\Task\Testing\Codecept('codecept.phar'))->excludeGroup('g')->getCommand())->contains(' --skip-group g'); + verify((new \Robo\Task\Testing\Codecept('codecept.phar'))->tap()->getCommand())->contains('--tap'); + verify((new \Robo\Task\Testing\Codecept('codecept.phar'))->json()->getCommand())->contains('--json'); + } + +} diff --git a/src/composer/vendor/consolidation/robo/tests/unit/Task/CollectionTest.php b/src/composer/vendor/consolidation/robo/tests/unit/Task/CollectionTest.php new file mode 100644 index 00000000..843589a9 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/tests/unit/Task/CollectionTest.php @@ -0,0 +1,183 @@ +add($taskA, 'a-name') + ->add($taskB, 'b-name'); + + // We add methods of our task instances as before and + // after tasks. These methods have access to the task + // class' fields, and may modify them as needed. + $collection + ->after('a-name', [$taskA, 'parenthesizer']) + ->after('a-name', [$taskA, 'emphasizer']) + ->after('b-name', [$taskB, 'emphasizer']) + ->after('b-name', [$taskB, 'parenthesizer']) + ->after('b-name', [$taskB, 'parenthesizer'], 'special-name'); + + $result = $collection->run(); + + // verify(var_export($result->getData(), true))->equals(''); + + // Ensure that the results have the correct key values + verify(implode(',', array_keys($result->getData())))->equals('a-name,b-name,special-name,time'); + + // Verify that all of the after tasks ran in + // the correct order. + verify($result['a-name']['a'])->equals('*(value-a)*'); + verify($result['b-name']['b'])->equals('(*value-b*)'); + + // Note that the last after task is added with a special name; + // its results therefore show up under the name given, rather + // than being stored under the name of the task it was added after. + verify($result['special-name']['b'])->equals('((*value-b*))'); + } + + public function testBeforeFilters() + { + $collection = new Collection(); + + $taskA = new CollectionTestTask('a', 'value-a'); + $taskB = new CollectionTestTask('b', 'value-b'); + + $collection + ->add($taskA, 'a-name') + ->add($taskB, 'b-name'); + + // We add methods of our task instances as before and + // after tasks. These methods have access to the task + // class' fields, and may modify them as needed. + $collection + ->before('b-name', [$taskA, 'parenthesizer']) + ->before('b-name', [$taskA, 'emphasizer'], 'special-before-name'); + + $result = $collection->run(); + + // Ensure that the results have the correct key values + verify(implode(',', array_keys($result->getData())))->equals('a-name,b-name,special-before-name,time'); + + // The result from the 'before' task is attached + // to 'b-name', since it was called as before('b-name', ...) + verify($result['b-name']['a'])->equals('(value-a)'); + // When a 'before' task is given its own name, then + // its results are attached under that name. + verify($result['special-before-name']['a'])->equals('*(value-a)*'); + } + + public function testAddCodeRollbackAndCompletion() + { + $collection = new Collection(); + $rollback1 = new CountingTask(); + $rollback2 = new CountingTask(); + $completion1 = new CountingTask(); + $completion2 = new CountingTask(); + + $collection + ->progressMessage("start collection tasks") + ->rollback($rollback1) + ->completion($completion1) + ->rollbackCode(function() use($rollback1) { $rollback1->run(); } ) + ->completionCode(function() use($completion1) { $completion1->run(); } ) + ->addCode(function () { return 42; }) + ->progressMessage("not reached") + ->rollback($rollback2) + ->completion($completion2) + ->addCode(function () { return 13; }); + + $collection->setLogger($this->guy->logger()); + + $result = $collection->run(); + // Execution stops on the first error. + // Confirm that status code is converted to a Result object. + verify($result->getExitCode())->equals(42); + verify($rollback1->getCount())->equals(2); + verify($rollback2->getCount())->equals(0); + verify($completion1->getCount())->equals(2); + verify($completion2->getCount())->equals(0); + $this->guy->seeInOutput('start collection tasks'); + $this->guy->doNotSeeInOutput('not reached'); + } +} + +class CountingTask extends BaseTask +{ + protected $count = 0; + + public function run() + { + $this->count++; + return Result::success($this); + } + + public function getCount() + { + return $this->count; + } +} + +class CollectionTestTask extends BaseTask +{ + protected $key; + protected $value; + + public function __construct($key, $value) + { + $this->key = $key; + $this->value = $value; + } + + public function run() + { + return $this->getValue(); + } + + protected function getValue() + { + $result = Result::success($this); + $result[$this->key] = $this->value; + + return $result; + } + + // Note that by returning a value with the same + // key as the result, we overwrite the value generated + // by the primary task method ('run()'). If we returned + // a result with a different key, then both values + // would appear in the result. + public function parenthesizer() + { + $this->value = "({$this->value})"; + return $this->getValue(); + } + + public function emphasizer() + { + $this->value = "*{$this->value}*"; + return $this->getValue(); + } +} diff --git a/src/composer/vendor/consolidation/robo/tests/unit/Task/CommandStackTest.php b/src/composer/vendor/consolidation/robo/tests/unit/Task/CommandStackTest.php new file mode 100644 index 00000000..7a83b5f7 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/tests/unit/Task/CommandStackTest.php @@ -0,0 +1,26 @@ +executable('some-executable') + ->exec('some-executable status') + ->getCommand() + )->equals('some-executable status'); + } + + public function testExecStackCommandIsNotTrimmedIfHavingSameCharsAsExecutable() + { + $commandStack = Stub::make('Robo\Task\CommandStack'); + verify($commandStack + ->executable('some-executable') + ->exec('status') + ->getCommand() + )->equals('some-executable status'); + } +} diff --git a/src/composer/vendor/consolidation/robo/tests/unit/Task/ComposerTest.php b/src/composer/vendor/consolidation/robo/tests/unit/Task/ComposerTest.php new file mode 100644 index 00000000..4e01fb89 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/tests/unit/Task/ComposerTest.php @@ -0,0 +1,266 @@ +baseComposer = test::double('Robo\Task\Composer\Base', [ + 'output' => new \Symfony\Component\Console\Output\NullOutput(), + 'logger' => new \Psr\Log\NullLogger(), + ]); + } + // tests + public function testComposerInstall() + { + $composer = test::double('Robo\Task\Composer\Install', ['executeCommand' => null, 'getConfig' => new \Robo\Config(), 'logger' => new \Psr\Log\NullLogger()]); + + (new \Robo\Task\Composer\Install('composer'))->run(); + $composer->verifyInvoked('executeCommand', ['composer install']); + + (new \Robo\Task\Composer\Install('composer')) + ->preferSource() + ->run(); + $composer->verifyInvoked('executeCommand', ['composer install --prefer-source']); + + (new \Robo\Task\Composer\Install('composer')) + ->optimizeAutoloader() + ->run(); + $composer->verifyInvoked('executeCommand', ['composer install --optimize-autoloader']); + } + + public function testComposerInstallAnsi() + { + $config = new \Robo\Config(); + $config->setDecorated(true); + $composer = test::double('Robo\Task\Composer\Install', ['executeCommand' => null, 'getConfig' => $config, 'logger' => new \Psr\Log\NullLogger()]); + + (new \Robo\Task\Composer\Install('composer'))->run(); + $composer->verifyInvoked('executeCommand', ['composer install --ansi']); + + (new \Robo\Task\Composer\Install('composer')) + ->preferSource() + ->run(); + $composer->verifyInvoked('executeCommand', ['composer install --prefer-source --ansi']); + + (new \Robo\Task\Composer\Install('composer')) + ->optimizeAutoloader() + ->run(); + $composer->verifyInvoked('executeCommand', ['composer install --optimize-autoloader --ansi']); + } + + public function testComposerUpdate() + { + $composer = test::double('Robo\Task\Composer\Update', ['executeCommand' => null, 'getConfig' => new \Robo\Config(), 'logger' => new \Psr\Log\NullLogger()]); + + (new \Robo\Task\Composer\Update('composer'))->run(); + $composer->verifyInvoked('executeCommand', ['composer update']); + + (new \Robo\Task\Composer\Update('composer')) + ->optimizeAutoloader() + ->run(); + $composer->verifyInvoked('executeCommand', ['composer update --optimize-autoloader']); + } + + public function testComposerDumpAutoload() + { + $composer = test::double('Robo\Task\Composer\DumpAutoload', ['executeCommand' => null, 'getConfig' => new \Robo\Config(), 'logger' => new \Psr\Log\NullLogger()]); + + (new \Robo\Task\Composer\DumpAutoload('composer'))->run(); + $composer->verifyInvoked('executeCommand', ['composer dump-autoload']); + + (new \Robo\Task\Composer\DumpAutoload('composer')) + ->noDev() + ->run(); + $composer->verifyInvoked('executeCommand', ['composer dump-autoload --no-dev']); + + (new \Robo\Task\Composer\DumpAutoload('composer')) + ->optimize() + ->run(); + $composer->verifyInvoked('executeCommand', ['composer dump-autoload --optimize']); + + (new \Robo\Task\Composer\DumpAutoload('composer')) + ->optimize() + ->noDev() + ->run(); + $composer->verifyInvoked('executeCommand', ['composer dump-autoload --optimize --no-dev']); + } + + public function testComposerValidate() + { + $composer = test::double('Robo\Task\Composer\Validate', ['executeCommand' => null, 'getConfig' => new \Robo\Config(), 'logger' => new \Psr\Log\NullLogger()]); + + (new \Robo\Task\Composer\Validate('composer'))->run(); + $composer->verifyInvoked('executeCommand', ['composer validate']); + + (new \Robo\Task\Composer\Validate('composer')) + ->noCheckAll() + ->run(); + $composer->verifyInvoked('executeCommand', ['composer validate --no-check-all']); + + (new \Robo\Task\Composer\Validate('composer')) + ->noCheckLock() + ->run(); + $composer->verifyInvoked('executeCommand', ['composer validate --no-check-lock']); + + (new \Robo\Task\Composer\Validate('composer')) + ->noCheckPublish() + ->run(); + $composer->verifyInvoked('executeCommand', ['composer validate --no-check-publish']); + + (new \Robo\Task\Composer\Validate('composer')) + ->withDependencies() + ->run(); + $composer->verifyInvoked('executeCommand', ['composer validate --with-dependencies']); + + (new \Robo\Task\Composer\Validate('composer')) + ->strict() + ->run(); + $composer->verifyInvoked('executeCommand', ['composer validate --strict']); + } + + public function testComposerInstallCommand() + { + verify( + (new \Robo\Task\Composer\Install('composer'))->setConfig(new \Robo\Config())->getCommand() + )->equals('composer install'); + + verify( + (new \Robo\Task\Composer\Install('composer')) + ->setConfig(new \Robo\Config()) + ->noDev() + ->preferDist() + ->optimizeAutoloader() + ->getCommand() + )->equals('composer install --prefer-dist --no-dev --optimize-autoloader'); + } + + public function testComposerUpdateCommand() + { + verify( + (new \Robo\Task\Composer\Update('composer'))->setConfig(new \Robo\Config())->getCommand() + )->equals('composer update'); + + verify( + (new \Robo\Task\Composer\Update('composer')) + ->setConfig(new \Robo\Config()) + ->noDev() + ->preferDist() + ->getCommand() + )->equals('composer update --prefer-dist --no-dev'); + + verify( + (new \Robo\Task\Composer\Update('composer')) + ->setConfig(new \Robo\Config()) + ->noDev() + ->preferDist() + ->optimizeAutoloader() + ->getCommand() + )->equals('composer update --prefer-dist --no-dev --optimize-autoloader'); + } + + public function testComposerDumpAutoloadCommand() + { + verify( + (new \Robo\Task\Composer\DumpAutoload('composer'))->setConfig(new \Robo\Config())->getCommand() + )->equals('composer dump-autoload'); + + verify( + (new \Robo\Task\Composer\DumpAutoload('composer')) + ->setConfig(new \Robo\Config()) + ->noDev() + ->getCommand() + )->equals('composer dump-autoload --no-dev'); + + verify( + (new \Robo\Task\Composer\DumpAutoload('composer')) + ->setConfig(new \Robo\Config()) + ->optimize() + ->getCommand() + )->equals('composer dump-autoload --optimize'); + + verify( + (new \Robo\Task\Composer\DumpAutoload('composer')) + ->setConfig(new \Robo\Config()) + ->optimize() + ->noDev() + ->getCommand() + )->equals('composer dump-autoload --optimize --no-dev'); + } + + public function testComposerRemove() + { + verify( + (new \Robo\Task\Composer\Remove('composer'))->setConfig(new \Robo\Config())->getCommand() + )->equals('composer remove'); + verify( + (new \Robo\Task\Composer\Remove('composer')) + ->setConfig(new \Robo\Config()) + ->dev() + ->noProgress() + ->noUpdate() + ->getCommand() + )->equals('composer remove --dev --no-progress --no-update'); + } + + public function testComposerValidateCommand() + { + verify( + (new \Robo\Task\Composer\Validate('composer'))->setConfig(new \Robo\Config())->getCommand() + )->equals('composer validate'); + + verify( + (new \Robo\Task\Composer\Validate('composer')) + ->setConfig(new \Robo\Config()) + ->noCheckAll() + ->getCommand() + )->equals('composer validate --no-check-all'); + + verify( + (new \Robo\Task\Composer\Validate('composer')) + ->setConfig(new \Robo\Config()) + ->noCheckLock() + ->getCommand() + )->equals('composer validate --no-check-lock'); + + verify( + (new \Robo\Task\Composer\Validate('composer')) + ->setConfig(new \Robo\Config()) + ->noCheckPublish() + ->getCommand() + )->equals('composer validate --no-check-publish'); + + verify( + (new \Robo\Task\Composer\Validate('composer')) + ->setConfig(new \Robo\Config()) + ->withDependencies() + ->getCommand() + )->equals('composer validate --with-dependencies'); + + verify( + (new \Robo\Task\Composer\Validate('composer')) + ->setConfig(new \Robo\Config()) + ->strict() + ->getCommand() + )->equals('composer validate --strict'); + + verify( + (new \Robo\Task\Composer\Validate('composer')) + ->setConfig(new \Robo\Config()) + ->noCheckAll() + ->noCheckLock() + ->noCheckPublish() + ->withDependencies() + ->strict() + ->getCommand() + )->equals('composer validate --no-check-all --no-check-lock --no-check-publish --with-dependencies --strict'); + } +} diff --git a/src/composer/vendor/consolidation/robo/tests/unit/Task/DockerTest.php b/src/composer/vendor/consolidation/robo/tests/unit/Task/DockerTest.php new file mode 100644 index 00000000..f72b237f --- /dev/null +++ b/src/composer/vendor/consolidation/robo/tests/unit/Task/DockerTest.php @@ -0,0 +1,97 @@ +baseDocker = test::double('Robo\Task\Docker\Base', [ + 'output' => new \Symfony\Component\Console\Output\NullOutput(), + 'logger' => new \Psr\Log\NullLogger(), + ]); + } + // tests + public function testDockerBuild() + { + $docker = test::double('Robo\Task\Docker\Build', ['executeCommand' => null, 'getConfig' => new \Robo\Config(), 'logger' => new \Psr\Log\NullLogger()]); + + (new \Robo\Task\Docker\Build())->run(); + $docker->verifyInvoked('executeCommand', ['docker build .']); + + (new \Robo\Task\Docker\Build())->tag('something')->run(); + $docker->verifyInvoked('executeCommand', ['docker build -t something .']); + } + + public function testDockerCommit() + { + $docker = test::double('Robo\Task\Docker\Commit', ['executeCommand' => null, 'getConfig' => new \Robo\Config(), 'logger' => new \Psr\Log\NullLogger()]); + + (new \Robo\Task\Docker\Commit('cid'))->run(); + $docker->verifyInvoked('executeCommand', ['docker commit cid ']); + + (new \Robo\Task\Docker\Commit('cid'))->name('somename')->run(); + $docker->verifyInvoked('executeCommand', ['docker commit cid somename ']); + } + + public function testDockerExec() + { + $docker = test::double('Robo\Task\Docker\Exec', ['executeCommand' => null, 'getConfig' => new \Robo\Config(), 'logger' => new \Psr\Log\NullLogger()]); + + (new \Robo\Task\Docker\Exec('cid'))->run(); + $docker->verifyInvoked('executeCommand', ['docker exec cid ']); + + (new \Robo\Task\Docker\Exec('cid'))->exec('pwd')->run(); + $docker->verifyInvoked('executeCommand', ['docker exec cid pwd']); + } + + public function testDockerPull() + { + $docker = test::double('Robo\Task\Docker\Pull', ['executeCommand' => null, 'getConfig' => new \Robo\Config(), 'logger' => new \Psr\Log\NullLogger()]); + + (new \Robo\Task\Docker\Pull('image'))->run(); + $docker->verifyInvoked('executeCommand', ['docker pull image ']); + } + + public function testDockerRemove() + { + $docker = test::double('Robo\Task\Docker\Remove', ['executeCommand' => null, 'getConfig' => new \Robo\Config(), 'logger' => new \Psr\Log\NullLogger()]); + + (new \Robo\Task\Docker\Remove('container'))->run(); + $docker->verifyInvoked('executeCommand', ['docker rm container ']); + } + + public function testDockerRun() + { + $docker = test::double('Robo\Task\Docker\Run', ['executeCommand' => null, 'getConfig' => new \Robo\Config(), 'logger' => new \Psr\Log\NullLogger(), 'getUniqId' => '12345']); + + (new \Robo\Task\Docker\Run('cid'))->tmpDir('/tmp')->run(); + $docker->verifyInvoked('executeCommand', ['docker run -i --cidfile /tmp/docker_12345.cid cid']); + + (new \Robo\Task\Docker\Run('cid'))->tmpDir('/tmp')->exec('pwd')->run(); + $docker->verifyInvoked('executeCommand', ['docker run -i --cidfile /tmp/docker_12345.cid cid pwd']); + } + + public function testDockerStart() + { + $docker = test::double('Robo\Task\Docker\Start', ['executeCommand' => null, 'getConfig' => new \Robo\Config(), 'logger' => new \Psr\Log\NullLogger()]); + + (new \Robo\Task\Docker\Start('cid'))->run(); + $docker->verifyInvoked('executeCommand', ['docker start cid']); + } + + public function testDockerStop() + { + $docker = test::double('Robo\Task\Docker\Stop', ['executeCommand' => null, 'getConfig' => new \Robo\Config(), 'logger' => new \Psr\Log\NullLogger()]); + + (new \Robo\Task\Docker\Stop('cid'))->run(); + $docker->verifyInvoked('executeCommand', ['docker stop cid']); + } +} diff --git a/src/composer/vendor/consolidation/robo/tests/unit/Task/ExecTaskTest.php b/src/composer/vendor/consolidation/robo/tests/unit/Task/ExecTaskTest.php new file mode 100644 index 00000000..15b3c224 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/tests/unit/Task/ExecTaskTest.php @@ -0,0 +1,73 @@ +process = test::double('Symfony\Component\Process\Process', [ + 'run' => false, + 'start' => false, + 'getOutput' => 'Hello world', + 'getExitCode' => 0, + 'logger' => new \Psr\Log\NullLogger(), + ]); + test::double('Robo\Task\Base\Exec', ['output' => new \Symfony\Component\Console\Output\NullOutput()]); + } + + public function testExec() + { + $task = new \Robo\Task\Base\Exec('ls'); + $task->setLogger(new \Psr\Log\NullLogger()); + + $result = $task->run(); + $this->process->verifyInvoked('run'); + verify($result->getMessage())->equals('Hello world'); + verify($result->getExitCode())->equals(0); + } + + public function testExecInBackground() + { + $task = new \Robo\Task\Base\Exec('ls'); + $task->setLogger(new \Psr\Log\NullLogger()); + + $result = $task->background()->run(); + $this->process->verifyInvoked('start'); + $this->process->verifyNeverInvoked('run'); + verify('exit code was not received', $result->getExitCode())->notEquals(100); + } + + public function testGetCommand() + { + verify((new \Robo\Task\Base\Exec('ls'))->getCommand())->equals('ls'); + } + + public function testExecStack() + { + $task = new \Robo\Task\Base\ExecStack(); + $task->setLogger(new \Psr\Log\NullLogger()); + + $task + ->exec('ls') + ->exec('cd /') + ->exec('cd home') + ->run(); + $this->process->verifyInvoked('run', 3); + } + + public function testExecStackCommand() + { + verify((new \Robo\Task\Base\ExecStack()) + ->exec('ls') + ->exec('cd /') + ->exec('cd home') + ->getCommand() + )->equals('ls && cd / && cd home'); + } +}; diff --git a/src/composer/vendor/consolidation/robo/tests/unit/Task/GitTest.php b/src/composer/vendor/consolidation/robo/tests/unit/Task/GitTest.php new file mode 100644 index 00000000..63b463b6 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/tests/unit/Task/GitTest.php @@ -0,0 +1,62 @@ +git = test::double('Robo\Task\Vcs\GitStack', [ + 'executeCommand' => new \AspectMock\Proxy\Anything(), + 'output' => new \Symfony\Component\Console\Output\NullOutput(), + 'logger' => new \Psr\Log\NullLogger(), + ]); + } + + // tests + public function testGitStackRun() + { + (new \Robo\Task\Vcs\GitStack('git'))->stopOnFail()->add('-A')->pull()->run(); + $this->git->verifyInvoked('executeCommand', ['git add -A']); + $this->git->verifyInvoked('executeCommand', ['git pull']); + + (new \Robo\Task\Vcs\GitStack('git'))->add('-A')->pull()->run(); + $this->git->verifyInvoked('executeCommand', ['git add -A && git pull']); + } + + public function testGitStackCommands() + { + verify( + (new \Robo\Task\Vcs\GitStack()) + ->cloneRepo('http://github.com/consolidation-org/Robo') + ->pull() + ->add('-A') + ->commit('changed') + ->push() + ->tag('0.6.0') + ->push('origin', '0.6.0') + ->getCommand() + )->equals("git clone http://github.com/consolidation-org/Robo && git pull && git add -A && git commit -m 'changed' && git push && git tag 0.6.0 && git push origin 0.6.0"); + } + + public function testGitStackCommandsWithTagMessage() + { + verify( + (new \Robo\Task\Vcs\GitStack()) + ->cloneRepo('http://github.com/consolidation-org/Robo') + ->pull() + ->add('-A') + ->commit('changed') + ->push() + ->tag('0.6.0', 'message') + ->push('origin', '0.6.0') + ->getCommand() + )->equals("git clone http://github.com/consolidation-org/Robo && git pull && git add -A && git commit -m 'changed' && git push && git tag -m 'message' 0.6.0 && git push origin 0.6.0"); + } +} diff --git a/src/composer/vendor/consolidation/robo/tests/unit/Task/GulpTest.php b/src/composer/vendor/consolidation/robo/tests/unit/Task/GulpTest.php new file mode 100644 index 00000000..e5b36c98 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/tests/unit/Task/GulpTest.php @@ -0,0 +1,85 @@ +baseGulp = test::double('Robo\Task\Gulp\Base', [ + 'output' => new \Symfony\Component\Console\Output\NullOutput() + ]); + } + + protected function adjustQuotes($expected) + { + $isWindows = defined('PHP_WINDOWS_VERSION_MAJOR'); + + if (!$isWindows) { + return strtr($expected, '"', "'"); + } + return $expected; + } + + // tests + public function testGulpGetCommand() + { + verify( + (new \Robo\Task\Gulp\Run('default','gulp'))->getCommand() + )->equals($this->adjustQuotes('gulp "default"')); + + verify( + (new \Robo\Task\Gulp\Run('another','gulp'))->getCommand() + )->equals($this->adjustQuotes('gulp "another"')); + + verify( + (new \Robo\Task\Gulp\Run('default','gulp'))->silent()->getCommand() + )->equals($this->adjustQuotes('gulp "default" --silent')); + + verify( + (new \Robo\Task\Gulp\Run('default','gulp'))->noColor()->getCommand() + )->equals($this->adjustQuotes('gulp "default" --no-color')); + + verify( + (new \Robo\Task\Gulp\Run('default','gulp'))->color()->getCommand() + )->equals($this->adjustQuotes('gulp "default" --color')); + + verify( + (new \Robo\Task\Gulp\Run('default','gulp'))->simple()->getCommand() + )->equals($this->adjustQuotes('gulp "default" --tasks-simple')); + } + + public function testGulpRun() + { + $gulp = test::double('Robo\Task\Gulp\Run', ['executeCommand' => null, 'getConfig' => new \Robo\Config(), 'logger' => new \Psr\Log\NullLogger()]); + + $task = (new \Robo\Task\Gulp\Run('default','gulp'))->simple(); + verify($task->getCommand())->equals($this->adjustQuotes('gulp "default" --tasks-simple')); + $task->run(); + $gulp->verifyInvoked('executeCommand', [$this->adjustQuotes('gulp "default" --tasks-simple')]); + } + + public function testGulpUnusualChars() + { + $isWindows = defined('PHP_WINDOWS_VERSION_MAJOR'); + + if ($isWindows) { + + verify( + (new \Robo\Task\Gulp\Run('anotherWith weired!("\') Chars','gulp'))->getCommand() + )->equals('gulp "anotherWith weired!(\"\') Chars"'); + + } else { + + verify( + (new \Robo\Task\Gulp\Run('anotherWith weired!("\') Chars','gulp'))->getCommand() + )->equals("gulp 'anotherWith weired!(\"'\\'') Chars'"); + + } + } +} diff --git a/src/composer/vendor/consolidation/robo/tests/unit/Task/HgTest.php b/src/composer/vendor/consolidation/robo/tests/unit/Task/HgTest.php new file mode 100644 index 00000000..7b36ece3 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/tests/unit/Task/HgTest.php @@ -0,0 +1,86 @@ +hg = Test::double('Robo\Task\Vcs\HgStack', [ + 'executeCommand' => new \AspectMock\Proxy\Anything(), + 'output' => new \Symfony\Component\Console\Output\NullOutput(), + 'logger' => new \Psr\Log\NullLogger(), + ]); + $this->hgStack = (new \Robo\Task\Vcs\HgStack('hg')); + } + + // tests + public function testHgStackRun() + { + $this->hgStack->stopOnFail()->add()->pull()->run(); + $this->hg->verifyInvoked('executeCommand', ['hg add']); + $this->hg->verifyInvoked('executeCommand', ['hg pull']); + + (new \Robo\Task\Vcs\HgStack('hg'))->add()->pull()->run(); + $this->hg->verifyInvoked('executeCommand', ['hg add && hg pull']); + } + + public function testHgStackPull() + { + verify( + $this->hgStack + ->pull() + ->getCommand() + )->equals('hg pull'); + } + + public function testHgStackAddFiles() + { + verify( + $this->hgStack + ->add('*.php', '*.css') + ->getCommand() + )->equals('hg add -I *.php -X *.css'); + } + + public function testHgStackCommands() + { + verify( + $this->hgStack + ->cloneRepo('https://bitbucket.org/durin42/hgsubversion') + ->pull() + ->add() + ->commit('changed') + ->push() + ->tag('0.6.0') + ->push('0.6.0') + ->getCommand() + )->equals("hg clone https://bitbucket.org/durin42/hgsubversion && hg pull && hg add && hg commit -m 'changed' && hg push && hg tag 0.6.0 && hg push -b '0.6.0'"); + } + + public function testHgStackCommandsWithTagMessage() + { + verify( + $this->hgStack + ->cloneRepo('https://bitbucket.org/durin42/hgsubversion') + ->pull() + ->add() + ->commit('changed') + ->push() + ->tag('0.6.0', 'message') + ->push('0.6.0') + ->getCommand() + )->equals("hg clone https://bitbucket.org/durin42/hgsubversion && hg pull && hg add && hg commit -m 'changed' && hg push && hg tag -m 'message' 0.6.0 && hg push -b '0.6.0'"); + } +} diff --git a/src/composer/vendor/consolidation/robo/tests/unit/Task/NpmTest.php b/src/composer/vendor/consolidation/robo/tests/unit/Task/NpmTest.php new file mode 100644 index 00000000..ce3ba6f4 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/tests/unit/Task/NpmTest.php @@ -0,0 +1,52 @@ +baseNpm = test::double('Robo\Task\Npm\Base', [ + 'output' => new \Symfony\Component\Console\Output\NullOutput(), + 'logger' => new \Psr\Log\NullLogger(), + ]); + } + + // tests + public function testNpmInstall() + { + $npm = test::double('Robo\Task\Npm\Install', ['executeCommand' => null, 'logger' => new \Psr\Log\NullLogger()]); + (new \Robo\Task\Npm\Install('npm'))->run(); + $npm->verifyInvoked('executeCommand', ['npm install']); + } + + public function testNpmUpdate() + { + $npm = test::double('Robo\Task\Npm\Update', ['executeCommand' => null, 'logger' => new \Psr\Log\NullLogger()]); + (new \Robo\Task\Npm\Update('npm'))->run(); + $npm->verifyInvoked('executeCommand', ['npm update']); + } + + public function testNpmInstallCommand() + { + verify( + (new \Robo\Task\Npm\Install('npm'))->getCommand() + )->equals('npm install'); + + verify( + (new \Robo\Task\Npm\Install('npm'))->getCommand() + )->equals('npm install'); + + verify( + (new \Robo\Task\Npm\Install('npm')) + ->noDev() + ->getCommand() + )->equals('npm install --production'); + } + +} diff --git a/src/composer/vendor/consolidation/robo/tests/unit/Task/PHPServerTest.php b/src/composer/vendor/consolidation/robo/tests/unit/Task/PHPServerTest.php new file mode 100644 index 00000000..30744958 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/tests/unit/Task/PHPServerTest.php @@ -0,0 +1,59 @@ +process = test::double('Symfony\Component\Process\Process', [ + 'run' => false, + 'start' => false, + 'getOutput' => 'Hello world', + 'getExitCode' => 0, + 'logger' => new \Psr\Log\NullLogger(), + ]); + test::double('Robo\Task\Development\PhpServer', ['output' => new \Symfony\Component\Console\Output\NullOutput()]); + } + + public function testServerBackgroundRun() + { + $task = new \Robo\Task\Development\PhpServer('8000'); + $task->setLogger(new \Psr\Log\NullLogger()); + + $task->background()->run(); + $this->process->verifyInvoked('start'); + } + + public function testServerRun() + { + $task = new \Robo\Task\Development\PhpServer('8000'); + $task->setLogger(new \Psr\Log\NullLogger()); + + $task->run(); + $this->process->verifyInvoked('run'); + } + + public function testServerCommand() + { + if (strtolower(PHP_OS) === 'linux') { + $expectedCommand = 'exec php -S 127.0.0.1:8000 -t web'; + } else { + $expectedCommand = 'php -S 127.0.0.1:8000 -t web'; + } + + verify( + (new \Robo\Task\Development\PhpServer('8000')) + ->host('127.0.0.1') + ->dir('web') + ->getCommand() + )->equals($expectedCommand); + } + +} diff --git a/src/composer/vendor/consolidation/robo/tests/unit/Task/PHPUnitTest.php b/src/composer/vendor/consolidation/robo/tests/unit/Task/PHPUnitTest.php new file mode 100644 index 00000000..3f7b235c --- /dev/null +++ b/src/composer/vendor/consolidation/robo/tests/unit/Task/PHPUnitTest.php @@ -0,0 +1,41 @@ +phpunit = test::double('Robo\Task\Testing\PHPUnit', [ + 'executeCommand' => null, + 'output' => new \Symfony\Component\Console\Output\NullOutput(), + 'logger' => new \Psr\Log\NullLogger(), + ]); + } + + // tests + public function testPhpUnitRun() + { + (new \Robo\Task\Testing\PHPUnit())->run(); + $this->phpunit->verifyInvoked('executeCommand'); + } + + public function testPHPUnitCommand() + { + $task = (new \Robo\Task\Testing\PHPUnit('phpunit')) + ->bootstrap('bootstrap.php') + ->filter('Model') + ->group('important') + ->xml('result.xml') + ->debug(); + verify($task->getCommand())->equals('phpunit --bootstrap bootstrap.php --filter Model --group important --log-junit result.xml --debug'); + $task->run(); + $this->phpunit->verifyInvoked('executeCommand', ['phpunit --bootstrap bootstrap.php --filter Model --group important --log-junit result.xml --debug']); + } + +} diff --git a/src/composer/vendor/consolidation/robo/tests/unit/Task/ParallelExecTest.php b/src/composer/vendor/consolidation/robo/tests/unit/Task/ParallelExecTest.php new file mode 100644 index 00000000..037f7ee3 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/tests/unit/Task/ParallelExecTest.php @@ -0,0 +1,43 @@ +process = test::double('Symfony\Component\Process\Process', [ + 'run' => false, + 'start' => false, + 'isRunning' => false, + 'getOutput' => 'Hello world', + 'getExitCode' => 0, + 'logger' => new \Psr\Log\NullLogger(), + ]); + } + + public function testParallelExec() + { + $task = new \Robo\Task\Base\ParallelExec(); + $task->setLogger($this->guy->logger()); + + $result = $task + ->process('ls 1') + ->process('ls 2') + ->process('ls 3') + ->run(); + $this->process->verifyInvokedMultipleTimes('start', 3); + verify($result->getExitCode())->equals(0); + $this->guy->seeInOutput("3 processes finished"); + } +} diff --git a/src/composer/vendor/consolidation/robo/tests/unit/Task/PhpspecTest.php b/src/composer/vendor/consolidation/robo/tests/unit/Task/PhpspecTest.php new file mode 100644 index 00000000..71336b33 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/tests/unit/Task/PhpspecTest.php @@ -0,0 +1,42 @@ +phpspec = test::double('Robo\Task\Testing\Phpspec', [ + 'executeCommand' => null, + 'output' => new \Symfony\Component\Console\Output\NullOutput(), + 'logger' => new \Psr\Log\NullLogger(), + ]); + } + + // tests + public function testPhpSpecRun() + { + (new \Robo\Task\Testing\Phpspec('phpspec'))->run(); + $this->phpspec->verifyInvoked('executeCommand', ['phpspec run']); + } + + public function testPHPSpecCommand() + { + $task = (new \Robo\Task\Testing\Phpspec('phpspec')) + ->stopOnFail() + ->noCodeGeneration() + ->quiet() + ->verbose('vv') + ->noAnsi() + ->noInteraction() + ->format('pretty'); + verify($task->getCommand())->equals('phpspec run --stop-on-failure --no-code-generation --quiet -vv --no-ansi --no-interaction --format pretty'); + $task->run(); + $this->phpspec->verifyInvoked('executeCommand', ['phpspec run --stop-on-failure --no-code-generation --quiet -vv --no-ansi --no-interaction --format pretty']); + } +} diff --git a/src/composer/vendor/consolidation/robo/tests/unit/Task/RsyncTest.php b/src/composer/vendor/consolidation/robo/tests/unit/Task/RsyncTest.php new file mode 100644 index 00000000..957d2188 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/tests/unit/Task/RsyncTest.php @@ -0,0 +1,59 @@ +fromPath('src/') + ->toHost('localhost') + ->toUser('dev') + ->toPath('/var/www/html/app/') + ->recursive() + ->excludeVcs() + ->checksum() + ->wholeFile() + ->verbose() + ->progress() + ->humanReadable() + ->stats() + ->getCommand() + )->equals( + 'rsync --recursive --exclude .git --exclude .svn --exclude .hg --checksum --whole-file --verbose --progress --human-readable --stats src/ \'dev@localhost:/var/www/html/app/\'' + ); + + // From the folder 'foo bar' (with space) in 'src' directory + verify( + (new \Robo\Task\Remote\Rsync()) + ->fromPath('src/foo bar/baz') + ->toHost('localhost') + ->toUser('dev') + ->toPath('/var/path/with/a space') + ->getCommand() + )->equals( + 'rsync \'src/foo bar/baz\' \'dev@localhost:/var/path/with/a space\'' + ); + + // Copy two folders, 'src/foo' and 'src/bar' + verify( + (new \Robo\Task\Remote\Rsync()) + ->fromPath(['src/foo', 'src/bar']) + ->toHost('localhost') + ->toUser('dev') + ->toPath('/var/path/with/a space') + ->getCommand() + )->equals( + 'rsync src/foo src/bar \'dev@localhost:/var/path/with/a space\'' + ); + } +} diff --git a/src/composer/vendor/consolidation/robo/tests/unit/Task/SemVerTest.php b/src/composer/vendor/consolidation/robo/tests/unit/Task/SemVerTest.php new file mode 100644 index 00000000..f68535bb --- /dev/null +++ b/src/composer/vendor/consolidation/robo/tests/unit/Task/SemVerTest.php @@ -0,0 +1,72 @@ + null]); + $res = (new \Robo\Task\Development\SemVer()) + ->increment('major') + ->prerelease('RC') + ->increment('patch') + ->run(); + verify($res->getMessage())->equals('v1.0.1-RC.1'); + $semver->verifyInvoked('dump'); + } + + public function testSemverIncrementMinorAfterIncrementedPatch() + { + $semver = test::double('Robo\Task\Development\SemVer', ['dump' => null]); + $res = (new \Robo\Task\Development\SemVer()) + ->increment('patch') + ->run(); + verify($res->getMessage())->equals('v0.0.1'); + $res = (new \Robo\Task\Development\SemVer()) + ->increment('minor') + ->run(); + verify($res->getMessage())->equals('v0.1.0'); + $semver->verifyInvoked('dump'); + } + + public function testSemverIncrementMajorAfterIncrementedMinorAndPatch() + { + $semver = test::double('Robo\Task\Development\SemVer', ['dump' => null]); + $res = (new \Robo\Task\Development\SemVer()) + ->increment('patch') + ->run(); + verify($res->getMessage())->equals('v0.0.1'); + $res = (new \Robo\Task\Development\SemVer()) + ->increment('minor') + ->run(); + verify($res->getMessage())->equals('v0.1.0'); + $res = (new \Robo\Task\Development\SemVer()) + ->increment('major') + ->run(); + verify($res->getMessage())->equals('v1.0.0'); + $semver->verifyInvoked('dump'); + } + + public function testThrowsExceptionWhenIncrementWithWrongParameter() + { + \PHPUnit_Framework_TestCase::setExpectedExceptionRegExp( + 'Robo\Exception\TaskException', + '/Bad argument, only one of the following is allowed: major, minor, patch/' + ); + $res = (new \Robo\Task\Development\SemVer()) + ->increment('wrongParameter'); + } + + public function testThrowsExceptionWhenSemverFileNotWriteable() + { + \PHPUnit_Framework_TestCase::setExpectedExceptionRegExp( + 'Robo\Exception\TaskException', + '/Failed to write semver file./' + ); + (new \Robo\Task\Development\SemVer('/.semver')) + ->increment('major') + ->run(); + } +} diff --git a/src/composer/vendor/consolidation/robo/tests/unit/Task/SshTest.php b/src/composer/vendor/consolidation/robo/tests/unit/Task/SshTest.php new file mode 100644 index 00000000..ec228998 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/tests/unit/Task/SshTest.php @@ -0,0 +1,61 @@ +exec('ls -la') + ->exec('chmod g+x logs') + ->getCommand() + )->equals("ssh user@remote.example.com 'ls -la && chmod g+x logs'"); + } + + public function testStopOnFail() + { + verify( + (new \Robo\Task\Remote\Ssh('remote.example.com', 'user')) + ->stopOnFail(false) + ->exec('one') + ->exec('two') + ->getCommand() + )->equals("ssh user@remote.example.com 'one ; two'"); + } + + /** + * Sets static configuration, then runs task without working dir, with working dir and again without. + */ + public function testWorkingDirectoryStaticConfiguration() + { + \Robo\Task\Remote\Ssh::configure('remoteDir', '/some-dir'); + verify( + (new \Robo\Task\Remote\Ssh('remote.example.com', 'user')) + ->setConfig(Robo::config()) + ->exec('echo test') + ->getCommand() + )->equals("ssh user@remote.example.com 'cd \"/some-dir\" && echo test'"); + verify( + (new \Robo\Task\Remote\Ssh('remote.example.com', 'user')) + ->remoteDir('/other-dir') + ->exec('echo test') + ->getCommand() + )->equals("ssh user@remote.example.com 'cd \"/other-dir\" && echo test'"); + verify( + (new \Robo\Task\Remote\Ssh('remote.example.com', 'user')) + ->setConfig(Robo::config()) + ->exec('echo test') + ->getCommand() + )->equals("ssh user@remote.example.com 'cd \"/some-dir\" && echo test'"); + \Robo\Task\Remote\Ssh::configure('remoteDir', null); + verify( + (new \Robo\Task\Remote\Ssh('remote.example.com', 'user')) + ->exec('echo test') + ->getCommand() + )->equals("ssh user@remote.example.com 'echo test'"); + } +} diff --git a/src/composer/vendor/consolidation/robo/tests/unit/Task/SvnTest.php b/src/composer/vendor/consolidation/robo/tests/unit/Task/SvnTest.php new file mode 100644 index 00000000..eeff03b7 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/tests/unit/Task/SvnTest.php @@ -0,0 +1,49 @@ +svn = test::double('Robo\Task\Vcs\SvnStack', [ + 'executeCommand' => new \AspectMock\Proxy\Anything(), + 'output' => $nullOutput, + 'logger' => new \Psr\Log\NullLogger(), + 'logger' => Robo::logger(), + 'getConfig' => Robo::config(), + 'progressIndicator' => $progressIndicator, + ]); + } + + // tests + public function testSvnStackRun() + { + $this->svn->construct()->update()->add()->run(); + $this->svn->verifyInvoked('executeCommand', ['svn update && svn add']); + } + + public function testSvnStackCommands() + { + verify( + (new \Robo\Task\Vcs\SvnStack('guest', 'foo')) + ->checkout('svn://server/trunk') + ->update() + ->add() + ->commit('changed') + ->getCommand() + )->equals("svn --username guest --password foo checkout svn://server/trunk && svn --username guest --password foo update && svn --username guest --password foo add && svn --username guest --password foo commit -m 'changed'"); + } + +} diff --git a/src/composer/vendor/consolidation/robo/tests/unit/_bootstrap.php b/src/composer/vendor/consolidation/robo/tests/unit/_bootstrap.php new file mode 100644 index 00000000..8a885558 --- /dev/null +++ b/src/composer/vendor/consolidation/robo/tests/unit/_bootstrap.php @@ -0,0 +1,2 @@ +setParentContainer($this); + } + } + ... + } +} + +``` + +**Cons:** + +Cons have been extensively discussed [here](https://github.com/container-interop/container-interop/pull/8#issuecomment-51721777). +Basically, forcing a setter into an interface is a bad idea. Setters are similar to constructor arguments, +and it's a bad idea to standardize a constructor: how the delegate container is configured into a container is an implementation detail. This outweights the benefits of the interface. + +### 4.4 Alternative: no exception case for delegate lookups + +Originally, the proposed wording for delegate lookup calls was: + +> Important! The lookup MUST be performed on the delegate container **only**, not on the container itself. + +This was later replaced by: + +> Important! By default, the lookup SHOULD be performed on the delegate container **only**, not on the container itself. +> +> It is however allowed for containers to provide exception cases for special entries, and a way to lookup +> into the same container (or another container) instead of the delegate container. + +Exception cases have been allowed to avoid breaking dependencies with some services that must be provided +by the container (on @njasm proposal). This was proposed here: https://github.com/container-interop/container-interop/pull/20#issuecomment-56597235 + +### 4.5 Alternative: having one of the containers act as the composite container + +In real-life scenarios, we usually have a big framework (Symfony 2, Zend Framework 2, etc...) and we want to +add another DI container to this container. Most of the time, the "big" framework will be responsible for +creating the controller's instances, using it's own DI container. Until *container-interop* is fully adopted, +the "big" framework will not be aware of the existence of a composite container that it should use instead +of its own container. + +For this real-life use cases, @mnapoli and @moufmouf proposed to extend the "big" framework's DI container +to make it act as a composite container. + +This has been discussed [here](https://github.com/container-interop/container-interop/pull/8#issuecomment-40367194) +and [here](http://mouf-php.com/container-interop-whats-next#solution4). + +This was implemented in Symfony 2 using: + +- [interop.symfony.di](https://github.com/thecodingmachine/interop.symfony.di/tree/v0.1.0) +- [framework interop](https://github.com/mnapoli/framework-interop/) + +This was implemented in Silex using: + +- [interop.silex.di](https://github.com/thecodingmachine/interop.silex.di) + +Having a container act as the composite container is not part of the delegate lookup standard because it is +simply a temporary design pattern used to make existing frameworks that do not support yet ContainerInterop +play nice with other DI containers. + + +5. Implementations +------------------ + +The following projects already implement the delegate lookup feature: + +- [Mouf](http://mouf-php.com), through the [`setDelegateLookupContainer` method](https://github.com/thecodingmachine/mouf/blob/2.0/src/Mouf/MoufManager.php#L2120) +- [PHP-DI](http://php-di.org/), through the [`$wrapperContainer` parameter of the constructor](https://github.com/mnapoli/PHP-DI/blob/master/src/DI/Container.php#L72) +- [pimple-interop](https://github.com/moufmouf/pimple-interop), through the [`$container` parameter of the constructor](https://github.com/moufmouf/pimple-interop/blob/master/src/Interop/Container/Pimple/PimpleInterop.php#L62) + +6. People +--------- + +Are listed here all people that contributed in the discussions, by alphabetical order: + +- [Alexandru Pătrănescu](https://github.com/drealecs) +- [Ben Peachey](https://github.com/potherca) +- [David Négrier](https://github.com/moufmouf) +- [Jeremy Lindblom](https://github.com/jeremeamia) +- [Marco Pivetta](https://github.com/Ocramius) +- [Matthieu Napoli](https://github.com/mnapoli) +- [Nelson J Morais](https://github.com/njasm) +- [Phil Sturgeon](https://github.com/philsturgeon) +- [Stephan Hochdörfer](https://github.com/shochdoerfer) + +7. Relevant Links +----------------- + +_**Note:** Order descending chronologically._ + +- [Pull request on the delegate lookup feature](https://github.com/container-interop/container-interop/pull/20) +- [Pull request on the interface idea](https://github.com/container-interop/container-interop/pull/8) +- [Original article exposing the delegate lookup idea along many others](http://mouf-php.com/container-interop-whats-next) + diff --git a/src/composer/vendor/container-interop/container-interop/docs/Delegate-lookup.md b/src/composer/vendor/container-interop/container-interop/docs/Delegate-lookup.md new file mode 100644 index 00000000..04eb3aea --- /dev/null +++ b/src/composer/vendor/container-interop/container-interop/docs/Delegate-lookup.md @@ -0,0 +1,60 @@ +Delegate lookup feature +======================= + +This document describes a standard for dependency injection containers. + +The goal set by the *delegate lookup* feature is to allow several containers to share entries. +Containers implementing this feature can perform dependency lookups in other containers. + +Containers implementing this feature will offer a greater lever of interoperability +with other containers. Implementation of this feature is therefore RECOMMENDED. + +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", +"SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be +interpreted as described in [RFC 2119][]. + +The word `implementor` in this document is to be interpreted as someone +implementing the delegate lookup feature in a dependency injection-related library or framework. +Users of dependency injections containers (DIC) are refered to as `user`. + +[RFC 2119]: http://tools.ietf.org/html/rfc2119 + +1. Vocabulary +------------- + +In a dependency injection container, the container is used to fetch entries. +Entries can have dependencies on other entries. Usually, these other entries are fetched by the container. + +The *delegate lookup* feature is the ability for a container to fetch dependencies in +another container. In the rest of the document, the word "container" will reference the container +implemented by the implementor. The word "delegate container" will reference the container we are +fetching the dependencies from. + +2. Specification +---------------- + +A container implementing the *delegate lookup* feature: + +- MUST implement the [`ContainerInterface`](ContainerInterface.md) +- MUST provide a way to register a delegate container (using a constructor parameter, or a setter, + or any possible way). The delegate container MUST implement the [`ContainerInterface`](ContainerInterface.md). + +When a container is configured to use a delegate container for dependencies: + +- Calls to the `get` method should only return an entry if the entry is part of the container. + If the entry is not part of the container, an exception should be thrown + (as requested by the [`ContainerInterface`](ContainerInterface.md)). +- Calls to the `has` method should only return `true` if the entry is part of the container. + If the entry is not part of the container, `false` should be returned. +- If the fetched entry has dependencies, **instead** of performing + the dependency lookup in the container, the lookup is performed on the *delegate container*. + +Important: By default, the dependency lookups SHOULD be performed on the delegate container **only**, not on the container itself. + +It is however allowed for containers to provide exception cases for special entries, and a way to lookup +into the same container (or another container) instead of the delegate container. + +3. Package / Interface +---------------------- + +This feature is not tied to any code, interface or package. diff --git a/src/composer/vendor/container-interop/container-interop/docs/images/interoperating_containers.png b/src/composer/vendor/container-interop/container-interop/docs/images/interoperating_containers.png new file mode 100644 index 0000000000000000000000000000000000000000..9c672e16c72a08708ea5bdeb51757c2951d3ee66 GIT binary patch literal 35971 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 literal 0 HcmV?d00001 diff --git a/src/composer/vendor/container-interop/container-interop/docs/images/priority.png b/src/composer/vendor/container-interop/container-interop/docs/images/priority.png new file mode 100644 index 0000000000000000000000000000000000000000..5760dc71b557fea7ec5bd5699adfd1c228b9cdec GIT binary patch literal 22949 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 composer-installer.php + hhvm composer-installer.php + hhvm -v ResourceLimit.SocketDefaultTimeout=30 -v Http.SlowQueryThreshold=30000 composer.phar update --prefer-source +elif [ "$TRAVIS_PHP_VERSION" = '5.3.3' ] ; then + composer self-update + composer update --prefer-source --no-dev + composer dump-autoload +else + composer self-update + composer update --prefer-source +fi diff --git a/src/composer/vendor/doctrine/instantiator/.travis.yml b/src/composer/vendor/doctrine/instantiator/.travis.yml new file mode 100644 index 00000000..7f1ec5f9 --- /dev/null +++ b/src/composer/vendor/doctrine/instantiator/.travis.yml @@ -0,0 +1,22 @@ +language: php + +php: + - 5.3.3 + - 5.3 + - 5.4 + - 5.5 + - 5.6 + - hhvm + +before_script: + - ./.travis.install.sh + - if [ $TRAVIS_PHP_VERSION = '5.6' ]; then PHPUNIT_FLAGS="--coverage-clover coverage.clover"; else PHPUNIT_FLAGS=""; fi + +script: + - if [ $TRAVIS_PHP_VERSION = '5.3.3' ]; then phpunit; fi + - if [ $TRAVIS_PHP_VERSION != '5.3.3' ]; then ./vendor/bin/phpunit $PHPUNIT_FLAGS; fi + - if [ $TRAVIS_PHP_VERSION != '5.3.3' ]; then ./vendor/bin/phpcs --standard=PSR2 ./src/ ./tests/; fi + - if [[ $TRAVIS_PHP_VERSION != '5.3.3' && $TRAVIS_PHP_VERSION != '5.4.29' && $TRAVIS_PHP_VERSION != '5.5.13' ]]; then php -n ./vendor/bin/athletic -p ./tests/DoctrineTest/InstantiatorPerformance/ -f GroupedFormatter; fi + +after_script: + - if [ $TRAVIS_PHP_VERSION = '5.6' ]; then wget https://scrutinizer-ci.com/ocular.phar; php ocular.phar code-coverage:upload --format=php-clover coverage.clover; fi diff --git a/src/composer/vendor/doctrine/instantiator/CONTRIBUTING.md b/src/composer/vendor/doctrine/instantiator/CONTRIBUTING.md new file mode 100644 index 00000000..75b84b2a --- /dev/null +++ b/src/composer/vendor/doctrine/instantiator/CONTRIBUTING.md @@ -0,0 +1,35 @@ +# Contributing + + * Coding standard for the project is [PSR-2](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md) + * The project will follow strict [object calisthenics](http://www.slideshare.net/guilhermeblanco/object-calisthenics-applied-to-php) + * Any contribution must provide tests for additional introduced conditions + * Any un-confirmed issue needs a failing test case before being accepted + * Pull requests must be sent from a new hotfix/feature branch, not from `master`. + +## Installation + +To install the project and run the tests, you need to clone it first: + +```sh +$ git clone git://github.com/doctrine/instantiator.git +``` + +You will then need to run a composer installation: + +```sh +$ cd Instantiator +$ curl -s https://getcomposer.org/installer | php +$ php composer.phar update +``` + +## Testing + +The PHPUnit version to be used is the one installed as a dev- dependency via composer: + +```sh +$ ./vendor/bin/phpunit +``` + +Accepted coverage for new contributions is 80%. Any contribution not satisfying this requirement +won't be merged. + diff --git a/src/composer/vendor/doctrine/instantiator/LICENSE b/src/composer/vendor/doctrine/instantiator/LICENSE new file mode 100644 index 00000000..4d983d1a --- /dev/null +++ b/src/composer/vendor/doctrine/instantiator/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2014 Doctrine Project + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/src/composer/vendor/doctrine/instantiator/README.md b/src/composer/vendor/doctrine/instantiator/README.md new file mode 100644 index 00000000..393ec7ca --- /dev/null +++ b/src/composer/vendor/doctrine/instantiator/README.md @@ -0,0 +1,40 @@ +# Instantiator + +This library provides a way of avoiding usage of constructors when instantiating PHP classes. + +[![Build Status](https://travis-ci.org/doctrine/instantiator.svg?branch=master)](https://travis-ci.org/doctrine/instantiator) +[![Code Coverage](https://scrutinizer-ci.com/g/doctrine/instantiator/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/doctrine/instantiator/?branch=master) +[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/doctrine/instantiator/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/doctrine/instantiator/?branch=master) +[![Dependency Status](https://www.versioneye.com/package/php--doctrine--instantiator/badge.svg)](https://www.versioneye.com/package/php--doctrine--instantiator) +[![HHVM Status](http://hhvm.h4cc.de/badge/doctrine/instantiator.png)](http://hhvm.h4cc.de/package/doctrine/instantiator) + +[![Latest Stable Version](https://poser.pugx.org/doctrine/instantiator/v/stable.png)](https://packagist.org/packages/doctrine/instantiator) +[![Latest Unstable Version](https://poser.pugx.org/doctrine/instantiator/v/unstable.png)](https://packagist.org/packages/doctrine/instantiator) + +## Installation + +The suggested installation method is via [composer](https://getcomposer.org/): + +```sh +php composer.phar require "doctrine/instantiator:~1.0.3" +``` + +## Usage + +The instantiator is able to create new instances of any class without using the constructor or any API of the class +itself: + +```php +$instantiator = new \Doctrine\Instantiator\Instantiator(); + +$instance = $instantiator->instantiate('My\\ClassName\\Here'); +``` + +## Contributing + +Please read the [CONTRIBUTING.md](CONTRIBUTING.md) contents if you wish to help out! + +## Credits + +This library was migrated from [ocramius/instantiator](https://github.com/Ocramius/Instantiator), which +has been donated to the doctrine organization, and which is now deprecated in favour of this package. diff --git a/src/composer/vendor/doctrine/instantiator/composer.json b/src/composer/vendor/doctrine/instantiator/composer.json new file mode 100644 index 00000000..4823890b --- /dev/null +++ b/src/composer/vendor/doctrine/instantiator/composer.json @@ -0,0 +1,45 @@ +{ + "name": "doctrine/instantiator", + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "type": "library", + "license": "MIT", + "homepage": "https://github.com/doctrine/instantiator", + "keywords": [ + "instantiate", + "constructor" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "http://ocramius.github.com/" + } + ], + "require": { + "php": ">=5.3,<8.0-DEV" + }, + "require-dev": { + "ext-phar": "*", + "ext-pdo": "*", + "phpunit/phpunit": "~4.0", + "squizlabs/php_codesniffer": "~2.0", + "athletic/athletic": "~0.1.8" + }, + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "autoload-dev": { + "psr-0": { + "DoctrineTest\\InstantiatorPerformance\\": "tests", + "DoctrineTest\\InstantiatorTest\\": "tests", + "DoctrineTest\\InstantiatorTestAsset\\": "tests" + } + }, + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + } +} diff --git a/src/composer/vendor/doctrine/instantiator/phpmd.xml.dist b/src/composer/vendor/doctrine/instantiator/phpmd.xml.dist new file mode 100644 index 00000000..82541056 --- /dev/null +++ b/src/composer/vendor/doctrine/instantiator/phpmd.xml.dist @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + diff --git a/src/composer/vendor/doctrine/instantiator/phpunit.xml.dist b/src/composer/vendor/doctrine/instantiator/phpunit.xml.dist new file mode 100644 index 00000000..0a8d5709 --- /dev/null +++ b/src/composer/vendor/doctrine/instantiator/phpunit.xml.dist @@ -0,0 +1,22 @@ + + + + ./tests/DoctrineTest/InstantiatorTest + + + + ./src + + + diff --git a/src/composer/vendor/doctrine/instantiator/src/Doctrine/Instantiator/Exception/ExceptionInterface.php b/src/composer/vendor/doctrine/instantiator/src/Doctrine/Instantiator/Exception/ExceptionInterface.php new file mode 100644 index 00000000..3065375a --- /dev/null +++ b/src/composer/vendor/doctrine/instantiator/src/Doctrine/Instantiator/Exception/ExceptionInterface.php @@ -0,0 +1,29 @@ +. + */ + +namespace Doctrine\Instantiator\Exception; + +/** + * Base exception marker interface for the instantiator component + * + * @author Marco Pivetta + */ +interface ExceptionInterface +{ +} diff --git a/src/composer/vendor/doctrine/instantiator/src/Doctrine/Instantiator/Exception/InvalidArgumentException.php b/src/composer/vendor/doctrine/instantiator/src/Doctrine/Instantiator/Exception/InvalidArgumentException.php new file mode 100644 index 00000000..ea8d28c5 --- /dev/null +++ b/src/composer/vendor/doctrine/instantiator/src/Doctrine/Instantiator/Exception/InvalidArgumentException.php @@ -0,0 +1,62 @@ +. + */ + +namespace Doctrine\Instantiator\Exception; + +use InvalidArgumentException as BaseInvalidArgumentException; +use ReflectionClass; + +/** + * Exception for invalid arguments provided to the instantiator + * + * @author Marco Pivetta + */ +class InvalidArgumentException extends BaseInvalidArgumentException implements ExceptionInterface +{ + /** + * @param string $className + * + * @return self + */ + public static function fromNonExistingClass($className) + { + if (interface_exists($className)) { + return new self(sprintf('The provided type "%s" is an interface, and can not be instantiated', $className)); + } + + if (PHP_VERSION_ID >= 50400 && trait_exists($className)) { + return new self(sprintf('The provided type "%s" is a trait, and can not be instantiated', $className)); + } + + return new self(sprintf('The provided class "%s" does not exist', $className)); + } + + /** + * @param ReflectionClass $reflectionClass + * + * @return self + */ + public static function fromAbstractClass(ReflectionClass $reflectionClass) + { + return new self(sprintf( + 'The provided class "%s" is abstract, and can not be instantiated', + $reflectionClass->getName() + )); + } +} diff --git a/src/composer/vendor/doctrine/instantiator/src/Doctrine/Instantiator/Exception/UnexpectedValueException.php b/src/composer/vendor/doctrine/instantiator/src/Doctrine/Instantiator/Exception/UnexpectedValueException.php new file mode 100644 index 00000000..1681e56e --- /dev/null +++ b/src/composer/vendor/doctrine/instantiator/src/Doctrine/Instantiator/Exception/UnexpectedValueException.php @@ -0,0 +1,79 @@ +. + */ + +namespace Doctrine\Instantiator\Exception; + +use Exception; +use ReflectionClass; +use UnexpectedValueException as BaseUnexpectedValueException; + +/** + * Exception for given parameters causing invalid/unexpected state on instantiation + * + * @author Marco Pivetta + */ +class UnexpectedValueException extends BaseUnexpectedValueException implements ExceptionInterface +{ + /** + * @param ReflectionClass $reflectionClass + * @param Exception $exception + * + * @return self + */ + public static function fromSerializationTriggeredException(ReflectionClass $reflectionClass, Exception $exception) + { + return new self( + sprintf( + 'An exception was raised while trying to instantiate an instance of "%s" via un-serialization', + $reflectionClass->getName() + ), + 0, + $exception + ); + } + + /** + * @param ReflectionClass $reflectionClass + * @param string $errorString + * @param int $errorCode + * @param string $errorFile + * @param int $errorLine + * + * @return UnexpectedValueException + */ + public static function fromUncleanUnSerialization( + ReflectionClass $reflectionClass, + $errorString, + $errorCode, + $errorFile, + $errorLine + ) { + return new self( + sprintf( + 'Could not produce an instance of "%s" via un-serialization, since an error was triggered ' + . 'in file "%s" at line "%d"', + $reflectionClass->getName(), + $errorFile, + $errorLine + ), + 0, + new Exception($errorString, $errorCode) + ); + } +} diff --git a/src/composer/vendor/doctrine/instantiator/src/Doctrine/Instantiator/Instantiator.php b/src/composer/vendor/doctrine/instantiator/src/Doctrine/Instantiator/Instantiator.php new file mode 100644 index 00000000..6d5b3b65 --- /dev/null +++ b/src/composer/vendor/doctrine/instantiator/src/Doctrine/Instantiator/Instantiator.php @@ -0,0 +1,273 @@ +. + */ + +namespace Doctrine\Instantiator; + +use Closure; +use Doctrine\Instantiator\Exception\InvalidArgumentException; +use Doctrine\Instantiator\Exception\UnexpectedValueException; +use Exception; +use ReflectionClass; + +/** + * {@inheritDoc} + * + * @author Marco Pivetta + */ +final class Instantiator implements InstantiatorInterface +{ + /** + * Markers used internally by PHP to define whether {@see \unserialize} should invoke + * the method {@see \Serializable::unserialize()} when dealing with classes implementing + * the {@see \Serializable} interface. + */ + const SERIALIZATION_FORMAT_USE_UNSERIALIZER = 'C'; + const SERIALIZATION_FORMAT_AVOID_UNSERIALIZER = 'O'; + + /** + * @var \Closure[] of {@see \Closure} instances used to instantiate specific classes + */ + private static $cachedInstantiators = array(); + + /** + * @var object[] of objects that can directly be cloned + */ + private static $cachedCloneables = array(); + + /** + * {@inheritDoc} + */ + public function instantiate($className) + { + if (isset(self::$cachedCloneables[$className])) { + return clone self::$cachedCloneables[$className]; + } + + if (isset(self::$cachedInstantiators[$className])) { + $factory = self::$cachedInstantiators[$className]; + + return $factory(); + } + + return $this->buildAndCacheFromFactory($className); + } + + /** + * Builds the requested object and caches it in static properties for performance + * + * @param string $className + * + * @return object + */ + private function buildAndCacheFromFactory($className) + { + $factory = self::$cachedInstantiators[$className] = $this->buildFactory($className); + $instance = $factory(); + + if ($this->isSafeToClone(new ReflectionClass($instance))) { + self::$cachedCloneables[$className] = clone $instance; + } + + return $instance; + } + + /** + * Builds a {@see \Closure} capable of instantiating the given $className without + * invoking its constructor. + * + * @param string $className + * + * @return Closure + */ + private function buildFactory($className) + { + $reflectionClass = $this->getReflectionClass($className); + + if ($this->isInstantiableViaReflection($reflectionClass)) { + return function () use ($reflectionClass) { + return $reflectionClass->newInstanceWithoutConstructor(); + }; + } + + $serializedString = sprintf( + '%s:%d:"%s":0:{}', + $this->getSerializationFormat($reflectionClass), + strlen($className), + $className + ); + + $this->checkIfUnSerializationIsSupported($reflectionClass, $serializedString); + + return function () use ($serializedString) { + return unserialize($serializedString); + }; + } + + /** + * @param string $className + * + * @return ReflectionClass + * + * @throws InvalidArgumentException + */ + private function getReflectionClass($className) + { + if (! class_exists($className)) { + throw InvalidArgumentException::fromNonExistingClass($className); + } + + $reflection = new ReflectionClass($className); + + if ($reflection->isAbstract()) { + throw InvalidArgumentException::fromAbstractClass($reflection); + } + + return $reflection; + } + + /** + * @param ReflectionClass $reflectionClass + * @param string $serializedString + * + * @throws UnexpectedValueException + * + * @return void + */ + private function checkIfUnSerializationIsSupported(ReflectionClass $reflectionClass, $serializedString) + { + set_error_handler(function ($code, $message, $file, $line) use ($reflectionClass, & $error) { + $error = UnexpectedValueException::fromUncleanUnSerialization( + $reflectionClass, + $message, + $code, + $file, + $line + ); + }); + + $this->attemptInstantiationViaUnSerialization($reflectionClass, $serializedString); + + restore_error_handler(); + + if ($error) { + throw $error; + } + } + + /** + * @param ReflectionClass $reflectionClass + * @param string $serializedString + * + * @throws UnexpectedValueException + * + * @return void + */ + private function attemptInstantiationViaUnSerialization(ReflectionClass $reflectionClass, $serializedString) + { + try { + unserialize($serializedString); + } catch (Exception $exception) { + restore_error_handler(); + + throw UnexpectedValueException::fromSerializationTriggeredException($reflectionClass, $exception); + } + } + + /** + * @param ReflectionClass $reflectionClass + * + * @return bool + */ + private function isInstantiableViaReflection(ReflectionClass $reflectionClass) + { + if (\PHP_VERSION_ID >= 50600) { + return ! ($this->hasInternalAncestors($reflectionClass) && $reflectionClass->isFinal()); + } + + return \PHP_VERSION_ID >= 50400 && ! $this->hasInternalAncestors($reflectionClass); + } + + /** + * Verifies whether the given class is to be considered internal + * + * @param ReflectionClass $reflectionClass + * + * @return bool + */ + private function hasInternalAncestors(ReflectionClass $reflectionClass) + { + do { + if ($reflectionClass->isInternal()) { + return true; + } + } while ($reflectionClass = $reflectionClass->getParentClass()); + + return false; + } + + /** + * Verifies if the given PHP version implements the `Serializable` interface serialization + * with an incompatible serialization format. If that's the case, use serialization marker + * "C" instead of "O". + * + * @link http://news.php.net/php.internals/74654 + * + * @param ReflectionClass $reflectionClass + * + * @return string the serialization format marker, either self::SERIALIZATION_FORMAT_USE_UNSERIALIZER + * or self::SERIALIZATION_FORMAT_AVOID_UNSERIALIZER + */ + private function getSerializationFormat(ReflectionClass $reflectionClass) + { + if ($this->isPhpVersionWithBrokenSerializationFormat() + && $reflectionClass->implementsInterface('Serializable') + ) { + return self::SERIALIZATION_FORMAT_USE_UNSERIALIZER; + } + + return self::SERIALIZATION_FORMAT_AVOID_UNSERIALIZER; + } + + /** + * Checks whether the current PHP runtime uses an incompatible serialization format + * + * @return bool + */ + private function isPhpVersionWithBrokenSerializationFormat() + { + return PHP_VERSION_ID === 50429 || PHP_VERSION_ID === 50513; + } + + /** + * Checks if a class is cloneable + * + * @param ReflectionClass $reflection + * + * @return bool + */ + private function isSafeToClone(ReflectionClass $reflection) + { + if (method_exists($reflection, 'isCloneable') && ! $reflection->isCloneable()) { + return false; + } + + // not cloneable if it implements `__clone`, as we want to avoid calling it + return ! $reflection->hasMethod('__clone'); + } +} diff --git a/src/composer/vendor/doctrine/instantiator/src/Doctrine/Instantiator/InstantiatorInterface.php b/src/composer/vendor/doctrine/instantiator/src/Doctrine/Instantiator/InstantiatorInterface.php new file mode 100644 index 00000000..b665bea8 --- /dev/null +++ b/src/composer/vendor/doctrine/instantiator/src/Doctrine/Instantiator/InstantiatorInterface.php @@ -0,0 +1,37 @@ +. + */ + +namespace Doctrine\Instantiator; + +/** + * Instantiator provides utility methods to build objects without invoking their constructors + * + * @author Marco Pivetta + */ +interface InstantiatorInterface +{ + /** + * @param string $className + * + * @return object + * + * @throws \Doctrine\Instantiator\Exception\ExceptionInterface + */ + public function instantiate($className); +} diff --git a/src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorPerformance/InstantiatorPerformanceEvent.php b/src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorPerformance/InstantiatorPerformanceEvent.php new file mode 100644 index 00000000..3e8fc6ff --- /dev/null +++ b/src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorPerformance/InstantiatorPerformanceEvent.php @@ -0,0 +1,96 @@ +. + */ + +namespace DoctrineTest\InstantiatorPerformance; + +use Athletic\AthleticEvent; +use Doctrine\Instantiator\Instantiator; + +/** + * Performance tests for {@see \Doctrine\Instantiator\Instantiator} + * + * @author Marco Pivetta + */ +class InstantiatorPerformanceEvent extends AthleticEvent +{ + /** + * @var \Doctrine\Instantiator\Instantiator + */ + private $instantiator; + + /** + * {@inheritDoc} + */ + protected function setUp() + { + $this->instantiator = new Instantiator(); + + $this->instantiator->instantiate(__CLASS__); + $this->instantiator->instantiate('ArrayObject'); + $this->instantiator->instantiate('DoctrineTest\\InstantiatorTestAsset\\SimpleSerializableAsset'); + $this->instantiator->instantiate('DoctrineTest\\InstantiatorTestAsset\\SerializableArrayObjectAsset'); + $this->instantiator->instantiate('DoctrineTest\\InstantiatorTestAsset\\UnCloneableAsset'); + } + + /** + * @iterations 20000 + * @baseline + * @group instantiation + */ + public function testInstantiateSelf() + { + $this->instantiator->instantiate(__CLASS__); + } + + /** + * @iterations 20000 + * @group instantiation + */ + public function testInstantiateInternalClass() + { + $this->instantiator->instantiate('ArrayObject'); + } + + /** + * @iterations 20000 + * @group instantiation + */ + public function testInstantiateSimpleSerializableAssetClass() + { + $this->instantiator->instantiate('DoctrineTest\\InstantiatorTestAsset\\SimpleSerializableAsset'); + } + + /** + * @iterations 20000 + * @group instantiation + */ + public function testInstantiateSerializableArrayObjectAsset() + { + $this->instantiator->instantiate('DoctrineTest\\InstantiatorTestAsset\\SerializableArrayObjectAsset'); + } + + /** + * @iterations 20000 + * @group instantiation + */ + public function testInstantiateUnCloneableAsset() + { + $this->instantiator->instantiate('DoctrineTest\\InstantiatorTestAsset\\UnCloneableAsset'); + } +} diff --git a/src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTest/Exception/InvalidArgumentExceptionTest.php b/src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTest/Exception/InvalidArgumentExceptionTest.php new file mode 100644 index 00000000..39d9b94d --- /dev/null +++ b/src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTest/Exception/InvalidArgumentExceptionTest.php @@ -0,0 +1,83 @@ +. + */ + +namespace DoctrineTest\InstantiatorTest\Exception; + +use Doctrine\Instantiator\Exception\InvalidArgumentException; +use PHPUnit_Framework_TestCase; +use ReflectionClass; + +/** + * Tests for {@see \Doctrine\Instantiator\Exception\InvalidArgumentException} + * + * @author Marco Pivetta + * + * @covers \Doctrine\Instantiator\Exception\InvalidArgumentException + */ +class InvalidArgumentExceptionTest extends PHPUnit_Framework_TestCase +{ + public function testFromNonExistingTypeWithNonExistingClass() + { + $className = __CLASS__ . uniqid(); + $exception = InvalidArgumentException::fromNonExistingClass($className); + + $this->assertInstanceOf('Doctrine\\Instantiator\\Exception\\InvalidArgumentException', $exception); + $this->assertSame('The provided class "' . $className . '" does not exist', $exception->getMessage()); + } + + public function testFromNonExistingTypeWithTrait() + { + if (PHP_VERSION_ID < 50400) { + $this->markTestSkipped('Need at least PHP 5.4.0, as this test requires traits support to run'); + } + + $exception = InvalidArgumentException::fromNonExistingClass( + 'DoctrineTest\\InstantiatorTestAsset\\SimpleTraitAsset' + ); + + $this->assertSame( + 'The provided type "DoctrineTest\\InstantiatorTestAsset\\SimpleTraitAsset" is a trait, ' + . 'and can not be instantiated', + $exception->getMessage() + ); + } + + public function testFromNonExistingTypeWithInterface() + { + $exception = InvalidArgumentException::fromNonExistingClass('Doctrine\\Instantiator\\InstantiatorInterface'); + + $this->assertSame( + 'The provided type "Doctrine\\Instantiator\\InstantiatorInterface" is an interface, ' + . 'and can not be instantiated', + $exception->getMessage() + ); + } + + public function testFromAbstractClass() + { + $reflection = new ReflectionClass('DoctrineTest\\InstantiatorTestAsset\\AbstractClassAsset'); + $exception = InvalidArgumentException::fromAbstractClass($reflection); + + $this->assertSame( + 'The provided class "DoctrineTest\\InstantiatorTestAsset\\AbstractClassAsset" is abstract, ' + . 'and can not be instantiated', + $exception->getMessage() + ); + } +} diff --git a/src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTest/Exception/UnexpectedValueExceptionTest.php b/src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTest/Exception/UnexpectedValueExceptionTest.php new file mode 100644 index 00000000..84154e73 --- /dev/null +++ b/src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTest/Exception/UnexpectedValueExceptionTest.php @@ -0,0 +1,69 @@ +. + */ + +namespace DoctrineTest\InstantiatorTest\Exception; + +use Doctrine\Instantiator\Exception\UnexpectedValueException; +use Exception; +use PHPUnit_Framework_TestCase; +use ReflectionClass; + +/** + * Tests for {@see \Doctrine\Instantiator\Exception\UnexpectedValueException} + * + * @author Marco Pivetta + * + * @covers \Doctrine\Instantiator\Exception\UnexpectedValueException + */ +class UnexpectedValueExceptionTest extends PHPUnit_Framework_TestCase +{ + public function testFromSerializationTriggeredException() + { + $reflectionClass = new ReflectionClass($this); + $previous = new Exception(); + $exception = UnexpectedValueException::fromSerializationTriggeredException($reflectionClass, $previous); + + $this->assertInstanceOf('Doctrine\\Instantiator\\Exception\\UnexpectedValueException', $exception); + $this->assertSame($previous, $exception->getPrevious()); + $this->assertSame( + 'An exception was raised while trying to instantiate an instance of "' + . __CLASS__ . '" via un-serialization', + $exception->getMessage() + ); + } + + public function testFromUncleanUnSerialization() + { + $reflection = new ReflectionClass('DoctrineTest\\InstantiatorTestAsset\\AbstractClassAsset'); + $exception = UnexpectedValueException::fromUncleanUnSerialization($reflection, 'foo', 123, 'bar', 456); + + $this->assertInstanceOf('Doctrine\\Instantiator\\Exception\\UnexpectedValueException', $exception); + $this->assertSame( + 'Could not produce an instance of "DoctrineTest\\InstantiatorTestAsset\\AbstractClassAsset" ' + . 'via un-serialization, since an error was triggered in file "bar" at line "456"', + $exception->getMessage() + ); + + $previous = $exception->getPrevious(); + + $this->assertInstanceOf('Exception', $previous); + $this->assertSame('foo', $previous->getMessage()); + $this->assertSame(123, $previous->getCode()); + } +} diff --git a/src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTest/InstantiatorTest.php b/src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTest/InstantiatorTest.php new file mode 100644 index 00000000..0a2cb931 --- /dev/null +++ b/src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTest/InstantiatorTest.php @@ -0,0 +1,219 @@ +. + */ + +namespace DoctrineTest\InstantiatorTest; + +use Doctrine\Instantiator\Exception\UnexpectedValueException; +use Doctrine\Instantiator\Instantiator; +use PHPUnit_Framework_TestCase; +use ReflectionClass; + +/** + * Tests for {@see \Doctrine\Instantiator\Instantiator} + * + * @author Marco Pivetta + * + * @covers \Doctrine\Instantiator\Instantiator + */ +class InstantiatorTest extends PHPUnit_Framework_TestCase +{ + /** + * @var Instantiator + */ + private $instantiator; + + /** + * {@inheritDoc} + */ + protected function setUp() + { + $this->instantiator = new Instantiator(); + } + + /** + * @param string $className + * + * @dataProvider getInstantiableClasses + */ + public function testCanInstantiate($className) + { + $this->assertInstanceOf($className, $this->instantiator->instantiate($className)); + } + + /** + * @param string $className + * + * @dataProvider getInstantiableClasses + */ + public function testInstantiatesSeparateInstances($className) + { + $instance1 = $this->instantiator->instantiate($className); + $instance2 = $this->instantiator->instantiate($className); + + $this->assertEquals($instance1, $instance2); + $this->assertNotSame($instance1, $instance2); + } + + public function testExceptionOnUnSerializationException() + { + if (defined('HHVM_VERSION')) { + $this->markTestSkipped( + 'As of facebook/hhvm#3432, HHVM has no PDORow, and therefore ' + . ' no internal final classes that cannot be instantiated' + ); + } + + $className = 'DoctrineTest\\InstantiatorTestAsset\\UnserializeExceptionArrayObjectAsset'; + + if (\PHP_VERSION_ID >= 50600) { + $className = 'PDORow'; + } + + if (\PHP_VERSION_ID === 50429 || \PHP_VERSION_ID === 50513) { + $className = 'DoctrineTest\\InstantiatorTestAsset\\SerializableArrayObjectAsset'; + } + + $this->setExpectedException('Doctrine\\Instantiator\\Exception\\UnexpectedValueException'); + + $this->instantiator->instantiate($className); + } + + public function testNoticeOnUnSerializationException() + { + if (\PHP_VERSION_ID >= 50600) { + $this->markTestSkipped( + 'PHP 5.6 supports `ReflectionClass#newInstanceWithoutConstructor()` for some internal classes' + ); + } + + try { + $this->instantiator->instantiate('DoctrineTest\\InstantiatorTestAsset\\WakeUpNoticesAsset'); + + $this->fail('No exception was raised'); + } catch (UnexpectedValueException $exception) { + $wakeUpNoticesReflection = new ReflectionClass('DoctrineTest\\InstantiatorTestAsset\\WakeUpNoticesAsset'); + $previous = $exception->getPrevious(); + + $this->assertInstanceOf('Exception', $previous); + + // in PHP 5.4.29 and PHP 5.5.13, this case is not a notice, but an exception being thrown + if (! (\PHP_VERSION_ID === 50429 || \PHP_VERSION_ID === 50513)) { + $this->assertSame( + 'Could not produce an instance of "DoctrineTest\\InstantiatorTestAsset\WakeUpNoticesAsset" ' + . 'via un-serialization, since an error was triggered in file "' + . $wakeUpNoticesReflection->getFileName() . '" at line "36"', + $exception->getMessage() + ); + + $this->assertSame('Something went bananas while un-serializing this instance', $previous->getMessage()); + $this->assertSame(\E_USER_NOTICE, $previous->getCode()); + } + } + } + + /** + * @param string $invalidClassName + * + * @dataProvider getInvalidClassNames + */ + public function testInstantiationFromNonExistingClass($invalidClassName) + { + $this->setExpectedException('Doctrine\\Instantiator\\Exception\\InvalidArgumentException'); + + $this->instantiator->instantiate($invalidClassName); + } + + public function testInstancesAreNotCloned() + { + $className = 'TemporaryClass' . uniqid(); + + eval('namespace ' . __NAMESPACE__ . '; class ' . $className . '{}'); + + $instance = $this->instantiator->instantiate(__NAMESPACE__ . '\\' . $className); + + $instance->foo = 'bar'; + + $instance2 = $this->instantiator->instantiate(__NAMESPACE__ . '\\' . $className); + + $this->assertObjectNotHasAttribute('foo', $instance2); + } + + /** + * Provides a list of instantiable classes (existing) + * + * @return string[][] + */ + public function getInstantiableClasses() + { + $classes = array( + array('stdClass'), + array(__CLASS__), + array('Doctrine\\Instantiator\\Instantiator'), + array('Exception'), + array('PharException'), + array('DoctrineTest\\InstantiatorTestAsset\\SimpleSerializableAsset'), + array('DoctrineTest\\InstantiatorTestAsset\\ExceptionAsset'), + array('DoctrineTest\\InstantiatorTestAsset\\FinalExceptionAsset'), + array('DoctrineTest\\InstantiatorTestAsset\\PharExceptionAsset'), + array('DoctrineTest\\InstantiatorTestAsset\\UnCloneableAsset'), + array('DoctrineTest\\InstantiatorTestAsset\\XMLReaderAsset'), + ); + + if (\PHP_VERSION_ID === 50429 || \PHP_VERSION_ID === 50513) { + return $classes; + } + + $classes = array_merge( + $classes, + array( + array('PharException'), + array('ArrayObject'), + array('DoctrineTest\\InstantiatorTestAsset\\ArrayObjectAsset'), + array('DoctrineTest\\InstantiatorTestAsset\\SerializableArrayObjectAsset'), + ) + ); + + if (\PHP_VERSION_ID >= 50600) { + $classes[] = array('DoctrineTest\\InstantiatorTestAsset\\WakeUpNoticesAsset'); + $classes[] = array('DoctrineTest\\InstantiatorTestAsset\\UnserializeExceptionArrayObjectAsset'); + } + + return $classes; + } + + /** + * Provides a list of instantiable classes (existing) + * + * @return string[][] + */ + public function getInvalidClassNames() + { + $classNames = array( + array(__CLASS__ . uniqid()), + array('Doctrine\\Instantiator\\InstantiatorInterface'), + array('DoctrineTest\\InstantiatorTestAsset\\AbstractClassAsset'), + ); + + if (\PHP_VERSION_ID >= 50400) { + $classNames[] = array('DoctrineTest\\InstantiatorTestAsset\\SimpleTraitAsset'); + } + + return $classNames; + } +} diff --git a/src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/AbstractClassAsset.php b/src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/AbstractClassAsset.php new file mode 100644 index 00000000..fbe28ddd --- /dev/null +++ b/src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/AbstractClassAsset.php @@ -0,0 +1,29 @@ +. + */ + +namespace DoctrineTest\InstantiatorTestAsset; + +/** + * A simple asset for an abstract class + * + * @author Marco Pivetta + */ +abstract class AbstractClassAsset +{ +} diff --git a/src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/ArrayObjectAsset.php b/src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/ArrayObjectAsset.php new file mode 100644 index 00000000..56146d70 --- /dev/null +++ b/src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/ArrayObjectAsset.php @@ -0,0 +1,41 @@ +. + */ + +namespace DoctrineTest\InstantiatorTestAsset; + +use ArrayObject; +use BadMethodCallException; + +/** + * Test asset that extends an internal PHP class + * + * @author Marco Pivetta + */ +class ArrayObjectAsset extends ArrayObject +{ + /** + * Constructor - should not be called + * + * @throws BadMethodCallException + */ + public function __construct() + { + throw new BadMethodCallException('Not supposed to be called!'); + } +} diff --git a/src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/ExceptionAsset.php b/src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/ExceptionAsset.php new file mode 100644 index 00000000..43bbe46b --- /dev/null +++ b/src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/ExceptionAsset.php @@ -0,0 +1,41 @@ +. + */ + +namespace DoctrineTest\InstantiatorTestAsset; + +use BadMethodCallException; +use Exception; + +/** + * Test asset that extends an internal PHP base exception + * + * @author Marco Pivetta + */ +class ExceptionAsset extends Exception +{ + /** + * Constructor - should not be called + * + * @throws BadMethodCallException + */ + public function __construct() + { + throw new BadMethodCallException('Not supposed to be called!'); + } +} diff --git a/src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/FinalExceptionAsset.php b/src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/FinalExceptionAsset.php new file mode 100644 index 00000000..7d268f5b --- /dev/null +++ b/src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/FinalExceptionAsset.php @@ -0,0 +1,41 @@ +. + */ + +namespace DoctrineTest\InstantiatorTestAsset; + +use BadMethodCallException; +use Exception; + +/** + * Test asset that extends an internal PHP base exception + * + * @author Marco Pivetta + */ +final class FinalExceptionAsset extends Exception +{ + /** + * Constructor - should not be called + * + * @throws BadMethodCallException + */ + public function __construct() + { + throw new BadMethodCallException('Not supposed to be called!'); + } +} diff --git a/src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/PharAsset.php b/src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/PharAsset.php new file mode 100644 index 00000000..553fd561 --- /dev/null +++ b/src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/PharAsset.php @@ -0,0 +1,41 @@ +. + */ + +namespace DoctrineTest\InstantiatorTestAsset; + +use BadMethodCallException; +use Phar; + +/** + * Test asset that extends an internal PHP class + * + * @author Marco Pivetta + */ +class PharAsset extends Phar +{ + /** + * Constructor - should not be called + * + * @throws BadMethodCallException + */ + public function __construct() + { + throw new BadMethodCallException('Not supposed to be called!'); + } +} diff --git a/src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/PharExceptionAsset.php b/src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/PharExceptionAsset.php new file mode 100644 index 00000000..42bf73e7 --- /dev/null +++ b/src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/PharExceptionAsset.php @@ -0,0 +1,44 @@ +. + */ + +namespace DoctrineTest\InstantiatorTestAsset; + +use BadMethodCallException; +use PharException; + +/** + * Test asset that extends an internal PHP class + * This class should be serializable without problems + * and without getting the "Erroneous data format for unserializing" + * error + * + * @author Marco Pivetta + */ +class PharExceptionAsset extends PharException +{ + /** + * Constructor - should not be called + * + * @throws BadMethodCallException + */ + public function __construct() + { + throw new BadMethodCallException('Not supposed to be called!'); + } +} diff --git a/src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/SerializableArrayObjectAsset.php b/src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/SerializableArrayObjectAsset.php new file mode 100644 index 00000000..ba19aaf6 --- /dev/null +++ b/src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/SerializableArrayObjectAsset.php @@ -0,0 +1,62 @@ +. + */ + +namespace DoctrineTest\InstantiatorTestAsset; + +use ArrayObject; +use BadMethodCallException; +use Serializable; + +/** + * Serializable test asset that also extends an internal class + * + * @author Marco Pivetta + */ +class SerializableArrayObjectAsset extends ArrayObject implements Serializable +{ + /** + * Constructor - should not be called + * + * @throws BadMethodCallException + */ + public function __construct() + { + throw new BadMethodCallException('Not supposed to be called!'); + } + + /** + * {@inheritDoc} + */ + public function serialize() + { + return ''; + } + + /** + * {@inheritDoc} + * + * Should not be called + * + * @throws BadMethodCallException + */ + public function unserialize($serialized) + { + throw new BadMethodCallException('Not supposed to be called!'); + } +} diff --git a/src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/SimpleSerializableAsset.php b/src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/SimpleSerializableAsset.php new file mode 100644 index 00000000..39f84a6c --- /dev/null +++ b/src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/SimpleSerializableAsset.php @@ -0,0 +1,61 @@ +. + */ + +namespace DoctrineTest\InstantiatorTestAsset; + +use BadMethodCallException; +use Serializable; + +/** + * Base serializable test asset + * + * @author Marco Pivetta + */ +class SimpleSerializableAsset implements Serializable +{ + /** + * Constructor - should not be called + * + * @throws BadMethodCallException + */ + public function __construct() + { + throw new BadMethodCallException('Not supposed to be called!'); + } + + /** + * {@inheritDoc} + */ + public function serialize() + { + return ''; + } + + /** + * {@inheritDoc} + * + * Should not be called + * + * @throws BadMethodCallException + */ + public function unserialize($serialized) + { + throw new BadMethodCallException('Not supposed to be called!'); + } +} diff --git a/src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/SimpleTraitAsset.php b/src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/SimpleTraitAsset.php new file mode 100644 index 00000000..04e78069 --- /dev/null +++ b/src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/SimpleTraitAsset.php @@ -0,0 +1,29 @@ +. + */ + +namespace DoctrineTest\InstantiatorTestAsset; + +/** + * A simple trait with no attached logic + * + * @author Marco Pivetta + */ +trait SimpleTraitAsset +{ +} diff --git a/src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/UnCloneableAsset.php b/src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/UnCloneableAsset.php new file mode 100644 index 00000000..7d03bdab --- /dev/null +++ b/src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/UnCloneableAsset.php @@ -0,0 +1,50 @@ +. + */ + +namespace DoctrineTest\InstantiatorTestAsset; + +use BadMethodCallException; + +/** + * Base un-cloneable asset + * + * @author Marco Pivetta + */ +class UnCloneableAsset +{ + /** + * Constructor - should not be called + * + * @throws BadMethodCallException + */ + public function __construct() + { + throw new BadMethodCallException('Not supposed to be called!'); + } + + /** + * Magic `__clone` - should not be invoked + * + * @throws BadMethodCallException + */ + public function __clone() + { + throw new BadMethodCallException('Not supposed to be called!'); + } +} diff --git a/src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/UnserializeExceptionArrayObjectAsset.php b/src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/UnserializeExceptionArrayObjectAsset.php new file mode 100644 index 00000000..b348a405 --- /dev/null +++ b/src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/UnserializeExceptionArrayObjectAsset.php @@ -0,0 +1,39 @@ +. + */ + +namespace DoctrineTest\InstantiatorTestAsset; + +use ArrayObject; +use BadMethodCallException; + +/** + * A simple asset for an abstract class + * + * @author Marco Pivetta + */ +class UnserializeExceptionArrayObjectAsset extends ArrayObject +{ + /** + * {@inheritDoc} + */ + public function __wakeup() + { + throw new BadMethodCallException(); + } +} diff --git a/src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/WakeUpNoticesAsset.php b/src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/WakeUpNoticesAsset.php new file mode 100644 index 00000000..18dc6711 --- /dev/null +++ b/src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/WakeUpNoticesAsset.php @@ -0,0 +1,38 @@ +. + */ + +namespace DoctrineTest\InstantiatorTestAsset; + +use ArrayObject; + +/** + * A simple asset for an abstract class + * + * @author Marco Pivetta + */ +class WakeUpNoticesAsset extends ArrayObject +{ + /** + * Wakeup method called after un-serialization + */ + public function __wakeup() + { + trigger_error('Something went bananas while un-serializing this instance'); + } +} diff --git a/src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/XMLReaderAsset.php b/src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/XMLReaderAsset.php new file mode 100644 index 00000000..39ee6992 --- /dev/null +++ b/src/composer/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/XMLReaderAsset.php @@ -0,0 +1,41 @@ +. + */ + +namespace DoctrineTest\InstantiatorTestAsset; + +use BadMethodCallException; +use XMLReader; + +/** + * Test asset that extends an internal PHP class + * + * @author Dave Marshall + */ +class XMLReaderAsset extends XMLReader +{ + /** + * Constructor - should not be called + * + * @throws BadMethodCallException + */ + public function __construct() + { + throw new BadMethodCallException('Not supposed to be called!'); + } +} diff --git a/src/composer/vendor/league/container/CHANGELOG.md b/src/composer/vendor/league/container/CHANGELOG.md new file mode 100644 index 00000000..cb2a9251 --- /dev/null +++ b/src/composer/vendor/league/container/CHANGELOG.md @@ -0,0 +1,108 @@ +# Changelog + +All Notable changes to `League\Container` will be documented in this file + +## 2.2.0 + +### Changed +- Service providers can now be added multiple times by giving them a signature. + +## 2.1.0 + +### Added +- Allow resolving of `RawArgument` objects as first class dependencies. + +### Changed +- Unnecessary recursion removed from `Container::get`. + +## 2.0.3 + +### Fixed +- Bug where delegating container was not passed to delegate when needed. +- Bug where `Container::extend` would not return a shared definition to extend. + +## 2.0.2 + +### Fixed +- Bug introduced in 2.0.1 where shared definitions registered via a service provider would never be returned as shared. + +## 2.0.1 + +### Fixed +- Bug where shared definitions were not stored as shared. + +## 2.0.0 + +### Added +- Now implementation of the container-interop project. +- `BootableServiceProviderInterface` for eagerly loaded service providers. +- Delegate container functionality. +- `RawArgument` to ensure scalars are not resolved from the container but seen as an argument. + +### Altered +- Refactor of definition functionality. +- `Container::share` replaces `singleton` functionality to improve understanding. +- Auto wiring is now disabled by default. +- Auto wiring abstracted to be a delegate container `ReflectionContainer` handling all reflection based functionality. +- Inflection functionality abstracted to an aggregate. +- Service provider functionality abstracted to an aggregate. +- Much bloat removed. +- `Container::call` now proxies to `ReflectionContainer::call` and handles argument resolution in a much more efficient way. + +### Removed +- Ability to register invokables, this functionality added a layer of complexity too large for the problem it solved. +- Container no longer accepts a configuration array, this functionality will now be provided by an external service provider package. + +## 1.4.0 + +### Added +- Added `isRegisteredCallable` method to public API. +- Invoking `call` now accepts named arguments at runtime. + +### Fixed +- Container now stores instantiated Service Providers after first instantiation. +- Extending a definition now looks in Service Providers as well as just Definitions. + +## 1.3.1 - 2015-02-21 + +### Fixed +- Fixed bug where arbitrary values were attempted to be resolved as classes. + +## 1.3.0 - 2015-02-09 + +### Added +- Added `ServiceProvider` functionality to allow cleaner resolving of complex dependencies. +- Added `Inflector` functionality to allow for manipulation of resolved objects of a specific type. +- Improvements to DRY throughout the package. + +### Fixed +- Setter in `ContainerAwareTrait` now returns self (`$this`). + +## 1.2.1 - 2015-01-29 + +### Fixed +- Allow arbitrary values to be registered via container config. + +## 1.2.0 - 2015-01-13 + +### Added +- Improvements to `Container::call` functionality. + +### Fixed +- General code tidy. +- Improvements to test suite. + +## 1.1.1 - 2015-01-13 + +### Fixed +- Allow singleton to be passed as method argument. + +## 1.1.0 - 2015-01-12 + +### Added +- Addition of `ContainerAwareTrait` to provide functionality from `ContainerAwareInterface`. + +## 1.0.0 - 2015-01-12 + +### Added +- Migrated from [Orno\Di](https://github.com/orno/di). diff --git a/src/composer/vendor/league/container/CONTRIBUTING.md b/src/composer/vendor/league/container/CONTRIBUTING.md new file mode 100644 index 00000000..e60a2612 --- /dev/null +++ b/src/composer/vendor/league/container/CONTRIBUTING.md @@ -0,0 +1,29 @@ +# Contributing + +Contributions are **welcome** and will be fully **credited**. + +We accept contributions via Pull Requests on [Github](https://github.com/thephpleague/container). + +## Pull Requests + +- **[PSR-2 Coding Standard](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md)** - The easiest way to apply the conventions is to install [PHP Code Sniffer](http://pear.php.net/package/PHP_CodeSniffer). + +- **Add tests!** - Your patch won't be accepted if it doesn't have tests. + +- **Document any change in behaviour** - Make sure the `README.md` and any other relevant documentation are kept up-to-date. + +- **Consider our release cycle** - We try to follow [SemVer v2.0.0](http://semver.org/). Randomly breaking public APIs is not an option. + +- **Create feature branches** - Don't ask us to pull from your master branch. + +- **One pull request per feature** - If you want to do more than one thing, send multiple pull requests. + +- **Send coherent history** - Make sure each individual commit in your pull request is meaningful. If you had to make multiple intermediate commits while developing, please squash them before submitting. + +## Running Tests + +``` bash +$ phpunit +``` + +**Happy coding**! diff --git a/src/composer/vendor/league/container/LICENSE.md b/src/composer/vendor/league/container/LICENSE.md new file mode 100644 index 00000000..2b681a4f --- /dev/null +++ b/src/composer/vendor/league/container/LICENSE.md @@ -0,0 +1,21 @@ +# The MIT License (MIT) + +Copyright (c) 2014 Phil Bennett + +> Permission is hereby granted, free of charge, to any person obtaining a copy +> of this software and associated documentation files (the "Software"), to deal +> in the Software without restriction, including without limitation the rights +> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +> copies of the Software, and to permit persons to whom the Software is +> furnished to do so, subject to the following conditions: +> +> The above copyright notice and this permission notice shall be included in +> all copies or substantial portions of the Software. +> +> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +> THE SOFTWARE. diff --git a/src/composer/vendor/league/container/README.md b/src/composer/vendor/league/container/README.md new file mode 100644 index 00000000..536ec6de --- /dev/null +++ b/src/composer/vendor/league/container/README.md @@ -0,0 +1,67 @@ +# Container (Dependency Injection) + +[![Author](http://img.shields.io/badge/author-@philipobenito-blue.svg?style=flat-square)](https://twitter.com/philipobenito) +[![Latest Version](https://img.shields.io/github/release/thephpleague/container.svg?style=flat-square)](https://github.com/thephpleague/container/releases) +[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE.md) +[![Build Status](https://img.shields.io/travis/thephpleague/container/master.svg?style=flat-square)](https://travis-ci.org/thephpleague/container) +[![Coverage Status](https://img.shields.io/scrutinizer/coverage/g/thephpleague/container.svg?style=flat-square)](https://scrutinizer-ci.com/g/thephpleague/container/code-structure) +[![Quality Score](https://img.shields.io/scrutinizer/g/thephpleague/container.svg?style=flat-square)](https://scrutinizer-ci.com/g/thephpleague/container) +[![Total Downloads](https://img.shields.io/packagist/dt/league/container.svg?style=flat-square)](https://packagist.org/packages/league/container) + +[![SensioLabsInsight](https://insight.sensiolabs.com/projects/ad6b4c3e-8f93-4968-8dd3-391d39a4c3c2/big.png)](https://insight.sensiolabs.com/projects/ad6b4c3e-8f93-4968-8dd3-391d39a4c3c2) + +This package is compliant with [PSR-1], [PSR-2] and [PSR-4]. If you notice compliance oversights, +please send a patch via pull request. + +[PSR-1]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-1-basic-coding-standard.md +[PSR-2]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md +[PSR-4]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader.md + +## Install + +Via Composer + +``` bash +$ composer require league/container +``` + +## Requirements + +The following versions of PHP are supported by this version. + +* PHP 5.4 +* PHP 5.5 +* PHP 5.6 +* PHP 7.0 +* HHVM + +## Documentation + +Container has [full documentation](http://container.thephpleague.com), powered by [Jekyll](http://jekyllrb.com/). + +Contribute to this documentation in the [gh-pages branch](https://github.com/thephpleague/container/tree/gh-pages/). + +## Testing + +``` bash +$ vendor/bin/phpunit +``` + +## Contributing + +Please see [CONTRIBUTING](https://github.com/thephpleague/container/blob/master/CONTRIBUTING.md) for details. + +## Security + +If you discover any security related issues, please email philipobenito@gmail.com instead of using the issue tracker. + +## Credits + +- [Phil Bennett](https://github.com/philipobenito) +- [All Contributors](https://github.com/thephpleague/container/contributors) + +All `Orno\Di` contributions can be found [here](https://github.com/orno/di/graphs/contributors). + +## License + +The MIT License (MIT). Please see [License File](https://github.com/thephpleague/container/blob/master/LICENSE.md) for more information. diff --git a/src/composer/vendor/league/container/composer.json b/src/composer/vendor/league/container/composer.json new file mode 100644 index 00000000..26a17b7b --- /dev/null +++ b/src/composer/vendor/league/container/composer.json @@ -0,0 +1,52 @@ +{ + "name": "league/container", + "description": "A fast and intuitive dependency injection container.", + "keywords": [ + "league", + "container", + "dependency", + "injection", + "di", + "service", + "provider" + ], + "homepage": "https://github.com/thephpleague/container", + "license": "MIT", + "authors": [ + { + "name": "Phil Bennett", + "email": "philipobenito@gmail.com", + "homepage": "http://www.philipobenito.com", + "role": "Developer" + } + ], + "require": { + "php": ">=5.4.0", + "container-interop/container-interop": "^1.1" + }, + "require-dev": { + "phpunit/phpunit" : "4.*" + }, + "provide": { + "container-interop/container-interop-implementation": "^1.1" + }, + "replace": { + "orno/di": "~2.0" + }, + "autoload": { + "psr-4": { + "League\\Container\\": "src" + } + }, + "autoload-dev": { + "psr-4": { + "League\\Container\\Test\\": "tests" + } + }, + "extra": { + "branch-alias": { + "dev-master": "2.x-dev", + "dev-1.x": "1.x-dev" + } + } +} diff --git a/src/composer/vendor/league/container/src/Argument/ArgumentResolverInterface.php b/src/composer/vendor/league/container/src/Argument/ArgumentResolverInterface.php new file mode 100644 index 00000000..2691d59c --- /dev/null +++ b/src/composer/vendor/league/container/src/Argument/ArgumentResolverInterface.php @@ -0,0 +1,26 @@ +getValue(); + continue; + } + + if (! is_string($arg)) { + continue; + } + + $container = $this->getContainer(); + + if (is_null($container) && $this instanceof ReflectionContainer) { + $container = $this; + } + + if (! is_null($container) && $container->has($arg)) { + $arg = $container->get($arg); + + if ($arg instanceof RawArgumentInterface) { + $arg = $arg->getValue(); + } + + continue; + } + } + + return $arguments; + } + + /** + * {@inheritdoc} + */ + public function reflectArguments(ReflectionFunctionAbstract $method, array $args = []) + { + $arguments = array_map(function (ReflectionParameter $param) use ($method, $args) { + $name = $param->getName(); + $class = $param->getClass(); + + if (array_key_exists($name, $args)) { + return $args[$name]; + } + + if (! is_null($class)) { + return $class->getName(); + } + + if ($param->isDefaultValueAvailable()) { + return $param->getDefaultValue(); + } + + throw new NotFoundException(sprintf( + 'Unable to resolve a value for parameter (%s) in the function/method (%s)', + $name, + $method->getName() + )); + }, $method->getParameters()); + + return $this->resolveArguments($arguments); + } + + /** + * @return ContainerInterface + */ + abstract public function getContainer(); +} diff --git a/src/composer/vendor/league/container/src/Argument/RawArgument.php b/src/composer/vendor/league/container/src/Argument/RawArgument.php new file mode 100644 index 00000000..a52e4928 --- /dev/null +++ b/src/composer/vendor/league/container/src/Argument/RawArgument.php @@ -0,0 +1,27 @@ +value = $value; + } + + /** + * {@inheritdoc} + */ + public function getValue() + { + return $this->value; + } +} diff --git a/src/composer/vendor/league/container/src/Argument/RawArgumentInterface.php b/src/composer/vendor/league/container/src/Argument/RawArgumentInterface.php new file mode 100644 index 00000000..85d92211 --- /dev/null +++ b/src/composer/vendor/league/container/src/Argument/RawArgumentInterface.php @@ -0,0 +1,13 @@ +providers = (is_null($providers)) + ? (new ServiceProviderAggregate)->setContainer($this) + : $providers->setContainer($this); + + $this->inflectors = (is_null($inflectors)) + ? (new InflectorAggregate)->setContainer($this) + : $inflectors->setContainer($this); + + $this->definitionFactory = (is_null($definitionFactory)) + ? (new DefinitionFactory)->setContainer($this) + : $definitionFactory->setContainer($this); + } + + /** + * {@inheritdoc} + */ + public function get($alias, array $args = []) + { + $service = $this->getFromThisContainer($alias, $args); + + if ($service === false && $this->providers->provides($alias)) { + $this->providers->register($alias); + $service = $this->getFromThisContainer($alias, $args); + } + + if ($service !== false) { + return $service; + } + + if ($resolved = $this->getFromDelegate($alias, $args)) { + return $this->inflectors->inflect($resolved); + } + + throw new NotFoundException( + sprintf('Alias (%s) is not being managed by the container', $alias) + ); + } + + /** + * {@inheritdoc} + */ + public function has($alias) + { + if (array_key_exists($alias, $this->definitions) || $this->hasShared($alias)) { + return true; + } + + if ($this->providers->provides($alias)) { + return true; + } + + return $this->hasInDelegate($alias); + } + + /** + * Returns a boolean to determine if the container has a shared instance of an alias. + * + * @param string $alias + * @param boolean $resolved + * @return boolean + */ + public function hasShared($alias, $resolved = false) + { + $shared = ($resolved === false) ? array_merge($this->shared, $this->sharedDefinitions) : $this->shared; + + return (array_key_exists($alias, $shared)); + } + + /** + * {@inheritdoc} + */ + public function add($alias, $concrete = null, $share = false) + { + if (is_null($concrete)) { + $concrete = $alias; + } + + $definition = $this->definitionFactory->getDefinition($alias, $concrete); + + if ($definition instanceof DefinitionInterface) { + if ($share === false) { + $this->definitions[$alias] = $definition; + } else { + $this->sharedDefinitions[$alias] = $definition; + } + + return $definition; + } + + // dealing with a value that cannot build a definition + $this->shared[$alias] = $concrete; + } + + /** + * {@inheritdoc} + */ + public function share($alias, $concrete = null) + { + return $this->add($alias, $concrete, true); + } + + /** + * {@inheritdoc} + */ + public function addServiceProvider($provider) + { + $this->providers->add($provider); + + return $this; + } + + /** + * {@inheritdoc} + */ + public function extend($alias) + { + if ($this->providers->provides($alias)) { + $this->providers->register($alias); + } + + if (array_key_exists($alias, $this->definitions)) { + return $this->definitions[$alias]; + } + + if (array_key_exists($alias, $this->sharedDefinitions)) { + return $this->sharedDefinitions[$alias]; + } + + throw new NotFoundException( + sprintf('Unable to extend alias (%s) as it is not being managed as a definition', $alias) + ); + } + + /** + * {@inheritdoc} + */ + public function inflector($type, callable $callback = null) + { + return $this->inflectors->add($type, $callback); + } + + /** + * {@inheritdoc} + */ + public function call(callable $callable, array $args = []) + { + return (new ReflectionContainer)->setContainer($this)->call($callable, $args); + } + + /** + * Delegate a backup container to be checked for services if it + * cannot be resolved via this container. + * + * @param \Interop\Container\ContainerInterface $container + * @return $this + */ + public function delegate(InteropContainerInterface $container) + { + $this->delegates[] = $container; + + if ($container instanceof ImmutableContainerAwareInterface) { + $container->setContainer($this); + } + + return $this; + } + + /** + * Returns true if service is registered in one of the delegated backup containers. + * + * @param string $alias + * @return boolean + */ + public function hasInDelegate($alias) + { + foreach ($this->delegates as $container) { + if ($container->has($alias)) { + return true; + } + } + + return false; + } + + /** + * Attempt to get a service from the stack of delegated backup containers. + * + * @param string $alias + * @param array $args + * @return mixed + */ + protected function getFromDelegate($alias, array $args = []) + { + foreach ($this->delegates as $container) { + if ($container->has($alias)) { + return $container->get($alias, $args); + } + + continue; + } + + return false; + } + + /** + * Get a service that has been registered in this container. + * + * @param string $alias + * @param array $args + * @return mixed + */ + protected function getFromThisContainer($alias, array $args = []) + { + if ($this->hasShared($alias, true)) { + return $this->inflectors->inflect($this->shared[$alias]); + } + + if (array_key_exists($alias, $this->sharedDefinitions)) { + $shared = $this->inflectors->inflect($this->sharedDefinitions[$alias]->build()); + $this->shared[$alias] = $shared; + return $shared; + } + + if (array_key_exists($alias, $this->definitions)) { + return $this->inflectors->inflect( + $this->definitions[$alias]->build($args) + ); + } + + return false; + } +} diff --git a/src/composer/vendor/league/container/src/ContainerAwareInterface.php b/src/composer/vendor/league/container/src/ContainerAwareInterface.php new file mode 100644 index 00000000..8addd2f9 --- /dev/null +++ b/src/composer/vendor/league/container/src/ContainerAwareInterface.php @@ -0,0 +1,20 @@ +container = $container; + + return $this; + } + + /** + * Get the container. + * + * @return \League\Container\ContainerInterface + */ + public function getContainer() + { + return $this->container; + } +} diff --git a/src/composer/vendor/league/container/src/ContainerInterface.php b/src/composer/vendor/league/container/src/ContainerInterface.php new file mode 100644 index 00000000..3996e326 --- /dev/null +++ b/src/composer/vendor/league/container/src/ContainerInterface.php @@ -0,0 +1,59 @@ +alias = $alias; + $this->concrete = $concrete; + } + + /** + * {@inheritdoc} + */ + public function withArgument($arg) + { + $this->arguments[] = $arg; + + return $this; + } + + /** + * {@inheritdoc} + */ + public function withArguments(array $args) + { + foreach ($args as $arg) { + $this->withArgument($arg); + } + + return $this; + } +} diff --git a/src/composer/vendor/league/container/src/Definition/CallableDefinition.php b/src/composer/vendor/league/container/src/Definition/CallableDefinition.php new file mode 100644 index 00000000..e8fe2e75 --- /dev/null +++ b/src/composer/vendor/league/container/src/Definition/CallableDefinition.php @@ -0,0 +1,23 @@ +arguments : $args; + $resolved = $this->resolveArguments($args); + + if (is_array($this->concrete) && is_string($this->concrete[0])) { + $this->concrete[0] = ($this->getContainer()->has($this->concrete[0])) + ? $this->getContainer()->get($this->concrete[0]) + : $this->concrete[0]; + } + + return call_user_func_array($this->concrete, $resolved); + } +} diff --git a/src/composer/vendor/league/container/src/Definition/ClassDefinition.php b/src/composer/vendor/league/container/src/Definition/ClassDefinition.php new file mode 100644 index 00000000..07448a2e --- /dev/null +++ b/src/composer/vendor/league/container/src/Definition/ClassDefinition.php @@ -0,0 +1,67 @@ +methods[] = [ + 'method' => $method, + 'arguments' => $args + ]; + + return $this; + } + + /** + * {@inheritdoc} + */ + public function withMethodCalls(array $methods = []) + { + foreach ($methods as $method => $args) { + $this->withMethodCall($method, $args); + } + + return $this; + } + + /** + * {@inheritdoc} + */ + public function build(array $args = []) + { + $args = (empty($args)) ? $this->arguments : $args; + $resolved = $this->resolveArguments($args); + $reflection = new ReflectionClass($this->concrete); + $instance = $reflection->newInstanceArgs($resolved); + + return $this->invokeMethods($instance); + } + + /** + * Invoke methods on resolved instance. + * + * @param object $instance + * @return object + */ + protected function invokeMethods($instance) + { + foreach ($this->methods as $method) { + $args = $this->resolveArguments($method['arguments']); + call_user_func_array([$instance, $method['method']], $args); + } + + return $instance; + } +} diff --git a/src/composer/vendor/league/container/src/Definition/ClassDefinitionInterface.php b/src/composer/vendor/league/container/src/Definition/ClassDefinitionInterface.php new file mode 100644 index 00000000..9f7e0b36 --- /dev/null +++ b/src/composer/vendor/league/container/src/Definition/ClassDefinitionInterface.php @@ -0,0 +1,23 @@ +setContainer($this->getContainer()); + } + + if (is_string($concrete) && class_exists($concrete)) { + return (new ClassDefinition($alias, $concrete))->setContainer($this->getContainer()); + } + + // if the item is not defineable we just return the value to be stored + // in the container as an arbitrary value/instance + return $concrete; + } +} diff --git a/src/composer/vendor/league/container/src/Definition/DefinitionFactoryInterface.php b/src/composer/vendor/league/container/src/Definition/DefinitionFactoryInterface.php new file mode 100644 index 00000000..7430b5cc --- /dev/null +++ b/src/composer/vendor/league/container/src/Definition/DefinitionFactoryInterface.php @@ -0,0 +1,17 @@ +container = $container; + + return $this; + } + + /** + * Get the container. + * + * @return \League\Container\ImmutableContainerInterface + */ + public function getContainer() + { + return $this->container; + } +} diff --git a/src/composer/vendor/league/container/src/ImmutableContainerInterface.php b/src/composer/vendor/league/container/src/ImmutableContainerInterface.php new file mode 100644 index 00000000..cd52a615 --- /dev/null +++ b/src/composer/vendor/league/container/src/ImmutableContainerInterface.php @@ -0,0 +1,10 @@ +methods[$name] = $args; + + return $this; + } + + /** + * Defines multiple methods to be invoked on the subject object. + * + * @param array $methods + * @return $this + */ + public function invokeMethods(array $methods) + { + foreach ($methods as $name => $args) { + $this->invokeMethod($name, $args); + } + + return $this; + } + + /** + * Defines a property to be set on the subject object. + * + * @param string $property + * @param mixed $value + * @return $this + */ + public function setProperty($property, $value) + { + $this->properties[$property] = $value; + + return $this; + } + + /** + * Defines multiple properties to be set on the subject object. + * + * @param array $properties + * @return $this + */ + public function setProperties(array $properties) + { + foreach ($properties as $property => $value) { + $this->setProperty($property, $value); + } + + return $this; + } + + /** + * Apply inflections to an object. + * + * @param object $object + * @return void + */ + public function inflect($object) + { + $properties = $this->resolveArguments(array_values($this->properties)); + $properties = array_combine(array_keys($this->properties), $properties); + + foreach ($properties as $property => $value) { + $object->{$property} = $value; + } + + foreach ($this->methods as $method => $args) { + $args = $this->resolveArguments($args); + + call_user_func_array([$object, $method], $args); + } + } +} diff --git a/src/composer/vendor/league/container/src/Inflector/InflectorAggregate.php b/src/composer/vendor/league/container/src/Inflector/InflectorAggregate.php new file mode 100644 index 00000000..f8552337 --- /dev/null +++ b/src/composer/vendor/league/container/src/Inflector/InflectorAggregate.php @@ -0,0 +1,53 @@ +inflectors[$type] = $inflector; + + return $inflector; + } + + $this->inflectors[$type] = $callback; + } + + /** + * {@inheritdoc} + */ + public function inflect($object) + { + foreach ($this->inflectors as $type => $inflector) { + if (! $object instanceof $type) { + continue; + } + + if ($inflector instanceof Inflector) { + $inflector->setContainer($this->getContainer()); + $inflector->inflect($object); + continue; + } + + // must be dealing with a callable as the inflector + call_user_func_array($inflector, [$object]); + } + + return $object; + } +} diff --git a/src/composer/vendor/league/container/src/Inflector/InflectorAggregateInterface.php b/src/composer/vendor/league/container/src/Inflector/InflectorAggregateInterface.php new file mode 100644 index 00000000..8266bc4e --- /dev/null +++ b/src/composer/vendor/league/container/src/Inflector/InflectorAggregateInterface.php @@ -0,0 +1,25 @@ +has($alias)) { + throw new NotFoundException( + sprintf('Alias (%s) is not an existing class and therefore cannot be resolved', $alias) + ); + } + + $reflector = new ReflectionClass($alias); + $construct = $reflector->getConstructor(); + + if ($construct === null) { + return new $alias; + } + + return $reflector->newInstanceArgs( + $this->reflectArguments($construct, $args) + ); + } + + /** + * {@inheritdoc} + */ + public function has($alias) + { + return class_exists($alias); + } + + /** + * Invoke a callable via the container. + * + * @param callable $callable + * @param array $args + * @return mixed + */ + public function call(callable $callable, array $args = []) + { + if (is_string($callable) && strpos($callable, '::') !== false) { + $callable = explode('::', $callable); + } + + if (is_array($callable)) { + $reflection = new ReflectionMethod($callable[0], $callable[1]); + + if ($reflection->isStatic()) { + $callable[0] = null; + } + + return $reflection->invokeArgs($callable[0], $this->reflectArguments($reflection, $args)); + } + + $reflection = new ReflectionFunction($callable); + + return $reflection->invokeArgs($this->reflectArguments($reflection, $args)); + } +} diff --git a/src/composer/vendor/league/container/src/ServiceProvider/AbstractServiceProvider.php b/src/composer/vendor/league/container/src/ServiceProvider/AbstractServiceProvider.php new file mode 100644 index 00000000..96cc7037 --- /dev/null +++ b/src/composer/vendor/league/container/src/ServiceProvider/AbstractServiceProvider.php @@ -0,0 +1,27 @@ +provides)); + } + + return $this->provides; + } +} diff --git a/src/composer/vendor/league/container/src/ServiceProvider/AbstractSignatureServiceProvider.php b/src/composer/vendor/league/container/src/ServiceProvider/AbstractSignatureServiceProvider.php new file mode 100644 index 00000000..9e36b553 --- /dev/null +++ b/src/composer/vendor/league/container/src/ServiceProvider/AbstractSignatureServiceProvider.php @@ -0,0 +1,31 @@ +signature = $signature; + + return $this; + } + + /** + * {@inheritdoc} + */ + public function getSignature() + { + return (is_null($this->signature)) ? get_class($this) : $this->signature; + } +} diff --git a/src/composer/vendor/league/container/src/ServiceProvider/BootableServiceProviderInterface.php b/src/composer/vendor/league/container/src/ServiceProvider/BootableServiceProviderInterface.php new file mode 100644 index 00000000..580580ff --- /dev/null +++ b/src/composer/vendor/league/container/src/ServiceProvider/BootableServiceProviderInterface.php @@ -0,0 +1,14 @@ +setContainer($this->getContainer()); + } + + if ($provider instanceof BootableServiceProviderInterface) { + $provider->boot(); + } + + if ($provider instanceof ServiceProviderInterface) { + foreach ($provider->provides() as $service) { + $this->providers[$service] = $provider; + } + + return $this; + } + + throw new \InvalidArgumentException( + 'A service provider must be a fully qualified class name or instance ' . + 'of (\League\Container\ServiceProvider\ServiceProviderInterface)' + ); + } + + /** + * {@inheritdoc} + */ + public function provides($service) + { + return array_key_exists($service, $this->providers); + } + + /** + * {@inheritdoc} + */ + public function register($service) + { + if (! array_key_exists($service, $this->providers)) { + throw new \InvalidArgumentException( + sprintf('(%s) is not provided by a service provider', $service) + ); + } + + $provider = $this->providers[$service]; + $signature = get_class($provider); + + if ($provider instanceof SignatureServiceProviderInterface) { + $signature = $provider->getSignature(); + } + + // ensure that the provider hasn't already been invoked by any other service request + if (in_array($signature, $this->registered)) { + return; + } + + $provider->register(); + + $this->registered[] = $signature; + } +} diff --git a/src/composer/vendor/league/container/src/ServiceProvider/ServiceProviderAggregateInterface.php b/src/composer/vendor/league/container/src/ServiceProvider/ServiceProviderAggregateInterface.php new file mode 100644 index 00000000..0825ff38 --- /dev/null +++ b/src/composer/vendor/league/container/src/ServiceProvider/ServiceProviderAggregateInterface.php @@ -0,0 +1,32 @@ +container property or the `getContainer` method + * from the ContainerAwareTrait. + * + * @return void + */ + public function register(); +} diff --git a/src/composer/vendor/league/container/src/ServiceProvider/SignatureServiceProviderInterface.php b/src/composer/vendor/league/container/src/ServiceProvider/SignatureServiceProviderInterface.php new file mode 100644 index 00000000..5022219b --- /dev/null +++ b/src/composer/vendor/league/container/src/ServiceProvider/SignatureServiceProviderInterface.php @@ -0,0 +1,24 @@ +copy($myObject); +``` + + +## Why? + +- How do you create copies of your objects? + +```php +$myCopy = clone $myObject; +``` + +- How do you create **deep** copies of your objects (i.e. copying also all the objects referenced in the properties)? + +You use [`__clone()`](http://www.php.net/manual/en/language.oop5.cloning.php#object.clone) and implement the behavior yourself. + +- But how do you handle **cycles** in the association graph? + +Now you're in for a big mess :( + +![association graph](doc/graph.png) + +### Using simply `clone` + +![Using clone](doc/clone.png) + +### Overridding `__clone()` + +![Overridding __clone](doc/deep-clone.png) + +### With `DeepCopy` + +![With DeepCopy](doc/deep-copy.png) + +## How it works + +DeepCopy recursively traverses all the object's properties and clones them. To avoid cloning the same object twice it keeps a hash map of all instances and thus preserves the object graph. + +## Going further + +You can add filters to customize the copy process. + +The method to add a filter is `$deepCopy->addFilter($filter, $matcher)`, +with `$filter` implementing `DeepCopy\Filter\Filter` +and `$matcher` implementing `DeepCopy\Matcher\Matcher`. + +We provide some generic filters and matchers. + +### Matchers + + - `DeepCopy\Matcher` applies on a object attribute. + - `DeepCopy\TypeMatcher` applies on any element found in graph, including array elements. + +#### Property name + +The `PropertyNameMatcher` will match a property by its name: + +```php +use DeepCopy\Matcher\PropertyNameMatcher; + +$matcher = new PropertyNameMatcher('id'); +// will apply a filter to any property of any objects named "id" +``` + +#### Specific property + +The `PropertyMatcher` will match a specific property of a specific class: + +```php +use DeepCopy\Matcher\PropertyMatcher; + +$matcher = new PropertyMatcher('MyClass', 'id'); +// will apply a filter to the property "id" of any objects of the class "MyClass" +``` + +#### Type + +The `TypeMatcher` will match any element by its type (instance of a class or any value that could be parameter of [gettype()](http://php.net/manual/en/function.gettype.php) function): + +```php +use DeepCopy\TypeMatcher\TypeMatcher; + +$matcher = new TypeMatcher('Doctrine\Common\Collections\Collection'); +// will apply a filter to any object that is an instance of Doctrine\Common\Collections\Collection +``` + +### Filters + + - `DeepCopy\Filter` applies a transformation to the object attribute matched by `DeepCopy\Matcher`. + - `DeepCopy\TypeFilter` applies a transformation to any element matched by `DeepCopy\TypeMatcher`. + +#### `SetNullFilter` + +Let's say for example that you are copying a database record (or a Doctrine entity), so you want the copy not to have any ID: + +```php +use DeepCopy\DeepCopy; +use DeepCopy\Filter\SetNullFilter; +use DeepCopy\Matcher\PropertyNameMatcher; + +$myObject = MyClass::load(123); +echo $myObject->id; // 123 + +$deepCopy = new DeepCopy(); +$deepCopy->addFilter(new SetNullFilter(), new PropertyNameMatcher('id')); +$myCopy = $deepCopy->copy($myObject); + +echo $myCopy->id; // null +``` + +#### `KeepFilter` + +If you want a property to remain untouched (for example, an association to an object): + +```php +use DeepCopy\DeepCopy; +use DeepCopy\Filter\KeepFilter; +use DeepCopy\Matcher\PropertyMatcher; + +$deepCopy = new DeepCopy(); +$deepCopy->addFilter(new KeepFilter(), new PropertyMatcher('MyClass', 'category')); +$myCopy = $deepCopy->copy($myObject); + +// $myCopy->category has not been touched +``` + +#### `ReplaceFilter` + + 1. If you want to replace the value of a property: + + ```php + use DeepCopy\DeepCopy; + use DeepCopy\Filter\ReplaceFilter; + use DeepCopy\Matcher\PropertyMatcher; + + $deepCopy = new DeepCopy(); + $callback = function ($currentValue) { + return $currentValue . ' (copy)' + }; + $deepCopy->addFilter(new ReplaceFilter($callback), new PropertyMatcher('MyClass', 'title')); + $myCopy = $deepCopy->copy($myObject); + + // $myCopy->title will contain the data returned by the callback, e.g. 'The title (copy)' + ``` + + 2. If you want to replace whole element: + + ```php + use DeepCopy\DeepCopy; + use DeepCopy\TypeFilter\ReplaceFilter; + use DeepCopy\TypeMatcher\TypeMatcher; + + $deepCopy = new DeepCopy(); + $callback = function (MyClass $myClass) { + return get_class($myClass); + }; + $deepCopy->addTypeFilter(new ReplaceFilter($callback), new TypeMatcher('MyClass')); + $myCopy = $deepCopy->copy(array(new MyClass, 'some string', new MyClass)); + + // $myCopy will contain ['MyClass', 'some stirng', 'MyClass'] + ``` + + +The `$callback` parameter of the `ReplaceFilter` constructor accepts any PHP callable. + +#### `ShallowCopyFilter` + +Stop *DeepCopy* from recursively copying element, using standard `clone` instead: + +```php +use DeepCopy\DeepCopy; +use DeepCopy\TypeFilter\ShallowCopyFilter; +use DeepCopy\TypeMatcher\TypeMatcher; +use Mockery as m; + +$this->deepCopy = new DeepCopy(); +$this->deepCopy->addTypeFilter( + new ShallowCopyFilter, + new TypeMatcher(m\MockInterface::class) +); + +$myServiceWithMocks = new MyService(m::mock(MyDependency1::class), m::mock(MyDependency2::class)); +// all mocks will be just cloned, not deep-copied +``` + +#### `DoctrineCollectionFilter` + +If you use Doctrine and want to copy an entity, you will need to use the `DoctrineCollectionFilter`: + +```php +use DeepCopy\DeepCopy; +use DeepCopy\Filter\Doctrine\DoctrineCollectionFilter; +use DeepCopy\Matcher\PropertyTypeMatcher; + +$deepCopy = new DeepCopy(); +$deepCopy->addFilter(new DoctrineCollectionFilter(), new PropertyTypeMatcher('Doctrine\Common\Collections\Collection')); +$myCopy = $deepCopy->copy($myObject); +``` + +#### `DoctrineEmptyCollectionFilter` + +If you use Doctrine and want to copy an entity who contains a `Collection` that you want to be reset, you can use the `DoctrineEmptyCollectionFilter` + +```php +use DeepCopy\DeepCopy; +use DeepCopy\Filter\Doctrine\DoctrineEmptyCollectionFilter; +use DeepCopy\Matcher\PropertyMatcher; + +$deepCopy = new DeepCopy(); +$deepCopy->addFilter(new DoctrineEmptyCollectionFilter(), new PropertyMatcher('MyClass', 'myProperty')); +$myCopy = $deepCopy->copy($myObject); + +// $myCopy->myProperty will return an empty collection +``` + +## Contributing + +DeepCopy is distributed under the MIT license. + +### Tests + +Running the tests is simple: + +```php +phpunit +``` diff --git a/src/composer/vendor/myclabs/deep-copy/composer.json b/src/composer/vendor/myclabs/deep-copy/composer.json new file mode 100644 index 00000000..d20287ab --- /dev/null +++ b/src/composer/vendor/myclabs/deep-copy/composer.json @@ -0,0 +1,21 @@ +{ + "name": "myclabs/deep-copy", + "type": "library", + "description": "Create deep copies (clones) of your objects", + "keywords": ["clone", "copy", "duplicate", "object", "object graph"], + "homepage": "https://github.com/myclabs/DeepCopy", + "license": "MIT", + "autoload": { + "psr-4": { "DeepCopy\\": "src/DeepCopy/" } + }, + "autoload-dev": { + "psr-4": { "DeepCopyTest\\": "tests/DeepCopyTest/" } + }, + "require": { + "php": ">=5.4.0" + }, + "require-dev": { + "doctrine/collections": "1.*", + "phpunit/phpunit": "~4.1" + } +} diff --git a/src/composer/vendor/myclabs/deep-copy/doc/clone.png b/src/composer/vendor/myclabs/deep-copy/doc/clone.png new file mode 100644 index 0000000000000000000000000000000000000000..376afd491257d44a8c3772b0b7b0bd7b6c747086 GIT binary patch literal 12380 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�+9eLb17NhZax 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 literal 0 HcmV?d00001 diff --git a/src/composer/vendor/myclabs/deep-copy/doc/graph.png b/src/composer/vendor/myclabs/deep-copy/doc/graph.png new file mode 100644 index 0000000000000000000000000000000000000000..4d5c9428f719bf6ad68f25a46d6e935c2362c4a5 GIT binary patch literal 6436 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 literal 0 HcmV?d00001 diff --git a/src/composer/vendor/myclabs/deep-copy/src/DeepCopy/DeepCopy.php b/src/composer/vendor/myclabs/deep-copy/src/DeepCopy/DeepCopy.php new file mode 100644 index 00000000..aee9e729 --- /dev/null +++ b/src/composer/vendor/myclabs/deep-copy/src/DeepCopy/DeepCopy.php @@ -0,0 +1,246 @@ +useCloneMethod = $useCloneMethod; + + $this->addTypeFilter(new SplDoublyLinkedList($this), new TypeMatcher('\SplDoublyLinkedList')); + } + + /** + * Cloning uncloneable properties won't throw exception. + * @param $skipUncloneable + * @return $this + */ + public function skipUncloneable($skipUncloneable = true) + { + $this->skipUncloneable = $skipUncloneable; + return $this; + } + + /** + * Perform a deep copy of the object. + * @param mixed $object + * @return mixed + */ + public function copy($object) + { + $this->hashMap = []; + + return $this->recursiveCopy($object); + } + + public function addFilter(Filter $filter, Matcher $matcher) + { + $this->filters[] = [ + 'matcher' => $matcher, + 'filter' => $filter, + ]; + } + + public function addTypeFilter(TypeFilter $filter, TypeMatcher $matcher) + { + $this->typeFilters[] = [ + 'matcher' => $matcher, + 'filter' => $filter, + ]; + } + + + private function recursiveCopy($var) + { + // Matches Type Filter + if ($filter = $this->getFirstMatchedTypeFilter($this->typeFilters, $var)) { + return $filter->apply($var); + } + + // Resource + if (is_resource($var)) { + return $var; + } + // Array + if (is_array($var)) { + return $this->copyArray($var); + } + // Scalar + if (! is_object($var)) { + return $var; + } + // Object + return $this->copyObject($var); + } + + /** + * Copy an array + * @param array $array + * @return array + */ + private function copyArray(array $array) + { + foreach ($array as $key => $value) { + $array[$key] = $this->recursiveCopy($value); + } + + return $array; + } + + /** + * Copy an object + * @param object $object + * @return object + */ + private function copyObject($object) + { + $objectHash = spl_object_hash($object); + + if (isset($this->hashMap[$objectHash])) { + return $this->hashMap[$objectHash]; + } + + $reflectedObject = new \ReflectionObject($object); + + if (false === $isCloneable = $reflectedObject->isCloneable() and $this->skipUncloneable) { + $this->hashMap[$objectHash] = $object; + return $object; + } + + if (false === $isCloneable) { + throw new CloneException(sprintf( + 'Class "%s" is not cloneable.', + $reflectedObject->getName() + )); + } + + $newObject = clone $object; + $this->hashMap[$objectHash] = $newObject; + if ($this->useCloneMethod && $reflectedObject->hasMethod('__clone')) { + return $object; + } + + if ($newObject instanceof \DateTimeInterface) { + return $newObject; + } + foreach (ReflectionHelper::getProperties($reflectedObject) as $property) { + $this->copyObjectProperty($newObject, $property); + } + + return $newObject; + } + + private function copyObjectProperty($object, ReflectionProperty $property) + { + // Ignore static properties + if ($property->isStatic()) { + return; + } + + // Apply the filters + foreach ($this->filters as $item) { + /** @var Matcher $matcher */ + $matcher = $item['matcher']; + /** @var Filter $filter */ + $filter = $item['filter']; + + if ($matcher->matches($object, $property->getName())) { + $filter->apply( + $object, + $property->getName(), + function ($object) { + return $this->recursiveCopy($object); + } + ); + // If a filter matches, we stop processing this property + return; + } + } + + $property->setAccessible(true); + $propertyValue = $property->getValue($object); + + // Copy the property + $property->setValue($object, $this->recursiveCopy($propertyValue)); + } + + /** + * Returns first filter that matches variable, NULL if no such filter found. + * @param array $filterRecords Associative array with 2 members: 'filter' with value of type {@see TypeFilter} and + * 'matcher' with value of type {@see TypeMatcher} + * @param mixed $var + * @return TypeFilter|null + */ + private function getFirstMatchedTypeFilter(array $filterRecords, $var) + { + $matched = $this->first( + $filterRecords, + function (array $record) use ($var) { + /* @var TypeMatcher $matcher */ + $matcher = $record['matcher']; + + return $matcher->matches($var); + } + ); + + return isset($matched) ? $matched['filter'] : null; + } + + /** + * Returns first element that matches predicate, NULL if no such element found. + * @param array $elements + * @param callable $predicate Predicate arguments are: element. + * @return mixed|null + */ + private function first(array $elements, callable $predicate) + { + foreach ($elements as $element) { + if (call_user_func($predicate, $element)) { + return $element; + } + } + + return null; + } +} diff --git a/src/composer/vendor/myclabs/deep-copy/src/DeepCopy/Exception/CloneException.php b/src/composer/vendor/myclabs/deep-copy/src/DeepCopy/Exception/CloneException.php new file mode 100644 index 00000000..dd3b617b --- /dev/null +++ b/src/composer/vendor/myclabs/deep-copy/src/DeepCopy/Exception/CloneException.php @@ -0,0 +1,6 @@ +setAccessible(true); + $oldCollection = $reflectionProperty->getValue($object); + + $newCollection = $oldCollection->map( + function ($item) use ($objectCopier) { + return $objectCopier($item); + } + ); + + $reflectionProperty->setValue($object, $newCollection); + } +} diff --git a/src/composer/vendor/myclabs/deep-copy/src/DeepCopy/Filter/Doctrine/DoctrineEmptyCollectionFilter.php b/src/composer/vendor/myclabs/deep-copy/src/DeepCopy/Filter/Doctrine/DoctrineEmptyCollectionFilter.php new file mode 100644 index 00000000..f9b3f7ac --- /dev/null +++ b/src/composer/vendor/myclabs/deep-copy/src/DeepCopy/Filter/Doctrine/DoctrineEmptyCollectionFilter.php @@ -0,0 +1,24 @@ +setAccessible(true); + + $reflectionProperty->setValue($object, new ArrayCollection()); + } +} \ No newline at end of file diff --git a/src/composer/vendor/myclabs/deep-copy/src/DeepCopy/Filter/Filter.php b/src/composer/vendor/myclabs/deep-copy/src/DeepCopy/Filter/Filter.php new file mode 100644 index 00000000..48076a1b --- /dev/null +++ b/src/composer/vendor/myclabs/deep-copy/src/DeepCopy/Filter/Filter.php @@ -0,0 +1,17 @@ +callback = $callable; + } + + /** + * {@inheritdoc} + */ + public function apply($object, $property, $objectCopier) + { + $reflectionProperty = new \ReflectionProperty($object, $property); + $reflectionProperty->setAccessible(true); + + $value = call_user_func($this->callback, $reflectionProperty->getValue($object)); + + $reflectionProperty->setValue($object, $value); + } +} diff --git a/src/composer/vendor/myclabs/deep-copy/src/DeepCopy/Filter/SetNullFilter.php b/src/composer/vendor/myclabs/deep-copy/src/DeepCopy/Filter/SetNullFilter.php new file mode 100644 index 00000000..d48f15b6 --- /dev/null +++ b/src/composer/vendor/myclabs/deep-copy/src/DeepCopy/Filter/SetNullFilter.php @@ -0,0 +1,22 @@ +setAccessible(true); + $reflectionProperty->setValue($object, null); + } +} diff --git a/src/composer/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/Matcher.php b/src/composer/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/Matcher.php new file mode 100644 index 00000000..91eb7c90 --- /dev/null +++ b/src/composer/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/Matcher.php @@ -0,0 +1,16 @@ +class = $class; + $this->property = $property; + } + + /** + * {@inheritdoc} + */ + public function matches($object, $property) + { + return ($object instanceof $this->class) && ($property == $this->property); + } +} diff --git a/src/composer/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/PropertyNameMatcher.php b/src/composer/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/PropertyNameMatcher.php new file mode 100644 index 00000000..9d9575f0 --- /dev/null +++ b/src/composer/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/PropertyNameMatcher.php @@ -0,0 +1,30 @@ +property = $property; + } + + /** + * {@inheritdoc} + */ + public function matches($object, $property) + { + return $property == $this->property; + } +} diff --git a/src/composer/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/PropertyTypeMatcher.php b/src/composer/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/PropertyTypeMatcher.php new file mode 100644 index 00000000..6935541d --- /dev/null +++ b/src/composer/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/PropertyTypeMatcher.php @@ -0,0 +1,38 @@ +propertyType = $propertyType; + } + + /** + * {@inheritdoc} + */ + public function matches($object, $property) + { + $reflectionProperty = new ReflectionProperty($object, $property); + $reflectionProperty->setAccessible(true); + + return $reflectionProperty->getValue($object) instanceof $this->propertyType; + } +} diff --git a/src/composer/vendor/myclabs/deep-copy/src/DeepCopy/Reflection/ReflectionHelper.php b/src/composer/vendor/myclabs/deep-copy/src/DeepCopy/Reflection/ReflectionHelper.php new file mode 100644 index 00000000..a094e729 --- /dev/null +++ b/src/composer/vendor/myclabs/deep-copy/src/DeepCopy/Reflection/ReflectionHelper.php @@ -0,0 +1,39 @@ +getProperties() does not return private properties from ancestor classes. + * + * @author muratyaman@gmail.com + * @see http://php.net/manual/en/reflectionclass.getproperties.php + * + * @param \ReflectionClass $ref + * @return \ReflectionProperty[] + */ + public static function getProperties(\ReflectionClass $ref) + { + $props = $ref->getProperties(); + $propsArr = array(); + + foreach ($props as $prop) { + $propertyName = $prop->getName(); + $propsArr[$propertyName] = $prop; + } + + if ($parentClass = $ref->getParentClass()) { + $parentPropsArr = self::getProperties($parentClass); + foreach ($propsArr as $key => $property) { + $parentPropsArr[$key] = $property; + } + + return $parentPropsArr; + } + + return $propsArr; + } +} diff --git a/src/composer/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/ReplaceFilter.php b/src/composer/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/ReplaceFilter.php new file mode 100644 index 00000000..0e42b0fe --- /dev/null +++ b/src/composer/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/ReplaceFilter.php @@ -0,0 +1,27 @@ +callback = $callable; + } + + /** + * {@inheritdoc} + */ + public function apply($element) + { + return call_user_func($this->callback, $element); + } +} diff --git a/src/composer/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/ShallowCopyFilter.php b/src/composer/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/ShallowCopyFilter.php new file mode 100644 index 00000000..408d18bb --- /dev/null +++ b/src/composer/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/ShallowCopyFilter.php @@ -0,0 +1,14 @@ +deepCopy = $deepCopy; + } + + /** + * {@inheritdoc} + */ + public function apply($element) + { + $newElement = clone $element; + + if ($element instanceof \SplDoublyLinkedList) { + // Replace each element in the list with a deep copy of itself + for ($i = 1; $i <= $newElement->count(); $i++) { + $newElement->push($this->deepCopy->copy($newElement->shift())); + } + } + + return $newElement; + + } +} diff --git a/src/composer/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/TypeFilter.php b/src/composer/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/TypeFilter.php new file mode 100644 index 00000000..a37a8ba8 --- /dev/null +++ b/src/composer/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/TypeFilter.php @@ -0,0 +1,12 @@ +type = $type; + } + + /** + * @param $element + * @return boolean + */ + public function matches($element) + { + return is_object($element) ? is_a($element, $this->type) : gettype($element) === $this->type; + } +} diff --git a/src/composer/vendor/phpdocumentor/reflection-common/.gitignore b/src/composer/vendor/phpdocumentor/reflection-common/.gitignore new file mode 100644 index 00000000..c56f6719 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-common/.gitignore @@ -0,0 +1,4 @@ +composer.phar +vendor/ +build/ + diff --git a/src/composer/vendor/phpdocumentor/reflection-common/LICENSE b/src/composer/vendor/phpdocumentor/reflection-common/LICENSE new file mode 100644 index 00000000..ed6926c1 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-common/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015 phpDocumentor + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/src/composer/vendor/phpdocumentor/reflection-common/README.md b/src/composer/vendor/phpdocumentor/reflection-common/README.md new file mode 100644 index 00000000..52b12bc0 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-common/README.md @@ -0,0 +1 @@ +# ReflectionCommon diff --git a/src/composer/vendor/phpdocumentor/reflection-common/composer.json b/src/composer/vendor/phpdocumentor/reflection-common/composer.json new file mode 100644 index 00000000..90eee0f0 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-common/composer.json @@ -0,0 +1,29 @@ +{ + "name": "phpdocumentor/reflection-common", + "keywords": ["phpdoc", "phpDocumentor", "reflection", "static analysis", "FQSEN"], + "homepage": "http://www.phpdoc.org", + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "license": "MIT", + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "require": { + "php": ">=5.5" + }, + "autoload" : { + "psr-4" : { + "phpDocumentor\\Reflection\\": ["src"] + } + }, + "require-dev": { + "phpunit/phpunit": "^4.6" + }, + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + } +} diff --git a/src/composer/vendor/phpdocumentor/reflection-common/composer.lock b/src/composer/vendor/phpdocumentor/reflection-common/composer.lock new file mode 100644 index 00000000..e01dc3c1 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-common/composer.lock @@ -0,0 +1,974 @@ +{ + "_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": "49ee00389e4ccd00d7e93a147103b2ab", + "packages": [], + "packages-dev": [ + { + "name": "doctrine/instantiator", + "version": "1.0.4", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "f976e5de371104877ebc89bd8fecb0019ed9c119" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/f976e5de371104877ebc89bd8fecb0019ed9c119", + "reference": "f976e5de371104877ebc89bd8fecb0019ed9c119", + "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.*@ALPHA" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "Doctrine\\Instantiator\\": "src" + } + }, + "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": "2014-10-13 12:58:55" + }, + { + "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.4.1", + "source": { + "type": "git", + "url": "https://github.com/phpspec/prophecy.git", + "reference": "3132b1f44c7bf2ec4c7eb2d3cb78fdeca760d373" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/3132b1f44c7bf2ec4c7eb2d3cb78fdeca760d373", + "reference": "3132b1f44c7bf2ec4c7eb2d3cb78fdeca760d373", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.2", + "phpdocumentor/reflection-docblock": "~2.0", + "sebastian/comparator": "~1.1" + }, + "require-dev": { + "phpspec/phpspec": "~2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, + "autoload": { + "psr-0": { + "Prophecy\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + }, + { + "name": "Marcello Duarte", + "email": "marcello.duarte@gmail.com" + } + ], + "description": "Highly opinionated mocking framework for PHP 5.3+", + "homepage": "https://github.com/phpspec/prophecy", + "keywords": [ + "Double", + "Dummy", + "fake", + "mock", + "spy", + "stub" + ], + "time": "2015-04-27 22:15:08" + }, + { + "name": "phpunit/php-code-coverage", + "version": "2.1.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "6b7d2094ca2a685a2cad846cb7cd7a30e8b9470f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/6b7d2094ca2a685a2cad846cb7cd7a30e8b9470f", + "reference": "6b7d2094ca2a685a2cad846cb7cd7a30e8b9470f", + "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.0", + "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.1.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-06-01 07:35:26" + }, + { + "name": "phpunit/php-file-iterator", + "version": "1.4.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "a923bb15680d0089e2316f7a4af8f437046e96bb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/a923bb15680d0089e2316f7a4af8f437046e96bb", + "reference": "a923bb15680d0089e2316f7a4af8f437046e96bb", + "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-04-02 05:19:05" + }, + { + "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.4.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-token-stream.git", + "reference": "eab81d02569310739373308137284e0158424330" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/eab81d02569310739373308137284e0158424330", + "reference": "eab81d02569310739373308137284e0158424330", + "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-04-08 04:46:07" + }, + { + "name": "phpunit/phpunit", + "version": "4.6.9", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "816d12536a7a032adc3b68737f82cfbbf98b79c1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/816d12536a7a032adc3b68737f82cfbbf98b79c1", + "reference": "816d12536a7a032adc3b68737f82cfbbf98b79c1", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-pcre": "*", + "ext-reflection": "*", + "ext-spl": "*", + "php": ">=5.3.3", + "phpspec/prophecy": "~1.3,>=1.3.1", + "phpunit/php-code-coverage": "~2.0,>=2.0.11", + "phpunit/php-file-iterator": "~1.4", + "phpunit/php-text-template": "~1.2", + "phpunit/php-timer": "~1.0", + "phpunit/phpunit-mock-objects": "~2.3", + "sebastian/comparator": "~1.1", + "sebastian/diff": "~1.2", + "sebastian/environment": "~1.2", + "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.6.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "time": "2015-05-29 06:00:03" + }, + { + "name": "phpunit/phpunit-mock-objects", + "version": "2.3.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", + "reference": "253c005852591fd547fc18cd5b7b43a1ec82d8f7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/253c005852591fd547fc18cd5b7b43a1ec82d8f7", + "reference": "253c005852591fd547fc18cd5b7b43a1ec82d8f7", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "~1.0,>=1.0.2", + "php": ">=5.3.3", + "phpunit/php-text-template": "~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-05-29 05:19:18" + }, + { + "name": "sebastian/comparator", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "1dd8869519a225f7f2b9eb663e225298fade819e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/1dd8869519a225f7f2b9eb663e225298fade819e", + "reference": "1dd8869519a225f7f2b9eb663e225298fade819e", + "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.1.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "http://www.github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "time": "2015-01-29 16:28:08" + }, + { + "name": "sebastian/diff", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "863df9687835c62aa423a22412d26fa2ebde3fd3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/863df9687835c62aa423a22412d26fa2ebde3fd3", + "reference": "863df9687835c62aa423a22412d26fa2ebde3fd3", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3-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": "http://www.github.com/sebastianbergmann/diff", + "keywords": [ + "diff" + ], + "time": "2015-02-22 15:13:53" + }, + { + "name": "sebastian/environment", + "version": "1.2.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "5a8c7d31914337b69923db26c4221b81ff5a196e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/5a8c7d31914337b69923db26c4221b81ff5a196e", + "reference": "5a8c7d31914337b69923db26c4221b81ff5a196e", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "time": "2015-01-01 10:01:08" + }, + { + "name": "sebastian/exporter", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "84839970d05254c73cde183a721c7af13aede943" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/84839970d05254c73cde183a721c7af13aede943", + "reference": "84839970d05254c73cde183a721c7af13aede943", + "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-01-27 07:23:06" + }, + { + "name": "sebastian/global-state", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "c7428acdb62ece0a45e6306f1ae85e1c05b09c01" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/c7428acdb62ece0a45e6306f1ae85e1c05b09c01", + "reference": "c7428acdb62ece0a45e6306f1ae85e1c05b09c01", + "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": "2014-10-06 09:23:50" + }, + { + "name": "sebastian/recursion-context", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "3989662bbb30a29d20d9faa04a846af79b276252" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/3989662bbb30a29d20d9faa04a846af79b276252", + "reference": "3989662bbb30a29d20d9faa04a846af79b276252", + "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-01-24 09:48:32" + }, + { + "name": "sebastian/version", + "version": "1.0.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "ab931d46cd0d3204a91e1b9a40c4bc13032b58e4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/ab931d46cd0d3204a91e1b9a40c4bc13032b58e4", + "reference": "ab931d46cd0d3204a91e1b9a40c4bc13032b58e4", + "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-02-24 06:35:25" + }, + { + "name": "symfony/yaml", + "version": "v2.7.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/Yaml.git", + "reference": "4a29a5248aed4fb45f626a7bbbd330291492f5c3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/Yaml/zipball/4a29a5248aed4fb45f626a7bbbd330291492f5c3", + "reference": "4a29a5248aed4fb45f626a7bbbd330291492f5c3", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "require-dev": { + "symfony/phpunit-bridge": "~2.7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Yaml\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Yaml Component", + "homepage": "https://symfony.com", + "time": "2015-05-02 15:21:08" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": [], + "platform-dev": [] +} diff --git a/src/composer/vendor/phpdocumentor/reflection-common/phpunit.xml.dist b/src/composer/vendor/phpdocumentor/reflection-common/phpunit.xml.dist new file mode 100644 index 00000000..31811501 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-common/phpunit.xml.dist @@ -0,0 +1,26 @@ + + + + + + ./tests/unit/ + + + + + src + + + + + + + + diff --git a/src/composer/vendor/phpdocumentor/reflection-common/src/Element.php b/src/composer/vendor/phpdocumentor/reflection-common/src/Element.php new file mode 100644 index 00000000..712e30e8 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-common/src/Element.php @@ -0,0 +1,32 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection; + +/** + * Interface for files processed by the ProjectFactory + */ +interface File +{ + /** + * Returns the content of the file as a string. + * + * @return string + */ + public function getContents(); + + /** + * Returns md5 hash of the file. + * + * @return string + */ + public function md5(); + + /** + * Returns an relative path to the file. + * + * @return string + */ + public function path(); +} diff --git a/src/composer/vendor/phpdocumentor/reflection-common/src/Fqsen.php b/src/composer/vendor/phpdocumentor/reflection-common/src/Fqsen.php new file mode 100644 index 00000000..c7be3f15 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-common/src/Fqsen.php @@ -0,0 +1,78 @@ +fqsen = $fqsen; + + if (isset($matches[2])) { + $this->name = $matches[2]; + } else { + $matches = explode('\\', $fqsen); + $this->name = trim(end($matches), '()'); + } + } + + /** + * converts this class to string. + * + * @return string + */ + public function __toString() + { + return $this->fqsen; + } + + /** + * Returns the name of the element without path. + * + * @return string + */ + public function getName() + { + return $this->name; + } +} diff --git a/src/composer/vendor/phpdocumentor/reflection-common/src/Location.php b/src/composer/vendor/phpdocumentor/reflection-common/src/Location.php new file mode 100644 index 00000000..57603219 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-common/src/Location.php @@ -0,0 +1,57 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection; + +/** + * The location where an element occurs within a file. + */ +final class Location +{ + /** @var int */ + private $lineNumber = 0; + + /** @var int */ + private $columnNumber = 0; + + /** + * Initializes the location for an element using its line number in the file and optionally the column number. + * + * @param int $lineNumber + * @param int $columnNumber + */ + public function __construct($lineNumber, $columnNumber = 0) + { + $this->lineNumber = $lineNumber; + $this->columnNumber = $columnNumber; + } + + /** + * Returns the line number that is covered by this location. + * + * @return integer + */ + public function getLineNumber() + { + return $this->lineNumber; + } + + /** + * Returns the column number (character position on a line) for this location object. + * + * @return integer + */ + public function getColumnNumber() + { + return $this->columnNumber; + } +} diff --git a/src/composer/vendor/phpdocumentor/reflection-common/src/Project.php b/src/composer/vendor/phpdocumentor/reflection-common/src/Project.php new file mode 100644 index 00000000..3ed1e393 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-common/src/Project.php @@ -0,0 +1,25 @@ +assertEquals($name, $instance->getName()); + } + + /** + * Data provider for ValidFormats tests. Contains a complete list from psr-5 draft. + * + * @return array + */ + public function validFqsenProvider() + { + return [ + ['\\', ''], + ['\My\Space', 'Space'], + ['\My\Space\myFunction()', 'myFunction'], + ['\My\Space\MY_CONSTANT', 'MY_CONSTANT'], + ['\My\Space\MY_CONSTANT2', 'MY_CONSTANT2'], + ['\My\Space\MyClass', 'MyClass'], + ['\My\Space\MyInterface', 'MyInterface'], + ['\My\Space\MyTrait', 'MyTrait'], + ['\My\Space\MyClass::myMethod()', 'myMethod'], + ['\My\Space\MyClass::$my_property', 'my_property'], + ['\My\Space\MyClass::MY_CONSTANT', 'MY_CONSTANT'], + ]; + } + + /** + * @param string $fqsen + * @covers ::__construct + * @dataProvider invalidFqsenProvider + * @expectedException \InvalidArgumentException + */ + public function testInValidFormats($fqsen) + { + new Fqsen($fqsen); + } + + /** + * Data provider for invalidFormats tests. Contains a complete list from psr-5 draft. + * + * @return array + */ + public function invalidFqsenProvider() + { + return [ + ['\My\*'], + ['\My\Space\.()'], + ['My\Space'], + ]; + } + + /** + * @covers ::__construct + * @covers ::__toString + */ + public function testToString() + { + $className = new Fqsen('\\phpDocumentor\\Application'); + + $this->assertEquals('\\phpDocumentor\\Application', (string)$className); + } +} diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/.gitignore b/src/composer/vendor/phpdocumentor/reflection-docblock/.gitignore new file mode 100644 index 00000000..3ce5adbb --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/.gitignore @@ -0,0 +1,2 @@ +.idea +vendor diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/.scrutinizer.yml b/src/composer/vendor/phpdocumentor/reflection-docblock/.scrutinizer.yml new file mode 100644 index 00000000..5061d523 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/.scrutinizer.yml @@ -0,0 +1,32 @@ +before_commands: + - "composer install --no-dev --prefer-source" + +tools: + external_code_coverage: true + php_code_sniffer: + enabled: true + config: + standard: PSR2 + filter: + paths: ["src/*", "tests/*"] + php_cpd: + enabled: true + excluded_dirs: ["tests", "vendor"] + php_loc: + enabled: true + excluded_dirs: ["tests", "vendor"] + php_mess_detector: + enabled: true + config: + ruleset: phpmd.xml.dist + design_rules: { eval_expression: false } + filter: + paths: ["src/*"] + php_pdepend: + enabled: true + excluded_dirs: ["tests", "vendor"] + php_analyzer: + enabled: true + filter: + paths: ["src/*", "tests/*"] + sensiolabs_security_checker: true diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/.travis.yml b/src/composer/vendor/phpdocumentor/reflection-docblock/.travis.yml new file mode 100644 index 00000000..920958df --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/.travis.yml @@ -0,0 +1,36 @@ +language: php +php: + - 5.5 + - 5.6 + - 7.0 + - hhvm + - nightly + +matrix: + allow_failures: + - php: + - hhvm + - nightly + +cache: + directories: + - $HOME/.composer/cache + +script: + - vendor/bin/phpunit --coverage-clover=coverage.clover -v + - composer update --no-interaction --prefer-source + - vendor/bin/phpunit -v + +before_script: + - composer install --no-interaction + +after_script: + - wget https://scrutinizer-ci.com/ocular.phar + - php ocular.phar code-coverage:upload --format=php-clover coverage.clover + +notifications: + irc: "irc.freenode.org#phpdocumentor" + email: + - mike.vanriel@naenius.com + - ashnazg@php.net + - boen.robot@gmail.com diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/LICENSE b/src/composer/vendor/phpdocumentor/reflection-docblock/LICENSE new file mode 100644 index 00000000..792e4040 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2010 Mike van Riel + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/README.md b/src/composer/vendor/phpdocumentor/reflection-docblock/README.md new file mode 100644 index 00000000..a1984a15 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/README.md @@ -0,0 +1,69 @@ +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 +----- + +In order to parse the DocBlock one needs a DocBlockFactory that can be +instantiated using its `createInstance` factory method like this: + +```php +$factory = \phpDocumentor\Reflection\DocBlockFactory::createInstance(); +``` + +Then we can use the `create` method of the factory to interpret the DocBlock. +Please note that it is also possible to provide a class that has the +`getDocComment()` method, such as an object of type `ReflectionClass`, the +create method will read that if it exists. + +```php +$docComment = <<create($docComment); +``` + +The `create` method will yield an object of type `\phpDocumentor\Reflection\DocBlock` +whose methods can be queried as shown in the following example. + +```php +// Should contain the summary for this DocBlock +$summary = $docblock->getSummary(); + +// Contains an object of type \phpDocumentor\Reflection\DocBlock\Description; +// you can either cast it to string or use the render method to get a string +// representation of the Description. +$description = $docblock->getDescription(); +``` + +> For more examples it would be best to review the scripts in the `/examples` +> folder. + diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/composer.json b/src/composer/vendor/phpdocumentor/reflection-docblock/composer.json new file mode 100644 index 00000000..85be2fdd --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/composer.json @@ -0,0 +1,28 @@ +{ + "name": "phpdocumentor/reflection-docblock", + "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "type": "library", + "license": "MIT", + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "require": { + "php": ">=5.5", + "phpdocumentor/reflection-common": "^1.0@dev", + "phpdocumentor/type-resolver": "^0.2.0", + "webmozart/assert": "^1.0" + }, + "autoload": { + "psr-4": {"phpDocumentor\\Reflection\\": ["src/"]} + }, + "autoload-dev": { + "psr-4": {"phpDocumentor\\Reflection\\": ["tests/unit"]} + }, + "require-dev": { + "mockery/mockery": "^0.9.4", + "phpunit/phpunit": "^4.4" + } +} diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/composer.lock b/src/composer/vendor/phpdocumentor/reflection-docblock/composer.lock new file mode 100644 index 00000000..b4da3c1b --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/composer.lock @@ -0,0 +1,1120 @@ +{ + "_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": "9dfabded4193c3fd2ec85874de3b2e3c", + "content-hash": "69f6ae6608b8524fa04ddb0264bbf091", + "packages": [ + { + "name": "phpdocumentor/reflection-common", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "9969bd1c9661a73fdab104df7dbf132639d5c4d8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/9969bd1c9661a73fdab104df7dbf132639d5c4d8", + "reference": "9969bd1c9661a73fdab104df7dbf132639d5c4d8", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "phpunit/phpunit": "^4.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ], + "time": "2015-06-12 22:21:38" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "0.2", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "b39c7a5b194f9ed7bd0dd345c751007a41862443" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/b39c7a5b194f9ed7bd0dd345c751007a41862443", + "reference": "b39c7a5b194f9ed7bd0dd345c751007a41862443", + "shasum": "" + }, + "require": { + "php": ">=5.5", + "phpdocumentor/reflection-common": "^1.0" + }, + "require-dev": { + "mockery/mockery": "^0.9.4", + "phpunit/phpunit": "^5.2||^4.8.24" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "time": "2016-06-10 07:14:17" + }, + { + "name": "webmozart/assert", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/webmozart/assert.git", + "reference": "b8ef76d0f0c3b9a0a1bc987085fe0a0ddba984ab" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozart/assert/zipball/b8ef76d0f0c3b9a0a1bc987085fe0a0ddba984ab", + "reference": "b8ef76d0f0c3b9a0a1bc987085fe0a0ddba984ab", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "time": "2015-05-12 15:19:25" + } + ], + "packages-dev": [ + { + "name": "doctrine/instantiator", + "version": "1.0.5", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d", + "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d", + "shasum": "" + }, + "require": { + "php": ">=5.3,<8.0-DEV" + }, + "require-dev": { + "athletic/athletic": "~0.1.8", + "ext-pdo": "*", + "ext-phar": "*", + "phpunit/phpunit": "~4.0", + "squizlabs/php_codesniffer": "~2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "http://ocramius.github.com/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://github.com/doctrine/instantiator", + "keywords": [ + "constructor", + "instantiate" + ], + "time": "2015-06-14 21:17:01" + }, + { + "name": "hamcrest/hamcrest-php", + "version": "v1.2.2", + "source": { + "type": "git", + "url": "https://github.com/hamcrest/hamcrest-php.git", + "reference": "b37020aa976fa52d3de9aa904aa2522dc518f79c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/b37020aa976fa52d3de9aa904aa2522dc518f79c", + "reference": "b37020aa976fa52d3de9aa904aa2522dc518f79c", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "replace": { + "cordoval/hamcrest-php": "*", + "davedevelopment/hamcrest-php": "*", + "kodova/hamcrest-php": "*" + }, + "require-dev": { + "phpunit/php-file-iterator": "1.3.3", + "satooshi/php-coveralls": "dev-master" + }, + "type": "library", + "autoload": { + "classmap": [ + "hamcrest" + ], + "files": [ + "hamcrest/Hamcrest.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD" + ], + "description": "This is the PHP port of Hamcrest Matchers", + "keywords": [ + "test" + ], + "time": "2015-05-11 14:41:42" + }, + { + "name": "mockery/mockery", + "version": "0.9.4", + "source": { + "type": "git", + "url": "https://github.com/padraic/mockery.git", + "reference": "70bba85e4aabc9449626651f48b9018ede04f86b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/padraic/mockery/zipball/70bba85e4aabc9449626651f48b9018ede04f86b", + "reference": "70bba85e4aabc9449626651f48b9018ede04f86b", + "shasum": "" + }, + "require": { + "hamcrest/hamcrest-php": "~1.1", + "lib-pcre": ">=7.0", + "php": ">=5.3.2" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.9.x-dev" + } + }, + "autoload": { + "psr-0": { + "Mockery": "library/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Pádraic Brady", + "email": "padraic.brady@gmail.com", + "homepage": "http://blog.astrumfutura.com" + }, + { + "name": "Dave Marshall", + "email": "dave.marshall@atstsolutions.co.uk", + "homepage": "http://davedevelopment.co.uk" + } + ], + "description": "Mockery is a simple yet flexible PHP mock object framework for use in unit testing with PHPUnit, PHPSpec or any other testing framework. Its core goal is to offer a test double framework with a succinct API capable of clearly defining all possible object operations and interactions using a human readable Domain Specific Language (DSL). Designed as a drop in alternative to PHPUnit's phpunit-mock-objects library, Mockery is easy to integrate with PHPUnit and can operate alongside phpunit-mock-objects without the World ending.", + "homepage": "http://github.com/padraic/mockery", + "keywords": [ + "BDD", + "TDD", + "library", + "mock", + "mock objects", + "mockery", + "stub", + "test", + "test double", + "testing" + ], + "time": "2015-04-02 19:54:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "2.1.6", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "631e365cf26bb2c078683e8d9bcf8bc631ac4d44" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/631e365cf26bb2c078683e8d9bcf8bc631ac4d44", + "reference": "631e365cf26bb2c078683e8d9bcf8bc631ac4d44", + "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.0", + "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.1.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-06-19 07:11:55" + }, + { + "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.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.6", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "83fe1bdc5d47658b727595c14da140da92b3d66d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/83fe1bdc5d47658b727595c14da140da92b3d66d", + "reference": "83fe1bdc5d47658b727595c14da140da92b3d66d", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "time": "2015-06-13 07:35:30" + }, + { + "name": "phpunit/php-token-stream", + "version": "1.4.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-token-stream.git", + "reference": "7a9b0969488c3c54fd62b4d504b3ec758fd005d9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/7a9b0969488c3c54fd62b4d504b3ec758fd005d9", + "reference": "7a9b0969488c3c54fd62b4d504b3ec758fd005d9", + "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-06-19 03:43:16" + }, + { + "name": "phpunit/phpunit", + "version": "4.4.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "2e8580deebb7d1ac92ac878595e6bffe01069c2a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/2e8580deebb7d1ac92ac878595e6bffe01069c2a", + "reference": "2e8580deebb7d1ac92ac878595e6bffe01069c2a", + "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.2", + "phpunit/php-text-template": "~1.2", + "phpunit/php-timer": "~1.0.2", + "phpunit/phpunit-mock-objects": "~2.3", + "sebastian/comparator": "~1.0", + "sebastian/diff": "~1.1", + "sebastian/environment": "~1.1", + "sebastian/exporter": "~1.1", + "sebastian/global-state": "~1.0", + "sebastian/recursion-context": "~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.4.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "time": "2015-01-27 16:06:15" + }, + { + "name": "phpunit/phpunit-mock-objects", + "version": "2.3.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", + "reference": "92408bb1968a81b3217a6fdf6c1a198da83caa35" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/92408bb1968a81b3217a6fdf6c1a198da83caa35", + "reference": "92408bb1968a81b3217a6fdf6c1a198da83caa35", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "~1.0,>=1.0.2", + "php": ">=5.3.3", + "phpunit/php-text-template": "~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-06-11 15:55:48" + }, + { + "name": "sebastian/comparator", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "1dd8869519a225f7f2b9eb663e225298fade819e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/1dd8869519a225f7f2b9eb663e225298fade819e", + "reference": "1dd8869519a225f7f2b9eb663e225298fade819e", + "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.1.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "http://www.github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "time": "2015-01-29 16:28:08" + }, + { + "name": "sebastian/diff", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "863df9687835c62aa423a22412d26fa2ebde3fd3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/863df9687835c62aa423a22412d26fa2ebde3fd3", + "reference": "863df9687835c62aa423a22412d26fa2ebde3fd3", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3-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": "http://www.github.com/sebastianbergmann/diff", + "keywords": [ + "diff" + ], + "time": "2015-02-22 15:13:53" + }, + { + "name": "sebastian/environment", + "version": "1.2.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "5a8c7d31914337b69923db26c4221b81ff5a196e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/5a8c7d31914337b69923db26c4221b81ff5a196e", + "reference": "5a8c7d31914337b69923db26c4221b81ff5a196e", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "time": "2015-01-01 10:01:08" + }, + { + "name": "sebastian/exporter", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "84839970d05254c73cde183a721c7af13aede943" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/84839970d05254c73cde183a721c7af13aede943", + "reference": "84839970d05254c73cde183a721c7af13aede943", + "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-01-27 07:23:06" + }, + { + "name": "sebastian/global-state", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "c7428acdb62ece0a45e6306f1ae85e1c05b09c01" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/c7428acdb62ece0a45e6306f1ae85e1c05b09c01", + "reference": "c7428acdb62ece0a45e6306f1ae85e1c05b09c01", + "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": "2014-10-06 09:23:50" + }, + { + "name": "sebastian/recursion-context", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "3989662bbb30a29d20d9faa04a846af79b276252" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/3989662bbb30a29d20d9faa04a846af79b276252", + "reference": "3989662bbb30a29d20d9faa04a846af79b276252", + "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-01-24 09:48:32" + }, + { + "name": "sebastian/version", + "version": "1.0.6", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", + "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", + "shasum": "" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "time": "2015-06-21 13:59:46" + }, + { + "name": "symfony/yaml", + "version": "v2.7.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/Yaml.git", + "reference": "9808e75c609a14f6db02f70fccf4ca4aab53c160" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/Yaml/zipball/9808e75c609a14f6db02f70fccf4ca4aab53c160", + "reference": "9808e75c609a14f6db02f70fccf4ca4aab53c160", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "require-dev": { + "symfony/phpunit-bridge": "~2.7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Yaml\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Yaml Component", + "homepage": "https://symfony.com", + "time": "2015-06-10 15:30:22" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": { + "phpdocumentor/reflection-common": 20 + }, + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": ">=5.5" + }, + "platform-dev": [] +} diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/examples/01-interpreting-a-simple-docblock.php b/src/composer/vendor/phpdocumentor/reflection-docblock/examples/01-interpreting-a-simple-docblock.php new file mode 100644 index 00000000..6d67dea4 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/examples/01-interpreting-a-simple-docblock.php @@ -0,0 +1,27 @@ +create($docComment); + +// Should contain the first line of the DocBlock +$summary = $docblock->getSummary(); + +// Contains an object of type Description; you can either cast it to string or use +// the render method to get a string representation of the Description. +// +// In subsequent examples we will be fiddling a bit more with the Description. +$description = $docblock->getDescription(); diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/examples/02-interpreting-tags.php b/src/composer/vendor/phpdocumentor/reflection-docblock/examples/02-interpreting-tags.php new file mode 100644 index 00000000..23995889 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/examples/02-interpreting-tags.php @@ -0,0 +1,24 @@ +create($docComment); + +// You can check if a DocBlock has one or more see tags +$hasSeeTag = $docblock->hasTag('see'); + +// Or we can get a complete list of all tags +$tags = $docblock->getTags(); + +// But we can also grab all tags of a specific type, such as `see` +$seeTags = $docblock->getTagsByName('see'); diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/examples/03-reconstituting-a-docblock.php b/src/composer/vendor/phpdocumentor/reflection-docblock/examples/03-reconstituting-a-docblock.php new file mode 100644 index 00000000..6bc10baf --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/examples/03-reconstituting-a-docblock.php @@ -0,0 +1,27 @@ +create($docComment); + +// Create the serializer that will reconstitute the DocBlock back to its original form. +$serializer = new Serializer(); + +// Reconstitution is performed by the `getDocComment()` method. +$reconstitutedDocComment = $serializer->getDocComment($docblock); + diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/examples/04-adding-your-own-tag.php b/src/composer/vendor/phpdocumentor/reflection-docblock/examples/04-adding-your-own-tag.php new file mode 100644 index 00000000..026d6069 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/examples/04-adding-your-own-tag.php @@ -0,0 +1,135 @@ + Important: Tag classes that act as Factories using the `create` method should implement the TagFactory interface. + */ +final class MyTag extends BaseTag implements StaticMethod +{ + /** + * A required property that is used by Formatters to reconstitute the complete tag line. + * + * @see Formatter + * + * @var string + */ + protected $name = 'my-tag'; + + /** + * The constructor for this Tag; this should contain all properties for this object. + * + * @param Description $description An example of how to add a Description to the tag; the Description is often + * an optional variable so passing null is allowed in this instance (though you can + * also construct an empty description object). + * + * @see BaseTag for the declaration of the description property and getDescription method. + */ + public function __construct(Description $description = null) + { + $this->description = $description; + } + + /** + * A static Factory that creates a new instance of the current Tag. + * + * In this example the MyTag tag can be created by passing a description text as $body. Because we have added + * a $descriptionFactory that is type-hinted as DescriptionFactory we can now construct a new Description object + * and pass that to the constructor. + * + * > You could directly instantiate a Description object here but that won't be parsed for inline tags and Types + * > won't be resolved. The DescriptionFactory will take care of those actions. + * + * The `create` method's interface states that this method only features a single parameter (`$body`) but the + * {@see TagFactory} will read the signature of this method and if it has more parameters then it will try + * to find declarations for it in the ServiceLocator of the TagFactory (see {@see TagFactory::$serviceLocator}). + * + * > Important: all properties following the `$body` should default to `null`, otherwise PHP will error because + * > it no longer matches the interface. This is why you often see the default tags check that an optional argument + * > is not null nonetheless. + * + * @param string $body + * @param DescriptionFactory $descriptionFactory + * @param Context|null $context The Context is used to resolve Types and FQSENs, although optional + * it is highly recommended to pass it. If you omit it then it is assumed that + * the DocBlock is in the global namespace and has no `use` statements. + * + * @see Tag for the interface declaration of the `create` method. + * @see Tag::create() for more information on this method's workings. + * + * @return MyTag + */ + public static function create($body, DescriptionFactory $descriptionFactory = null, Context $context = null) + { + Assert::string($body); + Assert::notNull($descriptionFactory); + + return new static($descriptionFactory->create($body, $context)); + } + + /** + * Returns a rendition of the original tag line. + * + * This method is used to reconstitute a DocBlock into its original form by the {@see Serializer}. It should + * feature all parts of the tag so that the serializer can put it back together. + * + * @return string + */ + public function __toString() + { + return (string)$this->description; + } +} + +$docComment = << MyTag::class]; + +// Do pass the list of custom tags to the Factory for the DocBlockFactory. +$factory = DocBlockFactory::createInstance($customTags); +// You can also add Tags later using `$factory->registerTagHandler()` with a tag name and Tag class name. + +// Create the DocBlock +$docblock = $factory->create($docComment); + +// Take a look: the $customTagObjects now contain an array with your newly added tag +$customTagObjects = $docblock->getTagsByName('my-tag'); + +// As an experiment: let's reconstitute the DocBlock and observe that because we added a __toString() method +// to the tag class that we can now also see it. +$serializer = new Serializer(); +$reconstitutedDocComment = $serializer->getDocComment($docblock); diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/examples/playing-with-descriptions/02-escaping.php b/src/composer/vendor/phpdocumentor/reflection-docblock/examples/playing-with-descriptions/02-escaping.php new file mode 100644 index 00000000..5ec772fe --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/examples/playing-with-descriptions/02-escaping.php @@ -0,0 +1,47 @@ +create($docComment); + +// Escaping is automatic so this happens in the DescriptionFactory. +$description = $docblock->getDescription(); + +// This is the rendition that we will receive of the Description. +$receivedDocComment = <<render(); diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/phpmd.xml.dist b/src/composer/vendor/phpdocumentor/reflection-docblock/phpmd.xml.dist new file mode 100644 index 00000000..9abf85cf --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/phpmd.xml.dist @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + 40 + + + diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/phpunit.xml.dist b/src/composer/vendor/phpdocumentor/reflection-docblock/phpunit.xml.dist new file mode 100644 index 00000000..3c2e9a37 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/phpunit.xml.dist @@ -0,0 +1,33 @@ + + + + + + ./tests/unit + + + ./tests/integration + + + + + ./src/ + + + ./vendor/ + + + + + + diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock.php b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock.php new file mode 100644 index 00000000..39911406 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock.php @@ -0,0 +1,220 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection; + +use phpDocumentor\Reflection\DocBlock\Tag; +use Webmozart\Assert\Assert; + +final class DocBlock +{ + /** @var string The opening line for this docblock. */ + private $summary = ''; + + /** @var DocBlock\Description The actual description for this docblock. */ + private $description = null; + + /** @var Tag[] An array containing all the tags in this docblock; except inline. */ + private $tags = array(); + + /** @var Types\Context Information about the context of this DocBlock. */ + private $context = null; + + /** @var Location Information about the location of this DocBlock. */ + private $location = null; + + /** @var bool Is this DocBlock (the start of) a template? */ + private $isTemplateStart = false; + + /** @var bool Does this DocBlock signify the end of a DocBlock template? */ + private $isTemplateEnd = false; + + /** + * @param string $summary + * @param DocBlock\Description $description + * @param DocBlock\Tag[] $tags + * @param Types\Context $context The context in which the DocBlock occurs. + * @param Location $location The location within the file that this DocBlock occurs in. + * @param bool $isTemplateStart + * @param bool $isTemplateEnd + */ + public function __construct( + $summary = '', + DocBlock\Description $description = null, + array $tags = [], + Types\Context $context = null, + Location $location = null, + $isTemplateStart = false, + $isTemplateEnd = false + ) + { + Assert::string($summary); + Assert::boolean($isTemplateStart); + Assert::boolean($isTemplateEnd); + Assert::allIsInstanceOf($tags, Tag::class); + + $this->summary = $summary; + $this->description = $description ?: new DocBlock\Description(''); + foreach ($tags as $tag) { + $this->addTag($tag); + } + + $this->context = $context; + $this->location = $location; + + $this->isTemplateEnd = $isTemplateEnd; + $this->isTemplateStart = $isTemplateStart; + } + + /** + * @return string + */ + public function getSummary() + { + return $this->summary; + } + + /** + * @return DocBlock\Description + */ + public function getDescription() + { + return $this->description; + } + + /** + * Returns the current context. + * + * @return Types\Context + */ + public function getContext() + { + return $this->context; + } + + /** + * Returns the current location. + * + * @return Location + */ + public function getLocation() + { + return $this->location; + } + + /** + * Returns whether this DocBlock is the start of a Template section. + * + * A Docblock may serve as template for a series of subsequent DocBlocks. This is indicated by a special marker + * (`#@+`) that is appended directly after the opening `/**` of a DocBlock. + * + * An example of such an opening is: + * + * ``` + * /**#@+ + * * My DocBlock + * * / + * ``` + * + * The description and tags (not the summary!) are copied onto all subsequent DocBlocks and also applied to all + * elements that follow until another DocBlock is found that contains the closing marker (`#@-`). + * + * @see self::isTemplateEnd() for the check whether a closing marker was provided. + * + * @return boolean + */ + public function isTemplateStart() + { + return $this->isTemplateStart; + } + + /** + * Returns whether this DocBlock is the end of a Template section. + * + * @see self::isTemplateStart() for a more complete description of the Docblock Template functionality. + * + * @return boolean + */ + public function isTemplateEnd() + { + return $this->isTemplateEnd; + } + + /** + * Returns the tags for this DocBlock. + * + * @return Tag[] + */ + public function getTags() + { + return $this->tags; + } + + /** + * Returns an array of tags matching the given name. If no tags are found + * an empty array is returned. + * + * @param string $name String to search by. + * + * @return Tag[] + */ + public function getTagsByName($name) + { + Assert::string($name); + + $result = array(); + + /** @var Tag $tag */ + foreach ($this->getTags() as $tag) { + if ($tag->getName() != $name) { + continue; + } + + $result[] = $tag; + } + + return $result; + } + + /** + * Checks if a tag of a certain type is present in this DocBlock. + * + * @param string $name Tag name to check for. + * + * @return bool + */ + public function hasTag($name) + { + Assert::string($name); + + /** @var Tag $tag */ + foreach ($this->getTags() as $tag) { + if ($tag->getName() == $name) { + return true; + } + } + + return false; + } + + /** + * Adds a tag to this DocBlock. + * + * @param Tag $tag The tag to add. + * + * @return void + */ + private function addTag(Tag $tag) + { + $this->tags[] = $tag; + } +} diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Description.php b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Description.php new file mode 100644 index 00000000..d1d7fc64 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Description.php @@ -0,0 +1,103 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock; + +use phpDocumentor\Reflection\DocBlock\Tags\Formatter; +use phpDocumentor\Reflection\DocBlock\Tags\Formatter\PassthroughFormatter; +use Webmozart\Assert\Assert; + +/** + * Object representing to description for a DocBlock. + * + * A Description object can consist of plain text but can also include tags. A Description Formatter can then combine + * a body template with sprintf-style placeholders together with formatted tags in order to reconstitute a complete + * description text using the format that you would prefer. + * + * Because parsing a Description text can be a verbose process this is handled by the {@see DescriptionFactory}. It is + * thus recommended to use that to create a Description object, like this: + * + * $description = $descriptionFactory->create('This is a {@see Description}', $context); + * + * The description factory will interpret the given body and create a body template and list of tags from them, and pass + * that onto the constructor if this class. + * + * > The $context variable is a class of type {@see \phpDocumentor\Reflection\Types\Context} and contains the namespace + * > and the namespace aliases that apply to this DocBlock. These are used by the Factory to resolve and expand partial + * > type names and FQSENs. + * + * If you do not want to use the DescriptionFactory you can pass a body template and tag listing like this: + * + * $description = new Description( + * 'This is a %1$s', + * [ new See(new Fqsen('\phpDocumentor\Reflection\DocBlock\Description')) ] + * ); + * + * It is generally recommended to use the Factory as that will also apply escaping rules, while the Description object + * is mainly responsible for rendering. + * + * @see DescriptionFactory to create a new Description. + * @see Description\Formatter for the formatting of the body and tags. + */ +class Description +{ + /** @var string */ + private $bodyTemplate; + + /** @var Tag[] */ + private $tags; + + /** + * Initializes a Description with its body (template) and a listing of the tags used in the body template. + * + * @param string $bodyTemplate + * @param Tag[] $tags + */ + public function __construct($bodyTemplate, array $tags = []) + { + Assert::string($bodyTemplate); + + $this->bodyTemplate = $bodyTemplate; + $this->tags = $tags; + } + + /** + * Renders this description as a string where the provided formatter will format the tags in the expected string + * format. + * + * @param Formatter|null $formatter + * + * @return string + */ + public function render(Formatter $formatter = null) + { + if ($formatter === null) { + $formatter = new PassthroughFormatter(); + } + + $tags = []; + foreach ($this->tags as $tag) { + $tags[] = '{' . $formatter->format($tag) . '}'; + } + return vsprintf($this->bodyTemplate, $tags); + } + + /** + * Returns a plain string representation of this description. + * + * @return string + */ + public function __toString() + { + return $this->render(); + } +} diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/DescriptionFactory.php b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/DescriptionFactory.php new file mode 100644 index 00000000..f34d0f7e --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/DescriptionFactory.php @@ -0,0 +1,192 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock; + +use phpDocumentor\Reflection\Types\Context as TypeContext; + +/** + * Creates a new Description object given a body of text. + * + * Descriptions in phpDocumentor are somewhat complex entities as they can contain one or more tags inside their + * body that can be replaced with a readable output. The replacing is done by passing a Formatter object to the + * Description object's `render` method. + * + * In addition to the above does a Description support two types of escape sequences: + * + * 1. `{@}` to escape the `@` character to prevent it from being interpreted as part of a tag, i.e. `{{@}link}` + * 2. `{}` to escape the `}` character, this can be used if you want to use the `}` character in the description + * of an inline tag. + * + * If a body consists of multiple lines then this factory will also remove any superfluous whitespace at the beginning + * of each line while maintaining any indentation that is used. This will prevent formatting parsers from tripping + * over unexpected spaces as can be observed with tag descriptions. + */ +class DescriptionFactory +{ + /** @var TagFactory */ + private $tagFactory; + + /** + * Initializes this factory with the means to construct (inline) tags. + * + * @param TagFactory $tagFactory + */ + public function __construct(TagFactory $tagFactory) + { + $this->tagFactory = $tagFactory; + } + + /** + * Returns the parsed text of this description. + * + * @param string $contents + * @param TypeContext $context + * + * @return Description + */ + public function create($contents, TypeContext $context = null) + { + list($text, $tags) = $this->parse($this->lex($contents), $context); + + return new Description($text, $tags); + } + + /** + * Strips the contents from superfluous whitespace and splits the description into a series of tokens. + * + * @param string $contents + * + * @return string[] A series of tokens of which the description text is composed. + */ + private function lex($contents) + { + $contents = $this->removeSuperfluousStartingWhitespace($contents); + + // performance optimalization; if there is no inline tag, don't bother splitting it up. + if (strpos($contents, '{@') === false) { + return [$contents]; + } + + return preg_split( + '/\{ + # "{@}" is not a valid inline tag. This ensures that we do not treat it as one, but treat it literally. + (?!@\}) + # We want to capture the whole tag line, but without the inline tag delimiters. + (\@ + # Match everything up to the next delimiter. + [^{}]* + # Nested inline tag content should not be captured, or it will appear in the result separately. + (?: + # Match nested inline tags. + (?: + # Because we did not catch the tag delimiters earlier, we must be explicit with them here. + # Notice that this also matches "{}", as a way to later introduce it as an escape sequence. + \{(?1)?\} + | + # Make sure we match hanging "{". + \{ + ) + # Match content after the nested inline tag. + [^{}]* + )* # If there are more inline tags, match them as well. We use "*" since there may not be any + # nested inline tags. + ) + \}/Sux', + $contents, + null, + PREG_SPLIT_DELIM_CAPTURE + ); + } + + /** + * Parses the stream of tokens in to a new set of tokens containing Tags. + * + * @param string[] $tokens + * @param TypeContext $context + * + * @return string[]|Tag[] + */ + private function parse($tokens, TypeContext $context) + { + $count = count($tokens); + $tagCount = 0; + $tags = []; + + for ($i = 1; $i < $count; $i += 2) { + $tags[] = $this->tagFactory->create($tokens[$i], $context); + $tokens[$i] = '%' . ++$tagCount . '$s'; + } + + //In order to allow "literal" inline tags, the otherwise invalid + //sequence "{@}" is changed to "@", and "{}" is changed to "}". + //"%" is escaped to "%%" because of vsprintf. + //See unit tests for examples. + for ($i = 0; $i < $count; $i += 2) { + $tokens[$i] = str_replace(['{@}', '{}', '%'], ['@', '}', '%%'], $tokens[$i]); + } + + return [implode('', $tokens), $tags]; + } + + /** + * Removes the superfluous from a multi-line description. + * + * When a description has more than one line then it can happen that the second and subsequent lines have an + * additional indentation. This is commonly in use with tags like this: + * + * {@}since 1.1.0 This is an example + * description where we have an + * indentation in the second and + * subsequent lines. + * + * If we do not normalize the indentation then we have superfluous whitespace on the second and subsequent + * lines and this may cause rendering issues when, for example, using a Markdown converter. + * + * @param string $contents + * + * @return string + */ + private function removeSuperfluousStartingWhitespace($contents) + { + $lines = explode("\n", $contents); + + // if there is only one line then we don't have lines with superfluous whitespace and + // can use the contents as-is + if (count($lines) <= 1) { + return $contents; + } + + // determine how many whitespace characters need to be stripped + $startingSpaceCount = 9999999; + for ($i = 1; $i < count($lines); $i++) { + // lines with a no length do not count as they are not indented at all + if (strlen(trim($lines[$i])) === 0) { + continue; + } + + // determine the number of prefixing spaces by checking the difference in line length before and after + // an ltrim + $startingSpaceCount = min($startingSpaceCount, strlen($lines[$i]) - strlen(ltrim($lines[$i]))); + } + + // strip the number of spaces from each line + if ($startingSpaceCount > 0) { + for ($i = 1; $i < count($lines); $i++) { + $lines[$i] = substr($lines[$i], $startingSpaceCount); + } + } + + return implode("\n", $lines); + } + +} diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/ExampleFinder.php b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/ExampleFinder.php new file mode 100644 index 00000000..3cc5dab3 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/ExampleFinder.php @@ -0,0 +1,170 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection; + +use phpDocumentor\Reflection\DocBlock\Tags\Example; + +/** + * Class used to find an example file's location based on a given ExampleDescriptor. + */ +class ExampleFinder +{ + /** @var string */ + private $sourceDirectory = ''; + + /** @var string[] */ + private $exampleDirectories = array(); + + /** + * Attempts to find the example contents for the given descriptor. + * + * @param Example $example + * + * @return string + */ + public function find(Example $example) + { + $filename = $example->getFilePath(); + + $file = $this->getExampleFileContents($filename); + if (!$file) { + return "** File not found : {$filename} **"; + } + + return implode('', array_slice($file, $example->getStartingLine() - 1, $example->getLineCount())); + } + + /** + * Registers the project's root directory where an 'examples' folder can be expected. + * + * @param string $directory + * + * @return void + */ + public function setSourceDirectory($directory = '') + { + $this->sourceDirectory = $directory; + } + + /** + * Returns the project's root directory where an 'examples' folder can be expected. + * + * @return string + */ + public function getSourceDirectory() + { + return $this->sourceDirectory; + } + + /** + * Registers a series of directories that may contain examples. + * + * @param string[] $directories + */ + public function setExampleDirectories(array $directories) + { + $this->exampleDirectories = $directories; + } + + /** + * Returns a series of directories that may contain examples. + * + * @return string[] + */ + public function getExampleDirectories() + { + return $this->exampleDirectories; + } + + /** + * Attempts to find the requested example file and returns its contents or null if no file was found. + * + * This method will try several methods in search of the given example file, the first one it encounters is + * returned: + * + * 1. Iterates through all examples folders for the given filename + * 2. Checks the source folder for the given filename + * 3. Checks the 'examples' folder in the current working directory for examples + * 4. Checks the path relative to the current working directory for the given filename + * + * @param string $filename + * + * @return string|null + */ + private function getExampleFileContents($filename) + { + $normalizedPath = null; + + foreach ($this->exampleDirectories as $directory) { + $exampleFileFromConfig = $this->constructExamplePath($directory, $filename); + if (is_readable($exampleFileFromConfig)) { + $normalizedPath = $exampleFileFromConfig; + break; + } + } + + if (!$normalizedPath) { + if (is_readable($this->getExamplePathFromSource($filename))) { + $normalizedPath = $this->getExamplePathFromSource($filename); + } elseif (is_readable($this->getExamplePathFromExampleDirectory($filename))) { + $normalizedPath = $this->getExamplePathFromExampleDirectory($filename); + } elseif (is_readable($filename)) { + $normalizedPath = $filename; + } + } + + return $normalizedPath && is_readable($normalizedPath) ? file($normalizedPath) : null; + } + + /** + * Get example filepath based on the example directory inside your project. + * + * @param string $file + * + * @return string + */ + private function getExamplePathFromExampleDirectory($file) + { + return getcwd() . DIRECTORY_SEPARATOR . 'examples' . DIRECTORY_SEPARATOR . $file; + } + + /** + * Returns a path to the example file in the given directory.. + * + * @param string $directory + * @param string $file + * + * @return string + */ + private function constructExamplePath($directory, $file) + { + return rtrim($directory, '\\/') . DIRECTORY_SEPARATOR . $file; + } + + /** + * Get example filepath based on sourcecode. + * + * @param string $file + * + * @return string + */ + private function getExamplePathFromSource($file) + { + return sprintf( + '%s%s%s', + trim($this->getSourceDirectory(), '\\/'), + DIRECTORY_SEPARATOR, + trim($file, '"') + ); + } +} diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Serializer.php b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Serializer.php new file mode 100644 index 00000000..7f1c89d3 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Serializer.php @@ -0,0 +1,143 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock; + +use phpDocumentor\Reflection\DocBlock; +use Webmozart\Assert\Assert; + +/** + * Converts a DocBlock back from an object to a complete DocComment including Asterisks. + */ +class Serializer +{ + /** @var string The string to indent the comment with. */ + protected $indentString = ' '; + + /** @var int The number of times the indent string is repeated. */ + protected $indent = 0; + + /** @var bool Whether to indent the first line with the given indent amount and string. */ + protected $isFirstLineIndented = true; + + /** @var int|null The max length of a line. */ + protected $lineLength = null; + + /** + * Create a Serializer instance. + * + * @param int $indent The number of times the indent string is repeated. + * @param string $indentString The string to indent the comment with. + * @param bool $indentFirstLine Whether to indent the first line. + * @param int|null $lineLength The max length of a line or NULL to disable line wrapping. + */ + public function __construct($indent = 0, $indentString = ' ', $indentFirstLine = true, $lineLength = null) + { + Assert::integer($indent); + Assert::string($indentString); + Assert::boolean($indentFirstLine); + Assert::nullOrInteger($lineLength); + + $this->indent = $indent; + $this->indentString = $indentString; + $this->isFirstLineIndented = $indentFirstLine; + $this->lineLength = $lineLength; + } + + /** + * Generate a DocBlock comment. + * + * @param DocBlock $docblock The DocBlock to serialize. + * + * @return string The serialized doc block. + */ + public function getDocComment(DocBlock $docblock) + { + $indent = str_repeat($this->indentString, $this->indent); + $firstIndent = $this->isFirstLineIndented ? $indent : ''; + // 3 === strlen(' * ') + $wrapLength = $this->lineLength ? $this->lineLength - strlen($indent) - 3 : null; + + $text = $this->removeTrailingSpaces( + $indent, + $this->addAsterisksForEachLine( + $indent, + $this->getSummaryAndDescriptionTextBlock($docblock, $wrapLength) + ) + ); + + $comment = "{$firstIndent}/**\n{$indent} * {$text}\n{$indent} *\n"; + $comment = $this->addTagBlock($docblock, $wrapLength, $indent, $comment); + $comment .= $indent . ' */'; + + return $comment; + } + + /** + * @param $indent + * @param $text + * @return mixed + */ + private function removeTrailingSpaces($indent, $text) + { + return str_replace("\n{$indent} * \n", "\n{$indent} *\n", $text); + } + + /** + * @param $indent + * @param $text + * @return mixed + */ + private function addAsterisksForEachLine($indent, $text) + { + return str_replace("\n", "\n{$indent} * ", $text); + } + + /** + * @param DocBlock $docblock + * @param $wrapLength + * @return string + */ + private function getSummaryAndDescriptionTextBlock(DocBlock $docblock, $wrapLength) + { + $text = $docblock->getSummary() . ((string)$docblock->getDescription() ? "\n\n" . $docblock->getDescription() + : ''); + if ($wrapLength !== null) { + $text = wordwrap($text, $wrapLength); + return $text; + } + return $text; + } + + /** + * @param DocBlock $docblock + * @param $wrapLength + * @param $indent + * @param $comment + * @return string + */ + private function addTagBlock(DocBlock $docblock, $wrapLength, $indent, $comment) + { + foreach ($docblock->getTags() as $tag) { + $formatter = new DocBlock\Tags\Formatter\PassthroughFormatter(); + $tagText = $formatter->format($tag); + if ($wrapLength !== null) { + $tagText = wordwrap($tagText, $wrapLength); + } + $tagText = str_replace("\n", "\n{$indent} * ", $tagText); + + $comment .= "{$indent} * {$tagText}\n"; + } + + return $comment; + } +} diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/StandardTagFactory.php b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/StandardTagFactory.php new file mode 100644 index 00000000..0a656466 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/StandardTagFactory.php @@ -0,0 +1,314 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock; + +use phpDocumentor\Reflection\DocBlock\Tags\Factory\StaticMethod; +use phpDocumentor\Reflection\DocBlock\Tags\Generic; +use phpDocumentor\Reflection\FqsenResolver; +use phpDocumentor\Reflection\Types\Context as TypeContext; +use Webmozart\Assert\Assert; + +/** + * Creates a Tag object given the contents of a tag. + * + * This Factory is capable of determining the appropriate class for a tag and instantiate it using its `create` + * factory method. The `create` factory method of a Tag can have a variable number of arguments; this way you can + * pass the dependencies that you need to construct a tag object. + * + * > Important: each parameter in addition to the body variable for the `create` method must default to null, otherwise + * > it violates the constraint with the interface; it is recommended to use the {@see Assert::notNull()} method to + * > verify that a dependency is actually passed. + * + * This Factory also features a Service Locator component that is used to pass the right dependencies to the + * `create` method of a tag; each dependency should be registered as a service or as a parameter. + * + * When you want to use a Tag of your own with custom handling you need to call the `registerTagHandler` method, pass + * the name of the tag and a Fully Qualified Class Name pointing to a class that implements the Tag interface. + */ +final class StandardTagFactory implements TagFactory +{ + /** PCRE regular expression matching a tag name. */ + const REGEX_TAGNAME = '[\w\-\_\\\\]+'; + + /** + * @var string[] An array with a tag as a key, and an FQCN to a class that handles it as an array value. + */ + private $tagHandlerMappings = [ + 'author' => '\phpDocumentor\Reflection\DocBlock\Tags\Author', + 'covers' => '\phpDocumentor\Reflection\DocBlock\Tags\Covers', + 'deprecated' => '\phpDocumentor\Reflection\DocBlock\Tags\Deprecated', + // 'example' => '\phpDocumentor\Reflection\DocBlock\Tags\Example', + 'link' => '\phpDocumentor\Reflection\DocBlock\Tags\Link', + 'method' => '\phpDocumentor\Reflection\DocBlock\Tags\Method', + 'param' => '\phpDocumentor\Reflection\DocBlock\Tags\Param', + 'property-read' => '\phpDocumentor\Reflection\DocBlock\Tags\PropertyRead', + 'property' => '\phpDocumentor\Reflection\DocBlock\Tags\Property', + 'property-write' => '\phpDocumentor\Reflection\DocBlock\Tags\PropertyWrite', + 'return' => '\phpDocumentor\Reflection\DocBlock\Tags\Return_', + 'see' => '\phpDocumentor\Reflection\DocBlock\Tags\See', + 'since' => '\phpDocumentor\Reflection\DocBlock\Tags\Since', + 'source' => '\phpDocumentor\Reflection\DocBlock\Tags\Source', + 'throw' => '\phpDocumentor\Reflection\DocBlock\Tags\Throws', + 'throws' => '\phpDocumentor\Reflection\DocBlock\Tags\Throws', + 'uses' => '\phpDocumentor\Reflection\DocBlock\Tags\Uses', + 'var' => '\phpDocumentor\Reflection\DocBlock\Tags\Var_', + 'version' => '\phpDocumentor\Reflection\DocBlock\Tags\Version' + ]; + + /** + * @var \ReflectionParameter[][] a lazy-loading cache containing parameters for each tagHandler that has been used. + */ + private $tagHandlerParameterCache = []; + + /** + * @var FqsenResolver + */ + private $fqsenResolver; + + /** + * @var mixed[] an array representing a simple Service Locator where we can store parameters and + * services that can be inserted into the Factory Methods of Tag Handlers. + */ + private $serviceLocator = []; + + /** + * Initialize this tag factory with the means to resolve an FQSEN and optionally a list of tag handlers. + * + * If no tag handlers are provided than the default list in the {@see self::$tagHandlerMappings} property + * is used. + * + * @param FqsenResolver $fqsenResolver + * @param string[] $tagHandlers + * + * @see self::registerTagHandler() to add a new tag handler to the existing default list. + */ + public function __construct(FqsenResolver $fqsenResolver, array $tagHandlers = null) + { + $this->fqsenResolver = $fqsenResolver; + if ($tagHandlers !== null) { + $this->tagHandlerMappings = $tagHandlers; + } + + $this->addService($fqsenResolver, FqsenResolver::class); + } + + /** + * {@inheritDoc} + */ + public function create($tagLine, TypeContext $context = null) + { + if (! $context) { + $context = new TypeContext(''); + } + + list($tagName, $tagBody) = $this->extractTagParts($tagLine); + + return $this->createTag($tagBody, $tagName, $context); + } + + /** + * {@inheritDoc} + */ + public function addParameter($name, $value) + { + $this->serviceLocator[$name] = $value; + } + + /** + * {@inheritDoc} + */ + public function addService($service, $alias = null) + { + $this->serviceLocator[$alias ?: get_class($service)] = $service; + } + + /** + * {@inheritDoc} + */ + public function registerTagHandler($tagName, $handler) + { + Assert::stringNotEmpty($tagName); + Assert::stringNotEmpty($handler); + Assert::classExists($handler); + Assert::implementsInterface($handler, StaticMethod::class); + + if (strpos($tagName, '\\') && $tagName[0] !== '\\') { + throw new \InvalidArgumentException( + 'A namespaced tag must have a leading backslash as it must be fully qualified' + ); + } + + $this->tagHandlerMappings[$tagName] = $handler; + } + + /** + * Extracts all components for a tag. + * + * @param string $tagLine + * + * @return string[] + */ + private function extractTagParts($tagLine) + { + $matches = array(); + if (! preg_match('/^@(' . self::REGEX_TAGNAME . ')(?:\s*([^\s].*)|$)?/us', $tagLine, $matches)) { + throw new \InvalidArgumentException( + 'The tag "' . $tagLine . '" does not seem to be wellformed, please check it for errors' + ); + } + + if (count($matches) < 3) { + $matches[] = ''; + } + + return array_slice($matches, 1); + } + + /** + * Creates a new tag object with the given name and body or returns null if the tag name was recognized but the + * body was invalid. + * + * @param string $body + * @param string $name + * @param TypeContext $context + * + * @return Tag|null + */ + private function createTag($body, $name, TypeContext $context) + { + $handlerClassName = $this->findHandlerClassName($name, $context); + $arguments = $this->getArgumentsForParametersFromWiring( + $this->fetchParametersForHandlerFactoryMethod($handlerClassName), + $this->getServiceLocatorWithDynamicParameters($context, $name, $body) + ) + ; + + return call_user_func_array([$handlerClassName, 'create'], $arguments); + } + + /** + * Determines the Fully Qualified Class Name of the Factory or Tag (containing a Factory Method `create`). + * + * @param string $tagName + * @param TypeContext $context + * + * @return string + */ + private function findHandlerClassName($tagName, TypeContext $context) + { + $handlerClassName = Generic::class; + if (isset($this->tagHandlerMappings[$tagName])) { + $handlerClassName = $this->tagHandlerMappings[$tagName]; + } elseif ($this->isAnnotation($tagName)) { + // TODO: Annotation support is planned for a later stage and as such is disabled for now + // $tagName = (string)$this->fqsenResolver->resolve($tagName, $context); + // if (isset($this->annotationMappings[$tagName])) { + // $handlerClassName = $this->annotationMappings[$tagName]; + // } + } + + return $handlerClassName; + } + + /** + * Retrieves the arguments that need to be passed to the Factory Method with the given Parameters. + * + * @param \ReflectionParameter[] $parameters + * @param mixed[] $locator + * + * @return mixed[] A series of values that can be passed to the Factory Method of the tag whose parameters + * is provided with this method. + */ + private function getArgumentsForParametersFromWiring($parameters, $locator) + { + $arguments = []; + foreach ($parameters as $index => $parameter) { + $typeHint = $parameter->getClass() ? $parameter->getClass()->getName() : null; + if (isset($locator[$typeHint])) { + $arguments[] = $locator[$typeHint]; + continue; + } + + $parameterName = $parameter->getName(); + if (isset($locator[$parameterName])) { + $arguments[] = $locator[$parameterName]; + continue; + } + + $arguments[] = null; + } + + return $arguments; + } + + /** + * Retrieves a series of ReflectionParameter objects for the static 'create' method of the given + * tag handler class name. + * + * @param string $handlerClassName + * + * @return \ReflectionParameter[] + */ + private function fetchParametersForHandlerFactoryMethod($handlerClassName) + { + if (! isset($this->tagHandlerParameterCache[$handlerClassName])) { + $methodReflection = new \ReflectionMethod($handlerClassName, 'create'); + $this->tagHandlerParameterCache[$handlerClassName] = $methodReflection->getParameters(); + } + + return $this->tagHandlerParameterCache[$handlerClassName]; + } + + /** + * Returns a copy of this class' Service Locator with added dynamic parameters, such as the tag's name, body and + * Context. + * + * @param TypeContext $context The Context (namespace and aliasses) that may be passed and is used to resolve FQSENs. + * @param string $tagName The name of the tag that may be passed onto the factory method of the Tag class. + * @param string $tagBody The body of the tag that may be passed onto the factory method of the Tag class. + * + * @return mixed[] + */ + private function getServiceLocatorWithDynamicParameters(TypeContext $context, $tagName, $tagBody) + { + $locator = array_merge( + $this->serviceLocator, + [ + 'name' => $tagName, + 'body' => $tagBody, + TypeContext::class => $context + ] + ); + + return $locator; + } + + /** + * Returns whether the given tag belongs to an annotation. + * + * @param string $tagContent + * + * @todo this method should be populated once we implement Annotation notation support. + * + * @return bool + */ + private function isAnnotation($tagContent) + { + // 1. Contains a namespace separator + // 2. Contains parenthesis + // 3. Is present in a list of known annotations (make the algorithm smart by first checking is the last part + // of the annotation class name matches the found tag name + + return false; + } +} diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tag.php b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tag.php new file mode 100644 index 00000000..e7653678 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tag.php @@ -0,0 +1,26 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock; + +use phpDocumentor\Reflection\DocBlock\Tags\Formatter; + +interface Tag +{ + public function getName(); + + public static function create($body); + + public function render(Formatter $formatter = null); + + public function __toString(); +} diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/TagFactory.php b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/TagFactory.php new file mode 100644 index 00000000..3c1d1132 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/TagFactory.php @@ -0,0 +1,93 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock; + +use phpDocumentor\Reflection\Types\Context as TypeContext; + +interface TagFactory +{ + /** + * Adds a parameter to the service locator that can be injected in a tag's factory method. + * + * When calling a tag's "create" method we always check the signature for dependencies to inject. One way is to + * typehint a parameter in the signature so that we can use that interface or class name to inject a dependency + * (see {@see addService()} for more information on that). + * + * Another way is to check the name of the argument against the names in the Service Locator. With this method + * you can add a variable that will be inserted when a tag's create method is not typehinted and has a matching + * name. + * + * Be aware that there are two reserved names: + * + * - name, representing the name of the tag. + * - body, representing the complete body of the tag. + * + * These parameters are injected at the last moment and will override any existing parameter with those names. + * + * @param string $name + * @param mixed $value + * + * @return void + */ + public function addParameter($name, $value); + + /** + * Registers a service with the Service Locator using the FQCN of the class or the alias, if provided. + * + * When calling a tag's "create" method we always check the signature for dependencies to inject. If a parameter + * has a typehint then the ServiceLocator is queried to see if a Service is registered for that typehint. + * + * Because interfaces are regularly used as type-hints this method provides an alias parameter; if the FQCN of the + * interface is passed as alias then every time that interface is requested the provided service will be returned. + * + * @param object $service + * @param string $alias + * + * @return void + */ + public function addService($service); + + /** + * Factory method responsible for instantiating the correct sub type. + * + * @param string $tagLine The text for this tag, including description. + * @param TypeContext $context + * + * @throws \InvalidArgumentException if an invalid tag line was presented. + * + * @return Tag A new tag object. + */ + public function create($tagLine, TypeContext $context = null); + + /** + * Registers a handler for tags. + * + * If you want to use your own tags then you can use this method to instruct the TagFactory to register the name + * of a tag with the FQCN of a 'Tag Handler'. The Tag handler should implement the {@see Tag} interface (and thus + * the create method). + * + * @param string $tagName Name of tag to register a handler for. When registering a namespaced tag, the full + * name, along with a prefixing slash MUST be provided. + * @param string $handler FQCN of handler. + * + * @throws \InvalidArgumentException if the tag name is not a string + * @throws \InvalidArgumentException if the tag name is namespaced (contains backslashes) but does not start with + * a backslash + * @throws \InvalidArgumentException if the handler is not a string + * @throws \InvalidArgumentException if the handler is not an existing class + * @throws \InvalidArgumentException if the handler does not implement the {@see Tag} interface + * + * @return void + */ + public function registerTagHandler($tagName, $handler); +} diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Author.php b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Author.php new file mode 100644 index 00000000..41a27886 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Author.php @@ -0,0 +1,100 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags; + +use Webmozart\Assert\Assert; + +/** + * Reflection class for an {@}author tag in a Docblock. + */ +final class Author extends BaseTag implements Factory\StaticMethod +{ + /** @var string register that this is the author tag. */ + protected $name = 'author'; + + /** @var string The name of the author */ + private $authorName = ''; + + /** @var string The email of the author */ + private $authorEmail = ''; + + /** + * Initializes this tag with the author name and e-mail. + * + * @param string $authorName + * @param string $authorEmail + */ + public function __construct($authorName, $authorEmail) + { + Assert::string($authorName); + Assert::string($authorEmail); + if ($authorEmail && !filter_var($authorEmail, FILTER_VALIDATE_EMAIL)) { + throw new \InvalidArgumentException('The author tag does not have a valid e-mail address'); + } + + $this->authorName = $authorName; + $this->authorEmail = $authorEmail; + } + + /** + * Gets the author's name. + * + * @return string The author's name. + */ + public function getAuthorName() + { + return $this->authorName; + } + + /** + * Returns the author's email. + * + * @return string The author's email. + */ + public function getEmail() + { + return $this->authorEmail; + } + + /** + * Returns this tag in string form. + * + * @return string + */ + public function __toString() + { + return $this->authorName . '<' . $this->authorEmail . '>'; + } + + /** + * Attempts to create a new Author object based on †he tag body. + * + * @param string $body + * + * @return static + */ + public static function create($body) + { + Assert::string($body); + + $splitTagContent = preg_match('/^([^\<]*)(?:\<([^\>]*)\>)?$/u', $body, $matches); + if (!$splitTagContent) { + return null; + } + + $authorName = trim($matches[1]); + $email = isset($matches[2]) ? trim($matches[2]) : ''; + + return new static($authorName, $email); + } +} diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/BaseTag.php b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/BaseTag.php new file mode 100644 index 00000000..14bb7177 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/BaseTag.php @@ -0,0 +1,52 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags; + +use phpDocumentor\Reflection\DocBlock; +use phpDocumentor\Reflection\DocBlock\Description; + +/** + * Parses a tag definition for a DocBlock. + */ +abstract class BaseTag implements DocBlock\Tag +{ + /** @var string Name of the tag */ + protected $name = ''; + + /** @var Description|null Description of the tag. */ + protected $description; + + /** + * Gets the name of this tag. + * + * @return string The name of this tag. + */ + public function getName() + { + return $this->name; + } + + public function getDescription() + { + return $this->description; + } + + public function render(Formatter $formatter = null) + { + if ($formatter === null) { + $formatter = new Formatter\PassthroughFormatter(); + } + + return $formatter->format($this); + } +} diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Covers.php b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Covers.php new file mode 100644 index 00000000..31b4f82c --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Covers.php @@ -0,0 +1,84 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags; + +use phpDocumentor\Reflection\DocBlock\DescriptionFactory; +use phpDocumentor\Reflection\Fqsen; +use phpDocumentor\Reflection\DocBlock\Description; +use phpDocumentor\Reflection\Types\Context as TypeContext; +use phpDocumentor\Reflection\FqsenResolver; +use Webmozart\Assert\Assert; + +/** + * Reflection class for a @covers tag in a Docblock. + */ +final class Covers extends BaseTag implements Factory\StaticMethod +{ + protected $name = 'covers'; + + /** @var Fqsen */ + private $refers = null; + + /** + * Initializes this tag. + * + * @param Fqsen $refers + * @param Description $description + */ + public function __construct(Fqsen $refers, Description $description = null) + { + $this->refers = $refers; + $this->description = $description; + } + + /** + * {@inheritdoc} + */ + public static function create( + $body, + DescriptionFactory $descriptionFactory = null, + FqsenResolver $resolver = null, + TypeContext $context = null + ) + { + Assert::string($body); + Assert::notEmpty($body); + + $parts = preg_split('/\s+/Su', $body, 2); + + return new static( + $resolver->resolve($parts[0], $context), + $descriptionFactory->create(isset($parts[1]) ? $parts[1] : '', $context) + ); + } + + /** + * Returns the structural element this tag refers to. + * + * @return Fqsen + */ + public function getReference() + { + return $this->refers; + } + + /** + * Returns a string representation of this tag. + * + * @return string + */ + public function __toString() + { + return $this->refers . ($this->description ? ' ' . $this->description->render() : ''); + } +} diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Deprecated.php b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Deprecated.php new file mode 100644 index 00000000..7c1039fa --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Deprecated.php @@ -0,0 +1,97 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags; + +use phpDocumentor\Reflection\Types\Context as TypeContext; +use phpDocumentor\Reflection\DocBlock\Description; +use phpDocumentor\Reflection\DocBlock\DescriptionFactory; +use Webmozart\Assert\Assert; + +/** + * Reflection class for a {@}deprecated tag in a Docblock. + */ +final class Deprecated extends BaseTag implements Factory\StaticMethod +{ + protected $name = 'deprecated'; + + /** + * PCRE regular expression matching a version vector. + * Assumes the "x" modifier. + */ + const REGEX_VECTOR = '(?: + # Normal release vectors. + \d\S* + | + # VCS version vectors. Per PHPCS, they are expected to + # follow the form of the VCS name, followed by ":", followed + # by the version vector itself. + # By convention, popular VCSes like CVS, SVN and GIT use "$" + # around the actual version vector. + [^\s\:]+\:\s*\$[^\$]+\$ + )'; + + /** @var string The version vector. */ + private $version = ''; + + public function __construct($version = null, Description $description = null) + { + Assert::nullOrStringNotEmpty($version); + + $this->version = $version; + $this->description = $description; + } + + /** + * @return static + */ + public static function create($body, DescriptionFactory $descriptionFactory = null, TypeContext $context = null) + { + Assert::nullOrString($body); + if (empty($body)) { + return new static(); + } + + $matches = []; + if (!preg_match('/^(' . self::REGEX_VECTOR . ')\s*(.+)?$/sux', $body, $matches)) { + return new static( + null, + null !== $descriptionFactory ? $descriptionFactory->create($body, $context) : null + ); + } + + return new static( + $matches[1], + $descriptionFactory->create(isset($matches[2]) ? $matches[2] : '', $context) + ); + } + + /** + * Gets the version section of the tag. + * + * @return string + */ + public function getVersion() + { + return $this->version; + } + + /** + * Returns a string representation for this tag. + * + * @return string + */ + public function __toString() + { + return $this->version . ($this->description ? ' ' . $this->description->render() : ''); + } +} diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Example.php b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Example.php new file mode 100644 index 00000000..571ef8df --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Example.php @@ -0,0 +1,158 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags; + +use phpDocumentor\Reflection\DocBlock\Tag; + +/** + * Reflection class for a {@}example tag in a Docblock. + */ +final class Example extends BaseTag +{ + /** + * @var string Path to a file to use as an example. May also be an absolute URI. + */ + private $filePath = ''; + + /** + * @var bool Whether the file path component represents an URI. This determines how the file portion + * appears at {@link getContent()}. + */ + private $isURI = false; + + /** + * {@inheritdoc} + */ + public function getContent() + { + if (null === $this->description) { + $filePath = '"' . $this->filePath . '"'; + if ($this->isURI) { + $filePath = $this->isUriRelative($this->filePath) + ? str_replace('%2F', '/', rawurlencode($this->filePath)) + :$this->filePath; + } + + $this->description = $filePath . ' ' . parent::getContent(); + } + + return $this->description; + } + + /** + * {@inheritdoc} + */ + public static function create($body) + { + // File component: File path in quotes or File URI / Source information + if (! preg_match('/^(?:\"([^\"]+)\"|(\S+))(?:\s+(.*))?$/sux', $body, $matches)) { + return null; + } + + $filePath = null; + $fileUri = null; + if ('' !== $matches[1]) { + $filePath = $matches[1]; + } else { + $fileUri = $matches[2]; + } + + $startingLine = 1; + $lineCount = null; + $description = null; + + // Starting line / Number of lines / Description + if (preg_match('/^([1-9]\d*)\s*(?:((?1))\s+)?(.*)$/sux', $matches[3], $matches)) { + $startingLine = (int)$matches[1]; + if (isset($matches[2]) && $matches[2] !== '') { + $lineCount = (int)$matches[2]; + } + $description = $matches[3]; + } + + return new static($filePath, $fileUri, $startingLine, $lineCount, $description); + } + + /** + * Returns the file path. + * + * @return string Path to a file to use as an example. + * May also be an absolute URI. + */ + public function getFilePath() + { + return $this->filePath; + } + + /** + * Sets the file path. + * + * @param string $filePath The new file path to use for the example. + * + * @return $this + */ + public function setFilePath($filePath) + { + $this->isURI = false; + $this->filePath = trim($filePath); + + $this->description = null; + return $this; + } + + /** + * Sets the file path as an URI. + * + * This function is equivalent to {@link setFilePath()}, except that it + * converts an URI to a file path before that. + * + * There is no getFileURI(), as {@link getFilePath()} is compatible. + * + * @param string $uri The new file URI to use as an example. + * + * @return $this + */ + public function setFileURI($uri) + { + $this->isURI = true; + $this->description = null; + + $this->filePath = $this->isUriRelative($uri) + ? rawurldecode(str_replace(array('/', '\\'), '%2F', $uri)) + : $this->filePath = $uri; + + return $this; + } + + /** + * Returns a string representation for this tag. + * + * @return string + */ + public function __toString() + { + return $this->filePath . ($this->description ? ' ' . $this->description->render() : ''); + } + + /** + * Returns true if the provided URI is relative or contains a complete scheme (and thus is absolute). + * + * @param string $uri + * + * @return bool + */ + private function isUriRelative($uri) + { + return false === strpos($uri, ':'); + } +} diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/StaticMethod.php b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/StaticMethod.php new file mode 100644 index 00000000..98aea455 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/StaticMethod.php @@ -0,0 +1,18 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags\Factory; + +interface StaticMethod +{ + public static function create($body); +} diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/Strategy.php b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/Strategy.php new file mode 100644 index 00000000..b9ca0b8a --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/Strategy.php @@ -0,0 +1,18 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags\Factory; + +interface Strategy +{ + public function create($body); +} diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter.php b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter.php new file mode 100644 index 00000000..64b2c603 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter.php @@ -0,0 +1,27 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags; + +use phpDocumentor\Reflection\DocBlock\Tag; + +interface Formatter +{ + /** + * Formats a tag into a string representation according to a specific format, such as Markdown. + * + * @param Tag $tag + * + * @return string + */ + public function format(Tag $tag); +} diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter/PassthroughFormatter.php b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter/PassthroughFormatter.php new file mode 100644 index 00000000..aa97572c --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter/PassthroughFormatter.php @@ -0,0 +1,31 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags\Formatter; + +use phpDocumentor\Reflection\DocBlock\Tag; +use phpDocumentor\Reflection\DocBlock\Tags\Formatter; + +class PassthroughFormatter implements Formatter +{ + /** + * Formats the given tag to return a simple plain text version. + * + * @param Tag $tag + * + * @return string + */ + public function format(Tag $tag) + { + return '@' . $tag->getName() . ' ' . (string)$tag; + } +} diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Generic.php b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Generic.php new file mode 100644 index 00000000..e4c53e00 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Generic.php @@ -0,0 +1,91 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags; + +use phpDocumentor\Reflection\DocBlock\Description; +use phpDocumentor\Reflection\DocBlock\DescriptionFactory; +use phpDocumentor\Reflection\DocBlock\StandardTagFactory; +use phpDocumentor\Reflection\Types\Context as TypeContext; +use Webmozart\Assert\Assert; + +/** + * Parses a tag definition for a DocBlock. + */ +class Generic extends BaseTag implements Factory\StaticMethod +{ + /** + * Parses a tag and populates the member variables. + * + * @param string $name Name of the tag. + * @param Description $description The contents of the given tag. + */ + public function __construct($name, Description $description = null) + { + $this->validateTagName($name); + + $this->name = $name; + $this->description = $description; + } + + /** + * Creates a new tag that represents any unknown tag type. + * + * @param string $body + * @param string $name + * @param DescriptionFactory $descriptionFactory + * @param TypeContext $context + * + * @return static + */ + public static function create( + $body, + $name = '', + DescriptionFactory $descriptionFactory = null, + TypeContext $context = null + ) { + Assert::string($body); + Assert::stringNotEmpty($name); + Assert::notNull($descriptionFactory); + + $description = $descriptionFactory && $body ? $descriptionFactory->create($body, $context) : null; + + return new static($name, $description); + } + + /** + * Returns the tag as a serialized string + * + * @return string + */ + public function __toString() + { + return ($this->description ? $this->description->render() : ''); + } + + /** + * Validates if the tag name matches the expected format, otherwise throws an exception. + * + * @param string $name + * + * @return void + */ + private function validateTagName($name) + { + if (! preg_match('/^' . StandardTagFactory::REGEX_TAGNAME . '$/u', $name)) { + throw new \InvalidArgumentException( + 'The tag name "' . $name . '" is not wellformed. Tags may only consist of letters, underscores, ' + . 'hyphens and backslashes.' + ); + } + } +} diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Link.php b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Link.php new file mode 100644 index 00000000..9c0e367e --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Link.php @@ -0,0 +1,77 @@ + + * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com) + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags; + +use phpDocumentor\Reflection\DocBlock\Description; +use phpDocumentor\Reflection\DocBlock\DescriptionFactory; +use phpDocumentor\Reflection\Types\Context as TypeContext; +use Webmozart\Assert\Assert; + +/** + * Reflection class for a @link tag in a Docblock. + */ +final class Link extends BaseTag implements Factory\StaticMethod +{ + protected $name = 'link'; + + /** @var string */ + private $link = ''; + + /** + * Initializes a link to a URL. + * + * @param string $link + * @param Description $description + */ + public function __construct($link, Description $description = null) + { + Assert::string($link); + + $this->link = $link; + $this->description = $description; + } + + /** + * {@inheritdoc} + */ + public static function create($body, DescriptionFactory $descriptionFactory = null, TypeContext $context = null) + { + Assert::string($body); + Assert::notNull($descriptionFactory); + + $parts = preg_split('/\s+/Su', $body, 2); + $description = isset($parts[1]) ? $descriptionFactory->create($parts[1], $context) : null; + + return new static($parts[0], $description); + } + + /** + * Gets the link + * + * @return string + */ + public function getLink() + { + return $this->link; + } + + /** + * Returns a string representation for this tag. + * + * @return string + */ + public function __toString() + { + return $this->link . ($this->description ? ' ' . $this->description->render() : ''); + } +} diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Method.php b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Method.php new file mode 100644 index 00000000..d600aaaa --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Method.php @@ -0,0 +1,230 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags; + +use phpDocumentor\Reflection\DocBlock\Description; +use phpDocumentor\Reflection\DocBlock\DescriptionFactory; +use phpDocumentor\Reflection\Type; +use phpDocumentor\Reflection\TypeResolver; +use phpDocumentor\Reflection\Types\Context as TypeContext; +use phpDocumentor\Reflection\Types\Void_; +use Webmozart\Assert\Assert; + +/** + * Reflection class for an {@}method in a Docblock. + */ +final class Method extends BaseTag implements Factory\StaticMethod +{ + protected $name = 'method'; + + /** @var string */ + private $methodName = ''; + + /** @var string[] */ + private $arguments = []; + + /** @var bool */ + private $isStatic = false; + + /** @var Type */ + private $returnType; + + public function __construct( + $methodName, + array $arguments = [], + Type $returnType = null, + $static = false, + Description $description = null + ) { + Assert::stringNotEmpty($methodName); + Assert::boolean($static); + + if ($returnType === null) { + $returnType = new Void_(); + } + + $this->methodName = $methodName; + $this->arguments = $this->filterArguments($arguments); + $this->returnType = $returnType; + $this->isStatic = $static; + $this->description = $description; + } + + /** + * {@inheritdoc} + */ + public static function create( + $body, + TypeResolver $typeResolver = null, + DescriptionFactory $descriptionFactory = null, + TypeContext $context = null + ) { + Assert::stringNotEmpty($body); + Assert::allNotNull([ $typeResolver, $descriptionFactory ]); + + // 1. none or more whitespace + // 2. optionally the keyword "static" followed by whitespace + // 3. optionally a word with underscores followed by whitespace : as + // type for the return value + // 4. then optionally a word with underscores followed by () and + // whitespace : as method name as used by phpDocumentor + // 5. then a word with underscores, followed by ( and any character + // until a ) and whitespace : as method name with signature + // 6. any remaining text : as description + if (!preg_match( + '/^ + # Static keyword + # Declares a static method ONLY if type is also present + (?: + (static) + \s+ + )? + # Return type + (?: + ( + (?:[\w\|_\\\\]+) + # array notation + (?:\[\])* + )? + \s+ + )? + # Legacy method name (not captured) + (?: + [\w_]+\(\)\s+ + )? + # Method name + ([\w\|_\\\\]+) + # Arguments + (?: + \(([^\)]*)\) + )? + \s* + # Description + (.*) + $/sux', + $body, + $matches + )) { + return null; + } + + list(, $static, $returnType, $methodName, $arguments, $description) = $matches; + + $static = $static === 'static'; + $returnType = $typeResolver->resolve($returnType, $context); + $description = $descriptionFactory->create($description, $context); + + if ('' !== $arguments) { + $arguments = explode(',', $arguments); + foreach($arguments as &$argument) { + $argument = explode(' ', self::stripRestArg(trim($argument)), 2); + if ($argument[0][0] === '$') { + $argumentName = substr($argument[0], 1); + $argumentType = new Void_(); + } else { + $argumentType = $typeResolver->resolve($argument[0], $context); + $argumentName = ''; + if (isset($argument[1])) { + $argument[1] = self::stripRestArg($argument[1]); + $argumentName = substr($argument[1], 1); + } + } + + $argument = [ 'name' => $argumentName, 'type' => $argumentType]; + } + } else { + $arguments = []; + } + + return new static($methodName, $arguments, $returnType, $static, $description); + } + + /** + * Retrieves the method name. + * + * @return string + */ + public function getMethodName() + { + return $this->methodName; + } + + /** + * @return string[] + */ + public function getArguments() + { + return $this->arguments; + } + + /** + * Checks whether the method tag describes a static method or not. + * + * @return bool TRUE if the method declaration is for a static method, FALSE otherwise. + */ + public function isStatic() + { + return $this->isStatic; + } + + /** + * @return Type + */ + public function getReturnType() + { + return $this->returnType; + } + + public function __toString() + { + $arguments = []; + foreach ($this->arguments as $argument) { + $arguments[] = $argument['type'] . ' $' . $argument['name']; + } + + return ($this->isStatic() ? 'static ' : '') + . (string)$this->returnType . ' ' + . $this->methodName + . '(' . implode(', ', $arguments) . ')' + . ($this->description ? ' ' . $this->description->render() : ''); + } + + private function filterArguments($arguments) + { + foreach ($arguments as &$argument) { + if (is_string($argument)) { + $argument = [ 'name' => $argument ]; + } + if (! isset($argument['type'])) { + $argument['type'] = new Void_(); + } + $keys = array_keys($argument); + if ($keys !== [ 'name', 'type' ]) { + throw new \InvalidArgumentException( + 'Arguments can only have the "name" and "type" fields, found: ' . var_export($keys, true) + ); + } + } + + return $arguments; + } + + private static function stripRestArg($argument) + { + if (strpos($argument, '...') === 0) { + $argument = trim(substr($argument, 3)); + } + + return $argument; + } +} diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Param.php b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Param.php new file mode 100644 index 00000000..1a51dc0d --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Param.php @@ -0,0 +1,141 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags; + +use phpDocumentor\Reflection\DocBlock\Description; +use phpDocumentor\Reflection\DocBlock\DescriptionFactory; +use phpDocumentor\Reflection\Type; +use phpDocumentor\Reflection\TypeResolver; +use phpDocumentor\Reflection\Types\Context as TypeContext; +use Webmozart\Assert\Assert; + +/** + * Reflection class for the {@}param tag in a Docblock. + */ +final class Param extends BaseTag implements Factory\StaticMethod +{ + /** @var string */ + protected $name = 'param'; + + /** @var Type */ + private $type; + + /** @var string */ + private $variableName = ''; + + /** @var bool determines whether this is a variadic argument */ + private $isVariadic = false; + + /** + * @param string $variableName + * @param Type $type + * @param bool $isVariadic + * @param Description $description + */ + public function __construct($variableName, Type $type = null, $isVariadic = false, Description $description = null) + { + Assert::string($variableName); + Assert::boolean($isVariadic); + + $this->variableName = $variableName; + $this->type = $type; + $this->isVariadic = $isVariadic; + $this->description = $description; + } + + /** + * {@inheritdoc} + */ + public static function create( + $body, + TypeResolver $typeResolver = null, + DescriptionFactory $descriptionFactory = null, + TypeContext $context = null + ) { + Assert::stringNotEmpty($body); + Assert::allNotNull([$typeResolver, $descriptionFactory]); + + $parts = preg_split('/(\s+)/Su', $body, 3, PREG_SPLIT_DELIM_CAPTURE); + $type = null; + $variableName = ''; + $isVariadic = false; + + // if the first item that is encountered is not a variable; it is a type + if (isset($parts[0]) && (strlen($parts[0]) > 0) && ($parts[0][0] !== '$')) { + $type = $typeResolver->resolve(array_shift($parts), $context); + array_shift($parts); + } + + // if the next item starts with a $ or ...$ it must be the variable name + if (isset($parts[0]) && (strlen($parts[0]) > 0) && ($parts[0][0] == '$' || substr($parts[0], 0, 4) === '...$')) { + $variableName = array_shift($parts); + array_shift($parts); + + if (substr($variableName, 0, 3) === '...') { + $isVariadic = true; + $variableName = substr($variableName, 3); + } + + if (substr($variableName, 0, 1) === '$') { + $variableName = substr($variableName, 1); + } + } + + $description = $descriptionFactory->create(implode('', $parts), $context); + + return new static($variableName, $type, $isVariadic, $description); + } + + /** + * Returns the variable's name. + * + * @return string + */ + public function getVariableName() + { + return $this->variableName; + } + + /** + * Returns the variable's type or null if unknown. + * + * @return Type|null + */ + public function getType() + { + return $this->type; + } + + /** + * Returns whether this tag is variadic. + * + * @return boolean + */ + public function isVariadic() + { + return $this->isVariadic; + } + + /** + * Returns a string representation for this tag. + * + * @return string + */ + public function __toString() + { + return ($this->type ? $this->type . ' ' : '') + . ($this->isVariadic() ? '...' : '') + . '$' . $this->variableName + . ($this->description ? ' ' . $this->description : ''); + } +} diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Property.php b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Property.php new file mode 100644 index 00000000..3c597133 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Property.php @@ -0,0 +1,118 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags; + +use phpDocumentor\Reflection\DocBlock\Description; +use phpDocumentor\Reflection\DocBlock\DescriptionFactory; +use phpDocumentor\Reflection\Type; +use phpDocumentor\Reflection\TypeResolver; +use phpDocumentor\Reflection\Types\Context as TypeContext; +use Webmozart\Assert\Assert; + +/** + * Reflection class for a {@}property tag in a Docblock. + */ +class Property extends BaseTag implements Factory\StaticMethod +{ + /** @var string */ + protected $name = 'property'; + + /** @var Type */ + private $type; + + /** @var string */ + protected $variableName = ''; + + /** + * @param string $variableName + * @param Type $type + * @param Description $description + */ + public function __construct($variableName, Type $type = null, Description $description = null) + { + Assert::string($variableName); + + $this->variableName = $variableName; + $this->type = $type; + $this->description = $description; + } + + /** + * {@inheritdoc} + */ + public static function create( + $body, + TypeResolver $typeResolver = null, + DescriptionFactory $descriptionFactory = null, + TypeContext $context = null + ) { + Assert::stringNotEmpty($body); + Assert::allNotNull([$typeResolver, $descriptionFactory]); + + $parts = preg_split('/(\s+)/Su', $body, 3, PREG_SPLIT_DELIM_CAPTURE); + $type = null; + $variableName = ''; + + // if the first item that is encountered is not a variable; it is a type + if (isset($parts[0]) && (strlen($parts[0]) > 0) && ($parts[0][0] !== '$')) { + $type = $typeResolver->resolve(array_shift($parts), $context); + array_shift($parts); + } + + // if the next item starts with a $ or ...$ it must be the variable name + if (isset($parts[0]) && (strlen($parts[0]) > 0) && ($parts[0][0] == '$')) { + $variableName = array_shift($parts); + array_shift($parts); + + if (substr($variableName, 0, 1) === '$') { + $variableName = substr($variableName, 1); + } + } + + $description = $descriptionFactory->create(implode('', $parts), $context); + + return new static($variableName, $type, $description); + } + + /** + * Returns the variable's name. + * + * @return string + */ + public function getVariableName() + { + return $this->variableName; + } + + /** + * Returns the variable's type or null if unknown. + * + * @return Type|null + */ + public function getType() + { + return $this->type; + } + + /** + * Returns a string representation for this tag. + * + * @return string + */ + public function __toString() + { + return ($this->type ? $this->type . ' ' : '') + . '$' . $this->variableName + . ($this->description ? ' ' . $this->description : ''); + } +} diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/PropertyRead.php b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/PropertyRead.php new file mode 100644 index 00000000..bf2b8056 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/PropertyRead.php @@ -0,0 +1,118 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags; + +use phpDocumentor\Reflection\DocBlock\Description; +use phpDocumentor\Reflection\DocBlock\DescriptionFactory; +use phpDocumentor\Reflection\Type; +use phpDocumentor\Reflection\TypeResolver; +use phpDocumentor\Reflection\Types\Context as TypeContext; +use Webmozart\Assert\Assert; + +/** + * Reflection class for a {@}property-read tag in a Docblock. + */ +class PropertyRead extends BaseTag implements Factory\StaticMethod +{ + /** @var string */ + protected $name = 'property-read'; + + /** @var Type */ + private $type; + + /** @var string */ + protected $variableName = ''; + + /** + * @param string $variableName + * @param Type $type + * @param Description $description + */ + public function __construct($variableName, Type $type = null, Description $description = null) + { + Assert::string($variableName); + + $this->variableName = $variableName; + $this->type = $type; + $this->description = $description; + } + + /** + * {@inheritdoc} + */ + public static function create( + $body, + TypeResolver $typeResolver = null, + DescriptionFactory $descriptionFactory = null, + TypeContext $context = null + ) { + Assert::stringNotEmpty($body); + Assert::allNotNull([$typeResolver, $descriptionFactory]); + + $parts = preg_split('/(\s+)/Su', $body, 3, PREG_SPLIT_DELIM_CAPTURE); + $type = null; + $variableName = ''; + + // if the first item that is encountered is not a variable; it is a type + if (isset($parts[0]) && (strlen($parts[0]) > 0) && ($parts[0][0] !== '$')) { + $type = $typeResolver->resolve(array_shift($parts), $context); + array_shift($parts); + } + + // if the next item starts with a $ or ...$ it must be the variable name + if (isset($parts[0]) && (strlen($parts[0]) > 0) && ($parts[0][0] == '$')) { + $variableName = array_shift($parts); + array_shift($parts); + + if (substr($variableName, 0, 1) === '$') { + $variableName = substr($variableName, 1); + } + } + + $description = $descriptionFactory->create(implode('', $parts), $context); + + return new static($variableName, $type, $description); + } + + /** + * Returns the variable's name. + * + * @return string + */ + public function getVariableName() + { + return $this->variableName; + } + + /** + * Returns the variable's type or null if unknown. + * + * @return Type|null + */ + public function getType() + { + return $this->type; + } + + /** + * Returns a string representation for this tag. + * + * @return string + */ + public function __toString() + { + return ($this->type ? $this->type . ' ' : '') + . '$' . $this->variableName + . ($this->description ? ' ' . $this->description : ''); + } +} diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/PropertyWrite.php b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/PropertyWrite.php new file mode 100644 index 00000000..db37e0fb --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/PropertyWrite.php @@ -0,0 +1,118 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags; + +use phpDocumentor\Reflection\DocBlock\Description; +use phpDocumentor\Reflection\DocBlock\DescriptionFactory; +use phpDocumentor\Reflection\Type; +use phpDocumentor\Reflection\TypeResolver; +use phpDocumentor\Reflection\Types\Context as TypeContext; +use Webmozart\Assert\Assert; + +/** + * Reflection class for a {@}property-write tag in a Docblock. + */ +class PropertyWrite extends BaseTag implements Factory\StaticMethod +{ + /** @var string */ + protected $name = 'property-write'; + + /** @var Type */ + private $type; + + /** @var string */ + protected $variableName = ''; + + /** + * @param string $variableName + * @param Type $type + * @param Description $description + */ + public function __construct($variableName, Type $type = null, Description $description = null) + { + Assert::string($variableName); + + $this->variableName = $variableName; + $this->type = $type; + $this->description = $description; + } + + /** + * {@inheritdoc} + */ + public static function create( + $body, + TypeResolver $typeResolver = null, + DescriptionFactory $descriptionFactory = null, + TypeContext $context = null + ) { + Assert::stringNotEmpty($body); + Assert::allNotNull([$typeResolver, $descriptionFactory]); + + $parts = preg_split('/(\s+)/Su', $body, 3, PREG_SPLIT_DELIM_CAPTURE); + $type = null; + $variableName = ''; + + // if the first item that is encountered is not a variable; it is a type + if (isset($parts[0]) && (strlen($parts[0]) > 0) && ($parts[0][0] !== '$')) { + $type = $typeResolver->resolve(array_shift($parts), $context); + array_shift($parts); + } + + // if the next item starts with a $ or ...$ it must be the variable name + if (isset($parts[0]) && (strlen($parts[0]) > 0) && ($parts[0][0] == '$')) { + $variableName = array_shift($parts); + array_shift($parts); + + if (substr($variableName, 0, 1) === '$') { + $variableName = substr($variableName, 1); + } + } + + $description = $descriptionFactory->create(implode('', $parts), $context); + + return new static($variableName, $type, $description); + } + + /** + * Returns the variable's name. + * + * @return string + */ + public function getVariableName() + { + return $this->variableName; + } + + /** + * Returns the variable's type or null if unknown. + * + * @return Type|null + */ + public function getType() + { + return $this->type; + } + + /** + * Returns a string representation for this tag. + * + * @return string + */ + public function __toString() + { + return ($this->type ? $this->type . ' ' : '') + . '$' . $this->variableName + . ($this->description ? ' ' . $this->description : ''); + } +} diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Return_.php b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Return_.php new file mode 100644 index 00000000..09a5870e --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Return_.php @@ -0,0 +1,73 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags; + +use phpDocumentor\Reflection\DocBlock\Description; +use phpDocumentor\Reflection\DocBlock\DescriptionFactory; +use phpDocumentor\Reflection\Type; +use phpDocumentor\Reflection\TypeResolver; +use phpDocumentor\Reflection\Types\Context as TypeContext; +use Webmozart\Assert\Assert; + +/** + * Reflection class for a {@}return tag in a Docblock. + */ +final class Return_ extends BaseTag implements Factory\StaticMethod +{ + protected $name = 'return'; + + /** @var Type */ + private $type; + + public function __construct(Type $type, Description $description = null) + { + $this->type = $type; + $this->description = $description; + } + + /** + * {@inheritdoc} + */ + public static function create( + $body, + TypeResolver $typeResolver = null, + DescriptionFactory $descriptionFactory = null, + TypeContext $context = null + ) + { + Assert::string($body); + Assert::allNotNull([$typeResolver, $descriptionFactory]); + + $parts = preg_split('/\s+/Su', $body, 2); + + $type = $typeResolver->resolve(isset($parts[0]) ? $parts[0] : '', $context); + $description = $descriptionFactory->create(isset($parts[1]) ? $parts[1] : '', $context); + + return new static($type, $description); + } + + /** + * Returns the type section of the variable. + * + * @return Type + */ + public function getType() + { + return $this->type; + } + + public function __toString() + { + return $this->type . ' ' . $this->description; + } +} diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/See.php b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/See.php new file mode 100644 index 00000000..64ee3d8e --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/See.php @@ -0,0 +1,81 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags; + +use phpDocumentor\Reflection\DocBlock\DescriptionFactory; +use phpDocumentor\Reflection\Fqsen; +use phpDocumentor\Reflection\FqsenResolver; +use phpDocumentor\Reflection\Types\Context as TypeContext; +use phpDocumentor\Reflection\DocBlock\Description; +use Webmozart\Assert\Assert; + +/** + * Reflection class for an {@}see tag in a Docblock. + */ +class See extends BaseTag implements Factory\StaticMethod +{ + protected $name = 'see'; + + /** @var Fqsen */ + protected $refers = null; + + /** + * Initializes this tag. + * + * @param Fqsen $refers + * @param Description $description + */ + public function __construct(Fqsen $refers, Description $description = null) + { + $this->refers = $refers; + $this->description = $description; + } + + /** + * {@inheritdoc} + */ + public static function create( + $body, + FqsenResolver $resolver = null, + DescriptionFactory $descriptionFactory = null, + TypeContext $context = null + ) { + Assert::string($body); + Assert::allNotNull([$resolver, $descriptionFactory]); + + $parts = preg_split('/\s+/Su', $body, 2); + $description = isset($parts[1]) ? $descriptionFactory->create($parts[1], $context) : null; + + return new static($resolver->resolve($parts[0], $context), $description); + } + + /** + * Returns the structural element this tag refers to. + * + * @return Fqsen + */ + public function getReference() + { + return $this->refers; + } + + /** + * Returns a string representation of this tag. + * + * @return string + */ + public function __toString() + { + return $this->refers . ($this->description ? ' ' . $this->description->render() : ''); + } +} diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Since.php b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Since.php new file mode 100644 index 00000000..3d002ed3 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Since.php @@ -0,0 +1,94 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags; + +use phpDocumentor\Reflection\Types\Context as TypeContext; +use phpDocumentor\Reflection\DocBlock\Description; +use phpDocumentor\Reflection\DocBlock\DescriptionFactory; +use Webmozart\Assert\Assert; + +/** + * Reflection class for a {@}since tag in a Docblock. + */ +final class Since extends BaseTag implements Factory\StaticMethod +{ + protected $name = 'since'; + + /** + * PCRE regular expression matching a version vector. + * Assumes the "x" modifier. + */ + const REGEX_VECTOR = '(?: + # Normal release vectors. + \d\S* + | + # VCS version vectors. Per PHPCS, they are expected to + # follow the form of the VCS name, followed by ":", followed + # by the version vector itself. + # By convention, popular VCSes like CVS, SVN and GIT use "$" + # around the actual version vector. + [^\s\:]+\:\s*\$[^\$]+\$ + )'; + + /** @var string The version vector. */ + private $version = ''; + + public function __construct($version = null, Description $description = null) + { + Assert::nullOrStringNotEmpty($version); + + $this->version = $version; + $this->description = $description; + } + + /** + * @return static + */ + public static function create($body, DescriptionFactory $descriptionFactory = null, TypeContext $context = null) + { + Assert::nullOrString($body); + if (empty($body)) { + return new static(); + } + + $matches = []; + if (! preg_match('/^(' . self::REGEX_VECTOR . ')\s*(.+)?$/sux', $body, $matches)) { + return null; + } + + return new static( + $matches[1], + $descriptionFactory->create(isset($matches[2]) ? $matches[2] : '', $context) + ); + } + + /** + * Gets the version section of the tag. + * + * @return string + */ + public function getVersion() + { + return $this->version; + } + + /** + * Returns a string representation for this tag. + * + * @return string + */ + public function __toString() + { + return $this->version . ($this->description ? ' ' . $this->description->render() : ''); + } +} diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Source.php b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Source.php new file mode 100644 index 00000000..b0646b96 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Source.php @@ -0,0 +1,96 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags; + +use phpDocumentor\Reflection\DocBlock\Description; +use phpDocumentor\Reflection\DocBlock\DescriptionFactory; +use phpDocumentor\Reflection\Types\Context as TypeContext; +use Webmozart\Assert\Assert; + +/** + * Reflection class for a {@}source tag in a Docblock. + */ +final class Source extends BaseTag implements Factory\StaticMethod +{ + /** @var string */ + protected $name = 'source'; + + /** @var int The starting line, relative to the structural element's location. */ + private $startingLine = 1; + + /** @var int|null The number of lines, relative to the starting line. NULL means "to the end". */ + private $lineCount = null; + + public function __construct($startingLine, $lineCount = null, Description $description = null) + { + Assert::integerish($startingLine); + Assert::nullOrIntegerish($lineCount); + + $this->startingLine = (int)$startingLine; + $this->lineCount = $lineCount !== null ? (int)$lineCount : null; + $this->description = $description; + } + + /** + * {@inheritdoc} + */ + public static function create($body, DescriptionFactory $descriptionFactory = null, TypeContext $context = null) + { + Assert::stringNotEmpty($body); + Assert::notNull($descriptionFactory); + + $startingLine = 1; + $lineCount = null; + $description = null; + + // Starting line / Number of lines / Description + if (preg_match('/^([1-9]\d*)\s*(?:((?1))\s+)?(.*)$/sux', $body, $matches)) { + $startingLine = (int)$matches[1]; + if (isset($matches[2]) && $matches[2] !== '') { + $lineCount = (int)$matches[2]; + } + $description = $matches[3]; + } + + return new static($startingLine, $lineCount, $descriptionFactory->create($description, $context)); + } + + /** + * Gets the starting line. + * + * @return int The starting line, relative to the structural element's + * location. + */ + public function getStartingLine() + { + return $this->startingLine; + } + + /** + * Returns the number of lines. + * + * @return int|null The number of lines, relative to the starting line. NULL + * means "to the end". + */ + public function getLineCount() + { + return $this->lineCount; + } + + public function __toString() + { + return $this->startingLine + . ($this->lineCount !== null ? ' ' . $this->lineCount : '') + . ($this->description ? ' ' . $this->description->render() : ''); + } +} diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Throws.php b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Throws.php new file mode 100644 index 00000000..349e773b --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Throws.php @@ -0,0 +1,72 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags; + +use phpDocumentor\Reflection\DocBlock\Description; +use phpDocumentor\Reflection\DocBlock\DescriptionFactory; +use phpDocumentor\Reflection\Type; +use phpDocumentor\Reflection\TypeResolver; +use phpDocumentor\Reflection\Types\Context as TypeContext; +use Webmozart\Assert\Assert; + +/** + * Reflection class for a {@}throws tag in a Docblock. + */ +final class Throws extends BaseTag implements Factory\StaticMethod +{ + protected $name = 'throws'; + + /** @var Type */ + private $type; + + public function __construct(Type $type, Description $description = null) + { + $this->type = $type; + $this->description = $description; + } + + /** + * {@inheritdoc} + */ + public static function create( + $body, + TypeResolver $typeResolver = null, + DescriptionFactory $descriptionFactory = null, + TypeContext $context = null + ) { + Assert::string($body); + Assert::allNotNull([$typeResolver, $descriptionFactory]); + + $parts = preg_split('/\s+/Su', $body, 2); + + $type = $typeResolver->resolve(isset($parts[0]) ? $parts[0] : '', $context); + $description = $descriptionFactory->create(isset($parts[1]) ? $parts[1] : '', $context); + + return new static($type, $description); + } + + /** + * Returns the type section of the variable. + * + * @return Type + */ + public function getType() + { + return $this->type; + } + + public function __toString() + { + return $this->type . ' ' . $this->description; + } +} diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Uses.php b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Uses.php new file mode 100644 index 00000000..00dc3e3b --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Uses.php @@ -0,0 +1,83 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags; + +use phpDocumentor\Reflection\DocBlock\Description; +use phpDocumentor\Reflection\DocBlock\DescriptionFactory; +use phpDocumentor\Reflection\Fqsen; +use phpDocumentor\Reflection\FqsenResolver; +use phpDocumentor\Reflection\Types\Context as TypeContext; +use Webmozart\Assert\Assert; + +/** + * Reflection class for a {@}uses tag in a Docblock. + */ +final class Uses extends BaseTag implements Factory\StaticMethod +{ + protected $name = 'uses'; + + /** @var Fqsen */ + protected $refers = null; + + /** + * Initializes this tag. + * + * @param Fqsen $refers + * @param Description $description + */ + public function __construct(Fqsen $refers, Description $description = null) + { + $this->refers = $refers; + $this->description = $description; + } + + /** + * {@inheritdoc} + */ + public static function create( + $body, + FqsenResolver $resolver = null, + DescriptionFactory $descriptionFactory = null, + TypeContext $context = null + ) { + Assert::string($body); + Assert::allNotNull([$resolver, $descriptionFactory]); + + $parts = preg_split('/\s+/Su', $body, 2); + + return new static( + $resolver->resolve($parts[0], $context), + $descriptionFactory->create(isset($parts[1]) ? $parts[1] : '', $context) + ); + } + + /** + * Returns the structural element this tag refers to. + * + * @return Fqsen + */ + public function getReference() + { + return $this->refers; + } + + /** + * Returns a string representation of this tag. + * + * @return string + */ + public function __toString() + { + return $this->refers . ' ' . $this->description->render(); + } +} diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Var_.php b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Var_.php new file mode 100644 index 00000000..e23c694b --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Var_.php @@ -0,0 +1,118 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags; + +use phpDocumentor\Reflection\DocBlock\Description; +use phpDocumentor\Reflection\DocBlock\DescriptionFactory; +use phpDocumentor\Reflection\Type; +use phpDocumentor\Reflection\TypeResolver; +use phpDocumentor\Reflection\Types\Context as TypeContext; +use Webmozart\Assert\Assert; + +/** + * Reflection class for a {@}var tag in a Docblock. + */ +class Var_ extends BaseTag implements Factory\StaticMethod +{ + /** @var string */ + protected $name = 'var'; + + /** @var Type */ + private $type; + + /** @var string */ + protected $variableName = ''; + + /** + * @param string $variableName + * @param Type $type + * @param Description $description + */ + public function __construct($variableName, Type $type = null, Description $description = null) + { + Assert::string($variableName); + + $this->variableName = $variableName; + $this->type = $type; + $this->description = $description; + } + + /** + * {@inheritdoc} + */ + public static function create( + $body, + TypeResolver $typeResolver = null, + DescriptionFactory $descriptionFactory = null, + TypeContext $context = null + ) { + Assert::stringNotEmpty($body); + Assert::allNotNull([$typeResolver, $descriptionFactory]); + + $parts = preg_split('/(\s+)/Su', $body, 3, PREG_SPLIT_DELIM_CAPTURE); + $type = null; + $variableName = ''; + + // if the first item that is encountered is not a variable; it is a type + if (isset($parts[0]) && (strlen($parts[0]) > 0) && ($parts[0][0] !== '$')) { + $type = $typeResolver->resolve(array_shift($parts), $context); + array_shift($parts); + } + + // if the next item starts with a $ or ...$ it must be the variable name + if (isset($parts[0]) && (strlen($parts[0]) > 0) && ($parts[0][0] == '$')) { + $variableName = array_shift($parts); + array_shift($parts); + + if (substr($variableName, 0, 1) === '$') { + $variableName = substr($variableName, 1); + } + } + + $description = $descriptionFactory->create(implode('', $parts), $context); + + return new static($variableName, $type, $description); + } + + /** + * Returns the variable's name. + * + * @return string + */ + public function getVariableName() + { + return $this->variableName; + } + + /** + * Returns the variable's type or null if unknown. + * + * @return Type|null + */ + public function getType() + { + return $this->type; + } + + /** + * Returns a string representation for this tag. + * + * @return string + */ + public function __toString() + { + return ($this->type ? $this->type . ' ' : '') + . '$' . $this->variableName + . ($this->description ? ' ' . $this->description : ''); + } +} diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Version.php b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Version.php new file mode 100644 index 00000000..3e0e5bef --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Version.php @@ -0,0 +1,94 @@ + + * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com) + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags; + +use phpDocumentor\Reflection\Types\Context as TypeContext; +use phpDocumentor\Reflection\DocBlock\Description; +use phpDocumentor\Reflection\DocBlock\DescriptionFactory; +use Webmozart\Assert\Assert; + +/** + * Reflection class for a {@}version tag in a Docblock. + */ +final class Version extends BaseTag implements Factory\StaticMethod +{ + protected $name = 'version'; + + /** + * PCRE regular expression matching a version vector. + * Assumes the "x" modifier. + */ + const REGEX_VECTOR = '(?: + # Normal release vectors. + \d\S* + | + # VCS version vectors. Per PHPCS, they are expected to + # follow the form of the VCS name, followed by ":", followed + # by the version vector itself. + # By convention, popular VCSes like CVS, SVN and GIT use "$" + # around the actual version vector. + [^\s\:]+\:\s*\$[^\$]+\$ + )'; + + /** @var string The version vector. */ + private $version = ''; + + public function __construct($version = null, Description $description = null) + { + Assert::nullOrStringNotEmpty($version); + + $this->version = $version; + $this->description = $description; + } + + /** + * @return static + */ + public static function create($body, DescriptionFactory $descriptionFactory = null, TypeContext $context = null) + { + Assert::nullOrString($body); + if (empty($body)) { + return new static(); + } + + $matches = []; + if (!preg_match('/^(' . self::REGEX_VECTOR . ')\s*(.+)?$/sux', $body, $matches)) { + return null; + } + + return new static( + $matches[1], + $descriptionFactory->create(isset($matches[2]) ? $matches[2] : '', $context) + ); + } + + /** + * Gets the version section of the tag. + * + * @return string + */ + public function getVersion() + { + return $this->version; + } + + /** + * Returns a string representation for this tag. + * + * @return string + */ + public function __toString() + { + return $this->version . ($this->description ? ' ' . $this->description->render() : ''); + } +} diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlockFactory.php b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlockFactory.php new file mode 100644 index 00000000..9ec2455d --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlockFactory.php @@ -0,0 +1,277 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection; + +use phpDocumentor\Reflection\DocBlock\DescriptionFactory; +use phpDocumentor\Reflection\DocBlock\StandardTagFactory; +use phpDocumentor\Reflection\DocBlock\Tag; +use phpDocumentor\Reflection\DocBlock\TagFactory; +use Webmozart\Assert\Assert; + +final class DocBlockFactory implements DocBlockFactoryInterface +{ + /** @var DocBlock\DescriptionFactory */ + private $descriptionFactory; + + /** @var DocBlock\TagFactory */ + private $tagFactory; + + /** + * Initializes this factory with the required subcontractors. + * + * @param DescriptionFactory $descriptionFactory + * @param TagFactory $tagFactory + */ + public function __construct(DescriptionFactory $descriptionFactory, TagFactory $tagFactory) + { + $this->descriptionFactory = $descriptionFactory; + $this->tagFactory = $tagFactory; + } + + /** + * Factory method for easy instantiation. + * + * @param string[] $additionalTags + * + * @return DocBlockFactory + */ + public static function createInstance(array $additionalTags = []) + { + $fqsenResolver = new FqsenResolver(); + $tagFactory = new StandardTagFactory($fqsenResolver); + $descriptionFactory = new DescriptionFactory($tagFactory); + + $tagFactory->addService($descriptionFactory); + $tagFactory->addService(new TypeResolver($fqsenResolver)); + + $docBlockFactory = new self($descriptionFactory, $tagFactory); + foreach ($additionalTags as $tagName => $tagHandler) { + $docBlockFactory->registerTagHandler($tagName, $tagHandler); + } + + return $docBlockFactory; + } + + /** + * @param object|string $docblock A string containing the DocBlock to parse or an object supporting the + * getDocComment method (such as a ReflectionClass object). + * @param Types\Context $context + * @param Location $location + * + * @return DocBlock + */ + public function create($docblock, Types\Context $context = null, Location $location = null) + { + if (is_object($docblock)) { + if (!method_exists($docblock, 'getDocComment')) { + $exceptionMessage = 'Invalid object passed; the given object must support the getDocComment method'; + throw new \InvalidArgumentException($exceptionMessage); + } + + $docblock = $docblock->getDocComment(); + } + + Assert::stringNotEmpty($docblock); + + if ($context === null) { + $context = new Types\Context(''); + } + + $parts = $this->splitDocBlock($this->stripDocComment($docblock)); + list($templateMarker, $summary, $description, $tags) = $parts; + + return new DocBlock( + $summary, + $description ? $this->descriptionFactory->create($description, $context) : null, + array_filter($this->parseTagBlock($tags, $context), function($tag) { + return $tag instanceof Tag; + }), + $context, + $location, + $templateMarker === '#@+', + $templateMarker === '#@-' + ); + } + + public function registerTagHandler($tagName, $handler) + { + $this->tagFactory->registerTagHandler($tagName, $handler); + } + + /** + * Strips the asterisks from the DocBlock comment. + * + * @param string $comment String containing the comment text. + * + * @return string + */ + private function stripDocComment($comment) + { + $comment = trim(preg_replace('#[ \t]*(?:\/\*\*|\*\/|\*)?[ \t]{0,1}(.*)?#u', '$1', $comment)); + + // reg ex above is not able to remove */ from a single line docblock + if (substr($comment, -2) == '*/') { + $comment = trim(substr($comment, 0, -2)); + } + + return str_replace(array("\r\n", "\r"), "\n", $comment); + } + + /** + * Splits the DocBlock into a template marker, summary, description and block of tags. + * + * @param string $comment Comment to split into the sub-parts. + * + * @author Richard van Velzen (@_richardJ) Special thanks to Richard for the regex responsible for the split. + * @author Mike van Riel for extending the regex with template marker support. + * + * @return string[] containing the template marker (if any), summary, description and a string containing the tags. + */ + private function splitDocBlock($comment) + { + // Performance improvement cheat: if the first character is an @ then only tags are in this DocBlock. This + // method does not split tags so we return this verbatim as the fourth result (tags). This saves us the + // performance impact of running a regular expression + if (strpos($comment, '@') === 0) { + return array('', '', '', $comment); + } + + // clears all extra horizontal whitespace from the line endings to prevent parsing issues + $comment = preg_replace('/\h*$/Sum', '', $comment); + + /* + * Splits the docblock into a template marker, summary, description and tags section. + * + * - The template marker is empty, #@+ or #@- if the DocBlock starts with either of those (a newline may + * occur after it and will be stripped). + * - The short description is started from the first character until a dot is encountered followed by a + * newline OR two consecutive newlines (horizontal whitespace is taken into account to consider spacing + * errors). This is optional. + * - The long description, any character until a new line is encountered followed by an @ and word + * characters (a tag). This is optional. + * - Tags; the remaining characters + * + * Big thanks to RichardJ for contributing this Regular Expression + */ + preg_match( + '/ + \A + # 1. Extract the template marker + (?:(\#\@\+|\#\@\-)\n?)? + + # 2. Extract the summary + (?: + (?! @\pL ) # The summary may not start with an @ + ( + [^\n.]+ + (?: + (?! \. \n | \n{2} ) # End summary upon a dot followed by newline or two newlines + [\n.] (?! [ \t]* @\pL ) # End summary when an @ is found as first character on a new line + [^\n.]+ # Include anything else + )* + \.? + )? + ) + + # 3. Extract the description + (?: + \s* # Some form of whitespace _must_ precede a description because a summary must be there + (?! @\pL ) # The description may not start with an @ + ( + [^\n]+ + (?: \n+ + (?! [ \t]* @\pL ) # End description when an @ is found as first character on a new line + [^\n]+ # Include anything else + )* + ) + )? + + # 4. Extract the tags (anything that follows) + (\s+ [\s\S]*)? # everything that follows + /ux', + $comment, + $matches + ); + array_shift($matches); + + while (count($matches) < 4) { + $matches[] = ''; + } + + return $matches; + } + + /** + * Creates the tag objects. + * + * @param string $tags Tag block to parse. + * @param Types\Context $context Context of the parsed Tag + * + * @return DocBlock\Tag[] + */ + private function parseTagBlock($tags, Types\Context $context) + { + $tags = $this->filterTagBlock($tags); + if (!$tags) { + return []; + } + + $result = $this->splitTagBlockIntoTagLines($tags); + foreach ($result as $key => $tagLine) { + $result[$key] = $this->tagFactory->create(trim($tagLine), $context); + } + + return $result; + } + + /** + * @param string $tags + * + * @return string[] + */ + private function splitTagBlockIntoTagLines($tags) + { + $result = array(); + foreach (explode("\n", $tags) as $tag_line) { + if (isset($tag_line[0]) && ($tag_line[0] === '@')) { + $result[] = $tag_line; + } else { + $result[count($result) - 1] .= "\n" . $tag_line; + } + } + + return $result; + } + + /** + * @param $tags + * @return string + */ + private function filterTagBlock($tags) + { + $tags = trim($tags); + if (!$tags) { + return null; + } + + if ('@' !== $tags[0]) { + // @codeCoverageIgnoreStart + // Can't simulate this; this only happens if there is an error with the parsing of the DocBlock that + // we didn't foresee. + throw new \LogicException('A tag block started with text instead of an at-sign(@): ' . $tags); + // @codeCoverageIgnoreEnd + } + + return $tags; + } +} diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlockFactoryInterface.php b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlockFactoryInterface.php new file mode 100644 index 00000000..b3533429 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/src/DocBlockFactoryInterface.php @@ -0,0 +1,23 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection; + +use phpDocumentor\Reflection\DocBlock\Description; +use phpDocumentor\Reflection\DocBlock\StandardTagFactory; +use phpDocumentor\Reflection\DocBlock\Tag; +use phpDocumentor\Reflection\DocBlock\Tags\See; + +/** + * @coversNothing + */ +class InterpretingDocBlocksTest extends \PHPUnit_Framework_TestCase +{ + public function testInterpretingASimpleDocBlock() + { + /** + * @var DocBlock $docblock + * @var string $summary + * @var Description $description + */ + include(__DIR__ . '/../../examples/01-interpreting-a-simple-docblock.php'); + + $descriptionText = <<assertInstanceOf(DocBlock::class, $docblock); + $this->assertSame('This is an example of a summary.', $summary); + $this->assertInstanceOf(Description::class, $description); + $this->assertSame($descriptionText, $description->render()); + $this->assertEmpty($docblock->getTags()); + } + + public function testInterpretingTags() + { + /** + * @var DocBlock $docblock + * @var boolean $hasSeeTag + * @var Tag[] $tags + * @var See[] $seeTags + */ + include(__DIR__ . '/../../examples/02-interpreting-tags.php'); + + $this->assertTrue($hasSeeTag); + $this->assertCount(1, $tags); + $this->assertCount(1, $seeTags); + + $this->assertInstanceOf(See::class, $tags[0]); + $this->assertInstanceOf(See::class, $seeTags[0]); + + $seeTag = $seeTags[0]; + $this->assertSame('\\' . StandardTagFactory::class, (string)$seeTag->getReference()); + $this->assertSame('', (string)$seeTag->getDescription()); + } + + public function testDescriptionsCanEscapeAtSignsAndClosingBraces() + { + /** + * @var string $docComment + * @var DocBlock $docblock + * @var Description $description + * @var string $receivedDocComment + * @var string $foundDescription + */ + + include(__DIR__ . '/../../examples/playing-with-descriptions/02-escaping.php'); + $this->assertSame(<<<'DESCRIPTION' +You can escape the @-sign by surrounding it with braces, for example: @. And escape a closing brace within an +inline tag by adding an opening brace in front of it like this: }. + +Here are example texts where you can see how they could be used in a real life situation: + + This is a text with an {@internal inline tag where a closing brace (}) is shown}. + Or an {@internal inline tag with a literal {@link} in it}. + +Do note that an {@internal inline tag that has an opening brace ({) does not break out}. +DESCRIPTION + , + $foundDescription + ) + ; + } +} diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/tests/integration/ReconstitutingADocBlockTest.php b/src/composer/vendor/phpdocumentor/reflection-docblock/tests/integration/ReconstitutingADocBlockTest.php new file mode 100644 index 00000000..92ac22ed --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/tests/integration/ReconstitutingADocBlockTest.php @@ -0,0 +1,35 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection; + +use phpDocumentor\Reflection\DocBlock\Description; +use phpDocumentor\Reflection\DocBlock\StandardTagFactory; +use phpDocumentor\Reflection\DocBlock\Tag; +use phpDocumentor\Reflection\DocBlock\Tags\See; + +/** + * @coversNothing + */ +class ReconstitutingADocBlockTest extends \PHPUnit_Framework_TestCase +{ + public function testReconstituteADocBlock() + { + /** + * @var string $docComment + * @var string $reconstitutedDocComment + */ + include(__DIR__ . '/../../examples/03-reconstituting-a-docblock.php'); + + $this->assertSame($docComment, $reconstitutedDocComment); + } +} diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/tests/integration/UsingTagsTest.php b/src/composer/vendor/phpdocumentor/reflection-docblock/tests/integration/UsingTagsTest.php new file mode 100644 index 00000000..984811b1 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/tests/integration/UsingTagsTest.php @@ -0,0 +1,39 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection; + +use phpDocumentor\Reflection\DocBlock\Description; +use phpDocumentor\Reflection\DocBlock\StandardTagFactory; +use phpDocumentor\Reflection\DocBlock\Tag; +use phpDocumentor\Reflection\DocBlock\Tags\See; + +/** + * @coversNothing + */ +class UsingTagsTest extends \PHPUnit_Framework_TestCase +{ + public function testAddingYourOwnTagUsingAStaticMethodAsFactory() + { + /** + * @var object[] $customTagObjects + * @var string $docComment + * @var string $reconstitutedDocComment + */ + include(__DIR__ . '/../../examples/04-adding-your-own-tag.php'); + + $this->assertInstanceOf(\MyTag::class, $customTagObjects[0]); + $this->assertSame('my-tag', $customTagObjects[0]->getName()); + $this->assertSame('I have a description', (string)$customTagObjects[0]->getDescription()); + $this->assertSame($docComment, $reconstitutedDocComment); + } +} diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/DescriptionFactoryTest.php b/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/DescriptionFactoryTest.php new file mode 100644 index 00000000..d3043f9a --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/DescriptionFactoryTest.php @@ -0,0 +1,174 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock; + +use Mockery as m; +use phpDocumentor\Reflection\DocBlock\Tags\Link; +use phpDocumentor\Reflection\Types\Context; + +/** + * @coversDefaultClass \phpDocumentor\Reflection\DocBlock\DescriptionFactory + * @covers :: + */ +class DescriptionFactoryTest extends \PHPUnit_Framework_TestCase +{ + /** + * @covers ::__construct + * @covers ::create + * @uses phpDocumentor\Reflection\DocBlock\Description + * @dataProvider provideSimpleExampleDescriptions + */ + public function testDescriptionCanParseASimpleString($contents) + { + $tagFactory = m::mock(TagFactory::class); + $tagFactory->shouldReceive('create')->never(); + + $factory = new DescriptionFactory($tagFactory); + $description = $factory->create($contents, new Context('')); + + $this->assertSame($contents, $description->render()); + } + + /** + * @covers ::__construct + * @covers ::create + * @uses phpDocumentor\Reflection\DocBlock\Description + * @dataProvider provideEscapeSequences + */ + public function testEscapeSequences($contents, $expected) + { + $tagFactory = m::mock(TagFactory::class); + $tagFactory->shouldReceive('create')->never(); + + $factory = new DescriptionFactory($tagFactory); + $description = $factory->create($contents, new Context('')); + + $this->assertSame($expected, $description->render()); + } + + /** + * @covers ::__construct + * @covers ::create + * @uses phpDocumentor\Reflection\DocBlock\Description + * @uses phpDocumentor\Reflection\DocBlock\Tags\Link + * @uses phpDocumentor\Reflection\DocBlock\Tags\BaseTag + * @uses phpDocumentor\Reflection\DocBlock\Tags\Formatter\PassthroughFormatter + * @uses phpDocumentor\Reflection\Types\Context + */ + public function testDescriptionCanParseAStringWithInlineTag() + { + $contents = 'This is text for a {@link http://phpdoc.org/ description} that uses an inline tag.'; + $context = new Context(''); + $tagFactory = m::mock(TagFactory::class); + $tagFactory->shouldReceive('create') + ->once() + ->with('@link http://phpdoc.org/ description', $context) + ->andReturn(new Link('http://phpdoc.org/', new Description('description'))) + ; + + $factory = new DescriptionFactory($tagFactory); + $description = $factory->create($contents, $context); + + $this->assertSame($contents, $description->render()); + } + + /** + * @covers ::__construct + * @covers ::create + * @uses phpDocumentor\Reflection\DocBlock\Description + * @uses phpDocumentor\Reflection\DocBlock\Tags\Link + * @uses phpDocumentor\Reflection\DocBlock\Tags\BaseTag + * @uses phpDocumentor\Reflection\DocBlock\Tags\Formatter\PassthroughFormatter + * @uses phpDocumentor\Reflection\Types\Context + */ + public function testDescriptionCanParseAStringStartingWithInlineTag() + { + $contents = '{@link http://phpdoc.org/ This} is text for a description that starts with an inline tag.'; + $context = new Context(''); + $tagFactory = m::mock(TagFactory::class); + $tagFactory->shouldReceive('create') + ->once() + ->with('@link http://phpdoc.org/ This', $context) + ->andReturn(new Link('http://phpdoc.org/', new Description('This'))) + ; + + $factory = new DescriptionFactory($tagFactory); + $description = $factory->create($contents, $context); + + $this->assertSame($contents, $description->render()); + } + + /** + * @covers ::__construct + * @covers ::create + * @uses phpDocumentor\Reflection\DocBlock\Description + */ + public function testIfSuperfluousStartingSpacesAreRemoved() + { + $factory = new DescriptionFactory(m::mock(TagFactory::class)); + $descriptionText = <<create($descriptionText, new Context('')); + + $this->assertSame($expectedDescription, $description->render()); + } + + /** + * Provides a series of example strings that the parser should correctly interpret and return. + * + * @return string[][] + */ + public function provideSimpleExampleDescriptions() + { + return [ + ['This is text for a description.'], + ['This is text for a description containing { that is literal.'], + ['This is text for a description containing } that is literal.'], + ['This is text for a description with {just a text} that is not a tag.'], + ]; + } + + public function provideEscapeSequences() + { + return [ + ['This is text for a description with a {@}.', 'This is text for a description with a @.'], + ['This is text for a description with a {}.', 'This is text for a description with a }.'], + ]; + } +} diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/DescriptionTest.php b/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/DescriptionTest.php new file mode 100644 index 00000000..b5917a9e --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/DescriptionTest.php @@ -0,0 +1,75 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock; + +use Mockery as m; +use phpDocumentor\Reflection\DocBlock\Tags\Formatter\PassthroughFormatter; +use phpDocumentor\Reflection\DocBlock\Tags\Generic; + +/** + * @coversDefaultClass \phpDocumentor\Reflection\DocBlock\Description + */ +class DescriptionTest extends \PHPUnit_Framework_TestCase +{ + /** + * @covers ::__construct + * @covers ::render + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Generic + * @uses \phpDocumentor\Reflection\DocBlock\Tags\BaseTag + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Formatter\PassthroughFormatter + */ + public function testDescriptionCanRenderUsingABodyWithPlaceholdersAndTags() + { + $body = 'This is a %1$s body.'; + $expected = 'This is a {@internal significant } body.'; + $tags = [new Generic('internal', new Description('significant '))]; + + $fixture = new Description($body, $tags); + + // without formatter (thus the PassthroughFormatter by default) + $this->assertSame($expected, $fixture->render()); + + // with a custom formatter + $formatter = m::mock(PassthroughFormatter::class); + $formatter->shouldReceive('format')->with($tags[0])->andReturn('@internal significant '); + $this->assertSame($expected, $fixture->render($formatter)); + } + + /** + * @covers ::__construct + * @covers ::render + * @covers ::__toString + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Generic + * @uses \phpDocumentor\Reflection\DocBlock\Tags\BaseTag + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Formatter\PassthroughFormatter + */ + public function testDescriptionCanBeCastToString() + { + $body = 'This is a %1$s body.'; + $expected = 'This is a {@internal significant } body.'; + $tags = [new Generic('internal', new Description('significant '))]; + + $fixture = new Description($body, $tags); + + $this->assertSame($expected, (string)$fixture); + } + + /** + * @covers ::__construct + * @expectedException \InvalidArgumentException + */ + public function testBodyTemplateMustBeAString() + { + new Description([]); + } +} diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/SerializerTest.php b/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/SerializerTest.php new file mode 100644 index 00000000..cb2b400f --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/SerializerTest.php @@ -0,0 +1,201 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock; + +use Mockery as m; +use phpDocumentor\Reflection\DocBlock; + +/** + * @coversDefaultClass \phpDocumentor\Reflection\DocBlock\Serializer + * @covers :: + */ +class SerializerTest extends \PHPUnit_Framework_TestCase +{ + /** + * @covers ::__construct + * @covers ::getDocComment + * @uses phpDocumentor\Reflection\DocBlock\Description + * @uses phpDocumentor\Reflection\DocBlock\Tags\Formatter\PassthroughFormatter + * @uses phpDocumentor\Reflection\DocBlock + * @uses phpDocumentor\Reflection\DocBlock\Tags\BaseTag + * @uses phpDocumentor\Reflection\DocBlock\Tags\Generic + */ + public function testReconstructsADocCommentFromADocBlock() + { + $expected = <<<'DOCCOMMENT' +/** + * This is a summary + * + * This is a description + * + * @unknown-tag Test description for the unknown tag + */ +DOCCOMMENT; + + $fixture = new Serializer(); + + $docBlock = new DocBlock( + 'This is a summary', + new Description('This is a description'), + [ + new DocBlock\Tags\Generic('unknown-tag', new Description('Test description for the unknown tag')) + ] + ); + + $this->assertSame($expected, $fixture->getDocComment($docBlock)); + } + + /** + * @covers ::__construct + * @covers ::getDocComment + * @uses phpDocumentor\Reflection\DocBlock\Description + * @uses phpDocumentor\Reflection\DocBlock\Tags\Formatter\PassthroughFormatter + * @uses phpDocumentor\Reflection\DocBlock + * @uses phpDocumentor\Reflection\DocBlock\Tags\BaseTag + * @uses phpDocumentor\Reflection\DocBlock\Tags\Generic + */ + public function testAddPrefixToDocBlock() + { + $expected = <<<'DOCCOMMENT' +aa/** +aa * This is a summary +aa * +aa * This is a description +aa * +aa * @unknown-tag Test description for the unknown tag +aa */ +DOCCOMMENT; + + $fixture = new Serializer(2, 'a'); + + $docBlock = new DocBlock( + 'This is a summary', + new Description('This is a description'), + [ + new DocBlock\Tags\Generic('unknown-tag', new Description('Test description for the unknown tag')) + ] + ); + + $this->assertSame($expected, $fixture->getDocComment($docBlock)); + } + + /** + * @covers ::__construct + * @covers ::getDocComment + * @uses phpDocumentor\Reflection\DocBlock\Description + * @uses phpDocumentor\Reflection\DocBlock\Tags\Formatter\PassthroughFormatter + * @uses phpDocumentor\Reflection\DocBlock + * @uses phpDocumentor\Reflection\DocBlock\Tags\BaseTag + * @uses phpDocumentor\Reflection\DocBlock\Tags\Generic + */ + public function testAddPrefixToDocBlockExceptFirstLine() + { + $expected = <<<'DOCCOMMENT' +/** +aa * This is a summary +aa * +aa * This is a description +aa * +aa * @unknown-tag Test description for the unknown tag +aa */ +DOCCOMMENT; + + $fixture = new Serializer(2, 'a', false); + + $docBlock = new DocBlock( + 'This is a summary', + new Description('This is a description'), + [ + new DocBlock\Tags\Generic('unknown-tag', new Description('Test description for the unknown tag')) + ] + ); + + $this->assertSame($expected, $fixture->getDocComment($docBlock)); + } + + /** + * @covers ::__construct + * @covers ::getDocComment + * @uses phpDocumentor\Reflection\DocBlock\Description + * @uses phpDocumentor\Reflection\DocBlock\Tags\Formatter\PassthroughFormatter + * @uses phpDocumentor\Reflection\DocBlock + * @uses phpDocumentor\Reflection\DocBlock\Tags\BaseTag + * @uses phpDocumentor\Reflection\DocBlock\Tags\Generic + */ + public function testWordwrapsAroundTheGivenAmountOfCharacters() + { + $expected = <<<'DOCCOMMENT' +/** + * This is a + * summary + * + * This is a + * description + * + * @unknown-tag + * Test + * description + * for the + * unknown tag + */ +DOCCOMMENT; + + $fixture = new Serializer(0, '', true, 15); + + $docBlock = new DocBlock( + 'This is a summary', + new Description('This is a description'), + [ + new DocBlock\Tags\Generic('unknown-tag', new Description('Test description for the unknown tag')) + ] + ); + + $this->assertSame($expected, $fixture->getDocComment($docBlock)); + } + + /** + * @covers ::__construct + * @expectedException \InvalidArgumentException + */ + public function testInitializationFailsIfIndentIsNotAnInteger() + { + new Serializer([]); + } + + /** + * @covers ::__construct + * @expectedException \InvalidArgumentException + */ + public function testInitializationFailsIfIndentStringIsNotAString() + { + new Serializer(0, []); + } + + /** + * @covers ::__construct + * @expectedException \InvalidArgumentException + */ + public function testInitializationFailsIfIndentFirstLineIsNotABoolean() + { + new Serializer(0, '', []); + } + + /** + * @covers ::__construct + * @expectedException \InvalidArgumentException + */ + public function testInitializationFailsIfLineLengthIsNotNullNorAnInteger() + { + new Serializer(0, '', false, []); + } +} diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/StandardTagFactoryTest.php b/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/StandardTagFactoryTest.php new file mode 100644 index 00000000..0247da04 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/StandardTagFactoryTest.php @@ -0,0 +1,361 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock; + +use Mockery as m; +use phpDocumentor\Reflection\DocBlock\Tags\Author; +use phpDocumentor\Reflection\DocBlock\Tags\Formatter; +use phpDocumentor\Reflection\DocBlock\Tags\Formatter\PassthroughFormatter; +use phpDocumentor\Reflection\DocBlock\Tags\Generic; +use phpDocumentor\Reflection\DocBlock\Tags\Return_; +use phpDocumentor\Reflection\DocBlock\Tags\See; +use phpDocumentor\Reflection\Fqsen; +use phpDocumentor\Reflection\FqsenResolver; +use phpDocumentor\Reflection\TypeResolver; +use phpDocumentor\Reflection\Types\Context; + +/** + * @coversDefaultClass phpDocumentor\Reflection\DocBlock\StandardTagFactory + * @covers :: + */ +class StandardTagFactoryTest extends \PHPUnit_Framework_TestCase +{ + /** + * @covers ::__construct + * @covers ::create + * @uses phpDocumentor\Reflection\DocBlock\StandardTagFactory::addService + * @uses phpDocumentor\Reflection\DocBlock\Tags\Generic + * @uses phpDocumentor\Reflection\DocBlock\Tags\BaseTag + * @uses phpDocumentor\Reflection\DocBlock\Description + */ + public function testCreatingAGenericTag() + { + $expectedTagName = 'unknown-tag'; + $expectedDescriptionText = 'This is a description'; + $expectedDescription = new Description($expectedDescriptionText); + $context = new Context(''); + + $descriptionFactory = m::mock(DescriptionFactory::class); + $descriptionFactory + ->shouldReceive('create') + ->once() + ->with($expectedDescriptionText, $context) + ->andReturn($expectedDescription) + ; + + $tagFactory = new StandardTagFactory(m::mock(FqsenResolver::class)); + $tagFactory->addService($descriptionFactory, DescriptionFactory::class); + + /** @var Generic $tag */ + $tag = $tagFactory->create('@' . $expectedTagName . ' This is a description', $context); + + $this->assertInstanceOf(Generic::class, $tag); + $this->assertSame($expectedTagName, $tag->getName()); + $this->assertSame($expectedDescription, $tag->getDescription()); + } + + /** + * @covers ::__construct + * @covers ::create + * @uses phpDocumentor\Reflection\DocBlock\StandardTagFactory::addService + * @uses phpDocumentor\Reflection\DocBlock\Tags\Author + * @uses phpDocumentor\Reflection\DocBlock\Tags\BaseTag + */ + public function testCreatingASpecificTag() + { + $context = new Context(''); + $tagFactory = new StandardTagFactory(m::mock(FqsenResolver::class)); + + /** @var Author $tag */ + $tag = $tagFactory->create('@author Mike van Riel ', $context); + + $this->assertInstanceOf(Author::class, $tag); + $this->assertSame('author', $tag->getName()); + } + + /** + * @covers ::__construct + * @covers ::create + * @uses phpDocumentor\Reflection\DocBlock\StandardTagFactory::addService + * @uses phpDocumentor\Reflection\DocBlock\Tags\See + * @uses phpDocumentor\Reflection\DocBlock\Tags\BaseTag + */ + public function testAnEmptyContextIsCreatedIfNoneIsProvided() + { + $fqsen = '\Tag'; + $resolver = m::mock(FqsenResolver::class) + ->shouldReceive('resolve') + ->with('Tag', m::type(Context::class)) + ->andReturn(new Fqsen($fqsen)) + ->getMock() + ; + $descriptionFactory = m::mock(DescriptionFactory::class); + $descriptionFactory->shouldIgnoreMissing(); + + $tagFactory = new StandardTagFactory($resolver); + $tagFactory->addService($descriptionFactory, DescriptionFactory::class); + + /** @var See $tag */ + $tag = $tagFactory->create('@see Tag'); + + $this->assertInstanceOf(See::class, $tag); + $this->assertSame($fqsen, (string)$tag->getReference()); + } + + /** + * @covers ::__construct + * @covers ::create + * @uses phpDocumentor\Reflection\DocBlock\StandardTagFactory::addService + * @uses phpDocumentor\Reflection\DocBlock\Tags\Author + * @uses phpDocumentor\Reflection\DocBlock\Tags\BaseTag + */ + public function testPassingYourOwnSetOfTagHandlers() + { + $context = new Context(''); + $tagFactory = new StandardTagFactory(m::mock(FqsenResolver::class), ['user' => Author::class]); + + /** @var Author $tag */ + $tag = $tagFactory->create('@user Mike van Riel ', $context); + + $this->assertInstanceOf(Author::class, $tag); + $this->assertSame('author', $tag->getName()); + } + + /** + * @covers ::create + * @uses phpDocumentor\Reflection\DocBlock\StandardTagFactory::__construct + * @uses phpDocumentor\Reflection\DocBlock\StandardTagFactory::addService + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage The tag "@user/myuser" does not seem to be wellformed, please check it for errors + */ + public function testExceptionIsThrownIfProvidedTagIsNotWellformed() + { + $this->markTestIncomplete( + 'For some reason this test fails; once I have access to a RegEx analyzer I will have to test the regex' + ) + ; + $tagFactory = new StandardTagFactory(m::mock(FqsenResolver::class)); + $tagFactory->create('@user[myuser'); + } + + /** + * @covers ::__construct + * @covers ::addParameter + * @uses phpDocumentor\Reflection\DocBlock\StandardTagFactory::addService + */ + public function testAddParameterToServiceLocator() + { + $resolver = m::mock(FqsenResolver::class); + $tagFactory = new StandardTagFactory($resolver); + $tagFactory->addParameter('myParam', 'myValue'); + + $this->assertAttributeSame( + [FqsenResolver::class => $resolver, 'myParam' => 'myValue'], + 'serviceLocator', + $tagFactory + ) + ; + } + + /** + * @covers ::addService + * @uses phpDocumentor\Reflection\DocBlock\StandardTagFactory::__construct + */ + public function testAddServiceToServiceLocator() + { + $service = new PassthroughFormatter(); + + $resolver = m::mock(FqsenResolver::class); + $tagFactory = new StandardTagFactory($resolver); + $tagFactory->addService($service); + + $this->assertAttributeSame( + [FqsenResolver::class => $resolver, PassthroughFormatter::class => $service], + 'serviceLocator', + $tagFactory + ) + ; + } + + /** + * @covers ::addService + * @uses phpDocumentor\Reflection\DocBlock\StandardTagFactory::__construct + */ + public function testInjectConcreteServiceForInterfaceToServiceLocator() + { + $interfaceName = Formatter::class; + $service = new PassthroughFormatter(); + + $resolver = m::mock(FqsenResolver::class); + $tagFactory = new StandardTagFactory($resolver); + $tagFactory->addService($service, $interfaceName); + + $this->assertAttributeSame( + [FqsenResolver::class => $resolver, $interfaceName => $service], + 'serviceLocator', + $tagFactory + ) + ; + } + + /** + * @covers ::registerTagHandler + * @uses phpDocumentor\Reflection\DocBlock\StandardTagFactory::__construct + * @uses phpDocumentor\Reflection\DocBlock\StandardTagFactory::addService + * @uses phpDocumentor\Reflection\DocBlock\StandardTagFactory::create + * @uses phpDocumentor\Reflection\DocBlock\Tags\Author + */ + public function testRegisteringAHandlerForANewTag() + { + $resolver = m::mock(FqsenResolver::class); + $tagFactory = new StandardTagFactory($resolver); + + $tagFactory->registerTagHandler('my-tag', Author::class); + + // Assert by trying to create one + $tag = $tagFactory->create('@my-tag Mike van Riel '); + $this->assertInstanceOf(Author::class, $tag); + } + + /** + * @covers ::registerTagHandler + * @uses phpDocumentor\Reflection\DocBlock\StandardTagFactory::__construct + * @uses phpDocumentor\Reflection\DocBlock\StandardTagFactory::addService + * @expectedException \InvalidArgumentException + */ + public function testHandlerRegistrationFailsIfProvidedTagNameIsNotAString() + { + $resolver = m::mock(FqsenResolver::class); + $tagFactory = new StandardTagFactory($resolver); + + $tagFactory->registerTagHandler([], Author::class); + } + + /** + * @covers ::registerTagHandler + * @uses phpDocumentor\Reflection\DocBlock\StandardTagFactory::__construct + * @uses phpDocumentor\Reflection\DocBlock\StandardTagFactory::addService + * @expectedException \InvalidArgumentException + */ + public function testHandlerRegistrationFailsIfProvidedTagNameIsEmpty() + { + $resolver = m::mock(FqsenResolver::class); + $tagFactory = new StandardTagFactory($resolver); + + $tagFactory->registerTagHandler('', Author::class); + } + + /** + * @covers ::registerTagHandler + * @uses phpDocumentor\Reflection\DocBlock\StandardTagFactory::__construct + * @uses phpDocumentor\Reflection\DocBlock\StandardTagFactory::addService + * @expectedException \InvalidArgumentException + */ + public function testHandlerRegistrationFailsIfProvidedTagNameIsNamespaceButNotFullyQualified() + { + $resolver = m::mock(FqsenResolver::class); + $tagFactory = new StandardTagFactory($resolver); + + $tagFactory->registerTagHandler('Name\Spaced\Tag', Author::class); + } + + /** + * @covers ::registerTagHandler + * @uses phpDocumentor\Reflection\DocBlock\StandardTagFactory::__construct + * @uses phpDocumentor\Reflection\DocBlock\StandardTagFactory::addService + * @expectedException \InvalidArgumentException + */ + public function testHandlerRegistrationFailsIfProvidedHandlerIsNotAString() + { + $resolver = m::mock(FqsenResolver::class); + $tagFactory = new StandardTagFactory($resolver); + + $tagFactory->registerTagHandler('my-tag', []); + } + + /** + * @covers ::registerTagHandler + * @uses phpDocumentor\Reflection\DocBlock\StandardTagFactory::__construct + * @uses phpDocumentor\Reflection\DocBlock\StandardTagFactory::addService + * @expectedException \InvalidArgumentException + */ + public function testHandlerRegistrationFailsIfProvidedHandlerIsEmpty() + { + $resolver = m::mock(FqsenResolver::class); + $tagFactory = new StandardTagFactory($resolver); + + $tagFactory->registerTagHandler('my-tag', ''); + } + + /** + * @covers ::registerTagHandler + * @uses phpDocumentor\Reflection\DocBlock\StandardTagFactory::__construct + * @uses phpDocumentor\Reflection\DocBlock\StandardTagFactory::addService + * @expectedException \InvalidArgumentException + */ + public function testHandlerRegistrationFailsIfProvidedHandlerIsNotAnExistingClassName() + { + $resolver = m::mock(FqsenResolver::class); + $tagFactory = new StandardTagFactory($resolver); + + $tagFactory->registerTagHandler('my-tag', 'IDoNotExist'); + } + + /** + * @covers ::registerTagHandler + * @uses phpDocumentor\Reflection\DocBlock\StandardTagFactory::__construct + * @uses phpDocumentor\Reflection\DocBlock\StandardTagFactory::addService + * @expectedException \InvalidArgumentException + */ + public function testHandlerRegistrationFailsIfProvidedHandlerDoesNotImplementTheTagInterface() + { + $resolver = m::mock(FqsenResolver::class); + $tagFactory = new StandardTagFactory($resolver); + + $tagFactory->registerTagHandler('my-tag', 'stdClass'); + } + + /** + * @covers ::create + * @uses phpDocumentor\Reflection\DocBlock\StandardTagFactory::__construct + * @uses phpDocumentor\Reflection\DocBlock\StandardTagFactory::addService + * @uses phpDocumentor\Reflection\Docblock\Description + * @uses phpDocumentor\Reflection\Docblock\Tags\Return_ + * @uses phpDocumentor\Reflection\Docblock\Tags\BaseTag + */ + public function testReturntagIsMappedCorrectly() + { + $context = new Context(''); + + $descriptionFactory = m::mock(DescriptionFactory::class); + $descriptionFactory + ->shouldReceive('create') + ->once() + ->with('', $context) + ->andReturn(new Description('')) + ; + + $typeResolver = new TypeResolver(); + + $tagFactory = new StandardTagFactory(m::mock(FqsenResolver::class)); + $tagFactory->addService($descriptionFactory, DescriptionFactory::class); + $tagFactory->addService($typeResolver, TypeResolver::class); + + + /** @var Return_ $tag */ + $tag = $tagFactory->create('@return mixed', $context); + + $this->assertInstanceOf(Return_::class, $tag); + $this->assertSame('return', $tag->getName()); + } +} diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/AuthorTest.php b/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/AuthorTest.php new file mode 100644 index 00000000..a54954f8 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/AuthorTest.php @@ -0,0 +1,148 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags; + +use Mockery as m; + +/** + * @coversDefaultClass \phpDocumentor\Reflection\DocBlock\Tags\Author + * @covers :: + */ +class AuthorTest extends \PHPUnit_Framework_TestCase +{ + /** + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Author::__construct + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::getName + */ + public function testIfCorrectTagNameIsReturned() + { + $fixture = new Author('Mike van Riel', 'mike@phpdoc.org'); + + $this->assertSame('author', $fixture->getName()); + } + + /** + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Author::__construct + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Author::__toString + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Formatter\PassthroughFormatter + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::render + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::getName + */ + public function testIfTagCanBeRenderedUsingDefaultFormatter() + { + $fixture = new Author('Mike van Riel', 'mike@phpdoc.org'); + + $this->assertSame('@author Mike van Riel', $fixture->render()); + } + + /** + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Author::__construct + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::render + */ + public function testIfTagCanBeRenderedUsingSpecificFormatter() + { + $fixture = new Author('Mike van Riel', 'mike@phpdoc.org'); + + $formatter = m::mock(Formatter::class); + $formatter->shouldReceive('format')->with($fixture)->andReturn('Rendered output'); + + $this->assertSame('Rendered output', $fixture->render($formatter)); + } + + /** + * @covers ::__construct + * @covers ::getAuthorName + */ + public function testHasTheAuthorName() + { + $expected = 'Mike van Riel'; + + $fixture = new Author($expected, 'mike@phpdoc.org'); + + $this->assertSame($expected, $fixture->getAuthorName()); + } + + /** + * @covers ::__construct + * @covers ::getAuthorName + * @expectedException \InvalidArgumentException + */ + public function testInitializationFailsIfAuthorNameIsNotAString() + { + new Author([], 'mike@phpdoc.org'); + } + + /** + * @covers ::__construct + * @covers ::getEmail + */ + public function testHasTheAuthorMailAddress() + { + $expected = 'mike@phpdoc.org'; + + $fixture = new Author('Mike van Riel', $expected); + + $this->assertSame($expected, $fixture->getEmail()); + } + + /** + * @covers ::__construct + * @expectedException \InvalidArgumentException + */ + public function testInitializationFailsIfEmailIsNotAString() + { + new Author('Mike van Riel', []); + } + + /** + * @covers ::__construct + * @expectedException \InvalidArgumentException + */ + public function testInitializationFailsIfEmailIsNotValid() + { + new Author('Mike van Riel', 'mike'); + } + + /** + * @covers ::__construct + * @covers ::__toString + */ + public function testStringRepresentationIsReturned() + { + $fixture = new Author('Mike van Riel', 'mike@phpdoc.org'); + + $this->assertSame('Mike van Riel', (string)$fixture); + } + + /** + * @covers ::create + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Author:: + */ + public function testFactoryMethod() + { + $fixture = Author::create('Mike van Riel '); + + $this->assertSame('Mike van Riel', (string)$fixture); + $this->assertSame('Mike van Riel', $fixture->getAuthorName()); + $this->assertSame('mike@phpdoc.org', $fixture->getEmail()); + } + + /** + * @covers ::create + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Author:: + */ + public function testFactoryMethodReturnsNullIfItCouldNotReadBody() + { + $this->assertNull(Author::create('dfgr<')); + } +} diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/CoversTest.php b/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/CoversTest.php new file mode 100644 index 00000000..a2b5e4b3 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/CoversTest.php @@ -0,0 +1,155 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags; + +use Mockery as m; +use phpDocumentor\Reflection\DocBlock\Description; +use phpDocumentor\Reflection\DocBlock\DescriptionFactory; +use phpDocumentor\Reflection\Fqsen; +use phpDocumentor\Reflection\FqsenResolver; +use phpDocumentor\Reflection\Types\Context; + +/** + * @coversDefaultClass \phpDocumentor\Reflection\DocBlock\Tags\Covers + * @covers :: + */ +class CoversTest extends \PHPUnit_Framework_TestCase +{ + /** + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Covers::__construct + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::getName + */ + public function testIfCorrectTagNameIsReturned() + { + $fixture = new Covers(new Fqsen('\DateTime'), new Description('Description')); + + $this->assertSame('covers', $fixture->getName()); + } + + /** + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Covers::__construct + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Covers::__toString + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Formatter\PassthroughFormatter + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::render + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::getName + */ + public function testIfTagCanBeRenderedUsingDefaultFormatter() + { + $fixture = new Covers(new Fqsen('\DateTime'), new Description('Description')); + + $this->assertSame('@covers \DateTime Description', $fixture->render()); + } + + /** + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Covers::__construct + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::render + */ + public function testIfTagCanBeRenderedUsingSpecificFormatter() + { + $fixture = new Covers(new Fqsen('\DateTime'), new Description('Description')); + + $formatter = m::mock(Formatter::class); + $formatter->shouldReceive('format')->with($fixture)->andReturn('Rendered output'); + + $this->assertSame('Rendered output', $fixture->render($formatter)); + } + + /** + * @covers ::__construct + * @covers ::getReference + */ + public function testHasReferenceToFqsen() + { + $expected = new Fqsen('\DateTime'); + + $fixture = new Covers($expected); + + $this->assertSame($expected, $fixture->getReference()); + } + + /** + * @covers ::__construct + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::getDescription + * @uses \phpDocumentor\Reflection\DocBlock\Description + */ + public function testHasDescription() + { + $expected = new Description('Description'); + + $fixture = new Covers(new Fqsen('\DateTime'), $expected); + + $this->assertSame($expected, $fixture->getDescription()); + } + + /** + * @covers ::__construct + * @covers ::__toString + * @uses \phpDocumentor\Reflection\DocBlock\Description + */ + public function testStringRepresentationIsReturned() + { + $fixture = new Covers(new Fqsen('\DateTime'), new Description('Description')); + + $this->assertSame('\DateTime Description', (string)$fixture); + } + + /** + * @covers ::create + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Covers:: + * @uses \phpDocumentor\Reflection\DocBlock\DescriptionFactory + * @uses \phpDocumentor\Reflection\FqsenResolver + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @uses \phpDocumentor\Reflection\Fqsen + * @uses \phpDocumentor\Reflection\Types\Context + */ + public function testFactoryMethod() + { + $descriptionFactory = m::mock(DescriptionFactory::class); + $resolver = m::mock(FqsenResolver::class); + $context = new Context(''); + + $fqsen = new Fqsen('\DateTime'); + $description = new Description('My Description'); + + $descriptionFactory + ->shouldReceive('create')->with('My Description', $context)->andReturn($description); + $resolver->shouldReceive('resolve')->with('DateTime', $context)->andReturn($fqsen); + + $fixture = Covers::create('DateTime My Description', $descriptionFactory, $resolver, $context); + + $this->assertSame('\DateTime My Description', (string)$fixture); + $this->assertSame($fqsen, $fixture->getReference()); + $this->assertSame($description, $fixture->getDescription()); + } + + /** + * @covers ::create + * @expectedException \InvalidArgumentException + */ + public function testFactoryMethodFailsIfBodyIsNotString() + { + $this->assertNull(Covers::create([])); + } + + /** + * @covers ::create + * @expectedException \InvalidArgumentException + */ + public function testFactoryMethodFailsIfBodyIsNotEmpty() + { + $this->assertNull(Covers::create('')); + } +} diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/DeprecatedTest.php b/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/DeprecatedTest.php new file mode 100644 index 00000000..8be9ad7e --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/DeprecatedTest.php @@ -0,0 +1,166 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags; + +use Mockery as m; +use phpDocumentor\Reflection\DocBlock\Description; +use phpDocumentor\Reflection\DocBlock\DescriptionFactory; +use phpDocumentor\Reflection\Types\Context; + +/** + * @coversDefaultClass \phpDocumentor\Reflection\DocBlock\Tags\Deprecated + * @covers :: + */ +class DeprecatedTest extends \PHPUnit_Framework_TestCase +{ + /** + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Deprecated::__construct + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::getName + */ + public function testIfCorrectTagNameIsReturned() + { + $fixture = new Deprecated('1.0', new Description('Description')); + + $this->assertSame('deprecated', $fixture->getName()); + } + + /** + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Deprecated::__construct + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Deprecated::__toString + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Formatter\PassthroughFormatter + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::render + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::getName + */ + public function testIfTagCanBeRenderedUsingDefaultFormatter() + { + $fixture = new Deprecated('1.0', new Description('Description')); + + $this->assertSame('@deprecated 1.0 Description', $fixture->render()); + } + + /** + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Deprecated::__construct + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::render + */ + public function testIfTagCanBeRenderedUsingSpecificFormatter() + { + $fixture = new Deprecated('1.0', new Description('Description')); + + $formatter = m::mock(Formatter::class); + $formatter->shouldReceive('format')->with($fixture)->andReturn('Rendered output'); + + $this->assertSame('Rendered output', $fixture->render($formatter)); + } + + /** + * @covers ::__construct + * @covers ::getVersion + */ + public function testHasVersionNumber() + { + $expected = '1.0'; + + $fixture = new Deprecated($expected); + + $this->assertSame($expected, $fixture->getVersion()); + } + + /** + * @covers ::__construct + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::getDescription + * @uses \phpDocumentor\Reflection\DocBlock\Description + */ + public function testHasDescription() + { + $expected = new Description('Description'); + + $fixture = new Deprecated('1.0', $expected); + + $this->assertSame($expected, $fixture->getDescription()); + } + + /** + * @covers ::__construct + * @covers ::__toString + * @uses \phpDocumentor\Reflection\DocBlock\Description + */ + public function testStringRepresentationIsReturned() + { + $fixture = new Deprecated('1.0', new Description('Description')); + + $this->assertSame('1.0 Description', (string)$fixture); + } + + /** + * @covers ::create + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Deprecated:: + * @uses \phpDocumentor\Reflection\DocBlock\DescriptionFactory + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @uses \phpDocumentor\Reflection\Types\Context + */ + public function testFactoryMethod() + { + $descriptionFactory = m::mock(DescriptionFactory::class); + $context = new Context(''); + + $version = '1.0'; + $description = new Description('My Description'); + + $descriptionFactory->shouldReceive('create')->with('My Description', $context)->andReturn($description); + + $fixture = Deprecated::create('1.0 My Description', $descriptionFactory, $context); + + $this->assertSame('1.0 My Description', (string)$fixture); + $this->assertSame($version, $fixture->getVersion()); + $this->assertSame($description, $fixture->getDescription()); + } + + /** + * @covers ::create + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Deprecated:: + * @uses \phpDocumentor\Reflection\DocBlock\DescriptionFactory + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @uses \phpDocumentor\Reflection\Types\Context + */ + public function testFactoryMethodCreatesEmptyDeprecatedTag() + { + $descriptionFactory = m::mock(DescriptionFactory::class); + $descriptionFactory->shouldReceive('create')->never(); + + $fixture = Deprecated::create('', $descriptionFactory, new Context('')); + + $this->assertSame('', (string)$fixture); + $this->assertSame(null, $fixture->getVersion()); + $this->assertSame(null, $fixture->getDescription()); + } + + /** + * @covers ::create + * @expectedException \InvalidArgumentException + */ + public function testFactoryMethodFailsIfVersionIsNotString() + { + $this->assertNull(Deprecated::create([])); + } + + /** + * @covers ::create + */ + public function testFactoryMethodReturnsNullIfBodyDoesNotMatchRegex() + { + $this->assertEquals(new Deprecated(), Deprecated::create('dkhf<')); + } +} diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/Formatter/PassthroughFormatterTest.php b/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/Formatter/PassthroughFormatterTest.php new file mode 100644 index 00000000..045a197f --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/Formatter/PassthroughFormatterTest.php @@ -0,0 +1,41 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags\Formatter; + +use Mockery as m; +use phpDocumentor\Reflection\DocBlock\Description; +use phpDocumentor\Reflection\DocBlock\Tags\Generic; + +/** + * @coversDefaultClass \phpDocumentor\Reflection\DocBlock\Tags\Formatter\PassthroughFormatter + */ +class PassthroughFormatterTest extends \PHPUnit_Framework_TestCase +{ + /** + * @covers ::format + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @uses \phpDocumentor\Reflection\DocBlock\Tags\BaseTag + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Generic + */ + public function testFormatterCallsToStringAndReturnsAStandardRepresentation() + { + $expected = '@unknown-tag This is a description'; + + $fixture = new PassthroughFormatter(); + + $this->assertSame( + $expected, + $fixture->format(new Generic('unknown-tag', new Description('This is a description'))) + ); + } +} diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/GenericTest.php b/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/GenericTest.php new file mode 100644 index 00000000..02fa5300 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/GenericTest.php @@ -0,0 +1,146 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @generic http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags; + +use Mockery as m; +use phpDocumentor\Reflection\DocBlock\Description; +use phpDocumentor\Reflection\DocBlock\DescriptionFactory; +use phpDocumentor\Reflection\Types\Context; + +/** + * @coversDefaultClass \phpDocumentor\Reflection\DocBlock\Tags\Generic + * @covers :: + */ +class GenericTest extends \PHPUnit_Framework_TestCase +{ + /** + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Generic::__construct + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::getName + */ + public function testIfCorrectTagNameIsReturned() + { + $fixture = new Generic('generic', new Description('Description')); + + $this->assertSame('generic', $fixture->getName()); + } + + /** + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Generic::__construct + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Generic::__toString + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Formatter\PassthroughFormatter + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @uses \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::getName + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::render + */ + public function testIfTagCanBeRenderedUsingDefaultFormatter() + { + $fixture = new Generic('generic', new Description('Description')); + + $this->assertSame('@generic Description', $fixture->render()); + } + + /** + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Generic::__construct + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::render + */ + public function testIfTagCanBeRenderedUsingSpecificFormatter() + { + $fixture = new Generic('generic', new Description('Description')); + + $formatter = m::mock(Formatter::class); + $formatter->shouldReceive('format')->with($fixture)->andReturn('Rendered output'); + + $this->assertSame('Rendered output', $fixture->render($formatter)); + } + + /** + * @covers ::__construct + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::getDescription + * @uses \phpDocumentor\Reflection\DocBlock\Description + */ + public function testHasDescription() + { + $expected = new Description('Description'); + + $fixture = new Generic('generic', $expected); + + $this->assertSame($expected, $fixture->getDescription()); + } + + /** + * @covers ::__construct + * @covers ::__toString + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @uses \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::getName + */ + public function testStringRepresentationIsReturned() + { + $fixture = new Generic('generic', new Description('Description')); + + $this->assertSame('Description', (string)$fixture); + } + + /** + * @covers ::create + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Generic:: + * @uses \phpDocumentor\Reflection\DocBlock\DescriptionFactory + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @uses \phpDocumentor\Reflection\Types\Context + */ + public function testFactoryMethod() + { + $descriptionFactory = m::mock(DescriptionFactory::class); + $context = new Context(''); + + $generics = 'generic'; + $description = new Description('My Description'); + + $descriptionFactory->shouldReceive('create')->with('My Description', $context)->andReturn($description); + + $fixture = Generic::create('My Description', 'generic', $descriptionFactory, $context); + + $this->assertSame('My Description', (string)$fixture); + $this->assertSame($generics, $fixture->getName()); + $this->assertSame($description, $fixture->getDescription()); + } + + /** + * @covers ::create + * @expectedException \InvalidArgumentException + */ + public function testFactoryMethodFailsIfNameIsNotString() + { + Generic::create('', []); + } + + /** + * @covers ::create + * @expectedException \InvalidArgumentException + */ + public function testFactoryMethodFailsIfNameIsNotEmpty() + { + Generic::create('', ''); + } + + /** + * @covers ::create + * @covers ::__construct + * @expectedException \InvalidArgumentException + */ + public function testFactoryMethodFailsIfNameContainsIllegalCharacters() + { + Generic::create('', 'name/myname'); + } +} diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/LinkTest.php b/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/LinkTest.php new file mode 100644 index 00000000..9940aec7 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/LinkTest.php @@ -0,0 +1,158 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags; + +use Mockery as m; +use phpDocumentor\Reflection\DocBlock\Description; +use phpDocumentor\Reflection\DocBlock\DescriptionFactory; +use phpDocumentor\Reflection\Types\Context; + +/** + * @coversDefaultClass \phpDocumentor\Reflection\DocBlock\Tags\Link + * @covers :: + */ +class LinkTest extends \PHPUnit_Framework_TestCase +{ + /** + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Link::__construct + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::getName + */ + public function testIfCorrectTagNameIsReturned() + { + $fixture = new Link('http://this.is.my/link', new Description('Description')); + + $this->assertSame('link', $fixture->getName()); + } + + /** + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Link::__construct + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Link::__toString + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Formatter\PassthroughFormatter + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::render + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::getName + */ + public function testIfTagCanBeRenderedUsingDefaultFormatter() + { + $fixture = new Link('http://this.is.my/link', new Description('Description')); + + $this->assertSame('@link http://this.is.my/link Description', $fixture->render()); + } + + /** + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Link::__construct + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::render + */ + public function testIfTagCanBeRenderedUsingSpecificFormatter() + { + $fixture = new Link('http://this.is.my/link', new Description('Description')); + + $formatter = m::mock(Formatter::class); + $formatter->shouldReceive('format')->with($fixture)->andReturn('Rendered output'); + + $this->assertSame('Rendered output', $fixture->render($formatter)); + } + + /** + * @covers ::__construct + * @covers ::getLink + */ + public function testHasLinkUrl() + { + $expected = 'http://this.is.my/link'; + + $fixture = new Link($expected); + + $this->assertSame($expected, $fixture->getLink()); + } + + /** + * @covers ::__construct + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::getDescription + * @uses \phpDocumentor\Reflection\DocBlock\Description + */ + public function testHasDescription() + { + $expected = new Description('Description'); + + $fixture = new Link('http://this.is.my/link', $expected); + + $this->assertSame($expected, $fixture->getDescription()); + } + + /** + * @covers ::__construct + * @covers ::__toString + * @uses \phpDocumentor\Reflection\DocBlock\Description + */ + public function testStringRepresentationIsReturned() + { + $fixture = new Link('http://this.is.my/link', new Description('Description')); + + $this->assertSame('http://this.is.my/link Description', (string)$fixture); + } + + /** + * @covers ::create + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Link:: + * @uses \phpDocumentor\Reflection\DocBlock\DescriptionFactory + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @uses \phpDocumentor\Reflection\Types\Context + */ + public function testFactoryMethod() + { + $descriptionFactory = m::mock(DescriptionFactory::class); + $context = new Context(''); + + $links = 'http://this.is.my/link'; + $description = new Description('My Description'); + + $descriptionFactory->shouldReceive('create')->with('My Description', $context)->andReturn($description); + + $fixture = Link::create('http://this.is.my/link My Description', $descriptionFactory, $context); + + $this->assertSame('http://this.is.my/link My Description', (string)$fixture); + $this->assertSame($links, $fixture->getLink()); + $this->assertSame($description, $fixture->getDescription()); + } + + /** + * @covers ::create + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Link:: + * @uses \phpDocumentor\Reflection\DocBlock\DescriptionFactory + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @uses \phpDocumentor\Reflection\Types\Context + */ + public function testFactoryMethodCreatesEmptyLinkTag() + { + $descriptionFactory = m::mock(DescriptionFactory::class); + $descriptionFactory->shouldReceive('create')->never(); + + $fixture = Link::create('', $descriptionFactory, new Context('')); + + $this->assertSame('', (string)$fixture); + $this->assertSame('', $fixture->getLink()); + $this->assertSame(null, $fixture->getDescription()); + } + + /** + * @covers ::create + * @expectedException \InvalidArgumentException + */ + public function testFactoryMethodFailsIfVersionIsNotString() + { + $this->assertNull(Link::create([])); + } +} diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/MethodTest.php b/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/MethodTest.php new file mode 100644 index 00000000..5d6e981e --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/MethodTest.php @@ -0,0 +1,437 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags; + +use Mockery as m; +use phpDocumentor\Reflection\DocBlock\Description; +use phpDocumentor\Reflection\DocBlock\DescriptionFactory; +use phpDocumentor\Reflection\TypeResolver; +use phpDocumentor\Reflection\Types\Array_; +use phpDocumentor\Reflection\Types\Compound; +use phpDocumentor\Reflection\Types\Context; +use phpDocumentor\Reflection\Types\Integer; +use phpDocumentor\Reflection\Types\Object_; +use phpDocumentor\Reflection\Types\String_; +use phpDocumentor\Reflection\Types\Void_; + +/** + * @coversDefaultClass \phpDocumentor\Reflection\DocBlock\Tags\Method + * @covers :: + */ +class MethodTest extends \PHPUnit_Framework_TestCase +{ + /** + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Method::__construct + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::getName + */ + public function testIfCorrectTagNameIsReturned() + { + $fixture = new Method('myMethod'); + + $this->assertSame('method', $fixture->getName()); + } + + /** + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Method::__construct + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Method::isStatic + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Method::__toString + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Formatter\PassthroughFormatter + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::render + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::getName + */ + public function testIfTagCanBeRenderedUsingDefaultFormatter() + { + $arguments = [ + ['name' => 'argument1', 'type' => new String_()], + ['name' => 'argument2', 'type' => new Object_()] + ]; + $fixture = new Method('myMethod', $arguments, new Void_(), true, new Description('My Description')); + + $this->assertSame( + '@method static void myMethod(string $argument1, object $argument2) My Description', + $fixture->render() + ); + } + + /** + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Method::__construct + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::render + */ + public function testIfTagCanBeRenderedUsingSpecificFormatter() + { + $fixture = new Method('myMethod'); + + $formatter = m::mock(Formatter::class); + $formatter->shouldReceive('format')->with($fixture)->andReturn('Rendered output'); + + $this->assertSame('Rendered output', $fixture->render($formatter)); + } + + /** + * @covers ::__construct + * @covers ::getMethodName + */ + public function testHasMethodName() + { + $expected = 'myMethod'; + + $fixture = new Method($expected); + + $this->assertSame($expected, $fixture->getMethodName()); + } + + /** + * @covers ::__construct + * @covers ::getArguments + */ + public function testHasArguments() + { + $arguments = [ + [ 'name' => 'argument1', 'type' => new String_() ] + ]; + + $fixture = new Method('myMethod', $arguments); + + $this->assertSame($arguments, $fixture->getArguments()); + } + + /** + * @covers ::__construct + * @covers ::getArguments + */ + public function testArgumentsMayBePassedAsString() + { + $arguments = ['argument1']; + $expected = [ + [ 'name' => $arguments[0], 'type' => new Void_() ] + ]; + + $fixture = new Method('myMethod', $arguments); + + $this->assertEquals($expected, $fixture->getArguments()); + } + + /** + * @covers ::__construct + * @covers ::getArguments + */ + public function testArgumentTypeCanBeInferredAsVoid() + { + $arguments = [ [ 'name' => 'argument1' ] ]; + $expected = [ + [ 'name' => $arguments[0]['name'], 'type' => new Void_() ] + ]; + + $fixture = new Method('myMethod', $arguments); + + $this->assertEquals($expected, $fixture->getArguments()); + } + + /** + * @covers ::create + */ + public function testRestArgumentIsParsedAsRegularArg() + { + $expected = [ + [ 'name' => 'arg1', 'type' => new Void_() ], + [ 'name' => 'rest', 'type' => new Void_() ], + [ 'name' => 'rest2', 'type' => new Array_() ], + ]; + + $descriptionFactory = m::mock(DescriptionFactory::class); + $resolver = new TypeResolver(); + $context = new Context(''); + $description = new Description(''); + $descriptionFactory->shouldReceive('create')->with('', $context)->andReturn($description); + + $fixture = Method::create( + 'void myMethod($arg1, ...$rest, array ... $rest2)', + $resolver, + $descriptionFactory, + $context + ); + + $this->assertEquals($expected, $fixture->getArguments()); + } + + /** + * @covers ::__construct + * @covers ::getReturnType + */ + public function testHasReturnType() + { + $expected = new String_(); + + $fixture = new Method('myMethod', [], $expected); + + $this->assertSame($expected, $fixture->getReturnType()); + } + + /** + * @covers ::__construct + * @covers ::getReturnType + */ + public function testReturnTypeCanBeInferredAsVoid() + { + $fixture = new Method('myMethod', []); + + $this->assertEquals(new Void_(), $fixture->getReturnType()); + } + + /** + * @covers ::__construct + * @covers ::isStatic + */ + public function testMethodCanBeStatic() + { + $expected = false; + $fixture = new Method('myMethod', [], null, $expected); + $this->assertSame($expected, $fixture->isStatic()); + + $expected = true; + $fixture = new Method('myMethod', [], null, $expected); + $this->assertSame($expected, $fixture->isStatic()); + } + + /** + * @covers ::__construct + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::getDescription + * @uses \phpDocumentor\Reflection\DocBlock\Description + */ + public function testHasDescription() + { + $expected = new Description('Description'); + + $fixture = new Method('myMethod', [], null, false, $expected); + + $this->assertSame($expected, $fixture->getDescription()); + } + + /** + * @covers ::__construct + * @covers ::__toString + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Method::isStatic + */ + public function testStringRepresentationIsReturned() + { + $arguments = [ + ['name' => 'argument1', 'type' => new String_()], + ['name' => 'argument2', 'type' => new Object_()] + ]; + $fixture = new Method('myMethod', $arguments, new Void_(), true, new Description('My Description')); + + $this->assertSame( + 'static void myMethod(string $argument1, object $argument2) My Description', + (string)$fixture + ); + } + + /** + * @covers ::create + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Method:: + * @uses \phpDocumentor\Reflection\DocBlock\DescriptionFactory + * @uses \phpDocumentor\Reflection\TypeResolver + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @uses \phpDocumentor\Reflection\Fqsen + * @uses \phpDocumentor\Reflection\Types\Context + */ + public function testFactoryMethod() + { + $descriptionFactory = m::mock(DescriptionFactory::class); + $resolver = new TypeResolver(); + $context = new Context(''); + + $description = new Description('My Description'); + $expectedArguments = [ + [ 'name' => 'argument1', 'type' => new String_() ], + [ 'name' => 'argument2', 'type' => new Void_() ] + ]; + + $descriptionFactory->shouldReceive('create')->with('My Description', $context)->andReturn($description); + + $fixture = Method::create( + 'static void myMethod(string $argument1, $argument2) My Description', + $resolver, + $descriptionFactory, + $context + ); + + $this->assertSame('static void myMethod(string $argument1, void $argument2) My Description', (string)$fixture); + $this->assertSame('myMethod', $fixture->getMethodName()); + $this->assertEquals($expectedArguments, $fixture->getArguments()); + $this->assertInstanceOf(Void_::class, $fixture->getReturnType()); + $this->assertSame($description, $fixture->getDescription()); + } + + public function collectionReturnTypesProvider() + { + return [ + ['int[]', Array_::class, Integer::class, Compound::class], + ['int[][]', Array_::class, Array_::class, Compound::class], + ['Object[]', Array_::class, Object_::class, Compound::class], + ['array[]', Array_::class, Array_::class, Compound::class], + ]; + } + + /** + * @dataProvider collectionReturnTypesProvider + * @covers ::create + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Method:: + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @uses \phpDocumentor\Reflection\DocBlock\DescriptionFactory + * @uses \phpDocumentor\Reflection\TypeResolver + * @uses \phpDocumentor\Reflection\Types\Array_ + * @uses \phpDocumentor\Reflection\Types\Compound + * @uses \phpDocumentor\Reflection\Types\Integer + * @uses \phpDocumentor\Reflection\Types\Object_ + * @param string $returnType + * @param string $expectedType + * @param string $expectedValueType + * @param string null $expectedKeyType + */ + public function testCollectionReturnTypes( + $returnType, + $expectedType, + $expectedValueType = null, + $expectedKeyType = null + ) { $resolver = new TypeResolver(); + $descriptionFactory = m::mock(DescriptionFactory::class); + $descriptionFactory->shouldReceive('create')->with('', null)->andReturn(new Description('')); + + $fixture = Method::create("$returnType myMethod(\$arg)", $resolver, $descriptionFactory); + $returnType = $fixture->getReturnType(); + $this->assertInstanceOf($expectedType, $returnType); + + if ($returnType instanceof Array_) { + $this->assertInstanceOf($expectedValueType, $returnType->getValueType()); + $this->assertInstanceOf($expectedKeyType, $returnType->getKeyType()); + } + } + + /** + * @covers ::create + * @expectedException \InvalidArgumentException + */ + public function testFactoryMethodFailsIfBodyIsNotString() + { + Method::create([]); + } + + /** + * @covers ::create + * @expectedException \InvalidArgumentException + */ + public function testFactoryMethodFailsIfBodyIsEmpty() + { + Method::create(''); + } + + /** + * @covers ::create + * @expectedException \InvalidArgumentException + */ + public function testFactoryMethodReturnsNullIfBodyIsIncorrect() + { + $this->assertNull(Method::create('body(')); + } + + /** + * @covers ::create + * @expectedException \InvalidArgumentException + */ + public function testFactoryMethodFailsIfResolverIsNull() + { + Method::create('body'); + } + + /** + * @covers ::create + * @expectedException \InvalidArgumentException + */ + public function testFactoryMethodFailsIfDescriptionFactoryIsNull() + { + Method::create('body', new TypeResolver()); + } + + /** + * @covers ::__construct + * @expectedException \InvalidArgumentException + */ + public function testCreationFailsIfBodyIsNotString() + { + new Method([]); + } + + /** + * @covers ::__construct + * @expectedException \InvalidArgumentException + */ + public function testCreationFailsIfBodyIsEmpty() + { + new Method(''); + } + + /** + * @covers ::__construct + * @expectedException \InvalidArgumentException + */ + public function testCreationFailsIfStaticIsNotBoolean() + { + new Method('body', [], null, []); + } + + /** + * @covers ::__construct + * @expectedException \InvalidArgumentException + */ + public function testCreationFailsIfArgumentRecordContainsInvalidEntry() + { + new Method('body', [ [ 'name' => 'myName', 'unknown' => 'nah' ] ]); + } + + /** + * @covers ::create + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Method:: + * @uses \phpDocumentor\Reflection\DocBlock\DescriptionFactory + * @uses \phpDocumentor\Reflection\TypeResolver + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @uses \phpDocumentor\Reflection\Fqsen + * @uses \phpDocumentor\Reflection\Types\Context + */ + public function testCreateMethodParenthesisMissing() + { + $descriptionFactory = m::mock(DescriptionFactory::class); + $resolver = new TypeResolver(); + $context = new Context(''); + + $description = new Description('My Description'); + + $descriptionFactory->shouldReceive('create')->with('My Description', $context)->andReturn($description); + + $fixture = Method::create( + 'static void myMethod My Description', + $resolver, + $descriptionFactory, + $context + ); + + $this->assertSame('static void myMethod() My Description', (string)$fixture); + $this->assertSame('myMethod', $fixture->getMethodName()); + $this->assertEquals([], $fixture->getArguments()); + $this->assertInstanceOf(Void_::class, $fixture->getReturnType()); + $this->assertSame($description, $fixture->getDescription()); + } +} diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/ParamTest.php b/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/ParamTest.php new file mode 100644 index 00000000..0c718ab7 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/ParamTest.php @@ -0,0 +1,228 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags; + +use Mockery as m; +use phpDocumentor\Reflection\DocBlock\Description; +use phpDocumentor\Reflection\DocBlock\DescriptionFactory; +use phpDocumentor\Reflection\TypeResolver; +use phpDocumentor\Reflection\Types\Context; +use phpDocumentor\Reflection\Types\String_; + +/** + * @coversDefaultClass \phpDocumentor\Reflection\DocBlock\Tags\Param + * @covers :: + */ +class ParamTest extends \PHPUnit_Framework_TestCase +{ + /** + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Param::__construct + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::getName + */ + public function testIfCorrectTagNameIsReturned() + { + $fixture = new Param('myParameter', null, false, new Description('Description')); + + $this->assertSame('param', $fixture->getName()); + } + + /** + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Param::__construct + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Param::isVariadic + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Param::__toString + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Formatter\PassthroughFormatter + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::render + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::getName + */ + public function testIfTagCanBeRenderedUsingDefaultFormatter() + { + $fixture = new Param('myParameter', new String_(), true, new Description('Description')); + $this->assertSame('@param string ...$myParameter Description', $fixture->render()); + + $fixture = new Param('myParameter', new String_(), false, new Description('Description')); + $this->assertSame('@param string $myParameter Description', $fixture->render()); + + $fixture = new Param('myParameter', null, false, new Description('Description')); + $this->assertSame('@param $myParameter Description', $fixture->render()); + + $fixture = new Param('myParameter'); + $this->assertSame('@param $myParameter', $fixture->render()); + } + + /** + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Param::__construct + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::render + */ + public function testIfTagCanBeRenderedUsingSpecificFormatter() + { + $fixture = new Param('myParameter'); + + $formatter = m::mock(Formatter::class); + $formatter->shouldReceive('format')->with($fixture)->andReturn('Rendered output'); + + $this->assertSame('Rendered output', $fixture->render($formatter)); + } + + /** + * @covers ::__construct + * @covers ::getVariableName + */ + public function testHasVariableName() + { + $expected = 'myParameter'; + + $fixture = new Param($expected); + + $this->assertSame($expected, $fixture->getVariableName()); + } + + /** + * @covers ::__construct + * @covers ::getType + */ + public function testHasType() + { + $expected = new String_(); + + $fixture = new Param('myParameter', $expected); + + $this->assertSame($expected, $fixture->getType()); + } + + /** + * @covers ::__construct + * @covers ::isVariadic + */ + public function testIfParameterIsVariadic() + { + $fixture = new Param('myParameter', new String_(), false); + $this->assertFalse($fixture->isVariadic()); + + $fixture = new Param('myParameter', new String_(), true); + $this->assertTrue($fixture->isVariadic()); + } + + /** + * @covers ::__construct + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::getDescription + * @uses \phpDocumentor\Reflection\DocBlock\Description + */ + public function testHasDescription() + { + $expected = new Description('Description'); + + $fixture = new Param('1.0', null, false, $expected); + + $this->assertSame($expected, $fixture->getDescription()); + } + + /** + * @covers ::__construct + * @covers ::isVariadic + * @covers ::__toString + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @uses \phpDocumentor\Reflection\Types\String_ + */ + public function testStringRepresentationIsReturned() + { + $fixture = new Param('myParameter', new String_(), true, new Description('Description')); + + $this->assertSame('string ...$myParameter Description', (string)$fixture); + } + + /** + * @covers ::create + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Param:: + * @uses \phpDocumentor\Reflection\DocBlock\DescriptionFactory + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @uses \phpDocumentor\Reflection\Types\Context + */ + public function testFactoryMethod() + { + $typeResolver = new TypeResolver(); + $descriptionFactory = m::mock(DescriptionFactory::class); + $context = new Context(''); + + $description = new Description('My Description'); + $descriptionFactory->shouldReceive('create')->with('My Description', $context)->andReturn($description); + + $fixture = Param::create('string ...$myParameter My Description', $typeResolver, $descriptionFactory, $context); + + $this->assertSame('string ...$myParameter My Description', (string)$fixture); + $this->assertSame('myParameter', $fixture->getVariableName()); + $this->assertInstanceOf(String_::class, $fixture->getType()); + $this->assertTrue($fixture->isVariadic()); + $this->assertSame($description, $fixture->getDescription()); + } + + /** + * @covers ::create + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Param:: + * @uses \phpDocumentor\Reflection\TypeResolver + * @uses \phpDocumentor\Reflection\DocBlock\DescriptionFactory + * @expectedException \InvalidArgumentException + */ + public function testFactoryMethodFailsIfEmptyBodyIsGiven() + { + $descriptionFactory = m::mock(DescriptionFactory::class); + Param::create('', new TypeResolver(), $descriptionFactory); + } + + /** + * @covers ::create + * @expectedException \InvalidArgumentException + */ + public function testFactoryMethodFailsIfBodyIsNotString() + { + Param::create([]); + } + + /** + * @covers ::create + * @expectedException \InvalidArgumentException + */ + public function testFactoryMethodFailsIfResolverIsNull() + { + Param::create('body'); + } + + /** + * @covers ::create + * @uses \phpDocumentor\Reflection\TypeResolver + * @expectedException \InvalidArgumentException + */ + public function testFactoryMethodFailsIfDescriptionFactoryIsNull() + { + Param::create('body', new TypeResolver()); + } + + /** + * @covers ::__construct + * @expectedException \InvalidArgumentException + */ + public function testExceptionIsThrownIfVariableNameIsNotString() + { + new Param([]); + } + + /** + * @covers ::__construct + * @expectedException \InvalidArgumentException + */ + public function testExceptionIsThrownIfVariadicIsNotBoolean() + { + new Param('', null, []); + } +} diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/PropertyReadTest.php b/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/PropertyReadTest.php new file mode 100644 index 00000000..c3fb7700 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/PropertyReadTest.php @@ -0,0 +1,201 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags; + +use Mockery as m; +use phpDocumentor\Reflection\DocBlock\Description; +use phpDocumentor\Reflection\DocBlock\DescriptionFactory; +use phpDocumentor\Reflection\TypeResolver; +use phpDocumentor\Reflection\Types\Context; +use phpDocumentor\Reflection\Types\String_; + +/** + * @coversDefaultClass \phpDocumentor\Reflection\DocBlock\Tags\PropertyRead + * @covers :: + */ +class PropertyReadTest extends \PHPUnit_Framework_TestCase +{ + /** + * @uses \phpDocumentor\Reflection\DocBlock\Tags\PropertyRead::__construct + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::getName + */ + public function testIfCorrectTagNameIsReturned() + { + $fixture = new PropertyRead('myProperty', null, new Description('Description')); + + $this->assertSame('property-read', $fixture->getName()); + } + + /** + * @uses \phpDocumentor\Reflection\DocBlock\Tags\PropertyRead::__construct + * @uses \phpDocumentor\Reflection\DocBlock\Tags\PropertyRead::__toString + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Formatter\PassthroughFormatter + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::render + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::getName + */ + public function testIfTagCanBeRenderedUsingDefaultFormatter() + { + $fixture = new PropertyRead('myProperty', new String_(), new Description('Description')); + $this->assertSame('@property-read string $myProperty Description', $fixture->render()); + + $fixture = new PropertyRead('myProperty', null, new Description('Description')); + $this->assertSame('@property-read $myProperty Description', $fixture->render()); + + $fixture = new PropertyRead('myProperty'); + $this->assertSame('@property-read $myProperty', $fixture->render()); + } + + /** + * @uses \phpDocumentor\Reflection\DocBlock\Tags\PropertyRead::__construct + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::render + */ + public function testIfTagCanBeRenderedUsingSpecificFormatter() + { + $fixture = new PropertyRead('myProperty'); + + $formatter = m::mock(Formatter::class); + $formatter->shouldReceive('format')->with($fixture)->andReturn('Rendered output'); + + $this->assertSame('Rendered output', $fixture->render($formatter)); + } + + /** + * @covers ::__construct + * @covers ::getVariableName + */ + public function testHasVariableName() + { + $expected = 'myProperty'; + + $fixture = new PropertyRead($expected); + + $this->assertSame($expected, $fixture->getVariableName()); + } + + /** + * @covers ::__construct + * @covers ::getType + */ + public function testHasType() + { + $expected = new String_(); + + $fixture = new PropertyRead('myProperty', $expected); + + $this->assertSame($expected, $fixture->getType()); + } + + /** + * @covers ::__construct + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::getDescription + * @uses \phpDocumentor\Reflection\DocBlock\Description + */ + public function testHasDescription() + { + $expected = new Description('Description'); + + $fixture = new PropertyRead('1.0', null, $expected); + + $this->assertSame($expected, $fixture->getDescription()); + } + + /** + * @covers ::__construct + * @covers ::__toString + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @uses \phpDocumentor\Reflection\Types\String_ + */ + public function testStringRepresentationIsReturned() + { + $fixture = new PropertyRead('myProperty', new String_(), new Description('Description')); + + $this->assertSame('string $myProperty Description', (string)$fixture); + } + + /** + * @covers ::create + * @uses \phpDocumentor\Reflection\DocBlock\Tags\PropertyRead:: + * @uses \phpDocumentor\Reflection\DocBlock\DescriptionFactory + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @uses \phpDocumentor\Reflection\Types\Context + */ + public function testFactoryMethod() + { + $typeResolver = new TypeResolver(); + $descriptionFactory = m::mock(DescriptionFactory::class); + $context = new Context(''); + + $description = new Description('My Description'); + $descriptionFactory->shouldReceive('create')->with('My Description', $context)->andReturn($description); + + $fixture = PropertyRead::create('string $myProperty My Description', $typeResolver, $descriptionFactory, + $context); + + $this->assertSame('string $myProperty My Description', (string)$fixture); + $this->assertSame('myProperty', $fixture->getVariableName()); + $this->assertInstanceOf(String_::class, $fixture->getType()); + $this->assertSame($description, $fixture->getDescription()); + } + + /** + * @covers ::create + * @uses \phpDocumentor\Reflection\DocBlock\Tags\PropertyRead:: + * @uses \phpDocumentor\Reflection\TypeResolver + * @uses \phpDocumentor\Reflection\DocBlock\DescriptionFactory + * @expectedException \InvalidArgumentException + */ + public function testFactoryMethodFailsIfEmptyBodyIsGiven() + { + $descriptionFactory = m::mock(DescriptionFactory::class); + PropertyRead::create('', new TypeResolver(), $descriptionFactory); + } + + /** + * @covers ::create + * @expectedException \InvalidArgumentException + */ + public function testFactoryMethodFailsIfBodyIsNotString() + { + PropertyRead::create([]); + } + + /** + * @covers ::create + * @expectedException \InvalidArgumentException + */ + public function testFactoryMethodFailsIfResolverIsNull() + { + PropertyRead::create('body'); + } + + /** + * @covers ::create + * @uses \phpDocumentor\Reflection\TypeResolver + * @expectedException \InvalidArgumentException + */ + public function testFactoryMethodFailsIfDescriptionFactoryIsNull() + { + PropertyRead::create('body', new TypeResolver()); + } + + /** + * @covers ::__construct + * @expectedException \InvalidArgumentException + */ + public function testExceptionIsThrownIfVariableNameIsNotString() + { + new PropertyRead([]); + } +} diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/PropertyTest.php b/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/PropertyTest.php new file mode 100644 index 00000000..908dfb28 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/PropertyTest.php @@ -0,0 +1,200 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags; + +use Mockery as m; +use phpDocumentor\Reflection\DocBlock\Description; +use phpDocumentor\Reflection\DocBlock\DescriptionFactory; +use phpDocumentor\Reflection\TypeResolver; +use phpDocumentor\Reflection\Types\Context; +use phpDocumentor\Reflection\Types\String_; + +/** + * @coversDefaultClass \phpDocumentor\Reflection\DocBlock\Tags\Property + * @covers :: + */ +class PropertyTest extends \PHPUnit_Framework_TestCase +{ + /** + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Property::__construct + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::getName + */ + public function testIfCorrectTagNameIsReturned() + { + $fixture = new Property('myProperty', null, new Description('Description')); + + $this->assertSame('property', $fixture->getName()); + } + + /** + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Property::__construct + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Property::__toString + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Formatter\PassthroughFormatter + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::render + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::getName + */ + public function testIfTagCanBeRenderedUsingDefaultFormatter() + { + $fixture = new Property('myProperty', new String_(), new Description('Description')); + $this->assertSame('@property string $myProperty Description', $fixture->render()); + + $fixture = new Property('myProperty', null, new Description('Description')); + $this->assertSame('@property $myProperty Description', $fixture->render()); + + $fixture = new Property('myProperty'); + $this->assertSame('@property $myProperty', $fixture->render()); + } + + /** + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Property::__construct + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::render + */ + public function testIfTagCanBeRenderedUsingSpecificFormatter() + { + $fixture = new Property('myProperty'); + + $formatter = m::mock(Formatter::class); + $formatter->shouldReceive('format')->with($fixture)->andReturn('Rendered output'); + + $this->assertSame('Rendered output', $fixture->render($formatter)); + } + + /** + * @covers ::__construct + * @covers ::getVariableName + */ + public function testHasVariableName() + { + $expected = 'myProperty'; + + $fixture = new Property($expected); + + $this->assertSame($expected, $fixture->getVariableName()); + } + + /** + * @covers ::__construct + * @covers ::getType + */ + public function testHasType() + { + $expected = new String_(); + + $fixture = new Property('myProperty', $expected); + + $this->assertSame($expected, $fixture->getType()); + } + + /** + * @covers ::__construct + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::getDescription + * @uses \phpDocumentor\Reflection\DocBlock\Description + */ + public function testHasDescription() + { + $expected = new Description('Description'); + + $fixture = new Property('1.0', null, $expected); + + $this->assertSame($expected, $fixture->getDescription()); + } + + /** + * @covers ::__construct + * @covers ::__toString + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @uses \phpDocumentor\Reflection\Types\String_ + */ + public function testStringRepresentationIsReturned() + { + $fixture = new Property('myProperty', new String_(), new Description('Description')); + + $this->assertSame('string $myProperty Description', (string)$fixture); + } + + /** + * @covers ::create + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Property:: + * @uses \phpDocumentor\Reflection\DocBlock\DescriptionFactory + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @uses \phpDocumentor\Reflection\Types\Context + */ + public function testFactoryMethod() + { + $typeResolver = new TypeResolver(); + $descriptionFactory = m::mock(DescriptionFactory::class); + $context = new Context(''); + + $description = new Description('My Description'); + $descriptionFactory->shouldReceive('create')->with('My Description', $context)->andReturn($description); + + $fixture = Property::create('string $myProperty My Description', $typeResolver, $descriptionFactory, $context); + + $this->assertSame('string $myProperty My Description', (string)$fixture); + $this->assertSame('myProperty', $fixture->getVariableName()); + $this->assertInstanceOf(String_::class, $fixture->getType()); + $this->assertSame($description, $fixture->getDescription()); + } + + /** + * @covers ::create + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Property:: + * @uses \phpDocumentor\Reflection\TypeResolver + * @uses \phpDocumentor\Reflection\DocBlock\DescriptionFactory + * @expectedException \InvalidArgumentException + */ + public function testFactoryMethodFailsIfEmptyBodyIsGiven() + { + $descriptionFactory = m::mock(DescriptionFactory::class); + Property::create('', new TypeResolver(), $descriptionFactory); + } + + /** + * @covers ::create + * @expectedException \InvalidArgumentException + */ + public function testFactoryMethodFailsIfBodyIsNotString() + { + Property::create([]); + } + + /** + * @covers ::create + * @expectedException \InvalidArgumentException + */ + public function testFactoryMethodFailsIfResolverIsNull() + { + Property::create('body'); + } + + /** + * @covers ::create + * @uses \phpDocumentor\Reflection\TypeResolver + * @expectedException \InvalidArgumentException + */ + public function testFactoryMethodFailsIfDescriptionFactoryIsNull() + { + Property::create('body', new TypeResolver()); + } + + /** + * @covers ::__construct + * @expectedException \InvalidArgumentException + */ + public function testExceptionIsThrownIfVariableNameIsNotString() + { + new Property([]); + } +} diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/PropertyWriteTest.php b/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/PropertyWriteTest.php new file mode 100644 index 00000000..5ea6524c --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/PropertyWriteTest.php @@ -0,0 +1,201 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags; + +use Mockery as m; +use phpDocumentor\Reflection\DocBlock\Description; +use phpDocumentor\Reflection\DocBlock\DescriptionFactory; +use phpDocumentor\Reflection\TypeResolver; +use phpDocumentor\Reflection\Types\Context; +use phpDocumentor\Reflection\Types\String_; + +/** + * @coversDefaultClass \phpDocumentor\Reflection\DocBlock\Tags\PropertyWrite + * @covers :: + */ +class PropertyWriteTest extends \PHPUnit_Framework_TestCase +{ + /** + * @uses \phpDocumentor\Reflection\DocBlock\Tags\PropertyWrite::__construct + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::getName + */ + public function testIfCorrectTagNameIsReturned() + { + $fixture = new PropertyWrite('myProperty', null, new Description('Description')); + + $this->assertSame('property-write', $fixture->getName()); + } + + /** + * @uses \phpDocumentor\Reflection\DocBlock\Tags\PropertyWrite::__construct + * @uses \phpDocumentor\Reflection\DocBlock\Tags\PropertyWrite::__toString + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Formatter\PassthroughFormatter + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::render + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::getName + */ + public function testIfTagCanBeRenderedUsingDefaultFormatter() + { + $fixture = new PropertyWrite('myProperty', new String_(), new Description('Description')); + $this->assertSame('@property-write string $myProperty Description', $fixture->render()); + + $fixture = new PropertyWrite('myProperty', null, new Description('Description')); + $this->assertSame('@property-write $myProperty Description', $fixture->render()); + + $fixture = new PropertyWrite('myProperty'); + $this->assertSame('@property-write $myProperty', $fixture->render()); + } + + /** + * @uses \phpDocumentor\Reflection\DocBlock\Tags\PropertyWrite::__construct + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::render + */ + public function testIfTagCanBeRenderedUsingSpecificFormatter() + { + $fixture = new PropertyWrite('myProperty'); + + $formatter = m::mock(Formatter::class); + $formatter->shouldReceive('format')->with($fixture)->andReturn('Rendered output'); + + $this->assertSame('Rendered output', $fixture->render($formatter)); + } + + /** + * @covers ::__construct + * @covers ::getVariableName + */ + public function testHasVariableName() + { + $expected = 'myProperty'; + + $fixture = new PropertyWrite($expected); + + $this->assertSame($expected, $fixture->getVariableName()); + } + + /** + * @covers ::__construct + * @covers ::getType + */ + public function testHasType() + { + $expected = new String_(); + + $fixture = new PropertyWrite('myProperty', $expected); + + $this->assertSame($expected, $fixture->getType()); + } + + /** + * @covers ::__construct + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::getDescription + * @uses \phpDocumentor\Reflection\DocBlock\Description + */ + public function testHasDescription() + { + $expected = new Description('Description'); + + $fixture = new PropertyWrite('1.0', null, $expected); + + $this->assertSame($expected, $fixture->getDescription()); + } + + /** + * @covers ::__construct + * @covers ::__toString + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @uses \phpDocumentor\Reflection\Types\String_ + */ + public function testStringRepresentationIsReturned() + { + $fixture = new PropertyWrite('myProperty', new String_(), new Description('Description')); + + $this->assertSame('string $myProperty Description', (string)$fixture); + } + + /** + * @covers ::create + * @uses \phpDocumentor\Reflection\DocBlock\Tags\PropertyWrite:: + * @uses \phpDocumentor\Reflection\DocBlock\DescriptionFactory + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @uses \phpDocumentor\Reflection\Types\Context + */ + public function testFactoryMethod() + { + $typeResolver = new TypeResolver(); + $descriptionFactory = m::mock(DescriptionFactory::class); + $context = new Context(''); + + $description = new Description('My Description'); + $descriptionFactory->shouldReceive('create')->with('My Description', $context)->andReturn($description); + + $fixture = PropertyWrite::create('string $myProperty My Description', $typeResolver, $descriptionFactory, + $context); + + $this->assertSame('string $myProperty My Description', (string)$fixture); + $this->assertSame('myProperty', $fixture->getVariableName()); + $this->assertInstanceOf(String_::class, $fixture->getType()); + $this->assertSame($description, $fixture->getDescription()); + } + + /** + * @covers ::create + * @uses \phpDocumentor\Reflection\DocBlock\Tags\PropertyWrite:: + * @uses \phpDocumentor\Reflection\TypeResolver + * @uses \phpDocumentor\Reflection\DocBlock\DescriptionFactory + * @expectedException \InvalidArgumentException + */ + public function testFactoryMethodFailsIfEmptyBodyIsGiven() + { + $descriptionFactory = m::mock(DescriptionFactory::class); + PropertyWrite::create('', new TypeResolver(), $descriptionFactory); + } + + /** + * @covers ::create + * @expectedException \InvalidArgumentException + */ + public function testFactoryMethodFailsIfBodyIsNotString() + { + PropertyWrite::create([]); + } + + /** + * @covers ::create + * @expectedException \InvalidArgumentException + */ + public function testFactoryMethodFailsIfResolverIsNull() + { + PropertyWrite::create('body'); + } + + /** + * @covers ::create + * @uses \phpDocumentor\Reflection\TypeResolver + * @expectedException \InvalidArgumentException + */ + public function testFactoryMethodFailsIfDescriptionFactoryIsNull() + { + PropertyWrite::create('body', new TypeResolver()); + } + + /** + * @covers ::__construct + * @expectedException \InvalidArgumentException + */ + public function testExceptionIsThrownIfVariableNameIsNotString() + { + new PropertyWrite([]); + } +} diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/ReturnTest.php b/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/ReturnTest.php new file mode 100644 index 00000000..2bc54391 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/ReturnTest.php @@ -0,0 +1,170 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags; + +use Mockery as m; +use phpDocumentor\Reflection\DocBlock\Description; +use phpDocumentor\Reflection\DocBlock\DescriptionFactory; +use phpDocumentor\Reflection\TypeResolver; +use phpDocumentor\Reflection\Types\Context; +use phpDocumentor\Reflection\Types\String_; + +/** + * @coversDefaultClass \phpDocumentor\Reflection\DocBlock\Tags\Return_ + * @covers :: + */ +class ReturnTest extends \PHPUnit_Framework_TestCase +{ + /** + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Return_::__construct + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::getName + */ + public function testIfCorrectTagNameIsReturned() + { + $fixture = new Return_(new String_(), new Description('Description')); + + $this->assertSame('return', $fixture->getName()); + } + + /** + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Return_::__construct + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Return_::__toString + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Formatter\PassthroughFormatter + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::render + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::getName + */ + public function testIfTagCanBeRenderedUsingDefaultFormatter() + { + $fixture = new Return_(new String_(), new Description('Description')); + + $this->assertSame('@return string Description', $fixture->render()); + } + + /** + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Return_::__construct + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::render + */ + public function testIfTagCanBeRenderedUsingSpecificFormatter() + { + $fixture = new Return_(new String_(), new Description('Description')); + + $formatter = m::mock(Formatter::class); + $formatter->shouldReceive('format')->with($fixture)->andReturn('Rendered output'); + + $this->assertSame('Rendered output', $fixture->render($formatter)); + } + + /** + * @covers ::__construct + * @covers ::getType + */ + public function testHasType() + { + $expected = new String_(); + + $fixture = new Return_($expected); + + $this->assertSame($expected, $fixture->getType()); + } + + /** + * @covers ::__construct + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::getDescription + * @uses \phpDocumentor\Reflection\DocBlock\Description + */ + public function testHasDescription() + { + $expected = new Description('Description'); + + $fixture = new Return_(new String_(), $expected); + + $this->assertSame($expected, $fixture->getDescription()); + } + + /** + * @covers ::__construct + * @covers ::__toString + * @uses \phpDocumentor\Reflection\DocBlock\Description + */ + public function testStringRepresentationIsReturned() + { + $fixture = new Return_(new String_(), new Description('Description')); + + $this->assertSame('string Description', (string)$fixture); + } + + /** + * @covers ::create + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Return_:: + * @uses \phpDocumentor\Reflection\DocBlock\DescriptionFactory + * @uses \phpDocumentor\Reflection\TypeResolver + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @uses \phpDocumentor\Reflection\Types\String_ + * @uses \phpDocumentor\Reflection\Types\Context + */ + public function testFactoryMethod() + { + $descriptionFactory = m::mock(DescriptionFactory::class); + $resolver = new TypeResolver(); + $context = new Context(''); + + $type = new String_(); + $description = new Description('My Description'); + $descriptionFactory->shouldReceive('create')->with('My Description', $context)->andReturn($description); + + $fixture = Return_::create('string My Description', $resolver, $descriptionFactory, $context); + + $this->assertSame('string My Description', (string)$fixture); + $this->assertEquals($type, $fixture->getType()); + $this->assertSame($description, $fixture->getDescription()); + } + + /** + * @covers ::create + * @expectedException \InvalidArgumentException + */ + public function testFactoryMethodFailsIfBodyIsNotString() + { + $this->assertNull(Return_::create([])); + } + + /** + * @covers ::create + * @expectedException \InvalidArgumentException + */ + public function testFactoryMethodFailsIfBodyIsNotEmpty() + { + $this->assertNull(Return_::create('')); + } + + /** + * @covers ::create + * @expectedException \InvalidArgumentException + */ + public function testFactoryMethodFailsIfResolverIsNull() + { + Return_::create('body'); + } + + /** + * @covers ::create + * @expectedException \InvalidArgumentException + */ + public function testFactoryMethodFailsIfDescriptionFactoryIsNull() + { + Return_::create('body', new TypeResolver()); + } +} diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/SeeTest.php b/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/SeeTest.php new file mode 100644 index 00000000..8d3e3e8c --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/SeeTest.php @@ -0,0 +1,173 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags; + +use Mockery as m; +use phpDocumentor\Reflection\DocBlock\Description; +use phpDocumentor\Reflection\DocBlock\DescriptionFactory; +use phpDocumentor\Reflection\Fqsen; +use phpDocumentor\Reflection\FqsenResolver; +use phpDocumentor\Reflection\Types\Context; + +/** + * @coversDefaultClass \phpDocumentor\Reflection\DocBlock\Tags\See + * @covers :: + */ +class SeeTest extends \PHPUnit_Framework_TestCase +{ + /** + * @uses \phpDocumentor\Reflection\DocBlock\Tags\See::__construct + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::getName + */ + public function testIfCorrectTagNameIsReturned() + { + $fixture = new See(new Fqsen('\DateTime'), new Description('Description')); + + $this->assertSame('see', $fixture->getName()); + } + + /** + * @uses \phpDocumentor\Reflection\DocBlock\Tags\See::__construct + * @uses \phpDocumentor\Reflection\DocBlock\Tags\See::__toString + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Formatter\PassthroughFormatter + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::render + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::getName + */ + public function testIfTagCanBeRenderedUsingDefaultFormatter() + { + $fixture = new See(new Fqsen('\DateTime'), new Description('Description')); + + $this->assertSame('@see \DateTime Description', $fixture->render()); + } + + /** + * @uses \phpDocumentor\Reflection\DocBlock\Tags\See::__construct + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::render + */ + public function testIfTagCanBeRenderedUsingSpecificFormatter() + { + $fixture = new See(new Fqsen('\DateTime'), new Description('Description')); + + $formatter = m::mock(Formatter::class); + $formatter->shouldReceive('format')->with($fixture)->andReturn('Rendered output'); + + $this->assertSame('Rendered output', $fixture->render($formatter)); + } + + /** + * @covers ::__construct + * @covers ::getReference + */ + public function testHasReferenceToFqsen() + { + $expected = new Fqsen('\DateTime'); + + $fixture = new See($expected); + + $this->assertSame($expected, $fixture->getReference()); + } + + /** + * @covers ::__construct + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::getDescription + * @uses \phpDocumentor\Reflection\DocBlock\Description + */ + public function testHasDescription() + { + $expected = new Description('Description'); + + $fixture = new See(new Fqsen('\DateTime'), $expected); + + $this->assertSame($expected, $fixture->getDescription()); + } + + /** + * @covers ::__construct + * @covers ::__toString + * @uses \phpDocumentor\Reflection\DocBlock\Description + */ + public function testStringRepresentationIsReturned() + { + $fixture = new See(new Fqsen('\DateTime'), new Description('Description')); + + $this->assertSame('\DateTime Description', (string)$fixture); + } + + /** + * @covers ::create + * @uses \phpDocumentor\Reflection\DocBlock\Tags\See:: + * @uses \phpDocumentor\Reflection\DocBlock\DescriptionFactory + * @uses \phpDocumentor\Reflection\FqsenResolver + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @uses \phpDocumentor\Reflection\Fqsen + * @uses \phpDocumentor\Reflection\Types\Context + */ + public function testFactoryMethod() + { + $descriptionFactory = m::mock(DescriptionFactory::class); + $resolver = m::mock(FqsenResolver::class); + $context = new Context(''); + + $fqsen = new Fqsen('\DateTime'); + $description = new Description('My Description'); + + $descriptionFactory + ->shouldReceive('create')->with('My Description', $context)->andReturn($description); + $resolver->shouldReceive('resolve')->with('DateTime', $context)->andReturn($fqsen); + + $fixture = See::create('DateTime My Description', $resolver, $descriptionFactory, $context); + + $this->assertSame('\DateTime My Description', (string)$fixture); + $this->assertSame($fqsen, $fixture->getReference()); + $this->assertSame($description, $fixture->getDescription()); + } + + /** + * @covers ::create + * @expectedException \InvalidArgumentException + */ + public function testFactoryMethodFailsIfBodyIsNotString() + { + $this->assertNull(See::create([])); + } + + /** + * @covers ::create + * @expectedException \InvalidArgumentException + */ + public function testFactoryMethodFailsIfBodyIsNotEmpty() + { + $this->assertNull(See::create('')); + } + + /** + * @covers ::create + * @expectedException \InvalidArgumentException + */ + public function testFactoryMethodFailsIfResolverIsNull() + { + See::create('body'); + } + + /** + * @covers ::create + * @expectedException \InvalidArgumentException + */ + public function testFactoryMethodFailsIfDescriptionFactoryIsNull() + { + See::create('body', new FqsenResolver()); + } +} diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/SinceTest.php b/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/SinceTest.php new file mode 100644 index 00000000..3f42db5d --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/SinceTest.php @@ -0,0 +1,166 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags; + +use Mockery as m; +use phpDocumentor\Reflection\DocBlock\Description; +use phpDocumentor\Reflection\DocBlock\DescriptionFactory; +use phpDocumentor\Reflection\Types\Context; + +/** + * @coversDefaultClass \phpDocumentor\Reflection\DocBlock\Tags\Since + * @covers :: + */ +class SinceTest extends \PHPUnit_Framework_TestCase +{ + /** + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Since::__construct + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::getName + */ + public function testIfCorrectTagNameIsReturned() + { + $fixture = new Since('1.0', new Description('Description')); + + $this->assertSame('since', $fixture->getName()); + } + + /** + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Since::__construct + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Since::__toString + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Formatter\PassthroughFormatter + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::render + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::getName + */ + public function testIfTagCanBeRenderedUsingDefaultFormatter() + { + $fixture = new Since('1.0', new Description('Description')); + + $this->assertSame('@since 1.0 Description', $fixture->render()); + } + + /** + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Since::__construct + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::render + */ + public function testIfTagCanBeRenderedUsingSpecificFormatter() + { + $fixture = new Since('1.0', new Description('Description')); + + $formatter = m::mock(Formatter::class); + $formatter->shouldReceive('format')->with($fixture)->andReturn('Rendered output'); + + $this->assertSame('Rendered output', $fixture->render($formatter)); + } + + /** + * @covers ::__construct + * @covers ::getVersion + */ + public function testHasVersionNumber() + { + $expected = '1.0'; + + $fixture = new Since($expected); + + $this->assertSame($expected, $fixture->getVersion()); + } + + /** + * @covers ::__construct + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::getDescription + * @uses \phpDocumentor\Reflection\DocBlock\Description + */ + public function testHasDescription() + { + $expected = new Description('Description'); + + $fixture = new Since('1.0', $expected); + + $this->assertSame($expected, $fixture->getDescription()); + } + + /** + * @covers ::__construct + * @covers ::__toString + * @uses \phpDocumentor\Reflection\DocBlock\Description + */ + public function testStringRepresentationIsReturned() + { + $fixture = new Since('1.0', new Description('Description')); + + $this->assertSame('1.0 Description', (string)$fixture); + } + + /** + * @covers ::create + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Since:: + * @uses \phpDocumentor\Reflection\DocBlock\DescriptionFactory + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @uses \phpDocumentor\Reflection\Types\Context + */ + public function testFactoryMethod() + { + $descriptionFactory = m::mock(DescriptionFactory::class); + $context = new Context(''); + + $version = '1.0'; + $description = new Description('My Description'); + + $descriptionFactory->shouldReceive('create')->with('My Description', $context)->andReturn($description); + + $fixture = Since::create('1.0 My Description', $descriptionFactory, $context); + + $this->assertSame('1.0 My Description', (string)$fixture); + $this->assertSame($version, $fixture->getVersion()); + $this->assertSame($description, $fixture->getDescription()); + } + + /** + * @covers ::create + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Since:: + * @uses \phpDocumentor\Reflection\DocBlock\DescriptionFactory + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @uses \phpDocumentor\Reflection\Types\Context + */ + public function testFactoryMethodCreatesEmptySinceTag() + { + $descriptionFactory = m::mock(DescriptionFactory::class); + $descriptionFactory->shouldReceive('create')->never(); + + $fixture = Since::create('', $descriptionFactory, new Context('')); + + $this->assertSame('', (string)$fixture); + $this->assertSame(null, $fixture->getVersion()); + $this->assertSame(null, $fixture->getDescription()); + } + + /** + * @covers ::create + * @expectedException \InvalidArgumentException + */ + public function testFactoryMethodFailsIfSinceIsNotString() + { + $this->assertNull(Since::create([])); + } + + /** + * @covers ::create + */ + public function testFactoryMethodReturnsNullIfBodyDoesNotMatchRegex() + { + $this->assertNull(Since::create('dkhf<')); + } +} diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/SourceTest.php b/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/SourceTest.php new file mode 100644 index 00000000..cbf01f65 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/SourceTest.php @@ -0,0 +1,199 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags; + +use Mockery as m; +use phpDocumentor\Reflection\DocBlock\Description; +use phpDocumentor\Reflection\DocBlock\DescriptionFactory; +use phpDocumentor\Reflection\TypeResolver; +use phpDocumentor\Reflection\Types\Context; +use phpDocumentor\Reflection\Types\String_; + +/** + * @coversDefaultClass \phpDocumentor\Reflection\DocBlock\Tags\Source + * @covers :: + */ +class SourceTest extends \PHPUnit_Framework_TestCase +{ + /** + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Source::__construct + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::getName + */ + public function testIfCorrectTagNameIsReturned() + { + $fixture = new Source(1, null, new Description('Description')); + + $this->assertSame('source', $fixture->getName()); + } + + /** + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Source::__construct + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Source::__toString + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Formatter\PassthroughFormatter + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::render + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::getName + */ + public function testIfTagCanBeRenderedUsingDefaultFormatter() + { + $fixture = new Source(1, 10, new Description('Description')); + $this->assertSame('@source 1 10 Description', $fixture->render()); + + $fixture = new Source(1, null, new Description('Description')); + $this->assertSame('@source 1 Description', $fixture->render()); + + $fixture = new Source(1); + $this->assertSame('@source 1', $fixture->render()); + } + + /** + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Source::__construct + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::render + */ + public function testIfTagCanBeRenderedUsingSpecificFormatter() + { + $fixture = new Source(1); + + $formatter = m::mock(Formatter::class); + $formatter->shouldReceive('format')->with($fixture)->andReturn('Rendered output'); + + $this->assertSame('Rendered output', $fixture->render($formatter)); + } + + /** + * @covers ::__construct + * @covers ::getStartingLine + */ + public function testHasStartingLine() + { + $expected = 1; + + $fixture = new Source($expected); + + $this->assertSame($expected, $fixture->getStartingLine()); + } + + /** + * @covers ::__construct + * @covers ::getLineCount + */ + public function testHasLineCount() + { + $expected = 2; + + $fixture = new Source(1, $expected); + + $this->assertSame($expected, $fixture->getLineCount()); + } + + /** + * @covers ::__construct + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::getDescription + * @uses \phpDocumentor\Reflection\DocBlock\Description + */ + public function testHasDescription() + { + $expected = new Description('Description'); + + $fixture = new Source('1', null, $expected); + + $this->assertSame($expected, $fixture->getDescription()); + } + + /** + * @covers ::__construct + * @covers ::__toString + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @uses \phpDocumentor\Reflection\Types\String_ + */ + public function testStringRepresentationIsReturned() + { + $fixture = new Source(1, 10, new Description('Description')); + + $this->assertSame('1 10 Description', (string)$fixture); + } + + /** + * @covers ::create + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Source:: + * @uses \phpDocumentor\Reflection\DocBlock\DescriptionFactory + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @uses \phpDocumentor\Reflection\Types\Context + */ + public function testFactoryMethod() + { + $descriptionFactory = m::mock(DescriptionFactory::class); + $context = new Context(''); + + $description = new Description('My Description'); + $descriptionFactory->shouldReceive('create')->with('My Description', $context)->andReturn($description); + + $fixture = Source::create('1 10 My Description', $descriptionFactory, $context); + + $this->assertSame('1 10 My Description', (string)$fixture); + $this->assertSame(1, $fixture->getStartingLine()); + $this->assertSame(10, $fixture->getLineCount()); + $this->assertSame($description, $fixture->getDescription()); + } + + /** + * @covers ::create + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Source:: + * @uses \phpDocumentor\Reflection\TypeResolver + * @uses \phpDocumentor\Reflection\DocBlock\DescriptionFactory + * @expectedException \InvalidArgumentException + */ + public function testFactoryMethodFailsIfEmptyBodyIsGiven() + { + $descriptionFactory = m::mock(DescriptionFactory::class); + Source::create('', $descriptionFactory); + } + + /** + * @covers ::create + * @expectedException \InvalidArgumentException + */ + public function testFactoryMethodFailsIfBodyIsNotString() + { + Source::create([]); + } + + /** + * @covers ::create + * @uses \phpDocumentor\Reflection\TypeResolver + * @expectedException \InvalidArgumentException + */ + public function testFactoryMethodFailsIfDescriptionFactoryIsNull() + { + Source::create('1'); + } + + /** + * @covers ::__construct + * @expectedException \InvalidArgumentException + */ + public function testExceptionIsThrownIfStartingLineIsNotInteger() + { + new Source('blabla'); + } + + /** + * @covers ::__construct + * @expectedException \InvalidArgumentException + */ + public function testExceptionIsThrownIfLineCountIsNotIntegerOrNull() + { + new Source('1', []); + } +} diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/ThrowsTest.php b/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/ThrowsTest.php new file mode 100644 index 00000000..657d6ca5 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/ThrowsTest.php @@ -0,0 +1,170 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags; + +use Mockery as m; +use phpDocumentor\Reflection\DocBlock\Description; +use phpDocumentor\Reflection\DocBlock\DescriptionFactory; +use phpDocumentor\Reflection\TypeResolver; +use phpDocumentor\Reflection\Types\Context; +use phpDocumentor\Reflection\Types\String_; + +/** + * @coversDefaultClass \phpDocumentor\Reflection\DocBlock\Tags\Throws + * @covers :: + */ +class ThrowsTest extends \PHPUnit_Framework_TestCase +{ + /** + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Throws::__construct + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::getName + */ + public function testIfCorrectTagNameIsReturned() + { + $fixture = new Throws(new String_(), new Description('Description')); + + $this->assertSame('throws', $fixture->getName()); + } + + /** + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Throws::__construct + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Throws::__toString + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Formatter\PassthroughFormatter + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::render + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::getName + */ + public function testIfTagCanBeRenderedUsingDefaultFormatter() + { + $fixture = new Throws(new String_(), new Description('Description')); + + $this->assertSame('@throws string Description', $fixture->render()); + } + + /** + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Throws::__construct + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::render + */ + public function testIfTagCanBeRenderedUsingSpecificFormatter() + { + $fixture = new Throws(new String_(), new Description('Description')); + + $formatter = m::mock(Formatter::class); + $formatter->shouldReceive('format')->with($fixture)->andReturn('Rendered output'); + + $this->assertSame('Rendered output', $fixture->render($formatter)); + } + + /** + * @covers ::__construct + * @covers ::getType + */ + public function testHasType() + { + $expected = new String_(); + + $fixture = new Throws($expected); + + $this->assertSame($expected, $fixture->getType()); + } + + /** + * @covers ::__construct + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::getDescription + * @uses \phpDocumentor\Reflection\DocBlock\Description + */ + public function testHasDescription() + { + $expected = new Description('Description'); + + $fixture = new Throws(new String_(), $expected); + + $this->assertSame($expected, $fixture->getDescription()); + } + + /** + * @covers ::__construct + * @covers ::__toString + * @uses \phpDocumentor\Reflection\DocBlock\Description + */ + public function testStringRepresentationIsReturned() + { + $fixture = new Throws(new String_(), new Description('Description')); + + $this->assertSame('string Description', (string)$fixture); + } + + /** + * @covers ::create + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Throws:: + * @uses \phpDocumentor\Reflection\DocBlock\DescriptionFactory + * @uses \phpDocumentor\Reflection\TypeResolver + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @uses \phpDocumentor\Reflection\Types\String_ + * @uses \phpDocumentor\Reflection\Types\Context + */ + public function testFactoryMethod() + { + $descriptionFactory = m::mock(DescriptionFactory::class); + $resolver = new TypeResolver(); + $context = new Context(''); + + $type = new String_(); + $description = new Description('My Description'); + $descriptionFactory->shouldReceive('create')->with('My Description', $context)->andReturn($description); + + $fixture = Throws::create('string My Description', $resolver, $descriptionFactory, $context); + + $this->assertSame('string My Description', (string)$fixture); + $this->assertEquals($type, $fixture->getType()); + $this->assertSame($description, $fixture->getDescription()); + } + + /** + * @covers ::create + * @expectedException \InvalidArgumentException + */ + public function testFactoryMethodFailsIfBodyIsNotString() + { + $this->assertNull(Throws::create([])); + } + + /** + * @covers ::create + * @expectedException \InvalidArgumentException + */ + public function testFactoryMethodFailsIfBodyIsNotEmpty() + { + $this->assertNull(Throws::create('')); + } + + /** + * @covers ::create + * @expectedException \InvalidArgumentException + */ + public function testFactoryMethodFailsIfResolverIsNull() + { + Throws::create('body'); + } + + /** + * @covers ::create + * @expectedException \InvalidArgumentException + */ + public function testFactoryMethodFailsIfDescriptionFactoryIsNull() + { + Throws::create('body', new TypeResolver()); + } +} diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/UsesTest.php b/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/UsesTest.php new file mode 100644 index 00000000..419f7e36 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/UsesTest.php @@ -0,0 +1,174 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags; + +use Mockery as m; +use phpDocumentor\Reflection\DocBlock\Description; +use phpDocumentor\Reflection\DocBlock\DescriptionFactory; +use phpDocumentor\Reflection\Fqsen; +use phpDocumentor\Reflection\FqsenResolver; +use phpDocumentor\Reflection\Types\Context; + +/** + * @coversDefaultClass \phpDocumentor\Reflection\DocBlock\Tags\Uses + * @covers :: + */ +class UsesTest extends \PHPUnit_Framework_TestCase +{ + /** + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Uses::__construct + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::getName + */ + public function testIfCorrectTagNameIsReturned() + { + $fixture = new Uses(new Fqsen('\DateTime'), new Description('Description')); + + $this->assertSame('uses', $fixture->getName()); + } + + /** + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Uses::__construct + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Uses::__toString + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Formatter\PassthroughFormatter + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::render + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::getName + */ + public function testIfTagCanBeRenderedUsingDefaultFormatter() + { + $fixture = new Uses(new Fqsen('\DateTime'), new Description('Description')); + + $this->assertSame('@uses \DateTime Description', $fixture->render()); + } + + /** + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Uses::__construct + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::render + */ + public function testIfTagCanBeRenderedUsingSpecificFormatter() + { + $fixture = new Uses(new Fqsen('\DateTime'), new Description('Description')); + + $formatter = m::mock(Formatter::class); + $formatter->shouldReceive('format')->with($fixture)->andReturn('Rendered output'); + + $this->assertSame('Rendered output', $fixture->render($formatter)); + } + + /** + * @covers ::__construct + * @covers ::getReference + */ + public function testHasReferenceToFqsen() + { + $expected = new Fqsen('\DateTime'); + + $fixture = new Uses($expected); + + $this->assertSame($expected, $fixture->getReference()); + } + + /** + * @covers ::__construct + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::getDescription + * @uses \phpDocumentor\Reflection\DocBlock\Description + */ + public function testHasDescription() + { + $expected = new Description('Description'); + + $fixture = new Uses(new Fqsen('\DateTime'), $expected); + + $this->assertSame($expected, $fixture->getDescription()); + } + + /** + * @covers ::__construct + * @covers ::__toString + * @uses \phpDocumentor\Reflection\DocBlock\Description + */ + public function testStringRepresentationIsReturned() + { + $fixture = new Uses(new Fqsen('\DateTime'), new Description('Description')); + + $this->assertSame('\DateTime Description', (string)$fixture); + } + + /** + * @covers ::create + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Uses:: + * @uses \phpDocumentor\Reflection\DocBlock\DescriptionFactory + * @uses \phpDocumentor\Reflection\FqsenResolver + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @uses \phpDocumentor\Reflection\Fqsen + * @uses \phpDocumentor\Reflection\Types\Context + */ + public function testFactoryMethod() + { + $descriptionFactory = m::mock(DescriptionFactory::class); + $resolver = m::mock(FqsenResolver::class); + $context = new Context(''); + + $fqsen = new Fqsen('\DateTime'); + $description = new Description('My Description'); + + $descriptionFactory + ->shouldReceive('create')->with('My Description', $context)->andReturn($description) + ; + $resolver->shouldReceive('resolve')->with('DateTime', $context)->andReturn($fqsen); + + $fixture = Uses::create('DateTime My Description', $resolver, $descriptionFactory, $context); + + $this->assertSame('\DateTime My Description', (string)$fixture); + $this->assertSame($fqsen, $fixture->getReference()); + $this->assertSame($description, $fixture->getDescription()); + } + + /** + * @covers ::create + * @expectedException \InvalidArgumentException + */ + public function testFactoryMethodFailsIfBodyIsNotString() + { + $this->assertNull(Uses::create([])); + } + + /** + * @covers ::create + * @expectedException \InvalidArgumentException + */ + public function testFactoryMethodFailsIfBodyIsNotEmpty() + { + $this->assertNull(Uses::create('')); + } + + /** + * @covers ::create + * @expectedException \InvalidArgumentException + */ + public function testFactoryMethodFailsIfResolverIsNull() + { + Uses::create('body'); + } + + /** + * @covers ::create + * @expectedException \InvalidArgumentException + */ + public function testFactoryMethodFailsIfDescriptionFactoryIsNull() + { + Uses::create('body', new FqsenResolver()); + } +} diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/VarTest.php b/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/VarTest.php new file mode 100644 index 00000000..34f290ad --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/VarTest.php @@ -0,0 +1,200 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags; + +use Mockery as m; +use phpDocumentor\Reflection\DocBlock\Description; +use phpDocumentor\Reflection\DocBlock\DescriptionFactory; +use phpDocumentor\Reflection\TypeResolver; +use phpDocumentor\Reflection\Types\Context; +use phpDocumentor\Reflection\Types\String_; + +/** + * @coversDefaultClass \phpDocumentor\Reflection\DocBlock\Tags\Var_ + * @covers :: + */ +class VarTest extends \PHPUnit_Framework_TestCase +{ + /** + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Var_::__construct + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::getName + */ + public function testIfCorrectTagNameIsReturned() + { + $fixture = new Var_('myVariable', null, new Description('Description')); + + $this->assertSame('var', $fixture->getName()); + } + + /** + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Var_::__construct + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Var_::__toString + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Formatter\PassthroughFormatter + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::render + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::getName + */ + public function testIfTagCanBeRenderedUsingDefaultFormatter() + { + $fixture = new Var_('myVariable', new String_(), new Description('Description')); + $this->assertSame('@var string $myVariable Description', $fixture->render()); + + $fixture = new Var_('myVariable', null, new Description('Description')); + $this->assertSame('@var $myVariable Description', $fixture->render()); + + $fixture = new Var_('myVariable'); + $this->assertSame('@var $myVariable', $fixture->render()); + } + + /** + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Var_::__construct + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::render + */ + public function testIfTagCanBeRenderedUsingSpecificFormatter() + { + $fixture = new Var_('myVariable'); + + $formatter = m::mock(Formatter::class); + $formatter->shouldReceive('format')->with($fixture)->andReturn('Rendered output'); + + $this->assertSame('Rendered output', $fixture->render($formatter)); + } + + /** + * @covers ::__construct + * @covers ::getVariableName + */ + public function testHasVariableName() + { + $expected = 'myVariable'; + + $fixture = new Var_($expected); + + $this->assertSame($expected, $fixture->getVariableName()); + } + + /** + * @covers ::__construct + * @covers ::getType + */ + public function testHasType() + { + $expected = new String_(); + + $fixture = new Var_('myVariable', $expected); + + $this->assertSame($expected, $fixture->getType()); + } + + /** + * @covers ::__construct + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::getDescription + * @uses \phpDocumentor\Reflection\DocBlock\Description + */ + public function testHasDescription() + { + $expected = new Description('Description'); + + $fixture = new Var_('1.0', null, $expected); + + $this->assertSame($expected, $fixture->getDescription()); + } + + /** + * @covers ::__construct + * @covers ::__toString + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @uses \phpDocumentor\Reflection\Types\String_ + */ + public function testStringRepresentationIsReturned() + { + $fixture = new Var_('myVariable', new String_(), new Description('Description')); + + $this->assertSame('string $myVariable Description', (string)$fixture); + } + + /** + * @covers ::create + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Var_:: + * @uses \phpDocumentor\Reflection\DocBlock\DescriptionFactory + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @uses \phpDocumentor\Reflection\Types\Context + */ + public function testFactoryMethod() + { + $typeResolver = new TypeResolver(); + $descriptionFactory = m::mock(DescriptionFactory::class); + $context = new Context(''); + + $description = new Description('My Description'); + $descriptionFactory->shouldReceive('create')->with('My Description', $context)->andReturn($description); + + $fixture = Var_::create('string $myVariable My Description', $typeResolver, $descriptionFactory, $context); + + $this->assertSame('string $myVariable My Description', (string)$fixture); + $this->assertSame('myVariable', $fixture->getVariableName()); + $this->assertInstanceOf(String_::class, $fixture->getType()); + $this->assertSame($description, $fixture->getDescription()); + } + + /** + * @covers ::create + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Var_:: + * @uses \phpDocumentor\Reflection\TypeResolver + * @uses \phpDocumentor\Reflection\DocBlock\DescriptionFactory + * @expectedException \InvalidArgumentException + */ + public function testFactoryMethodFailsIfEmptyBodyIsGiven() + { + $descriptionFactory = m::mock(DescriptionFactory::class); + Var_::create('', new TypeResolver(), $descriptionFactory); + } + + /** + * @covers ::create + * @expectedException \InvalidArgumentException + */ + public function testFactoryMethodFailsIfBodyIsNotString() + { + Var_::create([]); + } + + /** + * @covers ::create + * @expectedException \InvalidArgumentException + */ + public function testFactoryMethodFailsIfResolverIsNull() + { + Var_::create('body'); + } + + /** + * @covers ::create + * @uses \phpDocumentor\Reflection\TypeResolver + * @expectedException \InvalidArgumentException + */ + public function testFactoryMethodFailsIfDescriptionFactoryIsNull() + { + Var_::create('body', new TypeResolver()); + } + + /** + * @covers ::__construct + * @expectedException \InvalidArgumentException + */ + public function testExceptionIsThrownIfVariableNameIsNotString() + { + new Var_([]); + } +} diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/VersionTest.php b/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/VersionTest.php new file mode 100644 index 00000000..5c487fd3 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlock/Tags/VersionTest.php @@ -0,0 +1,166 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags; + +use Mockery as m; +use phpDocumentor\Reflection\DocBlock\Description; +use phpDocumentor\Reflection\DocBlock\DescriptionFactory; +use phpDocumentor\Reflection\Types\Context; + +/** + * @coversDefaultClass \phpDocumentor\Reflection\DocBlock\Tags\Version + * @covers :: + */ +class VersionTest extends \PHPUnit_Framework_TestCase +{ + /** + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Version::__construct + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::getName + */ + public function testIfCorrectTagNameIsReturned() + { + $fixture = new Version('1.0', new Description('Description')); + + $this->assertSame('version', $fixture->getName()); + } + + /** + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Version::__construct + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Version::__toString + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Formatter\PassthroughFormatter + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::render + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::getName + */ + public function testIfTagCanBeRenderedUsingDefaultFormatter() + { + $fixture = new Version('1.0', new Description('Description')); + + $this->assertSame('@version 1.0 Description', $fixture->render()); + } + + /** + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Version::__construct + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::render + */ + public function testIfTagCanBeRenderedUsingSpecificFormatter() + { + $fixture = new Version('1.0', new Description('Description')); + + $formatter = m::mock(Formatter::class); + $formatter->shouldReceive('format')->with($fixture)->andReturn('Rendered output'); + + $this->assertSame('Rendered output', $fixture->render($formatter)); + } + + /** + * @covers ::__construct + * @covers ::getVersion + */ + public function testHasVersionNumber() + { + $expected = '1.0'; + + $fixture = new Version($expected); + + $this->assertSame($expected, $fixture->getVersion()); + } + + /** + * @covers ::__construct + * @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::getDescription + * @uses \phpDocumentor\Reflection\DocBlock\Description + */ + public function testHasDescription() + { + $expected = new Description('Description'); + + $fixture = new Version('1.0', $expected); + + $this->assertSame($expected, $fixture->getDescription()); + } + + /** + * @covers ::__construct + * @covers ::__toString + * @uses \phpDocumentor\Reflection\DocBlock\Description + */ + public function testStringRepresentationIsReturned() + { + $fixture = new Version('1.0', new Description('Description')); + + $this->assertSame('1.0 Description', (string)$fixture); + } + + /** + * @covers ::create + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Version:: + * @uses \phpDocumentor\Reflection\DocBlock\DescriptionFactory + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @uses \phpDocumentor\Reflection\Types\Context + */ + public function testFactoryMethod() + { + $descriptionFactory = m::mock(DescriptionFactory::class); + $context = new Context(''); + + $version = '1.0'; + $description = new Description('My Description'); + + $descriptionFactory->shouldReceive('create')->with('My Description', $context)->andReturn($description); + + $fixture = Version::create('1.0 My Description', $descriptionFactory, $context); + + $this->assertSame('1.0 My Description', (string)$fixture); + $this->assertSame($version, $fixture->getVersion()); + $this->assertSame($description, $fixture->getDescription()); + } + + /** + * @covers ::create + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Version:: + * @uses \phpDocumentor\Reflection\DocBlock\DescriptionFactory + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @uses \phpDocumentor\Reflection\Types\Context + */ + public function testFactoryMethodCreatesEmptyVersionTag() + { + $descriptionFactory = m::mock(DescriptionFactory::class); + $descriptionFactory->shouldReceive('create')->never(); + + $fixture = Version::create('', $descriptionFactory, new Context('')); + + $this->assertSame('', (string)$fixture); + $this->assertSame(null, $fixture->getVersion()); + $this->assertSame(null, $fixture->getDescription()); + } + + /** + * @covers ::create + * @expectedException \InvalidArgumentException + */ + public function testFactoryMethodFailsIfVersionIsNotString() + { + $this->assertNull(Version::create([])); + } + + /** + * @covers ::create + */ + public function testFactoryMethodReturnsNullIfBodyDoesNotMatchRegex() + { + $this->assertNull(Version::create('dkhf<')); + } +} diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlockFactoryTest.php b/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlockFactoryTest.php new file mode 100644 index 00000000..f1261b65 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlockFactoryTest.php @@ -0,0 +1,290 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection; + +use Mockery as m; +use phpDocumentor\Reflection\DocBlock\Description; +use phpDocumentor\Reflection\DocBlock\DescriptionFactory; +use phpDocumentor\Reflection\DocBlock\Tag; +use phpDocumentor\Reflection\DocBlock\TagFactory; +use phpDocumentor\Reflection\DocBlock\Tags\Param; +use phpDocumentor\Reflection\Types\Context; + +/** + * @coversDefaultClass phpDocumentor\Reflection\DocBlockFactory + * @covers :: + * @uses \Webmozart\Assert\Assert + * @uses phpDocumentor\Reflection\DocBlock + */ +class DocBlockFactoryTest extends \PHPUnit_Framework_TestCase +{ + /** + * @covers ::__construct + * @covers ::createInstance + * @uses \phpDocumentor\Reflection\DocBlock\StandardTagFactory + * @uses \phpDocumentor\Reflection\DocBlock\DescriptionFactory + */ + public function testCreateFactoryUsingFactoryMethod() + { + $fixture = DocBlockFactory::createInstance(); + + $this->assertInstanceOf(DocBlockFactory::class, $fixture); + } + + /** + * @covers ::__construct + * @covers ::create + * @uses phpDocumentor\Reflection\DocBlock\Description + */ + public function testCreateDocBlockFromReflection() + { + $fixture = new DocBlockFactory(m::mock(DescriptionFactory::class), m::mock(TagFactory::class)); + + $docBlock = '/** This is a DocBlock */'; + $classReflector = m::mock(\ReflectionClass::class); + $classReflector->shouldReceive('getDocComment')->andReturn($docBlock); + $docblock = $fixture->create($classReflector); + + $this->assertInstanceOf(DocBlock::class, $docblock); + $this->assertSame('This is a DocBlock', $docblock->getSummary()); + $this->assertEquals(new Description(''), $docblock->getDescription()); + $this->assertSame([], $docblock->getTags()); + $this->assertEquals(new Context(''), $docblock->getContext()); + $this->assertNull($docblock->getLocation()); + } + + /** + * @covers ::__construct + * @covers ::create + * @uses phpDocumentor\Reflection\DocBlock\Description + */ + public function testCreateDocBlockFromStringWithDocComment() + { + $fixture = new DocBlockFactory(m::mock(DescriptionFactory::class), m::mock(TagFactory::class)); + + $docblock = $fixture->create('/** This is a DocBlock */'); + + $this->assertInstanceOf(DocBlock::class, $docblock); + $this->assertSame('This is a DocBlock', $docblock->getSummary()); + $this->assertEquals(new Description(''), $docblock->getDescription()); + $this->assertSame([], $docblock->getTags()); + $this->assertEquals(new Context(''), $docblock->getContext()); + $this->assertNull($docblock->getLocation()); + } + + /** + * @covers ::create + * @covers ::__construct + * @uses phpDocumentor\Reflection\DocBlock\Description + */ + public function testCreateDocBlockFromStringWithoutDocComment() + { + $fixture = new DocBlockFactory(m::mock(DescriptionFactory::class), m::mock(TagFactory::class)); + + $docblock = $fixture->create('This is a DocBlock'); + + $this->assertInstanceOf(DocBlock::class, $docblock); + $this->assertSame('This is a DocBlock', $docblock->getSummary()); + $this->assertEquals(new Description(''), $docblock->getDescription()); + $this->assertSame([], $docblock->getTags()); + $this->assertEquals(new Context(''), $docblock->getContext()); + $this->assertNull($docblock->getLocation()); + } + + /** + * @covers ::__construct + * @covers ::create + * @uses phpDocumentor\Reflection\DocBlock\DescriptionFactory + * @uses phpDocumentor\Reflection\DocBlock\Description + * @dataProvider provideSummaryAndDescriptions + */ + public function testSummaryAndDescriptionAreSeparated($given, $summary, $description) + { + $tagFactory = m::mock(TagFactory::class); + $fixture = new DocBlockFactory(new DescriptionFactory($tagFactory), $tagFactory); + + $docblock = $fixture->create($given); + + $this->assertSame($summary, $docblock->getSummary()); + $this->assertEquals(new Description($description), $docblock->getDescription()); + } + + /** + * @covers ::__construct + * @covers ::create + * @uses phpDocumentor\Reflection\DocBlock\DescriptionFactory + * @uses phpDocumentor\Reflection\DocBlock\Description + */ + public function testDescriptionsRetainFormatting() + { + $tagFactory = m::mock(TagFactory::class); + $fixture = new DocBlockFactory(new DescriptionFactory($tagFactory), $tagFactory); + + $given = <<create($given); + + $this->assertEquals(new Description($description), $docblock->getDescription()); + } + + /** + * @covers ::__construct + * @covers ::create + * @uses phpDocumentor\Reflection\DocBlock\DescriptionFactory + * @uses phpDocumentor\Reflection\DocBlock\Description + */ + public function testTagsAreInterpretedUsingFactory() + { + $tagString = << This is with + multiline description. +TAG; + + $tag = m::mock(Tag::class); + $tagFactory = m::mock(TagFactory::class); + $tagFactory->shouldReceive('create')->with($tagString, m::type(Context::class))->andReturn($tag); + + $fixture = new DocBlockFactory(new DescriptionFactory($tagFactory), $tagFactory); + + $given = << This is with + * multiline description. + */ +DOCBLOCK; + + $docblock = $fixture->create($given, new Context('')); + + $this->assertEquals([$tag], $docblock->getTags()); + } + + public function provideSummaryAndDescriptions() + { + return [ + ['This is a DocBlock', 'This is a DocBlock', ''], + [ + 'This is a DocBlock. This should still be summary.', + 'This is a DocBlock. This should still be summary.', + '' + ], + [ + <<shouldReceive('create')->with(m::any(), $context)->andReturn(new Param('param')); + $docblock = $fixture->create('/** @param MyType $param */', $context); + } + + /** + * @covers ::__construct + * @covers ::create + * + * @uses phpDocumentor\Reflection\DocBlock\DescriptionFactory + * @uses phpDocumentor\Reflection\DocBlock\Description + */ + public function testTagsAreFilteredForNullValues() + { + $tagString = << This is with + multiline description. +TAG; + + $tagFactory = m::mock(TagFactory::class); + $tagFactory->shouldReceive('create')->with($tagString, m::any())->andReturn(null); + + $fixture = new DocBlockFactory(new DescriptionFactory($tagFactory), $tagFactory); + + $given = << This is with + * multiline description. + */ +DOCBLOCK; + + $docblock = $fixture->create($given, new Context('')); + + $this->assertEquals([], $docblock->getTags()); + } +} diff --git a/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlockTest.php b/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlockTest.php new file mode 100644 index 00000000..4a8d4ded --- /dev/null +++ b/src/composer/vendor/phpdocumentor/reflection-docblock/tests/unit/DocBlockTest.php @@ -0,0 +1,252 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection; + +use Mockery as m; +use phpDocumentor\Reflection\Types\Context; + +/** + * @coversDefaultClass phpDocumentor\Reflection\DocBlock + * @covers :: + * @uses \Webmozart\Assert\Assert + */ +class DocBlockTest extends \PHPUnit_Framework_TestCase +{ + /** + * @covers ::__construct + * @covers ::getSummary + * + * @uses \phpDocumentor\Reflection\DocBlock\Description + */ + public function testDocBlockCanHaveASummary() + { + $summary = 'This is a summary'; + + $fixture = new DocBlock($summary); + + $this->assertSame($summary, $fixture->getSummary()); + } + + /** + * @covers ::__construct + * + * @expectedException \InvalidArgumentException + */ + public function testExceptionIsThrownIfSummaryIsNotAString() + { + new DocBlock([]); + } + + /** + * @covers ::__construct + * + * @expectedException \InvalidArgumentException + */ + public function testExceptionIsThrownIfTemplateStartIsNotABoolean() + { + new DocBlock('', null, [], null, null, ['is not boolean']); + } + + /** + * @covers ::__construct + * + * @expectedException \InvalidArgumentException + */ + public function testExceptionIsThrownIfTemplateEndIsNotABoolean() + { + new DocBlock('', null, [], null, null, false, ['is not boolean']); + } + + /** + * @covers ::__construct + * @covers ::getDescription + * + * @uses \phpDocumentor\Reflection\DocBlock\Description + */ + public function testDocBlockCanHaveADescription() + { + $description = new DocBlock\Description(''); + + $fixture = new DocBlock('', $description); + + $this->assertSame($description, $fixture->getDescription()); + } + + /** + * @covers ::__construct + * @covers ::getTags + * + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @uses \phpDocumentor\Reflection\DocBlock\Tag + */ + public function testDocBlockCanHaveTags() + { + $tags = [ + m::mock(DocBlock\Tag::class) + ]; + + $fixture = new DocBlock('', null, $tags); + + $this->assertSame($tags, $fixture->getTags()); + } + + /** + * @covers ::__construct + * @covers ::getTags + * + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @uses \phpDocumentor\Reflection\DocBlock\Tag + * + * @expectedException \InvalidArgumentException + */ + public function testDocBlockAllowsOnlyTags() + { + $tags = [ + null + ]; + + $fixture = new DocBlock('', null, $tags); + } + + /** + * @covers ::__construct + * @covers ::getTagsByName + * + * @uses \phpDocumentor\Reflection\DocBlock::getTags + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @uses \phpDocumentor\Reflection\DocBlock\Tag + */ + public function testFindTagsInDocBlockByName() + { + $tag1 = m::mock(DocBlock\Tag::class); + $tag2 = m::mock(DocBlock\Tag::class); + $tag3 = m::mock(DocBlock\Tag::class); + $tags = [$tag1, $tag2, $tag3]; + + $tag1->shouldReceive('getName')->andReturn('abc'); + $tag2->shouldReceive('getName')->andReturn('abcd'); + $tag3->shouldReceive('getName')->andReturn('ab'); + + $fixture = new DocBlock('', null, $tags); + + $this->assertSame([$tag2], $fixture->getTagsByName('abcd')); + $this->assertSame([], $fixture->getTagsByName('Ebcd')); + } + + /** + * @covers ::__construct + * @covers ::getTagsByName + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @expectedException \InvalidArgumentException + */ + public function testExceptionIsThrownIfNameForTagsIsNotString() + { + $fixture = new DocBlock(); + $fixture->getTagsByName([]); + } + + /** + * @covers ::__construct + * @covers ::hasTag + * + * @uses \phpDocumentor\Reflection\DocBlock::getTags + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @uses \phpDocumentor\Reflection\DocBlock\Tag + */ + public function testCheckIfThereAreTagsWithAGivenName() + { + $tag1 = m::mock(DocBlock\Tag::class); + $tag2 = m::mock(DocBlock\Tag::class); + $tag3 = m::mock(DocBlock\Tag::class); + $tags = [$tag1, $tag2, $tag3]; + + $tag1->shouldReceive('getName')->twice()->andReturn('abc'); + $tag2->shouldReceive('getName')->twice()->andReturn('abcd'); + $tag3->shouldReceive('getName')->once(); + + $fixture = new DocBlock('', null, $tags); + + $this->assertTrue($fixture->hasTag('abcd')); + $this->assertFalse($fixture->hasTag('Ebcd')); + } + + /** + * @covers ::__construct + * @covers ::hasTag + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @expectedException \InvalidArgumentException + */ + public function testExceptionIsThrownIfNameForCheckingTagsIsNotString() + { + $fixture = new DocBlock(); + $fixture->hasTag([]); + } + + /** + * @covers ::__construct + * @covers ::getContext + * + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @uses \phpDocumentor\Reflection\Types\Context + */ + public function testDocBlockKnowsInWhichNamespaceItIsAndWhichAliasesThereAre() + { + $context = new Context(''); + + $fixture = new DocBlock('', null, [], $context); + + $this->assertSame($context, $fixture->getContext()); + } + + /** + * @covers ::__construct + * @covers ::getLocation + * + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @uses \phpDocumentor\Reflection\Location + */ + public function testDocBlockKnowsAtWhichLineItIs() + { + $location = new Location(10); + + $fixture = new DocBlock('', null, [], null, $location); + + $this->assertSame($location, $fixture->getLocation()); + } + + /** + * @covers ::__construct + * @covers ::isTemplateStart + * + * @uses \phpDocumentor\Reflection\DocBlock\Description + */ + public function testDocBlockKnowsIfItIsTheStartOfADocBlockTemplate() + { + $fixture = new DocBlock('', null, [], null, null, true); + + $this->assertTrue($fixture->isTemplateStart()); + } + + /** + * @covers ::__construct + * @covers ::isTemplateEnd + * + * @uses \phpDocumentor\Reflection\DocBlock\Description + */ + public function testDocBlockKnowsIfItIsTheEndOfADocBlockTemplate() + { + $fixture = new DocBlock('', null, [], null, null, false, true); + + $this->assertTrue($fixture->isTemplateEnd()); + } +} diff --git a/src/composer/vendor/phpdocumentor/type-resolver/.gitignore b/src/composer/vendor/phpdocumentor/type-resolver/.gitignore new file mode 100644 index 00000000..82cfc4e9 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/type-resolver/.gitignore @@ -0,0 +1,3 @@ +.idea +composer.lock +vendor diff --git a/src/composer/vendor/phpdocumentor/type-resolver/.scrutinizer.yml b/src/composer/vendor/phpdocumentor/type-resolver/.scrutinizer.yml new file mode 100644 index 00000000..7d7372a8 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/type-resolver/.scrutinizer.yml @@ -0,0 +1,31 @@ +before_commands: + - "composer install --no-dev --prefer-source" + +tools: + external_code_coverage: true + php_code_sniffer: + config: + standard: PSR2 + filter: + paths: ["src/*", "tests/*"] + php_cpd: + enabled: true + excluded_dirs: ["tests", "vendor"] + php_loc: + enabled: true + excluded_dirs: ["tests", "vendor"] + php_mess_detector: + enabled: true + config: + ruleset: phpmd.xml.dist + design_rules: { eval_expression: false } + filter: + paths: ["src/*"] + php_pdepend: + enabled: true + excluded_dirs: ["tests", "vendor"] + php_analyzer: + enabled: true + filter: + paths: ["src/*", "tests/*"] + sensiolabs_security_checker: true diff --git a/src/composer/vendor/phpdocumentor/type-resolver/.travis.yml b/src/composer/vendor/phpdocumentor/type-resolver/.travis.yml new file mode 100644 index 00000000..c882b141 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/type-resolver/.travis.yml @@ -0,0 +1,34 @@ +language: php +php: + - 5.5 + - 5.6 + - 7.0 + - hhvm + - nightly + +matrix: + allow_failures: + - php: + - hhvm + - nightly + +cache: + directories: + - $HOME/.composer/cache + +script: + - vendor/bin/phpunit --coverage-clover=coverage.clover -v + - composer update --no-interaction --prefer-source + - vendor/bin/phpunit -v + +before_script: + - composer install --no-interaction + +after_script: + - if [ $TRAVIS_PHP_VERSION = '5.6' ]; then wget https://scrutinizer-ci.com/ocular.phar; php ocular.phar code-coverage:upload --format=php-clover coverage.clover; fi + +notifications: + irc: "irc.freenode.org#phpdocumentor" + email: + - me@mikevanriel.com + - ashnazg@php.net diff --git a/src/composer/vendor/phpdocumentor/type-resolver/LICENSE b/src/composer/vendor/phpdocumentor/type-resolver/LICENSE new file mode 100644 index 00000000..792e4040 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/type-resolver/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2010 Mike van Riel + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/src/composer/vendor/phpdocumentor/type-resolver/README.md b/src/composer/vendor/phpdocumentor/type-resolver/README.md new file mode 100644 index 00000000..ca8147bc --- /dev/null +++ b/src/composer/vendor/phpdocumentor/type-resolver/README.md @@ -0,0 +1,169 @@ +TypeResolver and FqsenResolver +============================== + +The specification on types in DocBlocks (PSR-5) describes various keywords and special constructs +but also how to statically resolve the partial name of a Class into a Fully Qualified Class Name (FQCN). + +PSR-5 also introduces an additional way to describe deeper elements than Classes, Interfaces and Traits +called the Fully Qualified Structural Element Name (FQSEN). Using this it is possible to refer to methods, +properties and class constants but also functions and global constants. + +This package provides two Resolvers that are capable of + +1. Returning a series of Value Object for given expression while resolving any partial class names, and +2. Returning an FQSEN object after resolving any partial Structural Element Names into Fully Qualified Structural + Element names. + +## Installing + +The easiest way to install this library is with [Composer](https://getcomposer.org) using the following command: + + $ composer require phpdocumentor/type-resolver + +## Examples + +Ready to dive in and don't want to read through all that text below? Just consult the [examples](examples) folder and +check which type of action that your want to accomplish. + +## On Types and Element Names + +This component can be used in one of two ways + +1. To resolve a Type or +2. To resolve a Fully Qualified Structural Element Name + +The big difference between these two is in the number of things it can resolve. + +The TypeResolver can resolve: + +- a php primitive or pseudo-primitive such as a string or void (`@var string` or `@return void`). +- a composite such as an array of string (`@var string[]`). +- a compound such as a string or integer (`@var string|integer`). +- an object or interface such as the TypeResolver class (`@var TypeResolver` + or `@var \phpDocumentor\Reflection\TypeResolver`) + + > please note that if you want to pass partial class names that additional steps are necessary, see the + > chapter `Resolving partial classes and FQSENs` for more information. + +Where the FqsenResolver can resolve: + +- Constant expressions (i.e. `@see \MyNamespace\MY_CONSTANT`) +- Function expressions (i.e. `@see \MyNamespace\myFunction()`) +- Class expressions (i.e. `@see \MyNamespace\MyClass`) +- Interface expressions (i.e. `@see \MyNamespace\MyInterface`) +- Trait expressions (i.e. `@see \MyNamespace\MyTrait`) +- Class constant expressions (i.e. `@see \MyNamespace\MyClass::MY_CONSTANT`) +- Property expressions (i.e. `@see \MyNamespace\MyClass::$myProperty`) +- Method expressions (i.e. `@see \MyNamespace\MyClass::myMethod()`) + +## Resolving a type + +In order to resolve a type you will have to instantiate the class `\phpDocumentor\Reflection\TypeResolver` +and call its `resolve` method like this: + + $typeResolver = new \phpDocumentor\Reflection\TypeResolver(); + $type = $typeResolver->resolve('string|integer'); + +In this example you will receive a Value Object of class `\phpDocumentor\Reflection\Types\Compound` that has two +elements, one of type `\phpDocumentor\Reflection\Types\String_` and one of type +`\phpDocumentor\Reflection\Types\Integer`. + +The real power of this resolver is in its capability to expand partial class names into fully qualified class names; but +in order to do that we need an additional `\phpDocumentor\Reflection\Types\Context` class that will inform the resolver +in which namespace the given expression occurs and which namespace aliases (or imports) apply. + +## Resolving an FQSEN + +A Fully Qualified Structural Element Name is a reference to another element in your code bases and can be resolved using +the `\phpDocumentor\Reflection\FqsenResolver` class' `resolve` method, like this: + + $fqsenResolver = new \phpDocumentor\Reflection\FqsenResolver(); + $fqsen = $fqsenResolver->resolve('\phpDocumentor\Reflection\FqsenResolver::resolve()'); + +In this example we resolve a Fully Qualified Structural Element Name (meaning that it includes the full namespace, class +name and element name) and receive a Value Object of type `\phpDocumentor\Reflection\Fqsen`. + +The real power of this resolver is in its capability to expand partial element names into Fully Qualified Structural +Element Names; but in order to do that we need an additional `\phpDocumentor\Reflection\Types\Context` class that will +inform the resolver in which namespace the given expression occurs and which namespace aliases (or imports) apply. + +## Resolving partial Classes and Structural Element Names + +Perhaps the best feature of this library is that it knows how to resolve partial class names into fully qualified class +names. + +For example, you have this file: + +```php + '\phpDocumentor\Reflection\Types'] + ); + +Or by using the `\phpDocumentor\Reflection\Types\ContextFactory` to instantiate a new context based on a Reflector +object or by providing the namespace that you'd like to extract and the source code of the file in which the given +type expression occurs. + + $contextFactory = new \phpDocumentor\Reflection\Types\ContextFactory(); + $context = $contextFactory->createFromReflector(new ReflectionMethod('\My\Example\Classy', '__construct')); + +or + + $contextFactory = new \phpDocumentor\Reflection\Types\ContextFactory(); + $context = $contextFactory->createForNamespace('\My\Example', file_get_contents('My/Example/Classy.php')); + +### Using the Context + +After you have obtained a Context it is just a matter of passing it along with the `resolve` method of either Resolver +class as second argument and the Resolvers will take this into account when resolving partial names. + +To obtain the resolved class name for the `@var` tag in the example above you can do: + + $typeResolver = new \phpDocumentor\Reflection\TypeResolver(); + $type = $typeResolver->resolve('Types\Context', $context); + +When you do this you will receive an object of class `\phpDocumentor\Reflection\Types\Object_` for which you can call +the `getFqsen` method to receive a Value Object that represents the complete FQSEN. So that would be +`phpDocumentor\Reflection\Types\Context`. + +> Why is the FQSEN wrapped in another object `Object_`? +> +> The resolve method of the TypeResolver only returns object with the interface `Type` and the FQSEN is a common +> type that does not represent a Type. Also: in some cases a type can represent an "Untyped Object", meaning that it +> is an object (signified by the `object` keyword) but does not refer to a specific element using an FQSEN. + +Another example is on how to resolve the FQSEN of a method as can be seen with the `@see` tag in the example above. To +resolve that you can do the following: + + $fqsenResolver = new \phpDocumentor\Reflection\FqsenResolver(); + $type = $fqsenResolver->resolve('Classy::otherFunction()', $context); + +Because Classy is a Class in the current namespace its FQSEN will have the `My\Example` namespace and by calling the +`resolve` method of the FQSEN Resolver you will receive an `Fqsen` object that refers to +`\My\Example\Classy::otherFunction()`. diff --git a/src/composer/vendor/phpdocumentor/type-resolver/composer.json b/src/composer/vendor/phpdocumentor/type-resolver/composer.json new file mode 100644 index 00000000..abaa965d --- /dev/null +++ b/src/composer/vendor/phpdocumentor/type-resolver/composer.json @@ -0,0 +1,27 @@ +{ + "name": "phpdocumentor/type-resolver", + "type": "library", + "license": "MIT", + "authors": [ + {"name": "Mike van Riel", "email": "me@mikevanriel.com"} + ], + "require": { + "php": ">=5.5", + "phpdocumentor/reflection-common": "^1.0" + }, + "autoload": { + "psr-4": {"phpDocumentor\\Reflection\\": ["src/"]} + }, + "autoload-dev": { + "psr-4": {"phpDocumentor\\Reflection\\": ["tests/unit"]} + }, + "require-dev": { + "phpunit/phpunit": "^5.2||^4.8.24", + "mockery/mockery": "^0.9.4" + }, + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + } +} diff --git a/src/composer/vendor/phpdocumentor/type-resolver/examples/01-resolving-simple-types.php b/src/composer/vendor/phpdocumentor/type-resolver/examples/01-resolving-simple-types.php new file mode 100644 index 00000000..682b1d3d --- /dev/null +++ b/src/composer/vendor/phpdocumentor/type-resolver/examples/01-resolving-simple-types.php @@ -0,0 +1,13 @@ +resolve('string|integer')); + +// Will return the string "string|int" +var_dump((string)$typeResolver->resolve('string|integer')); diff --git a/src/composer/vendor/phpdocumentor/type-resolver/examples/02-resolving-classes.php b/src/composer/vendor/phpdocumentor/type-resolver/examples/02-resolving-classes.php new file mode 100644 index 00000000..70aa5e42 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/type-resolver/examples/02-resolving-classes.php @@ -0,0 +1,12 @@ + 'Mockery' ]); +var_dump((string)$typeResolver->resolve('Types\Resolver|m\MockInterface', $context)); diff --git a/src/composer/vendor/phpdocumentor/type-resolver/examples/03-resolving-all-elements.php b/src/composer/vendor/phpdocumentor/type-resolver/examples/03-resolving-all-elements.php new file mode 100644 index 00000000..4f4282eb --- /dev/null +++ b/src/composer/vendor/phpdocumentor/type-resolver/examples/03-resolving-all-elements.php @@ -0,0 +1,17 @@ +resolve('Types\Resolver::resolveFqsen()', $context)); + +// Property named: \phpDocumentor\Types\Types\Resolver::$keyWords +var_dump((string)$fqsenResolver->resolve('Types\Resolver::$keyWords', $context)); diff --git a/src/composer/vendor/phpdocumentor/type-resolver/examples/04-discovering-the-context-using-class-reflection.php b/src/composer/vendor/phpdocumentor/type-resolver/examples/04-discovering-the-context-using-class-reflection.php new file mode 100644 index 00000000..957c97dd --- /dev/null +++ b/src/composer/vendor/phpdocumentor/type-resolver/examples/04-discovering-the-context-using-class-reflection.php @@ -0,0 +1,30 @@ +createFromReflector(new ReflectionClass('My\\Example\\Classy')); + +// Class named: \phpDocumentor\Reflection\Types\Resolver +var_dump((string)$typeResolver->resolve('Types\Resolver', $context)); + +// String +var_dump((string)$typeResolver->resolve('string', $context)); + +// Property named: \phpDocumentor\Reflection\Types\Resolver::$keyWords +var_dump((string)$fqsenResolver->resolve('Types\Resolver::$keyWords', $context)); + +// Class named: \My\Example\string +// - Shows the difference between the FqsenResolver and TypeResolver; the FqsenResolver will assume +// that the given value is not a type but most definitely a reference to another element. This is +// because conflicts between type keywords and class names can exist and if you know a reference +// is not a type but an element you can force that keywords are resolved. +var_dump((string)$fqsenResolver->resolve('string', $context)); diff --git a/src/composer/vendor/phpdocumentor/type-resolver/examples/05-discovering-the-context-using-method-reflection.php b/src/composer/vendor/phpdocumentor/type-resolver/examples/05-discovering-the-context-using-method-reflection.php new file mode 100644 index 00000000..10c0c883 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/type-resolver/examples/05-discovering-the-context-using-method-reflection.php @@ -0,0 +1,30 @@ +createFromReflector(new ReflectionMethod('My\\Example\\Classy', '__construct')); + +// Class named: \phpDocumentor\Reflection\Types\Resolver +var_dump((string)$typeResolver->resolve('Types\Resolver', $context)); + +// String +var_dump((string)$typeResolver->resolve('string', $context)); + +// Property named: \phpDocumentor\Reflection\Types\Resolver::$keyWords +var_dump((string)$fqsenResolver->resolve('Types\Resolver::$keyWords', $context)); + +// Class named: \My\Example\string +// - Shows the difference between the FqsenResolver and TypeResolver; the FqsenResolver will assume +// that the given value is not a type but most definitely a reference to another element. This is +// because conflicts between type keywords and class names can exist and if you know a reference +// is not a type but an element you can force that keywords are resolved. +var_dump((string)$fqsenResolver->resolve('string', $context)); diff --git a/src/composer/vendor/phpdocumentor/type-resolver/examples/06-discovering-the-context-using-file-contents.php b/src/composer/vendor/phpdocumentor/type-resolver/examples/06-discovering-the-context-using-file-contents.php new file mode 100644 index 00000000..a93728c8 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/type-resolver/examples/06-discovering-the-context-using-file-contents.php @@ -0,0 +1,22 @@ +createForNamespace('My\Example', file_get_contents('Classy.php')); + +// Class named: \phpDocumentor\Reflection\Types\Resolver +var_dump((string)$typeResolver->resolve('Types\Resolver', $context)); + +// String +var_dump((string)$typeResolver->resolve('string', $context)); + +// Property named: \phpDocumentor\Reflection\Types\Resolver::$keyWords +var_dump((string)$fqsenResolver->resolve('Types\Resolver::$keyWords', $context)); diff --git a/src/composer/vendor/phpdocumentor/type-resolver/examples/Classy.php b/src/composer/vendor/phpdocumentor/type-resolver/examples/Classy.php new file mode 100644 index 00000000..0705266f --- /dev/null +++ b/src/composer/vendor/phpdocumentor/type-resolver/examples/Classy.php @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + 40 + + + diff --git a/src/composer/vendor/phpdocumentor/type-resolver/phpunit.xml.dist b/src/composer/vendor/phpdocumentor/type-resolver/phpunit.xml.dist new file mode 100644 index 00000000..3246bef4 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/type-resolver/phpunit.xml.dist @@ -0,0 +1,31 @@ + + + + + + ./tests/unit + + + + + ./src/ + + + ./examples/ + ./vendor/ + + + + + + diff --git a/src/composer/vendor/phpdocumentor/type-resolver/src/FqsenResolver.php b/src/composer/vendor/phpdocumentor/type-resolver/src/FqsenResolver.php new file mode 100644 index 00000000..a0e0041c --- /dev/null +++ b/src/composer/vendor/phpdocumentor/type-resolver/src/FqsenResolver.php @@ -0,0 +1,76 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection; + +use phpDocumentor\Reflection\Types\Context; + +class FqsenResolver +{ + /** @var string Definition of the NAMESPACE operator in PHP */ + const OPERATOR_NAMESPACE = '\\'; + + public function resolve($fqsen, Context $context = null) + { + if ($context === null) { + $context = new Context(''); + } + + if ($this->isFqsen($fqsen)) { + return new Fqsen($fqsen); + } + + return $this->resolvePartialStructuralElementName($fqsen, $context); + } + + /** + * Tests whether the given type is a Fully Qualified Structural Element Name. + * + * @param string $type + * + * @return bool + */ + private function isFqsen($type) + { + return strpos($type, self::OPERATOR_NAMESPACE) === 0; + } + + /** + * Resolves a partial Structural Element Name (i.e. `Reflection\DocBlock`) to its FQSEN representation + * (i.e. `\phpDocumentor\Reflection\DocBlock`) based on the Namespace and aliases mentioned in the Context. + * + * @param string $type + * @param Context $context + * + * @return Fqsen + */ + private function resolvePartialStructuralElementName($type, Context $context) + { + $typeParts = explode(self::OPERATOR_NAMESPACE, $type, 2); + + $namespaceAliases = $context->getNamespaceAliases(); + + // if the first segment is not an alias; prepend namespace name and return + if (!isset($namespaceAliases[$typeParts[0]])) { + $namespace = $context->getNamespace(); + if ('' !== $namespace) { + $namespace .= self::OPERATOR_NAMESPACE; + } + + return new Fqsen(self::OPERATOR_NAMESPACE . $namespace . $type); + } + + $typeParts[0] = $namespaceAliases[$typeParts[0]]; + + return new Fqsen(self::OPERATOR_NAMESPACE . implode(self::OPERATOR_NAMESPACE, $typeParts)); + } +} diff --git a/src/composer/vendor/phpdocumentor/type-resolver/src/Type.php b/src/composer/vendor/phpdocumentor/type-resolver/src/Type.php new file mode 100644 index 00000000..33ca5595 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/type-resolver/src/Type.php @@ -0,0 +1,18 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection; + +interface Type +{ + public function __toString(); +} diff --git a/src/composer/vendor/phpdocumentor/type-resolver/src/TypeResolver.php b/src/composer/vendor/phpdocumentor/type-resolver/src/TypeResolver.php new file mode 100644 index 00000000..3a68a4d3 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/type-resolver/src/TypeResolver.php @@ -0,0 +1,266 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection; + +use phpDocumentor\Reflection\Types\Array_; +use phpDocumentor\Reflection\Types\Compound; +use phpDocumentor\Reflection\Types\Context; +use phpDocumentor\Reflection\Types\Object_; + +final class TypeResolver +{ + /** @var string Definition of the ARRAY operator for types */ + const OPERATOR_ARRAY = '[]'; + + /** @var string Definition of the NAMESPACE operator in PHP */ + const OPERATOR_NAMESPACE = '\\'; + + /** @var string[] List of recognized keywords and unto which Value Object they map */ + private $keywords = array( + 'string' => 'phpDocumentor\Reflection\Types\String_', + 'int' => 'phpDocumentor\Reflection\Types\Integer', + 'integer' => 'phpDocumentor\Reflection\Types\Integer', + 'bool' => 'phpDocumentor\Reflection\Types\Boolean', + 'boolean' => 'phpDocumentor\Reflection\Types\Boolean', + 'float' => 'phpDocumentor\Reflection\Types\Float_', + 'double' => 'phpDocumentor\Reflection\Types\Float_', + 'object' => 'phpDocumentor\Reflection\Types\Object_', + 'mixed' => 'phpDocumentor\Reflection\Types\Mixed', + 'array' => 'phpDocumentor\Reflection\Types\Array_', + 'resource' => 'phpDocumentor\Reflection\Types\Resource', + 'void' => 'phpDocumentor\Reflection\Types\Void_', + 'null' => 'phpDocumentor\Reflection\Types\Null_', + 'scalar' => 'phpDocumentor\Reflection\Types\Scalar', + 'callback' => 'phpDocumentor\Reflection\Types\Callable_', + 'callable' => 'phpDocumentor\Reflection\Types\Callable_', + 'false' => 'phpDocumentor\Reflection\Types\Boolean', + 'true' => 'phpDocumentor\Reflection\Types\Boolean', + 'self' => 'phpDocumentor\Reflection\Types\Self_', + '$this' => 'phpDocumentor\Reflection\Types\This', + 'static' => 'phpDocumentor\Reflection\Types\Static_' + ); + + /** @var FqsenResolver */ + private $fqsenResolver; + + /** + * Initializes this TypeResolver with the means to create and resolve Fqsen objects. + * + * @param FqsenResolver $fqsenResolver + */ + public function __construct(FqsenResolver $fqsenResolver = null) + { + $this->fqsenResolver = $fqsenResolver ?: new FqsenResolver(); + } + + /** + * Analyzes the given type and returns the FQCN variant. + * + * When a type is provided this method checks whether it is not a keyword or + * Fully Qualified Class Name. If so it will use the given namespace and + * aliases to expand the type to a FQCN representation. + * + * This method only works as expected if the namespace and aliases are set; + * no dynamic reflection is being performed here. + * + * @param string $type The relative or absolute type. + * @param Context $context + * + * @uses Context::getNamespace() to determine with what to prefix the type name. + * @uses Context::getNamespaceAliases() to check whether the first part of the relative type name should not be + * replaced with another namespace. + * + * @return Type|null + */ + public function resolve($type, Context $context = null) + { + if (!is_string($type)) { + throw new \InvalidArgumentException( + 'Attempted to resolve type but it appeared not to be a string, received: ' . var_export($type, true) + ); + } + + $type = trim($type); + if (!$type) { + throw new \InvalidArgumentException('Attempted to resolve "' . $type . '" but it appears to be empty'); + } + + if ($context === null) { + $context = new Context(''); + } + + switch (true) { + case $this->isKeyword($type): + return $this->resolveKeyword($type); + case ($this->isCompoundType($type)): + return $this->resolveCompoundType($type, $context); + case $this->isTypedArray($type): + return $this->resolveTypedArray($type, $context); + case $this->isFqsen($type): + return $this->resolveTypedObject($type); + case $this->isPartialStructuralElementName($type): + return $this->resolveTypedObject($type, $context); + // @codeCoverageIgnoreStart + default: + // I haven't got the foggiest how the logic would come here but added this as a defense. + throw new \RuntimeException( + 'Unable to resolve type "' . $type . '", there is no known method to resolve it' + ); + } + // @codeCoverageIgnoreEnd + } + + /** + * Adds a keyword to the list of Keywords and associates it with a specific Value Object. + * + * @param string $keyword + * @param string $typeClassName + * + * @return void + */ + public function addKeyword($keyword, $typeClassName) + { + if (!class_exists($typeClassName)) { + throw new \InvalidArgumentException( + 'The Value Object that needs to be created with a keyword "' . $keyword . '" must be an existing class' + . ' but we could not find the class ' . $typeClassName + ); + } + + if (!in_array(Type::class, class_implements($typeClassName))) { + throw new \InvalidArgumentException( + 'The class "' . $typeClassName . '" must implement the interface "phpDocumentor\Reflection\Type"' + ); + } + + $this->keywords[$keyword] = $typeClassName; + } + + /** + * Detects whether the given type represents an array. + * + * @param string $type A relative or absolute type as defined in the phpDocumentor documentation. + * + * @return bool + */ + private function isTypedArray($type) + { + return substr($type, -2) === self::OPERATOR_ARRAY; + } + + /** + * Detects whether the given type represents a PHPDoc keyword. + * + * @param string $type A relative or absolute type as defined in the phpDocumentor documentation. + * + * @return bool + */ + private function isKeyword($type) + { + return in_array(strtolower($type), array_keys($this->keywords), true); + } + + /** + * Detects whether the given type represents a relative structural element name. + * + * @param string $type A relative or absolute type as defined in the phpDocumentor documentation. + * + * @return bool + */ + private function isPartialStructuralElementName($type) + { + return ($type[0] !== self::OPERATOR_NAMESPACE) && !$this->isKeyword($type); + } + + /** + * Tests whether the given type is a Fully Qualified Structural Element Name. + * + * @param string $type + * + * @return bool + */ + private function isFqsen($type) + { + return strpos($type, self::OPERATOR_NAMESPACE) === 0; + } + + /** + * Tests whether the given type is a compound type (i.e. `string|int`). + * + * @param string $type + * + * @return bool + */ + private function isCompoundType($type) + { + return strpos($type, '|') !== false; + } + + /** + * Resolves the given typed array string (i.e. `string[]`) into an Array object with the right types set. + * + * @param string $type + * @param Context $context + * + * @return Array_ + */ + private function resolveTypedArray($type, Context $context) + { + return new Array_($this->resolve(substr($type, 0, -2), $context)); + } + + /** + * Resolves the given keyword (such as `string`) into a Type object representing that keyword. + * + * @param string $type + * + * @return Type + */ + private function resolveKeyword($type) + { + $className = $this->keywords[strtolower($type)]; + + return new $className(); + } + + /** + * Resolves the given FQSEN string into an FQSEN object. + * + * @param string $type + * + * @return Object_ + */ + private function resolveTypedObject($type, Context $context = null) + { + return new Object_($this->fqsenResolver->resolve($type, $context)); + } + + /** + * Resolves a compound type (i.e. `string|int`) into the appropriate Type objects or FQSEN. + * + * @param string $type + * @param Context $context + * + * @return Compound + */ + private function resolveCompoundType($type, Context $context) + { + $types = []; + + foreach (explode('|', $type) as $part) { + $types[] = $this->resolve($part, $context); + } + + return new Compound($types); + } +} diff --git a/src/composer/vendor/phpdocumentor/type-resolver/src/Types/Array_.php b/src/composer/vendor/phpdocumentor/type-resolver/src/Types/Array_.php new file mode 100644 index 00000000..45276c6b --- /dev/null +++ b/src/composer/vendor/phpdocumentor/type-resolver/src/Types/Array_.php @@ -0,0 +1,87 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\Types; + +use phpDocumentor\Reflection\Fqsen; +use phpDocumentor\Reflection\Type; + +/** + * Represents an array type as described in the PSR-5, the PHPDoc Standard. + * + * An array can be represented in two forms: + * + * 1. Untyped (`array`), where the key and value type is unknown and hence classified as 'Mixed'. + * 2. Types (`string[]`), where the value type is provided by preceding an opening and closing square bracket with a + * type name. + */ +final class Array_ implements Type +{ + /** @var Type */ + private $valueType; + + /** @var Type */ + private $keyType; + + /** + * Initializes this representation of an array with the given Type or Fqsen. + * + * @param Type $valueType + * @param Type $keyType + */ + public function __construct(Type $valueType = null, Type $keyType = null) + { + if ($keyType === null) { + $keyType = new Compound([ new String_(), new Integer() ]); + } + if ($valueType === null) { + $valueType = new Mixed(); + } + + $this->valueType = $valueType; + $this->keyType = $keyType; + } + + /** + * Returns the type for the keys of this array. + * + * @return Type + */ + public function getKeyType() + { + return $this->keyType; + } + + /** + * Returns the value for the keys of this array. + * + * @return Type + */ + public function getValueType() + { + return $this->valueType; + } + + /** + * Returns a rendered output of the Type as it would be used in a DocBlock. + * + * @return string + */ + public function __toString() + { + if ($this->valueType instanceof Mixed) { + return 'array'; + } + + return $this->valueType . '[]'; + } +} diff --git a/src/composer/vendor/phpdocumentor/type-resolver/src/Types/Boolean.php b/src/composer/vendor/phpdocumentor/type-resolver/src/Types/Boolean.php new file mode 100644 index 00000000..f82b19e5 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/type-resolver/src/Types/Boolean.php @@ -0,0 +1,31 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\Types; + +use phpDocumentor\Reflection\Type; + +/** + * Value Object representing a Boolean type. + */ +final class Boolean implements Type +{ + /** + * Returns a rendered output of the Type as it would be used in a DocBlock. + * + * @return string + */ + public function __toString() + { + return 'bool'; + } +} diff --git a/src/composer/vendor/phpdocumentor/type-resolver/src/Types/Callable_.php b/src/composer/vendor/phpdocumentor/type-resolver/src/Types/Callable_.php new file mode 100644 index 00000000..68ebfbd0 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/type-resolver/src/Types/Callable_.php @@ -0,0 +1,31 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\Types; + +use phpDocumentor\Reflection\Type; + +/** + * Value Object representing a Callable type. + */ +final class Callable_ implements Type +{ + /** + * Returns a rendered output of the Type as it would be used in a DocBlock. + * + * @return string + */ + public function __toString() + { + return 'callable'; + } +} diff --git a/src/composer/vendor/phpdocumentor/type-resolver/src/Types/Compound.php b/src/composer/vendor/phpdocumentor/type-resolver/src/Types/Compound.php new file mode 100644 index 00000000..3e5ebb5c --- /dev/null +++ b/src/composer/vendor/phpdocumentor/type-resolver/src/Types/Compound.php @@ -0,0 +1,82 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\Types; + +use phpDocumentor\Reflection\Type; + +/** + * Value Object representing a Compound Type. + * + * A Compound Type is not so much a special keyword or object reference but is a series of Types that are separated + * using an OR operator (`|`). This combination of types signifies that whatever is associated with this compound type + * may contain a value with any of the given types. + */ +final class Compound implements Type +{ + /** @var Type[] */ + private $types = []; + + /** + * Initializes a compound type (i.e. `string|int`) and tests if the provided types all implement the Type interface. + * + * @param Type[] $types + */ + public function __construct(array $types) + { + foreach ($types as $type) { + if (!$type instanceof Type) { + throw new \InvalidArgumentException('A compound type can only have other types as elements'); + } + } + + $this->types = $types; + } + + /** + * Returns the type at the given index. + * + * @param integer $index + * + * @return Type|null + */ + public function get($index) + { + if (!$this->has($index)) { + return null; + } + + return $this->types[$index]; + } + + /** + * Tests if this compound type has a type with the given index. + * + * @param integer $index + * + * @return bool + */ + public function has($index) + { + return isset($this->types[$index]); + } + + /** + * Returns a rendered output of the Type as it would be used in a DocBlock. + * + * @return string + */ + public function __toString() + { + return implode('|', $this->types); + } +} diff --git a/src/composer/vendor/phpdocumentor/type-resolver/src/Types/Context.php b/src/composer/vendor/phpdocumentor/type-resolver/src/Types/Context.php new file mode 100644 index 00000000..b4aa8f21 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/type-resolver/src/Types/Context.php @@ -0,0 +1,84 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\Types; + +/** + * Provides information about the Context in which the DocBlock occurs that receives this context. + * + * A DocBlock does not know of its own accord in which namespace it occurs and which namespace aliases are applicable + * for the block of code in which it is in. This information is however necessary to resolve Class names in tags since + * you can provide a short form or make use of namespace aliases. + * + * The phpDocumentor Reflection component knows how to create this class but if you use the DocBlock parser from your + * own application it is possible to generate a Context class using the ContextFactory; this will analyze the file in + * which an associated class resides for its namespace and imports. + * + * @see ContextFactory::createFromClassReflector() + * @see ContextFactory::createForNamespace() + */ +final class Context +{ + /** @var string The current namespace. */ + private $namespace = ''; + + /** @var array List of namespace aliases => Fully Qualified Namespace. */ + private $namespaceAliases = []; + + /** + * Initializes the new context and normalizes all passed namespaces to be in Qualified Namespace Name (QNN) + * format (without a preceding `\`). + * + * @param string $namespace The namespace where this DocBlock resides in. + * @param array $namespaceAliases List of namespace aliases => Fully Qualified Namespace. + */ + public function __construct($namespace, array $namespaceAliases = []) + { + $this->namespace = ('global' !== $namespace && 'default' !== $namespace) + ? trim((string)$namespace, '\\') + : ''; + + foreach ($namespaceAliases as $alias => $fqnn) { + if ($fqnn[0] === '\\') { + $fqnn = substr($fqnn, 1); + } + if ($fqnn[count($fqnn)-1] === '\\') { + $fqnn = substr($fqnn, 0, -1); + } + + $namespaceAliases[$alias] = $fqnn; + } + + $this->namespaceAliases = $namespaceAliases; + } + + /** + * Returns the Qualified Namespace Name (thus without `\` in front) where the associated element is in. + * + * @return string + */ + public function getNamespace() + { + return $this->namespace; + } + + /** + * Returns a list of Qualified Namespace Names (thus without `\` in front) that are imported, the keys represent + * the alias for the imported Namespace. + * + * @return string[] + */ + public function getNamespaceAliases() + { + return $this->namespaceAliases; + } +} diff --git a/src/composer/vendor/phpdocumentor/type-resolver/src/Types/ContextFactory.php b/src/composer/vendor/phpdocumentor/type-resolver/src/Types/ContextFactory.php new file mode 100644 index 00000000..147df694 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/type-resolver/src/Types/ContextFactory.php @@ -0,0 +1,210 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\Types; + +/** + * Convenience class to create a Context for DocBlocks when not using the Reflection Component of phpDocumentor. + * + * For a DocBlock to be able to resolve types that use partial namespace names or rely on namespace imports we need to + * provide a bit of context so that the DocBlock can read that and based on it decide how to resolve the types to + * Fully Qualified names. + * + * @see Context for more information. + */ +final class ContextFactory +{ + /** The literal used at the end of a use statement. */ + const T_LITERAL_END_OF_USE = ';'; + + /** The literal used between sets of use statements */ + const T_LITERAL_USE_SEPARATOR = ','; + + /** + * Build a Context given a Class Reflection. + * + * @param \ReflectionClass $reflector + * + * @see Context for more information on Contexts. + * + * @return Context + */ + public function createFromReflector(\Reflector $reflector) + { + if (method_exists($reflector, 'getDeclaringClass')) { + $reflector = $reflector->getDeclaringClass(); + } + + $fileName = $reflector->getFileName(); + $namespace = $reflector->getNamespaceName(); + + if (file_exists($fileName)) { + return $this->createForNamespace($namespace, file_get_contents($fileName)); + } + + return new Context($namespace, []); + } + + /** + * Build a Context for a namespace in the provided file contents. + * + * @param string $namespace It does not matter if a `\` precedes the namespace name, this method first normalizes. + * @param string $fileContents the file's contents to retrieve the aliases from with the given namespace. + * + * @see Context for more information on Contexts. + * + * @return Context + */ + public function createForNamespace($namespace, $fileContents) + { + $namespace = trim($namespace, '\\'); + $useStatements = []; + $currentNamespace = ''; + $tokens = new \ArrayIterator(token_get_all($fileContents)); + + while ($tokens->valid()) { + switch ($tokens->current()[0]) { + case T_NAMESPACE: + $currentNamespace = $this->parseNamespace($tokens); + break; + case T_CLASS: + // Fast-forward the iterator through the class so that any + // T_USE tokens found within are skipped - these are not + // valid namespace use statements so should be ignored. + $braceLevel = 0; + $firstBraceFound = false; + while ($tokens->valid() && ($braceLevel > 0 || !$firstBraceFound)) { + if ($tokens->current() === '{' + || $tokens->current()[0] === T_CURLY_OPEN + || $tokens->current()[0] === T_DOLLAR_OPEN_CURLY_BRACES) { + if (!$firstBraceFound) { + $firstBraceFound = true; + } + $braceLevel++; + } + + if ($tokens->current() === '}') { + $braceLevel--; + } + $tokens->next(); + } + break; + case T_USE: + if ($currentNamespace === $namespace) { + $useStatements = array_merge($useStatements, $this->parseUseStatement($tokens)); + } + break; + } + $tokens->next(); + } + + return new Context($namespace, $useStatements); + } + + /** + * Deduce the name from tokens when we are at the T_NAMESPACE token. + * + * @param \ArrayIterator $tokens + * + * @return string + */ + private function parseNamespace(\ArrayIterator $tokens) + { + // skip to the first string or namespace separator + $this->skipToNextStringOrNamespaceSeparator($tokens); + + $name = ''; + while ($tokens->valid() && ($tokens->current()[0] === T_STRING || $tokens->current()[0] === T_NS_SEPARATOR) + ) { + $name .= $tokens->current()[1]; + $tokens->next(); + } + + return $name; + } + + /** + * Deduce the names of all imports when we are at the T_USE token. + * + * @param \ArrayIterator $tokens + * + * @return string[] + */ + private function parseUseStatement(\ArrayIterator $tokens) + { + $uses = []; + $continue = true; + + while ($continue) { + $this->skipToNextStringOrNamespaceSeparator($tokens); + + list($alias, $fqnn) = $this->extractUseStatement($tokens); + $uses[$alias] = $fqnn; + if ($tokens->current()[0] === self::T_LITERAL_END_OF_USE) { + $continue = false; + } + } + + return $uses; + } + + /** + * Fast-forwards the iterator as longs as we don't encounter a T_STRING or T_NS_SEPARATOR token. + * + * @param \ArrayIterator $tokens + * + * @return void + */ + private function skipToNextStringOrNamespaceSeparator(\ArrayIterator $tokens) + { + while ($tokens->valid() && ($tokens->current()[0] !== T_STRING) && ($tokens->current()[0] !== T_NS_SEPARATOR)) { + $tokens->next(); + } + } + + /** + * Deduce the namespace name and alias of an import when we are at the T_USE token or have not reached the end of + * a USE statement yet. + * + * @param \ArrayIterator $tokens + * + * @return string + */ + private function extractUseStatement(\ArrayIterator $tokens) + { + $result = ['']; + while ($tokens->valid() + && ($tokens->current()[0] !== self::T_LITERAL_USE_SEPARATOR) + && ($tokens->current()[0] !== self::T_LITERAL_END_OF_USE) + ) { + if ($tokens->current()[0] === T_AS) { + $result[] = ''; + } + if ($tokens->current()[0] === T_STRING || $tokens->current()[0] === T_NS_SEPARATOR) { + $result[count($result) - 1] .= $tokens->current()[1]; + } + $tokens->next(); + } + + if (count($result) == 1) { + $backslashPos = strrpos($result[0], '\\'); + + if (false !== $backslashPos) { + $result[] = substr($result[0], $backslashPos + 1); + } else { + $result[] = $result[0]; + } + } + + return array_reverse($result); + } +} diff --git a/src/composer/vendor/phpdocumentor/type-resolver/src/Types/Float_.php b/src/composer/vendor/phpdocumentor/type-resolver/src/Types/Float_.php new file mode 100644 index 00000000..e58d8966 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/type-resolver/src/Types/Float_.php @@ -0,0 +1,31 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\Types; + +use phpDocumentor\Reflection\Type; + +/** + * Value Object representing a Float. + */ +final class Float_ implements Type +{ + /** + * Returns a rendered output of the Type as it would be used in a DocBlock. + * + * @return string + */ + public function __toString() + { + return 'float'; + } +} diff --git a/src/composer/vendor/phpdocumentor/type-resolver/src/Types/Integer.php b/src/composer/vendor/phpdocumentor/type-resolver/src/Types/Integer.php new file mode 100644 index 00000000..be4555ef --- /dev/null +++ b/src/composer/vendor/phpdocumentor/type-resolver/src/Types/Integer.php @@ -0,0 +1,28 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\Types; + +use phpDocumentor\Reflection\Type; + +final class Integer implements Type +{ + /** + * Returns a rendered output of the Type as it would be used in a DocBlock. + * + * @return string + */ + public function __toString() + { + return 'int'; + } +} diff --git a/src/composer/vendor/phpdocumentor/type-resolver/src/Types/Mixed.php b/src/composer/vendor/phpdocumentor/type-resolver/src/Types/Mixed.php new file mode 100644 index 00000000..79695f45 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/type-resolver/src/Types/Mixed.php @@ -0,0 +1,31 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\Types; + +use phpDocumentor\Reflection\Type; + +/** + * Value Object representing an unknown, or mixed, type. + */ +final class Mixed implements Type +{ + /** + * Returns a rendered output of the Type as it would be used in a DocBlock. + * + * @return string + */ + public function __toString() + { + return 'mixed'; + } +} diff --git a/src/composer/vendor/phpdocumentor/type-resolver/src/Types/Null_.php b/src/composer/vendor/phpdocumentor/type-resolver/src/Types/Null_.php new file mode 100644 index 00000000..203b4227 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/type-resolver/src/Types/Null_.php @@ -0,0 +1,31 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\Types; + +use phpDocumentor\Reflection\Type; + +/** + * Value Object representing a null value or type. + */ +final class Null_ implements Type +{ + /** + * Returns a rendered output of the Type as it would be used in a DocBlock. + * + * @return string + */ + public function __toString() + { + return 'null'; + } +} diff --git a/src/composer/vendor/phpdocumentor/type-resolver/src/Types/Object_.php b/src/composer/vendor/phpdocumentor/type-resolver/src/Types/Object_.php new file mode 100644 index 00000000..b337c715 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/type-resolver/src/Types/Object_.php @@ -0,0 +1,70 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\Types; + +use phpDocumentor\Reflection\Fqsen; +use phpDocumentor\Reflection\Type; + +/** + * Value Object representing an object. + * + * An object can be either typed or untyped. When an object is typed it means that it has an identifier, the FQSEN, + * pointing to an element in PHP. Object types that are untyped do not refer to a specific class but represent objects + * in general. + */ +final class Object_ implements Type +{ + /** @var Fqsen|null */ + private $fqsen; + + /** + * Initializes this object with an optional FQSEN, if not provided this object is considered 'untyped'. + * + * @param Fqsen $fqsen + */ + public function __construct(Fqsen $fqsen = null) + { + if (strpos((string)$fqsen, '::') !== false || strpos((string)$fqsen, '()') !== false) { + throw new \InvalidArgumentException( + 'Object types can only refer to a class, interface or trait but a method, function, constant or ' + . 'property was received: ' . (string)$fqsen + ); + } + + $this->fqsen = $fqsen; + } + + /** + * Returns the FQSEN associated with this object. + * + * @return Fqsen|null + */ + public function getFqsen() + { + return $this->fqsen; + } + + /** + * Returns a rendered output of the Type as it would be used in a DocBlock. + * + * @return string + */ + public function __toString() + { + if ($this->fqsen) { + return (string)$this->fqsen; + } + + return 'object'; + } +} diff --git a/src/composer/vendor/phpdocumentor/type-resolver/src/Types/Resource.php b/src/composer/vendor/phpdocumentor/type-resolver/src/Types/Resource.php new file mode 100644 index 00000000..2c2526b7 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/type-resolver/src/Types/Resource.php @@ -0,0 +1,31 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\Types; + +use phpDocumentor\Reflection\Type; + +/** + * Value Object representing the 'resource' Type. + */ +final class Resource implements Type +{ + /** + * Returns a rendered output of the Type as it would be used in a DocBlock. + * + * @return string + */ + public function __toString() + { + return 'resource'; + } +} diff --git a/src/composer/vendor/phpdocumentor/type-resolver/src/Types/Scalar.php b/src/composer/vendor/phpdocumentor/type-resolver/src/Types/Scalar.php new file mode 100644 index 00000000..1e2a6602 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/type-resolver/src/Types/Scalar.php @@ -0,0 +1,31 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\Types; + +use phpDocumentor\Reflection\Type; + +/** + * Value Object representing the 'scalar' pseudo-type, which is either a string, integer, float or boolean. + */ +final class Scalar implements Type +{ + /** + * Returns a rendered output of the Type as it would be used in a DocBlock. + * + * @return string + */ + public function __toString() + { + return 'scalar'; + } +} diff --git a/src/composer/vendor/phpdocumentor/type-resolver/src/Types/Self_.php b/src/composer/vendor/phpdocumentor/type-resolver/src/Types/Self_.php new file mode 100644 index 00000000..1ba3fc5a --- /dev/null +++ b/src/composer/vendor/phpdocumentor/type-resolver/src/Types/Self_.php @@ -0,0 +1,33 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\Types; + +use phpDocumentor\Reflection\Type; + +/** + * Value Object representing the 'self' type. + * + * Self, as a Type, represents the class in which the associated element was defined. + */ +final class Self_ implements Type +{ + /** + * Returns a rendered output of the Type as it would be used in a DocBlock. + * + * @return string + */ + public function __toString() + { + return 'self'; + } +} diff --git a/src/composer/vendor/phpdocumentor/type-resolver/src/Types/Static_.php b/src/composer/vendor/phpdocumentor/type-resolver/src/Types/Static_.php new file mode 100644 index 00000000..9eb67299 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/type-resolver/src/Types/Static_.php @@ -0,0 +1,38 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\Types; + +use phpDocumentor\Reflection\Type; + +/** + * Value Object representing the 'static' type. + * + * Self, as a Type, represents the class in which the associated element was called. This differs from self as self does + * not take inheritance into account but static means that the return type is always that of the class of the called + * element. + * + * See the documentation on late static binding in the PHP Documentation for more information on the difference between + * static and self. + */ +final class Static_ implements Type +{ + /** + * Returns a rendered output of the Type as it would be used in a DocBlock. + * + * @return string + */ + public function __toString() + { + return 'static'; + } +} diff --git a/src/composer/vendor/phpdocumentor/type-resolver/src/Types/String_.php b/src/composer/vendor/phpdocumentor/type-resolver/src/Types/String_.php new file mode 100644 index 00000000..8db59685 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/type-resolver/src/Types/String_.php @@ -0,0 +1,31 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\Types; + +use phpDocumentor\Reflection\Type; + +/** + * Value Object representing the type 'string'. + */ +final class String_ implements Type +{ + /** + * Returns a rendered output of the Type as it would be used in a DocBlock. + * + * @return string + */ + public function __toString() + { + return 'string'; + } +} diff --git a/src/composer/vendor/phpdocumentor/type-resolver/src/Types/This.php b/src/composer/vendor/phpdocumentor/type-resolver/src/Types/This.php new file mode 100644 index 00000000..c098a939 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/type-resolver/src/Types/This.php @@ -0,0 +1,34 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\Types; + +use phpDocumentor\Reflection\Type; + +/** + * Value Object representing the '$this' pseudo-type. + * + * $this, as a Type, represents the instance of the class associated with the element as it was called. $this is + * commonly used when documenting fluent interfaces since it represents that the same object is returned. + */ +final class This implements Type +{ + /** + * Returns a rendered output of the Type as it would be used in a DocBlock. + * + * @return string + */ + public function __toString() + { + return '$this'; + } +} diff --git a/src/composer/vendor/phpdocumentor/type-resolver/src/Types/Void_.php b/src/composer/vendor/phpdocumentor/type-resolver/src/Types/Void_.php new file mode 100644 index 00000000..3d1be272 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/type-resolver/src/Types/Void_.php @@ -0,0 +1,34 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\Types; + +use phpDocumentor\Reflection\Type; + +/** + * Value Object representing the pseudo-type 'void'. + * + * Void is generally only used when working with return types as it signifies that the method intentionally does not + * return any value. + */ +final class Void_ implements Type +{ + /** + * Returns a rendered output of the Type as it would be used in a DocBlock. + * + * @return string + */ + public function __toString() + { + return 'void'; + } +} diff --git a/src/composer/vendor/phpdocumentor/type-resolver/tests/unit/TypeResolverTest.php b/src/composer/vendor/phpdocumentor/type-resolver/tests/unit/TypeResolverTest.php new file mode 100644 index 00000000..f226f8ed --- /dev/null +++ b/src/composer/vendor/phpdocumentor/type-resolver/tests/unit/TypeResolverTest.php @@ -0,0 +1,395 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection; + +use Mockery as m; +use phpDocumentor\Reflection\Types\Array_; +use phpDocumentor\Reflection\Types\Compound; +use phpDocumentor\Reflection\Types\Context; +use phpDocumentor\Reflection\Types\Object_; + +/** + * @coversDefaultClass phpDocumentor\Reflection\TypeResolver + */ +class TypeResolverTest extends \PHPUnit_Framework_TestCase +{ + /** + * @param string $keyword + * @param string $expectedClass + * + * @covers ::__construct + * @covers ::resolve + * @covers :: + * + * @uses phpDocumentor\Reflection\Types\Context + * @uses phpDocumentor\Reflection\Types\Array_ + * @uses phpDocumentor\Reflection\Types\Object_ + * + * @dataProvider provideKeywords + */ + public function testResolvingKeywords($keyword, $expectedClass) + { + $fixture = new TypeResolver(); + + $resolvedType = $fixture->resolve($keyword, new Context('')); + + $this->assertInstanceOf($expectedClass, $resolvedType); + } + + /** + * @param string $fqsen + * + * @covers ::__construct + * @covers ::resolve + * @covers :: + * + * @uses phpDocumentor\Reflection\Types\Context + * @uses phpDocumentor\Reflection\Types\Object_ + * @uses phpDocumentor\Reflection\Fqsen + * @uses phpDocumentor\Reflection\FqsenResolver + * + * @dataProvider provideFqcn + */ + public function testResolvingFQSENs($fqsen) + { + $fixture = new TypeResolver(); + + /** @var Object_ $resolvedType */ + $resolvedType = $fixture->resolve($fqsen, new Context('')); + + $this->assertInstanceOf('phpDocumentor\Reflection\Types\Object_', $resolvedType); + $this->assertInstanceOf('phpDocumentor\Reflection\Fqsen', $resolvedType->getFqsen()); + $this->assertSame($fqsen, (string)$resolvedType); + } + + /** + * @covers ::__construct + * @covers ::resolve + * @covers :: + * + * @uses phpDocumentor\Reflection\Types\Context + * @uses phpDocumentor\Reflection\Types\Object_ + * @uses phpDocumentor\Reflection\Fqsen + * @uses phpDocumentor\Reflection\FqsenResolver + */ + public function testResolvingRelativeQSENsBasedOnNamespace() + { + $fixture = new TypeResolver(); + + /** @var Object_ $resolvedType */ + $resolvedType = $fixture->resolve('DocBlock', new Context('phpDocumentor\Reflection')); + + $this->assertInstanceOf('phpDocumentor\Reflection\Types\Object_', $resolvedType); + $this->assertInstanceOf('phpDocumentor\Reflection\Fqsen', $resolvedType->getFqsen()); + $this->assertSame('\phpDocumentor\Reflection\DocBlock', (string)$resolvedType); + } + + /** + * @covers ::__construct + * @covers ::resolve + * @covers :: + * + * @uses phpDocumentor\Reflection\Types\Context + * @uses phpDocumentor\Reflection\Types\Object_ + * @uses phpDocumentor\Reflection\Fqsen + * @uses phpDocumentor\Reflection\FqsenResolver + */ + public function testResolvingRelativeQSENsBasedOnNamespaceAlias() + { + $fixture = new TypeResolver(); + + /** @var Object_ $resolvedType */ + $resolvedType = $fixture->resolve( + 'm\MockInterface', + new Context('phpDocumentor\Reflection', ['m' => '\Mockery']) + ); + + $this->assertInstanceOf('phpDocumentor\Reflection\Types\Object_', $resolvedType); + $this->assertInstanceOf('phpDocumentor\Reflection\Fqsen', $resolvedType->getFqsen()); + $this->assertSame('\Mockery\MockInterface', (string)$resolvedType); + } + + /** + * @covers ::__construct + * @covers ::resolve + * @covers :: + * + * @uses phpDocumentor\Reflection\Types\Context + * @uses phpDocumentor\Reflection\Types\Array_ + * @uses phpDocumentor\Reflection\Types\String_ + */ + public function testResolvingTypedArrays() + { + $fixture = new TypeResolver(); + + /** @var Array_ $resolvedType */ + $resolvedType = $fixture->resolve('string[]', new Context('')); + + $this->assertInstanceOf('phpDocumentor\Reflection\Types\Array_', $resolvedType); + $this->assertSame('string[]', (string)$resolvedType); + $this->assertInstanceOf('phpDocumentor\Reflection\Types\Compound', $resolvedType->getKeyType()); + $this->assertInstanceOf('phpDocumentor\Reflection\Types\String_', $resolvedType->getValueType()); + } + + /** + * @covers ::__construct + * @covers ::resolve + * @covers :: + * + * @uses phpDocumentor\Reflection\Types\Context + * @uses phpDocumentor\Reflection\Types\Array_ + * @uses phpDocumentor\Reflection\Types\String_ + */ + public function testResolvingNestedTypedArrays() + { + $fixture = new TypeResolver(); + + /** @var Array_ $resolvedType */ + $resolvedType = $fixture->resolve('string[][]', new Context('')); + + /** @var Array_ $childValueType */ + $childValueType = $resolvedType->getValueType(); + + $this->assertInstanceOf('phpDocumentor\Reflection\Types\Array_', $resolvedType); + + $this->assertSame('string[][]', (string)$resolvedType); + $this->assertInstanceOf('phpDocumentor\Reflection\Types\Compound', $resolvedType->getKeyType()); + $this->assertInstanceOf('phpDocumentor\Reflection\Types\Array_', $childValueType); + + $this->assertSame('string[]', (string)$childValueType); + $this->assertInstanceOf('phpDocumentor\Reflection\Types\Compound', $childValueType->getKeyType()); + $this->assertInstanceOf('phpDocumentor\Reflection\Types\String_', $childValueType->getValueType()); + } + + /** + * @covers ::__construct + * @covers ::resolve + * @covers :: + * + * @uses phpDocumentor\Reflection\Types\Context + * @uses phpDocumentor\Reflection\Types\Compound + * @uses phpDocumentor\Reflection\Types\String_ + * @uses phpDocumentor\Reflection\Types\Object_ + * @uses phpDocumentor\Reflection\Fqsen + * @uses phpDocumentor\Reflection\FqsenResolver + */ + public function testResolvingCompoundTypes() + { + $fixture = new TypeResolver(); + + /** @var Compound $resolvedType */ + $resolvedType = $fixture->resolve('string|Reflection\DocBlock', new Context('phpDocumentor')); + + $this->assertInstanceOf('phpDocumentor\Reflection\Types\Compound', $resolvedType); + $this->assertSame('string|\phpDocumentor\Reflection\DocBlock', (string)$resolvedType); + + /** @var String $secondType */ + $firstType = $resolvedType->get(0); + + /** @var Object_ $secondType */ + $secondType = $resolvedType->get(1); + + $this->assertInstanceOf('phpDocumentor\Reflection\Types\String_', $firstType); + $this->assertInstanceOf('phpDocumentor\Reflection\Types\Object_', $secondType); + $this->assertInstanceOf('phpDocumentor\Reflection\Fqsen', $secondType->getFqsen()); + } + + /** + * @covers ::__construct + * @covers ::resolve + * @covers :: + * + * @uses phpDocumentor\Reflection\Types\Context + * @uses phpDocumentor\Reflection\Types\Compound + * @uses phpDocumentor\Reflection\Types\Array_ + * @uses phpDocumentor\Reflection\Types\Object_ + * @uses phpDocumentor\Reflection\Fqsen + * @uses phpDocumentor\Reflection\FqsenResolver + */ + public function testResolvingCompoundTypedArrayTypes() + { + $fixture = new TypeResolver(); + + /** @var Compound $resolvedType */ + $resolvedType = $fixture->resolve('\stdClass[]|Reflection\DocBlock[]', new Context('phpDocumentor')); + + $this->assertInstanceOf('phpDocumentor\Reflection\Types\Compound', $resolvedType); + $this->assertSame('\stdClass[]|\phpDocumentor\Reflection\DocBlock[]', (string)$resolvedType); + + /** @var Array_ $secondType */ + $firstType = $resolvedType->get(0); + + /** @var Array_ $secondType */ + $secondType = $resolvedType->get(1); + + $this->assertInstanceOf('phpDocumentor\Reflection\Types\Array_', $firstType); + $this->assertInstanceOf('phpDocumentor\Reflection\Types\Array_', $secondType); + $this->assertInstanceOf('phpDocumentor\Reflection\Types\Object_', $firstType->getValueType()); + $this->assertInstanceOf('phpDocumentor\Reflection\Types\Object_', $secondType->getValueType()); + } + + /** + * This test asserts that the parameter order is correct. + * + * When you pass two arrays separated by the compound operator (i.e. 'integer[]|string[]') then we always split the + * expression in its compound parts and then we parse the types with the array operators. If we were to switch the + * order around then 'integer[]|string[]' would read as an array of string or integer array; which is something + * other than what we intend. + * + * @covers ::__construct + * @covers ::resolve + * @covers :: + * + * @uses phpDocumentor\Reflection\Types\Context + * @uses phpDocumentor\Reflection\Types\Compound + * @uses phpDocumentor\Reflection\Types\Array_ + * @uses phpDocumentor\Reflection\Types\Integer + * @uses phpDocumentor\Reflection\Types\String_ + */ + public function testResolvingCompoundTypesWithTwoArrays() + { + $fixture = new TypeResolver(); + + /** @var Compound $resolvedType */ + $resolvedType = $fixture->resolve('integer[]|string[]', new Context('')); + + $this->assertInstanceOf('phpDocumentor\Reflection\Types\Compound', $resolvedType); + $this->assertSame('int[]|string[]', (string)$resolvedType); + + /** @var Array_ $firstType */ + $firstType = $resolvedType->get(0); + + /** @var Array_ $secondType */ + $secondType = $resolvedType->get(1); + + $this->assertInstanceOf('phpDocumentor\Reflection\Types\Array_', $firstType); + $this->assertInstanceOf('phpDocumentor\Reflection\Types\Integer', $firstType->getValueType()); + $this->assertInstanceOf('phpDocumentor\Reflection\Types\Array_', $secondType); + $this->assertInstanceOf('phpDocumentor\Reflection\Types\String_', $secondType->getValueType()); + } + + /** + * @covers ::__construct + * @covers ::addKeyword + * @uses phpDocumentor\Reflection\TypeResolver::resolve + * @uses phpDocumentor\Reflection\TypeResolver:: + * @uses phpDocumentor\Reflection\Types\Context + */ + public function testAddingAKeyword() + { + // Assign + $typeMock = m::mock(Type::class); + + // Act + $fixture = new TypeResolver(); + $fixture->addKeyword('mock', get_class($typeMock)); + + // Assert + $result = $fixture->resolve('mock', new Context('')); + $this->assertInstanceOf(get_class($typeMock), $result); + $this->assertNotSame($typeMock, $result); + } + + /** + * @covers ::__construct + * @covers ::addKeyword + * @uses phpDocumentor\Reflection\Types\Context + * @expectedException \InvalidArgumentException + */ + public function testAddingAKeywordFailsIfTypeClassDoesNotExist() + { + $fixture = new TypeResolver(); + $fixture->addKeyword('mock', 'IDoNotExist'); + } + + /** + * @covers ::__construct + * @covers ::addKeyword + * @uses phpDocumentor\Reflection\Types\Context + * @expectedException \InvalidArgumentException + */ + public function testAddingAKeywordFailsIfTypeClassDoesNotImplementTypeInterface() + { + $fixture = new TypeResolver(); + $fixture->addKeyword('mock', 'stdClass'); + } + + /** + * @covers ::__construct + * @covers ::resolve + * @uses phpDocumentor\Reflection\Types\Context + * + * @expectedException \InvalidArgumentException + */ + public function testExceptionIsThrownIfTypeIsEmpty() + { + $fixture = new TypeResolver(); + $fixture->resolve(' ', new Context('')); + } + + /** + * @covers ::__construct + * @covers ::resolve + * @uses phpDocumentor\Reflection\Types\Context + * + * @expectedException \InvalidArgumentException + */ + public function testExceptionIsThrownIfTypeIsNotAString() + { + $fixture = new TypeResolver(); + $fixture->resolve(['a'], new Context('')); + } + + /** + * Returns a list of keywords and expected classes that are created from them. + * + * @return string[][] + */ + public function provideKeywords() + { + return [ + ['string', 'phpDocumentor\Reflection\Types\String_'], + ['int', 'phpDocumentor\Reflection\Types\Integer'], + ['integer', 'phpDocumentor\Reflection\Types\Integer'], + ['float', 'phpDocumentor\Reflection\Types\Float_'], + ['double', 'phpDocumentor\Reflection\Types\Float_'], + ['bool', 'phpDocumentor\Reflection\Types\Boolean'], + ['boolean', 'phpDocumentor\Reflection\Types\Boolean'], + ['resource', 'phpDocumentor\Reflection\Types\Resource'], + ['null', 'phpDocumentor\Reflection\Types\Null_'], + ['callable', 'phpDocumentor\Reflection\Types\Callable_'], + ['callback', 'phpDocumentor\Reflection\Types\Callable_'], + ['array', 'phpDocumentor\Reflection\Types\Array_'], + ['scalar', 'phpDocumentor\Reflection\Types\Scalar'], + ['object', 'phpDocumentor\Reflection\Types\Object_'], + ['mixed', 'phpDocumentor\Reflection\Types\Mixed'], + ['void', 'phpDocumentor\Reflection\Types\Void_'], + ['$this', 'phpDocumentor\Reflection\Types\This'], + ['static', 'phpDocumentor\Reflection\Types\Static_'], + ['self', 'phpDocumentor\Reflection\Types\Self_'], + ]; + } + + /** + * Provides a list of FQSENs to test the resolution patterns with. + * + * @return string[][] + */ + public function provideFqcn() + { + return [ + 'namespace' => ['\phpDocumentor\Reflection'], + 'class' => ['\phpDocumentor\Reflection\DocBlock'], + ]; + } +} diff --git a/src/composer/vendor/phpdocumentor/type-resolver/tests/unit/Types/ContextFactoryTest.php b/src/composer/vendor/phpdocumentor/type-resolver/tests/unit/Types/ContextFactoryTest.php new file mode 100644 index 00000000..20d63c95 --- /dev/null +++ b/src/composer/vendor/phpdocumentor/type-resolver/tests/unit/Types/ContextFactoryTest.php @@ -0,0 +1,188 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\Types { + +// Added imports on purpose as mock for the unit tests, please do not remove. + use Mockery as m; + use phpDocumentor\Reflection\DocBlock, + phpDocumentor\Reflection\DocBlock\Tag; + use phpDocumentor; + use \ReflectionClass; // yes, the slash is part of the test + + /** + * @coversDefaultClass \phpDocumentor\Reflection\Types\ContextFactory + * @covers :: + */ + class ContextFactoryTest extends \PHPUnit_Framework_TestCase + { + /** + * @covers ::createFromReflector + * @covers ::createForNamespace + * @uses phpDocumentor\Reflection\Types\Context + */ + public function testReadsNamespaceFromClassReflection() + { + $fixture = new ContextFactory(); + $context = $fixture->createFromReflector(new ReflectionClass($this)); + + $this->assertSame(__NAMESPACE__, $context->getNamespace()); + } + + /** + * @covers ::createFromReflector + * @covers ::createForNamespace + * @uses phpDocumentor\Reflection\Types\Context + */ + public function testReadsAliasesFromClassReflection() + { + $fixture = new ContextFactory(); + $expected = [ + 'm' => 'Mockery', + 'DocBlock' => 'phpDocumentor\Reflection\DocBlock', + 'Tag' => 'phpDocumentor\Reflection\DocBlock\Tag', + 'phpDocumentor' => 'phpDocumentor', + 'ReflectionClass' => 'ReflectionClass' + ]; + $context = $fixture->createFromReflector(new ReflectionClass($this)); + + $this->assertSame($expected, $context->getNamespaceAliases()); + } + + /** + * @covers ::createForNamespace + * @uses phpDocumentor\Reflection\Types\Context + */ + public function testReadsNamespaceFromProvidedNamespaceAndContent() + { + $fixture = new ContextFactory(); + $context = $fixture->createForNamespace(__NAMESPACE__, file_get_contents(__FILE__)); + + $this->assertSame(__NAMESPACE__, $context->getNamespace()); + } + + /** + * @covers ::createForNamespace + * @uses phpDocumentor\Reflection\Types\Context + */ + public function testReadsAliasesFromProvidedNamespaceAndContent() + { + $fixture = new ContextFactory(); + $expected = [ + 'm' => 'Mockery', + 'DocBlock' => 'phpDocumentor\Reflection\DocBlock', + 'Tag' => 'phpDocumentor\Reflection\DocBlock\Tag', + 'phpDocumentor' => 'phpDocumentor', + 'ReflectionClass' => 'ReflectionClass' + ]; + $context = $fixture->createForNamespace(__NAMESPACE__, file_get_contents(__FILE__)); + + $this->assertSame($expected, $context->getNamespaceAliases()); + } + + /** + * @covers ::createForNamespace + * @uses phpDocumentor\Reflection\Types\Context + */ + public function testTraitUseIsNotDetectedAsNamespaceUse() + { + $php = "createForNamespace('Foo', $php); + + $this->assertSame([], $context->getNamespaceAliases()); + } + + /** + * @covers ::createForNamespace + * @uses phpDocumentor\Reflection\Types\Context + */ + public function testAllOpeningBracesAreCheckedWhenSearchingForEndOfClass() + { + $php = 'createForNamespace('Foo', $php); + + $this->assertSame([], $context->getNamespaceAliases()); + } + + /** + * @covers ::createFromReflector + */ + public function testEmptyFileName() + { + $fixture = new ContextFactory(); + $context = $fixture->createFromReflector(new \ReflectionClass('stdClass')); + + $this->assertSame([], $context->getNamespaceAliases()); + } + + /** + * @covers ::createFromReflector + */ + public function testEvalDClass() + { + eval(<<createFromReflector(new \ReflectionClass('Foo\Bar')); + + $this->assertSame([], $context->getNamespaceAliases()); + } + } +} + +namespace phpDocumentor\Reflection\Types\Mock { + // the following import should not show in the tests above + use phpDocumentor\Reflection\DocBlock\Description; +} diff --git a/src/composer/vendor/phpdocumentor/type-resolver/tests/unit/Types/ContextTest.php b/src/composer/vendor/phpdocumentor/type-resolver/tests/unit/Types/ContextTest.php new file mode 100644 index 00000000..165f415d --- /dev/null +++ b/src/composer/vendor/phpdocumentor/type-resolver/tests/unit/Types/ContextTest.php @@ -0,0 +1,61 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\Types; + +use Mockery as m; + +/** + * @coversDefaultClass \phpDocumentor\Reflection\Types\Context + */ +class ContextTest extends \PHPUnit_Framework_TestCase +{ + /** + * @covers ::__construct + * @covers ::getNamespace + */ + public function testProvidesANormalizedNamespace() + { + $fixture = new Context('\My\Space'); + $this->assertSame('My\Space', $fixture->getNamespace()); + } + + /** + * @covers ::__construct + * @covers ::getNamespace + */ + public function testInterpretsNamespaceNamedGlobalAsRootNamespace() + { + $fixture = new Context('global'); + $this->assertSame('', $fixture->getNamespace()); + } + + /** + * @covers ::__construct + * @covers ::getNamespace + */ + public function testInterpretsNamespaceNamedDefaultAsRootNamespace() + { + $fixture = new Context('default'); + $this->assertSame('', $fixture->getNamespace()); + } + + /** + * @covers ::__construct + * @covers ::getNamespaceAliases + */ + public function testProvidesNormalizedNamespaceAliases() + { + $fixture = new Context('', ['Space' => '\My\Space']); + $this->assertSame(['Space' => 'My\Space'], $fixture->getNamespaceAliases()); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/.gitignore b/src/composer/vendor/phpspec/prophecy/.gitignore new file mode 100644 index 00000000..0c93fcf3 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/.gitignore @@ -0,0 +1,4 @@ +*.tgz +*.phar +/composer.lock +/vendor diff --git a/src/composer/vendor/phpspec/prophecy/.travis.yml b/src/composer/vendor/phpspec/prophecy/.travis.yml new file mode 100644 index 00000000..e75c39ef --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/.travis.yml @@ -0,0 +1,29 @@ +language: php + +php: [5.3, 5.4, 5.5, 5.6, 7.0, hhvm] + +sudo: false + +cache: + directories: + - $HOME/.composer/cache + +branches: + except: + - /^bugfix\/.*$/ + - /^feature\/.*$/ + - /^optimization\/.*$/ + +matrix: + fast_finish: true + include: + - php: '7.0' + env: PHPDOCUMENTOR_REFLECTION_DOCBLOCK="^2.0" + +before_script: + - if [ -n "$PHPDOCUMENTOR_REFLECTION_DOCBLOCK" ]; then + composer require "phpdocumentor/reflection-docblock:${PHPDOCUMENTOR_REFLECTION_DOCBLOCK}" --no-update; + fi; + - travis_retry composer update --no-interaction + +script: vendor/bin/phpspec run -fpretty -v diff --git a/src/composer/vendor/phpspec/prophecy/CHANGES.md b/src/composer/vendor/phpspec/prophecy/CHANGES.md new file mode 100644 index 00000000..444c1fa6 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/CHANGES.md @@ -0,0 +1,147 @@ +1.6.1 / 2016-06-07 +================== + + * Ignored empty method names in invalid `@method` phpdoc + * Fixed the mocking of SplFileObject + * Added compatibility with phpdocumentor/reflection-docblock 3 + +1.6.0 / 2016-02-15 +================== + + * Add Variadics support (thanks @pamil) + * Add ProphecyComparator for comparing objects that need revealing (thanks @jon-acker) + * Add ApproximateValueToken (thanks @dantleech) + * Add support for 'self' and 'parent' return type (thanks @bendavies) + * Add __invoke to allowed reflectable methods list (thanks @ftrrtf) + * Updated ExportUtil to reflect the latest changes by Sebastian (thanks @jakari) + * Specify the required php version for composer (thanks @jakzal) + * Exclude 'args' in the generated backtrace (thanks @oradwell) + * Fix code generation for scalar parameters (thanks @trowski) + * Fix missing sprintf in InvalidArgumentException __construct call (thanks @emmanuelballery) + * Fix phpdoc for magic methods (thanks @Tobion) + * Fix PhpDoc for interfaces usage (thanks @ImmRanneft) + * Prevent final methods from being manually extended (thanks @kamioftea) + * Enhance exception for invalid argument to ThrowPromise (thanks @Tobion) + +1.5.0 / 2015-04-27 +================== + + * Add support for PHP7 scalar type hints (thanks @trowski) + * Add support for PHP7 return types (thanks @trowski) + * Update internal test suite to support PHP7 + +1.4.1 / 2015-04-27 +================== + + * Fixed bug in closure-based argument tokens (#181) + +1.4.0 / 2015-03-27 +================== + + * Fixed errors in return type phpdocs (thanks @sobit) + * Fixed stringifying of hash containing one value (thanks @avant1) + * Improved clarity of method call expectation exception (thanks @dantleech) + * Add ability to specify which argument is returned in willReturnArgument (thanks @coderbyheart) + * Add more information to MethodNotFound exceptions (thanks @ciaranmcnulty) + * Support for mocking classes with methods that return references (thanks @edsonmedina) + * Improved object comparison (thanks @whatthejeff) + * Adopted '^' in composer dependencies (thanks @GrahamCampbell) + * Fixed non-typehinted arguments being treated as optional (thanks @whatthejeff) + * Magic methods are now filtered for keywords (thanks @seagoj) + * More readable errors for failure when expecting single calls (thanks @dantleech) + +1.3.1 / 2014-11-17 +================== + + * Fix the edge case when failed predictions weren't recorded for `getCheckedPredictions()` + +1.3.0 / 2014-11-14 +================== + + * Add a way to get checked predictions with `MethodProphecy::getCheckedPredictions()` + * Fix HHVM compatibility + * Remove dead code (thanks @stof) + * Add support for DirectoryIterators (thanks @shanethehat) + +1.2.0 / 2014-07-18 +================== + + * Added support for doubling magic methods documented in the class phpdoc (thanks @armetiz) + * Fixed a segfault appearing in some cases (thanks @dmoreaulf) + * Fixed the doubling of methods with typehints on non-existent classes (thanks @gquemener) + * Added support for internal classes using keywords as method names (thanks @milan) + * Added IdenticalValueToken and Argument::is (thanks @florianv) + * Removed the usage of scalar typehints in HHVM as HHVM 3 does not support them anymore in PHP code (thanks @whatthejeff) + +1.1.2 / 2014-01-24 +================== + + * Spy automatically promotes spied method call to an expected one + +1.1.1 / 2014-01-15 +================== + + * Added support for HHVM + +1.1.0 / 2014-01-01 +================== + + * Changed the generated class names to use a static counter instead of a random number + * Added a clss patch for ReflectionClass::newInstance to make its argument optional consistently (thanks @docteurklein) + * Fixed mirroring of classes with typehints on non-existent classes (thanks @docteurklein) + * Fixed the support of array callables in CallbackPromise and CallbackPrediction (thanks @ciaranmcnulty) + * Added support for properties in ObjectStateToken (thanks @adrienbrault) + * Added support for mocking classes with a final constructor (thanks @ciaranmcnulty) + * Added ArrayEveryEntryToken and Argument::withEveryEntry() (thanks @adrienbrault) + * Added an exception when trying to prophesize on a final method instead of ignoring silently (thanks @docteurklein) + * Added StringContainToken and Argument::containingString() (thanks @peterjmit) + * Added ``shouldNotHaveBeenCalled`` on the MethodProphecy (thanks @ciaranmcnulty) + * Fixed the comparison of objects in ExactValuetoken (thanks @sstok) + * Deprecated ``shouldNotBeenCalled`` in favor of ``shouldNotHaveBeenCalled`` + +1.0.4 / 2013-08-10 +================== + + * Better randomness for generated class names (thanks @sstok) + * Add support for interfaces into TypeToken and Argument::type() (thanks @sstok) + * Add support for old-style (method name === class name) constructors (thanks @l310 for report) + +1.0.3 / 2013-07-04 +================== + + * Support callable typehints (thanks @stof) + * Do not attempt to autoload arrays when generating code (thanks @MarcoDeBortoli) + * New ArrayEntryToken (thanks @kagux) + +1.0.2 / 2013-05-19 +================== + + * Logical `AND` token added (thanks @kagux) + * Logical `NOT` token added (thanks @kagux) + * Add support for setting custom constructor arguments + * Properly stringify hashes + * Record calls that throw exceptions + * Migrate spec suite to PhpSpec 2.0 + +1.0.1 / 2013-04-30 +================== + + * Fix broken UnexpectedCallException message + * Trim AggregateException message + +1.0.0 / 2013-04-29 +================== + + * Improve exception messages + +1.0.0-BETA2 / 2013-04-03 +======================== + + * Add more debug information to CallTimes and Call prediction exception messages + * Fix MethodNotFoundException wrong namespace (thanks @gunnarlium) + * Fix some typos in the exception messages (thanks @pborreli) + +1.0.0-BETA1 / 2013-03-25 +======================== + + * Initial release diff --git a/src/composer/vendor/phpspec/prophecy/CONTRIBUTING.md b/src/composer/vendor/phpspec/prophecy/CONTRIBUTING.md new file mode 100644 index 00000000..72d8e933 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/CONTRIBUTING.md @@ -0,0 +1,21 @@ +Contributing +------------ + +Prophecy is an open source, community-driven project. If you'd like to contribute, +feel free to do this, but remember to follow these few simple rules: + +- Make your feature addition or bug fix, +- Add either specs or examples for any changes you're making (bugfixes or additions) + (please look into `spec/` folder for some examples). This is important so we don't break + it in a future version unintentionally, +- Commit your code, but do not mess with `CHANGES.md`, + +Running tests +------------- + +Make sure that you don't break anything with your changes by running: + +```bash +$> composer install --prefer-dist +$> vendor/bin/phpspec run +``` diff --git a/src/composer/vendor/phpspec/prophecy/LICENSE b/src/composer/vendor/phpspec/prophecy/LICENSE new file mode 100644 index 00000000..c8b36471 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/LICENSE @@ -0,0 +1,23 @@ +Copyright (c) 2013 Konstantin Kudryashov + Marcello Duarte + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/src/composer/vendor/phpspec/prophecy/README.md b/src/composer/vendor/phpspec/prophecy/README.md new file mode 100644 index 00000000..65ec16c4 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/README.md @@ -0,0 +1,391 @@ +# Prophecy + +[![Stable release](https://poser.pugx.org/phpspec/prophecy/version.svg)](https://packagist.org/packages/phpspec/prophecy) +[![Build Status](https://travis-ci.org/phpspec/prophecy.svg?branch=master)](https://travis-ci.org/phpspec/prophecy) + +Prophecy is a highly opinionated yet very powerful and flexible PHP object mocking +framework. Though initially it was created to fulfil phpspec2 needs, it is flexible +enough to be used inside any testing framework out there with minimal effort. + +## A simple example + +```php +prophet->prophesize('App\Security\Hasher'); + $user = new App\Entity\User($hasher->reveal()); + + $hasher->generateHash($user, 'qwerty')->willReturn('hashed_pass'); + + $user->setPassword('qwerty'); + + $this->assertEquals('hashed_pass', $user->getPassword()); + } + + protected function setup() + { + $this->prophet = new \Prophecy\Prophet; + } + + protected function tearDown() + { + $this->prophet->checkPredictions(); + } +} +``` + +## Installation + +### Prerequisites + +Prophecy requires PHP 5.3.3 or greater. + +### Setup through composer + +First, add Prophecy to the list of dependencies inside your `composer.json`: + +```json +{ + "require-dev": { + "phpspec/prophecy": "~1.0" + } +} +``` + +Then simply install it with composer: + +```bash +$> composer install --prefer-dist +``` + +You can read more about Composer on its [official webpage](http://getcomposer.org). + +## How to use it + +First of all, in Prophecy every word has a logical meaning, even the name of the library +itself (Prophecy). When you start feeling that, you'll become very fluid with this +tool. + +For example, Prophecy has been named that way because it concentrates on describing the future +behavior of objects with very limited knowledge about them. But as with any other prophecy, +those object prophecies can't create themselves - there should be a Prophet: + +```php +$prophet = new Prophecy\Prophet; +``` + +The Prophet creates prophecies by *prophesizing* them: + +```php +$prophecy = $prophet->prophesize(); +``` + +The result of the `prophesize()` method call is a new object of class `ObjectProphecy`. Yes, +that's your specific object prophecy, which describes how your object would behave +in the near future. But first, you need to specify which object you're talking about, +right? + +```php +$prophecy->willExtend('stdClass'); +$prophecy->willImplement('SessionHandlerInterface'); +``` + +There are 2 interesting calls - `willExtend` and `willImplement`. The first one tells +object prophecy that our object should extend specific class, the second one says that +it should implement some interface. Obviously, objects in PHP can implement multiple +interfaces, but extend only one parent class. + +### Dummies + +Ok, now we have our object prophecy. What can we do with it? First of all, we can get +our object *dummy* by revealing its prophecy: + +```php +$dummy = $prophecy->reveal(); +``` + +The `$dummy` variable now holds a special dummy object. Dummy objects are objects that extend +and/or implement preset classes/interfaces by overriding all their public methods. The key +point about dummies is that they do not hold any logic - they just do nothing. Any method +of the dummy will always return `null` and the dummy will never throw any exceptions. +Dummy is your friend if you don't care about the actual behavior of this double and just need +a token object to satisfy a method typehint. + +You need to understand one thing - a dummy is not a prophecy. Your object prophecy is still +assigned to `$prophecy` variable and in order to manipulate with your expectations, you +should work with it. `$dummy` is a dummy - a simple php object that tries to fulfil your +prophecy. + +### Stubs + +Ok, now we know how to create basic prophecies and reveal dummies from them. That's +awesome if we don't care about our _doubles_ (objects that reflect originals) +interactions. If we do, we need to use *stubs* or *mocks*. + +A stub is an object double, which doesn't have any expectations about the object behavior, +but when put in specific environment, behaves in specific way. Ok, I know, it's cryptic, +but bear with me for a minute. Simply put, a stub is a dummy, which depending on the called +method signature does different things (has logic). To create stubs in Prophecy: + +```php +$prophecy->read('123')->willReturn('value'); +``` + +Oh wow. We've just made an arbitrary call on the object prophecy? Yes, we did. And this +call returned us a new object instance of class `MethodProphecy`. Yep, that's a specific +method with arguments prophecy. Method prophecies give you the ability to create method +promises or predictions. We'll talk about method predictions later in the _Mocks_ section. + +#### Promises + +Promises are logical blocks, that represent your fictional methods in prophecy terms +and they are handled by the `MethodProphecy::will(PromiseInterface $promise)` method. +As a matter of fact, the call that we made earlier (`willReturn('value')`) is a simple +shortcut to: + +```php +$prophecy->read('123')->will(new Prophecy\Promise\ReturnPromise(array('value'))); +``` + +This promise will cause any call to our double's `read()` method with exactly one +argument - `'123'` to always return `'value'`. But that's only for this +promise, there's plenty others you can use: + +- `ReturnPromise` or `->willReturn(1)` - returns a value from a method call +- `ReturnArgumentPromise` or `->willReturnArgument($index)` - returns the nth method argument from call +- `ThrowPromise` or `->willThrow` - causes the method to throw specific exception +- `CallbackPromise` or `->will($callback)` - gives you a quick way to define your own custom logic + +Keep in mind, that you can always add even more promises by implementing +`Prophecy\Promise\PromiseInterface`. + +#### Method prophecies idempotency + +Prophecy enforces same method prophecies and, as a consequence, same promises and +predictions for the same method calls with the same arguments. This means: + +```php +$methodProphecy1 = $prophecy->read('123'); +$methodProphecy2 = $prophecy->read('123'); +$methodProphecy3 = $prophecy->read('321'); + +$methodProphecy1 === $methodProphecy2; +$methodProphecy1 !== $methodProphecy3; +``` + +That's interesting, right? Now you might ask me how would you define more complex +behaviors where some method call changes behavior of others. In PHPUnit or Mockery +you do that by predicting how many times your method will be called. In Prophecy, +you'll use promises for that: + +```php +$user->getName()->willReturn(null); + +// For PHP 5.4 +$user->setName('everzet')->will(function () { + $this->getName()->willReturn('everzet'); +}); + +// For PHP 5.3 +$user->setName('everzet')->will(function ($args, $user) { + $user->getName()->willReturn('everzet'); +}); + +// Or +$user->setName('everzet')->will(function ($args) use ($user) { + $user->getName()->willReturn('everzet'); +}); +``` + +And now it doesn't matter how many times or in which order your methods are called. +What matters is their behaviors and how well you faked it. + +#### Arguments wildcarding + +The previous example is awesome (at least I hope it is for you), but that's not +optimal enough. We hardcoded `'everzet'` in our expectation. Isn't there a better +way? In fact there is, but it involves understanding what this `'everzet'` +actually is. + +You see, even if method arguments used during method prophecy creation look +like simple method arguments, in reality they are not. They are argument token +wildcards. As a matter of fact, `->setName('everzet')` looks like a simple call just +because Prophecy automatically transforms it under the hood into: + +```php +$user->setName(new Prophecy\Argument\Token\ExactValueToken('everzet')); +``` + +Those argument tokens are simple PHP classes, that implement +`Prophecy\Argument\Token\TokenInterface` and tell Prophecy how to compare real arguments +with your expectations. And yes, those classnames are damn big. That's why there's a +shortcut class `Prophecy\Argument`, which you can use to create tokens like that: + +```php +use Prophecy\Argument; + +$user->setName(Argument::exact('everzet')); +``` + +`ExactValueToken` is not very useful in our case as it forced us to hardcode the username. +That's why Prophecy comes bundled with a bunch of other tokens: + +- `IdenticalValueToken` or `Argument::is($value)` - checks that the argument is identical to a specific value +- `ExactValueToken` or `Argument::exact($value)` - checks that the argument matches a specific value +- `TypeToken` or `Argument::type($typeOrClass)` - checks that the argument matches a specific type or + classname +- `ObjectStateToken` or `Argument::which($method, $value)` - checks that the argument method returns + a specific value +- `CallbackToken` or `Argument::that(callback)` - checks that the argument matches a custom callback +- `AnyValueToken` or `Argument::any()` - matches any argument +- `AnyValuesToken` or `Argument::cetera()` - matches any arguments to the rest of the signature +- `StringContainsToken` or `Argument::containingString($value)` - checks that the argument contains a specific string value + +And you can add even more by implementing `TokenInterface` with your own custom classes. + +So, let's refactor our initial `{set,get}Name()` logic with argument tokens: + +```php +use Prophecy\Argument; + +$user->getName()->willReturn(null); + +// For PHP 5.4 +$user->setName(Argument::type('string'))->will(function ($args) { + $this->getName()->willReturn($args[0]); +}); + +// For PHP 5.3 +$user->setName(Argument::type('string'))->will(function ($args, $user) { + $user->getName()->willReturn($args[0]); +}); + +// Or +$user->setName(Argument::type('string'))->will(function ($args) use ($user) { + $user->getName()->willReturn($args[0]); +}); +``` + +That's it. Now our `{set,get}Name()` prophecy will work with any string argument provided to it. +We've just described how our stub object should behave, even though the original object could have +no behavior whatsoever. + +One last bit about arguments now. You might ask, what happens in case of: + +```php +use Prophecy\Argument; + +$user->getName()->willReturn(null); + +// For PHP 5.4 +$user->setName(Argument::type('string'))->will(function ($args) { + $this->getName()->willReturn($args[0]); +}); + +// For PHP 5.3 +$user->setName(Argument::type('string'))->will(function ($args, $user) { + $user->getName()->willReturn($args[0]); +}); + +// Or +$user->setName(Argument::type('string'))->will(function ($args) use ($user) { + $user->getName()->willReturn($args[0]); +}); + +$user->setName(Argument::any())->will(function () { +}); +``` + +Nothing. Your stub will continue behaving the way it did before. That's because of how +arguments wildcarding works. Every argument token type has a different score level, which +wildcard then uses to calculate the final arguments match score and use the method prophecy +promise that has the highest score. In this case, `Argument::type()` in case of success +scores `5` and `Argument::any()` scores `3`. So the type token wins, as does the first +`setName()` method prophecy and its promise. The simple rule of thumb - more precise token +always wins. + +#### Getting stub objects + +Ok, now we know how to define our prophecy method promises, let's get our stub from +it: + +```php +$stub = $prophecy->reveal(); +``` + +As you might see, the only difference between how we get dummies and stubs is that with +stubs we describe every object conversation instead of just agreeing with `null` returns +(object being *dummy*). As a matter of fact, after you define your first promise +(method call), Prophecy will force you to define all the communications - it throws +the `UnexpectedCallException` for any call you didn't describe with object prophecy before +calling it on a stub. + +### Mocks + +Now we know how to define doubles without behavior (dummies) and doubles with behavior, but +no expectations (stubs). What's left is doubles for which we have some expectations. These +are called mocks and in Prophecy they look almost exactly the same as stubs, except that +they define *predictions* instead of *promises* on method prophecies: + +```php +$entityManager->flush()->shouldBeCalled(); +``` + +#### Predictions + +The `shouldBeCalled()` method here assigns `CallPrediction` to our method prophecy. +Predictions are a delayed behavior check for your prophecies. You see, during the entire lifetime +of your doubles, Prophecy records every single call you're making against it inside your +code. After that, Prophecy can use this collected information to check if it matches defined +predictions. You can assign predictions to method prophecies using the +`MethodProphecy::should(PredictionInterface $prediction)` method. As a matter of fact, +the `shouldBeCalled()` method we used earlier is just a shortcut to: + +```php +$entityManager->flush()->should(new Prophecy\Prediction\CallPrediction()); +``` + +It checks if your method of interest (that matches both the method name and the arguments wildcard) +was called 1 or more times. If the prediction failed then it throws an exception. When does this +check happen? Whenever you call `checkPredictions()` on the main Prophet object: + +```php +$prophet->checkPredictions(); +``` + +In PHPUnit, you would want to put this call into the `tearDown()` method. If no predictions +are defined, it would do nothing. So it won't harm to call it after every test. + +There are plenty more predictions you can play with: + +- `CallPrediction` or `shouldBeCalled()` - checks that the method has been called 1 or more times +- `NoCallsPrediction` or `shouldNotBeCalled()` - checks that the method has not been called +- `CallTimesPrediction` or `shouldBeCalledTimes($count)` - checks that the method has been called + `$count` times +- `CallbackPrediction` or `should($callback)` - checks the method against your own custom callback + +Of course, you can always create your own custom prediction any time by implementing +`PredictionInterface`. + +### Spies + +The last bit of awesomeness in Prophecy is out-of-the-box spies support. As I said in the previous +section, Prophecy records every call made during the double's entire lifetime. This means +you don't need to record predictions in order to check them. You can also do it +manually by using the `MethodProphecy::shouldHave(PredictionInterface $prediction)` method: + +```php +$em = $prophet->prophesize('Doctrine\ORM\EntityManager'); + +$controller->createUser($em->reveal()); + +$em->flush()->shouldHaveBeenCalled(); +``` + +Such manipulation with doubles is called spying. And with Prophecy it just works. diff --git a/src/composer/vendor/phpspec/prophecy/composer.json b/src/composer/vendor/phpspec/prophecy/composer.json new file mode 100644 index 00000000..23131b20 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/composer.json @@ -0,0 +1,43 @@ +{ + "name": "phpspec/prophecy", + "description": "Highly opinionated mocking framework for PHP 5.3+", + "keywords": ["Mock", "Stub", "Dummy", "Double", "Fake", "Spy"], + "homepage": "https://github.com/phpspec/prophecy", + "type": "library", + "license": "MIT", + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + }, + { + "name": "Marcello Duarte", + "email": "marcello.duarte@gmail.com" + } + ], + + "require": { + "php": "^5.3|^7.0", + "phpdocumentor/reflection-docblock": "^2.0|^3.0.2", + "sebastian/comparator": "^1.1", + "doctrine/instantiator": "^1.0.2", + "sebastian/recursion-context": "^1.0" + }, + + "require-dev": { + "phpspec/phpspec": "^2.0" + }, + + "autoload": { + "psr-0": { + "Prophecy\\": "src/" + } + }, + + "extra": { + "branch-alias": { + "dev-master": "1.6.x-dev" + } + } +} diff --git a/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Argument/ArgumentsWildcardSpec.php b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Argument/ArgumentsWildcardSpec.php new file mode 100644 index 00000000..5d6a2da3 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Argument/ArgumentsWildcardSpec.php @@ -0,0 +1,146 @@ +beConstructedWith(array(42, 'zet', $object)); + + $class = get_class($object->getWrappedObject()); + $hash = spl_object_hash($object->getWrappedObject()); + + $this->__toString()->shouldReturn("exact(42), exact(\"zet\"), exact($class:$hash Object (\n 'objectProphecy' => Prophecy\Prophecy\ObjectProphecy Object (*Prophecy*)\n))"); + } + + /** + * @param \Prophecy\Argument\Token\TokenInterface $token1 + * @param \Prophecy\Argument\Token\TokenInterface $token2 + * @param \Prophecy\Argument\Token\TokenInterface $token3 + */ + function it_generates_string_representation_from_all_tokens_imploded($token1, $token2, $token3) + { + $token1->__toString()->willReturn('token_1'); + $token2->__toString()->willReturn('token_2'); + $token3->__toString()->willReturn('token_3'); + + $this->beConstructedWith(array($token1, $token2, $token3)); + $this->__toString()->shouldReturn('token_1, token_2, token_3'); + } + + /** + * @param \Prophecy\Argument\Token\TokenInterface $token + */ + function it_exposes_list_of_tokens($token) + { + $this->beConstructedWith(array($token)); + + $this->getTokens()->shouldReturn(array($token)); + } + + function it_returns_score_of_1_if_there_are_no_tokens_and_arguments() + { + $this->beConstructedWith(array()); + + $this->scoreArguments(array())->shouldReturn(1); + } + + /** + * @param \Prophecy\Argument\Token\TokenInterface $token1 + * @param \Prophecy\Argument\Token\TokenInterface $token2 + * @param \Prophecy\Argument\Token\TokenInterface $token3 + */ + function it_should_return_match_score_based_on_all_tokens_score($token1, $token2, $token3) + { + $token1->scoreArgument('one')->willReturn(3); + $token1->isLast()->willReturn(false); + $token2->scoreArgument(2)->willReturn(5); + $token2->isLast()->willReturn(false); + $token3->scoreArgument($obj = new \stdClass())->willReturn(10); + $token3->isLast()->willReturn(false); + + $this->beConstructedWith(array($token1, $token2, $token3)); + $this->scoreArguments(array('one', 2, $obj))->shouldReturn(18); + } + + /** + * @param \Prophecy\Argument\Token\TokenInterface $token1 + * @param \Prophecy\Argument\Token\TokenInterface $token2 + * @param \Prophecy\Argument\Token\TokenInterface $token3 + */ + function it_returns_false_if_there_is_less_arguments_than_tokens($token1, $token2, $token3) + { + $token1->scoreArgument('one')->willReturn(3); + $token1->isLast()->willReturn(false); + $token2->scoreArgument(2)->willReturn(5); + $token2->isLast()->willReturn(false); + $token3->scoreArgument(null)->willReturn(false); + $token3->isLast()->willReturn(false); + + $this->beConstructedWith(array($token1, $token2, $token3)); + $this->scoreArguments(array('one', 2))->shouldReturn(false); + } + + /** + * @param \Prophecy\Argument\Token\TokenInterface $token1 + * @param \Prophecy\Argument\Token\TokenInterface $token2 + * @param \Prophecy\Argument\Token\TokenInterface $token3 + */ + function it_returns_false_if_there_is_less_tokens_than_arguments($token1, $token2, $token3) + { + $token1->scoreArgument('one')->willReturn(3); + $token1->isLast()->willReturn(false); + $token2->scoreArgument(2)->willReturn(5); + $token2->isLast()->willReturn(false); + $token3->scoreArgument($obj = new \stdClass())->willReturn(10); + $token3->isLast()->willReturn(false); + + $this->beConstructedWith(array($token1, $token2, $token3)); + $this->scoreArguments(array('one', 2, $obj, 4))->shouldReturn(false); + } + + /** + * @param \Prophecy\Argument\Token\TokenInterface $token1 + * @param \Prophecy\Argument\Token\TokenInterface $token2 + * @param \Prophecy\Argument\Token\TokenInterface $token3 + */ + function it_should_return_false_if_one_of_the_tokens_returns_false($token1, $token2, $token3) + { + $token1->scoreArgument('one')->willReturn(3); + $token1->isLast()->willReturn(false); + $token2->scoreArgument(2)->willReturn(false); + $token2->isLast()->willReturn(false); + $token3->scoreArgument($obj = new \stdClass())->willReturn(10); + $token3->isLast()->willReturn(false); + + $this->beConstructedWith(array($token1, $token2, $token3)); + $this->scoreArguments(array('one', 2, $obj))->shouldReturn(false); + } + + /** + * @param \Prophecy\Argument\Token\TokenInterface $token1 + * @param \Prophecy\Argument\Token\TokenInterface $token2 + * @param \Prophecy\Argument\Token\TokenInterface $token3 + */ + function it_should_calculate_score_until_last_token($token1, $token2, $token3) + { + $token1->scoreArgument('one')->willReturn(3); + $token1->isLast()->willReturn(false); + + $token2->scoreArgument(2)->willReturn(7); + $token2->isLast()->willReturn(true); + + $token3->scoreArgument($obj = new \stdClass())->willReturn(10); + $token3->isLast()->willReturn(false); + + $this->beConstructedWith(array($token1, $token2, $token3)); + $this->scoreArguments(array('one', 2, $obj))->shouldReturn(10); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/AnyValueTokenSpec.php b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/AnyValueTokenSpec.php new file mode 100644 index 00000000..a43e923c --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/AnyValueTokenSpec.php @@ -0,0 +1,28 @@ +shouldBeAnInstanceOf('Prophecy\Argument\Token\TokenInterface'); + } + + function it_is_not_last() + { + $this->shouldNotBeLast(); + } + + function its_string_representation_is_star() + { + $this->__toString()->shouldReturn('*'); + } + + function it_scores_any_argument_as_3() + { + $this->scoreArgument(42)->shouldReturn(3); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/AnyValuesTokenSpec.php b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/AnyValuesTokenSpec.php new file mode 100644 index 00000000..c29076f5 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/AnyValuesTokenSpec.php @@ -0,0 +1,28 @@ +shouldBeAnInstanceOf('Prophecy\Argument\Token\TokenInterface'); + } + + function it_is_last() + { + $this->shouldBeLast(); + } + + function its_string_representation_is_star_with_followup() + { + $this->__toString()->shouldReturn('* [, ...]'); + } + + function it_scores_any_argument_as_2() + { + $this->scoreArgument(42)->shouldReturn(2); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/ApproximateValueTokenSpec.php b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/ApproximateValueTokenSpec.php new file mode 100644 index 00000000..8799d6d5 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/ApproximateValueTokenSpec.php @@ -0,0 +1,55 @@ +beConstructedWith(10.12345678, 4); + } + + function it_is_initializable() + { + $this->shouldHaveType('Prophecy\Argument\Token\ApproximateValueToken'); + } + + function it_implements_TokenInterface() + { + $this->shouldBeAnInstanceOf('Prophecy\Argument\Token\TokenInterface'); + } + + function it_is_not_last() + { + $this->shouldNotBeLast(); + } + + function it_scores_10_if_rounded_argument_matches_rounded_value() + { + $this->scoreArgument(10.12345)->shouldReturn(10); + } + + function it_does_not_score_if_rounded_argument_does_not_match_rounded_value() + { + $this->scoreArgument(10.1234)->shouldReturn(false); + } + + function it_uses_a_default_precision_of_zero() + { + $this->beConstructedWith(10.7); + $this->scoreArgument(11.4)->shouldReturn(10); + } + + function it_does_not_score_if_rounded_argument_is_not_numeric() + { + $this->scoreArgument('hello')->shouldReturn(false); + } + + function it_has_simple_string_representation() + { + $this->__toString()->shouldBe('≅10.1235'); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/ArrayCountTokenSpec.php b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/ArrayCountTokenSpec.php new file mode 100644 index 00000000..5d040d59 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/ArrayCountTokenSpec.php @@ -0,0 +1,64 @@ +beConstructedWith(2); + } + + function it_implements_TokenInterface() + { + $this->shouldBeAnInstanceOf('Prophecy\Argument\Token\TokenInterface'); + } + + function it_is_not_last() + { + $this->shouldNotBeLast(); + } + + function it_scores_6_if_argument_array_has_proper_count() + { + $this->scoreArgument(array(1,2))->shouldReturn(6); + } + + /** + * @param \Countable $countable + */ + function it_scores_6_if_argument_countable_object_has_proper_count($countable) + { + $countable->count()->willReturn(2); + $this->scoreArgument($countable)->shouldReturn(6); + } + + function it_does_not_score_if_argument_is_neither_array_nor_countable_object() + { + $this->scoreArgument('string')->shouldBe(false); + $this->scoreArgument(5)->shouldBe(false); + $this->scoreArgument(new \stdClass)->shouldBe(false); + } + + function it_does_not_score_if_argument_array_has_wrong_count() + { + $this->scoreArgument(array(1))->shouldReturn(false); + } + + /** + * @param \Countable $countable + */ + function it_does_not_score_if_argument_countable_object_has_wrong_count($countable) + { + $countable->count()->willReturn(3); + $this->scoreArgument($countable)->shouldReturn(false); + } + + function it_has_simple_string_representation() + { + $this->__toString()->shouldBe('count(2)'); + } + +} diff --git a/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/ArrayEntryTokenSpec.php b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/ArrayEntryTokenSpec.php new file mode 100644 index 00000000..8ff0f158 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/ArrayEntryTokenSpec.php @@ -0,0 +1,229 @@ +beConstructedWith($key, $value); + } + + function it_implements_TokenInterface() + { + $this->shouldBeAnInstanceOf('Prophecy\Argument\Token\TokenInterface'); + } + + function it_is_not_last() + { + $this->shouldNotBeLast(); + } + + function it_holds_key_and_value($key, $value) + { + $this->getKey()->shouldBe($key); + $this->getValue()->shouldBe($value); + } + + function its_string_representation_tells_that_its_an_array_containing_the_key_value_pair($key, $value) + { + $key->__toString()->willReturn('key'); + $value->__toString()->willReturn('value'); + $this->__toString()->shouldBe('[..., key => value, ...]'); + } + + /** + * @param \Prophecy\Argument\Token\TokenInterface $key + * @param \stdClass $object + */ + function it_wraps_non_token_value_into_ExactValueToken($key, $object) + { + $this->beConstructedWith($key, $object); + $this->getValue()->shouldHaveType('\Prophecy\Argument\Token\ExactValueToken'); + } + + /** + * @param \stdClass $object + * @param \Prophecy\Argument\Token\TokenInterface $value + */ + function it_wraps_non_token_key_into_ExactValueToken($object, $value) + { + $this->beConstructedWith($object, $value); + $this->getKey()->shouldHaveType('\Prophecy\Argument\Token\ExactValueToken'); + } + + function it_scores_array_half_of_combined_scores_from_key_and_value_tokens($key, $value) + { + $key->scoreArgument('key')->willReturn(4); + $value->scoreArgument('value')->willReturn(6); + $this->scoreArgument(array('key'=>'value'))->shouldBe(5); + } + + /** + * @param \Prophecy\Argument\Token\TokenInterface $key + * @param \Prophecy\Argument\Token\TokenInterface $value + * @param \Iterator $object + */ + function it_scores_traversable_object_half_of_combined_scores_from_key_and_value_tokens($key, $value, $object) + { + $object->current()->will(function () use ($object) { + $object->valid()->willReturn(false); + + return 'value'; + }); + $object->key()->willReturn('key'); + $object->rewind()->willReturn(null); + $object->next()->willReturn(null); + $object->valid()->willReturn(true); + $key->scoreArgument('key')->willReturn(6); + $value->scoreArgument('value')->willReturn(2); + $this->scoreArgument($object)->shouldBe(4); + } + + /** + * @param \Prophecy\Argument\Token\AnyValuesToken $key + * @param \Prophecy\Argument\Token\TokenInterface $value + * @param \ArrayAccess $object + */ + function it_throws_exception_during_scoring_of_array_accessible_object_if_key_is_not_ExactValueToken($key, $value, $object) + { + $key->__toString()->willReturn('any_token'); + $this->beConstructedWith($key,$value); + $errorMessage = 'You can only use exact value tokens to match key of ArrayAccess object'.PHP_EOL. + 'But you used `any_token`.'; + $this->shouldThrow(new InvalidArgumentException($errorMessage))->duringScoreArgument($object); + } + + /** + * @param \Prophecy\Argument\Token\ExactValueToken $key + * @param \Prophecy\Argument\Token\TokenInterface $value + * @param \ArrayAccess $object + */ + function it_scores_array_accessible_object_half_of_combined_scores_from_key_and_value_tokens($key, $value, $object) + { + $object->offsetExists('key')->willReturn(true); + $object->offsetGet('key')->willReturn('value'); + $key->getValue()->willReturn('key'); + $key->scoreArgument('key')->willReturn(3); + $value->scoreArgument('value')->willReturn(1); + $this->scoreArgument($object)->shouldBe(2); + } + + /** + * @param \Prophecy\Argument\Token\AnyValuesToken $key + * @param \Prophecy\Argument\Token\TokenInterface $value + * @param \ArrayIterator $object + */ + function it_accepts_any_key_token_type_to_score_object_that_is_both_traversable_and_array_accessible($key, $value, $object) + { + $this->beConstructedWith($key, $value); + $object->current()->will(function () use ($object) { + $object->valid()->willReturn(false); + + return 'value'; + }); + $object->key()->willReturn('key'); + $object->rewind()->willReturn(null); + $object->next()->willReturn(null); + $object->valid()->willReturn(true); + $this->shouldNotThrow(new InvalidArgumentException)->duringScoreArgument($object); + } + + function it_does_not_score_if_argument_is_neither_array_nor_traversable_nor_array_accessible() + { + $this->scoreArgument('string')->shouldBe(false); + $this->scoreArgument(new \stdClass)->shouldBe(false); + } + + function it_does_not_score_empty_array() + { + $this->scoreArgument(array())->shouldBe(false); + } + + function it_does_not_score_array_if_key_and_value_tokens_do_not_score_same_entry($key, $value) + { + $argument = array(1 => 'foo', 2 => 'bar'); + $key->scoreArgument(1)->willReturn(true); + $key->scoreArgument(2)->willReturn(false); + $value->scoreArgument('foo')->willReturn(false); + $value->scoreArgument('bar')->willReturn(true); + $this->scoreArgument($argument)->shouldBe(false); + } + + /** + * @param \Iterator $object + */ + function it_does_not_score_traversable_object_without_entries($object) + { + $object->rewind()->willReturn(null); + $object->next()->willReturn(null); + $object->valid()->willReturn(false); + $this->scoreArgument($object)->shouldBe(false); + } + + /** + * @param \Prophecy\Argument\Token\TokenInterface $key + * @param \Prophecy\Argument\Token\TokenInterface $value + * @param \Iterator $object + */ + function it_does_not_score_traversable_object_if_key_and_value_tokens_do_not_score_same_entry($key, $value, $object) + { + $object->current()->willReturn('foo'); + $object->current()->will(function () use ($object) { + $object->valid()->willReturn(false); + + return 'bar'; + }); + $object->key()->willReturn(1); + $object->key()->willReturn(2); + $object->rewind()->willReturn(null); + $object->next()->willReturn(null); + $object->valid()->willReturn(true); + $key->scoreArgument(1)->willReturn(true); + $key->scoreArgument(2)->willReturn(false); + $value->scoreArgument('foo')->willReturn(false); + $value->scoreArgument('bar')->willReturn(true); + $this->scoreArgument($object)->shouldBe(false); + } + + /** + * @param \Prophecy\Argument\Token\ExactValueToken $key + * @param \ArrayAccess $object + */ + function it_does_not_score_array_accessible_object_if_it_has_no_offset_with_key_token_value($key, $object) + { + $object->offsetExists('key')->willReturn(false); + $key->getValue()->willReturn('key'); + $this->scoreArgument($object)->shouldBe(false); + } + + /** + * @param \Prophecy\Argument\Token\ExactValueToken $key + * @param \Prophecy\Argument\Token\TokenInterface $value + * @param \ArrayAccess $object + */ + function it_does_not_score_array_accessible_object_if_key_and_value_tokens_do_not_score_same_entry($key, $value, $object) + { + $object->offsetExists('key')->willReturn(true); + $object->offsetGet('key')->willReturn('value'); + $key->getValue()->willReturn('key'); + $value->scoreArgument('value')->willReturn(false); + $key->scoreArgument('key')->willReturn(true); + $this->scoreArgument($object)->shouldBe(false); + } + + function its_score_is_capped_at_8($key, $value) + { + $key->scoreArgument('key')->willReturn(10); + $value->scoreArgument('value')->willReturn(10); + $this->scoreArgument(array('key'=>'value'))->shouldBe(8); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/ArrayEveryEntryTokenSpec.php b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/ArrayEveryEntryTokenSpec.php new file mode 100644 index 00000000..8662e7d1 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/ArrayEveryEntryTokenSpec.php @@ -0,0 +1,109 @@ +beConstructedWith($value); + } + + function it_implements_TokenInterface() + { + $this->shouldBeAnInstanceOf('Prophecy\Argument\Token\TokenInterface'); + } + + function it_is_not_last() + { + $this->shouldNotBeLast(); + } + + function it_holds_value($value) + { + $this->getValue()->shouldBe($value); + } + + function its_string_representation_tells_that_its_an_array_containing_only_value($value) + { + $value->__toString()->willReturn('value'); + $this->__toString()->shouldBe('[value, ..., value]'); + } + + /** + * @param \stdClass $stdClass + */ + function it_wraps_non_token_value_into_ExactValueToken($stdClass) + { + $this->beConstructedWith($stdClass); + $this->getValue()->shouldHaveType('Prophecy\Argument\Token\ExactValueToken'); + } + + function it_does_not_score_if_argument_is_neither_array_nor_traversable() + { + $this->scoreArgument('string')->shouldBe(false); + $this->scoreArgument(new \stdClass)->shouldBe(false); + } + + function it_does_not_score_empty_array() + { + $this->scoreArgument(array())->shouldBe(false); + } + + /** + * @param \Iterator $object + */ + function it_does_not_score_traversable_object_without_entries($object) + { + $object->rewind()->willReturn(null); + $object->next()->willReturn(null); + $object->valid()->willReturn(false); + $this->scoreArgument($object)->shouldBe(false); + } + + function it_scores_avg_of_scores_from_value_tokens($value) + { + $value->scoreArgument('value1')->willReturn(6); + $value->scoreArgument('value2')->willReturn(3); + $this->scoreArgument(array('value1', 'value2'))->shouldBe(4.5); + } + + function it_scores_false_if_entry_scores_false($value) + { + $value->scoreArgument('value1')->willReturn(6); + $value->scoreArgument('value2')->willReturn(false); + $this->scoreArgument(array('value1', 'value2'))->shouldBe(false); + } + + function it_does_not_score_array_keys($value) + { + $value->scoreArgument('value')->willReturn(6); + $value->scoreArgument('key')->shouldNotBeCalled(0); + $this->scoreArgument(array('key' => 'value'))->shouldBe(6); + } + + /** + * @param \Prophecy\Argument\Token\TokenInterface $value + * @param \Iterator $object + */ + function it_scores_traversable_object_from_value_token($value, $object) + { + $object->current()->will(function ($args, $object) { + $object->valid()->willReturn(false); + + return 'value'; + }); + $object->key()->willReturn('key'); + $object->rewind()->willReturn(null); + $object->next()->willReturn(null); + $object->valid()->willReturn(true); + $value->scoreArgument('value')->willReturn(2); + $this->scoreArgument($object)->shouldBe(2); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/CallbackTokenSpec.php b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/CallbackTokenSpec.php new file mode 100644 index 00000000..4395bf09 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/CallbackTokenSpec.php @@ -0,0 +1,42 @@ +beConstructedWith('get_class'); + } + + function it_implements_TokenInterface() + { + $this->shouldBeAnInstanceOf('Prophecy\Argument\Token\TokenInterface'); + } + + function it_is_not_last() + { + $this->shouldNotBeLast(); + } + + function it_scores_7_if_argument_matches_callback() + { + $this->beConstructedWith(function ($argument) { return 2 === $argument; }); + + $this->scoreArgument(2)->shouldReturn(7); + } + + function it_does_not_scores_if_argument_does_not_match_callback() + { + $this->beConstructedWith(function ($argument) { return 2 === $argument; }); + + $this->scoreArgument(5)->shouldReturn(false); + } + + function its_string_representation_should_tell_that_its_callback() + { + $this->__toString()->shouldReturn('callback()'); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/ExactValueTokenSpec.php b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/ExactValueTokenSpec.php new file mode 100644 index 00000000..9e46e021 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/ExactValueTokenSpec.php @@ -0,0 +1,155 @@ +beConstructedWith(42); + } + + function it_implements_TokenInterface() + { + $this->shouldBeAnInstanceOf('Prophecy\Argument\Token\TokenInterface'); + } + + function it_is_not_last() + { + $this->shouldNotBeLast(); + } + + function it_holds_value() + { + $this->getValue()->shouldReturn(42); + } + + function it_scores_10_if_value_is_equal_to_argument() + { + $this->scoreArgument(42)->shouldReturn(10); + $this->scoreArgument('42')->shouldReturn(10); + } + + function it_scores_10_if_value_is_an_object_and_equal_to_argument() + { + $value = new \DateTime(); + $value2 = clone $value; + + $this->beConstructedWith($value); + $this->scoreArgument($value2)->shouldReturn(10); + } + + function it_does_not_scores_if_value_is_not_equal_to_argument() + { + $this->scoreArgument(50)->shouldReturn(false); + $this->scoreArgument(new \stdClass())->shouldReturn(false); + } + + function it_does_not_scores_if_value_an_object_and_is_not_equal_to_argument() + { + $value = new ExactValueTokenFixtureB('ABC'); + $value2 = new ExactValueTokenFixtureB('CBA'); + + $this->beConstructedWith($value); + $this->scoreArgument($value2)->shouldReturn(false); + } + + function it_does_not_scores_if_value_type_and_is_not_equal_to_argument() + { + $this->beConstructedWith(false); + $this->scoreArgument(0)->shouldReturn(false); + } + + function it_generates_proper_string_representation_for_integer() + { + $this->beConstructedWith(42); + $this->__toString()->shouldReturn('exact(42)'); + } + + function it_generates_proper_string_representation_for_string() + { + $this->beConstructedWith('some string'); + $this->__toString()->shouldReturn('exact("some string")'); + } + + function it_generates_single_line_representation_for_multiline_string() + { + $this->beConstructedWith("some\nstring"); + $this->__toString()->shouldReturn('exact("some\\nstring")'); + } + + function it_generates_proper_string_representation_for_double() + { + $this->beConstructedWith(42.3); + $this->__toString()->shouldReturn('exact(42.3)'); + } + + function it_generates_proper_string_representation_for_boolean_true() + { + $this->beConstructedWith(true); + $this->__toString()->shouldReturn('exact(true)'); + } + + function it_generates_proper_string_representation_for_boolean_false() + { + $this->beConstructedWith(false); + $this->__toString()->shouldReturn('exact(false)'); + } + + function it_generates_proper_string_representation_for_null() + { + $this->beConstructedWith(null); + $this->__toString()->shouldReturn('exact(null)'); + } + + function it_generates_proper_string_representation_for_empty_array() + { + $this->beConstructedWith(array()); + $this->__toString()->shouldReturn('exact([])'); + } + + function it_generates_proper_string_representation_for_array() + { + $this->beConstructedWith(array('zet', 42)); + $this->__toString()->shouldReturn('exact(["zet", 42])'); + } + + function it_generates_proper_string_representation_for_resource() + { + $resource = fopen(__FILE__, 'r'); + $this->beConstructedWith($resource); + $this->__toString()->shouldReturn('exact(stream:'.$resource.')'); + } + + /** + * @param \stdClass $object + */ + function it_generates_proper_string_representation_for_object($object) + { + $objHash = sprintf('%s:%s', + get_class($object->getWrappedObject()), + spl_object_hash($object->getWrappedObject()) + ); + + $this->beConstructedWith($object); + $this->__toString()->shouldReturn("exact($objHash Object (\n 'objectProphecy' => Prophecy\Prophecy\ObjectProphecy Object (*Prophecy*)\n))"); + } +} + +class ExactValueTokenFixtureA +{ + public $errors; +} + +class ExactValueTokenFixtureB extends ExactValueTokenFixtureA +{ + public $errors; + public $value = null; + + public function __construct($value) + { + $this->value = $value; + } +} diff --git a/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/IdenticalValueTokenSpec.php b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/IdenticalValueTokenSpec.php new file mode 100644 index 00000000..00c3a215 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/IdenticalValueTokenSpec.php @@ -0,0 +1,152 @@ +beConstructedWith(42); + } + + function it_is_initializable() + { + $this->shouldHaveType('Prophecy\Argument\Token\IdenticalValueToken'); + } + + function it_scores_11_if_string_value_is_identical_to_argument() + { + $this->beConstructedWith('foo'); + $this->scoreArgument('foo')->shouldReturn(11); + } + + function it_scores_11_if_boolean_value_is_identical_to_argument() + { + $this->beConstructedWith(false); + $this->scoreArgument(false)->shouldReturn(11); + } + + function it_scores_11_if_integer_value_is_identical_to_argument() + { + $this->beConstructedWith(31); + $this->scoreArgument(31)->shouldReturn(11); + } + + function it_scores_11_if_float_value_is_identical_to_argument() + { + $this->beConstructedWith(31.12); + $this->scoreArgument(31.12)->shouldReturn(11); + } + + function it_scores_11_if_array_value_is_identical_to_argument() + { + $this->beConstructedWith(array('foo' => 'bar')); + $this->scoreArgument(array('foo' => 'bar'))->shouldReturn(11); + } + + function it_scores_11_if_object_value_is_identical_to_argument() + { + $object = new \stdClass(); + + $this->beConstructedWith($object); + $this->scoreArgument($object)->shouldReturn(11); + } + + function it_scores_false_if_value_is_not_identical_to_argument() + { + $this->beConstructedWith(new \stdClass()); + $this->scoreArgument('foo')->shouldReturn(false); + } + + function it_scores_false_if_object_value_is_not_the_same_instance_than_argument() + { + $this->beConstructedWith(new \stdClass()); + $this->scoreArgument(new \stdClass())->shouldReturn(false); + } + + function it_scores_false_if_integer_value_is_not_identical_to_boolean_argument() + { + $this->beConstructedWith(1); + $this->scoreArgument(true)->shouldReturn(false); + } + + function it_is_not_last() + { + $this->shouldNotBeLast(); + } + + function it_generates_proper_string_representation_for_integer() + { + $this->beConstructedWith(42); + $this->__toString()->shouldReturn('identical(42)'); + } + + function it_generates_proper_string_representation_for_string() + { + $this->beConstructedWith('some string'); + $this->__toString()->shouldReturn('identical("some string")'); + } + + function it_generates_single_line_representation_for_multiline_string() + { + $this->beConstructedWith("some\nstring"); + $this->__toString()->shouldReturn('identical("some\\nstring")'); + } + + function it_generates_proper_string_representation_for_double() + { + $this->beConstructedWith(42.3); + $this->__toString()->shouldReturn('identical(42.3)'); + } + + function it_generates_proper_string_representation_for_boolean_true() + { + $this->beConstructedWith(true); + $this->__toString()->shouldReturn('identical(true)'); + } + + function it_generates_proper_string_representation_for_boolean_false() + { + $this->beConstructedWith(false); + $this->__toString()->shouldReturn('identical(false)'); + } + + function it_generates_proper_string_representation_for_null() + { + $this->beConstructedWith(null); + $this->__toString()->shouldReturn('identical(null)'); + } + + function it_generates_proper_string_representation_for_empty_array() + { + $this->beConstructedWith(array()); + $this->__toString()->shouldReturn('identical([])'); + } + + function it_generates_proper_string_representation_for_array() + { + $this->beConstructedWith(array('zet', 42)); + $this->__toString()->shouldReturn('identical(["zet", 42])'); + } + + function it_generates_proper_string_representation_for_resource() + { + $resource = fopen(__FILE__, 'r'); + $this->beConstructedWith($resource); + $this->__toString()->shouldReturn('identical(stream:'.$resource.')'); + } + + function it_generates_proper_string_representation_for_object($object) + { + $objHash = sprintf('%s:%s', + get_class($object->getWrappedObject()), + spl_object_hash($object->getWrappedObject()) + ); + + $this->beConstructedWith($object); + $this->__toString()->shouldReturn("identical($objHash Object (\n 'objectProphecy' => Prophecy\Prophecy\ObjectProphecy Object (*Prophecy*)\n))"); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/LogicalAndTokenSpec.php b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/LogicalAndTokenSpec.php new file mode 100644 index 00000000..bb5e3840 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/LogicalAndTokenSpec.php @@ -0,0 +1,78 @@ +beConstructedWith(array()); + $this->shouldBeAnInstanceOf('Prophecy\Argument\Token\TokenInterface'); + } + + function it_is_not_last() + { + $this->beConstructedWith(array()); + $this->shouldNotBeLast(); + } + + /** + * @param \Prophecy\Argument\Token\TokenInterface $token1 + * @param \Prophecy\Argument\Token\TokenInterface $token2 + * @param \Prophecy\Argument\Token\TokenInterface $token3 + */ + function it_generates_string_representation_from_all_tokens_imploded($token1, $token2, $token3) + { + $token1->__toString()->willReturn('token_1'); + $token2->__toString()->willReturn('token_2'); + $token3->__toString()->willReturn('token_3'); + + $this->beConstructedWith(array($token1, $token2, $token3)); + $this->__toString()->shouldReturn('bool(token_1 AND token_2 AND token_3)'); + } + + function it_wraps_non_token_arguments_into_ExactValueToken() + { + $this->beConstructedWith(array(15, '1985')); + $this->__toString()->shouldReturn("bool(exact(15) AND exact(\"1985\"))"); + } + + /** + * @param \Prophecy\Argument\Token\TokenInterface $token1 + * @param \Prophecy\Argument\Token\TokenInterface $token2 + */ + function it_scores_the_maximum_score_from_all_scores_returned_by_tokens($token1, $token2) + { + $token1->scoreArgument(1)->willReturn(10); + $token2->scoreArgument(1)->willReturn(5); + $this->beConstructedWith(array($token1, $token2)); + $this->scoreArgument(1)->shouldReturn(10); + } + + function it_does_not_score_if_there_are_no_arguments_or_tokens() + { + $this->beConstructedWith(array()); + $this->scoreArgument('any')->shouldReturn(false); + } + + /** + * @param \Prophecy\Argument\Token\TokenInterface $token1 + * @param \Prophecy\Argument\Token\TokenInterface $token2 + */ + function it_does_not_score_if_either_of_tokens_does_not_score($token1, $token2) + { + $token1->scoreArgument(1)->willReturn(10); + $token1->scoreArgument(2)->willReturn(false); + + $token2->scoreArgument(1)->willReturn(false); + $token2->scoreArgument(2)->willReturn(10); + + $this->beConstructedWith(array($token1, $token2)); + + $this->scoreArgument(1)->shouldReturn(false); + $this->scoreArgument(2)->shouldReturn(false); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/LogicalNotTokenSpec.php b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/LogicalNotTokenSpec.php new file mode 100644 index 00000000..7ce7f3d8 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/LogicalNotTokenSpec.php @@ -0,0 +1,65 @@ +beConstructedWith($token); + } + + function it_implements_TokenInterface() + { + $this->shouldBeAnInstanceOf('Prophecy\Argument\Token\TokenInterface'); + } + + function it_holds_originating_token($token) + { + $this->getOriginatingToken()->shouldReturn($token); + } + + function it_has_simple_string_representation($token) + { + $token->__toString()->willReturn('value'); + $this->__toString()->shouldBe('not(value)'); + } + + function it_wraps_non_token_argument_into_ExactValueToken() + { + $this->beConstructedWith(5); + $token = $this->getOriginatingToken(); + $token->shouldhaveType('Prophecy\Argument\Token\ExactValueToken'); + $token->getValue()->shouldBe(5); + } + + function it_scores_4_if_preset_token_does_not_match_the_argument($token) + { + $token->scoreArgument('argument')->willReturn(false); + $this->scoreArgument('argument')->shouldBe(4); + } + + function it_does_not_score_if_preset_token_matches_argument($token) + { + $token->scoreArgument('argument')->willReturn(5); + $this->scoreArgument('argument')->shouldBe(false); + } + + function it_is_last_if_preset_token_is_last($token) + { + $token->isLast()->willReturn(true); + $this->shouldBeLast(); + } + + function it_is_not_last_if_preset_token_is_not_last($token) + { + $token->isLast()->willReturn(false); + $this->shouldNotBeLast(); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/ObjectStateTokenSpec.php b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/ObjectStateTokenSpec.php new file mode 100644 index 00000000..a783a15f --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/ObjectStateTokenSpec.php @@ -0,0 +1,101 @@ +beConstructedWith('getName', 'stdClass'); + } + + function it_implements_TokenInterface() + { + $this->shouldBeAnInstanceOf('Prophecy\Argument\Token\TokenInterface'); + } + + function it_is_not_last() + { + $this->shouldNotBeLast(); + } + + /** + * @param \ReflectionClass $reflection + */ + function it_scores_8_if_argument_object_has_specific_method_state($reflection) + { + $reflection->getName()->willReturn('stdClass'); + + $this->scoreArgument($reflection)->shouldReturn(8); + } + + /** + * @param \stdClass $class + */ + function it_scores_8_if_argument_object_has_specific_property_state($class) + { + $class->getName = 'stdClass'; + + $this->scoreArgument($class)->shouldReturn(8); + } + + function it_does_not_score_if_argument_method_state_does_not_match() + { + $value = new ObjectStateTokenFixtureB('ABC'); + $value2 = new ObjectStateTokenFixtureB('CBA'); + + $this->beConstructedWith('getSelf', $value); + $this->scoreArgument($value2)->shouldReturn(false); + } + + /** + * @param \stdClass $class + */ + function it_does_not_score_if_argument_property_state_does_not_match($class) + { + $class->getName = 'SplFileInfo'; + + $this->scoreArgument($class)->shouldReturn(false); + } + + /** + * @param \spec\Prophecy\Argument\Token\ObjectStateTokenFixtureA $class + */ + function it_does_not_score_if_argument_object_does_not_have_method_or_property($class) + { + $this->scoreArgument($class)->shouldReturn(false); + } + + function it_does_not_score_if_argument_is_not_object() + { + $this->scoreArgument(42)->shouldReturn(false); + } + + function it_has_simple_string_representation() + { + $this->__toString()->shouldReturn('state(getName(), "stdClass")'); + } +} + +class ObjectStateTokenFixtureA +{ + public $errors; +} + +class ObjectStateTokenFixtureB extends ObjectStateTokenFixtureA +{ + public $errors; + public $value = null; + + public function __construct($value) + { + $this->value = $value; + } + + public function getSelf() + { + return $this; + } +} diff --git a/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/StringContainsTokenSpec.php b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/StringContainsTokenSpec.php new file mode 100644 index 00000000..c7fd2652 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/StringContainsTokenSpec.php @@ -0,0 +1,49 @@ +beConstructedWith('a substring'); + } + + function it_is_initializable() + { + $this->shouldHaveType('Prophecy\Argument\Token\StringContainsToken'); + } + + function it_implements_TokenInterface() + { + $this->shouldBeAnInstanceOf('Prophecy\Argument\Token\TokenInterface'); + } + + function it_holds_value() + { + $this->getValue()->shouldReturn('a substring'); + } + + function it_is_not_last() + { + $this->shouldNotBeLast(); + } + + function it_scores_6_if_the_argument_contains_the_value() + { + $this->scoreArgument('Argument containing a substring')->shouldReturn(6); + } + + function it_does_not_score_if_the_argument_does_not_contain_the_value() + { + $this->scoreArgument('Argument will not match')->shouldReturn(false); + } + + function its_string_representation_shows_substring() + { + $this->__toString()->shouldReturn('contains("a substring")'); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/TypeTokenSpec.php b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/TypeTokenSpec.php new file mode 100644 index 00000000..ae3e26e4 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/TypeTokenSpec.php @@ -0,0 +1,62 @@ +beConstructedWith('integer'); + } + + function it_implements_TokenInterface() + { + $this->shouldBeAnInstanceOf('Prophecy\Argument\Token\TokenInterface'); + } + + function it_is_not_last() + { + $this->shouldNotBeLast(); + } + + function it_scores_5_if_argument_matches_simple_type() + { + $this->beConstructedWith('integer'); + + $this->scoreArgument(42)->shouldReturn(5); + } + + function it_does_not_scores_if_argument_does_not_match_simple_type() + { + $this->beConstructedWith('integer'); + + $this->scoreArgument(42.0)->shouldReturn(false); + } + + /** + * @param \ReflectionObject $object + */ + function it_scores_5_if_argument_is_an_instance_of_specified_class($object) + { + $this->beConstructedWith('ReflectionClass'); + + $this->scoreArgument($object)->shouldReturn(5); + } + + function it_has_simple_string_representation() + { + $this->__toString()->shouldReturn('type(integer)'); + } + + /** + * @param \Prophecy\Argument\Token\TokenInterface $interface + */ + function it_scores_5_if_argument_is_an_instance_of_specified_interface($interface) + { + $this->beConstructedWith('Prophecy\Argument\Token\TokenInterface'); + + $this->scoreArgument($interface)->shouldReturn(5); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/spec/Prophecy/ArgumentSpec.php b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/ArgumentSpec.php new file mode 100644 index 00000000..64232a4d --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/ArgumentSpec.php @@ -0,0 +1,107 @@ +exact(42); + $token->shouldBeAnInstanceOf('Prophecy\Argument\Token\ExactValueToken'); + $token->getValue()->shouldReturn(42); + } + + function it_has_a_shortcut_for_any_argument_token() + { + $token = $this->any(); + $token->shouldBeAnInstanceOf('Prophecy\Argument\Token\AnyValueToken'); + } + + function it_has_a_shortcut_for_multiple_arguments_token() + { + $token = $this->cetera(); + $token->shouldBeAnInstanceOf('Prophecy\Argument\Token\AnyValuesToken'); + } + + function it_has_a_shortcut_for_type_token() + { + $token = $this->type('integer'); + $token->shouldBeAnInstanceOf('Prophecy\Argument\Token\TypeToken'); + } + + function it_has_a_shortcut_for_callback_token() + { + $token = $this->that('get_class'); + $token->shouldBeAnInstanceOf('Prophecy\Argument\Token\CallbackToken'); + } + + function it_has_a_shortcut_for_object_state_token() + { + $token = $this->which('getName', 'everzet'); + $token->shouldBeAnInstanceOf('Prophecy\Argument\Token\ObjectStateToken'); + } + + function it_has_a_shortcut_for_logical_and_token() + { + $token = $this->allOf('integer', 5); + $token->shouldBeAnInstanceOf('Prophecy\Argument\Token\LogicalAndToken'); + } + + function it_has_a_shortcut_for_array_count_token() + { + $token = $this->size(5); + $token->shouldBeAnInstanceOf('Prophecy\Argument\Token\ArrayCountToken'); + } + + function it_has_a_shortcut_for_array_entry_token() + { + $token = $this->withEntry('key', 'value'); + $token->shouldBeAnInstanceOf('Prophecy\Argument\Token\ArrayEntryToken'); + } + + function it_has_a_shortcut_for_array_every_entry_token() + { + $token = $this->withEveryEntry('value'); + $token->shouldBeAnInstanceOf('Prophecy\Argument\Token\ArrayEveryEntryToken'); + } + + function it_has_a_shortcut_for_identical_value_token() + { + $token = $this->is('value'); + $token->shouldBeAnInstanceOf('Prophecy\Argument\Token\IdenticalValueToken'); + } + + function it_has_a_shortcut_for_array_entry_token_matching_any_key() + { + $token = $this->containing('value'); + $token->shouldBeAnInstanceOf('Prophecy\Argument\Token\ArrayEntryToken'); + $token->getKey()->shouldHaveType('Prophecy\Argument\Token\AnyValueToken'); + } + + function it_has_a_shortcut_for_array_entry_token_matching_any_value() + { + $token = $this->withKey('key'); + $token->shouldBeAnInstanceOf('Prophecy\Argument\Token\ArrayEntryToken'); + $token->getValue()->shouldHaveType('Prophecy\Argument\Token\AnyValueToken'); + } + + function it_has_a_shortcut_for_logical_not_token() + { + $token = $this->not('kagux'); + $token->shouldBeAnInstanceOf('Prophecy\Argument\Token\LogicalNotToken'); + } + + function it_has_a_shortcut_for_string_contains_token() + { + $token = $this->containingString('string'); + $token->shouldBeAnInstanceOf('Prophecy\Argument\Token\StringContainsToken'); + } + + function it_has_a_shortcut_for_approximate_token() + { + $token = $this->approximate(10); + $token->shouldBeAnInstanceOf('Prophecy\Argument\Token\ApproximateValueToken'); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Call/CallCenterSpec.php b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Call/CallCenterSpec.php new file mode 100644 index 00000000..acf8d783 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Call/CallCenterSpec.php @@ -0,0 +1,195 @@ +scoreArguments(array(5, 2, 3))->willReturn(10); + $objectProphecy->getMethodProphecies()->willReturn(array()); + + $this->makeCall($objectProphecy, 'setValues', array(5, 2, 3)); + + $calls = $this->findCalls('setValues', $wildcard); + $calls->shouldHaveCount(1); + + $calls[0]->shouldBeAnInstanceOf('Prophecy\Call\Call'); + $calls[0]->getMethodName()->shouldReturn('setValues'); + $calls[0]->getArguments()->shouldReturn(array(5, 2, 3)); + $calls[0]->getReturnValue()->shouldReturn(null); + } + + function it_returns_null_for_any_call_through_makeCall_if_no_method_prophecies_added( + $objectProphecy + ) + { + $objectProphecy->getMethodProphecies()->willReturn(array()); + + $this->makeCall($objectProphecy, 'setValues', array(5, 2, 3))->shouldReturn(null); + } + + /** + * @param \Prophecy\Prophecy\MethodProphecy $method1 + * @param \Prophecy\Prophecy\MethodProphecy $method2 + * @param \Prophecy\Prophecy\MethodProphecy $method3 + * @param \Prophecy\Argument\ArgumentsWildcard $arguments1 + * @param \Prophecy\Argument\ArgumentsWildcard $arguments2 + * @param \Prophecy\Argument\ArgumentsWildcard $arguments3 + * @param \Prophecy\Promise\PromiseInterface $promise + */ + function it_executes_promise_of_method_prophecy_that_matches_signature_passed_to_makeCall( + $objectProphecy, $method1, $method2, $method3, $arguments1, $arguments2, $arguments3, + $promise + ) + { + $method1->getMethodName()->willReturn('getName'); + $method1->getArgumentsWildcard()->willReturn($arguments1); + $arguments1->scoreArguments(array('world', 'everything'))->willReturn(false); + + $method2->getMethodName()->willReturn('setTitle'); + $method2->getArgumentsWildcard()->willReturn($arguments2); + $arguments2->scoreArguments(array('world', 'everything'))->willReturn(false); + + $method3->getMethodName()->willReturn('getName'); + $method3->getArgumentsWildcard()->willReturn($arguments3); + $method3->getPromise()->willReturn($promise); + $arguments3->scoreArguments(array('world', 'everything'))->willReturn(200); + + $objectProphecy->getMethodProphecies()->willReturn(array( + 'method1' => array($method1), + 'method2' => array($method2, $method3) + )); + $objectProphecy->getMethodProphecies('getName')->willReturn(array($method1, $method3)); + $objectProphecy->reveal()->willReturn(new \stdClass()); + + $promise->execute(array('world', 'everything'), $objectProphecy->getWrappedObject(), $method3)->willReturn(42); + + $this->makeCall($objectProphecy, 'getName', array('world', 'everything'))->shouldReturn(42); + + $calls = $this->findCalls('getName', $arguments3); + $calls->shouldHaveCount(1); + $calls[0]->getReturnValue()->shouldReturn(42); + } + + /** + * @param \Prophecy\Prophecy\MethodProphecy $method1 + * @param \Prophecy\Prophecy\MethodProphecy $method2 + * @param \Prophecy\Prophecy\MethodProphecy $method3 + * @param \Prophecy\Argument\ArgumentsWildcard $arguments1 + * @param \Prophecy\Argument\ArgumentsWildcard $arguments2 + * @param \Prophecy\Argument\ArgumentsWildcard $arguments3 + * @param \Prophecy\Promise\PromiseInterface $promise + */ + function it_executes_promise_of_method_prophecy_that_matches_with_highest_score_to_makeCall( + $objectProphecy, $method1, $method2, $method3, $arguments1, $arguments2, $arguments3, + $promise + ) + { + $method1->getMethodName()->willReturn('getName'); + $method1->getArgumentsWildcard()->willReturn($arguments1); + $arguments1->scoreArguments(array('world', 'everything'))->willReturn(50); + + $method2->getMethodName()->willReturn('getName'); + $method2->getArgumentsWildcard()->willReturn($arguments2); + $method2->getPromise()->willReturn($promise); + $arguments2->scoreArguments(array('world', 'everything'))->willReturn(300); + + $method3->getMethodName()->willReturn('getName'); + $method3->getArgumentsWildcard()->willReturn($arguments3); + $arguments3->scoreArguments(array('world', 'everything'))->willReturn(200); + + $objectProphecy->getMethodProphecies()->willReturn(array( + 'method1' => array($method1), + 'method2' => array($method2, $method3) + )); + $objectProphecy->getMethodProphecies('getName')->willReturn(array( + $method1, $method2, $method3 + )); + $objectProphecy->reveal()->willReturn(new \stdClass()); + + $promise->execute(array('world', 'everything'), $objectProphecy->getWrappedObject(), $method2) + ->willReturn('second'); + + $this->makeCall($objectProphecy, 'getName', array('world', 'everything')) + ->shouldReturn('second'); + } + + /** + * @param \Prophecy\Prophecy\MethodProphecy $method + * @param \Prophecy\Argument\ArgumentsWildcard $arguments + */ + function it_throws_exception_if_call_does_not_match_any_of_defined_method_prophecies( + $objectProphecy, $method, $arguments + ) + { + $method->getMethodName()->willReturn('getName'); + $method->getArgumentsWildcard()->willReturn($arguments); + $arguments->scoreArguments(array('world', 'everything'))->willReturn(false); + $arguments->__toString()->willReturn('arg1, arg2'); + + $objectProphecy->getMethodProphecies()->willReturn(array('method1' => array($method))); + $objectProphecy->getMethodProphecies('getName')->willReturn(array($method)); + + $this->shouldThrow('Prophecy\Exception\Call\UnexpectedCallException') + ->duringMakeCall($objectProphecy, 'getName', array('world', 'everything')); + } + + /** + * @param \Prophecy\Prophecy\MethodProphecy $method + * @param \Prophecy\Argument\ArgumentsWildcard $arguments + */ + function it_returns_null_if_method_prophecy_that_matches_makeCall_arguments_has_no_promise( + $objectProphecy, $method, $arguments + ) + { + $method->getMethodName()->willReturn('getName'); + $method->getArgumentsWildcard()->willReturn($arguments); + $method->getPromise()->willReturn(null); + $arguments->scoreArguments(array('world', 'everything'))->willReturn(100); + + $objectProphecy->getMethodProphecies()->willReturn(array($method)); + $objectProphecy->getMethodProphecies('getName')->willReturn(array($method)); + + $this->makeCall($objectProphecy, 'getName', array('world', 'everything')) + ->shouldReturn(null); + } + + /** + * @param \Prophecy\Argument\ArgumentsWildcard $wildcard + */ + function it_finds_recorded_calls_by_a_method_name_and_arguments_wildcard( + $objectProphecy, $wildcard + ) + { + $objectProphecy->getMethodProphecies()->willReturn(array()); + + $this->makeCall($objectProphecy, 'getName', array('world')); + $this->makeCall($objectProphecy, 'getName', array('everything')); + $this->makeCall($objectProphecy, 'setName', array(42)); + + $wildcard->scoreArguments(array('world'))->willReturn(false); + $wildcard->scoreArguments(array('everything'))->willReturn(10); + + $calls = $this->findCalls('getName', $wildcard); + + $calls->shouldHaveCount(1); + $calls[0]->getMethodName()->shouldReturn('getName'); + $calls[0]->getArguments()->shouldReturn(array('everything')); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Call/CallSpec.php b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Call/CallSpec.php new file mode 100644 index 00000000..d1a85391 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Call/CallSpec.php @@ -0,0 +1,54 @@ +beConstructedWith('setValues', array(5, 2), 42, $exception, 'some_file.php', 23); + } + + function it_exposes_method_name_through_getter() + { + $this->getMethodName()->shouldReturn('setValues'); + } + + function it_exposes_arguments_through_getter() + { + $this->getArguments()->shouldReturn(array(5, 2)); + } + + function it_exposes_return_value_through_getter() + { + $this->getReturnValue()->shouldReturn(42); + } + + function it_exposes_exception_through_getter($exception) + { + $this->getException()->shouldReturn($exception); + } + + function it_exposes_file_and_line_through_getter() + { + $this->getFile()->shouldReturn('some_file.php'); + $this->getLine()->shouldReturn(23); + } + + function it_returns_shortpath_to_callPlace() + { + $this->getCallPlace()->shouldReturn('some_file.php:23'); + } + + function it_returns_unknown_as_callPlace_if_no_file_or_line_provided() + { + $this->beConstructedWith('setValues', array(), 0, null, null, null); + + $this->getCallPlace()->shouldReturn('unknown'); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Comparator/ClosureComparatorSpec.php b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Comparator/ClosureComparatorSpec.php new file mode 100644 index 00000000..c174e73c --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Comparator/ClosureComparatorSpec.php @@ -0,0 +1,39 @@ +shouldHaveType('SebastianBergmann\Comparator\Comparator'); + } + + function it_accepts_only_closures() + { + $this->accepts(123, 321)->shouldReturn(false); + $this->accepts('string', 'string')->shouldReturn(false); + $this->accepts(false, true)->shouldReturn(false); + $this->accepts(true, false)->shouldReturn(false); + $this->accepts((object)array(), (object)array())->shouldReturn(false); + $this->accepts(function(){}, (object)array())->shouldReturn(false); + $this->accepts(function(){}, (object)array())->shouldReturn(false); + + $this->accepts(function(){}, function(){})->shouldReturn(true); + } + + function it_asserts_that_all_closures_are_different() + { + $this->shouldThrow()->duringAssertEquals(function(){}, function(){}); + } + + function it_asserts_that_all_closures_are_different_even_if_its_the_same_closure() + { + $closure = function(){}; + + $this->shouldThrow()->duringAssertEquals($closure, $closure); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Comparator/FactorySpec.php b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Comparator/FactorySpec.php new file mode 100644 index 00000000..6b13336d --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Comparator/FactorySpec.php @@ -0,0 +1,20 @@ +shouldHaveType('SebastianBergmann\Comparator\Factory'); + } + + function it_should_have_ClosureComparator_registered() + { + $comparator = $this->getInstance()->getComparatorFor(function(){}, function(){}); + $comparator->shouldHaveType('Prophecy\Comparator\ClosureComparator'); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Comparator/ProphecyComparatorSpec.php b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Comparator/ProphecyComparatorSpec.php new file mode 100644 index 00000000..06bf6f17 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Comparator/ProphecyComparatorSpec.php @@ -0,0 +1,39 @@ +shouldHaveType('SebastianBergmann\Comparator\ObjectComparator'); + } + + function it_accepts_only_prophecy_objects() + { + $this->accepts(123, 321)->shouldReturn(false); + $this->accepts('string', 'string')->shouldReturn(false); + $this->accepts(false, true)->shouldReturn(false); + $this->accepts(true, false)->shouldReturn(false); + $this->accepts((object)array(), (object)array())->shouldReturn(false); + $this->accepts(function(){}, (object)array())->shouldReturn(false); + $this->accepts(function(){}, function(){})->shouldReturn(false); + + $prophet = new Prophet(); + $prophecy = $prophet->prophesize('Prophecy\Prophecy\ObjectProphecy'); + + $this->accepts($prophecy, $prophecy)->shouldReturn(true); + } + + function it_asserts_that_an_object_is_equal_to_its_revealed_prophecy() + { + $prophet = new Prophet(); + $prophecy = $prophet->prophesize('Prophecy\Prophecy\ObjectProphecy'); + + $this->shouldNotThrow()->duringAssertEquals($prophecy->reveal(), $prophecy); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/ClassPatch/DisableConstructorPatchSpec.php b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/ClassPatch/DisableConstructorPatchSpec.php new file mode 100644 index 00000000..2d7d934d --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/ClassPatch/DisableConstructorPatchSpec.php @@ -0,0 +1,59 @@ +shouldBeAnInstanceOf('Prophecy\Doubler\ClassPatch\ClassPatchInterface'); + } + + function its_priority_is_100() + { + $this->getPriority()->shouldReturn(100); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\ClassNode $node + */ + function it_supports_anything($node) + { + $this->supports($node)->shouldReturn(true); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\ClassNode $class + * @param \Prophecy\Doubler\Generator\Node\MethodNode $method + * @param \Prophecy\Doubler\Generator\Node\ArgumentNode $arg1 + * @param \Prophecy\Doubler\Generator\Node\ArgumentNode $arg2 + */ + function it_makes_all_constructor_arguments_optional($class, $method, $arg1, $arg2) + { + $class->hasMethod('__construct')->willReturn(true); + $class->getMethod('__construct')->willReturn($method); + $method->getArguments()->willReturn(array($arg1, $arg2)); + + $arg1->setDefault(null)->shouldBeCalled(); + $arg2->setDefault(null)->shouldBeCalled(); + + $method->setCode(Argument::type('string'))->shouldBeCalled(); + + $this->apply($class); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\ClassNode $class + */ + function it_creates_new_constructor_if_object_has_none($class) + { + $class->hasMethod('__construct')->willReturn(false); + $class->addMethod(Argument::type('Prophecy\Doubler\Generator\Node\MethodNode')) + ->shouldBeCalled(); + + $this->apply($class); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/ClassPatch/HhvmExceptionPatchSpec.php b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/ClassPatch/HhvmExceptionPatchSpec.php new file mode 100644 index 00000000..8c348b86 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/ClassPatch/HhvmExceptionPatchSpec.php @@ -0,0 +1,37 @@ +shouldBeAnInstanceOf('Prophecy\Doubler\ClassPatch\ClassPatchInterface'); + } + + function its_priority_is_minus_50() + { + $this->getPriority()->shouldReturn(-50); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\ClassNode $node + * @param \Prophecy\Doubler\Generator\Node\MethodNode $method + * @param \Prophecy\Doubler\Generator\Node\MethodNode $getterMethod + */ + function it_uses_parent_code_for_setTraceOptions($node, $method, $getterMethod) + { + $node->hasMethod('setTraceOptions')->willReturn(true); + $node->getMethod('setTraceOptions')->willReturn($method); + $node->hasMethod('getTraceOptions')->willReturn(true); + $node->getMethod('getTraceOptions')->willReturn($getterMethod); + + $method->useParentCode()->shouldBeCalled(); + $getterMethod->useParentCode()->shouldBeCalled(); + + $this->apply($node); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/ClassPatch/KeywordPatchSpec.php b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/ClassPatch/KeywordPatchSpec.php new file mode 100644 index 00000000..200d9619 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/ClassPatch/KeywordPatchSpec.php @@ -0,0 +1,44 @@ +shouldBeAnInstanceOf('Prophecy\Doubler\ClassPatch\ClassPatchInterface'); + } + + function its_priority_is_49() + { + $this->getPriority()->shouldReturn(49); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\ClassNode $node + * @param \Prophecy\Doubler\Generator\Node\MethodNode $method1 + * @param \Prophecy\Doubler\Generator\Node\MethodNode $method2 + * @param \Prophecy\Doubler\Generator\Node\MethodNode $method3 + */ + function it_will_remove_echo_and_eval_methods($node, $method1, $method2, $method3) + { + $node->removeMethod('eval')->shouldBeCalled(); + $node->removeMethod('echo')->shouldBeCalled(); + + $method1->getName()->willReturn('echo'); + $method2->getName()->willReturn('eval'); + $method3->getName()->willReturn('notKeyword'); + + $node->getMethods()->willReturn(array( + 'echo' => $method1, + 'eval' => $method2, + 'notKeyword' => $method3, + )); + + $this->apply($node); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/ClassPatch/MagicCallPatchSpec.php b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/ClassPatch/MagicCallPatchSpec.php new file mode 100644 index 00000000..edd8b80d --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/ClassPatch/MagicCallPatchSpec.php @@ -0,0 +1,125 @@ +shouldBeAnInstanceOf('Prophecy\Doubler\ClassPatch\ClassPatchInterface'); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\ClassNode $node + */ + function it_supports_anything($node) + { + $this->supports($node)->shouldReturn(true); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\ClassNode $node + */ + function it_discovers_api_using_phpdoc($node) + { + $node->getParentClass()->willReturn('spec\Prophecy\Doubler\ClassPatch\MagicalApi'); + + $node->addMethod(new MethodNode('undefinedMethod'))->shouldBeCalled(); + + $this->apply($node); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\ClassNode $node + */ + function it_ignores_existing_methods($node) + { + $node->getParentClass()->willReturn('spec\Prophecy\Doubler\ClassPatch\MagicalApiExtended'); + + $node->addMethod(new MethodNode('undefinedMethod'))->shouldBeCalled(); + $node->addMethod(new MethodNode('definedMethod'))->shouldNotBeCalled(); + + $this->apply($node); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\ClassNode $node + */ + function it_ignores_empty_methods_from_phpdoc($node) + { + $node->getParentClass()->willReturn('spec\Prophecy\Doubler\ClassPatch\MagicalApiInvalidMethodDefinition'); + + $node->addMethod(new MethodNode(''))->shouldNotBeCalled(); + + $this->apply($node); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\ClassNode $node + */ + function it_discovers_api_using_phpdoc_from_interface($node) + { + $node->getParentClass()->willReturn('spec\Prophecy\Doubler\ClassPatch\MagicalApiImplemented'); + + $node->addMethod(new MethodNode('implementedMethod'))->shouldBeCalled(); + + $this->apply($node); + } + + + function it_has_50_priority() + { + $this->getPriority()->shouldReturn(50); + } +} + +/** + * @method void undefinedMethod() + */ +class MagicalApi +{ + /** + * @return void + */ + public function definedMethod() + { + + } +} + +/** + * @method void invalidMethodDefinition + * @method void + * @method + */ +class MagicalApiInvalidMethodDefinition +{ +} + +/** + * @method void undefinedMethod() + * @method void definedMethod() + */ +class MagicalApiExtended extends MagicalApi +{ + +} + +/** + */ +class MagicalApiImplemented implements MagicalApiInterface +{ + +} + +/** + * @method void implementedMethod() + */ +interface MagicalApiInterface +{ + +} diff --git a/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/ClassPatch/ProphecySubjectPatchSpec.php b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/ClassPatch/ProphecySubjectPatchSpec.php new file mode 100644 index 00000000..c460814c --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/ClassPatch/ProphecySubjectPatchSpec.php @@ -0,0 +1,83 @@ +shouldBeAnInstanceOf('Prophecy\Doubler\ClassPatch\ClassPatchInterface'); + } + + function it_has_priority_of_0() + { + $this->getPriority()->shouldReturn(0); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\ClassNode $node + */ + function it_supports_any_class($node) + { + $this->supports($node)->shouldReturn(true); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\ClassNode $node + */ + function it_forces_class_to_implement_ProphecySubjectInterface($node) + { + $node->addInterface('Prophecy\Prophecy\ProphecySubjectInterface')->shouldBeCalled(); + + $node->addProperty('objectProphecy', 'private')->willReturn(null); + $node->getMethods()->willReturn(array()); + $node->hasMethod(Argument::any())->willReturn(false); + $node->addMethod(Argument::type('Prophecy\Doubler\Generator\Node\MethodNode'))->willReturn(null); + $node->addMethod(Argument::type('Prophecy\Doubler\Generator\Node\MethodNode'))->willReturn(null); + + $this->apply($node); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\ClassNode $node + * @param \Prophecy\Doubler\Generator\Node\MethodNode $constructor + * @param \Prophecy\Doubler\Generator\Node\MethodNode $method1 + * @param \Prophecy\Doubler\Generator\Node\MethodNode $method2 + * @param \Prophecy\Doubler\Generator\Node\MethodNode $method3 + */ + function it_forces_all_class_methods_except_constructor_to_proxy_calls_into_prophecy_makeCall( + $node, $constructor, $method1, $method2, $method3 + ) + { + $node->addInterface('Prophecy\Prophecy\ProphecySubjectInterface')->willReturn(null); + $node->addProperty('objectProphecy', 'private')->willReturn(null); + $node->hasMethod(Argument::any())->willReturn(false); + $node->addMethod(Argument::type('Prophecy\Doubler\Generator\Node\MethodNode'))->willReturn(null); + $node->addMethod(Argument::type('Prophecy\Doubler\Generator\Node\MethodNode'))->willReturn(null); + + $constructor->getName()->willReturn('__construct'); + $method1->getName()->willReturn('method1'); + $method2->getName()->willReturn('method2'); + $method3->getName()->willReturn('method3'); + + $node->getMethods()->willReturn(array( + 'method1' => $method1, + 'method2' => $method2, + 'method3' => $method3, + )); + + $constructor->setCode(Argument::any())->shouldNotBeCalled(); + + $method1->setCode('return $this->getProphecy()->makeProphecyMethodCall(__FUNCTION__, func_get_args());') + ->shouldBeCalled(); + $method2->setCode('return $this->getProphecy()->makeProphecyMethodCall(__FUNCTION__, func_get_args());') + ->shouldBeCalled(); + $method3->setCode('return $this->getProphecy()->makeProphecyMethodCall(__FUNCTION__, func_get_args());') + ->shouldBeCalled(); + + $this->apply($node); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/ClassPatch/ReflectionClassNewInstancePatchSpec.php b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/ClassPatch/ReflectionClassNewInstancePatchSpec.php new file mode 100644 index 00000000..4116e4df --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/ClassPatch/ReflectionClassNewInstancePatchSpec.php @@ -0,0 +1,47 @@ +shouldBeAnInstanceOf('Prophecy\Doubler\ClassPatch\ClassPatchInterface'); + } + + function its_priority_is_50() + { + $this->getPriority()->shouldReturn(50); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\ClassNode $reflectionClassNode + * @param \Prophecy\Doubler\Generator\Node\ClassNode $anotherClassNode + */ + function it_supports_ReflectionClass_only($reflectionClassNode, $anotherClassNode) + { + $reflectionClassNode->getParentClass()->willReturn('ReflectionClass'); + $anotherClassNode->getParentClass()->willReturn('stdClass'); + + $this->supports($reflectionClassNode)->shouldReturn(true); + $this->supports($anotherClassNode)->shouldReturn(false); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\ClassNode $class + * @param \Prophecy\Doubler\Generator\Node\MethodNode $method + * @param \Prophecy\Doubler\Generator\Node\ArgumentNode $arg1 + * @param \Prophecy\Doubler\Generator\Node\ArgumentNode $arg2 + */ + function it_makes_all_newInstance_arguments_optional($class, $method, $arg1, $arg2) + { + $class->getMethod('newInstance')->willReturn($method); + $method->getArguments()->willReturn(array($arg1)); + $arg1->setDefault(null)->shouldBeCalled(); + + $this->apply($class); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/ClassPatch/SplFileInfoPatchSpec.php b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/ClassPatch/SplFileInfoPatchSpec.php new file mode 100644 index 00000000..42e854ac --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/ClassPatch/SplFileInfoPatchSpec.php @@ -0,0 +1,107 @@ +shouldBeAnInstanceOf('Prophecy\Doubler\ClassPatch\ClassPatchInterface'); + } + + function its_priority_is_50() + { + $this->getPriority()->shouldReturn(50); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\ClassNode $node + */ + function it_does_not_support_nodes_without_parent_class($node) + { + $node->getParentClass()->willReturn('stdClass'); + $this->supports($node)->shouldReturn(false); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\ClassNode $node + */ + function it_supports_nodes_with_SplFileInfo_as_parent_class($node) + { + $node->getParentClass()->willReturn('SplFileInfo'); + $this->supports($node)->shouldReturn(true); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\ClassNode $node + */ + function it_supports_nodes_with_derivative_of_SplFileInfo_as_parent_class($node) + { + $node->getParentClass()->willReturn('SplFileInfo'); + $this->supports($node)->shouldReturn(true); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\ClassNode $node + */ + function it_adds_a_method_to_node_if_not_exists($node) + { + $node->hasMethod('__construct')->willReturn(false); + $node->addMethod(Argument::any())->shouldBeCalled(); + $node->getParentClass()->shouldBeCalled(); + + $this->apply($node); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\ClassNode $node + * @param \Prophecy\Doubler\Generator\Node\MethodNode $method + */ + function it_updates_existing_method_if_found($node, $method) + { + $node->hasMethod('__construct')->willReturn(true); + $node->getMethod('__construct')->willReturn($method); + $node->getParentClass()->shouldBeCalled(); + + $method->useParentCode()->shouldBeCalled(); + + $this->apply($node); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\ClassNode $node + * @param \Prophecy\Doubler\Generator\Node\MethodNode $method + */ + function it_should_not_supply_a_file_for_a_directory_iterator($node, $method) + { + $node->hasMethod('__construct')->willReturn(true); + $node->getMethod('__construct')->willReturn($method); + $node->getParentClass()->willReturn('DirectoryIterator'); + + $method->setCode(Argument::that(function($value) { + return strpos($value, '.php') === false; + }))->shouldBeCalled(); + + $this->apply($node); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\ClassNode $node + * @param \Prophecy\Doubler\Generator\Node\MethodNode $method + */ + function it_should_supply_a_file_for_a_spl_file_object($node, $method) + { + $node->hasMethod('__construct')->willReturn(true); + $node->getMethod('__construct')->willReturn($method); + $node->getParentClass()->willReturn('SplFileObject'); + + $method->setCode(Argument::that(function($value) { + return strpos($value, '.php') !== false; + }))->shouldBeCalled(); + + $this->apply($node); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/ClassPatch/TraversablePatchSpec.php b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/ClassPatch/TraversablePatchSpec.php new file mode 100644 index 00000000..2279b720 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/ClassPatch/TraversablePatchSpec.php @@ -0,0 +1,61 @@ +shouldBeAnInstanceOf('Prophecy\Doubler\ClassPatch\ClassPatchInterface'); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\ClassNode $node + */ + function it_supports_class_that_implements_only_Traversable($node) + { + $node->getInterfaces()->willReturn(array('Traversable')); + + $this->supports($node)->shouldReturn(true); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\ClassNode $node + */ + function it_does_not_support_class_that_implements_Iterator($node) + { + $node->getInterfaces()->willReturn(array('Traversable', 'Iterator')); + + $this->supports($node)->shouldReturn(false); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\ClassNode $node + */ + function it_does_not_support_class_that_implements_IteratorAggregate($node) + { + $node->getInterfaces()->willReturn(array('Traversable', 'IteratorAggregate')); + + $this->supports($node)->shouldReturn(false); + } + + function it_has_100_priority() + { + $this->getPriority()->shouldReturn(100); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\ClassNode $node + */ + function it_forces_node_to_implement_IteratorAggregate($node) + { + $node->addInterface('Iterator')->shouldBeCalled(); + + $node->addMethod(Argument::type('Prophecy\Doubler\Generator\Node\MethodNode'))->willReturn(null); + + $this->apply($node); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/DoublerSpec.php b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/DoublerSpec.php new file mode 100644 index 00000000..a39fa87f --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/DoublerSpec.php @@ -0,0 +1,122 @@ +beConstructedWith($mirror, $creator, $namer); + } + + function it_does_not_have_patches_by_default() + { + $this->getClassPatches()->shouldHaveCount(0); + } + + /** + * @param \Prophecy\Doubler\ClassPatch\ClassPatchInterface $patch + */ + function its_registerClassPatch_adds_a_patch_to_the_doubler($patch) + { + $this->registerClassPatch($patch); + $this->getClassPatches()->shouldReturn(array($patch)); + } + + /** + * @param \Prophecy\Doubler\ClassPatch\ClassPatchInterface $alt1 + * @param \Prophecy\Doubler\ClassPatch\ClassPatchInterface $alt2 + * @param \Prophecy\Doubler\ClassPatch\ClassPatchInterface $alt3 + * @param \Prophecy\Doubler\ClassPatch\ClassPatchInterface $alt4 + */ + function its_getClassPatches_sorts_patches_by_priority($alt1, $alt2, $alt3, $alt4) + { + $alt1->getPriority()->willReturn(2); + $alt2->getPriority()->willReturn(50); + $alt3->getPriority()->willReturn(10); + $alt4->getPriority()->willReturn(0); + + $this->registerClassPatch($alt1); + $this->registerClassPatch($alt2); + $this->registerClassPatch($alt3); + $this->registerClassPatch($alt4); + + $this->getClassPatches()->shouldReturn(array($alt2, $alt3, $alt1, $alt4)); + } + + /** + * @param \Prophecy\Doubler\ClassPatch\ClassPatchInterface $alt1 + * @param \Prophecy\Doubler\ClassPatch\ClassPatchInterface $alt2 + * @param \ReflectionClass $class + * @param \ReflectionClass $interface1 + * @param \ReflectionClass $interface2 + * @param \Prophecy\Doubler\Generator\Node\ClassNode $node + */ + function its_double_mirrors_alterates_and_instantiates_provided_class( + $mirror, $creator, $namer, $alt1, $alt2, $class, $interface1, $interface2, $node + ) + { + $mirror->reflect($class, array($interface1, $interface2))->willReturn($node); + $alt1->supports($node)->willReturn(true); + $alt2->supports($node)->willReturn(false); + $alt1->getPriority()->willReturn(1); + $alt2->getPriority()->willReturn(2); + $namer->name($class, array($interface1, $interface2))->willReturn('SplStack'); + $class->getName()->willReturn('stdClass'); + $interface1->getName()->willReturn('ArrayAccess'); + $interface2->getName()->willReturn('Iterator'); + + $alt1->apply($node)->shouldBeCalled(); + $alt2->apply($node)->shouldNotBeCalled(); + $creator->create('SplStack', $node)->shouldBeCalled(); + + $this->registerClassPatch($alt1); + $this->registerClassPatch($alt2); + + $this->double($class, array($interface1, $interface2)) + ->shouldReturnAnInstanceOf('SplStack'); + } + + /** + * @param \ReflectionClass $class + * @param \Prophecy\Doubler\Generator\Node\ClassNode $node + */ + function it_double_instantiates_a_class_with_constructor_argument($mirror, $class, $node, $namer) + { + $class->getName()->willReturn('ReflectionClass'); + $mirror->reflect($class, array())->willReturn($node); + $namer->name($class, array())->willReturn('ReflectionClass'); + + $double = $this->double($class, array(), array('stdClass')); + $double->shouldBeAnInstanceOf('ReflectionClass'); + $double->getName()->shouldReturn('stdClass'); + } + + /** + * @param \ReflectionClass $class + * @param \Prophecy\Doubler\Generator\Node\ClassNode $node + */ + function it_can_instantiate_class_with_final_constructor($mirror, $class, $node, $namer) + { + $class->getName()->willReturn('spec\Prophecy\Doubler\WithFinalConstructor'); + $mirror->reflect($class, array())->willReturn($node); + $namer->name($class, array())->willReturn('spec\Prophecy\Doubler\WithFinalConstructor'); + + $double = $this->double($class, array()); + + $double->shouldBeAnInstanceOf('spec\Prophecy\Doubler\WithFinalConstructor'); + } +} + +class WithFinalConstructor +{ + final public function __construct() {} +} diff --git a/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/Generator/ClassCodeGeneratorSpec.php b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/Generator/ClassCodeGeneratorSpec.php new file mode 100644 index 00000000..b0830482 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/Generator/ClassCodeGeneratorSpec.php @@ -0,0 +1,323 @@ +getParentClass()->willReturn('RuntimeException'); + $class->getInterfaces()->willReturn(array( + 'Prophecy\Doubler\Generator\MirroredInterface', 'ArrayAccess', 'ArrayIterator' + )); + $class->getProperties()->willReturn(array('name' => 'public', 'email' => 'private')); + $class->getMethods()->willReturn(array($method1, $method2, $method3)); + + $method1->getName()->willReturn('getName'); + $method1->getVisibility()->willReturn('public'); + $method1->returnsReference()->willReturn(false); + $method1->isStatic()->willReturn(true); + $method1->getArguments()->willReturn(array($argument11, $argument12)); + $method1->hasReturnType()->willReturn(true); + $method1->getReturnType()->willReturn('string'); + $method1->getCode()->willReturn('return $this->name;'); + + $method2->getName()->willReturn('getEmail'); + $method2->getVisibility()->willReturn('protected'); + $method2->returnsReference()->willReturn(false); + $method2->isStatic()->willReturn(false); + $method2->getArguments()->willReturn(array($argument21)); + $method2->hasReturnType()->willReturn(false); + $method2->getCode()->willReturn('return $this->email;'); + + $method3->getName()->willReturn('getRefValue'); + $method3->getVisibility()->willReturn('public'); + $method3->returnsReference()->willReturn(true); + $method3->isStatic()->willReturn(false); + $method3->getArguments()->willReturn(array($argument31)); + $method3->hasReturnType()->willReturn(false); + $method3->getCode()->willReturn('return $this->refValue;'); + + $argument11->getName()->willReturn('fullname'); + $argument11->getTypeHint()->willReturn('array'); + $argument11->isOptional()->willReturn(true); + $argument11->getDefault()->willReturn(null); + $argument11->isPassedByReference()->willReturn(false); + $argument11->isVariadic()->willReturn(false); + + $argument12->getName()->willReturn('class'); + $argument12->getTypeHint()->willReturn('ReflectionClass'); + $argument12->isOptional()->willReturn(false); + $argument12->isPassedByReference()->willReturn(false); + $argument12->isVariadic()->willReturn(false); + + $argument21->getName()->willReturn('default'); + $argument21->getTypeHint()->willReturn('string'); + $argument21->isOptional()->willReturn(true); + $argument21->getDefault()->willReturn('ever.zet@gmail.com'); + $argument21->isPassedByReference()->willReturn(false); + $argument21->isVariadic()->willReturn(false); + + $argument31->getName()->willReturn('refValue'); + $argument31->getTypeHint()->willReturn(null); + $argument31->isOptional()->willReturn(false); + $argument31->getDefault()->willReturn(); + $argument31->isPassedByReference()->willReturn(false); + $argument31->isVariadic()->willReturn(false); + + $code = $this->generate('CustomClass', $class); + + if (version_compare(PHP_VERSION, '7.0', '>=')) { + $expected = <<<'PHP' +namespace { +class CustomClass extends \RuntimeException implements \Prophecy\Doubler\Generator\MirroredInterface, \ArrayAccess, \ArrayIterator { +public $name; +private $email; + +public static function getName(array $fullname = NULL, \ReflectionClass $class): string { +return $this->name; +} +protected function getEmail(string $default = 'ever.zet@gmail.com') { +return $this->email; +} +public function &getRefValue( $refValue) { +return $this->refValue; +} + +} +} +PHP; + } else { + $expected = <<<'PHP' +namespace { +class CustomClass extends \RuntimeException implements \Prophecy\Doubler\Generator\MirroredInterface, \ArrayAccess, \ArrayIterator { +public $name; +private $email; + +public static function getName(array $fullname = NULL, \ReflectionClass $class) { +return $this->name; +} +protected function getEmail(\string $default = 'ever.zet@gmail.com') { +return $this->email; +} +public function &getRefValue( $refValue) { +return $this->refValue; +} + +} +} +PHP; + } + $expected = strtr($expected, array("\r\n" => "\n", "\r" => "\n")); + $code->shouldBe($expected); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\ClassNode $class + * @param \Prophecy\Doubler\Generator\Node\MethodNode $method1 + * @param \Prophecy\Doubler\Generator\Node\MethodNode $method2 + * @param \Prophecy\Doubler\Generator\Node\MethodNode $method3 + * @param \Prophecy\Doubler\Generator\Node\MethodNode $method4 + * @param \Prophecy\Doubler\Generator\Node\ArgumentNode $argument1 + * @param \Prophecy\Doubler\Generator\Node\ArgumentNode $argument2 + * @param \Prophecy\Doubler\Generator\Node\ArgumentNode $argument3 + * @param \Prophecy\Doubler\Generator\Node\ArgumentNode $argument4 + */ + function it_generates_proper_php_code_for_variadics( + $class, $method1, $method2, $method3, $method4, $argument1, $argument2, + $argument3, $argument4 + ) + { + $class->getParentClass()->willReturn('stdClass'); + $class->getInterfaces()->willReturn(array('Prophecy\Doubler\Generator\MirroredInterface')); + $class->getProperties()->willReturn(array()); + $class->getMethods()->willReturn(array( + $method1, $method2, $method3, $method4 + )); + + $method1->getName()->willReturn('variadic'); + $method1->getVisibility()->willReturn('public'); + $method1->returnsReference()->willReturn(false); + $method1->isStatic()->willReturn(false); + $method1->getArguments()->willReturn(array($argument1)); + $method1->hasReturnType()->willReturn(false); + $method1->getCode()->willReturn(''); + + $method2->getName()->willReturn('variadicByRef'); + $method2->getVisibility()->willReturn('public'); + $method2->returnsReference()->willReturn(false); + $method2->isStatic()->willReturn(false); + $method2->getArguments()->willReturn(array($argument2)); + $method2->hasReturnType()->willReturn(false); + $method2->getCode()->willReturn(''); + + $method3->getName()->willReturn('variadicWithType'); + $method3->getVisibility()->willReturn('public'); + $method3->returnsReference()->willReturn(false); + $method3->isStatic()->willReturn(false); + $method3->getArguments()->willReturn(array($argument3)); + $method3->hasReturnType()->willReturn(false); + $method3->getCode()->willReturn(''); + + $method4->getName()->willReturn('variadicWithTypeByRef'); + $method4->getVisibility()->willReturn('public'); + $method4->returnsReference()->willReturn(false); + $method4->isStatic()->willReturn(false); + $method4->getArguments()->willReturn(array($argument4)); + $method4->hasReturnType()->willReturn(false); + $method4->getCode()->willReturn(''); + + $argument1->getName()->willReturn('args'); + $argument1->getTypeHint()->willReturn(null); + $argument1->isOptional()->willReturn(false); + $argument1->isPassedByReference()->willReturn(false); + $argument1->isVariadic()->willReturn(true); + + $argument2->getName()->willReturn('args'); + $argument2->getTypeHint()->willReturn(null); + $argument2->isOptional()->willReturn(false); + $argument2->isPassedByReference()->willReturn(true); + $argument2->isVariadic()->willReturn(true); + + $argument3->getName()->willReturn('args'); + $argument3->getTypeHint()->willReturn('\ReflectionClass'); + $argument3->isOptional()->willReturn(false); + $argument3->isPassedByReference()->willReturn(false); + $argument3->isVariadic()->willReturn(true); + + $argument4->getName()->willReturn('args'); + $argument4->getTypeHint()->willReturn('\ReflectionClass'); + $argument4->isOptional()->willReturn(false); + $argument4->isPassedByReference()->willReturn(true); + $argument4->isVariadic()->willReturn(true); + + $code = $this->generate('CustomClass', $class); + $expected = <<<'PHP' +namespace { +class CustomClass extends \stdClass implements \Prophecy\Doubler\Generator\MirroredInterface { + +public function variadic( ...$args) { + +} +public function variadicByRef( &...$args) { + +} +public function variadicWithType(\\ReflectionClass ...$args) { + +} +public function variadicWithTypeByRef(\\ReflectionClass &...$args) { + +} + +} +} +PHP; + $expected = strtr($expected, array("\r\n" => "\n", "\r" => "\n")); + $code->shouldBe($expected); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\ClassNode $class + * @param \Prophecy\Doubler\Generator\Node\MethodNode $method + * @param \Prophecy\Doubler\Generator\Node\ArgumentNode $argument + */ + function it_overrides_properly_methods_with_args_passed_by_reference( + $class, $method, $argument + ) + { + $class->getParentClass()->willReturn('RuntimeException'); + $class->getInterfaces()->willReturn(array('Prophecy\Doubler\Generator\MirroredInterface')); + $class->getProperties()->willReturn(array()); + $class->getMethods()->willReturn(array($method)); + + $method->getName()->willReturn('getName'); + $method->getVisibility()->willReturn('public'); + $method->isStatic()->willReturn(false); + $method->getArguments()->willReturn(array($argument)); + $method->hasReturnType()->willReturn(false); + $method->returnsReference()->willReturn(false); + $method->getCode()->willReturn('return $this->name;'); + + $argument->getName()->willReturn('fullname'); + $argument->getTypeHint()->willReturn('array'); + $argument->isOptional()->willReturn(true); + $argument->getDefault()->willReturn(null); + $argument->isPassedByReference()->willReturn(true); + $argument->isVariadic()->willReturn(false); + + $code = $this->generate('CustomClass', $class); + $expected =<<<'PHP' +namespace { +class CustomClass extends \RuntimeException implements \Prophecy\Doubler\Generator\MirroredInterface { + +public function getName(array &$fullname = NULL) { +return $this->name; +} + +} +} +PHP; + $expected = strtr($expected, array("\r\n" => "\n", "\r" => "\n")); + $code->shouldBe($expected); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\ClassNode $class + */ + function it_generates_empty_class_for_empty_ClassNode($class) + { + $class->getParentClass()->willReturn('stdClass'); + $class->getInterfaces()->willReturn(array('Prophecy\Doubler\Generator\MirroredInterface')); + $class->getProperties()->willReturn(array()); + $class->getMethods()->willReturn(array()); + + $code = $this->generate('CustomClass', $class); + $expected =<<<'PHP' +namespace { +class CustomClass extends \stdClass implements \Prophecy\Doubler\Generator\MirroredInterface { + + +} +} +PHP; + $expected = strtr($expected, array("\r\n" => "\n", "\r" => "\n")); + $code->shouldBe($expected); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\ClassNode $class + */ + function it_wraps_class_in_namespace_if_it_is_namespaced($class) + { + $class->getParentClass()->willReturn('stdClass'); + $class->getInterfaces()->willReturn(array('Prophecy\Doubler\Generator\MirroredInterface')); + $class->getProperties()->willReturn(array()); + $class->getMethods()->willReturn(array()); + + $code = $this->generate('My\Awesome\CustomClass', $class); + $expected =<<<'PHP' +namespace My\Awesome { +class CustomClass extends \stdClass implements \Prophecy\Doubler\Generator\MirroredInterface { + + +} +} +PHP; + $expected = strtr($expected, array("\r\n" => "\n", "\r" => "\n")); + $code->shouldBe($expected); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/Generator/ClassCreatorSpec.php b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/Generator/ClassCreatorSpec.php new file mode 100644 index 00000000..c7b57009 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/Generator/ClassCreatorSpec.php @@ -0,0 +1,44 @@ +beConstructedWith($generator); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\ClassNode $class + */ + function it_evaluates_code_generated_by_ClassCodeGenerator($generator, $class) + { + $generator->generate('stdClass', $class)->shouldBeCalled()->willReturn( + 'return 42;' + ); + + $this->create('stdClass', $class)->shouldReturn(42); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\ClassNode $class + */ + function it_throws_an_exception_if_class_does_not_exist_after_evaluation($generator, $class) + { + $generator->generate('CustomClass', $class)->shouldBeCalled()->willReturn( + 'return 42;' + ); + + $class->getParentClass()->willReturn('stdClass'); + $class->getInterfaces()->willReturn(array('Interface1', 'Interface2')); + + $this->shouldThrow('Prophecy\Exception\Doubler\ClassCreatorException') + ->duringCreate('CustomClass', $class); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/Generator/ClassMirrorSpec.php b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/Generator/ClassMirrorSpec.php new file mode 100644 index 00000000..de804480 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/Generator/ClassMirrorSpec.php @@ -0,0 +1,784 @@ +getName()->willReturn('Custom\ClassName'); + $class->getParentClass()->willReturn($parent); + $class->isInterface()->willReturn(false); + $class->isFinal()->willReturn(false); + $class->getMethods(ReflectionMethod::IS_ABSTRACT)->willReturn(array()); + $class->getMethods(ReflectionMethod::IS_PUBLIC)->willReturn(array( + $method1, $method2, $method3 + )); + + $parent->getName()->willReturn('Custom\ParentClassName'); + + $method1->getDeclaringClass()->willReturn($class); + $method2->getDeclaringClass()->willReturn($class); + $method3->getDeclaringClass()->willReturn($class); + + $method1->getName()->willReturn('getName'); + $method2->getName()->willReturn('getSelf'); + $method3->getName()->willReturn('getParent'); + + $method1->isFinal()->willReturn(false); + $method2->isFinal()->willReturn(false); + $method3->isFinal()->willReturn(false); + + $method1->isProtected()->willReturn(false); + $method2->isProtected()->willReturn(false); + $method3->isProtected()->willReturn(false); + + $method1->isStatic()->willReturn(false); + $method2->isStatic()->willReturn(false); + $method3->isStatic()->willReturn(false); + + $method1->returnsReference()->willReturn(false); + $method2->returnsReference()->willReturn(false); + $method3->returnsReference()->willReturn(false); + + $method1->getParameters()->willReturn(array()); + $method2->getParameters()->willReturn(array()); + $method3->getParameters()->willReturn(array()); + + if (version_compare(PHP_VERSION, '7.0', '>=')) { + $method1->hasReturnType()->willReturn(true); + $method1->getReturnType()->willReturn('string'); + $method2->hasReturnType()->willReturn(true); + $method2->getReturnType()->willReturn('self'); + $method3->hasReturnType()->willReturn(true); + $method3->getReturnType()->willReturn('parent'); + } + + $classNode = $this->reflect($class, array()); + $classNode->shouldBeAnInstanceOf('Prophecy\Doubler\Generator\Node\ClassNode'); + $classNode->getParentClass()->shouldReturn('Custom\ClassName'); + + $methodNodes = $classNode->getMethods(); + $methodNodes->shouldHaveCount(3); + + $classNode->hasMethod('getName')->shouldReturn(true); + $classNode->hasMethod('getSelf')->shouldReturn(true); + $classNode->hasMethod('getParent')->shouldReturn(true); + + if (version_compare(PHP_VERSION, '7.0', '>=')) { + $classNode->getMethod('getName')->getReturnType()->shouldReturn('string'); + $classNode->getMethod('getSelf')->getReturnType()->shouldReturn('\Custom\ClassName'); + $classNode->getMethod('getParent')->getReturnType()->shouldReturn('\Custom\ParentClassName'); + } + } + + /** + * @param ReflectionClass $class + * @param ReflectionMethod $method + * @param ReflectionParameter $parameter + */ + function it_changes_argument_names_if_they_are_varying($class, $method, $parameter) + { + + $class->getName()->willReturn('Custom\ClassName'); + $class->isInterface()->willReturn(false); + $class->isFinal()->willReturn(false); + $class->getMethods(ReflectionMethod::IS_PUBLIC)->willReturn(array($method)); + $class->getMethods(ReflectionMethod::IS_ABSTRACT)->willReturn(array()); + + $method->getParameters()->willReturn(array($parameter)); + $method->getName()->willReturn('methodName'); + $method->isFinal()->willReturn(false); + $method->isProtected()->willReturn(false); + $method->isStatic()->willReturn(false); + $method->returnsReference()->willReturn(false); + + if (version_compare(PHP_VERSION, '7.0', '>=')) { + $method->hasReturnType()->willReturn(false); + } + + $parameter->getName()->willReturn('...'); + $parameter->isDefaultValueAvailable()->willReturn(true); + $parameter->getDefaultValue()->willReturn(null); + $parameter->isPassedByReference()->willReturn(false); + $parameter->getClass()->willReturn($class); + if (version_compare(PHP_VERSION, '5.6', '>=')) { + $parameter->isVariadic()->willReturn(false); + } + + $classNode = $this->reflect($class, array()); + + $methodNodes = $classNode->getMethods(); + + $argumentNodes = $methodNodes['methodName']->getArguments(); + $argumentNode = $argumentNodes[0]; + + $argumentNode->getName()->shouldReturn('__dot_dot_dot__'); + } + + /** + * @param ReflectionClass $class + * @param ReflectionMethod $method + */ + function it_reflects_protected_abstract_methods($class, $method) + { + $class->getName()->willReturn('Custom\ClassName'); + $class->isInterface()->willReturn(false); + $class->isFinal()->willReturn(false); + $class->getMethods(ReflectionMethod::IS_ABSTRACT)->willReturn(array($method)); + $class->getMethods(ReflectionMethod::IS_PUBLIC)->willReturn(array()); + + $method->isProtected()->willReturn(true); + $method->isStatic()->willReturn(false); + $method->getParameters()->willReturn(array()); + $method->getName()->willReturn('innerDetail'); + $method->returnsReference()->willReturn(false); + + if (version_compare(PHP_VERSION, '7.0', '>=')) { + $method->hasReturnType()->willReturn(false); + } + + $classNode = $this->reflect($class, array()); + $classNode->shouldBeAnInstanceOf('Prophecy\Doubler\Generator\Node\ClassNode'); + $classNode->getParentClass()->shouldReturn('Custom\ClassName'); + + $methodNodes = $classNode->getMethods(); + $methodNodes->shouldHaveCount(1); + + $methodNodes['innerDetail']->getVisibility()->shouldReturn('protected'); + } + + /** + * @param ReflectionClass $class + * @param ReflectionMethod $method + */ + function it_reflects_public_static_methods($class, $method) + { + $class->getName()->willReturn('Custom\ClassName'); + $class->isInterface()->willReturn(false); + $class->isFinal()->willReturn(false); + $class->getMethods(ReflectionMethod::IS_ABSTRACT)->willReturn(array($method)); + $class->getMethods(ReflectionMethod::IS_PUBLIC)->willReturn(array()); + + $method->isProtected()->willReturn(true); + $method->isStatic()->willReturn(true); + $method->getParameters()->willReturn(array()); + $method->getName()->willReturn('innerDetail'); + $method->returnsReference()->willReturn(false); + + if (version_compare(PHP_VERSION, '7.0', '>=')) { + $method->hasReturnType()->willReturn(false); + } + + $classNode = $this->reflect($class, array()); + $classNode->shouldBeAnInstanceOf('Prophecy\Doubler\Generator\Node\ClassNode'); + $classNode->getParentClass()->shouldReturn('Custom\ClassName'); + + $methodNodes = $classNode->getMethods(); + $methodNodes->shouldHaveCount(1); + + $methodNodes['innerDetail']->getVisibility()->shouldReturn('protected'); + $methodNodes['innerDetail']->isStatic()->shouldReturn(true); + } + + /** + * @param ReflectionClass $class + * @param ReflectionMethod $constructMethod + * @param ReflectionMethod $destructMethod + * @param ReflectionMethod $sleepMethod + * @param ReflectionMethod $wakeupMethod + * @param ReflectionMethod $toStringMethod + * @param ReflectionMethod $callMethod + * @param ReflectionMethod $invokeMethod + */ + function it_reflects_allowed_magic_methods($class, $constructMethod, $destructMethod, $sleepMethod, $wakeupMethod, $toStringMethod, $callMethod, $invokeMethod) + { + $class->getName()->willReturn('Custom\ClassName'); + $class->isInterface()->willReturn(false); + $class->isFinal()->willReturn(false); + $class->getMethods(ReflectionMethod::IS_ABSTRACT)->willReturn(array()); + $class->getMethods(ReflectionMethod::IS_PUBLIC)->willReturn(array( + $constructMethod, $destructMethod, $sleepMethod, $wakeupMethod, $toStringMethod, $callMethod, $invokeMethod + )); + + $constructMethod->getName()->willReturn('__construct'); + $destructMethod->getName()->willReturn('__destruct'); + $sleepMethod->getName()->willReturn('__sleep'); + $wakeupMethod->getName()->willReturn('__wakeup'); + $toStringMethod->getName()->willReturn('__toString'); + $callMethod->getName()->willReturn('__call'); + $invokeMethod->getName()->willReturn('__invoke'); + + $constructMethod->isFinal()->willReturn(false); + $destructMethod->isFinal()->willReturn(false); + $sleepMethod->isFinal()->willReturn(false); + $wakeupMethod->isFinal()->willReturn(false); + $toStringMethod->isFinal()->willReturn(false); + $callMethod->isFinal()->willReturn(false); + $invokeMethod->isFinal()->willReturn(false); + + $constructMethod->isProtected()->willReturn(false); + $destructMethod->isProtected()->willReturn(false); + $sleepMethod->isProtected()->willReturn(false); + $wakeupMethod->isProtected()->willReturn(false); + $toStringMethod->isProtected()->willReturn(false); + $callMethod->isProtected()->willReturn(false); + $invokeMethod->isProtected()->willReturn(false); + + $constructMethod->isStatic()->willReturn(false); + $destructMethod->isStatic()->willReturn(false); + $sleepMethod->isStatic()->willReturn(false); + $wakeupMethod->isStatic()->willReturn(false); + $toStringMethod->isStatic()->willReturn(false); + $callMethod->isStatic()->willReturn(false); + $invokeMethod->isStatic()->willReturn(false); + + $constructMethod->returnsReference()->willReturn(false); + $destructMethod->returnsReference()->willReturn(false); + $sleepMethod->returnsReference()->willReturn(false); + $wakeupMethod->returnsReference()->willReturn(false); + $toStringMethod->returnsReference()->willReturn(false); + $callMethod->returnsReference()->willReturn(false); + $invokeMethod->returnsReference()->willReturn(false); + + $constructMethod->getParameters()->willReturn(array()); + $destructMethod->getParameters()->willReturn(array()); + $sleepMethod->getParameters()->willReturn(array()); + $wakeupMethod->getParameters()->willReturn(array()); + $toStringMethod->getParameters()->willReturn(array()); + $callMethod->getParameters()->willReturn(array()); + $invokeMethod->getParameters()->willReturn(array()); + + if (version_compare(PHP_VERSION, '7.0', '>=')) { + $constructMethod->hasReturnType()->willReturn(false); + $destructMethod->hasReturnType()->willReturn(false); + $sleepMethod->hasReturnType()->willReturn(false); + $wakeupMethod->hasReturnType()->willReturn(false); + $toStringMethod->hasReturnType()->willReturn(false); + $callMethod->hasReturnType()->willReturn(false); + $invokeMethod->hasReturnType()->willReturn(false); + } + + $classNode = $this->reflect($class, array()); + $classNode->shouldBeAnInstanceOf('Prophecy\Doubler\Generator\Node\ClassNode'); + $classNode->getParentClass()->shouldReturn('Custom\ClassName'); + + $methodNodes = $classNode->getMethods(); + $methodNodes->shouldHaveCount(7); + } + + /** + * @param ReflectionClass $class + * @param ReflectionMethod $method + * @param ReflectionParameter $param1 + * @param ReflectionParameter $param2 + * @param ReflectionClass $typeHint + * @param ReflectionParameter $param3 + * @param ReflectionParameter $param4 + */ + function it_properly_reads_methods_arguments_with_types( + $class, $method, $param1, $param2, $typeHint, $param3, $param4 + ) + { + $class->getName()->willReturn('Custom\ClassName'); + $class->isInterface()->willReturn(false); + $class->isFinal()->willReturn(false); + $class->getMethods(ReflectionMethod::IS_ABSTRACT)->willReturn(array()); + $class->getMethods(ReflectionMethod::IS_PUBLIC)->willReturn(array($method)); + + $method->getName()->willReturn('methodWithArgs'); + $method->isFinal()->willReturn(false); + $method->isProtected()->willReturn(true); + $method->isStatic()->willReturn(false); + $method->returnsReference()->willReturn(false); + $method->getParameters()->willReturn(array($param1, $param2, $param3, $param4)); + + if (version_compare(PHP_VERSION, '7.0', '>=')) { + $method->hasReturnType()->willReturn(false); + } + + $param1->getName()->willReturn('arg_1'); + $param1->isArray()->willReturn(true); + $param1->getClass()->willReturn(null); + $param1->isDefaultValueAvailable()->willReturn(true); + $param1->isPassedByReference()->willReturn(false); + $param1->allowsNull()->willReturn(false); + $param1->getDefaultValue()->willReturn(array()); + + $param2->getName()->willReturn('arg2'); + $param2->isArray()->willReturn(false); + $param2->getClass()->willReturn($typeHint); + $param2->isDefaultValueAvailable()->willReturn(false); + $param2->isOptional()->willReturn(false); + $param2->isPassedByReference()->willReturn(false); + $param2->allowsNull()->willReturn(false); + $typeHint->getName()->willReturn('ArrayAccess'); + + $param3->getName()->willReturn('arg_3'); + $param3->isArray()->willReturn(false); + if (version_compare(PHP_VERSION, '5.4', '>=')) { + $param3->isCallable()->willReturn(true); + } + $param3->getClass()->willReturn(null); + $param3->isOptional()->willReturn(false); + $param3->isDefaultValueAvailable()->willReturn(false); + $param3->isPassedByReference()->willReturn(false); + $param3->allowsNull()->willReturn(true); + + $param4->getName()->willReturn('arg_4'); + $param4->isArray()->willReturn(false); + $param4->getClass()->willReturn($typeHint); + $param4->isPassedByReference()->willReturn(false); + $param4->allowsNull()->willReturn(true); + + if (version_compare(PHP_VERSION, '5.6', '>=')) { + $param1->isVariadic()->willReturn(false); + $param2->isVariadic()->willReturn(false); + $param3->isVariadic()->willReturn(false); + $param4->isVariadic()->willReturn(true); + } else { + $param4->isOptional()->willReturn(true); + $param4->isDefaultValueAvailable()->willReturn(false); + } + + $classNode = $this->reflect($class, array()); + $methodNodes = $classNode->getMethods(); + $argNodes = $methodNodes['methodWithArgs']->getArguments(); + + $argNodes[0]->getName()->shouldReturn('arg_1'); + $argNodes[0]->getTypeHint()->shouldReturn('array'); + $argNodes[0]->isOptional()->shouldReturn(true); + $argNodes[0]->getDefault()->shouldReturn(array()); + + $argNodes[1]->getName()->shouldReturn('arg2'); + $argNodes[1]->getTypeHint()->shouldReturn('ArrayAccess'); + $argNodes[1]->isOptional()->shouldReturn(false); + + $argNodes[2]->getName()->shouldReturn('arg_3'); + if (version_compare(PHP_VERSION, '5.4', '>=')) { + $argNodes[2]->getTypeHint()->shouldReturn('callable'); + $argNodes[2]->isOptional()->shouldReturn(true); + $argNodes[2]->getDefault()->shouldReturn(null); + } else { + $argNodes[2]->isOptional()->shouldReturn(false); + } + + $argNodes[3]->getName()->shouldReturn('arg_4'); + $argNodes[3]->getTypeHint()->shouldReturn('ArrayAccess'); + if (version_compare(PHP_VERSION, '5.6', '>=')) { + $argNodes[3]->isVariadic()->shouldReturn(true); + } else { + $argNodes[3]->isOptional()->shouldReturn(true); + $argNodes[3]->getDefault()->shouldReturn(null); + } + } + + /** + * @param ReflectionClass $class + * @param ReflectionMethod $method + * @param ReflectionParameter $param1 + */ + function it_marks_required_args_without_types_as_not_optional( + $class, $method, $param1 + ) + { + $class->getName()->willReturn('Custom\ClassName'); + $class->isInterface()->willReturn(false); + $class->isFinal()->willReturn(false); + $class->getMethods(ReflectionMethod::IS_ABSTRACT)->willReturn(array()); + $class->getMethods(ReflectionMethod::IS_PUBLIC)->willReturn(array($method)); + + $method->getName()->willReturn('methodWithArgs'); + $method->isFinal()->willReturn(false); + $method->isProtected()->willReturn(false); + $method->isStatic()->willReturn(false); + $method->returnsReference()->willReturn(false); + $method->getParameters()->willReturn(array($param1)); + + if (version_compare(PHP_VERSION, '7.0', '>=')) { + $method->hasReturnType()->willReturn(false); + } + + $param1->getName()->willReturn('arg_1'); + $param1->isArray()->willReturn(false); + if (version_compare(PHP_VERSION, '5.4', '>=')) { + $param1->isCallable()->willReturn(false); + } + $param1->getClass()->willReturn(null); + + if (version_compare(PHP_VERSION, '7.0', '>=')) { + $param1->hasType()->willReturn(false); + } + + if (version_compare(PHP_VERSION, '5.6', '>=')) { + $param1->isVariadic()->willReturn(false); + } + $param1->isDefaultValueAvailable()->willReturn(false); + $param1->isOptional()->willReturn(false); + $param1->isPassedByReference()->willReturn(false); + $param1->allowsNull()->willReturn(true); + if (defined('HHVM_VERSION')) { + $param1->getTypehintText()->willReturn(null); + } + + $classNode = $this->reflect($class, array()); + $methodNodes = $classNode->getMethods(); + $argNodes = $methodNodes['methodWithArgs']->getArguments(); + + $argNodes[0]->isOptional()->shouldReturn(false); + } + + /** + * @param ReflectionClass $class + * @param ReflectionMethod $method + * @param ReflectionParameter $param1 + * @param ReflectionParameter $param2 + * @param ReflectionParameter $param3 + * @param ReflectionClass $typeHint + */ + function it_marks_passed_by_reference_args_as_passed_by_reference( + $class, $method, $param1, $param2, $param3, $typeHint + ) + { + $class->getName()->willReturn('Custom\ClassName'); + $class->isInterface()->willReturn(false); + $class->isFinal()->willReturn(false); + $class->getMethods(ReflectionMethod::IS_ABSTRACT)->willReturn(array()); + $class->getMethods(ReflectionMethod::IS_PUBLIC)->willReturn(array($method)); + + $method->getName()->willReturn('methodWithArgs'); + $method->isFinal()->willReturn(false); + $method->isProtected()->willReturn(false); + $method->isStatic()->willReturn(false); + $method->returnsReference()->willReturn(false); + $method->getParameters()->willReturn(array($param1, $param2, $param3)); + + if (version_compare(PHP_VERSION, '7.0', '>=')) { + $method->hasReturnType()->willReturn(false); + } + + $param1->getName()->willReturn('arg_1'); + $param1->isArray()->willReturn(false); + if (version_compare(PHP_VERSION, '5.4', '>=')) { + $param1->isCallable()->willReturn(false); + } + $param1->getClass()->willReturn(null); + if (version_compare(PHP_VERSION, '5.6', '>=')) { + $param1->isVariadic()->willReturn(false); + } + $param1->isDefaultValueAvailable()->willReturn(false); + $param1->isOptional()->willReturn(true); + $param1->isPassedByReference()->willReturn(true); + + if (version_compare(PHP_VERSION, '7.0', '>=')) { + $param1->hasType()->willReturn(false); + } + + $param1->allowsNull()->willReturn(false); + if (defined('HHVM_VERSION')) { + $param1->getTypehintText()->willReturn(null); + } + + $param2->getName()->willReturn('arg2'); + $param2->isArray()->willReturn(false); + $param2->getClass()->willReturn($typeHint); + if (version_compare(PHP_VERSION, '5.6', '>=')) { + $param2->isVariadic()->willReturn(false); + } + $param2->isDefaultValueAvailable()->willReturn(false); + $param2->isOptional()->willReturn(false); + $param2->isPassedByReference()->willReturn(false); + + if (version_compare(PHP_VERSION, '7.0', '>=')) { + $param2->hasType()->willReturn(false); + } + + $param2->allowsNull()->willReturn(false); + $typeHint->getName()->willReturn('ArrayAccess'); + + $param3->getName()->willReturn('arg2'); + $param3->isArray()->willReturn(false); + $param3->getClass()->willReturn($typeHint); + if (version_compare(PHP_VERSION, '5.6', '>=')) { + $param3->isVariadic()->willReturn(true); + } else { + $param3->isOptional()->willReturn(true); + $param3->isDefaultValueAvailable()->willReturn(false); + } + $param3->isPassedByReference()->willReturn(true); + $param3->allowsNull()->willReturn(true); + + $classNode = $this->reflect($class, array()); + $methodNodes = $classNode->getMethods(); + $argNodes = $methodNodes['methodWithArgs']->getArguments(); + + $argNodes[0]->isPassedByReference()->shouldReturn(true); + $argNodes[1]->isPassedByReference()->shouldReturn(false); + $argNodes[2]->isPassedByReference()->shouldReturn(true); + } + + /** + * @param ReflectionClass $class + */ + function it_throws_an_exception_if_class_is_final($class) + { + $class->isInterface()->willReturn(false); + $class->isFinal()->willReturn(true); + $class->getName()->willReturn('Custom\ClassName'); + + $this->shouldThrow('Prophecy\Exception\Doubler\ClassMirrorException') + ->duringReflect($class, array()); + } + + /** + * @param ReflectionClass $class + * @param ReflectionMethod $method + */ + function it_ignores_final_methods($class, $method) + { + $class->getName()->willReturn('Custom\ClassName'); + $class->isInterface()->willReturn(false); + $class->isFinal()->willReturn(false); + $class->getMethods(ReflectionMethod::IS_ABSTRACT)->willReturn(array()); + $class->getMethods(ReflectionMethod::IS_PUBLIC)->willReturn(array($method)); + + $method->isFinal()->willReturn(true); + $method->getName()->willReturn('finalImplementation'); + + $classNode = $this->reflect($class, array()); + $classNode->getMethods()->shouldHaveCount(0); + } + + /** + * @param ReflectionClass $class + * @param ReflectionMethod $method + */ + function it_marks_final_methods_as_unextendable($class, $method) + { + $class->getName()->willReturn('Custom\ClassName'); + $class->isInterface()->willReturn(false); + $class->isFinal()->willReturn(false); + $class->getMethods(ReflectionMethod::IS_ABSTRACT)->willReturn(array()); + $class->getMethods(ReflectionMethod::IS_PUBLIC)->willReturn(array($method)); + + $method->isFinal()->willReturn(true); + $method->getName()->willReturn('finalImplementation'); + + $classNode = $this->reflect($class, array()); + $classNode->getUnextendableMethods()->shouldHaveCount(1); + $classNode->isExtendable('finalImplementation')->shouldReturn(false); + } + + /** + * @param ReflectionClass $interface + */ + function it_throws_an_exception_if_interface_provided_instead_of_class($interface) + { + $interface->isInterface()->willReturn(true); + $interface->getName()->willReturn('Custom\ClassName'); + + $this->shouldThrow('Prophecy\Exception\InvalidArgumentException') + ->duringReflect($interface, array()); + } + + /** + * @param ReflectionClass $interface1 + * @param ReflectionClass $interface2 + * @param ReflectionMethod $method1 + * @param ReflectionMethod $method2 + * @param ReflectionMethod $method3 + */ + function it_reflects_all_interfaces_methods( + $interface1, $interface2, $method1, $method2, $method3 + ) + { + $interface1->getName()->willReturn('MyInterface1'); + $interface2->getName()->willReturn('MyInterface2'); + + $interface1->isInterface()->willReturn(true); + $interface2->isInterface()->willReturn(true); + + $interface1->getMethods()->willReturn(array($method1)); + $interface2->getMethods()->willReturn(array($method2, $method3)); + + $method1->getName()->willReturn('getName'); + $method2->getName()->willReturn('isPublic'); + $method3->getName()->willReturn('isAbstract'); + + $method1->isProtected()->willReturn(false); + $method2->isProtected()->willReturn(false); + $method3->isProtected()->willReturn(false); + + $method1->returnsReference()->willReturn(false); + $method2->returnsReference()->willReturn(false); + $method3->returnsReference()->willReturn(false); + + $method1->isStatic()->willReturn(false); + $method2->isStatic()->willReturn(false); + $method3->isStatic()->willReturn(false); + + $method1->getParameters()->willReturn(array()); + $method2->getParameters()->willReturn(array()); + $method3->getParameters()->willReturn(array()); + + if (version_compare(PHP_VERSION, '7.0', '>=')) { + $method1->hasReturnType()->willReturn(false); + $method2->hasReturnType()->willReturn(false); + $method3->hasReturnType()->willReturn(false); + } + + $classNode = $this->reflect(null, array($interface1, $interface2)); + + $classNode->shouldBeAnInstanceOf('Prophecy\Doubler\Generator\Node\ClassNode'); + $classNode->getParentClass()->shouldReturn('stdClass'); + $classNode->getInterfaces()->shouldReturn(array( + 'Prophecy\Doubler\Generator\ReflectionInterface', 'MyInterface2', 'MyInterface1', + )); + + $methodNodes = $classNode->getMethods(); + $methodNodes->shouldHaveCount(3); + + $classNode->hasMethod('getName')->shouldReturn(true); + $classNode->hasMethod('isPublic')->shouldReturn(true); + $classNode->hasMethod('isAbstract')->shouldReturn(true); + } + + /** + * @param ReflectionClass $class + * @param ReflectionMethod $method1 + * @param ReflectionMethod $method2 + * @param ReflectionMethod $method3 + */ + function it_ignores_virtually_private_methods($class, $method1, $method2, $method3) + { + $class->getName()->willReturn('SomeClass'); + $class->isInterface()->willReturn(false); + $class->isFinal()->willReturn(false); + $class->getMethods(ReflectionMethod::IS_ABSTRACT)->willReturn(array()); + $class->getMethods(ReflectionMethod::IS_PUBLIC)->willReturn(array($method1, $method2, $method3)); + + $method1->getName()->willReturn('_getName'); + $method2->getName()->willReturn('__toString'); + $method3->getName()->willReturn('isAbstract'); + + $method1->isFinal()->willReturn(false); + $method2->isFinal()->willReturn(false); + $method3->isFinal()->willReturn(false); + + $method1->isProtected()->willReturn(false); + $method2->isProtected()->willReturn(false); + $method3->isProtected()->willReturn(false); + + $method1->isStatic()->willReturn(false); + $method2->isStatic()->willReturn(false); + $method3->isStatic()->willReturn(false); + + $method1->returnsReference()->willReturn(false); + $method2->returnsReference()->willReturn(false); + $method3->returnsReference()->willReturn(false); + + $method1->getParameters()->willReturn(array()); + $method2->getParameters()->willReturn(array()); + $method3->getParameters()->willReturn(array()); + + if (version_compare(PHP_VERSION, '7.0', '>=')) { + $method1->hasReturnType()->willReturn(false); + $method2->hasReturnType()->willReturn(false); + $method3->hasReturnType()->willReturn(false); + } + + $classNode = $this->reflect($class, array()); + $methodNodes = $classNode->getMethods(); + $methodNodes->shouldHaveCount(2); + + $classNode->hasMethod('isAbstract')->shouldReturn(true); + } + + /** + * @param ReflectionClass $class + * @param ReflectionMethod $method + */ + function it_does_not_throw_exception_for_virtually_private_finals($class, $method) + { + $class->getName()->willReturn('SomeClass'); + $class->isInterface()->willReturn(false); + $class->isFinal()->willReturn(false); + $class->getMethods(ReflectionMethod::IS_ABSTRACT)->willReturn(array()); + $class->getMethods(ReflectionMethod::IS_PUBLIC)->willReturn(array($method)); + + $method->getName()->willReturn('__toString'); + $method->isFinal()->willReturn(true); + + $this->shouldNotThrow()->duringReflect($class, array()); + } + + /** + * @param ReflectionClass $class + */ + function it_throws_an_exception_if_class_provided_in_interfaces_list($class) + { + $class->getName()->willReturn('MyClass'); + $class->isInterface()->willReturn(false); + + $this->shouldThrow('InvalidArgumentException') + ->duringReflect(null, array($class)); + } + + function it_throws_an_exception_if_not_reflection_provided_as_interface() + { + $this->shouldThrow('InvalidArgumentException') + ->duringReflect(null, array(null)); + } + + function it_doesnt_fail_to_typehint_nonexistent_FQCN() + { + $classNode = $this->reflect(new ReflectionClass('spec\Prophecy\Doubler\Generator\OptionalDepsClass'), array()); + $method = $classNode->getMethod('iHaveAStrangeTypeHintedArg'); + $arguments = $method->getArguments(); + $arguments[0]->getTypeHint()->shouldBe('I\Simply\Am\Nonexistent'); + } + + function it_doesnt_fail_to_typehint_nonexistent_RQCN() + { + $classNode = $this->reflect(new ReflectionClass('spec\Prophecy\Doubler\Generator\OptionalDepsClass'), array()); + $method = $classNode->getMethod('iHaveAnEvenStrangerTypeHintedArg'); + $arguments = $method->getArguments(); + $arguments[0]->getTypeHint()->shouldBe('I\Simply\Am\Not'); + } + + function it_doesnt_use_scalar_typehints() + { + $classNode = $this->reflect(new ReflectionClass('ReflectionMethod'), array()); + $method = $classNode->getMethod('export'); + $arguments = $method->getArguments(); + $arguments[0]->getTypeHint()->shouldReturn(null); + $arguments[1]->getTypeHint()->shouldReturn(null); + $arguments[2]->getTypeHint()->shouldReturn(null); + } +} + +class OptionalDepsClass +{ + public function iHaveAStrangeTypeHintedArg(\I\Simply\Am\Nonexistent $class) + { + } + + public function iHaveAnEvenStrangerTypeHintedArg(Simply\Am\Not $class) + { + } +} diff --git a/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/Generator/Node/ArgumentNodeSpec.php b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/Generator/Node/ArgumentNodeSpec.php new file mode 100644 index 00000000..2c8d1886 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/Generator/Node/ArgumentNodeSpec.php @@ -0,0 +1,92 @@ +beConstructedWith('name'); + } + + function it_is_not_be_passed_by_reference_by_default() + { + $this->shouldNotBePassedByReference(); + } + + function it_is_passed_by_reference_if_marked() + { + $this->setAsPassedByReference(); + $this->shouldBePassedByReference(); + } + + function it_is_not_variadic_by_default() + { + $this->shouldNotBeVariadic(); + } + + function it_is_variadic_if_marked() + { + $this->setAsVariadic(); + $this->shouldBeVariadic(); + } + + function it_does_not_have_default_by_default() + { + $this->shouldNotHaveDefault(); + } + + function it_does_not_have_default_if_variadic() + { + $this->setDefault(null); + $this->setAsVariadic(); + $this->shouldNotHaveDefault(); + } + + function it_does_have_default_if_not_variadic() + { + $this->setDefault(null); + $this->setAsVariadic(false); + $this->hasDefault()->shouldReturn(true); + } + + function it_has_name_with_which_it_was_been_constructed() + { + $this->getName()->shouldReturn('name'); + } + + function it_has_no_typehint_by_default() + { + $this->getTypeHint()->shouldReturn(null); + } + + function its_typeHint_is_mutable() + { + $this->setTypeHint('array'); + $this->getTypeHint()->shouldReturn('array'); + } + + function it_does_not_have_default_value_by_default() + { + $this->getDefault()->shouldReturn(null); + } + + function it_is_not_optional_by_default() + { + $this->isOptional()->shouldReturn(false); + } + + function its_default_is_mutable() + { + $this->setDefault(array()); + $this->getDefault()->shouldReturn(array()); + } + + function it_is_marked_as_optional_when_default_is_set() + { + $this->setDefault(null); + $this->isOptional()->shouldReturn(true); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/Generator/Node/ClassNodeSpec.php b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/Generator/Node/ClassNodeSpec.php new file mode 100644 index 00000000..be7e1026 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/Generator/Node/ClassNodeSpec.php @@ -0,0 +1,200 @@ +getParentClass()->shouldReturn('stdClass'); + } + + function its_parentClass_is_mutable() + { + $this->setParentClass('Exception'); + $this->getParentClass()->shouldReturn('Exception'); + } + + function its_parentClass_is_set_to_stdClass_if_user_set_null() + { + $this->setParentClass(null); + $this->getParentClass()->shouldReturn('stdClass'); + } + + function it_does_not_implement_any_interface_by_default() + { + $this->getInterfaces()->shouldHaveCount(0); + } + + function its_addInterface_adds_item_to_the_list_of_implemented_interfaces() + { + $this->addInterface('MyInterface'); + $this->getInterfaces()->shouldHaveCount(1); + } + + function its_hasInterface_returns_true_if_class_implements_interface() + { + $this->addInterface('MyInterface'); + $this->hasInterface('MyInterface')->shouldReturn(true); + } + + function its_hasInterface_returns_false_if_class_does_not_implements_interface() + { + $this->hasInterface('MyInterface')->shouldReturn(false); + } + + function it_supports_implementation_of_multiple_interfaces() + { + $this->addInterface('MyInterface'); + $this->addInterface('MySecondInterface'); + $this->getInterfaces()->shouldHaveCount(2); + } + + function it_ignores_same_interfaces_added_twice() + { + $this->addInterface('MyInterface'); + $this->addInterface('MyInterface'); + + $this->getInterfaces()->shouldHaveCount(1); + $this->getInterfaces()->shouldReturn(array('MyInterface')); + } + + function it_does_not_have_methods_by_default() + { + $this->getMethods()->shouldHaveCount(0); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\MethodNode $method1 + * @param \Prophecy\Doubler\Generator\Node\MethodNode $method2 + */ + function it_can_has_methods($method1, $method2) + { + $method1->getName()->willReturn('__construct'); + $method2->getName()->willReturn('getName'); + + $this->addMethod($method1); + $this->addMethod($method2); + + $this->getMethods()->shouldReturn(array( + '__construct' => $method1, + 'getName' => $method2 + )); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\MethodNode $method + */ + function its_hasMethod_returns_true_if_method_exists($method) + { + $method->getName()->willReturn('getName'); + + $this->addMethod($method); + + $this->hasMethod('getName')->shouldReturn(true); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\MethodNode $method + */ + function its_getMethod_returns_method_by_name($method) + { + $method->getName()->willReturn('getName'); + + $this->addMethod($method); + + $this->getMethod('getName')->shouldReturn($method); + } + + function its_hasMethod_returns_false_if_method_does_not_exists() + { + $this->hasMethod('getName')->shouldReturn(false); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\MethodNode $method + */ + function its_hasMethod_returns_false_if_method_has_been_removed($method) + { + $method->getName()->willReturn('getName'); + $this->addMethod($method); + $this->removeMethod('getName'); + + $this->hasMethod('getName')->shouldReturn(false); + } + + + function it_does_not_have_properties_by_default() + { + $this->getProperties()->shouldHaveCount(0); + } + + function it_is_able_to_have_properties() + { + $this->addProperty('title'); + $this->addProperty('text', 'private'); + $this->getProperties()->shouldReturn(array( + 'title' => 'public', + 'text' => 'private' + )); + } + + function its_addProperty_does_not_accept_unsupported_visibility() + { + $this->shouldThrow('InvalidArgumentException')->duringAddProperty('title', 'town'); + } + + function its_addProperty_lowercases_visibility_before_setting() + { + $this->addProperty('text', 'PRIVATE'); + $this->getProperties()->shouldReturn(array('text' => 'private')); + } + + function its_has_no_unextendable_methods_by_default() + { + $this->getUnextendableMethods()->shouldHaveCount(0); + } + + function its_addUnextendableMethods_adds_an_unextendable_method() + { + $this->addUnextendableMethod('testMethod'); + $this->getUnextendableMethods()->shouldHaveCount(1); + } + + function its_methods_are_extendable_by_default() + { + $this->isExtendable('testMethod')->shouldReturn(true); + } + + function its_unextendable_methods_are_not_extendable() + { + $this->addUnextendableMethod('testMethod'); + $this->isExtendable('testMethod')->shouldReturn(false); + } + + function its_addUnextendableMethods_doesnt_create_duplicates() + { + $this->addUnextendableMethod('testMethod'); + $this->addUnextendableMethod('testMethod'); + $this->getUnextendableMethods()->shouldHaveCount(1); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\MethodNode $method + */ + function it_throws_an_exception_when_adding_a_method_that_isnt_extendable($method) + { + $this->addUnextendableMethod('testMethod'); + $method->getName()->willReturn('testMethod'); + + $expectedException = new MethodNotExtendableException( + "Method `testMethod` is not extendable, so can not be added.", + "stdClass", + "testMethod" + ); + $this->shouldThrow($expectedException)->duringAddMethod($method); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/Generator/Node/MethodNodeSpec.php b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/Generator/Node/MethodNodeSpec.php new file mode 100644 index 00000000..49bd9f59 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/Generator/Node/MethodNodeSpec.php @@ -0,0 +1,141 @@ +beConstructedWith('getTitle'); + } + + function it_has_a_name() + { + $this->getName()->shouldReturn('getTitle'); + } + + function it_has_public_visibility_by_default() + { + $this->getVisibility()->shouldReturn('public'); + } + + function its_visibility_is_mutable() + { + $this->setVisibility('private'); + $this->getVisibility()->shouldReturn('private'); + } + + function it_is_not_static_by_default() + { + $this->shouldNotBeStatic(); + } + + function it_does_not_return_a_reference_by_default() + { + $this->returnsReference()->shouldReturn(false); + } + + function it_should_be_settable_as_returning_a_reference_through_setter() + { + $this->setReturnsReference(); + $this->returnsReference()->shouldReturn(true); + } + + function it_should_be_settable_as_static_through_setter() + { + $this->setStatic(); + $this->shouldBeStatic(); + } + + function it_accepts_only_supported_visibilities() + { + $this->shouldThrow('InvalidArgumentException')->duringSetVisibility('stealth'); + } + + function it_lowercases_visibility_before_setting_it() + { + $this->setVisibility('Public'); + $this->getVisibility()->shouldReturn('public'); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\ArgumentNode $argument1 + * @param \Prophecy\Doubler\Generator\Node\ArgumentNode $argument2 + */ + function its_useParentCode_causes_method_to_call_parent($argument1, $argument2) + { + $argument1->getName()->willReturn('objectName'); + $argument2->getName()->willReturn('default'); + + $argument1->isVariadic()->willReturn(false); + $argument2->isVariadic()->willReturn(true); + + $this->addArgument($argument1); + $this->addArgument($argument2); + + $this->useParentCode(); + + $this->getCode()->shouldReturn( + 'return parent::getTitle($objectName, ...$default);' + ); + } + + function its_code_is_mutable() + { + $this->setCode('echo "code";'); + $this->getCode()->shouldReturn('echo "code";'); + } + + function its_reference_returning_methods_will_generate_exceptions() + { + $this->setCode('echo "code";'); + $this->setReturnsReference(); + $this->getCode()->shouldReturn("throw new \Prophecy\Exception\Doubler\ReturnByReferenceException('Returning by reference not supported', get_class(\$this), 'getTitle');"); + } + + function its_setCode_provided_with_null_cleans_method_body() + { + $this->setCode(null); + $this->getCode()->shouldReturn(''); + } + + function it_is_constructable_with_code() + { + $this->beConstructedWith('getTitle', 'die();'); + $this->getCode()->shouldReturn('die();'); + } + + function it_does_not_have_arguments_by_default() + { + $this->getArguments()->shouldHaveCount(0); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\ArgumentNode $argument1 + * @param \Prophecy\Doubler\Generator\Node\ArgumentNode $argument2 + */ + function it_supports_adding_arguments($argument1, $argument2) + { + $this->addArgument($argument1); + $this->addArgument($argument2); + + $this->getArguments()->shouldReturn(array($argument1, $argument2)); + } + + function it_does_not_have_return_type_by_default() + { + $this->hasReturnType()->shouldReturn(false); + } + + function it_setReturnType_sets_return_type() + { + $returnType = 'string'; + + $this->setReturnType($returnType); + + $this->hasReturnType()->shouldReturn(true); + $this->getReturnType()->shouldReturn($returnType); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/LazyDoubleSpec.php b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/LazyDoubleSpec.php new file mode 100644 index 00000000..7026126f --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/LazyDoubleSpec.php @@ -0,0 +1,96 @@ +beConstructedWith($doubler); + } + + /** + * @param \Prophecy\Prophecy\ProphecySubjectInterface $double + */ + function it_returns_anonymous_double_instance_by_default($doubler, $double) + { + $doubler->double(null, array())->willReturn($double); + + $this->getInstance()->shouldReturn($double); + } + + /** + * @param \Prophecy\Prophecy\ProphecySubjectInterface $double + * @param \ReflectionClass $class + */ + function it_returns_class_double_instance_if_set($doubler, $double, $class) + { + $doubler->double($class, array())->willReturn($double); + + $this->setParentClass($class); + + $this->getInstance()->shouldReturn($double); + } + + /** + * @param \Prophecy\Prophecy\ProphecySubjectInterface $double1 + * @param \Prophecy\Prophecy\ProphecySubjectInterface $double2 + */ + function it_returns_same_double_instance_if_called_2_times( + $doubler, $double1, $double2 + ) + { + $doubler->double(null, array())->willReturn($double1); + $doubler->double(null, array())->willReturn($double2); + + $this->getInstance()->shouldReturn($double2); + $this->getInstance()->shouldReturn($double2); + } + + function its_setParentClass_throws_ClassNotFoundException_if_class_not_found() + { + $this->shouldThrow('Prophecy\Exception\Doubler\ClassNotFoundException') + ->duringSetParentClass('SomeUnexistingClass'); + } + + /** + * @param \Prophecy\Prophecy\ProphecySubjectInterface $double + */ + function its_setParentClass_throws_exception_if_prophecy_is_already_created( + $doubler, $double + ) + { + $doubler->double(null, array())->willReturn($double); + + $this->getInstance(); + + $this->shouldThrow('Prophecy\Exception\Doubler\DoubleException') + ->duringSetParentClass('stdClass'); + } + + function its_addInterface_throws_InterfaceNotFoundException_if_no_interface_found() + { + $this->shouldThrow('Prophecy\Exception\Doubler\InterfaceNotFoundException') + ->duringAddInterface('SomeUnexistingInterface'); + } + + /** + * @param \Prophecy\Prophecy\ProphecySubjectInterface $double + */ + function its_addInterface_throws_exception_if_prophecy_is_already_created( + $doubler, $double + ) + { + $doubler->double(null, array())->willReturn($double); + + $this->getInstance(); + + $this->shouldThrow('Prophecy\Exception\Doubler\DoubleException') + ->duringAddInterface('ArrayAccess'); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/NameGeneratorSpec.php b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/NameGeneratorSpec.php new file mode 100644 index 00000000..a3e74919 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Doubler/NameGeneratorSpec.php @@ -0,0 +1,72 @@ +getName()->willReturn('stdClass'); + $this->name($class, array())->shouldStartWith('Double\stdClass\\'); + } + + /** + * @param \ReflectionClass $class + */ + function its_name_generates_name_based_on_namespaced_class_reflection($class) + { + $class->getName()->willReturn('Some\Custom\Class'); + $this->name($class, array())->shouldStartWith('Double\Some\Custom\Class\P'); + } + + /** + * @param \ReflectionClass $interface1 + * @param \ReflectionClass $interface2 + */ + function its_name_generates_name_based_on_interface_shortnames($interface1, $interface2) + { + $interface1->getShortName()->willReturn('HandlerInterface'); + $interface2->getShortName()->willReturn('LoaderInterface'); + + $this->name(null, array($interface1, $interface2))->shouldStartWith( + 'Double\HandlerInterface\LoaderInterface\P' + ); + } + + function it_generates_proper_name_for_no_class_and_interfaces_list() + { + $this->name(null, array())->shouldStartWith('Double\stdClass\P'); + } + + /** + * @param \ReflectionClass $class + * @param \ReflectionClass $interface1 + * @param \ReflectionClass $interface2 + */ + function its_name_generates_name_based_only_on_class_if_its_available( + $class, $interface1, $interface2 + ) + { + $class->getName()->willReturn('Some\Custom\Class'); + $interface1->getShortName()->willReturn('HandlerInterface'); + $interface2->getShortName()->willReturn('LoaderInterface'); + + $this->name($class, array($interface1, $interface2))->shouldStartWith( + 'Double\Some\Custom\Class\P' + ); + } + + public function getMatchers() + { + return array( + 'startWith' => function ($subject, $string) { + return 0 === strpos($subject, $string); + }, + ); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Exception/Call/UnexpectedCallExceptionSpec.php b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Exception/Call/UnexpectedCallExceptionSpec.php new file mode 100644 index 00000000..6fd1a5c3 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Exception/Call/UnexpectedCallExceptionSpec.php @@ -0,0 +1,32 @@ +beConstructedWith('msg', $objectProphecy, 'getName', array('arg1', 'arg2')); + } + + function it_is_prophecy_exception() + { + $this->shouldBeAnInstanceOf('Prophecy\Exception\Prophecy\ObjectProphecyException'); + } + + function it_exposes_method_name_through_getter() + { + $this->getMethodName()->shouldReturn('getName'); + } + + function it_exposes_arguments_through_getter() + { + $this->getArguments()->shouldReturn(array('arg1', 'arg2')); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Exception/Doubler/ClassCreatorExceptionSpec.php b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Exception/Doubler/ClassCreatorExceptionSpec.php new file mode 100644 index 00000000..58241385 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Exception/Doubler/ClassCreatorExceptionSpec.php @@ -0,0 +1,28 @@ +beConstructedWith('', $node); + } + + function it_is_a_prophecy_exception() + { + $this->shouldBeAnInstanceOf('Prophecy\Exception\Exception'); + $this->shouldBeAnInstanceOf('Prophecy\Exception\Doubler\DoublerException'); + } + + function it_contains_a_reflected_node($node) + { + $this->getClassNode()->shouldReturn($node); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Exception/Doubler/ClassMirrorExceptionSpec.php b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Exception/Doubler/ClassMirrorExceptionSpec.php new file mode 100644 index 00000000..21e31a34 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Exception/Doubler/ClassMirrorExceptionSpec.php @@ -0,0 +1,27 @@ +beConstructedWith('', $class); + } + + function it_is_a_prophecy_exception() + { + $this->shouldBeAnInstanceOf('Prophecy\Exception\Exception'); + $this->shouldBeAnInstanceOf('Prophecy\Exception\Doubler\DoublerException'); + } + + function it_contains_a_reflected_class_link($class) + { + $this->getReflectedClass()->shouldReturn($class); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Exception/Doubler/ClassNotFoundExceptionSpec.php b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Exception/Doubler/ClassNotFoundExceptionSpec.php new file mode 100644 index 00000000..251512b9 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Exception/Doubler/ClassNotFoundExceptionSpec.php @@ -0,0 +1,25 @@ +beConstructedWith('msg', 'CustomClass'); + } + + function it_is_a_prophecy_exception() + { + $this->shouldBeAnInstanceOf('Prophecy\Exception\Exception'); + $this->shouldBeAnInstanceOf('Prophecy\Exception\Doubler\DoubleException'); + } + + function its_getClassname_returns_classname() + { + $this->getClassname()->shouldReturn('CustomClass'); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Exception/Doubler/DoubleExceptionSpec.php b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Exception/Doubler/DoubleExceptionSpec.php new file mode 100644 index 00000000..6fe5a19a --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Exception/Doubler/DoubleExceptionSpec.php @@ -0,0 +1,14 @@ +shouldBeAnInstanceOf('RuntimeException'); + $this->shouldBeAnInstanceOf('Prophecy\Exception\Doubler\DoublerException'); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Exception/Doubler/InterfaceNotFoundExceptionSpec.php b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Exception/Doubler/InterfaceNotFoundExceptionSpec.php new file mode 100644 index 00000000..ad1a439e --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Exception/Doubler/InterfaceNotFoundExceptionSpec.php @@ -0,0 +1,24 @@ +beConstructedWith('msg', 'CustomInterface'); + } + + function it_extends_ClassNotFoundException() + { + $this->shouldBeAnInstanceOf('Prophecy\Exception\Doubler\ClassNotFoundException'); + } + + function its_getClassname_returns_classname() + { + $this->getClassname()->shouldReturn('CustomInterface'); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Exception/Doubler/MethodNotExtendableExceptionSpec.php b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Exception/Doubler/MethodNotExtendableExceptionSpec.php new file mode 100644 index 00000000..5028b026 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Exception/Doubler/MethodNotExtendableExceptionSpec.php @@ -0,0 +1,29 @@ +beConstructedWith('', 'User', 'getName'); + } + + function it_is_DoubleException() + { + $this->shouldHaveType('Prophecy\Exception\Doubler\DoubleException'); + } + + function it_has_MethodName() + { + $this->getMethodName()->shouldReturn('getName'); + } + + function it_has_classname() + { + $this->getClassName()->shouldReturn('User'); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Exception/Doubler/MethodNotFoundExceptionSpec.php b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Exception/Doubler/MethodNotFoundExceptionSpec.php new file mode 100644 index 00000000..a889dd7e --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Exception/Doubler/MethodNotFoundExceptionSpec.php @@ -0,0 +1,40 @@ +beConstructedWith('', 'User', 'getName', array(1, 2, 3)); + } + + function it_is_DoubleException() + { + $this->shouldHaveType('Prophecy\Exception\Doubler\DoubleException'); + } + + function it_has_MethodName() + { + $this->getMethodName()->shouldReturn('getName'); + } + + function it_has_classnamej() + { + $this->getClassname()->shouldReturn('User'); + } + + function it_has_an_arguments_list() + { + $this->getArguments()->shouldReturn(array(1, 2, 3)); + } + + function it_has_a_default_null_argument_list() + { + $this->beConstructedWith('', 'User', 'getName'); + $this->getArguments()->shouldReturn(null); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Exception/Prediction/AggregateExceptionSpec.php b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Exception/Prediction/AggregateExceptionSpec.php new file mode 100644 index 00000000..22a5ebdb --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Exception/Prediction/AggregateExceptionSpec.php @@ -0,0 +1,57 @@ +beConstructedWith(null); + } + + function it_is_prediction_exception() + { + $this->shouldBeAnInstanceOf('RuntimeException'); + $this->shouldBeAnInstanceOf('Prophecy\Exception\Prediction\PredictionException'); + } + + /** + * @param \Prophecy\Prophecy\ObjectProphecy $object + */ + function it_can_store_objectProphecy_link($object) + { + $this->setObjectProphecy($object); + $this->getObjectProphecy()->shouldReturn($object); + } + + function it_should_not_have_exceptions_at_the_beginning() + { + $this->getExceptions()->shouldHaveCount(0); + } + + /** + * @param \Prophecy\Exception\Prediction\PredictionException $exception + */ + function it_should_append_exception_through_append_method($exception) + { + $exception->getMessage()->willReturn('Exception #1'); + + $this->append($exception); + + $this->getExceptions()->shouldReturn(array($exception)); + } + + /** + * @param \Prophecy\Exception\Prediction\PredictionException $exception + */ + function it_should_update_message_during_append($exception) + { + $exception->getMessage()->willReturn('Exception #1'); + + $this->append($exception); + + $this->getMessage()->shouldReturn(" Exception #1"); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Exception/Prediction/NoCallsExceptionSpec.php b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Exception/Prediction/NoCallsExceptionSpec.php new file mode 100644 index 00000000..473f1a2d --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Exception/Prediction/NoCallsExceptionSpec.php @@ -0,0 +1,29 @@ +getObjectProphecy()->willReturn($objectProphecy); + + $this->beConstructedWith('message', $methodProphecy); + } + + function it_is_PredictionException() + { + $this->shouldHaveType('Prophecy\Exception\Prediction\PredictionException'); + } + + function it_extends_MethodProphecyException() + { + $this->shouldHaveType('Prophecy\Exception\Prophecy\MethodProphecyException'); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Exception/Prediction/UnexpectedCallsCountExceptionSpec.php b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Exception/Prediction/UnexpectedCallsCountExceptionSpec.php new file mode 100644 index 00000000..adad975b --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Exception/Prediction/UnexpectedCallsCountExceptionSpec.php @@ -0,0 +1,31 @@ +getObjectProphecy()->willReturn($objectProphecy); + + $this->beConstructedWith('message', $methodProphecy, 5, array($call1, $call2)); + } + + function it_extends_UnexpectedCallsException() + { + $this->shouldBeAnInstanceOf('Prophecy\Exception\Prediction\UnexpectedCallsException'); + } + + function it_should_expose_expectedCount_through_getter() + { + $this->getExpectedCount()->shouldReturn(5); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Exception/Prediction/UnexpectedCallsExceptionSpec.php b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Exception/Prediction/UnexpectedCallsExceptionSpec.php new file mode 100644 index 00000000..c0fe24d7 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Exception/Prediction/UnexpectedCallsExceptionSpec.php @@ -0,0 +1,36 @@ +getObjectProphecy()->willReturn($objectProphecy); + + $this->beConstructedWith('message', $methodProphecy, array($call1, $call2)); + } + + function it_is_PredictionException() + { + $this->shouldHaveType('Prophecy\Exception\Prediction\PredictionException'); + } + + function it_extends_MethodProphecyException() + { + $this->shouldHaveType('Prophecy\Exception\Prophecy\MethodProphecyException'); + } + + function it_should_expose_calls_list_through_getter($call1, $call2) + { + $this->getCalls()->shouldReturn(array($call1, $call2)); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Exception/Prophecy/MethodProphecyExceptionSpec.php b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Exception/Prophecy/MethodProphecyExceptionSpec.php new file mode 100644 index 00000000..97cf9e10 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Exception/Prophecy/MethodProphecyExceptionSpec.php @@ -0,0 +1,30 @@ +getObjectProphecy()->willReturn($objectProphecy); + + $this->beConstructedWith('message', $methodProphecy); + } + + function it_extends_DoubleException() + { + $this->shouldBeAnInstanceOf('Prophecy\Exception\Prophecy\ObjectProphecyException'); + } + + function it_holds_a_stub_reference($methodProphecy) + { + $this->getMethodProphecy()->shouldReturn($methodProphecy); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Exception/Prophecy/ObjectProphecyExceptionSpec.php b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Exception/Prophecy/ObjectProphecyExceptionSpec.php new file mode 100644 index 00000000..bcacfedc --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Exception/Prophecy/ObjectProphecyExceptionSpec.php @@ -0,0 +1,27 @@ +beConstructedWith('message', $objectProphecy); + } + + function it_should_be_a_prophecy_exception() + { + $this->shouldBeAnInstanceOf('Prophecy\Exception\Prophecy\ProphecyException'); + } + + function it_holds_double_reference($objectProphecy) + { + $this->getObjectProphecy()->shouldReturn($objectProphecy); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Prediction/CallPredictionSpec.php b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Prediction/CallPredictionSpec.php new file mode 100644 index 00000000..3da8c599 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Prediction/CallPredictionSpec.php @@ -0,0 +1,42 @@ +shouldHaveType('Prophecy\Prediction\PredictionInterface'); + } + + /** + * @param \Prophecy\Prophecy\ObjectProphecy $object + * @param \Prophecy\Prophecy\MethodProphecy $method + * @param \Prophecy\Call\Call $call + */ + function it_does_nothing_if_there_is_more_than_one_call_been_made($object, $method, $call) + { + $this->check(array($call), $object, $method)->shouldReturn(null); + } + + /** + * @param \Prophecy\Prophecy\ObjectProphecy $object + * @param \Prophecy\Prophecy\MethodProphecy $method + * @param \Prophecy\Argument\ArgumentsWildcard $arguments + */ + function it_throws_NoCallsException_if_no_calls_found($object, $method, $arguments) + { + $method->getObjectProphecy()->willReturn($object); + $method->getMethodName()->willReturn('getName'); + $method->getArgumentsWildcard()->willReturn($arguments); + $arguments->__toString()->willReturn('123'); + $object->reveal()->willReturn(new \stdClass()); + $object->findProphecyMethodCalls('getName', Argument::any())->willReturn(array()); + + $this->shouldThrow('Prophecy\Exception\Prediction\NoCallsException') + ->duringCheck(array(), $object, $method); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Prediction/CallTimesPredictionSpec.php b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Prediction/CallTimesPredictionSpec.php new file mode 100644 index 00000000..c6708927 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Prediction/CallTimesPredictionSpec.php @@ -0,0 +1,54 @@ +beConstructedWith(2); + } + + function it_is_prediction() + { + $this->shouldHaveType('Prophecy\Prediction\PredictionInterface'); + } + + /** + * @param \Prophecy\Prophecy\ObjectProphecy $object + * @param \Prophecy\Prophecy\MethodProphecy $method + * @param \Prophecy\Call\Call $call1 + * @param \Prophecy\Call\Call $call2 + */ + function it_does_nothing_if_there_were_exact_amount_of_calls_being_made( + $object, $method, $call1, $call2 + ) + { + $this->check(array($call1, $call2), $object, $method)->shouldReturn(null); + } + + /** + * @param \Prophecy\Prophecy\ObjectProphecy $object + * @param \Prophecy\Prophecy\MethodProphecy $method + * @param \Prophecy\Call\Call $call + * @param \Prophecy\Argument\ArgumentsWildcard $arguments + */ + function it_throws_UnexpectedCallsCountException_if_calls_found( + $object, $method, $call, $arguments + ) + { + $method->getObjectProphecy()->willReturn($object); + $method->getMethodName()->willReturn('getName'); + $method->getArgumentsWildcard()->willReturn($arguments); + $arguments->__toString()->willReturn('123'); + + $call->getMethodName()->willReturn('getName'); + $call->getArguments()->willReturn(array(5, 4, 'three')); + $call->getCallPlace()->willReturn('unknown'); + + $this->shouldThrow('Prophecy\Exception\Prediction\UnexpectedCallsCountException') + ->duringCheck(array($call), $object, $method); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Prediction/CallbackPredictionSpec.php b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Prediction/CallbackPredictionSpec.php new file mode 100644 index 00000000..7fe475ef --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Prediction/CallbackPredictionSpec.php @@ -0,0 +1,36 @@ +beConstructedWith('get_class'); + } + + function it_is_prediction() + { + $this->shouldHaveType('Prophecy\Prediction\PredictionInterface'); + } + + /** + * @param \Prophecy\Prophecy\ObjectProphecy $object + * @param \Prophecy\Prophecy\MethodProphecy $method + * @param \Prophecy\Call\Call $call + */ + function it_proxies_call_to_callback($object, $method, $call) + { + $returnFirstCallCallback = function ($calls, $object, $method) { + throw new RuntimeException; + }; + + $this->beConstructedWith($returnFirstCallCallback); + + $this->shouldThrow('RuntimeException')->duringCheck(array($call), $object, $method); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Prediction/NoCallsPredictionSpec.php b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Prediction/NoCallsPredictionSpec.php new file mode 100644 index 00000000..a3ef9bcb --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Prediction/NoCallsPredictionSpec.php @@ -0,0 +1,43 @@ +shouldHaveType('Prophecy\Prediction\PredictionInterface'); + } + + /** + * @param \Prophecy\Prophecy\ObjectProphecy $object + * @param \Prophecy\Prophecy\MethodProphecy $method + */ + function it_does_nothing_if_there_is_no_calls_made($object, $method) + { + $this->check(array(), $object, $method)->shouldReturn(null); + } + + /** + * @param \Prophecy\Prophecy\ObjectProphecy $object + * @param \Prophecy\Prophecy\MethodProphecy $method + * @param \Prophecy\Call\Call $call + * @param \Prophecy\Argument\ArgumentsWildcard $arguments + */ + function it_throws_UnexpectedCallsException_if_calls_found($object, $method, $call, $arguments) + { + $method->getObjectProphecy()->willReturn($object); + $method->getMethodName()->willReturn('getName'); + $method->getArgumentsWildcard()->willReturn($arguments); + $arguments->__toString()->willReturn('123'); + + $call->getMethodName()->willReturn('getName'); + $call->getArguments()->willReturn(array(5, 4, 'three')); + $call->getCallPlace()->willReturn('unknown'); + + $this->shouldThrow('Prophecy\Exception\Prediction\UnexpectedCallsException') + ->duringCheck(array($call), $object, $method); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Promise/CallbackPromiseSpec.php b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Promise/CallbackPromiseSpec.php new file mode 100644 index 00000000..5d99b1b1 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Promise/CallbackPromiseSpec.php @@ -0,0 +1,110 @@ +beConstructedWith('get_class'); + } + + function it_is_promise() + { + $this->shouldBeAnInstanceOf('Prophecy\Promise\PromiseInterface'); + } + + /** + * @param \Prophecy\Prophecy\ObjectProphecy $object + * @param \Prophecy\Prophecy\MethodProphecy $method + */ + function it_should_execute_closure_callback($object, $method) + { + $firstArgumentCallback = function ($args) { + return $args[0]; + }; + + $this->beConstructedWith($firstArgumentCallback); + + $this->execute(array('one', 'two'), $object, $method)->shouldReturn('one'); + } + + /** + * @param \Prophecy\Prophecy\ObjectProphecy $object + * @param \Prophecy\Prophecy\MethodProphecy $method + */ + function it_should_execute_static_array_callback($object, $method) + { + $firstArgumentCallback = array('spec\Prophecy\Promise\ClassCallback', 'staticCallbackMethod'); + + $this->beConstructedWith($firstArgumentCallback); + + $this->execute(array('one', 'two'), $object, $method)->shouldReturn('one'); + } + + /** + * @param \Prophecy\Prophecy\ObjectProphecy $object + * @param \Prophecy\Prophecy\MethodProphecy $method + */ + function it_should_execute_instance_array_callback($object, $method) + { + $class = new ClassCallback(); + $firstArgumentCallback = array($class, 'callbackMethod'); + + $this->beConstructedWith($firstArgumentCallback); + + $this->execute(array('one', 'two'), $object, $method)->shouldReturn('one'); + } + + /** + * @param \Prophecy\Prophecy\ObjectProphecy $object + * @param \Prophecy\Prophecy\MethodProphecy $method + */ + function it_should_execute_string_function_callback($object, $method) + { + $firstArgumentCallback = 'spec\Prophecy\Promise\functionCallbackFirstArgument'; + + $this->beConstructedWith($firstArgumentCallback); + + $this->execute(array('one', 'two'), $object, $method)->shouldReturn('one'); + } + +} + +/** + * Class used to test callbackpromise + * + * @param array + * @return string + */ +class ClassCallback +{ + /** + * @param array $args + */ + function callbackMethod($args) + { + return $args[0]; + } + + /** + * @param array $args + */ + static function staticCallbackMethod($args) + { + return $args[0]; + } +} + +/** + * Callback function used to test callbackpromise + * + * @param array + * @return string + */ +function functionCallbackFirstArgument($args) +{ + return $args[0]; +} diff --git a/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Promise/ReturnArgumentPromiseSpec.php b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Promise/ReturnArgumentPromiseSpec.php new file mode 100644 index 00000000..4acb7bb0 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Promise/ReturnArgumentPromiseSpec.php @@ -0,0 +1,41 @@ +shouldBeAnInstanceOf('Prophecy\Promise\PromiseInterface'); + } + + /** + * @param \Prophecy\Prophecy\ObjectProphecy $object + * @param \Prophecy\Prophecy\MethodProphecy $method + */ + function it_should_return_first_argument_if_provided($object, $method) + { + $this->execute(array('one', 'two'), $object, $method)->shouldReturn('one'); + } + + /** + * @param \Prophecy\Prophecy\ObjectProphecy $object + * @param \Prophecy\Prophecy\MethodProphecy $method + */ + function it_should_return_null_if_no_arguments_provided($object, $method) + { + $this->execute(array(), $object, $method)->shouldReturn(null); + } + + /** + * @param \Prophecy\Prophecy\ObjectProphecy $object + * @param \Prophecy\Prophecy\MethodProphecy $method + */ + function it_should_return_nth_argument_if_provided($object, $method) + { + $this->beConstructedWith(1); + $this->execute(array('one', 'two'), $object, $method)->shouldReturn('two'); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Promise/ReturnPromiseSpec.php b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Promise/ReturnPromiseSpec.php new file mode 100644 index 00000000..18bfd87a --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Promise/ReturnPromiseSpec.php @@ -0,0 +1,61 @@ +beConstructedWith(array(42)); + } + + function it_is_promise() + { + $this->shouldBeAnInstanceOf('Prophecy\Promise\PromiseInterface'); + } + + /** + * @param \Prophecy\Prophecy\ObjectProphecy $object + * @param \Prophecy\Prophecy\MethodProphecy $method + */ + function it_returns_value_it_was_constructed_with($object, $method) + { + $this->execute(array(), $object, $method)->shouldReturn(42); + } + + /** + * @param \Prophecy\Prophecy\ObjectProphecy $object + * @param \Prophecy\Prophecy\MethodProphecy $method + */ + function it_always_returns_last_value_left_in_the_return_values($object, $method) + { + $this->execute(array(), $object, $method)->shouldReturn(42); + $this->execute(array(), $object, $method)->shouldReturn(42); + } + + /** + * @param \Prophecy\Prophecy\ObjectProphecy $object + * @param \Prophecy\Prophecy\MethodProphecy $method + */ + function it_consequently_returns_multiple_values_it_was_constructed_with($object, $method) + { + $this->beConstructedWith(array(42, 24, 12)); + + $this->execute(array(), $object, $method)->shouldReturn(42); + $this->execute(array(), $object, $method)->shouldReturn(24); + $this->execute(array(), $object, $method)->shouldReturn(12); + } + + /** + * @param \Prophecy\Prophecy\ObjectProphecy $object + * @param \Prophecy\Prophecy\MethodProphecy $method + */ + function it_returns_null_if_constructed_with_empty_array($object, $method) + { + $this->beConstructedWith(array()); + + $this->execute(array(), $object, $method)->shouldReturn(null); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Promise/ThrowPromiseSpec.php b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Promise/ThrowPromiseSpec.php new file mode 100644 index 00000000..5f448979 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Promise/ThrowPromiseSpec.php @@ -0,0 +1,58 @@ +beConstructedWith('RuntimeException'); + } + + function it_is_promise() + { + $this->shouldBeAnInstanceOf('Prophecy\Promise\PromiseInterface'); + } + + /** + * @param \Prophecy\Prophecy\ObjectProphecy $object + * @param \Prophecy\Prophecy\MethodProphecy $method + */ + function it_instantiates_and_throws_exception_from_provided_classname($object, $method) + { + $this->beConstructedWith('InvalidArgumentException'); + + $this->shouldThrow('InvalidArgumentException') + ->duringExecute(array(), $object, $method); + } + + /** + * @param \Prophecy\Prophecy\ObjectProphecy $object + * @param \Prophecy\Prophecy\MethodProphecy $method + */ + function it_instantiates_exceptions_with_required_arguments($object, $method) + { + $this->beConstructedWith('spec\Prophecy\Promise\RequiredArgumentException'); + + $this->shouldThrow('spec\Prophecy\Promise\RequiredArgumentException') + ->duringExecute(array(), $object, $method); + } + + /** + * @param \Prophecy\Prophecy\ObjectProphecy $object + * @param \Prophecy\Prophecy\MethodProphecy $method + */ + function it_throws_provided_exception($object, $method) + { + $this->beConstructedWith($exc = new \RuntimeException('Some exception')); + + $this->shouldThrow($exc)->duringExecute(array(), $object, $method); + } +} + +class RequiredArgumentException extends \Exception +{ + final public function __construct($message, $code) {} +} diff --git a/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Prophecy/MethodProphecySpec.php b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Prophecy/MethodProphecySpec.php new file mode 100644 index 00000000..41ee8cde --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Prophecy/MethodProphecySpec.php @@ -0,0 +1,384 @@ +reveal()->willReturn($reflection); + + $this->beConstructedWith($objectProphecy, 'getName', null); + } + + function it_is_initializable() + { + $this->shouldHaveType('Prophecy\Prophecy\MethodProphecy'); + } + + function its_constructor_throws_MethodNotFoundException_for_unexisting_method($objectProphecy) + { + $this->shouldThrow('Prophecy\Exception\Doubler\MethodNotFoundException')->during( + '__construct', array($objectProphecy, 'getUnexisting', null) + ); + } + + /** + * @param ClassWithFinalMethod $subject + */ + function its_constructor_throws_MethodProphecyException_for_final_methods($objectProphecy, $subject) + { + $objectProphecy->reveal()->willReturn($subject); + + $this->shouldThrow('Prophecy\Exception\Prophecy\MethodProphecyException')->during( + '__construct', array($objectProphecy, 'finalMethod', null) + ); + } + + function its_constructor_transforms_array_passed_as_3rd_argument_to_ArgumentsWildcard( + $objectProphecy + ) + { + $this->beConstructedWith($objectProphecy, 'getName', array(42, 33)); + + $wildcard = $this->getArgumentsWildcard(); + $wildcard->shouldNotBe(null); + $wildcard->__toString()->shouldReturn('exact(42), exact(33)'); + } + + function its_constructor_does_not_touch_third_argument_if_it_is_null($objectProphecy) + { + $this->beConstructedWith($objectProphecy, 'getName', null); + + $wildcard = $this->getArgumentsWildcard(); + $wildcard->shouldBe(null); + } + + /** + * @param \Prophecy\Promise\PromiseInterface $promise + */ + function it_records_promise_through_will_method($promise, $objectProphecy) + { + $objectProphecy->addMethodProphecy($this)->willReturn(null); + + $this->will($promise); + $this->getPromise()->shouldReturn($promise); + } + + /** + * @param \Prophecy\Promise\PromiseInterface $promise + */ + function it_adds_itself_to_ObjectProphecy_during_call_to_will($objectProphecy, $promise) + { + $objectProphecy->addMethodProphecy($this)->shouldBeCalled(); + + $this->will($promise); + } + + function it_adds_ReturnPromise_during_willReturn_call($objectProphecy) + { + $objectProphecy->addMethodProphecy($this)->willReturn(null); + + $this->willReturn(42); + $this->getPromise()->shouldBeAnInstanceOf('Prophecy\Promise\ReturnPromise'); + } + + function it_adds_ThrowPromise_during_willThrow_call($objectProphecy) + { + $objectProphecy->addMethodProphecy($this)->willReturn(null); + + $this->willThrow('RuntimeException'); + $this->getPromise()->shouldBeAnInstanceOf('Prophecy\Promise\ThrowPromise'); + } + + function it_adds_ReturnArgumentPromise_during_willReturnArgument_call($objectProphecy) + { + $objectProphecy->addMethodProphecy($this)->willReturn(null); + + $this->willReturnArgument(); + $this->getPromise()->shouldBeAnInstanceOf('Prophecy\Promise\ReturnArgumentPromise'); + } + + function it_adds_ReturnArgumentPromise_during_willReturnArgument_call_with_index_argument($objectProphecy) + { + $objectProphecy->addMethodProphecy($this)->willReturn(null); + + $this->willReturnArgument(1); + $promise = $this->getPromise(); + $promise->shouldBeAnInstanceOf('Prophecy\Promise\ReturnArgumentPromise'); + $promise->execute(array('one', 'two'), $objectProphecy, $this)->shouldReturn('two'); + } + + function it_adds_CallbackPromise_during_will_call_with_callback_argument($objectProphecy) + { + $objectProphecy->addMethodProphecy($this)->willReturn(null); + + $callback = function () {}; + + $this->will($callback); + $this->getPromise()->shouldBeAnInstanceOf('Prophecy\Promise\CallbackPromise'); + } + + /** + * @param \Prophecy\Prediction\PredictionInterface $prediction + */ + function it_records_prediction_through_should_method($prediction, $objectProphecy) + { + $objectProphecy->addMethodProphecy($this)->willReturn(null); + + $this->callOnWrappedObject('should', array($prediction)); + $this->getPrediction()->shouldReturn($prediction); + } + + function it_adds_CallbackPrediction_during_should_call_with_callback_argument($objectProphecy) + { + $objectProphecy->addMethodProphecy($this)->willReturn(null); + + $callback = function () {}; + + $this->callOnWrappedObject('should', array($callback)); + $this->getPrediction()->shouldBeAnInstanceOf('Prophecy\Prediction\CallbackPrediction'); + } + + /** + * @param \Prophecy\Prediction\PredictionInterface $prediction + */ + function it_adds_itself_to_ObjectProphecy_during_call_to_should($objectProphecy, $prediction) + { + $objectProphecy->addMethodProphecy($this)->shouldBeCalled(); + + $this->callOnWrappedObject('should', array($prediction)); + } + + function it_adds_CallPrediction_during_shouldBeCalled_call($objectProphecy) + { + $objectProphecy->addMethodProphecy($this)->willReturn(null); + + $this->callOnWrappedObject('shouldBeCalled', array()); + $this->getPrediction()->shouldBeAnInstanceOf('Prophecy\Prediction\CallPrediction'); + } + + function it_adds_NoCallsPrediction_during_shouldNotBeCalled_call($objectProphecy) + { + $objectProphecy->addMethodProphecy($this)->willReturn(null); + + $this->callOnWrappedObject('shouldNotBeCalled', array()); + $this->getPrediction()->shouldBeAnInstanceOf('Prophecy\Prediction\NoCallsPrediction'); + } + + function it_adds_CallTimesPrediction_during_shouldBeCalledTimes_call($objectProphecy) + { + $objectProphecy->addMethodProphecy($this)->willReturn(null); + + $this->callOnWrappedObject('shouldBeCalledTimes', array(5)); + $this->getPrediction()->shouldBeAnInstanceOf('Prophecy\Prediction\CallTimesPrediction'); + } + + /** + * @param \Prophecy\Argument\ArgumentsWildcard $arguments + * @param \Prophecy\Prediction\PredictionInterface $prediction + * @param \Prophecy\Call\Call $call1 + * @param \Prophecy\Call\Call $call2 + */ + function it_checks_prediction_via_shouldHave_method_call( + $objectProphecy, $arguments, $prediction, $call1, $call2 + ) + { + $objectProphecy->addMethodProphecy($this)->willReturn(null); + $prediction->check(array($call1, $call2), $objectProphecy->getWrappedObject(), $this)->shouldBeCalled(); + $objectProphecy->findProphecyMethodCalls('getName', $arguments)->willReturn(array($call1, $call2)); + + $this->withArguments($arguments); + $this->callOnWrappedObject('shouldHave', array($prediction)); + } + + /** + * @param \Prophecy\Argument\ArgumentsWildcard $arguments + * @param \Prophecy\Prediction\PredictionInterface $prediction + * @param \Prophecy\Call\Call $call1 + * @param \Prophecy\Call\Call $call2 + */ + function it_sets_return_promise_during_shouldHave_call_if_none_was_set_before( + $objectProphecy, $arguments, $prediction, $call1, $call2 + ) + { + $objectProphecy->addMethodProphecy($this)->willReturn(null); + $prediction->check(array($call1, $call2), $objectProphecy->getWrappedObject(), $this)->shouldBeCalled(); + $objectProphecy->findProphecyMethodCalls('getName', $arguments)->willReturn(array($call1, $call2)); + + $this->withArguments($arguments); + $this->callOnWrappedObject('shouldHave', array($prediction)); + + $this->getPromise()->shouldReturnAnInstanceOf('Prophecy\Promise\ReturnPromise'); + } + + /** + * @param \Prophecy\Argument\ArgumentsWildcard $arguments + * @param \Prophecy\Prediction\PredictionInterface $prediction + * @param \Prophecy\Call\Call $call1 + * @param \Prophecy\Call\Call $call2 + * @param \Prophecy\Promise\PromiseInterface $promise + */ + function it_does_not_set_return_promise_during_shouldHave_call_if_it_was_set_before( + $objectProphecy, $arguments, $prediction, $call1, $call2, $promise + ) + { + $objectProphecy->addMethodProphecy($this)->willReturn(null); + $prediction->check(array($call1, $call2), $objectProphecy->getWrappedObject(), $this)->shouldBeCalled(); + $objectProphecy->findProphecyMethodCalls('getName', $arguments)->willReturn(array($call1, $call2)); + + $this->will($promise); + $this->withArguments($arguments); + $this->callOnWrappedObject('shouldHave', array($prediction)); + + $this->getPromise()->shouldReturn($promise); + } + + /** + * @param \Prophecy\Argument\ArgumentsWildcard $arguments + * @param \Prophecy\Prediction\PredictionInterface $prediction1 + * @param \Prophecy\Prediction\PredictionInterface $prediction2 + * @param \Prophecy\Call\Call $call1 + * @param \Prophecy\Call\Call $call2 + * @param \Prophecy\Promise\PromiseInterface $promise + */ + function it_records_checked_predictions( + $objectProphecy, $arguments, $prediction1, $prediction2, $call1, $call2, $promise + ) + { + $objectProphecy->addMethodProphecy($this)->willReturn(null); + $prediction1->check(array($call1, $call2), $objectProphecy->getWrappedObject(), $this)->willReturn(); + $prediction2->check(array($call1, $call2), $objectProphecy->getWrappedObject(), $this)->willReturn(); + $objectProphecy->findProphecyMethodCalls('getName', $arguments)->willReturn(array($call1, $call2)); + + $this->will($promise); + $this->withArguments($arguments); + $this->callOnWrappedObject('shouldHave', array($prediction1)); + $this->callOnWrappedObject('shouldHave', array($prediction2)); + + $this->getCheckedPredictions()->shouldReturn(array($prediction1, $prediction2)); + } + + /** + * @param \Prophecy\Argument\ArgumentsWildcard $arguments + * @param \Prophecy\Prediction\PredictionInterface $prediction + * @param \Prophecy\Call\Call $call1 + * @param \Prophecy\Call\Call $call2 + * @param \Prophecy\Promise\PromiseInterface $promise + */ + function it_records_even_failed_checked_predictions( + $objectProphecy, $arguments, $prediction, $call1, $call2, $promise + ) + { + $objectProphecy->addMethodProphecy($this)->willReturn(null); + $prediction->check(array($call1, $call2), $objectProphecy->getWrappedObject(), $this)->willThrow(new \RuntimeException()); + $objectProphecy->findProphecyMethodCalls('getName', $arguments)->willReturn(array($call1, $call2)); + + $this->will($promise); + $this->withArguments($arguments); + + try { + $this->callOnWrappedObject('shouldHave', array($prediction)); + } catch (\Exception $e) {} + + $this->getCheckedPredictions()->shouldReturn(array($prediction)); + } + + /** + * @param \Prophecy\Argument\ArgumentsWildcard $arguments + * @param \Prophecy\Prediction\PredictionInterface $prediction + * @param \Prophecy\Call\Call $call1 + * @param \Prophecy\Call\Call $call2 + */ + function it_checks_prediction_via_shouldHave_method_call_with_callback( + $objectProphecy, $arguments, $prediction, $call1, $call2 + ) + { + $callback = function ($calls, $object, $method) { + throw new \RuntimeException; + }; + $objectProphecy->findProphecyMethodCalls('getName', $arguments)->willReturn(array($call1, $call2)); + + $this->withArguments($arguments); + $this->shouldThrow('RuntimeException')->duringShouldHave($callback); + } + + function it_does_nothing_during_checkPrediction_if_no_prediction_set() + { + $this->checkPrediction()->shouldReturn(null); + } + + /** + * @param \Prophecy\Argument\ArgumentsWildcard $arguments + * @param \Prophecy\Prediction\PredictionInterface $prediction + * @param \Prophecy\Call\Call $call1 + * @param \Prophecy\Call\Call $call2 + */ + function it_checks_set_prediction_during_checkPrediction( + $objectProphecy, $arguments, $prediction, $call1, $call2 + ) + { + $prediction->check(array($call1, $call2), $objectProphecy->getWrappedObject(), $this)->shouldBeCalled(); + $objectProphecy->findProphecyMethodCalls('getName', $arguments)->willReturn(array($call1, $call2)); + $objectProphecy->addMethodProphecy($this)->willReturn(null); + + $this->withArguments($arguments); + $this->callOnWrappedObject('should', array($prediction)); + $this->checkPrediction(); + } + + function it_links_back_to_ObjectProphecy_through_getter($objectProphecy) + { + $this->getObjectProphecy()->shouldReturn($objectProphecy); + } + + function it_has_MethodName() + { + $this->getMethodName()->shouldReturn('getName'); + } + + /** + * @param \Prophecy\Argument\ArgumentsWildcard $wildcard + */ + function it_contains_ArgumentsWildcard_it_was_constructed_with($objectProphecy, $wildcard) + { + $this->beConstructedWith($objectProphecy, 'getName', $wildcard); + + $this->getArgumentsWildcard()->shouldReturn($wildcard); + } + + /** + * @param \Prophecy\Argument\ArgumentsWildcard $wildcard + */ + function its_ArgumentWildcard_is_mutable_through_setter($wildcard) + { + $this->withArguments($wildcard); + + $this->getArgumentsWildcard()->shouldReturn($wildcard); + } + + function its_withArguments_transforms_passed_array_into_ArgumentsWildcard() + { + $this->withArguments(array(42, 33)); + + $wildcard = $this->getArgumentsWildcard(); + $wildcard->shouldNotBe(null); + $wildcard->__toString()->shouldReturn('exact(42), exact(33)'); + } + + function its_withArguments_throws_exception_if_wrong_arguments_provided() + { + $this->shouldThrow('Prophecy\Exception\InvalidArgumentException')->duringWithArguments(42); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Prophecy/ObjectProphecySpec.php b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Prophecy/ObjectProphecySpec.php new file mode 100644 index 00000000..7e249d9b --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Prophecy/ObjectProphecySpec.php @@ -0,0 +1,319 @@ +beConstructedWith($lazyDouble); + + $lazyDouble->getInstance()->willReturn($double); + } + + function it_implements_ProphecyInterface() + { + $this->shouldBeAnInstanceOf('Prophecy\Prophecy\ProphecyInterface'); + } + + function it_sets_parentClass_during_willExtend_call($lazyDouble) + { + $lazyDouble->setParentClass('123')->shouldBeCalled(); + + $this->willExtend('123'); + } + + function it_adds_interface_during_willImplement_call($lazyDouble) + { + $lazyDouble->addInterface('222')->shouldBeCalled(); + + $this->willImplement('222'); + } + + function it_sets_constructor_arguments_during_willBeConstructedWith_call($lazyDouble) + { + $lazyDouble->setArguments(array(1, 2, 5))->shouldBeCalled(); + + $this->willBeConstructedWith(array(1, 2, 5)); + } + + function it_does_not_have_method_prophecies_by_default() + { + $this->getMethodProphecies()->shouldHaveCount(0); + } + + /** + * @param \Prophecy\Prophecy\MethodProphecy $method1 + * @param \Prophecy\Prophecy\MethodProphecy $method2 + * @param \Prophecy\Argument\ArgumentsWildcard $arguments + */ + function it_should_get_method_prophecies_by_method_name($method1, $method2, $arguments) + { + $method1->getMethodName()->willReturn('getName'); + $method1->getArgumentsWildcard()->willReturn($arguments); + $method2->getMethodName()->willReturn('setName'); + $method2->getArgumentsWildcard()->willReturn($arguments); + + $this->addMethodProphecy($method1); + $this->addMethodProphecy($method2); + + $methods = $this->getMethodProphecies('setName'); + $methods->shouldHaveCount(1); + $methods[0]->getMethodName()->shouldReturn('setName'); + } + + function it_should_return_empty_array_if_no_method_prophecies_found() + { + $methods = $this->getMethodProphecies('setName'); + $methods->shouldHaveCount(0); + } + + /** + * @param \Prophecy\Call\CallCenter $callCenter + */ + function it_should_proxy_makeProphecyMethodCall_to_CallCenter($lazyDouble, $callCenter) + { + $this->beConstructedWith($lazyDouble, $callCenter); + + $callCenter->makeCall($this->getWrappedObject(), 'setName', array('everzet'))->willReturn(42); + + $this->makeProphecyMethodCall('setName', array('everzet'))->shouldReturn(42); + } + + /** + * @param \Prophecy\Call\CallCenter $callCenter + * @param \Prophecy\Prophecy\RevealerInterface $revealer + */ + function it_should_reveal_arguments_and_return_values_from_callCenter( + $lazyDouble, $callCenter, $revealer + ) + { + $this->beConstructedWith($lazyDouble, $callCenter, $revealer); + + $revealer->reveal(array('question'))->willReturn(array('life')); + $revealer->reveal('answer')->willReturn(42); + + $callCenter->makeCall($this->getWrappedObject(), 'setName', array('life'))->willReturn('answer'); + + $this->makeProphecyMethodCall('setName', array('question'))->shouldReturn(42); + } + + /** + * @param \Prophecy\Call\CallCenter $callCenter + * @param \Prophecy\Argument\ArgumentsWildcard $wildcard + * @param \Prophecy\Call\Call $call + */ + function it_should_proxy_getProphecyMethodCalls_to_CallCenter( + $lazyDouble, $callCenter, $wildcard, $call + ) + { + $this->beConstructedWith($lazyDouble, $callCenter); + + $callCenter->findCalls('setName', $wildcard)->willReturn(array($call)); + + $this->findProphecyMethodCalls('setName', $wildcard)->shouldReturn(array($call)); + } + + /** + * @param \Prophecy\Prophecy\MethodProphecy $methodProphecy + * @param \Prophecy\Argument\ArgumentsWildcard $argumentsWildcard + */ + function its_addMethodProphecy_adds_method_prophecy( + $methodProphecy, $argumentsWildcard + ) + { + $methodProphecy->getArgumentsWildcard()->willReturn($argumentsWildcard); + $methodProphecy->getMethodName()->willReturn('getUsername'); + + $this->addMethodProphecy($methodProphecy); + + $this->getMethodProphecies()->shouldReturn(array( + 'getUsername' => array($methodProphecy) + )); + } + + /** + * @param \Prophecy\Prophecy\MethodProphecy $methodProphecy1 + * @param \Prophecy\Prophecy\MethodProphecy $methodProphecy2 + * @param \Prophecy\Argument\ArgumentsWildcard $argumentsWildcard1 + * @param \Prophecy\Argument\ArgumentsWildcard $argumentsWildcard2 + */ + function its_addMethodProphecy_handles_prophecies_with_different_arguments( + $methodProphecy1, $methodProphecy2, $argumentsWildcard1, $argumentsWildcard2 + ) + { + $methodProphecy1->getArgumentsWildcard()->willReturn($argumentsWildcard1); + $methodProphecy1->getMethodName()->willReturn('getUsername'); + + $methodProphecy2->getArgumentsWildcard()->willReturn($argumentsWildcard2); + $methodProphecy2->getMethodName()->willReturn('getUsername'); + + $this->addMethodProphecy($methodProphecy1); + $this->addMethodProphecy($methodProphecy2); + + $this->getMethodProphecies()->shouldReturn(array( + 'getUsername' => array( + $methodProphecy1, + $methodProphecy2, + ) + )); + } + + /** + * @param \Prophecy\Prophecy\MethodProphecy $methodProphecy1 + * @param \Prophecy\Prophecy\MethodProphecy $methodProphecy2 + * @param \Prophecy\Argument\ArgumentsWildcard $argumentsWildcard1 + * @param \Prophecy\Argument\ArgumentsWildcard $argumentsWildcard2 + */ + function its_addMethodProphecy_handles_prophecies_for_different_methods( + $methodProphecy1, $methodProphecy2, $argumentsWildcard1, $argumentsWildcard2 + ) + { + $methodProphecy1->getArgumentsWildcard()->willReturn($argumentsWildcard1); + $methodProphecy1->getMethodName()->willReturn('getUsername'); + + $methodProphecy2->getArgumentsWildcard()->willReturn($argumentsWildcard2); + $methodProphecy2->getMethodName()->willReturn('isUsername'); + + $this->addMethodProphecy($methodProphecy1); + $this->addMethodProphecy($methodProphecy2); + + $this->getMethodProphecies()->shouldReturn(array( + 'getUsername' => array( + $methodProphecy1 + ), + 'isUsername' => array( + $methodProphecy2 + ) + )); + } + + /** + * @param \Prophecy\Prophecy\MethodProphecy $methodProphecy + */ + function its_addMethodProphecy_throws_exception_when_method_has_no_ArgumentsWildcard( + $methodProphecy + ) + { + $methodProphecy->getArgumentsWildcard()->willReturn(null); + $methodProphecy->getObjectProphecy()->willReturn($this); + $methodProphecy->getMethodName()->willReturn('getTitle'); + + $this->shouldThrow('Prophecy\Exception\Prophecy\MethodProphecyException')->duringAddMethodProphecy( + $methodProphecy + ); + } + + function it_returns_null_after_checkPredictions_call_if_there_is_no_method_prophecies() + { + $this->checkProphecyMethodsPredictions()->shouldReturn(null); + } + + /** + * @param \Prophecy\Prophecy\MethodProphecy $methodProphecy1 + * @param \Prophecy\Prophecy\MethodProphecy $methodProphecy2 + * @param \Prophecy\Argument\ArgumentsWildcard $argumentsWildcard1 + * @param \Prophecy\Argument\ArgumentsWildcard $argumentsWildcard2 + */ + function it_throws_AggregateException_during_checkPredictions_if_predictions_fail( + $methodProphecy1, $methodProphecy2, $argumentsWildcard1, $argumentsWildcard2 + ) + { + $methodProphecy1->getMethodName()->willReturn('getName'); + $methodProphecy1->getArgumentsWildcard()->willReturn($argumentsWildcard1); + $methodProphecy1->checkPrediction() + ->willThrow('Prophecy\Exception\Prediction\AggregateException'); + + $methodProphecy2->getMethodName()->willReturn('setName'); + $methodProphecy2->getArgumentsWildcard()->willReturn($argumentsWildcard2); + $methodProphecy2->checkPrediction() + ->willThrow('Prophecy\Exception\Prediction\AggregateException'); + + $this->addMethodProphecy($methodProphecy1); + $this->addMethodProphecy($methodProphecy2); + + $this->shouldThrow('Prophecy\Exception\Prediction\AggregateException') + ->duringCheckProphecyMethodsPredictions(); + } + + /** + * @param \Prophecy\Doubler\Doubler $doubler + * @param \Prophecy\Prophecy\ProphecySubjectInterface $reflection + */ + function it_returns_new_MethodProphecy_instance_for_arbitrary_call($doubler, $reflection) + { + $doubler->double(Argument::any())->willReturn($reflection); + + $return = $this->getProphecy(); + $return->shouldBeAnInstanceOf('Prophecy\Prophecy\MethodProphecy'); + $return->getMethodName()->shouldReturn('getProphecy'); + } + + /** + * @param \Prophecy\Doubler\Doubler $doubler + * @param \Prophecy\Prophecy\ProphecySubjectInterface $reflection + */ + function it_returns_same_MethodProphecy_for_same_registered_signature($doubler, $reflection) + { + $doubler->double(Argument::any())->willReturn($reflection); + + $this->addMethodProphecy($methodProphecy1 = $this->getProphecy(1, 2, 3)); + $methodProphecy2 = $this->getProphecy(1, 2, 3); + + $methodProphecy2->shouldBe($methodProphecy1); + } + + /** + * @param \Prophecy\Doubler\Doubler $doubler + * @param \Prophecy\Prophecy\ProphecySubjectInterface $reflection + */ + function it_returns_new_MethodProphecy_for_different_signatures($doubler, $reflection) + { + $doubler->double(Argument::any())->willReturn($reflection); + + $value = new ObjectProphecySpecFixtureB('ABC'); + $value2 = new ObjectProphecySpecFixtureB('CBA'); + + $this->addMethodProphecy($methodProphecy1 = $this->getProphecy(1, 2, 3, $value)); + $methodProphecy2 = $this->getProphecy(1, 2, 3, $value2); + + $methodProphecy2->shouldNotBe($methodProphecy1); + } + + /** + * @param \Prophecy\Doubler\Doubler $doubler + * @param \Prophecy\Prophecy\ProphecySubjectInterface $reflection + */ + function it_returns_new_MethodProphecy_for_all_callback_signatures($doubler, $reflection) + { + $doubler->double(Argument::any())->willReturn($reflection); + + $this->addMethodProphecy($methodProphecy1 = $this->getProphecy(function(){})); + $methodProphecy2 = $this->getProphecy(function(){}); + + $methodProphecy2->shouldNotBe($methodProphecy1); + } +} + +class ObjectProphecySpecFixtureA +{ + public $errors; +} + +class ObjectProphecySpecFixtureB extends ObjectProphecySpecFixtureA +{ + public $errors; + public $value = null; + + public function __construct($value) + { + $this->value = $value; + } +} diff --git a/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Prophecy/RevealerSpec.php b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Prophecy/RevealerSpec.php new file mode 100644 index 00000000..4d83d739 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Prophecy/RevealerSpec.php @@ -0,0 +1,51 @@ +shouldBeAnInstanceOf('Prophecy\Prophecy\RevealerInterface'); + } + + /** + * @param \Prophecy\Prophecy\ProphecyInterface $prophecy + * @param \stdClass $object + */ + function it_reveals_single_instance_of_ProphecyInterface($prophecy, $object) + { + $prophecy->reveal()->willReturn($object); + + $this->reveal($prophecy)->shouldReturn($object); + } + + /** + * @param \Prophecy\Prophecy\ProphecyInterface $prophecy1 + * @param \Prophecy\Prophecy\ProphecyInterface $prophecy2 + * @param \stdClass $object1 + * @param \stdClass $object2 + */ + function it_reveals_instances_of_ProphecyInterface_inside_array( + $prophecy1, $prophecy2, $object1, $object2 + ) + { + $prophecy1->reveal()->willReturn($object1); + $prophecy2->reveal()->willReturn($object2); + + $this->reveal(array( + array('item' => $prophecy2), + $prophecy1 + ))->shouldReturn(array( + array('item' => $object2), + $object1 + )); + } + + function it_does_not_touch_non_prophecy_interface() + { + $this->reveal(42)->shouldReturn(42); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/spec/Prophecy/ProphetSpec.php b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/ProphetSpec.php new file mode 100644 index 00000000..74d5976a --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/ProphetSpec.php @@ -0,0 +1,91 @@ +double(null, array())->willReturn($double); + + $this->beConstructedWith($doubler); + } + + function it_constructs_new_prophecy_on_prophesize_call() + { + $prophecy = $this->prophesize(); + $prophecy->shouldBeAnInstanceOf('Prophecy\Prophecy\ObjectProphecy'); + } + + /** + * @param \Prophecy\Prophecy\ProphecySubjectInterface $newDouble + */ + function it_constructs_new_prophecy_with_parent_class_if_specified($doubler, $newDouble) + { + $doubler->double(Argument::any(), array())->willReturn($newDouble); + + $this->prophesize('Prophecy\Prophet')->reveal()->shouldReturn($newDouble); + } + + /** + * @param \Prophecy\Prophecy\ProphecySubjectInterface $newDouble + */ + function it_constructs_new_prophecy_with_interface_if_specified($doubler, $newDouble) + { + $doubler->double(null, Argument::any())->willReturn($newDouble); + + $this->prophesize('ArrayAccess')->reveal()->shouldReturn($newDouble); + } + + function it_exposes_all_created_prophecies_through_getter() + { + $prophecy1 = $this->prophesize(); + $prophecy2 = $this->prophesize(); + + $this->getProphecies()->shouldReturn(array($prophecy1, $prophecy2)); + } + + function it_does_nothing_during_checkPredictions_call_if_no_predictions_defined() + { + $this->checkPredictions()->shouldReturn(null); + } + + /** + * @param \Prophecy\Prophecy\MethodProphecy $method1 + * @param \Prophecy\Prophecy\MethodProphecy $method2 + * @param \Prophecy\Argument\ArgumentsWildcard $arguments1 + * @param \Prophecy\Argument\ArgumentsWildcard $arguments2 + */ + function it_throws_AggregateException_if_defined_predictions_fail( + $method1, $method2, $arguments1, $arguments2 + ) + { + $method1->getMethodName()->willReturn('getName'); + $method1->getArgumentsWildcard()->willReturn($arguments1); + $method1->checkPrediction()->willReturn(null); + + $method2->getMethodName()->willReturn('isSet'); + $method2->getArgumentsWildcard()->willReturn($arguments2); + $method2->checkPrediction()->willThrow( + 'Prophecy\Exception\Prediction\AggregateException' + ); + + $this->prophesize()->addMethodProphecy($method1); + $this->prophesize()->addMethodProphecy($method2); + + $this->shouldThrow('Prophecy\Exception\Prediction\AggregateException') + ->duringCheckPredictions(); + } + + function it_exposes_doubler_through_getter($doubler) + { + $this->getDoubler()->shouldReturn($doubler); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Util/StringUtilSpec.php b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Util/StringUtilSpec.php new file mode 100644 index 00000000..a4eef59f --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/spec/Prophecy/Util/StringUtilSpec.php @@ -0,0 +1,97 @@ +stringify(42)->shouldReturn('42'); + } + + function it_generates_proper_string_representation_for_string() + { + $this->stringify('some string')->shouldReturn('"some string"'); + } + + function it_generates_single_line_representation_for_multiline_string() + { + $this->stringify("some\nstring")->shouldReturn('"some\\nstring"'); + } + + function it_generates_proper_string_representation_for_double() + { + $this->stringify(42.3)->shouldReturn('42.3'); + } + + function it_generates_proper_string_representation_for_boolean_true() + { + $this->stringify(true)->shouldReturn('true'); + } + + function it_generates_proper_string_representation_for_boolean_false() + { + $this->stringify(false)->shouldReturn('false'); + } + + function it_generates_proper_string_representation_for_null() + { + $this->stringify(null)->shouldReturn('null'); + } + + function it_generates_proper_string_representation_for_empty_array() + { + $this->stringify(array())->shouldReturn('[]'); + } + + function it_generates_proper_string_representation_for_array() + { + $this->stringify(array('zet', 42))->shouldReturn('["zet", 42]'); + } + + function it_generates_proper_string_representation_for_hash_containing_one_value() + { + $this->stringify(array('ever' => 'zet'))->shouldReturn('["ever" => "zet"]'); + } + + function it_generates_proper_string_representation_for_hash() + { + $this->stringify(array('ever' => 'zet', 52 => 'hey', 'num' => 42))->shouldReturn( + '["ever" => "zet", 52 => "hey", "num" => 42]' + ); + } + + function it_generates_proper_string_representation_for_resource() + { + $resource = fopen(__FILE__, 'r'); + $this->stringify($resource)->shouldReturn('stream:'.$resource); + } + + /** + * @param \stdClass $object + */ + function it_generates_proper_string_representation_for_object($object) + { + $objHash = sprintf('%s:%s', + get_class($object->getWrappedObject()), + spl_object_hash($object->getWrappedObject()) + ) . " Object (\n 'objectProphecy' => Prophecy\Prophecy\ObjectProphecy Object (*Prophecy*)\n)"; + + $this->stringify($object)->shouldReturn("$objHash"); + } + + /** + * @param stdClass $object + */ + function it_generates_proper_string_representation_for_object_without_exporting($object) + { + $objHash = sprintf('%s:%s', + get_class($object->getWrappedObject()), + spl_object_hash($object->getWrappedObject()) + ); + + $this->stringify($object, false)->shouldReturn("$objHash"); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument.php new file mode 100644 index 00000000..fde6aa90 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument.php @@ -0,0 +1,212 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy; + +use Prophecy\Argument\Token; + +/** + * Argument tokens shortcuts. + * + * @author Konstantin Kudryashov + */ +class Argument +{ + /** + * Checks that argument is exact value or object. + * + * @param mixed $value + * + * @return Token\ExactValueToken + */ + public static function exact($value) + { + return new Token\ExactValueToken($value); + } + + /** + * Checks that argument is of specific type or instance of specific class. + * + * @param string $type Type name (`integer`, `string`) or full class name + * + * @return Token\TypeToken + */ + public static function type($type) + { + return new Token\TypeToken($type); + } + + /** + * Checks that argument object has specific state. + * + * @param string $methodName + * @param mixed $value + * + * @return Token\ObjectStateToken + */ + public static function which($methodName, $value) + { + return new Token\ObjectStateToken($methodName, $value); + } + + /** + * Checks that argument matches provided callback. + * + * @param callable $callback + * + * @return Token\CallbackToken + */ + public static function that($callback) + { + return new Token\CallbackToken($callback); + } + + /** + * Matches any single value. + * + * @return Token\AnyValueToken + */ + public static function any() + { + return new Token\AnyValueToken; + } + + /** + * Matches all values to the rest of the signature. + * + * @return Token\AnyValuesToken + */ + public static function cetera() + { + return new Token\AnyValuesToken; + } + + /** + * Checks that argument matches all tokens + * + * @param mixed ... a list of tokens + * + * @return Token\LogicalAndToken + */ + public static function allOf() + { + return new Token\LogicalAndToken(func_get_args()); + } + + /** + * Checks that argument array or countable object has exact number of elements. + * + * @param integer $value array elements count + * + * @return Token\ArrayCountToken + */ + public static function size($value) + { + return new Token\ArrayCountToken($value); + } + + /** + * Checks that argument array contains (key, value) pair + * + * @param mixed $key exact value or token + * @param mixed $value exact value or token + * + * @return Token\ArrayEntryToken + */ + public static function withEntry($key, $value) + { + return new Token\ArrayEntryToken($key, $value); + } + + /** + * Checks that arguments array entries all match value + * + * @param mixed $value + * + * @return Token\ArrayEveryEntryToken + */ + public static function withEveryEntry($value) + { + return new Token\ArrayEveryEntryToken($value); + } + + /** + * Checks that argument array contains value + * + * @param mixed $value + * + * @return Token\ArrayEntryToken + */ + public static function containing($value) + { + return new Token\ArrayEntryToken(self::any(), $value); + } + + /** + * Checks that argument array has key + * + * @param mixed $key exact value or token + * + * @return Token\ArrayEntryToken + */ + public static function withKey($key) + { + return new Token\ArrayEntryToken($key, self::any()); + } + + /** + * Checks that argument does not match the value|token. + * + * @param mixed $value either exact value or argument token + * + * @return Token\LogicalNotToken + */ + public static function not($value) + { + return new Token\LogicalNotToken($value); + } + + /** + * @param string $value + * + * @return Token\StringContainsToken + */ + public static function containingString($value) + { + return new Token\StringContainsToken($value); + } + + /** + * Checks that argument is identical value. + * + * @param mixed $value + * + * @return Token\IdenticalValueToken + */ + public static function is($value) + { + return new Token\IdenticalValueToken($value); + } + + /** + * Check that argument is same value when rounding to the + * given precision. + * + * @param float $value + * @param float $precision + * + * @return Token\ApproximateValueToken + */ + public static function approximate($value, $precision = 0) + { + return new Token\ApproximateValueToken($value, $precision); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument/ArgumentsWildcard.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument/ArgumentsWildcard.php new file mode 100644 index 00000000..a088f21d --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument/ArgumentsWildcard.php @@ -0,0 +1,101 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Argument; + +/** + * Arguments wildcarding. + * + * @author Konstantin Kudryashov + */ +class ArgumentsWildcard +{ + /** + * @var Token\TokenInterface[] + */ + private $tokens = array(); + private $string; + + /** + * Initializes wildcard. + * + * @param array $arguments Array of argument tokens or values + */ + public function __construct(array $arguments) + { + foreach ($arguments as $argument) { + if (!$argument instanceof Token\TokenInterface) { + $argument = new Token\ExactValueToken($argument); + } + + $this->tokens[] = $argument; + } + } + + /** + * Calculates wildcard match score for provided arguments. + * + * @param array $arguments + * + * @return false|int False OR integer score (higher - better) + */ + public function scoreArguments(array $arguments) + { + if (0 == count($arguments) && 0 == count($this->tokens)) { + return 1; + } + + $arguments = array_values($arguments); + $totalScore = 0; + foreach ($this->tokens as $i => $token) { + $argument = isset($arguments[$i]) ? $arguments[$i] : null; + if (1 >= $score = $token->scoreArgument($argument)) { + return false; + } + + $totalScore += $score; + + if (true === $token->isLast()) { + return $totalScore; + } + } + + if (count($arguments) > count($this->tokens)) { + return false; + } + + return $totalScore; + } + + /** + * Returns string representation for wildcard. + * + * @return string + */ + public function __toString() + { + if (null === $this->string) { + $this->string = implode(', ', array_map(function ($token) { + return (string) $token; + }, $this->tokens)); + } + + return $this->string; + } + + /** + * @return array + */ + public function getTokens() + { + return $this->tokens; + } +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/AnyValueToken.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/AnyValueToken.php new file mode 100644 index 00000000..50988112 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/AnyValueToken.php @@ -0,0 +1,52 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Argument\Token; + +/** + * Any single value token. + * + * @author Konstantin Kudryashov + */ +class AnyValueToken implements TokenInterface +{ + /** + * Always scores 3 for any argument. + * + * @param $argument + * + * @return int + */ + public function scoreArgument($argument) + { + return 3; + } + + /** + * Returns false. + * + * @return bool + */ + public function isLast() + { + return false; + } + + /** + * Returns string representation for token. + * + * @return string + */ + public function __toString() + { + return '*'; + } +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/AnyValuesToken.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/AnyValuesToken.php new file mode 100644 index 00000000..f76b17bc --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/AnyValuesToken.php @@ -0,0 +1,52 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Argument\Token; + +/** + * Any values token. + * + * @author Konstantin Kudryashov + */ +class AnyValuesToken implements TokenInterface +{ + /** + * Always scores 2 for any argument. + * + * @param $argument + * + * @return int + */ + public function scoreArgument($argument) + { + return 2; + } + + /** + * Returns true to stop wildcard from processing other tokens. + * + * @return bool + */ + public function isLast() + { + return true; + } + + /** + * Returns string representation for token. + * + * @return string + */ + public function __toString() + { + return '* [, ...]'; + } +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ApproximateValueToken.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ApproximateValueToken.php new file mode 100644 index 00000000..d4918b1a --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ApproximateValueToken.php @@ -0,0 +1,55 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Argument\Token; + +/** + * Approximate value token + * + * @author Daniel Leech + */ +class ApproximateValueToken implements TokenInterface +{ + private $value; + private $precision; + + public function __construct($value, $precision = 0) + { + $this->value = $value; + $this->precision = $precision; + } + + /** + * {@inheritdoc} + */ + public function scoreArgument($argument) + { + return round($argument, $this->precision) === round($this->value, $this->precision) ? 10 : false; + } + + /** + * {@inheritdoc} + */ + public function isLast() + { + return false; + } + + /** + * Returns string representation for token. + * + * @return string + */ + public function __toString() + { + return sprintf('≅%s', round($this->value, $this->precision)); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ArrayCountToken.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ArrayCountToken.php new file mode 100644 index 00000000..96b4befd --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ArrayCountToken.php @@ -0,0 +1,86 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Argument\Token; + +/** + * Array elements count token. + * + * @author Boris Mikhaylov + */ + +class ArrayCountToken implements TokenInterface +{ + private $count; + + /** + * @param integer $value + */ + public function __construct($value) + { + $this->count = $value; + } + + /** + * Scores 6 when argument has preset number of elements. + * + * @param $argument + * + * @return bool|int + */ + public function scoreArgument($argument) + { + return $this->isCountable($argument) && $this->hasProperCount($argument) ? 6 : false; + } + + /** + * Returns false. + * + * @return boolean + */ + public function isLast() + { + return false; + } + + /** + * Returns string representation for token. + * + * @return string + */ + public function __toString() + { + return sprintf('count(%s)', $this->count); + } + + /** + * Returns true if object is either array or instance of \Countable + * + * @param $argument + * @return bool + */ + private function isCountable($argument) + { + return (is_array($argument) || $argument instanceof \Countable); + } + + /** + * Returns true if $argument has expected number of elements + * + * @param array|\Countable $argument + * + * @return bool + */ + private function hasProperCount($argument) + { + return $this->count === count($argument); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ArrayEntryToken.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ArrayEntryToken.php new file mode 100644 index 00000000..0305fc72 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ArrayEntryToken.php @@ -0,0 +1,143 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Argument\Token; + +use Prophecy\Exception\InvalidArgumentException; + +/** + * Array entry token. + * + * @author Boris Mikhaylov + */ +class ArrayEntryToken implements TokenInterface +{ + /** @var \Prophecy\Argument\Token\TokenInterface */ + private $key; + /** @var \Prophecy\Argument\Token\TokenInterface */ + private $value; + + /** + * @param mixed $key exact value or token + * @param mixed $value exact value or token + */ + public function __construct($key, $value) + { + $this->key = $this->wrapIntoExactValueToken($key); + $this->value = $this->wrapIntoExactValueToken($value); + } + + /** + * Scores half of combined scores from key and value tokens for same entry. Capped at 8. + * If argument implements \ArrayAccess without \Traversable, then key token is restricted to ExactValueToken. + * + * @param array|\ArrayAccess|\Traversable $argument + * + * @throws \Prophecy\Exception\InvalidArgumentException + * @return bool|int + */ + public function scoreArgument($argument) + { + if ($argument instanceof \Traversable) { + $argument = iterator_to_array($argument); + } + + if ($argument instanceof \ArrayAccess) { + $argument = $this->convertArrayAccessToEntry($argument); + } + + if (!is_array($argument) || empty($argument)) { + return false; + } + + $keyScores = array_map(array($this->key,'scoreArgument'), array_keys($argument)); + $valueScores = array_map(array($this->value,'scoreArgument'), $argument); + $scoreEntry = function ($value, $key) { + return $value && $key ? min(8, ($key + $value) / 2) : false; + }; + + return max(array_map($scoreEntry, $valueScores, $keyScores)); + } + + /** + * Returns false. + * + * @return boolean + */ + public function isLast() + { + return false; + } + + /** + * Returns string representation for token. + * + * @return string + */ + public function __toString() + { + return sprintf('[..., %s => %s, ...]', $this->key, $this->value); + } + + /** + * Returns key + * + * @return TokenInterface + */ + public function getKey() + { + return $this->key; + } + + /** + * Returns value + * + * @return TokenInterface + */ + public function getValue() + { + return $this->value; + } + + /** + * Wraps non token $value into ExactValueToken + * + * @param $value + * @return TokenInterface + */ + private function wrapIntoExactValueToken($value) + { + return $value instanceof TokenInterface ? $value : new ExactValueToken($value); + } + + /** + * Converts instance of \ArrayAccess to key => value array entry + * + * @param \ArrayAccess $object + * + * @return array|null + * @throws \Prophecy\Exception\InvalidArgumentException + */ + private function convertArrayAccessToEntry(\ArrayAccess $object) + { + if (!$this->key instanceof ExactValueToken) { + throw new InvalidArgumentException(sprintf( + 'You can only use exact value tokens to match key of ArrayAccess object'.PHP_EOL. + 'But you used `%s`.', + $this->key + )); + } + + $key = $this->key->getValue(); + + return $object->offsetExists($key) ? array($key => $object[$key]) : array(); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ArrayEveryEntryToken.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ArrayEveryEntryToken.php new file mode 100644 index 00000000..5d41fa48 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ArrayEveryEntryToken.php @@ -0,0 +1,82 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Argument\Token; + +/** + * Array every entry token. + * + * @author Adrien Brault + */ +class ArrayEveryEntryToken implements TokenInterface +{ + /** + * @var TokenInterface + */ + private $value; + + /** + * @param mixed $value exact value or token + */ + public function __construct($value) + { + if (!$value instanceof TokenInterface) { + $value = new ExactValueToken($value); + } + + $this->value = $value; + } + + /** + * {@inheritdoc} + */ + public function scoreArgument($argument) + { + if (!$argument instanceof \Traversable && !is_array($argument)) { + return false; + } + + $scores = array(); + foreach ($argument as $key => $argumentEntry) { + $scores[] = $this->value->scoreArgument($argumentEntry); + } + + if (empty($scores) || in_array(false, $scores, true)) { + return false; + } + + return array_sum($scores) / count($scores); + } + + /** + * {@inheritdoc} + */ + public function isLast() + { + return false; + } + + /** + * {@inheritdoc} + */ + public function __toString() + { + return sprintf('[%s, ..., %s]', $this->value, $this->value); + } + + /** + * @return TokenInterface + */ + public function getValue() + { + return $this->value; + } +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/CallbackToken.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/CallbackToken.php new file mode 100644 index 00000000..f45ba20b --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/CallbackToken.php @@ -0,0 +1,75 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Argument\Token; + +use Prophecy\Exception\InvalidArgumentException; + +/** + * Callback-verified token. + * + * @author Konstantin Kudryashov + */ +class CallbackToken implements TokenInterface +{ + private $callback; + + /** + * Initializes token. + * + * @param callable $callback + * + * @throws \Prophecy\Exception\InvalidArgumentException + */ + public function __construct($callback) + { + if (!is_callable($callback)) { + throw new InvalidArgumentException(sprintf( + 'Callable expected as an argument to CallbackToken, but got %s.', + gettype($callback) + )); + } + + $this->callback = $callback; + } + + /** + * Scores 7 if callback returns true, false otherwise. + * + * @param $argument + * + * @return bool|int + */ + public function scoreArgument($argument) + { + return call_user_func($this->callback, $argument) ? 7 : false; + } + + /** + * Returns false. + * + * @return bool + */ + public function isLast() + { + return false; + } + + /** + * Returns string representation for token. + * + * @return string + */ + public function __toString() + { + return 'callback()'; + } +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ExactValueToken.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ExactValueToken.php new file mode 100644 index 00000000..aa960f3f --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ExactValueToken.php @@ -0,0 +1,116 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Argument\Token; + +use SebastianBergmann\Comparator\ComparisonFailure; +use Prophecy\Comparator\Factory as ComparatorFactory; +use Prophecy\Util\StringUtil; + +/** + * Exact value token. + * + * @author Konstantin Kudryashov + */ +class ExactValueToken implements TokenInterface +{ + private $value; + private $string; + private $util; + private $comparatorFactory; + + /** + * Initializes token. + * + * @param mixed $value + * @param StringUtil $util + * @param ComparatorFactory $comparatorFactory + */ + public function __construct($value, StringUtil $util = null, ComparatorFactory $comparatorFactory = null) + { + $this->value = $value; + $this->util = $util ?: new StringUtil(); + + $this->comparatorFactory = $comparatorFactory ?: ComparatorFactory::getInstance(); + } + + /** + * Scores 10 if argument matches preset value. + * + * @param $argument + * + * @return bool|int + */ + public function scoreArgument($argument) + { + if (is_object($argument) && is_object($this->value)) { + $comparator = $this->comparatorFactory->getComparatorFor( + $argument, $this->value + ); + + try { + $comparator->assertEquals($argument, $this->value); + return 10; + } catch (ComparisonFailure $failure) {} + } + + // If either one is an object it should be castable to a string + if (is_object($argument) xor is_object($this->value)) { + if (is_object($argument) && !method_exists($argument, '__toString')) { + return false; + } + + if (is_object($this->value) && !method_exists($this->value, '__toString')) { + return false; + } + } elseif (is_numeric($argument) && is_numeric($this->value)) { + // noop + } elseif (gettype($argument) !== gettype($this->value)) { + return false; + } + + return $argument == $this->value ? 10 : false; + } + + /** + * Returns preset value against which token checks arguments. + * + * @return mixed + */ + public function getValue() + { + return $this->value; + } + + /** + * Returns false. + * + * @return bool + */ + public function isLast() + { + return false; + } + + /** + * Returns string representation for token. + * + * @return string + */ + public function __toString() + { + if (null === $this->string) { + $this->string = sprintf('exact(%s)', $this->util->stringify($this->value)); + } + + return $this->string; + } +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/IdenticalValueToken.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/IdenticalValueToken.php new file mode 100644 index 00000000..0b6d23ab --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/IdenticalValueToken.php @@ -0,0 +1,74 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Argument\Token; + +use Prophecy\Util\StringUtil; + +/** + * Identical value token. + * + * @author Florian Voutzinos + */ +class IdenticalValueToken implements TokenInterface +{ + private $value; + private $string; + private $util; + + /** + * Initializes token. + * + * @param mixed $value + * @param StringUtil $util + */ + public function __construct($value, StringUtil $util = null) + { + $this->value = $value; + $this->util = $util ?: new StringUtil(); + } + + /** + * Scores 11 if argument matches preset value. + * + * @param $argument + * + * @return bool|int + */ + public function scoreArgument($argument) + { + return $argument === $this->value ? 11 : false; + } + + /** + * Returns false. + * + * @return bool + */ + public function isLast() + { + return false; + } + + /** + * Returns string representation for token. + * + * @return string + */ + public function __toString() + { + if (null === $this->string) { + $this->string = sprintf('identical(%s)', $this->util->stringify($this->value)); + } + + return $this->string; + } +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/LogicalAndToken.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/LogicalAndToken.php new file mode 100644 index 00000000..4ee1b25e --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/LogicalAndToken.php @@ -0,0 +1,80 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Argument\Token; + +/** + * Logical AND token. + * + * @author Boris Mikhaylov + */ +class LogicalAndToken implements TokenInterface +{ + private $tokens = array(); + + /** + * @param array $arguments exact values or tokens + */ + public function __construct(array $arguments) + { + foreach ($arguments as $argument) { + if (!$argument instanceof TokenInterface) { + $argument = new ExactValueToken($argument); + } + $this->tokens[] = $argument; + } + } + + /** + * Scores maximum score from scores returned by tokens for this argument if all of them score. + * + * @param $argument + * + * @return bool|int + */ + public function scoreArgument($argument) + { + if (0 === count($this->tokens)) { + return false; + } + + $maxScore = 0; + foreach ($this->tokens as $token) { + $score = $token->scoreArgument($argument); + if (false === $score) { + return false; + } + $maxScore = max($score, $maxScore); + } + + return $maxScore; + } + + /** + * Returns false. + * + * @return boolean + */ + public function isLast() + { + return false; + } + + /** + * Returns string representation for token. + * + * @return string + */ + public function __toString() + { + return sprintf('bool(%s)', implode(' AND ', $this->tokens)); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/LogicalNotToken.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/LogicalNotToken.php new file mode 100644 index 00000000..623efa57 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/LogicalNotToken.php @@ -0,0 +1,73 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Argument\Token; + +/** + * Logical NOT token. + * + * @author Boris Mikhaylov + */ +class LogicalNotToken implements TokenInterface +{ + /** @var \Prophecy\Argument\Token\TokenInterface */ + private $token; + + /** + * @param mixed $value exact value or token + */ + public function __construct($value) + { + $this->token = $value instanceof TokenInterface? $value : new ExactValueToken($value); + } + + /** + * Scores 4 when preset token does not match the argument. + * + * @param $argument + * + * @return bool|int + */ + public function scoreArgument($argument) + { + return false === $this->token->scoreArgument($argument) ? 4 : false; + } + + /** + * Returns true if preset token is last. + * + * @return bool|int + */ + public function isLast() + { + return $this->token->isLast(); + } + + /** + * Returns originating token. + * + * @return TokenInterface + */ + public function getOriginatingToken() + { + return $this->token; + } + + /** + * Returns string representation for token. + * + * @return string + */ + public function __toString() + { + return sprintf('not(%s)', $this->token); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ObjectStateToken.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ObjectStateToken.php new file mode 100644 index 00000000..8d93bfd6 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ObjectStateToken.php @@ -0,0 +1,104 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Argument\Token; + +use SebastianBergmann\Comparator\ComparisonFailure; +use Prophecy\Comparator\Factory as ComparatorFactory; +use Prophecy\Util\StringUtil; + +/** + * Object state-checker token. + * + * @author Konstantin Kudryashov + */ +class ObjectStateToken implements TokenInterface +{ + private $name; + private $value; + private $util; + private $comparatorFactory; + + /** + * Initializes token. + * + * @param string $methodName + * @param mixed $value Expected return value + * @param null|StringUtil $util + * @param ComparatorFactory $comparatorFactory + */ + public function __construct( + $methodName, + $value, + StringUtil $util = null, + ComparatorFactory $comparatorFactory = null + ) { + $this->name = $methodName; + $this->value = $value; + $this->util = $util ?: new StringUtil; + + $this->comparatorFactory = $comparatorFactory ?: ComparatorFactory::getInstance(); + } + + /** + * Scores 8 if argument is an object, which method returns expected value. + * + * @param mixed $argument + * + * @return bool|int + */ + public function scoreArgument($argument) + { + if (is_object($argument) && method_exists($argument, $this->name)) { + $actual = call_user_func(array($argument, $this->name)); + + $comparator = $this->comparatorFactory->getComparatorFor( + $actual, $this->value + ); + + try { + $comparator->assertEquals($actual, $this->value); + return 8; + } catch (ComparisonFailure $failure) { + return false; + } + } + + if (is_object($argument) && property_exists($argument, $this->name)) { + return $argument->{$this->name} === $this->value ? 8 : false; + } + + return false; + } + + /** + * Returns false. + * + * @return bool + */ + public function isLast() + { + return false; + } + + /** + * Returns string representation for token. + * + * @return string + */ + public function __toString() + { + return sprintf('state(%s(), %s)', + $this->name, + $this->util->stringify($this->value) + ); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/StringContainsToken.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/StringContainsToken.php new file mode 100644 index 00000000..24ff8c2e --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/StringContainsToken.php @@ -0,0 +1,67 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Argument\Token; + +/** + * String contains token. + * + * @author Peter Mitchell + */ +class StringContainsToken implements TokenInterface +{ + private $value; + + /** + * Initializes token. + * + * @param string $value + */ + public function __construct($value) + { + $this->value = $value; + } + + public function scoreArgument($argument) + { + return strpos($argument, $this->value) !== false ? 6 : false; + } + + /** + * Returns preset value against which token checks arguments. + * + * @return mixed + */ + public function getValue() + { + return $this->value; + } + + /** + * Returns false. + * + * @return bool + */ + public function isLast() + { + return false; + } + + /** + * Returns string representation for token. + * + * @return string + */ + public function __toString() + { + return sprintf('contains("%s")', $this->value); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/TokenInterface.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/TokenInterface.php new file mode 100644 index 00000000..625d3bad --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/TokenInterface.php @@ -0,0 +1,43 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Argument\Token; + +/** + * Argument token interface. + * + * @author Konstantin Kudryashov + */ +interface TokenInterface +{ + /** + * Calculates token match score for provided argument. + * + * @param $argument + * + * @return bool|int + */ + public function scoreArgument($argument); + + /** + * Returns true if this token prevents check of other tokens (is last one). + * + * @return bool|int + */ + public function isLast(); + + /** + * Returns string representation for token. + * + * @return string + */ + public function __toString(); +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/TypeToken.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/TypeToken.php new file mode 100644 index 00000000..cb65132c --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/TypeToken.php @@ -0,0 +1,76 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Argument\Token; + +use Prophecy\Exception\InvalidArgumentException; + +/** + * Value type token. + * + * @author Konstantin Kudryashov + */ +class TypeToken implements TokenInterface +{ + private $type; + + /** + * @param string $type + */ + public function __construct($type) + { + $checker = "is_{$type}"; + if (!function_exists($checker) && !interface_exists($type) && !class_exists($type)) { + throw new InvalidArgumentException(sprintf( + 'Type or class name expected as an argument to TypeToken, but got %s.', $type + )); + } + + $this->type = $type; + } + + /** + * Scores 5 if argument has the same type this token was constructed with. + * + * @param $argument + * + * @return bool|int + */ + public function scoreArgument($argument) + { + $checker = "is_{$this->type}"; + if (function_exists($checker)) { + return call_user_func($checker, $argument) ? 5 : false; + } + + return $argument instanceof $this->type ? 5 : false; + } + + /** + * Returns false. + * + * @return bool + */ + public function isLast() + { + return false; + } + + /** + * Returns string representation for token. + * + * @return string + */ + public function __toString() + { + return sprintf('type(%s)', $this->type); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Call/Call.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Call/Call.php new file mode 100644 index 00000000..2f3fbadb --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Call/Call.php @@ -0,0 +1,127 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Call; + +use Exception; + +/** + * Call object. + * + * @author Konstantin Kudryashov + */ +class Call +{ + private $methodName; + private $arguments; + private $returnValue; + private $exception; + private $file; + private $line; + + /** + * Initializes call. + * + * @param string $methodName + * @param array $arguments + * @param mixed $returnValue + * @param Exception $exception + * @param null|string $file + * @param null|int $line + */ + public function __construct($methodName, array $arguments, $returnValue, + Exception $exception = null, $file, $line) + { + $this->methodName = $methodName; + $this->arguments = $arguments; + $this->returnValue = $returnValue; + $this->exception = $exception; + + if ($file) { + $this->file = $file; + $this->line = intval($line); + } + } + + /** + * Returns called method name. + * + * @return string + */ + public function getMethodName() + { + return $this->methodName; + } + + /** + * Returns called method arguments. + * + * @return array + */ + public function getArguments() + { + return $this->arguments; + } + + /** + * Returns called method return value. + * + * @return null|mixed + */ + public function getReturnValue() + { + return $this->returnValue; + } + + /** + * Returns exception that call thrown. + * + * @return null|Exception + */ + public function getException() + { + return $this->exception; + } + + /** + * Returns callee filename. + * + * @return string + */ + public function getFile() + { + return $this->file; + } + + /** + * Returns callee line number. + * + * @return int + */ + public function getLine() + { + return $this->line; + } + + /** + * Returns short notation for callee place. + * + * @return string + */ + public function getCallPlace() + { + if (null === $this->file) { + return 'unknown'; + } + + return sprintf('%s:%d', $this->file, $this->line); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Call/CallCenter.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Call/CallCenter.php new file mode 100644 index 00000000..a1f8c618 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Call/CallCenter.php @@ -0,0 +1,162 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Call; + +use Prophecy\Prophecy\MethodProphecy; +use Prophecy\Prophecy\ObjectProphecy; +use Prophecy\Argument\ArgumentsWildcard; +use Prophecy\Util\StringUtil; +use Prophecy\Exception\Call\UnexpectedCallException; + +/** + * Calls receiver & manager. + * + * @author Konstantin Kudryashov + */ +class CallCenter +{ + private $util; + + /** + * @var Call[] + */ + private $recordedCalls = array(); + + /** + * Initializes call center. + * + * @param StringUtil $util + */ + public function __construct(StringUtil $util = null) + { + $this->util = $util ?: new StringUtil; + } + + /** + * Makes and records specific method call for object prophecy. + * + * @param ObjectProphecy $prophecy + * @param string $methodName + * @param array $arguments + * + * @return mixed Returns null if no promise for prophecy found or promise return value. + * + * @throws \Prophecy\Exception\Call\UnexpectedCallException If no appropriate method prophecy found + */ + public function makeCall(ObjectProphecy $prophecy, $methodName, array $arguments) + { + // For efficiency exclude 'args' from the generated backtrace + if (PHP_VERSION_ID >= 50400) { + // Limit backtrace to last 3 calls as we don't use the rest + // Limit argument was introduced in PHP 5.4.0 + $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 3); + } elseif (defined('DEBUG_BACKTRACE_IGNORE_ARGS')) { + // DEBUG_BACKTRACE_IGNORE_ARGS was introduced in PHP 5.3.6 + $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); + } else { + $backtrace = debug_backtrace(); + } + + $file = $line = null; + if (isset($backtrace[2]) && isset($backtrace[2]['file'])) { + $file = $backtrace[2]['file']; + $line = $backtrace[2]['line']; + } + + // If no method prophecies defined, then it's a dummy, so we'll just return null + if ('__destruct' === $methodName || 0 == count($prophecy->getMethodProphecies())) { + $this->recordedCalls[] = new Call($methodName, $arguments, null, null, $file, $line); + + return null; + } + + // There are method prophecies, so it's a fake/stub. Searching prophecy for this call + $matches = array(); + foreach ($prophecy->getMethodProphecies($methodName) as $methodProphecy) { + if (0 < $score = $methodProphecy->getArgumentsWildcard()->scoreArguments($arguments)) { + $matches[] = array($score, $methodProphecy); + } + } + + // If fake/stub doesn't have method prophecy for this call - throw exception + if (!count($matches)) { + throw $this->createUnexpectedCallException($prophecy, $methodName, $arguments); + } + + // Sort matches by their score value + @usort($matches, function ($match1, $match2) { return $match2[0] - $match1[0]; }); + + // If Highest rated method prophecy has a promise - execute it or return null instead + $returnValue = null; + $exception = null; + if ($promise = $matches[0][1]->getPromise()) { + try { + $returnValue = $promise->execute($arguments, $prophecy, $matches[0][1]); + } catch (\Exception $e) { + $exception = $e; + } + } + + $this->recordedCalls[] = new Call( + $methodName, $arguments, $returnValue, $exception, $file, $line + ); + + if (null !== $exception) { + throw $exception; + } + + return $returnValue; + } + + /** + * Searches for calls by method name & arguments wildcard. + * + * @param string $methodName + * @param ArgumentsWildcard $wildcard + * + * @return Call[] + */ + public function findCalls($methodName, ArgumentsWildcard $wildcard) + { + return array_values( + array_filter($this->recordedCalls, function (Call $call) use ($methodName, $wildcard) { + return $methodName === $call->getMethodName() + && 0 < $wildcard->scoreArguments($call->getArguments()) + ; + }) + ); + } + + private function createUnexpectedCallException(ObjectProphecy $prophecy, $methodName, + array $arguments) + { + $classname = get_class($prophecy->reveal()); + $argstring = implode(', ', array_map(array($this->util, 'stringify'), $arguments)); + $expected = implode("\n", array_map(function (MethodProphecy $methodProphecy) { + return sprintf(' - %s(%s)', + $methodProphecy->getMethodName(), + $methodProphecy->getArgumentsWildcard() + ); + }, call_user_func_array('array_merge', $prophecy->getMethodProphecies()))); + + return new UnexpectedCallException( + sprintf( + "Method call:\n". + " - %s(%s)\n". + "on %s was not expected, expected calls were:\n%s", + + $methodName, $argstring, $classname, $expected + ), + $prophecy, $methodName, $arguments + ); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Comparator/ClosureComparator.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Comparator/ClosureComparator.php new file mode 100644 index 00000000..874e474c --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Comparator/ClosureComparator.php @@ -0,0 +1,42 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Comparator; + +use SebastianBergmann\Comparator\Comparator; +use SebastianBergmann\Comparator\ComparisonFailure; + +/** + * Closure comparator. + * + * @author Konstantin Kudryashov + */ +final class ClosureComparator extends Comparator +{ + public function accepts($expected, $actual) + { + return is_object($expected) && $expected instanceof \Closure + && is_object($actual) && $actual instanceof \Closure; + } + + public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false) + { + throw new ComparisonFailure( + $expected, + $actual, + // we don't need a diff + '', + '', + false, + 'all closures are born different' + ); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Comparator/Factory.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Comparator/Factory.php new file mode 100644 index 00000000..2070db14 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Comparator/Factory.php @@ -0,0 +1,47 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Comparator; + +use SebastianBergmann\Comparator\Factory as BaseFactory; + +/** + * Prophecy comparator factory. + * + * @author Konstantin Kudryashov + */ +final class Factory extends BaseFactory +{ + /** + * @var Factory + */ + private static $instance; + + public function __construct() + { + parent::__construct(); + + $this->register(new ClosureComparator()); + $this->register(new ProphecyComparator()); + } + + /** + * @return Factory + */ + public static function getInstance() + { + if (self::$instance === null) { + self::$instance = new Factory; + } + + return self::$instance; + } +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Comparator/ProphecyComparator.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Comparator/ProphecyComparator.php new file mode 100644 index 00000000..298a8e35 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Comparator/ProphecyComparator.php @@ -0,0 +1,28 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Comparator; + +use Prophecy\Prophecy\ProphecyInterface; +use SebastianBergmann\Comparator\ObjectComparator; + +class ProphecyComparator extends ObjectComparator +{ + public function accepts($expected, $actual) + { + return is_object($expected) && is_object($actual) && $actual instanceof ProphecyInterface; + } + + public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false, array &$processed = array()) + { + parent::assertEquals($expected, $actual->reveal(), $delta, $canonicalize, $ignoreCase, $processed); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/CachedDoubler.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/CachedDoubler.php new file mode 100644 index 00000000..d6b6b1a9 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/CachedDoubler.php @@ -0,0 +1,68 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Doubler; + +use ReflectionClass; + +/** + * Cached class doubler. + * Prevents mirroring/creation of the same structure twice. + * + * @author Konstantin Kudryashov + */ +class CachedDoubler extends Doubler +{ + private $classes = array(); + + /** + * {@inheritdoc} + */ + public function registerClassPatch(ClassPatch\ClassPatchInterface $patch) + { + $this->classes[] = array(); + + parent::registerClassPatch($patch); + } + + /** + * {@inheritdoc} + */ + protected function createDoubleClass(ReflectionClass $class = null, array $interfaces) + { + $classId = $this->generateClassId($class, $interfaces); + if (isset($this->classes[$classId])) { + return $this->classes[$classId]; + } + + return $this->classes[$classId] = parent::createDoubleClass($class, $interfaces); + } + + /** + * @param ReflectionClass $class + * @param ReflectionClass[] $interfaces + * + * @return string + */ + private function generateClassId(ReflectionClass $class = null, array $interfaces) + { + $parts = array(); + if (null !== $class) { + $parts[] = $class->getName(); + } + foreach ($interfaces as $interface) { + $parts[] = $interface->getName(); + } + sort($parts); + + return md5(implode('', $parts)); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ClassPatchInterface.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ClassPatchInterface.php new file mode 100644 index 00000000..d6d19685 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ClassPatchInterface.php @@ -0,0 +1,48 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Doubler\ClassPatch; + +use Prophecy\Doubler\Generator\Node\ClassNode; + +/** + * Class patch interface. + * Class patches extend doubles functionality or help + * Prophecy to avoid some internal PHP bugs. + * + * @author Konstantin Kudryashov + */ +interface ClassPatchInterface +{ + /** + * Checks if patch supports specific class node. + * + * @param ClassNode $node + * + * @return bool + */ + public function supports(ClassNode $node); + + /** + * Applies patch to the specific class node. + * + * @param ClassNode $node + * @return void + */ + public function apply(ClassNode $node); + + /** + * Returns patch priority, which determines when patch will be applied. + * + * @return int Priority number (higher - earlier) + */ + public function getPriority(); +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/DisableConstructorPatch.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/DisableConstructorPatch.php new file mode 100644 index 00000000..61998fc4 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/DisableConstructorPatch.php @@ -0,0 +1,72 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Doubler\ClassPatch; + +use Prophecy\Doubler\Generator\Node\ClassNode; +use Prophecy\Doubler\Generator\Node\MethodNode; + +/** + * Disable constructor. + * Makes all constructor arguments optional. + * + * @author Konstantin Kudryashov + */ +class DisableConstructorPatch implements ClassPatchInterface +{ + /** + * Checks if class has `__construct` method. + * + * @param ClassNode $node + * + * @return bool + */ + public function supports(ClassNode $node) + { + return true; + } + + /** + * Makes all class constructor arguments optional. + * + * @param ClassNode $node + */ + public function apply(ClassNode $node) + { + if (!$node->hasMethod('__construct')) { + $node->addMethod(new MethodNode('__construct', '')); + + return; + } + + $constructor = $node->getMethod('__construct'); + foreach ($constructor->getArguments() as $argument) { + $argument->setDefault(null); + } + + $constructor->setCode(<< + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Doubler\ClassPatch; + +use Prophecy\Doubler\Generator\Node\ClassNode; + +/** + * Exception patch for HHVM to remove the stubs from special methods + * + * @author Christophe Coevoet + */ +class HhvmExceptionPatch implements ClassPatchInterface +{ + /** + * Supports exceptions on HHVM. + * + * @param ClassNode $node + * + * @return bool + */ + public function supports(ClassNode $node) + { + if (!defined('HHVM_VERSION')) { + return false; + } + + return 'Exception' === $node->getParentClass() || is_subclass_of($node->getParentClass(), 'Exception'); + } + + /** + * Removes special exception static methods from the doubled methods. + * + * @param ClassNode $node + * + * @return void + */ + public function apply(ClassNode $node) + { + if ($node->hasMethod('setTraceOptions')) { + $node->getMethod('setTraceOptions')->useParentCode(); + } + if ($node->hasMethod('getTraceOptions')) { + $node->getMethod('getTraceOptions')->useParentCode(); + } + } + + /** + * {@inheritdoc} + */ + public function getPriority() + { + return -50; + } +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/KeywordPatch.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/KeywordPatch.php new file mode 100644 index 00000000..b0d9793a --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/KeywordPatch.php @@ -0,0 +1,135 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Doubler\ClassPatch; + +use Prophecy\Doubler\Generator\Node\ClassNode; + +/** + * Remove method functionality from the double which will clash with php keywords. + * + * @author Milan Magudia + */ +class KeywordPatch implements ClassPatchInterface +{ + /** + * Support any class + * + * @param ClassNode $node + * + * @return boolean + */ + public function supports(ClassNode $node) + { + return true; + } + + /** + * Remove methods that clash with php keywords + * + * @param ClassNode $node + */ + public function apply(ClassNode $node) + { + $methodNames = array_keys($node->getMethods()); + $methodsToRemove = array_intersect($methodNames, $this->getKeywords()); + foreach ($methodsToRemove as $methodName) { + $node->removeMethod($methodName); + } + } + + /** + * Returns patch priority, which determines when patch will be applied. + * + * @return int Priority number (higher - earlier) + */ + public function getPriority() { + return 49; + } + + /** + * Returns array of php keywords. + * + * @return array + */ + private function getKeywords() { + + return array( + '__halt_compiler', + 'abstract', + 'and', + 'array', + 'as', + 'break', + 'callable', + 'case', + 'catch', + 'class', + 'clone', + 'const', + 'continue', + 'declare', + 'default', + 'die', + 'do', + 'echo', + 'else', + 'elseif', + 'empty', + 'enddeclare', + 'endfor', + 'endforeach', + 'endif', + 'endswitch', + 'endwhile', + 'eval', + 'exit', + 'extends', + 'final', + 'finally', + 'for', + 'foreach', + 'function', + 'global', + 'goto', + 'if', + 'implements', + 'include', + 'include_once', + 'instanceof', + 'insteadof', + 'interface', + 'isset', + 'list', + 'namespace', + 'new', + 'or', + 'print', + 'private', + 'protected', + 'public', + 'require', + 'require_once', + 'return', + 'static', + 'switch', + 'throw', + 'trait', + 'try', + 'unset', + 'use', + 'var', + 'while', + 'xor', + 'yield', + ); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/MagicCallPatch.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/MagicCallPatch.php new file mode 100644 index 00000000..23891c09 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/MagicCallPatch.php @@ -0,0 +1,85 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Doubler\ClassPatch; + +use Prophecy\Doubler\Generator\Node\ClassNode; +use Prophecy\Doubler\Generator\Node\MethodNode; +use Prophecy\PhpDocumentor\ClassAndInterfaceTagRetriever; +use Prophecy\PhpDocumentor\MethodTagRetrieverInterface; + +/** + * Discover Magical API using "@method" PHPDoc format. + * + * @author Thomas Tourlourat + * @author Kévin Dunglas + * @author Théo FIDRY + */ +class MagicCallPatch implements ClassPatchInterface +{ + private $tagRetriever; + + public function __construct(MethodTagRetrieverInterface $tagRetriever = null) + { + $this->tagRetriever = null === $tagRetriever ? new ClassAndInterfaceTagRetriever() : $tagRetriever; + } + + /** + * Support any class + * + * @param ClassNode $node + * + * @return boolean + */ + public function supports(ClassNode $node) + { + return true; + } + + /** + * Discover Magical API + * + * @param ClassNode $node + */ + public function apply(ClassNode $node) + { + $parentClass = $node->getParentClass(); + $reflectionClass = new \ReflectionClass($parentClass); + + $tagList = $this->tagRetriever->getTagList($reflectionClass); + + foreach($tagList as $tag) { + $methodName = $tag->getMethodName(); + + if (empty($methodName)) { + continue; + } + + if (!$reflectionClass->hasMethod($methodName)) { + $methodNode = new MethodNode($methodName); + $methodNode->setStatic($tag->isStatic()); + + $node->addMethod($methodNode); + } + } + } + + /** + * Returns patch priority, which determines when patch will be applied. + * + * @return integer Priority number (higher - earlier) + */ + public function getPriority() + { + return 50; + } +} + diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ProphecySubjectPatch.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ProphecySubjectPatch.php new file mode 100644 index 00000000..ab0bb7c7 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ProphecySubjectPatch.php @@ -0,0 +1,98 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Doubler\ClassPatch; + +use Prophecy\Doubler\Generator\Node\ClassNode; +use Prophecy\Doubler\Generator\Node\MethodNode; +use Prophecy\Doubler\Generator\Node\ArgumentNode; + +/** + * Add Prophecy functionality to the double. + * This is a core class patch for Prophecy. + * + * @author Konstantin Kudryashov + */ +class ProphecySubjectPatch implements ClassPatchInterface +{ + /** + * Always returns true. + * + * @param ClassNode $node + * + * @return bool + */ + public function supports(ClassNode $node) + { + return true; + } + + /** + * Apply Prophecy functionality to class node. + * + * @param ClassNode $node + */ + public function apply(ClassNode $node) + { + $node->addInterface('Prophecy\Prophecy\ProphecySubjectInterface'); + $node->addProperty('objectProphecy', 'private'); + + foreach ($node->getMethods() as $name => $method) { + if ('__construct' === strtolower($name)) { + continue; + } + + $method->setCode( + 'return $this->getProphecy()->makeProphecyMethodCall(__FUNCTION__, func_get_args());' + ); + } + + $prophecySetter = new MethodNode('setProphecy'); + $prophecyArgument = new ArgumentNode('prophecy'); + $prophecyArgument->setTypeHint('Prophecy\Prophecy\ProphecyInterface'); + $prophecySetter->addArgument($prophecyArgument); + $prophecySetter->setCode('$this->objectProphecy = $prophecy;'); + + $prophecyGetter = new MethodNode('getProphecy'); + $prophecyGetter->setCode('return $this->objectProphecy;'); + + if ($node->hasMethod('__call')) { + $__call = $node->getMethod('__call'); + } else { + $__call = new MethodNode('__call'); + $__call->addArgument(new ArgumentNode('name')); + $__call->addArgument(new ArgumentNode('arguments')); + + $node->addMethod($__call); + } + + $__call->setCode(<<getProphecy(), func_get_arg(0) +); +PHP + ); + + $node->addMethod($prophecySetter); + $node->addMethod($prophecyGetter); + } + + /** + * Returns patch priority, which determines when patch will be applied. + * + * @return int Priority number (higher - earlier) + */ + public function getPriority() + { + return 0; + } +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ReflectionClassNewInstancePatch.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ReflectionClassNewInstancePatch.php new file mode 100644 index 00000000..9166aeef --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ReflectionClassNewInstancePatch.php @@ -0,0 +1,57 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Doubler\ClassPatch; + +use Prophecy\Doubler\Generator\Node\ClassNode; + +/** + * ReflectionClass::newInstance patch. + * Makes first argument of newInstance optional, since it works but signature is misleading + * + * @author Florian Klein + */ +class ReflectionClassNewInstancePatch implements ClassPatchInterface +{ + /** + * Supports ReflectionClass + * + * @param ClassNode $node + * + * @return bool + */ + public function supports(ClassNode $node) + { + return 'ReflectionClass' === $node->getParentClass(); + } + + /** + * Updates newInstance's first argument to make it optional + * + * @param ClassNode $node + */ + public function apply(ClassNode $node) + { + foreach ($node->getMethod('newInstance')->getArguments() as $argument) { + $argument->setDefault(null); + } + } + + /** + * Returns patch priority, which determines when patch will be applied. + * + * @return int Priority number (higher = earlier) + */ + public function getPriority() + { + return 50; + } +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/SplFileInfoPatch.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/SplFileInfoPatch.php new file mode 100644 index 00000000..eba82980 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/SplFileInfoPatch.php @@ -0,0 +1,105 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Doubler\ClassPatch; + +use Prophecy\Doubler\Generator\Node\ClassNode; +use Prophecy\Doubler\Generator\Node\MethodNode; + +/** + * SplFileInfo patch. + * Makes SplFileInfo and derivative classes usable with Prophecy. + * + * @author Konstantin Kudryashov + */ +class SplFileInfoPatch implements ClassPatchInterface +{ + /** + * Supports everything that extends SplFileInfo. + * + * @param ClassNode $node + * + * @return bool + */ + public function supports(ClassNode $node) + { + if (null === $node->getParentClass()) { + return false; + } + + return 'SplFileInfo' === $node->getParentClass() + || is_subclass_of($node->getParentClass(), 'SplFileInfo') + ; + } + + /** + * Updated constructor code to call parent one with dummy file argument. + * + * @param ClassNode $node + */ + public function apply(ClassNode $node) + { + if ($node->hasMethod('__construct')) { + $constructor = $node->getMethod('__construct'); + } else { + $constructor = new MethodNode('__construct'); + $node->addMethod($constructor); + } + + if ($this->nodeIsDirectoryIterator($node)) { + $constructor->setCode('return parent::__construct("' . __DIR__ . '");'); + + return; + } + + if ($this->nodeIsSplFileObject($node)) { + $constructor->setCode('return parent::__construct("' . __FILE__ .'");'); + + return; + } + + $constructor->useParentCode(); + } + + /** + * Returns patch priority, which determines when patch will be applied. + * + * @return int Priority number (higher - earlier) + */ + public function getPriority() + { + return 50; + } + + /** + * @param ClassNode $node + * @return boolean + */ + private function nodeIsDirectoryIterator(ClassNode $node) + { + $parent = $node->getParentClass(); + + return 'DirectoryIterator' === $parent + || is_subclass_of($parent, 'DirectoryIterator'); + } + + /** + * @param ClassNode $node + * @return boolean + */ + private function nodeIsSplFileObject(ClassNode $node) + { + $parent = $node->getParentClass(); + + return 'SplFileObject' === $parent + || is_subclass_of($parent, 'SplFileObject'); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/TraversablePatch.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/TraversablePatch.php new file mode 100644 index 00000000..eea02028 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/TraversablePatch.php @@ -0,0 +1,83 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Doubler\ClassPatch; + +use Prophecy\Doubler\Generator\Node\ClassNode; +use Prophecy\Doubler\Generator\Node\MethodNode; + +/** + * Traversable interface patch. + * Forces classes that implement interfaces, that extend Traversable to also implement Iterator. + * + * @author Konstantin Kudryashov + */ +class TraversablePatch implements ClassPatchInterface +{ + /** + * Supports nodetree, that implement Traversable, but not Iterator or IteratorAggregate. + * + * @param ClassNode $node + * + * @return bool + */ + public function supports(ClassNode $node) + { + if (in_array('Iterator', $node->getInterfaces())) { + return false; + } + if (in_array('IteratorAggregate', $node->getInterfaces())) { + return false; + } + + foreach ($node->getInterfaces() as $interface) { + if ('Traversable' !== $interface && !is_subclass_of($interface, 'Traversable')) { + continue; + } + if ('Iterator' === $interface || is_subclass_of($interface, 'Iterator')) { + continue; + } + if ('IteratorAggregate' === $interface || is_subclass_of($interface, 'IteratorAggregate')) { + continue; + } + + return true; + } + + return false; + } + + /** + * Forces class to implement Iterator interface. + * + * @param ClassNode $node + */ + public function apply(ClassNode $node) + { + $node->addInterface('Iterator'); + + $node->addMethod(new MethodNode('current')); + $node->addMethod(new MethodNode('key')); + $node->addMethod(new MethodNode('next')); + $node->addMethod(new MethodNode('rewind')); + $node->addMethod(new MethodNode('valid')); + } + + /** + * Returns patch priority, which determines when patch will be applied. + * + * @return int Priority number (higher - earlier) + */ + public function getPriority() + { + return 100; + } +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/DoubleInterface.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/DoubleInterface.php new file mode 100644 index 00000000..699be3a2 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/DoubleInterface.php @@ -0,0 +1,22 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Doubler; + +/** + * Core double interface. + * All doubled classes will implement this one. + * + * @author Konstantin Kudryashov + */ +interface DoubleInterface +{ +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/Doubler.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/Doubler.php new file mode 100644 index 00000000..a378ae27 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/Doubler.php @@ -0,0 +1,146 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Doubler; + +use Doctrine\Instantiator\Instantiator; +use Prophecy\Doubler\ClassPatch\ClassPatchInterface; +use Prophecy\Doubler\Generator\ClassMirror; +use Prophecy\Doubler\Generator\ClassCreator; +use Prophecy\Exception\InvalidArgumentException; +use ReflectionClass; + +/** + * Cached class doubler. + * Prevents mirroring/creation of the same structure twice. + * + * @author Konstantin Kudryashov + */ +class Doubler +{ + private $mirror; + private $creator; + private $namer; + + /** + * @var ClassPatchInterface[] + */ + private $patches = array(); + + /** + * @var \Doctrine\Instantiator\Instantiator + */ + private $instantiator; + + /** + * Initializes doubler. + * + * @param ClassMirror $mirror + * @param ClassCreator $creator + * @param NameGenerator $namer + */ + public function __construct(ClassMirror $mirror = null, ClassCreator $creator = null, + NameGenerator $namer = null) + { + $this->mirror = $mirror ?: new ClassMirror; + $this->creator = $creator ?: new ClassCreator; + $this->namer = $namer ?: new NameGenerator; + } + + /** + * Returns list of registered class patches. + * + * @return ClassPatchInterface[] + */ + public function getClassPatches() + { + return $this->patches; + } + + /** + * Registers new class patch. + * + * @param ClassPatchInterface $patch + */ + public function registerClassPatch(ClassPatchInterface $patch) + { + $this->patches[] = $patch; + + @usort($this->patches, function (ClassPatchInterface $patch1, ClassPatchInterface $patch2) { + return $patch2->getPriority() - $patch1->getPriority(); + }); + } + + /** + * Creates double from specific class or/and list of interfaces. + * + * @param ReflectionClass $class + * @param ReflectionClass[] $interfaces Array of ReflectionClass instances + * @param array $args Constructor arguments + * + * @return DoubleInterface + * + * @throws \Prophecy\Exception\InvalidArgumentException + */ + public function double(ReflectionClass $class = null, array $interfaces, array $args = null) + { + foreach ($interfaces as $interface) { + if (!$interface instanceof ReflectionClass) { + throw new InvalidArgumentException(sprintf( + "[ReflectionClass \$interface1 [, ReflectionClass \$interface2]] array expected as\n". + "a second argument to `Doubler::double(...)`, but got %s.", + is_object($interface) ? get_class($interface).' class' : gettype($interface) + )); + } + } + + $classname = $this->createDoubleClass($class, $interfaces); + $reflection = new ReflectionClass($classname); + + if (null !== $args) { + return $reflection->newInstanceArgs($args); + } + if ((null === $constructor = $reflection->getConstructor()) + || ($constructor->isPublic() && !$constructor->isFinal())) { + return $reflection->newInstance(); + } + + if (!$this->instantiator) { + $this->instantiator = new Instantiator(); + } + + return $this->instantiator->instantiate($classname); + } + + /** + * Creates double class and returns its FQN. + * + * @param ReflectionClass $class + * @param ReflectionClass[] $interfaces + * + * @return string + */ + protected function createDoubleClass(ReflectionClass $class = null, array $interfaces) + { + $name = $this->namer->name($class, $interfaces); + $node = $this->mirror->reflect($class, $interfaces); + + foreach ($this->patches as $patch) { + if ($patch->supports($node)) { + $patch->apply($node); + } + } + + $this->creator->create($name, $node); + + return $name; + } +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ClassCodeGenerator.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ClassCodeGenerator.php new file mode 100644 index 00000000..dc03f429 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ClassCodeGenerator.php @@ -0,0 +1,112 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Doubler\Generator; + +/** + * Class code creator. + * Generates PHP code for specific class node tree. + * + * @author Konstantin Kudryashov + */ +class ClassCodeGenerator +{ + /** + * Generates PHP code for class node. + * + * @param string $classname + * @param Node\ClassNode $class + * + * @return string + */ + public function generate($classname, Node\ClassNode $class) + { + $parts = explode('\\', $classname); + $classname = array_pop($parts); + $namespace = implode('\\', $parts); + + $code = sprintf("class %s extends \%s implements %s {\n", + $classname, $class->getParentClass(), implode(', ', + array_map(function ($interface) {return '\\'.$interface;}, $class->getInterfaces()) + ) + ); + + foreach ($class->getProperties() as $name => $visibility) { + $code .= sprintf("%s \$%s;\n", $visibility, $name); + } + $code .= "\n"; + + foreach ($class->getMethods() as $method) { + $code .= $this->generateMethod($method)."\n"; + } + $code .= "\n}"; + + return sprintf("namespace %s {\n%s\n}", $namespace, $code); + } + + private function generateMethod(Node\MethodNode $method) + { + $php = sprintf("%s %s function %s%s(%s)%s {\n", + $method->getVisibility(), + $method->isStatic() ? 'static' : '', + $method->returnsReference() ? '&':'', + $method->getName(), + implode(', ', $this->generateArguments($method->getArguments())), + version_compare(PHP_VERSION, '7.0', '>=') && $method->hasReturnType() + ? sprintf(': %s', $method->getReturnType()) + : '' + ); + $php .= $method->getCode()."\n"; + + return $php.'}'; + } + + private function generateArguments(array $arguments) + { + return array_map(function (Node\ArgumentNode $argument) { + $php = ''; + + if ($hint = $argument->getTypeHint()) { + switch ($hint) { + case 'array': + case 'callable': + $php .= $hint; + break; + + case 'string': + case 'int': + case 'float': + case 'bool': + if (version_compare(PHP_VERSION, '7.0', '>=')) { + $php .= $hint; + break; + } + // Fall-through to default case for PHP 5.x + + default: + $php .= '\\'.$hint; + } + } + + $php .= ' '.($argument->isPassedByReference() ? '&' : ''); + + $php .= $argument->isVariadic() ? '...' : ''; + + $php .= '$'.$argument->getName(); + + if ($argument->isOptional() && !$argument->isVariadic()) { + $php .= ' = '.var_export($argument->getDefault(), true); + } + + return $php; + }, $arguments); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ClassCreator.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ClassCreator.php new file mode 100644 index 00000000..882a4a4b --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ClassCreator.php @@ -0,0 +1,67 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Doubler\Generator; + +use Prophecy\Exception\Doubler\ClassCreatorException; + +/** + * Class creator. + * Creates specific class in current environment. + * + * @author Konstantin Kudryashov + */ +class ClassCreator +{ + private $generator; + + /** + * Initializes creator. + * + * @param ClassCodeGenerator $generator + */ + public function __construct(ClassCodeGenerator $generator = null) + { + $this->generator = $generator ?: new ClassCodeGenerator; + } + + /** + * Creates class. + * + * @param string $classname + * @param Node\ClassNode $class + * + * @return mixed + * + * @throws \Prophecy\Exception\Doubler\ClassCreatorException + */ + public function create($classname, Node\ClassNode $class) + { + $code = $this->generator->generate($classname, $class); + $return = eval($code); + + if (!class_exists($classname, false)) { + if (count($class->getInterfaces())) { + throw new ClassCreatorException(sprintf( + 'Could not double `%s` and implement interfaces: [%s].', + $class->getParentClass(), implode(', ', $class->getInterfaces()) + ), $class); + } + + throw new ClassCreatorException( + sprintf('Could not double `%s`.', $class->getParentClass()), + $class + ); + } + + return $return; + } +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ClassMirror.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ClassMirror.php new file mode 100644 index 00000000..acdb2c15 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ClassMirror.php @@ -0,0 +1,254 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Doubler\Generator; + +use Prophecy\Exception\InvalidArgumentException; +use Prophecy\Exception\Doubler\ClassMirrorException; +use ReflectionClass; +use ReflectionMethod; +use ReflectionParameter; + +/** + * Class mirror. + * Core doubler class. Mirrors specific class and/or interfaces into class node tree. + * + * @author Konstantin Kudryashov + */ +class ClassMirror +{ + private static $reflectableMethods = array( + '__construct', + '__destruct', + '__sleep', + '__wakeup', + '__toString', + '__call', + '__invoke' + ); + + /** + * Reflects provided arguments into class node. + * + * @param ReflectionClass $class + * @param ReflectionClass[] $interfaces + * + * @return Node\ClassNode + * + * @throws \Prophecy\Exception\InvalidArgumentException + */ + public function reflect(ReflectionClass $class = null, array $interfaces) + { + $node = new Node\ClassNode; + + if (null !== $class) { + if (true === $class->isInterface()) { + throw new InvalidArgumentException(sprintf( + "Could not reflect %s as a class, because it\n". + "is interface - use the second argument instead.", + $class->getName() + )); + } + + $this->reflectClassToNode($class, $node); + } + + foreach ($interfaces as $interface) { + if (!$interface instanceof ReflectionClass) { + throw new InvalidArgumentException(sprintf( + "[ReflectionClass \$interface1 [, ReflectionClass \$interface2]] array expected as\n". + "a second argument to `ClassMirror::reflect(...)`, but got %s.", + is_object($interface) ? get_class($interface).' class' : gettype($interface) + )); + } + if (false === $interface->isInterface()) { + throw new InvalidArgumentException(sprintf( + "Could not reflect %s as an interface, because it\n". + "is class - use the first argument instead.", + $interface->getName() + )); + } + + $this->reflectInterfaceToNode($interface, $node); + } + + $node->addInterface('Prophecy\Doubler\Generator\ReflectionInterface'); + + return $node; + } + + private function reflectClassToNode(ReflectionClass $class, Node\ClassNode $node) + { + if (true === $class->isFinal()) { + throw new ClassMirrorException(sprintf( + 'Could not reflect class %s as it is marked final.', $class->getName() + ), $class); + } + + $node->setParentClass($class->getName()); + + foreach ($class->getMethods(ReflectionMethod::IS_ABSTRACT) as $method) { + if (false === $method->isProtected()) { + continue; + } + + $this->reflectMethodToNode($method, $node); + } + + foreach ($class->getMethods(ReflectionMethod::IS_PUBLIC) as $method) { + if (0 === strpos($method->getName(), '_') + && !in_array($method->getName(), self::$reflectableMethods)) { + continue; + } + + if (true === $method->isFinal()) { + $node->addUnextendableMethod($method->getName()); + continue; + } + + $this->reflectMethodToNode($method, $node); + } + } + + private function reflectInterfaceToNode(ReflectionClass $interface, Node\ClassNode $node) + { + $node->addInterface($interface->getName()); + + foreach ($interface->getMethods() as $method) { + $this->reflectMethodToNode($method, $node); + } + } + + private function reflectMethodToNode(ReflectionMethod $method, Node\ClassNode $classNode) + { + $node = new Node\MethodNode($method->getName()); + + if (true === $method->isProtected()) { + $node->setVisibility('protected'); + } + + if (true === $method->isStatic()) { + $node->setStatic(); + } + + if (true === $method->returnsReference()) { + $node->setReturnsReference(); + } + + if (version_compare(PHP_VERSION, '7.0', '>=') && true === $method->hasReturnType()) { + $returnType = (string) $method->getReturnType(); + $returnTypeLower = strtolower($returnType); + + if ('self' === $returnTypeLower) { + $returnType = $method->getDeclaringClass()->getName(); + } + if ('parent' === $returnTypeLower) { + $returnType = $method->getDeclaringClass()->getParentClass()->getName(); + } + + $node->setReturnType($returnType); + } + + if (is_array($params = $method->getParameters()) && count($params)) { + foreach ($params as $param) { + $this->reflectArgumentToNode($param, $node); + } + } + + $classNode->addMethod($node); + } + + private function reflectArgumentToNode(ReflectionParameter $parameter, Node\MethodNode $methodNode) + { + $name = $parameter->getName() == '...' ? '__dot_dot_dot__' : $parameter->getName(); + $node = new Node\ArgumentNode($name); + + $node->setTypeHint($this->getTypeHint($parameter)); + + if ($this->isVariadic($parameter)) { + $node->setAsVariadic(); + } + + if ($this->hasDefaultValue($parameter)) { + $node->setDefault($this->getDefaultValue($parameter)); + } + + if ($parameter->isPassedByReference()) { + $node->setAsPassedByReference(); + } + + $methodNode->addArgument($node); + } + + private function hasDefaultValue(ReflectionParameter $parameter) + { + if ($this->isVariadic($parameter)) { + return false; + } + + if ($parameter->isDefaultValueAvailable()) { + return true; + } + + return $parameter->isOptional() || $this->isNullable($parameter); + } + + private function getDefaultValue(ReflectionParameter $parameter) + { + if (!$parameter->isDefaultValueAvailable()) { + return null; + } + + return $parameter->getDefaultValue(); + } + + private function getTypeHint(ReflectionParameter $parameter) + { + if (null !== $className = $this->getParameterClassName($parameter)) { + return $className; + } + + if (true === $parameter->isArray()) { + return 'array'; + } + + if (version_compare(PHP_VERSION, '5.4', '>=') && true === $parameter->isCallable()) { + return 'callable'; + } + + if (version_compare(PHP_VERSION, '7.0', '>=') && true === $parameter->hasType()) { + return (string) $parameter->getType(); + } + + return null; + } + + private function isVariadic(ReflectionParameter $parameter) + { + return PHP_VERSION_ID >= 50600 && $parameter->isVariadic(); + } + + private function isNullable(ReflectionParameter $parameter) + { + return $parameter->allowsNull() && null !== $this->getTypeHint($parameter); + } + + private function getParameterClassName(ReflectionParameter $parameter) + { + try { + return $parameter->getClass() ? $parameter->getClass()->getName() : null; + } catch (\ReflectionException $e) { + preg_match('/\[\s\<\w+?>\s([\w,\\\]+)/s', $parameter, $matches); + + return isset($matches[1]) ? $matches[1] : null; + } + } +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/ArgumentNode.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/ArgumentNode.php new file mode 100644 index 00000000..cf6fd735 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/ArgumentNode.php @@ -0,0 +1,91 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Doubler\Generator\Node; + +/** + * Argument node. + * + * @author Konstantin Kudryashov + */ +class ArgumentNode +{ + private $name; + private $typeHint; + private $default; + private $optional = false; + private $byReference = false; + private $isVariadic = false; + + /** + * @param string $name + */ + public function __construct($name) + { + $this->name = $name; + } + + public function getName() + { + return $this->name; + } + + public function getTypeHint() + { + return $this->typeHint; + } + + public function setTypeHint($typeHint = null) + { + $this->typeHint = $typeHint; + } + + public function hasDefault() + { + return $this->isOptional() && !$this->isVariadic(); + } + + public function getDefault() + { + return $this->default; + } + + public function setDefault($default = null) + { + $this->optional = true; + $this->default = $default; + } + + public function isOptional() + { + return $this->optional; + } + + public function setAsPassedByReference($byReference = true) + { + $this->byReference = $byReference; + } + + public function isPassedByReference() + { + return $this->byReference; + } + + public function setAsVariadic($isVariadic = true) + { + $this->isVariadic = $isVariadic; + } + + public function isVariadic() + { + return $this->isVariadic; + } +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/ClassNode.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/ClassNode.php new file mode 100644 index 00000000..1499a1d3 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/ClassNode.php @@ -0,0 +1,166 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Doubler\Generator\Node; + +use Prophecy\Exception\Doubler\MethodNotExtendableException; +use Prophecy\Exception\InvalidArgumentException; + +/** + * Class node. + * + * @author Konstantin Kudryashov + */ +class ClassNode +{ + private $parentClass = 'stdClass'; + private $interfaces = array(); + private $properties = array(); + private $unextendableMethods = array(); + + /** + * @var MethodNode[] + */ + private $methods = array(); + + public function getParentClass() + { + return $this->parentClass; + } + + /** + * @param string $class + */ + public function setParentClass($class) + { + $this->parentClass = $class ?: 'stdClass'; + } + + /** + * @return string[] + */ + public function getInterfaces() + { + return $this->interfaces; + } + + /** + * @param string $interface + */ + public function addInterface($interface) + { + if ($this->hasInterface($interface)) { + return; + } + + array_unshift($this->interfaces, $interface); + } + + /** + * @param string $interface + * + * @return bool + */ + public function hasInterface($interface) + { + return in_array($interface, $this->interfaces); + } + + public function getProperties() + { + return $this->properties; + } + + public function addProperty($name, $visibility = 'public') + { + $visibility = strtolower($visibility); + + if (!in_array($visibility, array('public', 'private', 'protected'))) { + throw new InvalidArgumentException(sprintf( + '`%s` property visibility is not supported.', $visibility + )); + } + + $this->properties[$name] = $visibility; + } + + /** + * @return MethodNode[] + */ + public function getMethods() + { + return $this->methods; + } + + public function addMethod(MethodNode $method) + { + if (!$this->isExtendable($method->getName())){ + $message = sprintf( + 'Method `%s` is not extendable, so can not be added.', $method->getName() + ); + throw new MethodNotExtendableException($message, $this->getParentClass(), $method->getName()); + } + $this->methods[$method->getName()] = $method; + } + + public function removeMethod($name) + { + unset($this->methods[$name]); + } + + /** + * @param string $name + * + * @return MethodNode|null + */ + public function getMethod($name) + { + return $this->hasMethod($name) ? $this->methods[$name] : null; + } + + /** + * @param string $name + * + * @return bool + */ + public function hasMethod($name) + { + return isset($this->methods[$name]); + } + + /** + * @return string[] + */ + public function getUnextendableMethods() + { + return $this->unextendableMethods; + } + + /** + * @param string $unextendableMethod + */ + public function addUnextendableMethod($unextendableMethod) + { + if (!$this->isExtendable($unextendableMethod)){ + return; + } + $this->unextendableMethods[] = $unextendableMethod; + } + + /** + * @param string $method + * @return bool + */ + public function isExtendable($method) + { + return !in_array($method, $this->unextendableMethods); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/MethodNode.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/MethodNode.php new file mode 100644 index 00000000..8402ab8f --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/MethodNode.php @@ -0,0 +1,188 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Doubler\Generator\Node; + +use Prophecy\Exception\InvalidArgumentException; + +/** + * Method node. + * + * @author Konstantin Kudryashov + */ +class MethodNode +{ + private $name; + private $code; + private $visibility = 'public'; + private $static = false; + private $returnsReference = false; + private $returnType; + + /** + * @var ArgumentNode[] + */ + private $arguments = array(); + + /** + * @param string $name + * @param string $code + */ + public function __construct($name, $code = null) + { + $this->name = $name; + $this->code = $code; + } + + public function getVisibility() + { + return $this->visibility; + } + + /** + * @param string $visibility + */ + public function setVisibility($visibility) + { + $visibility = strtolower($visibility); + + if (!in_array($visibility, array('public', 'private', 'protected'))) { + throw new InvalidArgumentException(sprintf( + '`%s` method visibility is not supported.', $visibility + )); + } + + $this->visibility = $visibility; + } + + public function isStatic() + { + return $this->static; + } + + public function setStatic($static = true) + { + $this->static = (bool) $static; + } + + public function returnsReference() + { + return $this->returnsReference; + } + + public function setReturnsReference() + { + $this->returnsReference = true; + } + + public function getName() + { + return $this->name; + } + + public function addArgument(ArgumentNode $argument) + { + $this->arguments[] = $argument; + } + + /** + * @return ArgumentNode[] + */ + public function getArguments() + { + return $this->arguments; + } + + public function hasReturnType() + { + return null !== $this->returnType; + } + + /** + * @param string $type + */ + public function setReturnType($type = null) + { + switch ($type) { + case '': + $this->returnType = null; + break; + + case 'string'; + case 'float': + case 'int': + case 'bool': + case 'array': + case 'callable': + $this->returnType = $type; + break; + + case 'double': + case 'real': + $this->returnType = 'float'; + break; + + case 'boolean': + $this->returnType = 'bool'; + break; + + case 'integer': + $this->returnType = 'int'; + break; + + default: + $this->returnType = '\\' . ltrim($type, '\\'); + } + } + + public function getReturnType() + { + return $this->returnType; + } + + /** + * @param string $code + */ + public function setCode($code) + { + $this->code = $code; + } + + public function getCode() + { + if ($this->returnsReference) + { + return "throw new \Prophecy\Exception\Doubler\ReturnByReferenceException('Returning by reference not supported', get_class(\$this), '{$this->name}');"; + } + + return (string) $this->code; + } + + public function useParentCode() + { + $this->code = sprintf( + 'return parent::%s(%s);', $this->getName(), implode(', ', + array_map(array($this, 'generateArgument'), $this->arguments) + ) + ); + } + + private function generateArgument(ArgumentNode $arg) + { + $argument = '$'.$arg->getName(); + + if ($arg->isVariadic()) { + $argument = '...'.$argument; + } + + return $argument; + } +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ReflectionInterface.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ReflectionInterface.php new file mode 100644 index 00000000..d720b151 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ReflectionInterface.php @@ -0,0 +1,22 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Doubler\Generator; + +/** + * Reflection interface. + * All reflected classes implement this interface. + * + * @author Konstantin Kudryashov + */ +interface ReflectionInterface +{ +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/LazyDouble.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/LazyDouble.php new file mode 100644 index 00000000..8a99c4ce --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/LazyDouble.php @@ -0,0 +1,127 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Doubler; + +use Prophecy\Exception\Doubler\DoubleException; +use Prophecy\Exception\Doubler\ClassNotFoundException; +use Prophecy\Exception\Doubler\InterfaceNotFoundException; +use ReflectionClass; + +/** + * Lazy double. + * Gives simple interface to describe double before creating it. + * + * @author Konstantin Kudryashov + */ +class LazyDouble +{ + private $doubler; + private $class; + private $interfaces = array(); + private $arguments = null; + private $double; + + /** + * Initializes lazy double. + * + * @param Doubler $doubler + */ + public function __construct(Doubler $doubler) + { + $this->doubler = $doubler; + } + + /** + * Tells doubler to use specific class as parent one for double. + * + * @param string|ReflectionClass $class + * + * @throws \Prophecy\Exception\Doubler\ClassNotFoundException + * @throws \Prophecy\Exception\Doubler\DoubleException + */ + public function setParentClass($class) + { + if (null !== $this->double) { + throw new DoubleException('Can not extend class with already instantiated double.'); + } + + if (!$class instanceof ReflectionClass) { + if (!class_exists($class)) { + throw new ClassNotFoundException(sprintf('Class %s not found.', $class), $class); + } + + $class = new ReflectionClass($class); + } + + $this->class = $class; + } + + /** + * Tells doubler to implement specific interface with double. + * + * @param string|ReflectionClass $interface + * + * @throws \Prophecy\Exception\Doubler\InterfaceNotFoundException + * @throws \Prophecy\Exception\Doubler\DoubleException + */ + public function addInterface($interface) + { + if (null !== $this->double) { + throw new DoubleException( + 'Can not implement interface with already instantiated double.' + ); + } + + if (!$interface instanceof ReflectionClass) { + if (!interface_exists($interface)) { + throw new InterfaceNotFoundException( + sprintf('Interface %s not found.', $interface), + $interface + ); + } + + $interface = new ReflectionClass($interface); + } + + $this->interfaces[] = $interface; + } + + /** + * Sets constructor arguments. + * + * @param array $arguments + */ + public function setArguments(array $arguments = null) + { + $this->arguments = $arguments; + } + + /** + * Creates double instance or returns already created one. + * + * @return DoubleInterface + */ + public function getInstance() + { + if (null === $this->double) { + if (null !== $this->arguments) { + return $this->double = $this->doubler->double( + $this->class, $this->interfaces, $this->arguments + ); + } + + $this->double = $this->doubler->double($this->class, $this->interfaces); + } + + return $this->double; + } +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/NameGenerator.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/NameGenerator.php new file mode 100644 index 00000000..d67ec6a4 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Doubler/NameGenerator.php @@ -0,0 +1,52 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Doubler; + +use ReflectionClass; + +/** + * Name generator. + * Generates classname for double. + * + * @author Konstantin Kudryashov + */ +class NameGenerator +{ + private static $counter = 1; + + /** + * Generates name. + * + * @param ReflectionClass $class + * @param ReflectionClass[] $interfaces + * + * @return string + */ + public function name(ReflectionClass $class = null, array $interfaces) + { + $parts = array(); + + if (null !== $class) { + $parts[] = $class->getName(); + } else { + foreach ($interfaces as $interface) { + $parts[] = $interface->getShortName(); + } + } + + if (!count($parts)) { + $parts[] = 'stdClass'; + } + + return sprintf('Double\%s\P%d', implode('\\', $parts), self::$counter++); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Call/UnexpectedCallException.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Call/UnexpectedCallException.php new file mode 100644 index 00000000..48ed2254 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Call/UnexpectedCallException.php @@ -0,0 +1,40 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Exception\Call; + +use Prophecy\Exception\Prophecy\ObjectProphecyException; +use Prophecy\Prophecy\ObjectProphecy; + +class UnexpectedCallException extends ObjectProphecyException +{ + private $methodName; + private $arguments; + + public function __construct($message, ObjectProphecy $objectProphecy, + $methodName, array $arguments) + { + parent::__construct($message, $objectProphecy); + + $this->methodName = $methodName; + $this->arguments = $arguments; + } + + public function getMethodName() + { + return $this->methodName; + } + + public function getArguments() + { + return $this->arguments; + } +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ClassCreatorException.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ClassCreatorException.php new file mode 100644 index 00000000..822918a2 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ClassCreatorException.php @@ -0,0 +1,31 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Exception\Doubler; + +use Prophecy\Doubler\Generator\Node\ClassNode; + +class ClassCreatorException extends \RuntimeException implements DoublerException +{ + private $node; + + public function __construct($message, ClassNode $node) + { + parent::__construct($message); + + $this->node = $node; + } + + public function getClassNode() + { + return $this->node; + } +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ClassMirrorException.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ClassMirrorException.php new file mode 100644 index 00000000..8fc53b8b --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ClassMirrorException.php @@ -0,0 +1,31 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Exception\Doubler; + +use ReflectionClass; + +class ClassMirrorException extends \RuntimeException implements DoublerException +{ + private $class; + + public function __construct($message, ReflectionClass $class) + { + parent::__construct($message); + + $this->class = $class; + } + + public function getReflectedClass() + { + return $this->class; + } +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ClassNotFoundException.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ClassNotFoundException.php new file mode 100644 index 00000000..5bc826d7 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ClassNotFoundException.php @@ -0,0 +1,33 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Exception\Doubler; + +class ClassNotFoundException extends DoubleException +{ + private $classname; + + /** + * @param string $message + * @param string $classname + */ + public function __construct($message, $classname) + { + parent::__construct($message); + + $this->classname = $classname; + } + + public function getClassname() + { + return $this->classname; + } +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/DoubleException.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/DoubleException.php new file mode 100644 index 00000000..6642a58f --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/DoubleException.php @@ -0,0 +1,18 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Exception\Doubler; + +use RuntimeException; + +class DoubleException extends RuntimeException implements DoublerException +{ +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/DoublerException.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/DoublerException.php new file mode 100644 index 00000000..9d6be179 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/DoublerException.php @@ -0,0 +1,18 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Exception\Doubler; + +use Prophecy\Exception\Exception; + +interface DoublerException extends Exception +{ +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/InterfaceNotFoundException.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/InterfaceNotFoundException.php new file mode 100644 index 00000000..e344dead --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/InterfaceNotFoundException.php @@ -0,0 +1,20 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Exception\Doubler; + +class InterfaceNotFoundException extends ClassNotFoundException +{ + public function getInterfaceName() + { + return $this->getClassname(); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/MethodNotExtendableException.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/MethodNotExtendableException.php new file mode 100644 index 00000000..56f47b11 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/MethodNotExtendableException.php @@ -0,0 +1,41 @@ +methodName = $methodName; + $this->className = $className; + } + + + /** + * @return string + */ + public function getMethodName() + { + return $this->methodName; + } + + /** + * @return string + */ + public function getClassName() + { + return $this->className; + } + + } diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/MethodNotFoundException.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/MethodNotFoundException.php new file mode 100644 index 00000000..b113941f --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/MethodNotFoundException.php @@ -0,0 +1,60 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Exception\Doubler; + +class MethodNotFoundException extends DoubleException +{ + /** + * @var string + */ + private $classname; + + /** + * @var string + */ + private $methodName; + + /** + * @var array + */ + private $arguments; + + /** + * @param string $message + * @param string $classname + * @param string $methodName + * @param null|Argument\ArgumentsWildcard|array $arguments + */ + public function __construct($message, $classname, $methodName, $arguments = null) + { + parent::__construct($message); + + $this->classname = $classname; + $this->methodName = $methodName; + $this->arguments = $arguments; + } + + public function getClassname() + { + return $this->classname; + } + + public function getMethodName() + { + return $this->methodName; + } + + public function getArguments() + { + return $this->arguments; + } +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ReturnByReferenceException.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ReturnByReferenceException.php new file mode 100644 index 00000000..63030497 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ReturnByReferenceException.php @@ -0,0 +1,41 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Exception\Doubler; + +class ReturnByReferenceException extends DoubleException +{ + private $classname; + private $methodName; + + /** + * @param string $message + * @param string $classname + * @param string $methodName + */ + public function __construct($message, $classname, $methodName) + { + parent::__construct($message); + + $this->classname = $classname; + $this->methodName = $methodName; + } + + public function getClassname() + { + return $this->classname; + } + + public function getMethodName() + { + return $this->methodName; + } +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Exception.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Exception.php new file mode 100644 index 00000000..ac9fe4dd --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Exception.php @@ -0,0 +1,26 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Exception; + +/** + * Core Prophecy exception interface. + * All Prophecy exceptions implement it. + * + * @author Konstantin Kudryashov + */ +interface Exception +{ + /** + * @return string + */ + public function getMessage(); +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/InvalidArgumentException.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/InvalidArgumentException.php new file mode 100644 index 00000000..bc91c690 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/InvalidArgumentException.php @@ -0,0 +1,16 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Exception; + +class InvalidArgumentException extends \InvalidArgumentException implements Exception +{ +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/AggregateException.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/AggregateException.php new file mode 100644 index 00000000..44b598a4 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/AggregateException.php @@ -0,0 +1,50 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Exception\Prediction; + +use Prophecy\Prophecy\ObjectProphecy; + +class AggregateException extends \RuntimeException implements PredictionException +{ + private $exceptions = array(); + private $objectProphecy; + + public function append(PredictionException $exception) + { + $message = $exception->getMessage(); + $message = ' '.strtr($message, array("\n" => "\n "))."\n"; + + $this->message = rtrim($this->message.$message); + $this->exceptions[] = $exception; + } + + /** + * @return PredictionException[] + */ + public function getExceptions() + { + return $this->exceptions; + } + + public function setObjectProphecy(ObjectProphecy $objectProphecy) + { + $this->objectProphecy = $objectProphecy; + } + + /** + * @return ObjectProphecy + */ + public function getObjectProphecy() + { + return $this->objectProphecy; + } +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/FailedPredictionException.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/FailedPredictionException.php new file mode 100644 index 00000000..bbbbc3d9 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/FailedPredictionException.php @@ -0,0 +1,24 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Exception\Prediction; + +use RuntimeException; + +/** + * Basic failed prediction exception. + * Use it for custom prediction failures. + * + * @author Konstantin Kudryashov + */ +class FailedPredictionException extends RuntimeException implements PredictionException +{ +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/NoCallsException.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/NoCallsException.php new file mode 100644 index 00000000..05ea4aad --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/NoCallsException.php @@ -0,0 +1,18 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Exception\Prediction; + +use Prophecy\Exception\Prophecy\MethodProphecyException; + +class NoCallsException extends MethodProphecyException implements PredictionException +{ +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/PredictionException.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/PredictionException.php new file mode 100644 index 00000000..2596b1ef --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/PredictionException.php @@ -0,0 +1,18 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Exception\Prediction; + +use Prophecy\Exception\Exception; + +interface PredictionException extends Exception +{ +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/UnexpectedCallsCountException.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/UnexpectedCallsCountException.php new file mode 100644 index 00000000..9d905431 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/UnexpectedCallsCountException.php @@ -0,0 +1,31 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Exception\Prediction; + +use Prophecy\Prophecy\MethodProphecy; + +class UnexpectedCallsCountException extends UnexpectedCallsException +{ + private $expectedCount; + + public function __construct($message, MethodProphecy $methodProphecy, $count, array $calls) + { + parent::__construct($message, $methodProphecy, $calls); + + $this->expectedCount = intval($count); + } + + public function getExpectedCount() + { + return $this->expectedCount; + } +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/UnexpectedCallsException.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/UnexpectedCallsException.php new file mode 100644 index 00000000..7a99c2d7 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/UnexpectedCallsException.php @@ -0,0 +1,32 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Exception\Prediction; + +use Prophecy\Prophecy\MethodProphecy; +use Prophecy\Exception\Prophecy\MethodProphecyException; + +class UnexpectedCallsException extends MethodProphecyException implements PredictionException +{ + private $calls = array(); + + public function __construct($message, MethodProphecy $methodProphecy, array $calls) + { + parent::__construct($message, $methodProphecy); + + $this->calls = $calls; + } + + public function getCalls() + { + return $this->calls; + } +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Prophecy/MethodProphecyException.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Prophecy/MethodProphecyException.php new file mode 100644 index 00000000..1b03eaf4 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Prophecy/MethodProphecyException.php @@ -0,0 +1,34 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Exception\Prophecy; + +use Prophecy\Prophecy\MethodProphecy; + +class MethodProphecyException extends ObjectProphecyException +{ + private $methodProphecy; + + public function __construct($message, MethodProphecy $methodProphecy) + { + parent::__construct($message, $methodProphecy->getObjectProphecy()); + + $this->methodProphecy = $methodProphecy; + } + + /** + * @return MethodProphecy + */ + public function getMethodProphecy() + { + return $this->methodProphecy; + } +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Prophecy/ObjectProphecyException.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Prophecy/ObjectProphecyException.php new file mode 100644 index 00000000..e345402e --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Prophecy/ObjectProphecyException.php @@ -0,0 +1,34 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Exception\Prophecy; + +use Prophecy\Prophecy\ObjectProphecy; + +class ObjectProphecyException extends \RuntimeException implements ProphecyException +{ + private $objectProphecy; + + public function __construct($message, ObjectProphecy $objectProphecy) + { + parent::__construct($message); + + $this->objectProphecy = $objectProphecy; + } + + /** + * @return ObjectProphecy + */ + public function getObjectProphecy() + { + return $this->objectProphecy; + } +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Prophecy/ProphecyException.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Prophecy/ProphecyException.php new file mode 100644 index 00000000..91573328 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Exception/Prophecy/ProphecyException.php @@ -0,0 +1,18 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Exception\Prophecy; + +use Prophecy\Exception\Exception; + +interface ProphecyException extends Exception +{ +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/PhpDocumentor/ClassAndInterfaceTagRetriever.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/PhpDocumentor/ClassAndInterfaceTagRetriever.php new file mode 100644 index 00000000..209821ce --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/PhpDocumentor/ClassAndInterfaceTagRetriever.php @@ -0,0 +1,69 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\PhpDocumentor; + +use phpDocumentor\Reflection\DocBlock\Tag\MethodTag as LegacyMethodTag; +use phpDocumentor\Reflection\DocBlock\Tags\Method; + +/** + * @author Théo FIDRY + * + * @internal + */ +final class ClassAndInterfaceTagRetriever implements MethodTagRetrieverInterface +{ + private $classRetriever; + + public function __construct(MethodTagRetrieverInterface $classRetriever = null) + { + if (null !== $classRetriever) { + $this->classRetriever = $classRetriever; + + return; + } + + $this->classRetriever = class_exists('phpDocumentor\Reflection\DocBlockFactory') && class_exists('phpDocumentor\Reflection\Types\ContextFactory') + ? new ClassTagRetriever() + : new LegacyClassTagRetriever() + ; + } + + /** + * @param \ReflectionClass $reflectionClass + * + * @return LegacyMethodTag[]|Method[] + */ + public function getTagList(\ReflectionClass $reflectionClass) + { + return array_merge( + $this->classRetriever->getTagList($reflectionClass), + $this->getInterfacesTagList($reflectionClass) + ); + } + + /** + * @param \ReflectionClass $reflectionClass + * + * @return LegacyMethodTag[]|Method[] + */ + private function getInterfacesTagList(\ReflectionClass $reflectionClass) + { + $interfaces = $reflectionClass->getInterfaces(); + $tagList = array(); + + foreach($interfaces as $interface) { + $tagList = array_merge($tagList, $this->classRetriever->getTagList($interface)); + } + + return $tagList; + } +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/PhpDocumentor/ClassTagRetriever.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/PhpDocumentor/ClassTagRetriever.php new file mode 100644 index 00000000..1d2da8f0 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/PhpDocumentor/ClassTagRetriever.php @@ -0,0 +1,52 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\PhpDocumentor; + +use phpDocumentor\Reflection\DocBlock\Tags\Method; +use phpDocumentor\Reflection\DocBlockFactory; +use phpDocumentor\Reflection\Types\ContextFactory; + +/** + * @author Théo FIDRY + * + * @internal + */ +final class ClassTagRetriever implements MethodTagRetrieverInterface +{ + private $docBlockFactory; + private $contextFactory; + + public function __construct() + { + $this->docBlockFactory = DocBlockFactory::createInstance(); + $this->contextFactory = new ContextFactory(); + } + + /** + * @param \ReflectionClass $reflectionClass + * + * @return Method[] + */ + public function getTagList(\ReflectionClass $reflectionClass) + { + try { + $phpdoc = $this->docBlockFactory->create( + $reflectionClass, + $this->contextFactory->createFromReflector($reflectionClass) + ); + + return $phpdoc->getTagsByName('method'); + } catch (\InvalidArgumentException $e) { + return array(); + } + } +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/PhpDocumentor/LegacyClassTagRetriever.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/PhpDocumentor/LegacyClassTagRetriever.php new file mode 100644 index 00000000..c0dec3de --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/PhpDocumentor/LegacyClassTagRetriever.php @@ -0,0 +1,35 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\PhpDocumentor; + +use phpDocumentor\Reflection\DocBlock; +use phpDocumentor\Reflection\DocBlock\Tag\MethodTag as LegacyMethodTag; + +/** + * @author Théo FIDRY + * + * @internal + */ +final class LegacyClassTagRetriever implements MethodTagRetrieverInterface +{ + /** + * @param \ReflectionClass $reflectionClass + * + * @return LegacyMethodTag[] + */ + public function getTagList(\ReflectionClass $reflectionClass) + { + $phpdoc = new DocBlock($reflectionClass->getDocComment()); + + return $phpdoc->getTagsByName('method'); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/PhpDocumentor/MethodTagRetrieverInterface.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/PhpDocumentor/MethodTagRetrieverInterface.php new file mode 100644 index 00000000..d3989dad --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/PhpDocumentor/MethodTagRetrieverInterface.php @@ -0,0 +1,30 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\PhpDocumentor; + +use phpDocumentor\Reflection\DocBlock\Tag\MethodTag as LegacyMethodTag; +use phpDocumentor\Reflection\DocBlock\Tags\Method; + +/** + * @author Théo FIDRY + * + * @internal + */ +interface MethodTagRetrieverInterface +{ + /** + * @param \ReflectionClass $reflectionClass + * + * @return LegacyMethodTag[]|Method[] + */ + public function getTagList(\ReflectionClass $reflectionClass); +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Prediction/CallPrediction.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Prediction/CallPrediction.php new file mode 100644 index 00000000..b4787366 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Prediction/CallPrediction.php @@ -0,0 +1,86 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Prediction; + +use Prophecy\Call\Call; +use Prophecy\Prophecy\ObjectProphecy; +use Prophecy\Prophecy\MethodProphecy; +use Prophecy\Argument\ArgumentsWildcard; +use Prophecy\Argument\Token\AnyValuesToken; +use Prophecy\Util\StringUtil; +use Prophecy\Exception\Prediction\NoCallsException; + +/** + * Call prediction. + * + * @author Konstantin Kudryashov + */ +class CallPrediction implements PredictionInterface +{ + private $util; + + /** + * Initializes prediction. + * + * @param StringUtil $util + */ + public function __construct(StringUtil $util = null) + { + $this->util = $util ?: new StringUtil; + } + + /** + * Tests that there was at least one call. + * + * @param Call[] $calls + * @param ObjectProphecy $object + * @param MethodProphecy $method + * + * @throws \Prophecy\Exception\Prediction\NoCallsException + */ + public function check(array $calls, ObjectProphecy $object, MethodProphecy $method) + { + if (count($calls)) { + return; + } + + $methodCalls = $object->findProphecyMethodCalls( + $method->getMethodName(), + new ArgumentsWildcard(array(new AnyValuesToken)) + ); + + if (count($methodCalls)) { + throw new NoCallsException(sprintf( + "No calls have been made that match:\n". + " %s->%s(%s)\n". + "but expected at least one.\n". + "Recorded `%s(...)` calls:\n%s", + + get_class($object->reveal()), + $method->getMethodName(), + $method->getArgumentsWildcard(), + $method->getMethodName(), + $this->util->stringifyCalls($methodCalls) + ), $method); + } + + throw new NoCallsException(sprintf( + "No calls have been made that match:\n". + " %s->%s(%s)\n". + "but expected at least one.", + + get_class($object->reveal()), + $method->getMethodName(), + $method->getArgumentsWildcard() + ), $method); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Prediction/CallTimesPrediction.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Prediction/CallTimesPrediction.php new file mode 100644 index 00000000..31c6c575 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Prediction/CallTimesPrediction.php @@ -0,0 +1,107 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Prediction; + +use Prophecy\Call\Call; +use Prophecy\Prophecy\ObjectProphecy; +use Prophecy\Prophecy\MethodProphecy; +use Prophecy\Argument\ArgumentsWildcard; +use Prophecy\Argument\Token\AnyValuesToken; +use Prophecy\Util\StringUtil; +use Prophecy\Exception\Prediction\UnexpectedCallsCountException; + +/** + * Prediction interface. + * Predictions are logical test blocks, tied to `should...` keyword. + * + * @author Konstantin Kudryashov + */ +class CallTimesPrediction implements PredictionInterface +{ + private $times; + private $util; + + /** + * Initializes prediction. + * + * @param int $times + * @param StringUtil $util + */ + public function __construct($times, StringUtil $util = null) + { + $this->times = intval($times); + $this->util = $util ?: new StringUtil; + } + + /** + * Tests that there was exact amount of calls made. + * + * @param Call[] $calls + * @param ObjectProphecy $object + * @param MethodProphecy $method + * + * @throws \Prophecy\Exception\Prediction\UnexpectedCallsCountException + */ + public function check(array $calls, ObjectProphecy $object, MethodProphecy $method) + { + if ($this->times == count($calls)) { + return; + } + + $methodCalls = $object->findProphecyMethodCalls( + $method->getMethodName(), + new ArgumentsWildcard(array(new AnyValuesToken)) + ); + + if (count($calls)) { + $message = sprintf( + "Expected exactly %d calls that match:\n". + " %s->%s(%s)\n". + "but %d were made:\n%s", + + $this->times, + get_class($object->reveal()), + $method->getMethodName(), + $method->getArgumentsWildcard(), + count($calls), + $this->util->stringifyCalls($calls) + ); + } elseif (count($methodCalls)) { + $message = sprintf( + "Expected exactly %d calls that match:\n". + " %s->%s(%s)\n". + "but none were made.\n". + "Recorded `%s(...)` calls:\n%s", + + $this->times, + get_class($object->reveal()), + $method->getMethodName(), + $method->getArgumentsWildcard(), + $method->getMethodName(), + $this->util->stringifyCalls($methodCalls) + ); + } else { + $message = sprintf( + "Expected exactly %d calls that match:\n". + " %s->%s(%s)\n". + "but none were made.", + + $this->times, + get_class($object->reveal()), + $method->getMethodName(), + $method->getArgumentsWildcard() + ); + } + + throw new UnexpectedCallsCountException($message, $method, $this->times, $calls); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Prediction/CallbackPrediction.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Prediction/CallbackPrediction.php new file mode 100644 index 00000000..44bc782c --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Prediction/CallbackPrediction.php @@ -0,0 +1,65 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Prediction; + +use Prophecy\Call\Call; +use Prophecy\Prophecy\ObjectProphecy; +use Prophecy\Prophecy\MethodProphecy; +use Prophecy\Exception\InvalidArgumentException; +use Closure; + +/** + * Callback prediction. + * + * @author Konstantin Kudryashov + */ +class CallbackPrediction implements PredictionInterface +{ + private $callback; + + /** + * Initializes callback prediction. + * + * @param callable $callback Custom callback + * + * @throws \Prophecy\Exception\InvalidArgumentException + */ + public function __construct($callback) + { + if (!is_callable($callback)) { + throw new InvalidArgumentException(sprintf( + 'Callable expected as an argument to CallbackPrediction, but got %s.', + gettype($callback) + )); + } + + $this->callback = $callback; + } + + /** + * Executes preset callback. + * + * @param Call[] $calls + * @param ObjectProphecy $object + * @param MethodProphecy $method + */ + public function check(array $calls, ObjectProphecy $object, MethodProphecy $method) + { + $callback = $this->callback; + + if ($callback instanceof Closure && method_exists('Closure', 'bind')) { + $callback = Closure::bind($callback, $object); + } + + call_user_func($callback, $calls, $object, $method); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Prediction/NoCallsPrediction.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Prediction/NoCallsPrediction.php new file mode 100644 index 00000000..46ac5bfc --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Prediction/NoCallsPrediction.php @@ -0,0 +1,68 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Prediction; + +use Prophecy\Call\Call; +use Prophecy\Prophecy\ObjectProphecy; +use Prophecy\Prophecy\MethodProphecy; +use Prophecy\Util\StringUtil; +use Prophecy\Exception\Prediction\UnexpectedCallsException; + +/** + * No calls prediction. + * + * @author Konstantin Kudryashov + */ +class NoCallsPrediction implements PredictionInterface +{ + private $util; + + /** + * Initializes prediction. + * + * @param null|StringUtil $util + */ + public function __construct(StringUtil $util = null) + { + $this->util = $util ?: new StringUtil; + } + + /** + * Tests that there were no calls made. + * + * @param Call[] $calls + * @param ObjectProphecy $object + * @param MethodProphecy $method + * + * @throws \Prophecy\Exception\Prediction\UnexpectedCallsException + */ + public function check(array $calls, ObjectProphecy $object, MethodProphecy $method) + { + if (!count($calls)) { + return; + } + + $verb = count($calls) === 1 ? 'was' : 'were'; + + throw new UnexpectedCallsException(sprintf( + "No calls expected that match:\n". + " %s->%s(%s)\n". + "but %d %s made:\n%s", + get_class($object->reveal()), + $method->getMethodName(), + $method->getArgumentsWildcard(), + count($calls), + $verb, + $this->util->stringifyCalls($calls) + ), $method, $calls); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Prediction/PredictionInterface.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Prediction/PredictionInterface.php new file mode 100644 index 00000000..f7fb06a9 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Prediction/PredictionInterface.php @@ -0,0 +1,37 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Prediction; + +use Prophecy\Call\Call; +use Prophecy\Prophecy\ObjectProphecy; +use Prophecy\Prophecy\MethodProphecy; + +/** + * Prediction interface. + * Predictions are logical test blocks, tied to `should...` keyword. + * + * @author Konstantin Kudryashov + */ +interface PredictionInterface +{ + /** + * Tests that double fulfilled prediction. + * + * @param Call[] $calls + * @param ObjectProphecy $object + * @param MethodProphecy $method + * + * @throws object + * @return void + */ + public function check(array $calls, ObjectProphecy $object, MethodProphecy $method); +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Promise/CallbackPromise.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Promise/CallbackPromise.php new file mode 100644 index 00000000..5f406bf7 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Promise/CallbackPromise.php @@ -0,0 +1,66 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Promise; + +use Prophecy\Prophecy\ObjectProphecy; +use Prophecy\Prophecy\MethodProphecy; +use Prophecy\Exception\InvalidArgumentException; +use Closure; + +/** + * Callback promise. + * + * @author Konstantin Kudryashov + */ +class CallbackPromise implements PromiseInterface +{ + private $callback; + + /** + * Initializes callback promise. + * + * @param callable $callback Custom callback + * + * @throws \Prophecy\Exception\InvalidArgumentException + */ + public function __construct($callback) + { + if (!is_callable($callback)) { + throw new InvalidArgumentException(sprintf( + 'Callable expected as an argument to CallbackPromise, but got %s.', + gettype($callback) + )); + } + + $this->callback = $callback; + } + + /** + * Evaluates promise callback. + * + * @param array $args + * @param ObjectProphecy $object + * @param MethodProphecy $method + * + * @return mixed + */ + public function execute(array $args, ObjectProphecy $object, MethodProphecy $method) + { + $callback = $this->callback; + + if ($callback instanceof Closure && method_exists('Closure', 'bind')) { + $callback = Closure::bind($callback, $object); + } + + return call_user_func($callback, $args, $object, $method); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Promise/PromiseInterface.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Promise/PromiseInterface.php new file mode 100644 index 00000000..382537b4 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Promise/PromiseInterface.php @@ -0,0 +1,35 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Promise; + +use Prophecy\Prophecy\ObjectProphecy; +use Prophecy\Prophecy\MethodProphecy; + +/** + * Promise interface. + * Promises are logical blocks, tied to `will...` keyword. + * + * @author Konstantin Kudryashov + */ +interface PromiseInterface +{ + /** + * Evaluates promise. + * + * @param array $args + * @param ObjectProphecy $object + * @param MethodProphecy $method + * + * @return mixed + */ + public function execute(array $args, ObjectProphecy $object, MethodProphecy $method); +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Promise/ReturnArgumentPromise.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Promise/ReturnArgumentPromise.php new file mode 100644 index 00000000..39bfeea0 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Promise/ReturnArgumentPromise.php @@ -0,0 +1,61 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Promise; + +use Prophecy\Exception\InvalidArgumentException; +use Prophecy\Prophecy\ObjectProphecy; +use Prophecy\Prophecy\MethodProphecy; + +/** + * Return argument promise. + * + * @author Konstantin Kudryashov + */ +class ReturnArgumentPromise implements PromiseInterface +{ + /** + * @var int + */ + private $index; + + /** + * Initializes callback promise. + * + * @param int $index The zero-indexed number of the argument to return + * + * @throws \Prophecy\Exception\InvalidArgumentException + */ + public function __construct($index = 0) + { + if (!is_int($index) || $index < 0) { + throw new InvalidArgumentException(sprintf( + 'Zero-based index expected as argument to ReturnArgumentPromise, but got %s.', + $index + )); + } + $this->index = $index; + } + + /** + * Returns nth argument if has one, null otherwise. + * + * @param array $args + * @param ObjectProphecy $object + * @param MethodProphecy $method + * + * @return null|mixed + */ + public function execute(array $args, ObjectProphecy $object, MethodProphecy $method) + { + return count($args) > $this->index ? $args[$this->index] : null; + } +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Promise/ReturnPromise.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Promise/ReturnPromise.php new file mode 100644 index 00000000..c7d5ac59 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Promise/ReturnPromise.php @@ -0,0 +1,55 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Promise; + +use Prophecy\Prophecy\ObjectProphecy; +use Prophecy\Prophecy\MethodProphecy; + +/** + * Return promise. + * + * @author Konstantin Kudryashov + */ +class ReturnPromise implements PromiseInterface +{ + private $returnValues = array(); + + /** + * Initializes promise. + * + * @param array $returnValues Array of values + */ + public function __construct(array $returnValues) + { + $this->returnValues = $returnValues; + } + + /** + * Returns saved values one by one until last one, then continuously returns last value. + * + * @param array $args + * @param ObjectProphecy $object + * @param MethodProphecy $method + * + * @return mixed + */ + public function execute(array $args, ObjectProphecy $object, MethodProphecy $method) + { + $value = array_shift($this->returnValues); + + if (!count($this->returnValues)) { + $this->returnValues[] = $value; + } + + return $value; + } +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Promise/ThrowPromise.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Promise/ThrowPromise.php new file mode 100644 index 00000000..68a8b471 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Promise/ThrowPromise.php @@ -0,0 +1,91 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Promise; + +use Doctrine\Instantiator\Instantiator; +use Prophecy\Prophecy\ObjectProphecy; +use Prophecy\Prophecy\MethodProphecy; +use Prophecy\Exception\InvalidArgumentException; +use ReflectionClass; + +/** + * Throw promise. + * + * @author Konstantin Kudryashov + */ +class ThrowPromise implements PromiseInterface +{ + private $exception; + + /** + * @var \Doctrine\Instantiator\Instantiator + */ + private $instantiator; + + /** + * Initializes promise. + * + * @param string|\Exception $exception Exception class name or instance + * + * @throws \Prophecy\Exception\InvalidArgumentException + */ + public function __construct($exception) + { + if (is_string($exception)) { + if (!class_exists($exception) + && 'Exception' !== $exception + && !is_subclass_of($exception, 'Exception')) { + throw new InvalidArgumentException(sprintf( + 'Exception class or instance expected as argument to ThrowPromise, but got %s.', + $exception + )); + } + } elseif (!$exception instanceof \Exception) { + throw new InvalidArgumentException(sprintf( + 'Exception class or instance expected as argument to ThrowPromise, but got %s.', + is_object($exception) ? get_class($exception) : gettype($exception) + )); + } + + $this->exception = $exception; + } + + /** + * Throws predefined exception. + * + * @param array $args + * @param ObjectProphecy $object + * @param MethodProphecy $method + * + * @throws object + */ + public function execute(array $args, ObjectProphecy $object, MethodProphecy $method) + { + if (is_string($this->exception)) { + $classname = $this->exception; + $reflection = new ReflectionClass($classname); + $constructor = $reflection->getConstructor(); + + if ($constructor->isPublic() && 0 == $constructor->getNumberOfRequiredParameters()) { + throw $reflection->newInstance(); + } + + if (!$this->instantiator) { + $this->instantiator = new Instantiator(); + } + + throw $this->instantiator->instantiate($classname); + } + + throw $this->exception; + } +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Prophecy/MethodProphecy.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Prophecy/MethodProphecy.php new file mode 100644 index 00000000..27e80f5b --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Prophecy/MethodProphecy.php @@ -0,0 +1,438 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Prophecy; + +use Prophecy\Argument; +use Prophecy\Prophet; +use Prophecy\Promise; +use Prophecy\Prediction; +use Prophecy\Exception\Doubler\MethodNotFoundException; +use Prophecy\Exception\InvalidArgumentException; +use Prophecy\Exception\Prophecy\MethodProphecyException; + +/** + * Method prophecy. + * + * @author Konstantin Kudryashov + */ +class MethodProphecy +{ + private $objectProphecy; + private $methodName; + private $argumentsWildcard; + private $promise; + private $prediction; + private $checkedPredictions = array(); + private $bound = false; + + /** + * Initializes method prophecy. + * + * @param ObjectProphecy $objectProphecy + * @param string $methodName + * @param null|Argument\ArgumentsWildcard|array $arguments + * + * @throws \Prophecy\Exception\Doubler\MethodNotFoundException If method not found + */ + public function __construct(ObjectProphecy $objectProphecy, $methodName, $arguments = null) + { + $double = $objectProphecy->reveal(); + if (!method_exists($double, $methodName)) { + throw new MethodNotFoundException(sprintf( + 'Method `%s::%s()` is not defined.', get_class($double), $methodName + ), get_class($double), $methodName, $arguments); + } + + $this->objectProphecy = $objectProphecy; + $this->methodName = $methodName; + + $reflectedMethod = new \ReflectionMethod($double, $methodName); + if ($reflectedMethod->isFinal()) { + throw new MethodProphecyException(sprintf( + "Can not add prophecy for a method `%s::%s()`\n". + "as it is a final method.", + get_class($double), + $methodName + ), $this); + } + + if (null !== $arguments) { + $this->withArguments($arguments); + } + + if (version_compare(PHP_VERSION, '7.0', '>=') && true === $reflectedMethod->hasReturnType()) { + $type = (string) $reflectedMethod->getReturnType(); + $this->will(function () use ($type) { + switch ($type) { + case 'string': return ''; + case 'float': return 0.0; + case 'int': return 0; + case 'bool': return false; + case 'array': return array(); + + case 'callable': + case 'Closure': + return function () {}; + + case 'Traversable': + case 'Generator': + // Remove eval() when minimum version >=5.5 + /** @var callable $generator */ + $generator = eval('return function () { yield; };'); + return $generator(); + + default: + $prophet = new Prophet; + return $prophet->prophesize($type)->reveal(); + } + }); + } + } + + /** + * Sets argument wildcard. + * + * @param array|Argument\ArgumentsWildcard $arguments + * + * @return $this + * + * @throws \Prophecy\Exception\InvalidArgumentException + */ + public function withArguments($arguments) + { + if (is_array($arguments)) { + $arguments = new Argument\ArgumentsWildcard($arguments); + } + + if (!$arguments instanceof Argument\ArgumentsWildcard) { + throw new InvalidArgumentException(sprintf( + "Either an array or an instance of ArgumentsWildcard expected as\n". + 'a `MethodProphecy::withArguments()` argument, but got %s.', + gettype($arguments) + )); + } + + $this->argumentsWildcard = $arguments; + + return $this; + } + + /** + * Sets custom promise to the prophecy. + * + * @param callable|Promise\PromiseInterface $promise + * + * @return $this + * + * @throws \Prophecy\Exception\InvalidArgumentException + */ + public function will($promise) + { + if (is_callable($promise)) { + $promise = new Promise\CallbackPromise($promise); + } + + if (!$promise instanceof Promise\PromiseInterface) { + throw new InvalidArgumentException(sprintf( + 'Expected callable or instance of PromiseInterface, but got %s.', + gettype($promise) + )); + } + + $this->bindToObjectProphecy(); + $this->promise = $promise; + + return $this; + } + + /** + * Sets return promise to the prophecy. + * + * @see Prophecy\Promise\ReturnPromise + * + * @return $this + */ + public function willReturn() + { + return $this->will(new Promise\ReturnPromise(func_get_args())); + } + + /** + * Sets return argument promise to the prophecy. + * + * @param int $index The zero-indexed number of the argument to return + * + * @see Prophecy\Promise\ReturnArgumentPromise + * + * @return $this + */ + public function willReturnArgument($index = 0) + { + return $this->will(new Promise\ReturnArgumentPromise($index)); + } + + /** + * Sets throw promise to the prophecy. + * + * @see Prophecy\Promise\ThrowPromise + * + * @param string|\Exception $exception Exception class or instance + * + * @return $this + */ + public function willThrow($exception) + { + return $this->will(new Promise\ThrowPromise($exception)); + } + + /** + * Sets custom prediction to the prophecy. + * + * @param callable|Prediction\PredictionInterface $prediction + * + * @return $this + * + * @throws \Prophecy\Exception\InvalidArgumentException + */ + public function should($prediction) + { + if (is_callable($prediction)) { + $prediction = new Prediction\CallbackPrediction($prediction); + } + + if (!$prediction instanceof Prediction\PredictionInterface) { + throw new InvalidArgumentException(sprintf( + 'Expected callable or instance of PredictionInterface, but got %s.', + gettype($prediction) + )); + } + + $this->bindToObjectProphecy(); + $this->prediction = $prediction; + + return $this; + } + + /** + * Sets call prediction to the prophecy. + * + * @see Prophecy\Prediction\CallPrediction + * + * @return $this + */ + public function shouldBeCalled() + { + return $this->should(new Prediction\CallPrediction); + } + + /** + * Sets no calls prediction to the prophecy. + * + * @see Prophecy\Prediction\NoCallsPrediction + * + * @return $this + */ + public function shouldNotBeCalled() + { + return $this->should(new Prediction\NoCallsPrediction); + } + + /** + * Sets call times prediction to the prophecy. + * + * @see Prophecy\Prediction\CallTimesPrediction + * + * @param $count + * + * @return $this + */ + public function shouldBeCalledTimes($count) + { + return $this->should(new Prediction\CallTimesPrediction($count)); + } + + /** + * Checks provided prediction immediately. + * + * @param callable|Prediction\PredictionInterface $prediction + * + * @return $this + * + * @throws \Prophecy\Exception\InvalidArgumentException + */ + public function shouldHave($prediction) + { + if (is_callable($prediction)) { + $prediction = new Prediction\CallbackPrediction($prediction); + } + + if (!$prediction instanceof Prediction\PredictionInterface) { + throw new InvalidArgumentException(sprintf( + 'Expected callable or instance of PredictionInterface, but got %s.', + gettype($prediction) + )); + } + + if (null === $this->promise) { + $this->willReturn(); + } + + $calls = $this->getObjectProphecy()->findProphecyMethodCalls( + $this->getMethodName(), + $this->getArgumentsWildcard() + ); + + try { + $prediction->check($calls, $this->getObjectProphecy(), $this); + $this->checkedPredictions[] = $prediction; + } catch (\Exception $e) { + $this->checkedPredictions[] = $prediction; + + throw $e; + } + + return $this; + } + + /** + * Checks call prediction. + * + * @see Prophecy\Prediction\CallPrediction + * + * @return $this + */ + public function shouldHaveBeenCalled() + { + return $this->shouldHave(new Prediction\CallPrediction); + } + + /** + * Checks no calls prediction. + * + * @see Prophecy\Prediction\NoCallsPrediction + * + * @return $this + */ + public function shouldNotHaveBeenCalled() + { + return $this->shouldHave(new Prediction\NoCallsPrediction); + } + + /** + * Checks no calls prediction. + * + * @see Prophecy\Prediction\NoCallsPrediction + * @deprecated + * + * @return $this + */ + public function shouldNotBeenCalled() + { + return $this->shouldNotHaveBeenCalled(); + } + + /** + * Checks call times prediction. + * + * @see Prophecy\Prediction\CallTimesPrediction + * + * @param int $count + * + * @return $this + */ + public function shouldHaveBeenCalledTimes($count) + { + return $this->shouldHave(new Prediction\CallTimesPrediction($count)); + } + + /** + * Checks currently registered [with should(...)] prediction. + */ + public function checkPrediction() + { + if (null === $this->prediction) { + return; + } + + $this->shouldHave($this->prediction); + } + + /** + * Returns currently registered promise. + * + * @return null|Promise\PromiseInterface + */ + public function getPromise() + { + return $this->promise; + } + + /** + * Returns currently registered prediction. + * + * @return null|Prediction\PredictionInterface + */ + public function getPrediction() + { + return $this->prediction; + } + + /** + * Returns predictions that were checked on this object. + * + * @return Prediction\PredictionInterface[] + */ + public function getCheckedPredictions() + { + return $this->checkedPredictions; + } + + /** + * Returns object prophecy this method prophecy is tied to. + * + * @return ObjectProphecy + */ + public function getObjectProphecy() + { + return $this->objectProphecy; + } + + /** + * Returns method name. + * + * @return string + */ + public function getMethodName() + { + return $this->methodName; + } + + /** + * Returns arguments wildcard. + * + * @return Argument\ArgumentsWildcard + */ + public function getArgumentsWildcard() + { + return $this->argumentsWildcard; + } + + private function bindToObjectProphecy() + { + if ($this->bound) { + return; + } + + $this->getObjectProphecy()->addMethodProphecy($this); + $this->bound = true; + } +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Prophecy/ObjectProphecy.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Prophecy/ObjectProphecy.php new file mode 100644 index 00000000..8d8f8a1b --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Prophecy/ObjectProphecy.php @@ -0,0 +1,281 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Prophecy; + +use SebastianBergmann\Comparator\ComparisonFailure; +use Prophecy\Comparator\Factory as ComparatorFactory; +use Prophecy\Call\Call; +use Prophecy\Doubler\LazyDouble; +use Prophecy\Argument\ArgumentsWildcard; +use Prophecy\Call\CallCenter; +use Prophecy\Exception\Prophecy\ObjectProphecyException; +use Prophecy\Exception\Prophecy\MethodProphecyException; +use Prophecy\Exception\Prediction\AggregateException; +use Prophecy\Exception\Prediction\PredictionException; + +/** + * Object prophecy. + * + * @author Konstantin Kudryashov + */ +class ObjectProphecy implements ProphecyInterface +{ + private $lazyDouble; + private $callCenter; + private $revealer; + private $comparatorFactory; + + /** + * @var MethodProphecy[][] + */ + private $methodProphecies = array(); + + /** + * Initializes object prophecy. + * + * @param LazyDouble $lazyDouble + * @param CallCenter $callCenter + * @param RevealerInterface $revealer + * @param ComparatorFactory $comparatorFactory + */ + public function __construct( + LazyDouble $lazyDouble, + CallCenter $callCenter = null, + RevealerInterface $revealer = null, + ComparatorFactory $comparatorFactory = null + ) { + $this->lazyDouble = $lazyDouble; + $this->callCenter = $callCenter ?: new CallCenter; + $this->revealer = $revealer ?: new Revealer; + + $this->comparatorFactory = $comparatorFactory ?: ComparatorFactory::getInstance(); + } + + /** + * Forces double to extend specific class. + * + * @param string $class + * + * @return $this + */ + public function willExtend($class) + { + $this->lazyDouble->setParentClass($class); + + return $this; + } + + /** + * Forces double to implement specific interface. + * + * @param string $interface + * + * @return $this + */ + public function willImplement($interface) + { + $this->lazyDouble->addInterface($interface); + + return $this; + } + + /** + * Sets constructor arguments. + * + * @param array $arguments + * + * @return $this + */ + public function willBeConstructedWith(array $arguments = null) + { + $this->lazyDouble->setArguments($arguments); + + return $this; + } + + /** + * Reveals double. + * + * @return object + * + * @throws \Prophecy\Exception\Prophecy\ObjectProphecyException If double doesn't implement needed interface + */ + public function reveal() + { + $double = $this->lazyDouble->getInstance(); + + if (null === $double || !$double instanceof ProphecySubjectInterface) { + throw new ObjectProphecyException( + "Generated double must implement ProphecySubjectInterface, but it does not.\n". + 'It seems you have wrongly configured doubler without required ClassPatch.', + $this + ); + } + + $double->setProphecy($this); + + return $double; + } + + /** + * Adds method prophecy to object prophecy. + * + * @param MethodProphecy $methodProphecy + * + * @throws \Prophecy\Exception\Prophecy\MethodProphecyException If method prophecy doesn't + * have arguments wildcard + */ + public function addMethodProphecy(MethodProphecy $methodProphecy) + { + $argumentsWildcard = $methodProphecy->getArgumentsWildcard(); + if (null === $argumentsWildcard) { + throw new MethodProphecyException(sprintf( + "Can not add prophecy for a method `%s::%s()`\n". + "as you did not specify arguments wildcard for it.", + get_class($this->reveal()), + $methodProphecy->getMethodName() + ), $methodProphecy); + } + + $methodName = $methodProphecy->getMethodName(); + + if (!isset($this->methodProphecies[$methodName])) { + $this->methodProphecies[$methodName] = array(); + } + + $this->methodProphecies[$methodName][] = $methodProphecy; + } + + /** + * Returns either all or related to single method prophecies. + * + * @param null|string $methodName + * + * @return MethodProphecy[] + */ + public function getMethodProphecies($methodName = null) + { + if (null === $methodName) { + return $this->methodProphecies; + } + + if (!isset($this->methodProphecies[$methodName])) { + return array(); + } + + return $this->methodProphecies[$methodName]; + } + + /** + * Makes specific method call. + * + * @param string $methodName + * @param array $arguments + * + * @return mixed + */ + public function makeProphecyMethodCall($methodName, array $arguments) + { + $arguments = $this->revealer->reveal($arguments); + $return = $this->callCenter->makeCall($this, $methodName, $arguments); + + return $this->revealer->reveal($return); + } + + /** + * Finds calls by method name & arguments wildcard. + * + * @param string $methodName + * @param ArgumentsWildcard $wildcard + * + * @return Call[] + */ + public function findProphecyMethodCalls($methodName, ArgumentsWildcard $wildcard) + { + return $this->callCenter->findCalls($methodName, $wildcard); + } + + /** + * Checks that registered method predictions do not fail. + * + * @throws \Prophecy\Exception\Prediction\AggregateException If any of registered predictions fail + */ + public function checkProphecyMethodsPredictions() + { + $exception = new AggregateException(sprintf("%s:\n", get_class($this->reveal()))); + $exception->setObjectProphecy($this); + + foreach ($this->methodProphecies as $prophecies) { + foreach ($prophecies as $prophecy) { + try { + $prophecy->checkPrediction(); + } catch (PredictionException $e) { + $exception->append($e); + } + } + } + + if (count($exception->getExceptions())) { + throw $exception; + } + } + + /** + * Creates new method prophecy using specified method name and arguments. + * + * @param string $methodName + * @param array $arguments + * + * @return MethodProphecy + */ + public function __call($methodName, array $arguments) + { + $arguments = new ArgumentsWildcard($this->revealer->reveal($arguments)); + + foreach ($this->getMethodProphecies($methodName) as $prophecy) { + $argumentsWildcard = $prophecy->getArgumentsWildcard(); + $comparator = $this->comparatorFactory->getComparatorFor( + $argumentsWildcard, $arguments + ); + + try { + $comparator->assertEquals($argumentsWildcard, $arguments); + return $prophecy; + } catch (ComparisonFailure $failure) {} + } + + return new MethodProphecy($this, $methodName, $arguments); + } + + /** + * Tries to get property value from double. + * + * @param string $name + * + * @return mixed + */ + public function __get($name) + { + return $this->reveal()->$name; + } + + /** + * Tries to set property value to double. + * + * @param string $name + * @param mixed $value + */ + public function __set($name, $value) + { + $this->reveal()->$name = $this->revealer->reveal($value); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Prophecy/ProphecyInterface.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Prophecy/ProphecyInterface.php new file mode 100644 index 00000000..462f15a9 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Prophecy/ProphecyInterface.php @@ -0,0 +1,27 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Prophecy; + +/** + * Core Prophecy interface. + * + * @author Konstantin Kudryashov + */ +interface ProphecyInterface +{ + /** + * Reveals prophecy object (double) . + * + * @return object + */ + public function reveal(); +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Prophecy/ProphecySubjectInterface.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Prophecy/ProphecySubjectInterface.php new file mode 100644 index 00000000..2d839585 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Prophecy/ProphecySubjectInterface.php @@ -0,0 +1,34 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Prophecy; + +/** + * Controllable doubles interface. + * + * @author Konstantin Kudryashov + */ +interface ProphecySubjectInterface +{ + /** + * Sets subject prophecy. + * + * @param ProphecyInterface $prophecy + */ + public function setProphecy(ProphecyInterface $prophecy); + + /** + * Returns subject prophecy. + * + * @return ProphecyInterface + */ + public function getProphecy(); +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Prophecy/Revealer.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Prophecy/Revealer.php new file mode 100644 index 00000000..60ecdac8 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Prophecy/Revealer.php @@ -0,0 +1,44 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Prophecy; + +/** + * Basic prophecies revealer. + * + * @author Konstantin Kudryashov + */ +class Revealer implements RevealerInterface +{ + /** + * Unwraps value(s). + * + * @param mixed $value + * + * @return mixed + */ + public function reveal($value) + { + if (is_array($value)) { + return array_map(array($this, __FUNCTION__), $value); + } + + if (!is_object($value)) { + return $value; + } + + if ($value instanceof ProphecyInterface) { + $value = $value->reveal(); + } + + return $value; + } +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Prophecy/RevealerInterface.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Prophecy/RevealerInterface.php new file mode 100644 index 00000000..ffc82bb6 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Prophecy/RevealerInterface.php @@ -0,0 +1,29 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Prophecy; + +/** + * Prophecies revealer interface. + * + * @author Konstantin Kudryashov + */ +interface RevealerInterface +{ + /** + * Unwraps value(s). + * + * @param mixed $value + * + * @return mixed + */ + public function reveal($value); +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Prophet.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Prophet.php new file mode 100644 index 00000000..ac649234 --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Prophet.php @@ -0,0 +1,134 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy; + +use Prophecy\Doubler\Doubler; +use Prophecy\Doubler\LazyDouble; +use Prophecy\Doubler\ClassPatch; +use Prophecy\Prophecy\ObjectProphecy; +use Prophecy\Prophecy\RevealerInterface; +use Prophecy\Prophecy\Revealer; +use Prophecy\Call\CallCenter; +use Prophecy\Util\StringUtil; +use Prophecy\Exception\Prediction\PredictionException; +use Prophecy\Exception\Prediction\AggregateException; + +/** + * Prophet creates prophecies. + * + * @author Konstantin Kudryashov + */ +class Prophet +{ + private $doubler; + private $revealer; + private $util; + + /** + * @var ObjectProphecy[] + */ + private $prophecies = array(); + + /** + * Initializes Prophet. + * + * @param null|Doubler $doubler + * @param null|RevealerInterface $revealer + * @param null|StringUtil $util + */ + public function __construct(Doubler $doubler = null, RevealerInterface $revealer = null, + StringUtil $util = null) + { + if (null === $doubler) { + $doubler = new Doubler; + $doubler->registerClassPatch(new ClassPatch\SplFileInfoPatch); + $doubler->registerClassPatch(new ClassPatch\TraversablePatch); + $doubler->registerClassPatch(new ClassPatch\DisableConstructorPatch); + $doubler->registerClassPatch(new ClassPatch\ProphecySubjectPatch); + $doubler->registerClassPatch(new ClassPatch\ReflectionClassNewInstancePatch); + $doubler->registerClassPatch(new ClassPatch\HhvmExceptionPatch()); + $doubler->registerClassPatch(new ClassPatch\MagicCallPatch); + $doubler->registerClassPatch(new ClassPatch\KeywordPatch); + } + + $this->doubler = $doubler; + $this->revealer = $revealer ?: new Revealer; + $this->util = $util ?: new StringUtil; + } + + /** + * Creates new object prophecy. + * + * @param null|string $classOrInterface Class or interface name + * + * @return ObjectProphecy + */ + public function prophesize($classOrInterface = null) + { + $this->prophecies[] = $prophecy = new ObjectProphecy( + new LazyDouble($this->doubler), + new CallCenter($this->util), + $this->revealer + ); + + if ($classOrInterface && class_exists($classOrInterface)) { + return $prophecy->willExtend($classOrInterface); + } + + if ($classOrInterface && interface_exists($classOrInterface)) { + return $prophecy->willImplement($classOrInterface); + } + + return $prophecy; + } + + /** + * Returns all created object prophecies. + * + * @return ObjectProphecy[] + */ + public function getProphecies() + { + return $this->prophecies; + } + + /** + * Returns Doubler instance assigned to this Prophet. + * + * @return Doubler + */ + public function getDoubler() + { + return $this->doubler; + } + + /** + * Checks all predictions defined by prophecies of this Prophet. + * + * @throws Exception\Prediction\AggregateException If any prediction fails + */ + public function checkPredictions() + { + $exception = new AggregateException("Some predictions failed:\n"); + foreach ($this->prophecies as $prophecy) { + try { + $prophecy->checkProphecyMethodsPredictions(); + } catch (PredictionException $e) { + $exception->append($e); + } + } + + if (count($exception->getExceptions())) { + throw $exception; + } + } +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Util/ExportUtil.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Util/ExportUtil.php new file mode 100644 index 00000000..49ed6a3f --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Util/ExportUtil.php @@ -0,0 +1,211 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * This class is a modification from sebastianbergmann/exporter + * @see https://github.com/sebastianbergmann/exporter + */ +class ExportUtil +{ + /** + * Exports a value as a string + * + * The output of this method is similar to the output of print_r(), but + * improved in various aspects: + * + * - NULL is rendered as "null" (instead of "") + * - TRUE is rendered as "true" (instead of "1") + * - FALSE is rendered as "false" (instead of "") + * - Strings are always quoted with single quotes + * - Carriage returns and newlines are normalized to \n + * - Recursion and repeated rendering is treated properly + * + * @param mixed $value + * @param int $indentation The indentation level of the 2nd+ line + * @return string + */ + public static function export($value, $indentation = 0) + { + return self::recursiveExport($value, $indentation); + } + + /** + * Converts an object to an array containing all of its private, protected + * and public properties. + * + * @param mixed $value + * @return array + */ + public static function toArray($value) + { + if (!is_object($value)) { + return (array) $value; + } + + $array = array(); + + foreach ((array) $value as $key => $val) { + // properties are transformed to keys in the following way: + // private $property => "\0Classname\0property" + // protected $property => "\0*\0property" + // public $property => "property" + if (preg_match('/^\0.+\0(.+)$/', $key, $matches)) { + $key = $matches[1]; + } + + // See https://github.com/php/php-src/commit/5721132 + if ($key === "\0gcdata") { + continue; + } + + $array[$key] = $val; + } + + // Some internal classes like SplObjectStorage don't work with the + // above (fast) mechanism nor with reflection in Zend. + // Format the output similarly to print_r() in this case + if ($value instanceof \SplObjectStorage) { + // However, the fast method does work in HHVM, and exposes the + // internal implementation. Hide it again. + if (property_exists('\SplObjectStorage', '__storage')) { + unset($array['__storage']); + } elseif (property_exists('\SplObjectStorage', 'storage')) { + unset($array['storage']); + } + + if (property_exists('\SplObjectStorage', '__key')) { + unset($array['__key']); + } + + foreach ($value as $key => $val) { + $array[spl_object_hash($val)] = array( + 'obj' => $val, + 'inf' => $value->getInfo(), + ); + } + } + + return $array; + } + + /** + * Recursive implementation of export + * + * @param mixed $value The value to export + * @param int $indentation The indentation level of the 2nd+ line + * @param \SebastianBergmann\RecursionContext\Context $processed Previously processed objects + * @return string + * @see SebastianBergmann\Exporter\Exporter::export + */ + protected static function recursiveExport(&$value, $indentation, $processed = null) + { + if ($value === null) { + return 'null'; + } + + if ($value === true) { + return 'true'; + } + + if ($value === false) { + return 'false'; + } + + if (is_float($value) && floatval(intval($value)) === $value) { + return "$value.0"; + } + + if (is_resource($value)) { + return sprintf( + 'resource(%d) of type (%s)', + $value, + get_resource_type($value) + ); + } + + if (is_string($value)) { + // Match for most non printable chars somewhat taking multibyte chars into account + if (preg_match('/[^\x09-\x0d\x20-\xff]/', $value)) { + return 'Binary String: 0x' . bin2hex($value); + } + + return "'" . + str_replace(array("\r\n", "\n\r", "\r"), array("\n", "\n", "\n"), $value) . + "'"; + } + + $whitespace = str_repeat(' ', 4 * $indentation); + + if (!$processed) { + $processed = new Context; + } + + if (is_array($value)) { + if (($key = $processed->contains($value)) !== false) { + return 'Array &' . $key; + } + + $key = $processed->add($value); + $values = ''; + + if (count($value) > 0) { + foreach ($value as $k => $v) { + $values .= sprintf( + '%s %s => %s' . "\n", + $whitespace, + self::recursiveExport($k, $indentation), + self::recursiveExport($value[$k], $indentation + 1, $processed) + ); + } + + $values = "\n" . $values . $whitespace; + } + + return sprintf('Array &%s (%s)', $key, $values); + } + + if (is_object($value)) { + $class = get_class($value); + + if ($value instanceof ProphecyInterface) { + return sprintf('%s Object (*Prophecy*)', $class); + } elseif ($hash = $processed->contains($value)) { + return sprintf('%s:%s Object', $class, $hash); + } + + $hash = $processed->add($value); + $values = ''; + $array = self::toArray($value); + + if (count($array) > 0) { + foreach ($array as $k => $v) { + $values .= sprintf( + '%s %s => %s' . "\n", + $whitespace, + self::recursiveExport($k, $indentation), + self::recursiveExport($v, $indentation + 1, $processed) + ); + } + + $values = "\n" . $values . $whitespace; + } + + return sprintf('%s:%s Object (%s)', $class, $hash, $values); + } + + return var_export($value, true); + } +} diff --git a/src/composer/vendor/phpspec/prophecy/src/Prophecy/Util/StringUtil.php b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Util/StringUtil.php new file mode 100644 index 00000000..bb90156a --- /dev/null +++ b/src/composer/vendor/phpspec/prophecy/src/Prophecy/Util/StringUtil.php @@ -0,0 +1,89 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Util; + +use Prophecy\Call\Call; + +/** + * String utility. + * + * @author Konstantin Kudryashov + */ +class StringUtil +{ + /** + * Stringifies any provided value. + * + * @param mixed $value + * @param boolean $exportObject + * + * @return string + */ + public function stringify($value, $exportObject = true) + { + if (is_array($value)) { + if (range(0, count($value) - 1) === array_keys($value)) { + return '['.implode(', ', array_map(array($this, __FUNCTION__), $value)).']'; + } + + $stringify = array($this, __FUNCTION__); + + return '['.implode(', ', array_map(function ($item, $key) use ($stringify) { + return (is_integer($key) ? $key : '"'.$key.'"'). + ' => '.call_user_func($stringify, $item); + }, $value, array_keys($value))).']'; + } + if (is_resource($value)) { + return get_resource_type($value).':'.$value; + } + if (is_object($value)) { + return $exportObject ? ExportUtil::export($value) : sprintf('%s:%s', get_class($value), spl_object_hash($value)); + } + if (true === $value || false === $value) { + return $value ? 'true' : 'false'; + } + if (is_string($value)) { + $str = sprintf('"%s"', str_replace("\n", '\\n', $value)); + + if (50 <= strlen($str)) { + return substr($str, 0, 50).'"...'; + } + + return $str; + } + if (null === $value) { + return 'null'; + } + + return (string) $value; + } + + /** + * Stringifies provided array of calls. + * + * @param Call[] $calls Array of Call instances + * + * @return string + */ + public function stringifyCalls(array $calls) + { + $self = $this; + + return implode(PHP_EOL, array_map(function (Call $call) use ($self) { + return sprintf(' - %s(%s) @ %s', + $call->getMethodName(), + implode(', ', array_map(array($self, 'stringify'), $call->getArguments())), + str_replace(GETCWD().DIRECTORY_SEPARATOR, '', $call->getCallPlace()) + ); + }, $calls)); + } +} diff --git a/src/composer/vendor/phpunit/php-code-coverage/.gitattributes b/src/composer/vendor/phpunit/php-code-coverage/.gitattributes new file mode 100644 index 00000000..461090b7 --- /dev/null +++ b/src/composer/vendor/phpunit/php-code-coverage/.gitattributes @@ -0,0 +1 @@ +*.php diff=php diff --git a/src/composer/vendor/phpunit/php-code-coverage/.gitignore b/src/composer/vendor/phpunit/php-code-coverage/.gitignore new file mode 100644 index 00000000..1f3de0e3 --- /dev/null +++ b/src/composer/vendor/phpunit/php-code-coverage/.gitignore @@ -0,0 +1,12 @@ +build/api +build/code-browser +build/coverage +build/logs +build/pdepend +cache.properties +/tests/_files/tmp +/vendor +/composer.lock +/composer.phar +/.idea +/.php_cs.cache diff --git a/src/composer/vendor/phpunit/php-code-coverage/.php_cs b/src/composer/vendor/phpunit/php-code-coverage/.php_cs new file mode 100644 index 00000000..de5cde18 --- /dev/null +++ b/src/composer/vendor/phpunit/php-code-coverage/.php_cs @@ -0,0 +1,69 @@ +files() + ->in('src') + ->in('tests') + ->exclude('_files') + ->name('*.php'); + +return Symfony\CS\Config\Config::create() + ->setUsingCache(true) + ->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', + 'lowercase_constants', + 'lowercase_keywords', + 'method_argument_space', + 'multiple_use', + 'namespace_no_leading_whitespace', + 'no_blank_lines_after_class_opening', + 'no_empty_lines_after_phpdocs', + 'parenthesis', + 'php_closing_tag', + 'phpdoc_indent', + 'phpdoc_no_access', + 'phpdoc_no_empty_return', + 'phpdoc_no_package', + 'phpdoc_params', + 'phpdoc_scalar', + 'phpdoc_separation', + 'phpdoc_to_comment', + 'phpdoc_trim', + 'phpdoc_types', + 'phpdoc_var_without_name', + 'remove_lines_between_uses', + 'return', + 'self_accessor', + 'short_array_syntax', + 'short_tag', + 'single_line_after_imports', + 'single_quote', + 'spaces_before_semicolon', + 'spaces_cast', + 'ternary_spaces', + 'trailing_spaces', + 'trim_array_spaces', + 'unused_use', + 'visibility', + 'whitespacy_lines' + ) + ) + ->finder($finder); + diff --git a/src/composer/vendor/phpunit/php-code-coverage/.travis.yml b/src/composer/vendor/phpunit/php-code-coverage/.travis.yml new file mode 100644 index 00000000..be89e194 --- /dev/null +++ b/src/composer/vendor/phpunit/php-code-coverage/.travis.yml @@ -0,0 +1,22 @@ +language: php + +php: + - 5.6 + - 7.0 + - nightly + +sudo: false + +before_install: + - composer self-update + +install: + - travis_retry composer install --no-interaction --prefer-source + +script: + + - vendor/bin/phpunit --configuration build + +notifications: + email: false + diff --git a/src/composer/vendor/phpunit/php-code-coverage/CONTRIBUTING.md b/src/composer/vendor/phpunit/php-code-coverage/CONTRIBUTING.md new file mode 100644 index 00000000..76a43458 --- /dev/null +++ b/src/composer/vendor/phpunit/php-code-coverage/CONTRIBUTING.md @@ -0,0 +1 @@ +Please refer to [https://github.com/sebastianbergmann/phpunit/blob/master/CONTRIBUTING.md](https://github.com/sebastianbergmann/phpunit/blob/master/CONTRIBUTING.md) for details on how to contribute to this project. diff --git a/src/composer/vendor/phpunit/php-code-coverage/ChangeLog-2.2.md b/src/composer/vendor/phpunit/php-code-coverage/ChangeLog-2.2.md new file mode 100644 index 00000000..353b6f65 --- /dev/null +++ b/src/composer/vendor/phpunit/php-code-coverage/ChangeLog-2.2.md @@ -0,0 +1,56 @@ +# Changes in PHP_CodeCoverage 2.2 + +All notable changes of the PHP_CodeCoverage 2.2 release series are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles. + +## [2.2.4] - 2015-10-06 + +### Fixed + +* Fixed [#391](https://github.com/sebastianbergmann/php-code-coverage/pull/391): Missing `` tag + +## [2.2.3] - 2015-09-14 + +### Fixed + +* Fixed [#368](https://github.com/sebastianbergmann/php-code-coverage/pull/368): Blacklists and whitelists are not merged when merging data sets +* Fixed [#370](https://github.com/sebastianbergmann/php-code-coverage/issues/370): Confusing statistics for source file that declares a class without methods +* Fixed [#372](https://github.com/sebastianbergmann/php-code-coverage/pull/372): Nested classes and functions are not handled correctly +* Fixed [#382](https://github.com/sebastianbergmann/php-code-coverage/issues/382): Crap4J report generates incorrect XML logfile + +## [2.2.2] - 2015-08-04 + +### Added + +* Reintroduced the `PHP_CodeCoverage_Driver_HHVM` driver as an extension of `PHP_CodeCoverage_Driver_Xdebug` that does not use `xdebug_start_code_coverage()` with options not supported by HHVM + +### Changed + +* Bumped required version of `sebastian/environment` to 1.3.2 for [#365](https://github.com/sebastianbergmann/php-code-coverage/issues/365) + +## [2.2.1] - 2015-08-02 + +### Changed + +* Bumped required version of `sebastian/environment` to 1.3.1 for [#365](https://github.com/sebastianbergmann/php-code-coverage/issues/365) + +## [2.2.0] - 2015-08-01 + +### Added + +* Added a driver for PHPDBG (requires PHP 7) +* Added `PHP_CodeCoverage::setDisableIgnoredLines()` to disable the ignoring of lines using annotations such as `@codeCoverageIgnore` + +### Changed + +* Annotating a method with `@deprecated` now has the same effect as annotating it with `@codeCoverageIgnore` + +### Removed + +* The dedicated driver for HHVM, `PHP_CodeCoverage_Driver_HHVM` has been removed + +[2.2.4]: https://github.com/sebastianbergmann/php-code-coverage/compare/2.2.3...2.2.4 +[2.2.3]: https://github.com/sebastianbergmann/php-code-coverage/compare/2.2.2...2.2.3 +[2.2.2]: https://github.com/sebastianbergmann/php-code-coverage/compare/2.2.1...2.2.2 +[2.2.1]: https://github.com/sebastianbergmann/php-code-coverage/compare/2.2.0...2.2.1 +[2.2.0]: https://github.com/sebastianbergmann/php-code-coverage/compare/2.1...2.2.0 + diff --git a/src/composer/vendor/phpunit/php-code-coverage/ChangeLog-3.0.md b/src/composer/vendor/phpunit/php-code-coverage/ChangeLog-3.0.md new file mode 100644 index 00000000..a39fa8d4 --- /dev/null +++ b/src/composer/vendor/phpunit/php-code-coverage/ChangeLog-3.0.md @@ -0,0 +1,31 @@ +# Changes in PHP_CodeCoverage 3.0 + +All notable changes of the PHP_CodeCoverage 3.0 release series are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles. + +## [3.0.2] - 2015-11-12 + +### Changed + +* It is now optional that `@deprecated` code is ignored + +## [3.0.1] - 2015-10-06 + +### Fixed + +* Fixed [#391](https://github.com/sebastianbergmann/php-code-coverage/pull/391): Missing `` tag + +## [3.0.0] - 2015-10-02 + +### Changed + +* It is now mandatory to configure a whitelist + +### Removed + +* The blacklist functionality has been removed +* PHP_CodeCoverage is no longer supported on PHP 5.3, PHP 5.4, and PHP 5.5 + +[3.0.2]: https://github.com/sebastianbergmann/php-code-coverage/compare/3.0.1...3.0.2 +[3.0.1]: https://github.com/sebastianbergmann/php-code-coverage/compare/3.0.0...3.0.1 +[3.0.0]: https://github.com/sebastianbergmann/php-code-coverage/compare/2.2...3.0.0 + diff --git a/src/composer/vendor/phpunit/php-code-coverage/ChangeLog-3.1.md b/src/composer/vendor/phpunit/php-code-coverage/ChangeLog-3.1.md new file mode 100644 index 00000000..f7a0de90 --- /dev/null +++ b/src/composer/vendor/phpunit/php-code-coverage/ChangeLog-3.1.md @@ -0,0 +1,30 @@ +# Changes in PHP_CodeCoverage 3.1 + +All notable changes of the PHP_CodeCoverage 3.1 release series are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles. + +## [3.1.1] - 2016-02-04 + +### Changed + +* Allow version 2.0.x of `sebastian/version` dependency + +## [3.1.0] - 2016-01-11 + +### Added + +* Implemented [#234](https://github.com/sebastianbergmann/php-code-coverage/issues/234): Optionally raise an exception when a specified unit of code is not executed + +### Changed + +* The Clover XML report now contains cyclomatic complexity information +* The Clover XML report now contains method visibility information +* Cleanup and refactoring of various areas of code +* Added missing test cases + +### Removed + +* The functionality controlled by the `mapTestClassNameToCoveredClassName` setting has been removed + +[3.1.1]: https://github.com/sebastianbergmann/php-code-coverage/compare/3.1.0...3.1.1 +[3.1.0]: https://github.com/sebastianbergmann/php-code-coverage/compare/3.0...3.1.0 + diff --git a/src/composer/vendor/phpunit/php-code-coverage/ChangeLog-3.2.md b/src/composer/vendor/phpunit/php-code-coverage/ChangeLog-3.2.md new file mode 100644 index 00000000..34c65cf4 --- /dev/null +++ b/src/composer/vendor/phpunit/php-code-coverage/ChangeLog-3.2.md @@ -0,0 +1,23 @@ +# Changes in PHP_CodeCoverage 3.2 + +All notable changes of the PHP_CodeCoverage 3.2 release series are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles. + +## [3.2.1] - 2016-02-18 + +### Changed + +* Updated dependency information in `composer.json` + +## [3.2.0] - 2016-02-13 + +### Added + +* Added optional check for missing `@covers` annotation when the usage of `@covers` annotations is forced + +### Changed + +* Improved `PHP_CodeCoverage_UnintentionallyCoveredCodeException` message + +[3.2.1]: https://github.com/sebastianbergmann/php-code-coverage/compare/3.2.0...3.2.1 +[3.2.0]: https://github.com/sebastianbergmann/php-code-coverage/compare/3.1...3.2.0 + diff --git a/src/composer/vendor/phpunit/php-code-coverage/ChangeLog-3.3.md b/src/composer/vendor/phpunit/php-code-coverage/ChangeLog-3.3.md new file mode 100644 index 00000000..2cf15229 --- /dev/null +++ b/src/composer/vendor/phpunit/php-code-coverage/ChangeLog-3.3.md @@ -0,0 +1,33 @@ +# Changes in PHP_CodeCoverage 3.3 + +All notable changes of the PHP_CodeCoverage 3.3 release series are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles. + +## [3.3.3] - 2016-MM-DD + +### Fixed + +* Fixed [#438](https://github.com/sebastianbergmann/php-code-coverage/issues/438): Wrong base directory for Clover reports + +## [3.3.2] - 2016-05-25 + +### Changed + +* The constructor of `PHP_CodeCoverage_Report_Text` now has default values for its parameters + +## [3.3.1] - 2016-04-08 + +### Fixed + +* Fixed handling of lines that contain `declare` statements + +## [3.3.0] - 2016-03-03 + +### Added + +* Added support for whitelisting classes for the unintentionally covered code unit check + +[3.3.3]: https://github.com/sebastianbergmann/php-code-coverage/compare/3.3.2...3.3.3 +[3.3.2]: https://github.com/sebastianbergmann/php-code-coverage/compare/3.3.1...3.3.2 +[3.3.1]: https://github.com/sebastianbergmann/php-code-coverage/compare/3.3.0...3.3.1 +[3.3.0]: https://github.com/sebastianbergmann/php-code-coverage/compare/3.2...3.3.0 + diff --git a/src/composer/vendor/phpunit/php-code-coverage/ChangeLog-4.0.md b/src/composer/vendor/phpunit/php-code-coverage/ChangeLog-4.0.md new file mode 100644 index 00000000..b085d46b --- /dev/null +++ b/src/composer/vendor/phpunit/php-code-coverage/ChangeLog-4.0.md @@ -0,0 +1,26 @@ +# Changes in PHP_CodeCoverage 4.0 + +All notable changes of the PHP_CodeCoverage 4.0 release series are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles. + +## [4.0.2] - 2016-11-01 + +### Fixed + +* Fixed [#440](https://github.com/sebastianbergmann/php-code-coverage/pull/440): Dashboard charts not showing tooltips for data points + +## [4.0.1] - 2016-07-26 + +### Fixed + +* Fixed [#458](https://github.com/sebastianbergmann/php-code-coverage/pull/458): XML report does not know about warning status + +## [4.0.0] - 2016-06-03 + +### Changed + +* This component now uses namespaces + +[4.0.2]: https://github.com/sebastianbergmann/php-code-coverage/compare/4.0.1...4.0.2 +[4.0.1]: https://github.com/sebastianbergmann/php-code-coverage/compare/4.0.0...4.0.1 +[4.0.0]: https://github.com/sebastianbergmann/php-code-coverage/compare/3.3...4.0.0 + diff --git a/src/composer/vendor/phpunit/php-code-coverage/LICENSE b/src/composer/vendor/phpunit/php-code-coverage/LICENSE new file mode 100644 index 00000000..fcfa37e8 --- /dev/null +++ b/src/composer/vendor/phpunit/php-code-coverage/LICENSE @@ -0,0 +1,33 @@ +PHP_CodeCoverage + +Copyright (c) 2009-2015, Sebastian Bergmann . +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + * Neither the name of Sebastian Bergmann nor the names of his + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. diff --git a/src/composer/vendor/phpunit/php-code-coverage/README.md b/src/composer/vendor/phpunit/php-code-coverage/README.md new file mode 100644 index 00000000..c01384b8 --- /dev/null +++ b/src/composer/vendor/phpunit/php-code-coverage/README.md @@ -0,0 +1,51 @@ +[![Latest Stable Version](https://poser.pugx.org/phpunit/php-code-coverage/v/stable.png)](https://packagist.org/packages/phpunit/php-code-coverage) +[![Build Status](https://travis-ci.org/sebastianbergmann/php-code-coverage.svg?branch=master)](https://travis-ci.org/sebastianbergmann/php-code-coverage) + +# PHP_CodeCoverage + +**PHP_CodeCoverage** is a library that provides collection, processing, and rendering functionality for PHP code coverage information. + +## Requirements + +PHP 5.6 is required but using the latest version of PHP is highly recommended. + +### PHP 5 + +[Xdebug](http://xdebug.org/) is the only source of raw code coverage data supported for PHP 5. Version 2.2.1 of Xdebug is required but using the latest version is highly recommended. + +### PHP 7 + +Version 2.4.0 (or later) of [Xdebug](http://xdebug.org/) as well as [phpdbg](http://phpdbg.com/docs) are supported sources of raw code coverage data for PHP 7. + +### HHVM + +A version of HHVM that implements the Xdebug API for code coverage (`xdebug_*_code_coverage()`) is required. + +## Installation + +You can add this library as a local, per-project dependency to your project using [Composer](https://getcomposer.org/): + + composer require phpunit/php-code-coverage + +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 phpunit/php-code-coverage + +## Using the PHP_CodeCoverage API + +```php +start(''); + +// ... + +$coverage->stop(); + +$writer = new \SebastianBergmann\CodeCoverage\Report\Clover; +$writer->process($coverage, '/tmp/clover.xml'); + +$writer = new \SebastianBergmann\CodeCoverage\Report\Html\Facade; +$writer->process($coverage, '/tmp/code-coverage-report'); +``` + diff --git a/src/composer/vendor/phpunit/php-code-coverage/build.xml b/src/composer/vendor/phpunit/php-code-coverage/build.xml new file mode 100644 index 00000000..c335d158 --- /dev/null +++ b/src/composer/vendor/phpunit/php-code-coverage/build.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/composer/vendor/phpunit/php-code-coverage/build/phpunit.xml b/src/composer/vendor/phpunit/php-code-coverage/build/phpunit.xml new file mode 100644 index 00000000..fa15d5d4 --- /dev/null +++ b/src/composer/vendor/phpunit/php-code-coverage/build/phpunit.xml @@ -0,0 +1,16 @@ + + + + ../tests/tests + + + + + ../src + + + diff --git a/src/composer/vendor/phpunit/php-code-coverage/composer.json b/src/composer/vendor/phpunit/php-code-coverage/composer.json new file mode 100644 index 00000000..2dc52d82 --- /dev/null +++ b/src/composer/vendor/phpunit/php-code-coverage/composer.json @@ -0,0 +1,51 @@ +{ + "name": "phpunit/php-code-coverage", + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "type": "library", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "license": "BSD-3-Clause", + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", + "irc": "irc://irc.freenode.net/phpunit" + }, + "require": { + "php": "^5.6 || ^7.0", + "phpunit/php-file-iterator": "~1.3", + "phpunit/php-token-stream": "^1.4.2", + "phpunit/php-text-template": "~1.2", + "sebastian/code-unit-reverse-lookup": "~1.0", + "sebastian/environment": "^1.3.2 || ^2.0", + "sebastian/version": "~1.0|~2.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.4", + "ext-xdebug": ">=2.1.4" + }, + "suggest": { + "ext-dom": "*", + "ext-xdebug": ">=2.4.0", + "ext-xmlwriter": "*" + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "extra": { + "branch-alias": { + "dev-master": "4.0.x-dev" + } + } +} diff --git a/src/composer/vendor/phpunit/php-code-coverage/src/CodeCoverage.php b/src/composer/vendor/phpunit/php-code-coverage/src/CodeCoverage.php new file mode 100644 index 00000000..49332e34 --- /dev/null +++ b/src/composer/vendor/phpunit/php-code-coverage/src/CodeCoverage.php @@ -0,0 +1,1105 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SebastianBergmann\CodeCoverage; + +use SebastianBergmann\CodeCoverage\Driver\Driver; +use SebastianBergmann\CodeCoverage\Driver\Xdebug; +use SebastianBergmann\CodeCoverage\Driver\HHVM; +use SebastianBergmann\CodeCoverage\Driver\PHPDBG; +use SebastianBergmann\CodeCoverage\Node\Builder; +use SebastianBergmann\CodeCoverage\Node\Directory; +use SebastianBergmann\CodeUnitReverseLookup\Wizard; +use SebastianBergmann\Environment\Runtime; + +/** + * Provides collection functionality for PHP code coverage information. + */ +class CodeCoverage +{ + /** + * @var Driver + */ + private $driver; + + /** + * @var Filter + */ + private $filter; + + /** + * @var Wizard + */ + private $wizard; + + /** + * @var bool + */ + private $cacheTokens = false; + + /** + * @var bool + */ + private $checkForUnintentionallyCoveredCode = false; + + /** + * @var bool + */ + private $forceCoversAnnotation = false; + + /** + * @var bool + */ + private $checkForUnexecutedCoveredCode = false; + + /** + * @var bool + */ + private $checkForMissingCoversAnnotation = false; + + /** + * @var bool + */ + private $addUncoveredFilesFromWhitelist = true; + + /** + * @var bool + */ + private $processUncoveredFilesFromWhitelist = false; + + /** + * @var bool + */ + private $ignoreDeprecatedCode = false; + + /** + * @var mixed + */ + private $currentId; + + /** + * Code coverage data. + * + * @var array + */ + private $data = []; + + /** + * @var array + */ + private $ignoredLines = []; + + /** + * @var bool + */ + private $disableIgnoredLines = false; + + /** + * Test data. + * + * @var array + */ + private $tests = []; + + /** + * @var string[] + */ + private $unintentionallyCoveredSubclassesWhitelist = []; + + /** + * Determine if the data has been initialized or not + * + * @var bool + */ + private $isInitialized = false; + + /** + * Determine whether we need to check for dead and unused code on each test + * + * @var bool + */ + private $shouldCheckForDeadAndUnused = true; + + /** + * Constructor. + * + * @param Driver $driver + * @param Filter $filter + * + * @throws RuntimeException + */ + public function __construct(Driver $driver = null, Filter $filter = null) + { + if ($driver === null) { + $driver = $this->selectDriver(); + } + + if ($filter === null) { + $filter = new Filter; + } + + $this->driver = $driver; + $this->filter = $filter; + + $this->wizard = new Wizard; + } + + /** + * Returns the code coverage information as a graph of node objects. + * + * @return Directory + */ + public function getReport() + { + $builder = new Builder; + + return $builder->build($this); + } + + /** + * Clears collected code coverage data. + */ + public function clear() + { + $this->isInitialized = false; + $this->currentId = null; + $this->data = []; + $this->tests = []; + } + + /** + * Returns the filter object used. + * + * @return Filter + */ + public function filter() + { + return $this->filter; + } + + /** + * Returns the collected code coverage data. + * Set $raw = true to bypass all filters. + * + * @param bool $raw + * + * @return array + */ + public function getData($raw = false) + { + if (!$raw && $this->addUncoveredFilesFromWhitelist) { + $this->addUncoveredFilesFromWhitelist(); + } + + return $this->data; + } + + /** + * Sets the coverage data. + * + * @param array $data + */ + public function setData(array $data) + { + $this->data = $data; + } + + /** + * Returns the test data. + * + * @return array + */ + public function getTests() + { + return $this->tests; + } + + /** + * Sets the test data. + * + * @param array $tests + */ + public function setTests(array $tests) + { + $this->tests = $tests; + } + + /** + * Start collection of code coverage information. + * + * @param mixed $id + * @param bool $clear + * + * @throws InvalidArgumentException + */ + public function start($id, $clear = false) + { + if (!is_bool($clear)) { + throw InvalidArgumentException::create( + 1, + 'boolean' + ); + } + + if ($clear) { + $this->clear(); + } + + if ($this->isInitialized === false) { + $this->initializeData(); + } + + $this->currentId = $id; + + $this->driver->start($this->shouldCheckForDeadAndUnused); + } + + /** + * Stop collection of code coverage information. + * + * @param bool $append + * @param mixed $linesToBeCovered + * @param array $linesToBeUsed + * + * @return array + * + * @throws InvalidArgumentException + */ + public function stop($append = true, $linesToBeCovered = [], array $linesToBeUsed = []) + { + if (!is_bool($append)) { + throw InvalidArgumentException::create( + 1, + 'boolean' + ); + } + + if (!is_array($linesToBeCovered) && $linesToBeCovered !== false) { + throw InvalidArgumentException::create( + 2, + 'array or false' + ); + } + + $data = $this->driver->stop(); + $this->append($data, null, $append, $linesToBeCovered, $linesToBeUsed); + + $this->currentId = null; + + return $data; + } + + /** + * Appends code coverage data. + * + * @param array $data + * @param mixed $id + * @param bool $append + * @param mixed $linesToBeCovered + * @param array $linesToBeUsed + * + * @throws RuntimeException + */ + public function append(array $data, $id = null, $append = true, $linesToBeCovered = [], array $linesToBeUsed = []) + { + if ($id === null) { + $id = $this->currentId; + } + + if ($id === null) { + throw new RuntimeException; + } + + $this->applyListsFilter($data); + $this->applyIgnoredLinesFilter($data); + $this->initializeFilesThatAreSeenTheFirstTime($data); + + if (!$append) { + return; + } + + if ($id != 'UNCOVERED_FILES_FROM_WHITELIST') { + $this->applyCoversAnnotationFilter( + $data, + $linesToBeCovered, + $linesToBeUsed + ); + } + + if (empty($data)) { + return; + } + + $size = 'unknown'; + $status = null; + + if ($id instanceof \PHPUnit_Framework_TestCase) { + $_size = $id->getSize(); + + if ($_size == \PHPUnit_Util_Test::SMALL) { + $size = 'small'; + } elseif ($_size == \PHPUnit_Util_Test::MEDIUM) { + $size = 'medium'; + } elseif ($_size == \PHPUnit_Util_Test::LARGE) { + $size = 'large'; + } + + $status = $id->getStatus(); + $id = get_class($id) . '::' . $id->getName(); + } elseif ($id instanceof \PHPUnit_Extensions_PhptTestCase) { + $size = 'large'; + $id = $id->getName(); + } + + $this->tests[$id] = ['size' => $size, 'status' => $status]; + + foreach ($data as $file => $lines) { + if (!$this->filter->isFile($file)) { + continue; + } + + foreach ($lines as $k => $v) { + if ($v == Driver::LINE_EXECUTED) { + if (empty($this->data[$file][$k]) || !in_array($id, $this->data[$file][$k])) { + $this->data[$file][$k][] = $id; + } + } + } + } + } + + /** + * Merges the data from another instance. + * + * @param CodeCoverage $that + */ + public function merge(CodeCoverage $that) + { + $this->filter->setWhitelistedFiles( + array_merge($this->filter->getWhitelistedFiles(), $that->filter()->getWhitelistedFiles()) + ); + + foreach ($that->data as $file => $lines) { + if (!isset($this->data[$file])) { + if (!$this->filter->isFiltered($file)) { + $this->data[$file] = $lines; + } + + continue; + } + + foreach ($lines as $line => $data) { + if ($data !== null) { + if (!isset($this->data[$file][$line])) { + $this->data[$file][$line] = $data; + } else { + $this->data[$file][$line] = array_unique( + array_merge($this->data[$file][$line], $data) + ); + } + } + } + } + + $this->tests = array_merge($this->tests, $that->getTests()); + } + + /** + * @param bool $flag + * + * @throws InvalidArgumentException + */ + public function setCacheTokens($flag) + { + if (!is_bool($flag)) { + throw InvalidArgumentException::create( + 1, + 'boolean' + ); + } + + $this->cacheTokens = $flag; + } + + /** + * @return bool + */ + public function getCacheTokens() + { + return $this->cacheTokens; + } + + /** + * @param bool $flag + * + * @throws InvalidArgumentException + */ + public function setCheckForUnintentionallyCoveredCode($flag) + { + if (!is_bool($flag)) { + throw InvalidArgumentException::create( + 1, + 'boolean' + ); + } + + $this->checkForUnintentionallyCoveredCode = $flag; + } + + /** + * @param bool $flag + * + * @throws InvalidArgumentException + */ + public function setForceCoversAnnotation($flag) + { + if (!is_bool($flag)) { + throw InvalidArgumentException::create( + 1, + 'boolean' + ); + } + + $this->forceCoversAnnotation = $flag; + } + + /** + * @param bool $flag + * + * @throws InvalidArgumentException + */ + public function setCheckForMissingCoversAnnotation($flag) + { + if (!is_bool($flag)) { + throw InvalidArgumentException::create( + 1, + 'boolean' + ); + } + + $this->checkForMissingCoversAnnotation = $flag; + } + + /** + * @param bool $flag + * + * @throws InvalidArgumentException + */ + public function setCheckForUnexecutedCoveredCode($flag) + { + if (!is_bool($flag)) { + throw InvalidArgumentException::create( + 1, + 'boolean' + ); + } + + $this->checkForUnexecutedCoveredCode = $flag; + } + + /** + * @deprecated + * + * @param bool $flag + * + * @throws InvalidArgumentException + */ + public function setMapTestClassNameToCoveredClassName($flag) + { + } + + /** + * @param bool $flag + * + * @throws InvalidArgumentException + */ + public function setAddUncoveredFilesFromWhitelist($flag) + { + if (!is_bool($flag)) { + throw InvalidArgumentException::create( + 1, + 'boolean' + ); + } + + $this->addUncoveredFilesFromWhitelist = $flag; + } + + /** + * @param bool $flag + * + * @throws InvalidArgumentException + */ + public function setProcessUncoveredFilesFromWhitelist($flag) + { + if (!is_bool($flag)) { + throw InvalidArgumentException::create( + 1, + 'boolean' + ); + } + + $this->processUncoveredFilesFromWhitelist = $flag; + } + + /** + * @param bool $flag + * + * @throws InvalidArgumentException + */ + public function setDisableIgnoredLines($flag) + { + if (!is_bool($flag)) { + throw InvalidArgumentException::create( + 1, + 'boolean' + ); + } + + $this->disableIgnoredLines = $flag; + } + + /** + * @param bool $flag + * + * @throws InvalidArgumentException + */ + public function setIgnoreDeprecatedCode($flag) + { + if (!is_bool($flag)) { + throw InvalidArgumentException::create( + 1, + 'boolean' + ); + } + + $this->ignoreDeprecatedCode = $flag; + } + + /** + * @param array $whitelist + */ + public function setUnintentionallyCoveredSubclassesWhitelist(array $whitelist) + { + $this->unintentionallyCoveredSubclassesWhitelist = $whitelist; + } + + /** + * Applies the @covers annotation filtering. + * + * @param array $data + * @param mixed $linesToBeCovered + * @param array $linesToBeUsed + * + * @throws MissingCoversAnnotationException + * @throws UnintentionallyCoveredCodeException + */ + private function applyCoversAnnotationFilter(array &$data, $linesToBeCovered, array $linesToBeUsed) + { + if ($linesToBeCovered === false || + ($this->forceCoversAnnotation && empty($linesToBeCovered))) { + if ($this->checkForMissingCoversAnnotation) { + throw new MissingCoversAnnotationException; + } + + $data = []; + + return; + } + + if (empty($linesToBeCovered)) { + return; + } + + if ($this->checkForUnintentionallyCoveredCode) { + $this->performUnintentionallyCoveredCodeCheck( + $data, + $linesToBeCovered, + $linesToBeUsed + ); + } + + if ($this->checkForUnexecutedCoveredCode) { + $this->performUnexecutedCoveredCodeCheck($data, $linesToBeCovered, $linesToBeUsed); + } + + $data = array_intersect_key($data, $linesToBeCovered); + + foreach (array_keys($data) as $filename) { + $_linesToBeCovered = array_flip($linesToBeCovered[$filename]); + + $data[$filename] = array_intersect_key( + $data[$filename], + $_linesToBeCovered + ); + } + } + + /** + * Applies the whitelist filtering. + * + * @param array $data + */ + private function applyListsFilter(array &$data) + { + foreach (array_keys($data) as $filename) { + if ($this->filter->isFiltered($filename)) { + unset($data[$filename]); + } + } + } + + /** + * Applies the "ignored lines" filtering. + * + * @param array $data + */ + private function applyIgnoredLinesFilter(array &$data) + { + foreach (array_keys($data) as $filename) { + if (!$this->filter->isFile($filename)) { + continue; + } + + foreach ($this->getLinesToBeIgnored($filename) as $line) { + unset($data[$filename][$line]); + } + } + } + + /** + * @param array $data + */ + private function initializeFilesThatAreSeenTheFirstTime(array $data) + { + foreach ($data as $file => $lines) { + if ($this->filter->isFile($file) && !isset($this->data[$file])) { + $this->data[$file] = []; + + foreach ($lines as $k => $v) { + $this->data[$file][$k] = $v == -2 ? null : []; + } + } + } + } + + /** + * Processes whitelisted files that are not covered. + */ + private function addUncoveredFilesFromWhitelist() + { + $data = []; + $uncoveredFiles = array_diff( + $this->filter->getWhitelist(), + array_keys($this->data) + ); + + foreach ($uncoveredFiles as $uncoveredFile) { + if (!file_exists($uncoveredFile)) { + continue; + } + + if (!$this->processUncoveredFilesFromWhitelist) { + $data[$uncoveredFile] = []; + + $lines = count(file($uncoveredFile)); + + for ($i = 1; $i <= $lines; $i++) { + $data[$uncoveredFile][$i] = Driver::LINE_NOT_EXECUTED; + } + } + } + + $this->append($data, 'UNCOVERED_FILES_FROM_WHITELIST'); + } + + /** + * Returns the lines of a source file that should be ignored. + * + * @param string $filename + * + * @return array + * + * @throws InvalidArgumentException + */ + private function getLinesToBeIgnored($filename) + { + if (!is_string($filename)) { + throw InvalidArgumentException::create( + 1, + 'string' + ); + } + + if (!isset($this->ignoredLines[$filename])) { + $this->ignoredLines[$filename] = []; + + if ($this->disableIgnoredLines) { + return $this->ignoredLines[$filename]; + } + + $ignore = false; + $stop = false; + $lines = file($filename); + $numLines = count($lines); + + foreach ($lines as $index => $line) { + if (!trim($line)) { + $this->ignoredLines[$filename][] = $index + 1; + } + } + + if ($this->cacheTokens) { + $tokens = \PHP_Token_Stream_CachingFactory::get($filename); + } else { + $tokens = new \PHP_Token_Stream($filename); + } + + $classes = array_merge($tokens->getClasses(), $tokens->getTraits()); + $tokens = $tokens->tokens(); + + foreach ($tokens as $token) { + switch (get_class($token)) { + case 'PHP_Token_COMMENT': + case 'PHP_Token_DOC_COMMENT': + $_token = trim($token); + $_line = trim($lines[$token->getLine() - 1]); + + if ($_token == '// @codeCoverageIgnore' || + $_token == '//@codeCoverageIgnore') { + $ignore = true; + $stop = true; + } elseif ($_token == '// @codeCoverageIgnoreStart' || + $_token == '//@codeCoverageIgnoreStart') { + $ignore = true; + } elseif ($_token == '// @codeCoverageIgnoreEnd' || + $_token == '//@codeCoverageIgnoreEnd') { + $stop = true; + } + + if (!$ignore) { + $start = $token->getLine(); + $end = $start + substr_count($token, "\n"); + + // Do not ignore the first line when there is a token + // before the comment + if (0 !== strpos($_token, $_line)) { + $start++; + } + + for ($i = $start; $i < $end; $i++) { + $this->ignoredLines[$filename][] = $i; + } + + // A DOC_COMMENT token or a COMMENT token starting with "/*" + // does not contain the final \n character in its text + if (isset($lines[$i-1]) && 0 === strpos($_token, '/*') && '*/' === substr(trim($lines[$i-1]), -2)) { + $this->ignoredLines[$filename][] = $i; + } + } + break; + + case 'PHP_Token_INTERFACE': + case 'PHP_Token_TRAIT': + case 'PHP_Token_CLASS': + case 'PHP_Token_FUNCTION': + /* @var \PHP_Token_Interface $token */ + + $docblock = $token->getDocblock(); + + $this->ignoredLines[$filename][] = $token->getLine(); + + if (strpos($docblock, '@codeCoverageIgnore') || ($this->ignoreDeprecatedCode && strpos($docblock, '@deprecated'))) { + $endLine = $token->getEndLine(); + + for ($i = $token->getLine(); $i <= $endLine; $i++) { + $this->ignoredLines[$filename][] = $i; + } + } elseif ($token instanceof \PHP_Token_INTERFACE || + $token instanceof \PHP_Token_TRAIT || + $token instanceof \PHP_Token_CLASS) { + if (empty($classes[$token->getName()]['methods'])) { + for ($i = $token->getLine(); + $i <= $token->getEndLine(); + $i++) { + $this->ignoredLines[$filename][] = $i; + } + } else { + $firstMethod = array_shift( + $classes[$token->getName()]['methods'] + ); + + do { + $lastMethod = array_pop( + $classes[$token->getName()]['methods'] + ); + } while ($lastMethod !== null && + substr($lastMethod['signature'], 0, 18) == 'anonymous function'); + + if ($lastMethod === null) { + $lastMethod = $firstMethod; + } + + for ($i = $token->getLine(); + $i < $firstMethod['startLine']; + $i++) { + $this->ignoredLines[$filename][] = $i; + } + + for ($i = $token->getEndLine(); + $i > $lastMethod['endLine']; + $i--) { + $this->ignoredLines[$filename][] = $i; + } + } + } + break; + + case 'PHP_Token_NAMESPACE': + $this->ignoredLines[$filename][] = $token->getEndLine(); + + // Intentional fallthrough + case 'PHP_Token_DECLARE': + case 'PHP_Token_OPEN_TAG': + case 'PHP_Token_CLOSE_TAG': + case 'PHP_Token_USE': + $this->ignoredLines[$filename][] = $token->getLine(); + break; + } + + if ($ignore) { + $this->ignoredLines[$filename][] = $token->getLine(); + + if ($stop) { + $ignore = false; + $stop = false; + } + } + } + + $this->ignoredLines[$filename][] = $numLines + 1; + + $this->ignoredLines[$filename] = array_unique( + $this->ignoredLines[$filename] + ); + + sort($this->ignoredLines[$filename]); + } + + return $this->ignoredLines[$filename]; + } + + /** + * @param array $data + * @param array $linesToBeCovered + * @param array $linesToBeUsed + * + * @throws UnintentionallyCoveredCodeException + */ + private function performUnintentionallyCoveredCodeCheck(array &$data, array $linesToBeCovered, array $linesToBeUsed) + { + $allowedLines = $this->getAllowedLines( + $linesToBeCovered, + $linesToBeUsed + ); + + $unintentionallyCoveredUnits = []; + + foreach ($data as $file => $_data) { + foreach ($_data as $line => $flag) { + if ($flag == 1 && !isset($allowedLines[$file][$line])) { + $unintentionallyCoveredUnits[] = $this->wizard->lookup($file, $line); + } + } + } + + $unintentionallyCoveredUnits = $this->processUnintentionallyCoveredUnits($unintentionallyCoveredUnits); + + if (!empty($unintentionallyCoveredUnits)) { + throw new UnintentionallyCoveredCodeException( + $unintentionallyCoveredUnits + ); + } + } + + /** + * @param array $data + * @param array $linesToBeCovered + * @param array $linesToBeUsed + * + * @throws CoveredCodeNotExecutedException + */ + private function performUnexecutedCoveredCodeCheck(array &$data, array $linesToBeCovered, array $linesToBeUsed) + { + $expectedLines = $this->getAllowedLines( + $linesToBeCovered, + $linesToBeUsed + ); + + foreach ($data as $file => $_data) { + foreach (array_keys($_data) as $line) { + if (!isset($expectedLines[$file][$line])) { + continue; + } + + unset($expectedLines[$file][$line]); + } + } + + $message = ''; + + foreach ($expectedLines as $file => $lines) { + if (empty($lines)) { + continue; + } + + foreach (array_keys($lines) as $line) { + $message .= sprintf('- %s:%d' . PHP_EOL, $file, $line); + } + } + + if (!empty($message)) { + throw new CoveredCodeNotExecutedException($message); + } + } + + /** + * @param array $linesToBeCovered + * @param array $linesToBeUsed + * + * @return array + */ + private function getAllowedLines(array $linesToBeCovered, array $linesToBeUsed) + { + $allowedLines = []; + + foreach (array_keys($linesToBeCovered) as $file) { + if (!isset($allowedLines[$file])) { + $allowedLines[$file] = []; + } + + $allowedLines[$file] = array_merge( + $allowedLines[$file], + $linesToBeCovered[$file] + ); + } + + foreach (array_keys($linesToBeUsed) as $file) { + if (!isset($allowedLines[$file])) { + $allowedLines[$file] = []; + } + + $allowedLines[$file] = array_merge( + $allowedLines[$file], + $linesToBeUsed[$file] + ); + } + + foreach (array_keys($allowedLines) as $file) { + $allowedLines[$file] = array_flip( + array_unique($allowedLines[$file]) + ); + } + + return $allowedLines; + } + + /** + * @return Driver + * + * @throws RuntimeException + */ + private function selectDriver() + { + $runtime = new Runtime; + + if (!$runtime->canCollectCodeCoverage()) { + throw new RuntimeException('No code coverage driver available'); + } + + if ($runtime->isHHVM()) { + return new HHVM; + } elseif ($runtime->isPHPDBG()) { + return new PHPDBG; + } else { + return new Xdebug; + } + } + + /** + * @param array $unintentionallyCoveredUnits + * + * @return array + */ + private function processUnintentionallyCoveredUnits(array $unintentionallyCoveredUnits) + { + $unintentionallyCoveredUnits = array_unique($unintentionallyCoveredUnits); + sort($unintentionallyCoveredUnits); + + foreach (array_keys($unintentionallyCoveredUnits) as $k => $v) { + $unit = explode('::', $unintentionallyCoveredUnits[$k]); + + if (count($unit) != 2) { + continue; + } + + $class = new \ReflectionClass($unit[0]); + + foreach ($this->unintentionallyCoveredSubclassesWhitelist as $whitelisted) { + if ($class->isSubclassOf($whitelisted)) { + unset($unintentionallyCoveredUnits[$k]); + break; + } + } + } + + return array_values($unintentionallyCoveredUnits); + } + + /** + * If we are processing uncovered files from whitelist, + * we can initialize the data before we start to speed up the tests + */ + protected function initializeData() + { + $this->isInitialized = true; + + if ($this->processUncoveredFilesFromWhitelist) { + $this->shouldCheckForDeadAndUnused = false; + + $this->driver->start(true); + + foreach ($this->filter->getWhitelist() as $file) { + if ($this->filter->isFile($file)) { + include_once($file); + } + } + + $data = []; + $coverage = $this->driver->stop(); + + foreach ($coverage as $file => $fileCoverage) { + if ($this->filter->isFiltered($file)) { + continue; + } + + foreach (array_keys($fileCoverage) as $key) { + if ($fileCoverage[$key] == Driver::LINE_EXECUTED) { + $fileCoverage[$key] = Driver::LINE_NOT_EXECUTED; + } + } + + $data[$file] = $fileCoverage; + } + + $this->append($data, 'UNCOVERED_FILES_FROM_WHITELIST'); + } + } +} diff --git a/src/composer/vendor/phpunit/php-code-coverage/src/Driver/Driver.php b/src/composer/vendor/phpunit/php-code-coverage/src/Driver/Driver.php new file mode 100644 index 00000000..bdd1b979 --- /dev/null +++ b/src/composer/vendor/phpunit/php-code-coverage/src/Driver/Driver.php @@ -0,0 +1,52 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SebastianBergmann\CodeCoverage\Driver; + +/** + * Interface for code coverage drivers. + */ +interface Driver +{ + /** + * @var int + * + * @see http://xdebug.org/docs/code_coverage + */ + const LINE_EXECUTED = 1; + + /** + * @var int + * + * @see http://xdebug.org/docs/code_coverage + */ + const LINE_NOT_EXECUTED = -1; + + /** + * @var int + * + * @see http://xdebug.org/docs/code_coverage + */ + const LINE_NOT_EXECUTABLE = -2; + + /** + * Start collection of code coverage information. + * + * @param bool $determineUnusedAndDead + */ + public function start($determineUnusedAndDead = true); + + /** + * Stop collection of code coverage information. + * + * @return array + */ + public function stop(); +} diff --git a/src/composer/vendor/phpunit/php-code-coverage/src/Driver/HHVM.php b/src/composer/vendor/phpunit/php-code-coverage/src/Driver/HHVM.php new file mode 100644 index 00000000..b35ea81b --- /dev/null +++ b/src/composer/vendor/phpunit/php-code-coverage/src/Driver/HHVM.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 SebastianBergmann\CodeCoverage\Driver; + +/** + * Driver for HHVM's code coverage functionality. + * + * @codeCoverageIgnore + */ +class HHVM extends Xdebug +{ + /** + * Start collection of code coverage information. + * + * @param bool $determineUnusedAndDead + */ + public function start($determineUnusedAndDead = true) + { + xdebug_start_code_coverage(); + } +} diff --git a/src/composer/vendor/phpunit/php-code-coverage/src/Driver/PHPDBG.php b/src/composer/vendor/phpunit/php-code-coverage/src/Driver/PHPDBG.php new file mode 100644 index 00000000..86cc8444 --- /dev/null +++ b/src/composer/vendor/phpunit/php-code-coverage/src/Driver/PHPDBG.php @@ -0,0 +1,111 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SebastianBergmann\CodeCoverage\Driver; + +use SebastianBergmann\CodeCoverage\RuntimeException; + +/** + * Driver for PHPDBG's code coverage functionality. + * + * @codeCoverageIgnore + */ +class PHPDBG implements Driver +{ + /** + * Constructor. + */ + public function __construct() + { + if (PHP_SAPI !== 'phpdbg') { + throw new RuntimeException( + 'This driver requires the PHPDBG SAPI' + ); + } + + if (!function_exists('phpdbg_start_oplog')) { + throw new RuntimeException( + 'This build of PHPDBG does not support code coverage' + ); + } + } + + /** + * Start collection of code coverage information. + * + * @param bool $determineUnusedAndDead + */ + public function start($determineUnusedAndDead = true) + { + phpdbg_start_oplog(); + } + + /** + * Stop collection of code coverage information. + * + * @return array + */ + public function stop() + { + static $fetchedLines = []; + + $dbgData = phpdbg_end_oplog(); + + if ($fetchedLines == []) { + $sourceLines = phpdbg_get_executable(); + } else { + $newFiles = array_diff( + get_included_files(), + array_keys($fetchedLines) + ); + + if ($newFiles) { + $sourceLines = phpdbg_get_executable( + ['files' => $newFiles] + ); + } else { + $sourceLines = []; + } + } + + foreach ($sourceLines as $file => $lines) { + foreach ($lines as $lineNo => $numExecuted) { + $sourceLines[$file][$lineNo] = self::LINE_NOT_EXECUTED; + } + } + + $fetchedLines = array_merge($fetchedLines, $sourceLines); + + return $this->detectExecutedLines($fetchedLines, $dbgData); + } + + /** + * Convert phpdbg based data into the format CodeCoverage expects + * + * @param array $sourceLines + * @param array $dbgData + * + * @return array + */ + private function detectExecutedLines(array $sourceLines, array $dbgData) + { + foreach ($dbgData as $file => $coveredLines) { + foreach ($coveredLines as $lineNo => $numExecuted) { + // phpdbg also reports $lineNo=0 when e.g. exceptions get thrown. + // make sure we only mark lines executed which are actually executable. + if (isset($sourceLines[$file][$lineNo])) { + $sourceLines[$file][$lineNo] = self::LINE_EXECUTED; + } + } + } + + return $sourceLines; + } +} diff --git a/src/composer/vendor/phpunit/php-code-coverage/src/Driver/Xdebug.php b/src/composer/vendor/phpunit/php-code-coverage/src/Driver/Xdebug.php new file mode 100644 index 00000000..30099e05 --- /dev/null +++ b/src/composer/vendor/phpunit/php-code-coverage/src/Driver/Xdebug.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 SebastianBergmann\CodeCoverage\Driver; + +use SebastianBergmann\CodeCoverage\RuntimeException; + +/** + * Driver for Xdebug's code coverage functionality. + * + * @codeCoverageIgnore + */ +class Xdebug implements Driver +{ + /** + * Cache the number of lines for each file + * + * @var array + */ + private $cacheNumLines = []; + + /** + * Constructor. + */ + public function __construct() + { + if (!extension_loaded('xdebug')) { + throw new RuntimeException('This driver requires Xdebug'); + } + + if (version_compare(phpversion('xdebug'), '2.2.1', '>=') && + !ini_get('xdebug.coverage_enable')) { + throw new RuntimeException( + 'xdebug.coverage_enable=On has to be set in php.ini' + ); + } + } + + /** + * Start collection of code coverage information. + * + * @param bool $determineUnusedAndDead + */ + public function start($determineUnusedAndDead = true) + { + if ($determineUnusedAndDead) { + xdebug_start_code_coverage(XDEBUG_CC_UNUSED | XDEBUG_CC_DEAD_CODE); + } else { + xdebug_start_code_coverage(); + } + } + + /** + * Stop collection of code coverage information. + * + * @return array + */ + public function stop() + { + $data = xdebug_get_code_coverage(); + xdebug_stop_code_coverage(); + + return $this->cleanup($data); + } + + /** + * @param array $data + * + * @return array + */ + private function cleanup(array $data) + { + foreach (array_keys($data) as $file) { + unset($data[$file][0]); + + if (strpos($file, 'xdebug://debug-eval') !== 0 && file_exists($file)) { + $numLines = $this->getNumberOfLinesInFile($file); + + foreach (array_keys($data[$file]) as $line) { + if ($line > $numLines) { + unset($data[$file][$line]); + } + } + } + } + + return $data; + } + + /** + * @param string $file + * + * @return int + */ + private function getNumberOfLinesInFile($file) + { + if (!isset($this->cacheNumLines[$file])) { + $buffer = file_get_contents($file); + $lines = substr_count($buffer, "\n"); + + if (substr($buffer, -1) !== "\n") { + $lines++; + } + + $this->cacheNumLines[$file] = $lines; + } + + return $this->cacheNumLines[$file]; + } +} diff --git a/src/composer/vendor/phpunit/php-code-coverage/src/Exception/CoveredCodeNotExecutedException.php b/src/composer/vendor/phpunit/php-code-coverage/src/Exception/CoveredCodeNotExecutedException.php new file mode 100644 index 00000000..ca28a231 --- /dev/null +++ b/src/composer/vendor/phpunit/php-code-coverage/src/Exception/CoveredCodeNotExecutedException.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 SebastianBergmann\CodeCoverage; + +/** + * Exception that is raised when covered code is not executed. + */ +class CoveredCodeNotExecutedException extends RuntimeException +{ +} diff --git a/src/composer/vendor/phpunit/php-code-coverage/src/Exception/Exception.php b/src/composer/vendor/phpunit/php-code-coverage/src/Exception/Exception.php new file mode 100644 index 00000000..a3ba4c4c --- /dev/null +++ b/src/composer/vendor/phpunit/php-code-coverage/src/Exception/Exception.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 SebastianBergmann\CodeCoverage; + +/** + * Exception interface for php-code-coverage component. + */ +interface Exception +{ +} diff --git a/src/composer/vendor/phpunit/php-code-coverage/src/Exception/InvalidArgumentException.php b/src/composer/vendor/phpunit/php-code-coverage/src/Exception/InvalidArgumentException.php new file mode 100644 index 00000000..1733f6cb --- /dev/null +++ b/src/composer/vendor/phpunit/php-code-coverage/src/Exception/InvalidArgumentException.php @@ -0,0 +1,37 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SebastianBergmann\CodeCoverage; + +class InvalidArgumentException extends \InvalidArgumentException implements Exception +{ + /** + * @param int $argument + * @param string $type + * @param mixed $value + * + * @return InvalidArgumentException + */ + public static function create($argument, $type, $value = null) + { + $stack = debug_backtrace(0); + + return new self( + sprintf( + 'Argument #%d%sof %s::%s() must be a %s', + $argument, + $value !== null ? ' (' . gettype($value) . '#' . $value . ')' : ' (No Value) ', + $stack[1]['class'], + $stack[1]['function'], + $type + ) + ); + } +} diff --git a/src/composer/vendor/phpunit/php-code-coverage/src/Exception/MissingCoversAnnotationException.php b/src/composer/vendor/phpunit/php-code-coverage/src/Exception/MissingCoversAnnotationException.php new file mode 100644 index 00000000..7bc5cf3e --- /dev/null +++ b/src/composer/vendor/phpunit/php-code-coverage/src/Exception/MissingCoversAnnotationException.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 SebastianBergmann\CodeCoverage; + +/** + * Exception that is raised when @covers must be used but is not. + */ +class MissingCoversAnnotationException extends RuntimeException +{ +} diff --git a/src/composer/vendor/phpunit/php-code-coverage/src/Exception/RuntimeException.php b/src/composer/vendor/phpunit/php-code-coverage/src/Exception/RuntimeException.php new file mode 100644 index 00000000..c143db7d --- /dev/null +++ b/src/composer/vendor/phpunit/php-code-coverage/src/Exception/RuntimeException.php @@ -0,0 +1,15 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SebastianBergmann\CodeCoverage; + +class RuntimeException extends \RuntimeException implements Exception +{ +} diff --git a/src/composer/vendor/phpunit/php-code-coverage/src/Exception/UnintentionallyCoveredCodeException.php b/src/composer/vendor/phpunit/php-code-coverage/src/Exception/UnintentionallyCoveredCodeException.php new file mode 100644 index 00000000..3ea542b1 --- /dev/null +++ b/src/composer/vendor/phpunit/php-code-coverage/src/Exception/UnintentionallyCoveredCodeException.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 SebastianBergmann\CodeCoverage; + +/** + * Exception that is raised when code is unintentionally covered. + */ +class UnintentionallyCoveredCodeException extends RuntimeException +{ + /** + * @var array + */ + private $unintentionallyCoveredUnits = []; + + /** + * @param array $unintentionallyCoveredUnits + */ + public function __construct(array $unintentionallyCoveredUnits) + { + $this->unintentionallyCoveredUnits = $unintentionallyCoveredUnits; + + parent::__construct($this->toString()); + } + + /** + * @return array + */ + public function getUnintentionallyCoveredUnits() + { + return $this->unintentionallyCoveredUnits; + } + + /** + * @return string + */ + private function toString() + { + $message = ''; + + foreach ($this->unintentionallyCoveredUnits as $unit) { + $message .= '- ' . $unit . "\n"; + } + + return $message; + } +} diff --git a/src/composer/vendor/phpunit/php-code-coverage/src/Filter.php b/src/composer/vendor/phpunit/php-code-coverage/src/Filter.php new file mode 100644 index 00000000..771a657a --- /dev/null +++ b/src/composer/vendor/phpunit/php-code-coverage/src/Filter.php @@ -0,0 +1,173 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SebastianBergmann\CodeCoverage; + +/** + * Filter for whitelisting of code coverage information. + */ +class Filter +{ + /** + * Source files that are whitelisted. + * + * @var array + */ + private $whitelistedFiles = []; + + /** + * Adds a directory to the whitelist (recursively). + * + * @param string $directory + * @param string $suffix + * @param string $prefix + */ + public function addDirectoryToWhitelist($directory, $suffix = '.php', $prefix = '') + { + $facade = new \File_Iterator_Facade; + $files = $facade->getFilesAsArray($directory, $suffix, $prefix); + + foreach ($files as $file) { + $this->addFileToWhitelist($file); + } + } + + /** + * Adds a file to the whitelist. + * + * @param string $filename + */ + public function addFileToWhitelist($filename) + { + $this->whitelistedFiles[realpath($filename)] = true; + } + + /** + * Adds files to the whitelist. + * + * @param array $files + */ + public function addFilesToWhitelist(array $files) + { + foreach ($files as $file) { + $this->addFileToWhitelist($file); + } + } + + /** + * Removes a directory from the whitelist (recursively). + * + * @param string $directory + * @param string $suffix + * @param string $prefix + */ + public function removeDirectoryFromWhitelist($directory, $suffix = '.php', $prefix = '') + { + $facade = new \File_Iterator_Facade; + $files = $facade->getFilesAsArray($directory, $suffix, $prefix); + + foreach ($files as $file) { + $this->removeFileFromWhitelist($file); + } + } + + /** + * Removes a file from the whitelist. + * + * @param string $filename + */ + public function removeFileFromWhitelist($filename) + { + $filename = realpath($filename); + + unset($this->whitelistedFiles[$filename]); + } + + /** + * Checks whether a filename is a real filename. + * + * @param string $filename + * + * @return bool + */ + public function isFile($filename) + { + if ($filename == '-' || + strpos($filename, 'vfs://') === 0 || + strpos($filename, 'xdebug://debug-eval') !== false || + strpos($filename, 'eval()\'d code') !== false || + strpos($filename, 'runtime-created function') !== false || + strpos($filename, 'runkit created function') !== false || + strpos($filename, 'assert code') !== false || + strpos($filename, 'regexp code') !== false) { + return false; + } + + return file_exists($filename); + } + + /** + * Checks whether or not a file is filtered. + * + * @param string $filename + * + * @return bool + */ + public function isFiltered($filename) + { + if (!$this->isFile($filename)) { + return true; + } + + $filename = realpath($filename); + + return !isset($this->whitelistedFiles[$filename]); + } + + /** + * Returns the list of whitelisted files. + * + * @return array + */ + public function getWhitelist() + { + return array_keys($this->whitelistedFiles); + } + + /** + * Returns whether this filter has a whitelist. + * + * @return bool + */ + public function hasWhitelist() + { + return !empty($this->whitelistedFiles); + } + + /** + * Returns the whitelisted files. + * + * @return array + */ + public function getWhitelistedFiles() + { + return $this->whitelistedFiles; + } + + /** + * Sets the whitelisted files. + * + * @param array $whitelistedFiles + */ + public function setWhitelistedFiles($whitelistedFiles) + { + $this->whitelistedFiles = $whitelistedFiles; + } +} diff --git a/src/composer/vendor/phpunit/php-code-coverage/src/Node/AbstractNode.php b/src/composer/vendor/phpunit/php-code-coverage/src/Node/AbstractNode.php new file mode 100644 index 00000000..f3608058 --- /dev/null +++ b/src/composer/vendor/phpunit/php-code-coverage/src/Node/AbstractNode.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 SebastianBergmann\CodeCoverage\Node; + +use SebastianBergmann\CodeCoverage\Util; + +/** + * Base class for nodes in the code coverage information tree. + */ +abstract class AbstractNode implements \Countable +{ + /** + * @var string + */ + private $name; + + /** + * @var string + */ + private $path; + + /** + * @var array + */ + private $pathArray; + + /** + * @var AbstractNode + */ + private $parent; + + /** + * @var string + */ + private $id; + + /** + * Constructor. + * + * @param string $name + * @param AbstractNode $parent + */ + public function __construct($name, AbstractNode $parent = null) + { + if (substr($name, -1) == '/') { + $name = substr($name, 0, -1); + } + + $this->name = $name; + $this->parent = $parent; + } + + /** + * @return string + */ + public function getName() + { + return $this->name; + } + + /** + * @return string + */ + public function getId() + { + if ($this->id === null) { + $parent = $this->getParent(); + + if ($parent === null) { + $this->id = 'index'; + } else { + $parentId = $parent->getId(); + + if ($parentId == 'index') { + $this->id = str_replace(':', '_', $this->name); + } else { + $this->id = $parentId . '/' . $this->name; + } + } + } + + return $this->id; + } + + /** + * @return string + */ + public function getPath() + { + if ($this->path === null) { + if ($this->parent === null || $this->parent->getPath() === null || $this->parent->getPath() === false) { + $this->path = $this->name; + } else { + $this->path = $this->parent->getPath() . '/' . $this->name; + } + } + + return $this->path; + } + + /** + * @return array + */ + public function getPathAsArray() + { + if ($this->pathArray === null) { + if ($this->parent === null) { + $this->pathArray = []; + } else { + $this->pathArray = $this->parent->getPathAsArray(); + } + + $this->pathArray[] = $this; + } + + return $this->pathArray; + } + + /** + * @return AbstractNode + */ + public function getParent() + { + return $this->parent; + } + + /** + * Returns the percentage of classes that has been tested. + * + * @param bool $asString + * + * @return int + */ + public function getTestedClassesPercent($asString = true) + { + return Util::percent( + $this->getNumTestedClasses(), + $this->getNumClasses(), + $asString + ); + } + + /** + * Returns the percentage of traits that has been tested. + * + * @param bool $asString + * + * @return int + */ + public function getTestedTraitsPercent($asString = true) + { + return Util::percent( + $this->getNumTestedTraits(), + $this->getNumTraits(), + $asString + ); + } + + /** + * Returns the percentage of traits that has been tested. + * + * @param bool $asString + * + * @return int + */ + public function getTestedClassesAndTraitsPercent($asString = true) + { + return Util::percent( + $this->getNumTestedClassesAndTraits(), + $this->getNumClassesAndTraits(), + $asString + ); + } + + /** + * Returns the percentage of methods that has been tested. + * + * @param bool $asString + * + * @return int + */ + public function getTestedMethodsPercent($asString = true) + { + return Util::percent( + $this->getNumTestedMethods(), + $this->getNumMethods(), + $asString + ); + } + + /** + * Returns the percentage of executed lines. + * + * @param bool $asString + * + * @return int + */ + public function getLineExecutedPercent($asString = true) + { + return Util::percent( + $this->getNumExecutedLines(), + $this->getNumExecutableLines(), + $asString + ); + } + + /** + * Returns the number of classes and traits. + * + * @return int + */ + public function getNumClassesAndTraits() + { + return $this->getNumClasses() + $this->getNumTraits(); + } + + /** + * Returns the number of tested classes and traits. + * + * @return int + */ + public function getNumTestedClassesAndTraits() + { + return $this->getNumTestedClasses() + $this->getNumTestedTraits(); + } + + /** + * Returns the classes and traits of this node. + * + * @return array + */ + public function getClassesAndTraits() + { + return array_merge($this->getClasses(), $this->getTraits()); + } + + /** + * Returns the classes of this node. + * + * @return array + */ + abstract public function getClasses(); + + /** + * Returns the traits of this node. + * + * @return array + */ + abstract public function getTraits(); + + /** + * Returns the functions of this node. + * + * @return array + */ + abstract public function getFunctions(); + + /** + * Returns the LOC/CLOC/NCLOC of this node. + * + * @return array + */ + abstract public function getLinesOfCode(); + + /** + * Returns the number of executable lines. + * + * @return int + */ + abstract public function getNumExecutableLines(); + + /** + * Returns the number of executed lines. + * + * @return int + */ + abstract public function getNumExecutedLines(); + + /** + * Returns the number of classes. + * + * @return int + */ + abstract public function getNumClasses(); + + /** + * Returns the number of tested classes. + * + * @return int + */ + abstract public function getNumTestedClasses(); + + /** + * Returns the number of traits. + * + * @return int + */ + abstract public function getNumTraits(); + + /** + * Returns the number of tested traits. + * + * @return int + */ + abstract public function getNumTestedTraits(); + + /** + * Returns the number of methods. + * + * @return int + */ + abstract public function getNumMethods(); + + /** + * Returns the number of tested methods. + * + * @return int + */ + abstract public function getNumTestedMethods(); + + /** + * Returns the number of functions. + * + * @return int + */ + abstract public function getNumFunctions(); + + /** + * Returns the number of tested functions. + * + * @return int + */ + abstract public function getNumTestedFunctions(); +} diff --git a/src/composer/vendor/phpunit/php-code-coverage/src/Node/Builder.php b/src/composer/vendor/phpunit/php-code-coverage/src/Node/Builder.php new file mode 100644 index 00000000..8a6a65c1 --- /dev/null +++ b/src/composer/vendor/phpunit/php-code-coverage/src/Node/Builder.php @@ -0,0 +1,244 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SebastianBergmann\CodeCoverage\Node; + +use SebastianBergmann\CodeCoverage\CodeCoverage; + +class Builder +{ + /** + * @param CodeCoverage $coverage + * + * @return Directory + */ + public function build(CodeCoverage $coverage) + { + $files = $coverage->getData(); + $commonPath = $this->reducePaths($files); + $root = new Directory( + $commonPath, + null + ); + + $this->addItems( + $root, + $this->buildDirectoryStructure($files), + $coverage->getTests(), + $coverage->getCacheTokens() + ); + + return $root; + } + + /** + * @param Directory $root + * @param array $items + * @param array $tests + * @param bool $cacheTokens + */ + private function addItems(Directory $root, array $items, array $tests, $cacheTokens) + { + foreach ($items as $key => $value) { + if (substr($key, -2) == '/f') { + $key = substr($key, 0, -2); + + if (file_exists($root->getPath() . DIRECTORY_SEPARATOR . $key)) { + $root->addFile($key, $value, $tests, $cacheTokens); + } + } else { + $child = $root->addDirectory($key); + $this->addItems($child, $value, $tests, $cacheTokens); + } + } + } + + /** + * Builds an array representation of the directory structure. + * + * For instance, + * + * + * Array + * ( + * [Money.php] => Array + * ( + * ... + * ) + * + * [MoneyBag.php] => Array + * ( + * ... + * ) + * ) + * + * + * is transformed into + * + * + * Array + * ( + * [.] => Array + * ( + * [Money.php] => Array + * ( + * ... + * ) + * + * [MoneyBag.php] => Array + * ( + * ... + * ) + * ) + * ) + * + * + * @param array $files + * + * @return array + */ + private function buildDirectoryStructure($files) + { + $result = []; + + foreach ($files as $path => $file) { + $path = explode('/', $path); + $pointer = &$result; + $max = count($path); + + for ($i = 0; $i < $max; $i++) { + if ($i == ($max - 1)) { + $type = '/f'; + } else { + $type = ''; + } + + $pointer = &$pointer[$path[$i] . $type]; + } + + $pointer = $file; + } + + return $result; + } + + /** + * Reduces the paths by cutting the longest common start path. + * + * For instance, + * + * + * Array + * ( + * [/home/sb/Money/Money.php] => Array + * ( + * ... + * ) + * + * [/home/sb/Money/MoneyBag.php] => Array + * ( + * ... + * ) + * ) + * + * + * is reduced to + * + * + * Array + * ( + * [Money.php] => Array + * ( + * ... + * ) + * + * [MoneyBag.php] => Array + * ( + * ... + * ) + * ) + * + * + * @param array $files + * + * @return string + */ + private function reducePaths(&$files) + { + if (empty($files)) { + return '.'; + } + + $commonPath = ''; + $paths = array_keys($files); + + if (count($files) == 1) { + $commonPath = dirname($paths[0]) . '/'; + $files[basename($paths[0])] = $files[$paths[0]]; + + unset($files[$paths[0]]); + + return $commonPath; + } + + $max = count($paths); + + for ($i = 0; $i < $max; $i++) { + // strip phar:// prefixes + if (strpos($paths[$i], 'phar://') === 0) { + $paths[$i] = substr($paths[$i], 7); + $paths[$i] = strtr($paths[$i], '/', DIRECTORY_SEPARATOR); + } + $paths[$i] = explode(DIRECTORY_SEPARATOR, $paths[$i]); + + if (empty($paths[$i][0])) { + $paths[$i][0] = DIRECTORY_SEPARATOR; + } + } + + $done = false; + $max = count($paths); + + while (!$done) { + for ($i = 0; $i < $max - 1; $i++) { + if (!isset($paths[$i][0]) || + !isset($paths[$i+1][0]) || + $paths[$i][0] != $paths[$i+1][0]) { + $done = true; + break; + } + } + + if (!$done) { + $commonPath .= $paths[0][0]; + + if ($paths[0][0] != DIRECTORY_SEPARATOR) { + $commonPath .= DIRECTORY_SEPARATOR; + } + + for ($i = 0; $i < $max; $i++) { + array_shift($paths[$i]); + } + } + } + + $original = array_keys($files); + $max = count($original); + + for ($i = 0; $i < $max; $i++) { + $files[implode('/', $paths[$i])] = $files[$original[$i]]; + unset($files[$original[$i]]); + } + + ksort($files); + + return substr($commonPath, 0, -1); + } +} diff --git a/src/composer/vendor/phpunit/php-code-coverage/src/Node/Directory.php b/src/composer/vendor/phpunit/php-code-coverage/src/Node/Directory.php new file mode 100644 index 00000000..6a9f28db --- /dev/null +++ b/src/composer/vendor/phpunit/php-code-coverage/src/Node/Directory.php @@ -0,0 +1,483 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SebastianBergmann\CodeCoverage\Node; + +use SebastianBergmann\CodeCoverage\InvalidArgumentException; + +/** + * Represents a directory in the code coverage information tree. + */ +class Directory extends AbstractNode implements \IteratorAggregate +{ + /** + * @var AbstractNode[] + */ + private $children = []; + + /** + * @var Directory[] + */ + private $directories = []; + + /** + * @var File[] + */ + private $files = []; + + /** + * @var array + */ + private $classes; + + /** + * @var array + */ + private $traits; + + /** + * @var array + */ + private $functions; + + /** + * @var array + */ + private $linesOfCode = null; + + /** + * @var int + */ + private $numFiles = -1; + + /** + * @var int + */ + private $numExecutableLines = -1; + + /** + * @var int + */ + private $numExecutedLines = -1; + + /** + * @var int + */ + private $numClasses = -1; + + /** + * @var int + */ + private $numTestedClasses = -1; + + /** + * @var int + */ + private $numTraits = -1; + + /** + * @var int + */ + private $numTestedTraits = -1; + + /** + * @var int + */ + private $numMethods = -1; + + /** + * @var int + */ + private $numTestedMethods = -1; + + /** + * @var int + */ + private $numFunctions = -1; + + /** + * @var int + */ + private $numTestedFunctions = -1; + + /** + * Returns the number of files in/under this node. + * + * @return int + */ + public function count() + { + if ($this->numFiles == -1) { + $this->numFiles = 0; + + foreach ($this->children as $child) { + $this->numFiles += count($child); + } + } + + return $this->numFiles; + } + + /** + * Returns an iterator for this node. + * + * @return \RecursiveIteratorIterator + */ + public function getIterator() + { + return new \RecursiveIteratorIterator( + new Iterator($this), + \RecursiveIteratorIterator::SELF_FIRST + ); + } + + /** + * Adds a new directory. + * + * @param string $name + * + * @return Directory + */ + public function addDirectory($name) + { + $directory = new self($name, $this); + + $this->children[] = $directory; + $this->directories[] = &$this->children[count($this->children) - 1]; + + return $directory; + } + + /** + * Adds a new file. + * + * @param string $name + * @param array $coverageData + * @param array $testData + * @param bool $cacheTokens + * + * @return File + * + * @throws InvalidArgumentException + */ + public function addFile($name, array $coverageData, array $testData, $cacheTokens) + { + $file = new File( + $name, + $this, + $coverageData, + $testData, + $cacheTokens + ); + + $this->children[] = $file; + $this->files[] = &$this->children[count($this->children) - 1]; + + $this->numExecutableLines = -1; + $this->numExecutedLines = -1; + + return $file; + } + + /** + * Returns the directories in this directory. + * + * @return array + */ + public function getDirectories() + { + return $this->directories; + } + + /** + * Returns the files in this directory. + * + * @return array + */ + public function getFiles() + { + return $this->files; + } + + /** + * Returns the child nodes of this node. + * + * @return array + */ + public function getChildNodes() + { + return $this->children; + } + + /** + * Returns the classes of this node. + * + * @return array + */ + public function getClasses() + { + if ($this->classes === null) { + $this->classes = []; + + foreach ($this->children as $child) { + $this->classes = array_merge( + $this->classes, + $child->getClasses() + ); + } + } + + return $this->classes; + } + + /** + * Returns the traits of this node. + * + * @return array + */ + public function getTraits() + { + if ($this->traits === null) { + $this->traits = []; + + foreach ($this->children as $child) { + $this->traits = array_merge( + $this->traits, + $child->getTraits() + ); + } + } + + return $this->traits; + } + + /** + * Returns the functions of this node. + * + * @return array + */ + public function getFunctions() + { + if ($this->functions === null) { + $this->functions = []; + + foreach ($this->children as $child) { + $this->functions = array_merge( + $this->functions, + $child->getFunctions() + ); + } + } + + return $this->functions; + } + + /** + * Returns the LOC/CLOC/NCLOC of this node. + * + * @return array + */ + public function getLinesOfCode() + { + if ($this->linesOfCode === null) { + $this->linesOfCode = ['loc' => 0, 'cloc' => 0, 'ncloc' => 0]; + + foreach ($this->children as $child) { + $linesOfCode = $child->getLinesOfCode(); + + $this->linesOfCode['loc'] += $linesOfCode['loc']; + $this->linesOfCode['cloc'] += $linesOfCode['cloc']; + $this->linesOfCode['ncloc'] += $linesOfCode['ncloc']; + } + } + + return $this->linesOfCode; + } + + /** + * Returns the number of executable lines. + * + * @return int + */ + public function getNumExecutableLines() + { + if ($this->numExecutableLines == -1) { + $this->numExecutableLines = 0; + + foreach ($this->children as $child) { + $this->numExecutableLines += $child->getNumExecutableLines(); + } + } + + return $this->numExecutableLines; + } + + /** + * Returns the number of executed lines. + * + * @return int + */ + public function getNumExecutedLines() + { + if ($this->numExecutedLines == -1) { + $this->numExecutedLines = 0; + + foreach ($this->children as $child) { + $this->numExecutedLines += $child->getNumExecutedLines(); + } + } + + return $this->numExecutedLines; + } + + /** + * Returns the number of classes. + * + * @return int + */ + public function getNumClasses() + { + if ($this->numClasses == -1) { + $this->numClasses = 0; + + foreach ($this->children as $child) { + $this->numClasses += $child->getNumClasses(); + } + } + + return $this->numClasses; + } + + /** + * Returns the number of tested classes. + * + * @return int + */ + public function getNumTestedClasses() + { + if ($this->numTestedClasses == -1) { + $this->numTestedClasses = 0; + + foreach ($this->children as $child) { + $this->numTestedClasses += $child->getNumTestedClasses(); + } + } + + return $this->numTestedClasses; + } + + /** + * Returns the number of traits. + * + * @return int + */ + public function getNumTraits() + { + if ($this->numTraits == -1) { + $this->numTraits = 0; + + foreach ($this->children as $child) { + $this->numTraits += $child->getNumTraits(); + } + } + + return $this->numTraits; + } + + /** + * Returns the number of tested traits. + * + * @return int + */ + public function getNumTestedTraits() + { + if ($this->numTestedTraits == -1) { + $this->numTestedTraits = 0; + + foreach ($this->children as $child) { + $this->numTestedTraits += $child->getNumTestedTraits(); + } + } + + return $this->numTestedTraits; + } + + /** + * Returns the number of methods. + * + * @return int + */ + public function getNumMethods() + { + if ($this->numMethods == -1) { + $this->numMethods = 0; + + foreach ($this->children as $child) { + $this->numMethods += $child->getNumMethods(); + } + } + + return $this->numMethods; + } + + /** + * Returns the number of tested methods. + * + * @return int + */ + public function getNumTestedMethods() + { + if ($this->numTestedMethods == -1) { + $this->numTestedMethods = 0; + + foreach ($this->children as $child) { + $this->numTestedMethods += $child->getNumTestedMethods(); + } + } + + return $this->numTestedMethods; + } + + /** + * Returns the number of functions. + * + * @return int + */ + public function getNumFunctions() + { + if ($this->numFunctions == -1) { + $this->numFunctions = 0; + + foreach ($this->children as $child) { + $this->numFunctions += $child->getNumFunctions(); + } + } + + return $this->numFunctions; + } + + /** + * Returns the number of tested functions. + * + * @return int + */ + public function getNumTestedFunctions() + { + if ($this->numTestedFunctions == -1) { + $this->numTestedFunctions = 0; + + foreach ($this->children as $child) { + $this->numTestedFunctions += $child->getNumTestedFunctions(); + } + } + + return $this->numTestedFunctions; + } +} diff --git a/src/composer/vendor/phpunit/php-code-coverage/src/Node/File.php b/src/composer/vendor/phpunit/php-code-coverage/src/Node/File.php new file mode 100644 index 00000000..b94f2076 --- /dev/null +++ b/src/composer/vendor/phpunit/php-code-coverage/src/Node/File.php @@ -0,0 +1,684 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SebastianBergmann\CodeCoverage\Node; + +use SebastianBergmann\CodeCoverage\InvalidArgumentException; + +/** + * Represents a file in the code coverage information tree. + */ +class File extends AbstractNode +{ + /** + * @var array + */ + private $coverageData; + + /** + * @var array + */ + private $testData; + + /** + * @var int + */ + private $numExecutableLines = 0; + + /** + * @var int + */ + private $numExecutedLines = 0; + + /** + * @var array + */ + private $classes = []; + + /** + * @var array + */ + private $traits = []; + + /** + * @var array + */ + private $functions = []; + + /** + * @var array + */ + private $linesOfCode = []; + + /** + * @var int + */ + private $numTestedTraits = 0; + + /** + * @var int + */ + private $numTestedClasses = 0; + + /** + * @var int + */ + private $numMethods = null; + + /** + * @var int + */ + private $numTestedMethods = null; + + /** + * @var int + */ + private $numTestedFunctions = null; + + /** + * @var array + */ + private $startLines = []; + + /** + * @var array + */ + private $endLines = []; + + /** + * @var bool + */ + private $cacheTokens; + + /** + * Constructor. + * + * @param string $name + * @param AbstractNode $parent + * @param array $coverageData + * @param array $testData + * @param bool $cacheTokens + * + * @throws InvalidArgumentException + */ + public function __construct($name, AbstractNode $parent, array $coverageData, array $testData, $cacheTokens) + { + if (!is_bool($cacheTokens)) { + throw InvalidArgumentException::create( + 1, + 'boolean' + ); + } + + parent::__construct($name, $parent); + + $this->coverageData = $coverageData; + $this->testData = $testData; + $this->cacheTokens = $cacheTokens; + + $this->calculateStatistics(); + } + + /** + * Returns the number of files in/under this node. + * + * @return int + */ + public function count() + { + return 1; + } + + /** + * Returns the code coverage data of this node. + * + * @return array + */ + public function getCoverageData() + { + return $this->coverageData; + } + + /** + * Returns the test data of this node. + * + * @return array + */ + public function getTestData() + { + return $this->testData; + } + + /** + * Returns the classes of this node. + * + * @return array + */ + public function getClasses() + { + return $this->classes; + } + + /** + * Returns the traits of this node. + * + * @return array + */ + public function getTraits() + { + return $this->traits; + } + + /** + * Returns the functions of this node. + * + * @return array + */ + public function getFunctions() + { + return $this->functions; + } + + /** + * Returns the LOC/CLOC/NCLOC of this node. + * + * @return array + */ + public function getLinesOfCode() + { + return $this->linesOfCode; + } + + /** + * Returns the number of executable lines. + * + * @return int + */ + public function getNumExecutableLines() + { + return $this->numExecutableLines; + } + + /** + * Returns the number of executed lines. + * + * @return int + */ + public function getNumExecutedLines() + { + return $this->numExecutedLines; + } + + /** + * Returns the number of classes. + * + * @return int + */ + public function getNumClasses() + { + return count($this->classes); + } + + /** + * Returns the number of tested classes. + * + * @return int + */ + public function getNumTestedClasses() + { + return $this->numTestedClasses; + } + + /** + * Returns the number of traits. + * + * @return int + */ + public function getNumTraits() + { + return count($this->traits); + } + + /** + * Returns the number of tested traits. + * + * @return int + */ + public function getNumTestedTraits() + { + return $this->numTestedTraits; + } + + /** + * Returns the number of methods. + * + * @return int + */ + public function getNumMethods() + { + if ($this->numMethods === null) { + $this->numMethods = 0; + + foreach ($this->classes as $class) { + foreach ($class['methods'] as $method) { + if ($method['executableLines'] > 0) { + $this->numMethods++; + } + } + } + + foreach ($this->traits as $trait) { + foreach ($trait['methods'] as $method) { + if ($method['executableLines'] > 0) { + $this->numMethods++; + } + } + } + } + + return $this->numMethods; + } + + /** + * Returns the number of tested methods. + * + * @return int + */ + public function getNumTestedMethods() + { + if ($this->numTestedMethods === null) { + $this->numTestedMethods = 0; + + foreach ($this->classes as $class) { + foreach ($class['methods'] as $method) { + if ($method['executableLines'] > 0 && + $method['coverage'] == 100) { + $this->numTestedMethods++; + } + } + } + + foreach ($this->traits as $trait) { + foreach ($trait['methods'] as $method) { + if ($method['executableLines'] > 0 && + $method['coverage'] == 100) { + $this->numTestedMethods++; + } + } + } + } + + return $this->numTestedMethods; + } + + /** + * Returns the number of functions. + * + * @return int + */ + public function getNumFunctions() + { + return count($this->functions); + } + + /** + * Returns the number of tested functions. + * + * @return int + */ + public function getNumTestedFunctions() + { + if ($this->numTestedFunctions === null) { + $this->numTestedFunctions = 0; + + foreach ($this->functions as $function) { + if ($function['executableLines'] > 0 && + $function['coverage'] == 100) { + $this->numTestedFunctions++; + } + } + } + + return $this->numTestedFunctions; + } + + /** + * Calculates coverage statistics for the file. + */ + protected function calculateStatistics() + { + $classStack = $functionStack = []; + + if ($this->cacheTokens) { + $tokens = \PHP_Token_Stream_CachingFactory::get($this->getPath()); + } else { + $tokens = new \PHP_Token_Stream($this->getPath()); + } + + $this->processClasses($tokens); + $this->processTraits($tokens); + $this->processFunctions($tokens); + $this->linesOfCode = $tokens->getLinesOfCode(); + unset($tokens); + + for ($lineNumber = 1; $lineNumber <= $this->linesOfCode['loc']; $lineNumber++) { + if (isset($this->startLines[$lineNumber])) { + // Start line of a class. + if (isset($this->startLines[$lineNumber]['className'])) { + if (isset($currentClass)) { + $classStack[] = &$currentClass; + } + + $currentClass = &$this->startLines[$lineNumber]; + } // Start line of a trait. + elseif (isset($this->startLines[$lineNumber]['traitName'])) { + $currentTrait = &$this->startLines[$lineNumber]; + } // Start line of a method. + elseif (isset($this->startLines[$lineNumber]['methodName'])) { + $currentMethod = &$this->startLines[$lineNumber]; + } // Start line of a function. + elseif (isset($this->startLines[$lineNumber]['functionName'])) { + if (isset($currentFunction)) { + $functionStack[] = &$currentFunction; + } + + $currentFunction = &$this->startLines[$lineNumber]; + } + } + + if (isset($this->coverageData[$lineNumber])) { + if (isset($currentClass)) { + $currentClass['executableLines']++; + } + + if (isset($currentTrait)) { + $currentTrait['executableLines']++; + } + + if (isset($currentMethod)) { + $currentMethod['executableLines']++; + } + + if (isset($currentFunction)) { + $currentFunction['executableLines']++; + } + + $this->numExecutableLines++; + + if (count($this->coverageData[$lineNumber]) > 0) { + if (isset($currentClass)) { + $currentClass['executedLines']++; + } + + if (isset($currentTrait)) { + $currentTrait['executedLines']++; + } + + if (isset($currentMethod)) { + $currentMethod['executedLines']++; + } + + if (isset($currentFunction)) { + $currentFunction['executedLines']++; + } + + $this->numExecutedLines++; + } + } + + if (isset($this->endLines[$lineNumber])) { + // End line of a class. + if (isset($this->endLines[$lineNumber]['className'])) { + unset($currentClass); + + if ($classStack) { + end($classStack); + $key = key($classStack); + $currentClass = &$classStack[$key]; + unset($classStack[$key]); + } + } // End line of a trait. + elseif (isset($this->endLines[$lineNumber]['traitName'])) { + unset($currentTrait); + } // End line of a method. + elseif (isset($this->endLines[$lineNumber]['methodName'])) { + unset($currentMethod); + } // End line of a function. + elseif (isset($this->endLines[$lineNumber]['functionName'])) { + unset($currentFunction); + + if ($functionStack) { + end($functionStack); + $key = key($functionStack); + $currentFunction = &$functionStack[$key]; + unset($functionStack[$key]); + } + } + } + } + + foreach ($this->traits as &$trait) { + foreach ($trait['methods'] as &$method) { + if ($method['executableLines'] > 0) { + $method['coverage'] = ($method['executedLines'] / + $method['executableLines']) * 100; + } else { + $method['coverage'] = 100; + } + + $method['crap'] = $this->crap( + $method['ccn'], + $method['coverage'] + ); + + $trait['ccn'] += $method['ccn']; + } + + if ($trait['executableLines'] > 0) { + $trait['coverage'] = ($trait['executedLines'] / + $trait['executableLines']) * 100; + } else { + $trait['coverage'] = 100; + } + + if ($trait['coverage'] == 100) { + $this->numTestedClasses++; + } + + $trait['crap'] = $this->crap( + $trait['ccn'], + $trait['coverage'] + ); + } + + foreach ($this->classes as &$class) { + foreach ($class['methods'] as &$method) { + if ($method['executableLines'] > 0) { + $method['coverage'] = ($method['executedLines'] / + $method['executableLines']) * 100; + } else { + $method['coverage'] = 100; + } + + $method['crap'] = $this->crap( + $method['ccn'], + $method['coverage'] + ); + + $class['ccn'] += $method['ccn']; + } + + if ($class['executableLines'] > 0) { + $class['coverage'] = ($class['executedLines'] / + $class['executableLines']) * 100; + } else { + $class['coverage'] = 100; + } + + if ($class['coverage'] == 100) { + $this->numTestedClasses++; + } + + $class['crap'] = $this->crap( + $class['ccn'], + $class['coverage'] + ); + } + } + + /** + * @param \PHP_Token_Stream $tokens + */ + protected function processClasses(\PHP_Token_Stream $tokens) + { + $classes = $tokens->getClasses(); + unset($tokens); + + $link = $this->getId() . '.html#'; + + foreach ($classes as $className => $class) { + $this->classes[$className] = [ + 'className' => $className, + 'methods' => [], + 'startLine' => $class['startLine'], + 'executableLines' => 0, + 'executedLines' => 0, + 'ccn' => 0, + 'coverage' => 0, + 'crap' => 0, + 'package' => $class['package'], + 'link' => $link . $class['startLine'] + ]; + + $this->startLines[$class['startLine']] = &$this->classes[$className]; + $this->endLines[$class['endLine']] = &$this->classes[$className]; + + foreach ($class['methods'] as $methodName => $method) { + $this->classes[$className]['methods'][$methodName] = $this->newMethod($methodName, $method, $link); + + $this->startLines[$method['startLine']] = &$this->classes[$className]['methods'][$methodName]; + $this->endLines[$method['endLine']] = &$this->classes[$className]['methods'][$methodName]; + } + } + } + + /** + * @param \PHP_Token_Stream $tokens + */ + protected function processTraits(\PHP_Token_Stream $tokens) + { + $traits = $tokens->getTraits(); + unset($tokens); + + $link = $this->getId() . '.html#'; + + foreach ($traits as $traitName => $trait) { + $this->traits[$traitName] = [ + 'traitName' => $traitName, + 'methods' => [], + 'startLine' => $trait['startLine'], + 'executableLines' => 0, + 'executedLines' => 0, + 'ccn' => 0, + 'coverage' => 0, + 'crap' => 0, + 'package' => $trait['package'], + 'link' => $link . $trait['startLine'] + ]; + + $this->startLines[$trait['startLine']] = &$this->traits[$traitName]; + $this->endLines[$trait['endLine']] = &$this->traits[$traitName]; + + foreach ($trait['methods'] as $methodName => $method) { + $this->traits[$traitName]['methods'][$methodName] = $this->newMethod($methodName, $method, $link); + + $this->startLines[$method['startLine']] = &$this->traits[$traitName]['methods'][$methodName]; + $this->endLines[$method['endLine']] = &$this->traits[$traitName]['methods'][$methodName]; + } + } + } + + /** + * @param \PHP_Token_Stream $tokens + */ + protected function processFunctions(\PHP_Token_Stream $tokens) + { + $functions = $tokens->getFunctions(); + unset($tokens); + + $link = $this->getId() . '.html#'; + + foreach ($functions as $functionName => $function) { + $this->functions[$functionName] = [ + 'functionName' => $functionName, + 'signature' => $function['signature'], + 'startLine' => $function['startLine'], + 'executableLines' => 0, + 'executedLines' => 0, + 'ccn' => $function['ccn'], + 'coverage' => 0, + 'crap' => 0, + 'link' => $link . $function['startLine'] + ]; + + $this->startLines[$function['startLine']] = &$this->functions[$functionName]; + $this->endLines[$function['endLine']] = &$this->functions[$functionName]; + } + } + + /** + * Calculates the Change Risk Anti-Patterns (CRAP) index for a unit of code + * based on its cyclomatic complexity and percentage of code coverage. + * + * @param int $ccn + * @param float $coverage + * + * @return string + */ + protected function crap($ccn, $coverage) + { + if ($coverage == 0) { + return (string) (pow($ccn, 2) + $ccn); + } + + if ($coverage >= 95) { + return (string) $ccn; + } + + return sprintf( + '%01.2F', + pow($ccn, 2) * pow(1 - $coverage/100, 3) + $ccn + ); + } + + /** + * @param string $methodName + * @param array $method + * @param string $link + * + * @return array + */ + private function newMethod($methodName, array $method, $link) + { + return [ + 'methodName' => $methodName, + 'visibility' => $method['visibility'], + 'signature' => $method['signature'], + 'startLine' => $method['startLine'], + 'endLine' => $method['endLine'], + 'executableLines' => 0, + 'executedLines' => 0, + 'ccn' => $method['ccn'], + 'coverage' => 0, + 'crap' => 0, + 'link' => $link . $method['startLine'], + ]; + } +} diff --git a/src/composer/vendor/phpunit/php-code-coverage/src/Node/Iterator.php b/src/composer/vendor/phpunit/php-code-coverage/src/Node/Iterator.php new file mode 100644 index 00000000..e2463805 --- /dev/null +++ b/src/composer/vendor/phpunit/php-code-coverage/src/Node/Iterator.php @@ -0,0 +1,103 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SebastianBergmann\CodeCoverage\Node; + +/** + * Recursive iterator for node object graphs. + */ +class Iterator implements \RecursiveIterator +{ + /** + * @var int + */ + private $position; + + /** + * @var AbstractNode[] + */ + private $nodes; + + /** + * @param Directory $node + */ + public function __construct(Directory $node) + { + $this->nodes = $node->getChildNodes(); + } + + /** + * Rewinds the Iterator to the first element. + */ + public function rewind() + { + $this->position = 0; + } + + /** + * Checks if there is a current element after calls to rewind() or next(). + * + * @return bool + */ + public function valid() + { + return $this->position < count($this->nodes); + } + + /** + * Returns the key of the current element. + * + * @return int + */ + public function key() + { + return $this->position; + } + + /** + * Returns the current element. + * + * @return \PHPUnit_Framework_Test + */ + public function current() + { + return $this->valid() ? $this->nodes[$this->position] : null; + } + + /** + * Moves forward to next element. + */ + public function next() + { + $this->position++; + } + + /** + * Returns the sub iterator for the current element. + * + * @return Iterator + */ + public function getChildren() + { + return new self( + $this->nodes[$this->position] + ); + } + + /** + * Checks whether the current element has children. + * + * @return bool + */ + public function hasChildren() + { + return $this->nodes[$this->position] instanceof Directory; + } +} diff --git a/src/composer/vendor/phpunit/php-code-coverage/src/Report/Clover.php b/src/composer/vendor/phpunit/php-code-coverage/src/Report/Clover.php new file mode 100644 index 00000000..054b1dfd --- /dev/null +++ b/src/composer/vendor/phpunit/php-code-coverage/src/Report/Clover.php @@ -0,0 +1,251 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SebastianBergmann\CodeCoverage\Report; + +use SebastianBergmann\CodeCoverage\CodeCoverage; +use SebastianBergmann\CodeCoverage\Node\File; + +/** + * Generates a Clover XML logfile from a code coverage object. + */ +class Clover +{ + /** + * @param CodeCoverage $coverage + * @param string $target + * @param string $name + * + * @return string + */ + public function process(CodeCoverage $coverage, $target = null, $name = null) + { + $xmlDocument = new \DOMDocument('1.0', 'UTF-8'); + $xmlDocument->formatOutput = true; + + $xmlCoverage = $xmlDocument->createElement('coverage'); + $xmlCoverage->setAttribute('generated', (int) $_SERVER['REQUEST_TIME']); + $xmlDocument->appendChild($xmlCoverage); + + $xmlProject = $xmlDocument->createElement('project'); + $xmlProject->setAttribute('timestamp', (int) $_SERVER['REQUEST_TIME']); + + if (is_string($name)) { + $xmlProject->setAttribute('name', $name); + } + + $xmlCoverage->appendChild($xmlProject); + + $packages = []; + $report = $coverage->getReport(); + unset($coverage); + + foreach ($report as $item) { + if (!$item instanceof File) { + continue; + } + + /* @var File $item */ + + $xmlFile = $xmlDocument->createElement('file'); + $xmlFile->setAttribute('name', $item->getPath()); + + $classes = $item->getClassesAndTraits(); + $coverage = $item->getCoverageData(); + $lines = []; + $namespace = 'global'; + + foreach ($classes as $className => $class) { + $classStatements = 0; + $coveredClassStatements = 0; + $coveredMethods = 0; + $classMethods = 0; + + foreach ($class['methods'] as $methodName => $method) { + if ($method['executableLines'] == 0) { + continue; + } + + $classMethods++; + $classStatements += $method['executableLines']; + $coveredClassStatements += $method['executedLines']; + + if ($method['coverage'] == 100) { + $coveredMethods++; + } + + $methodCount = 0; + + foreach (range($method['startLine'], $method['endLine']) as $line) { + if (isset($coverage[$line]) && ($coverage[$line] !== null)) { + $methodCount = max($methodCount, count($coverage[$line])); + } + } + + $lines[$method['startLine']] = [ + 'ccn' => $method['ccn'], + 'count' => $methodCount, + 'crap' => $method['crap'], + 'type' => 'method', + 'visibility' => $method['visibility'], + 'name' => $methodName + ]; + } + + if (!empty($class['package']['namespace'])) { + $namespace = $class['package']['namespace']; + } + + $xmlClass = $xmlDocument->createElement('class'); + $xmlClass->setAttribute('name', $className); + $xmlClass->setAttribute('namespace', $namespace); + + if (!empty($class['package']['fullPackage'])) { + $xmlClass->setAttribute( + 'fullPackage', + $class['package']['fullPackage'] + ); + } + + if (!empty($class['package']['category'])) { + $xmlClass->setAttribute( + 'category', + $class['package']['category'] + ); + } + + if (!empty($class['package']['package'])) { + $xmlClass->setAttribute( + 'package', + $class['package']['package'] + ); + } + + if (!empty($class['package']['subpackage'])) { + $xmlClass->setAttribute( + 'subpackage', + $class['package']['subpackage'] + ); + } + + $xmlFile->appendChild($xmlClass); + + $xmlMetrics = $xmlDocument->createElement('metrics'); + $xmlMetrics->setAttribute('complexity', $class['ccn']); + $xmlMetrics->setAttribute('methods', $classMethods); + $xmlMetrics->setAttribute('coveredmethods', $coveredMethods); + $xmlMetrics->setAttribute('conditionals', 0); + $xmlMetrics->setAttribute('coveredconditionals', 0); + $xmlMetrics->setAttribute('statements', $classStatements); + $xmlMetrics->setAttribute('coveredstatements', $coveredClassStatements); + $xmlMetrics->setAttribute('elements', $classMethods + $classStatements /* + conditionals */); + $xmlMetrics->setAttribute('coveredelements', $coveredMethods + $coveredClassStatements /* + coveredconditionals */); + $xmlClass->appendChild($xmlMetrics); + } + + foreach ($coverage as $line => $data) { + if ($data === null || isset($lines[$line])) { + continue; + } + + $lines[$line] = [ + 'count' => count($data), 'type' => 'stmt' + ]; + } + + ksort($lines); + + foreach ($lines as $line => $data) { + $xmlLine = $xmlDocument->createElement('line'); + $xmlLine->setAttribute('num', $line); + $xmlLine->setAttribute('type', $data['type']); + + if (isset($data['name'])) { + $xmlLine->setAttribute('name', $data['name']); + } + + if (isset($data['visibility'])) { + $xmlLine->setAttribute('visibility', $data['visibility']); + } + + if (isset($data['ccn'])) { + $xmlLine->setAttribute('complexity', $data['ccn']); + } + + if (isset($data['crap'])) { + $xmlLine->setAttribute('crap', $data['crap']); + } + + $xmlLine->setAttribute('count', $data['count']); + $xmlFile->appendChild($xmlLine); + } + + $linesOfCode = $item->getLinesOfCode(); + + $xmlMetrics = $xmlDocument->createElement('metrics'); + $xmlMetrics->setAttribute('loc', $linesOfCode['loc']); + $xmlMetrics->setAttribute('ncloc', $linesOfCode['ncloc']); + $xmlMetrics->setAttribute('classes', $item->getNumClassesAndTraits()); + $xmlMetrics->setAttribute('methods', $item->getNumMethods()); + $xmlMetrics->setAttribute('coveredmethods', $item->getNumTestedMethods()); + $xmlMetrics->setAttribute('conditionals', 0); + $xmlMetrics->setAttribute('coveredconditionals', 0); + $xmlMetrics->setAttribute('statements', $item->getNumExecutableLines()); + $xmlMetrics->setAttribute('coveredstatements', $item->getNumExecutedLines()); + $xmlMetrics->setAttribute('elements', $item->getNumMethods() + $item->getNumExecutableLines() /* + conditionals */); + $xmlMetrics->setAttribute('coveredelements', $item->getNumTestedMethods() + $item->getNumExecutedLines() /* + coveredconditionals */); + $xmlFile->appendChild($xmlMetrics); + + if ($namespace == 'global') { + $xmlProject->appendChild($xmlFile); + } else { + if (!isset($packages[$namespace])) { + $packages[$namespace] = $xmlDocument->createElement( + 'package' + ); + + $packages[$namespace]->setAttribute('name', $namespace); + $xmlProject->appendChild($packages[$namespace]); + } + + $packages[$namespace]->appendChild($xmlFile); + } + } + + $linesOfCode = $report->getLinesOfCode(); + + $xmlMetrics = $xmlDocument->createElement('metrics'); + $xmlMetrics->setAttribute('files', count($report)); + $xmlMetrics->setAttribute('loc', $linesOfCode['loc']); + $xmlMetrics->setAttribute('ncloc', $linesOfCode['ncloc']); + $xmlMetrics->setAttribute('classes', $report->getNumClassesAndTraits()); + $xmlMetrics->setAttribute('methods', $report->getNumMethods()); + $xmlMetrics->setAttribute('coveredmethods', $report->getNumTestedMethods()); + $xmlMetrics->setAttribute('conditionals', 0); + $xmlMetrics->setAttribute('coveredconditionals', 0); + $xmlMetrics->setAttribute('statements', $report->getNumExecutableLines()); + $xmlMetrics->setAttribute('coveredstatements', $report->getNumExecutedLines()); + $xmlMetrics->setAttribute('elements', $report->getNumMethods() + $report->getNumExecutableLines() /* + conditionals */); + $xmlMetrics->setAttribute('coveredelements', $report->getNumTestedMethods() + $report->getNumExecutedLines() /* + coveredconditionals */); + $xmlProject->appendChild($xmlMetrics); + + $buffer = $xmlDocument->saveXML(); + + if ($target !== null) { + if (!is_dir(dirname($target))) { + mkdir(dirname($target), 0777, true); + } + + file_put_contents($target, $buffer); + } + + return $buffer; + } +} diff --git a/src/composer/vendor/phpunit/php-code-coverage/src/Report/Crap4j.php b/src/composer/vendor/phpunit/php-code-coverage/src/Report/Crap4j.php new file mode 100644 index 00000000..7adf78fe --- /dev/null +++ b/src/composer/vendor/phpunit/php-code-coverage/src/Report/Crap4j.php @@ -0,0 +1,172 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SebastianBergmann\CodeCoverage\Report; + +use SebastianBergmann\CodeCoverage\CodeCoverage; +use SebastianBergmann\CodeCoverage\Node\File; +use SebastianBergmann\CodeCoverage\InvalidArgumentException; + +class Crap4j +{ + /** + * @var int + */ + private $threshold; + + /** + * @param int $threshold + */ + public function __construct($threshold = 30) + { + if (!is_int($threshold)) { + throw InvalidArgumentException::create( + 1, + 'integer' + ); + } + + $this->threshold = $threshold; + } + + /** + * @param CodeCoverage $coverage + * @param string $target + * @param string $name + * + * @return string + */ + public function process(CodeCoverage $coverage, $target = null, $name = null) + { + $document = new \DOMDocument('1.0', 'UTF-8'); + $document->formatOutput = true; + + $root = $document->createElement('crap_result'); + $document->appendChild($root); + + $project = $document->createElement('project', is_string($name) ? $name : ''); + $root->appendChild($project); + $root->appendChild($document->createElement('timestamp', date('Y-m-d H:i:s', (int) $_SERVER['REQUEST_TIME']))); + + $stats = $document->createElement('stats'); + $methodsNode = $document->createElement('methods'); + + $report = $coverage->getReport(); + unset($coverage); + + $fullMethodCount = 0; + $fullCrapMethodCount = 0; + $fullCrapLoad = 0; + $fullCrap = 0; + + foreach ($report as $item) { + $namespace = 'global'; + + if (!$item instanceof File) { + continue; + } + + $file = $document->createElement('file'); + $file->setAttribute('name', $item->getPath()); + + $classes = $item->getClassesAndTraits(); + + foreach ($classes as $className => $class) { + foreach ($class['methods'] as $methodName => $method) { + $crapLoad = $this->getCrapLoad($method['crap'], $method['ccn'], $method['coverage']); + + $fullCrap += $method['crap']; + $fullCrapLoad += $crapLoad; + $fullMethodCount++; + + if ($method['crap'] >= $this->threshold) { + $fullCrapMethodCount++; + } + + $methodNode = $document->createElement('method'); + + if (!empty($class['package']['namespace'])) { + $namespace = $class['package']['namespace']; + } + + $methodNode->appendChild($document->createElement('package', $namespace)); + $methodNode->appendChild($document->createElement('className', $className)); + $methodNode->appendChild($document->createElement('methodName', $methodName)); + $methodNode->appendChild($document->createElement('methodSignature', htmlspecialchars($method['signature']))); + $methodNode->appendChild($document->createElement('fullMethod', htmlspecialchars($method['signature']))); + $methodNode->appendChild($document->createElement('crap', $this->roundValue($method['crap']))); + $methodNode->appendChild($document->createElement('complexity', $method['ccn'])); + $methodNode->appendChild($document->createElement('coverage', $this->roundValue($method['coverage']))); + $methodNode->appendChild($document->createElement('crapLoad', round($crapLoad))); + + $methodsNode->appendChild($methodNode); + } + } + } + + $stats->appendChild($document->createElement('name', 'Method Crap Stats')); + $stats->appendChild($document->createElement('methodCount', $fullMethodCount)); + $stats->appendChild($document->createElement('crapMethodCount', $fullCrapMethodCount)); + $stats->appendChild($document->createElement('crapLoad', round($fullCrapLoad))); + $stats->appendChild($document->createElement('totalCrap', $fullCrap)); + + if ($fullMethodCount > 0) { + $crapMethodPercent = $this->roundValue((100 * $fullCrapMethodCount) / $fullMethodCount); + } else { + $crapMethodPercent = 0; + } + + $stats->appendChild($document->createElement('crapMethodPercent', $crapMethodPercent)); + + $root->appendChild($stats); + $root->appendChild($methodsNode); + + $buffer = $document->saveXML(); + + if ($target !== null) { + if (!is_dir(dirname($target))) { + mkdir(dirname($target), 0777, true); + } + + file_put_contents($target, $buffer); + } + + return $buffer; + } + + /** + * @param float $crapValue + * @param int $cyclomaticComplexity + * @param float $coveragePercent + * + * @return float + */ + private function getCrapLoad($crapValue, $cyclomaticComplexity, $coveragePercent) + { + $crapLoad = 0; + + if ($crapValue >= $this->threshold) { + $crapLoad += $cyclomaticComplexity * (1.0 - $coveragePercent / 100); + $crapLoad += $cyclomaticComplexity / $this->threshold; + } + + return $crapLoad; + } + + /** + * @param float $value + * + * @return float + */ + private function roundValue($value) + { + return round($value, 2); + } +} diff --git a/src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Facade.php b/src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Facade.php new file mode 100644 index 00000000..adcfe424 --- /dev/null +++ b/src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Facade.php @@ -0,0 +1,179 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SebastianBergmann\CodeCoverage\Report\Html; + +use SebastianBergmann\CodeCoverage\CodeCoverage; +use SebastianBergmann\CodeCoverage\Node\Directory as DirectoryNode; +use SebastianBergmann\CodeCoverage\RuntimeException; + +/** + * Generates an HTML report from a code coverage object. + */ +class Facade +{ + /** + * @var string + */ + private $templatePath; + + /** + * @var string + */ + private $generator; + + /** + * @var int + */ + private $lowUpperBound; + + /** + * @var int + */ + private $highLowerBound; + + /** + * Constructor. + * + * @param int $lowUpperBound + * @param int $highLowerBound + * @param string $generator + */ + public function __construct($lowUpperBound = 50, $highLowerBound = 90, $generator = '') + { + $this->generator = $generator; + $this->highLowerBound = $highLowerBound; + $this->lowUpperBound = $lowUpperBound; + $this->templatePath = __DIR__ . '/Renderer/Template/'; + } + + /** + * @param CodeCoverage $coverage + * @param string $target + */ + public function process(CodeCoverage $coverage, $target) + { + $target = $this->getDirectory($target); + $report = $coverage->getReport(); + unset($coverage); + + if (!isset($_SERVER['REQUEST_TIME'])) { + $_SERVER['REQUEST_TIME'] = time(); + } + + $date = date('D M j G:i:s T Y', $_SERVER['REQUEST_TIME']); + + $dashboard = new Dashboard( + $this->templatePath, + $this->generator, + $date, + $this->lowUpperBound, + $this->highLowerBound + ); + + $directory = new Directory( + $this->templatePath, + $this->generator, + $date, + $this->lowUpperBound, + $this->highLowerBound + ); + + $file = new File( + $this->templatePath, + $this->generator, + $date, + $this->lowUpperBound, + $this->highLowerBound + ); + + $directory->render($report, $target . 'index.html'); + $dashboard->render($report, $target . 'dashboard.html'); + + foreach ($report as $node) { + $id = $node->getId(); + + if ($node instanceof DirectoryNode) { + if (!file_exists($target . $id)) { + mkdir($target . $id, 0777, true); + } + + $directory->render($node, $target . $id . '/index.html'); + $dashboard->render($node, $target . $id . '/dashboard.html'); + } else { + $dir = dirname($target . $id); + + if (!file_exists($dir)) { + mkdir($dir, 0777, true); + } + + $file->render($node, $target . $id . '.html'); + } + } + + $this->copyFiles($target); + } + + /** + * @param string $target + */ + private function copyFiles($target) + { + $dir = $this->getDirectory($target . 'css'); + copy($this->templatePath . 'css/bootstrap.min.css', $dir . 'bootstrap.min.css'); + copy($this->templatePath . 'css/nv.d3.min.css', $dir . 'nv.d3.min.css'); + copy($this->templatePath . 'css/style.css', $dir . 'style.css'); + + $dir = $this->getDirectory($target . 'fonts'); + copy($this->templatePath . 'fonts/glyphicons-halflings-regular.eot', $dir . 'glyphicons-halflings-regular.eot'); + copy($this->templatePath . 'fonts/glyphicons-halflings-regular.svg', $dir . 'glyphicons-halflings-regular.svg'); + copy($this->templatePath . 'fonts/glyphicons-halflings-regular.ttf', $dir . 'glyphicons-halflings-regular.ttf'); + copy($this->templatePath . 'fonts/glyphicons-halflings-regular.woff', $dir . 'glyphicons-halflings-regular.woff'); + copy($this->templatePath . 'fonts/glyphicons-halflings-regular.woff2', $dir . 'glyphicons-halflings-regular.woff2'); + + $dir = $this->getDirectory($target . 'js'); + copy($this->templatePath . 'js/bootstrap.min.js', $dir . 'bootstrap.min.js'); + copy($this->templatePath . 'js/d3.min.js', $dir . 'd3.min.js'); + copy($this->templatePath . 'js/holder.min.js', $dir . 'holder.min.js'); + copy($this->templatePath . 'js/html5shiv.min.js', $dir . 'html5shiv.min.js'); + copy($this->templatePath . 'js/jquery.min.js', $dir . 'jquery.min.js'); + copy($this->templatePath . 'js/nv.d3.min.js', $dir . 'nv.d3.min.js'); + copy($this->templatePath . 'js/respond.min.js', $dir . 'respond.min.js'); + } + + /** + * @param string $directory + * + * @return string + * + * @throws RuntimeException + */ + private function getDirectory($directory) + { + if (substr($directory, -1, 1) != DIRECTORY_SEPARATOR) { + $directory .= DIRECTORY_SEPARATOR; + } + + if (is_dir($directory)) { + return $directory; + } + + if (@mkdir($directory, 0777, true)) { + return $directory; + } + + throw new RuntimeException( + sprintf( + 'Directory "%s" does not exist.', + $directory + ) + ); + } +} diff --git a/src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer.php b/src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer.php new file mode 100644 index 00000000..7f5af8bb --- /dev/null +++ b/src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer.php @@ -0,0 +1,297 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SebastianBergmann\CodeCoverage\Report\Html; + +use SebastianBergmann\CodeCoverage\Node\AbstractNode; +use SebastianBergmann\CodeCoverage\Node\File as FileNode; +use SebastianBergmann\CodeCoverage\Node\Directory as DirectoryNode; +use SebastianBergmann\Environment\Runtime; +use SebastianBergmann\Version; + +/** + * Base class for node renderers. + */ +abstract class Renderer +{ + /** + * @var string + */ + protected $templatePath; + + /** + * @var string + */ + protected $generator; + + /** + * @var string + */ + protected $date; + + /** + * @var int + */ + protected $lowUpperBound; + + /** + * @var int + */ + protected $highLowerBound; + + /** + * @var string + */ + protected $version; + + /** + * Constructor. + * + * @param string $templatePath + * @param string $generator + * @param string $date + * @param int $lowUpperBound + * @param int $highLowerBound + */ + public function __construct($templatePath, $generator, $date, $lowUpperBound, $highLowerBound) + { + $version = new Version('4.0.2', dirname(dirname(dirname(dirname(__DIR__))))); + + $this->templatePath = $templatePath; + $this->generator = $generator; + $this->date = $date; + $this->lowUpperBound = $lowUpperBound; + $this->highLowerBound = $highLowerBound; + $this->version = $version->getVersion(); + } + + /** + * @param \Text_Template $template + * @param array $data + * + * @return string + */ + protected function renderItemTemplate(\Text_Template $template, array $data) + { + $numSeparator = ' / '; + + if (isset($data['numClasses']) && $data['numClasses'] > 0) { + $classesLevel = $this->getColorLevel($data['testedClassesPercent']); + + $classesNumber = $data['numTestedClasses'] . $numSeparator . + $data['numClasses']; + + $classesBar = $this->getCoverageBar( + $data['testedClassesPercent'] + ); + } else { + $classesLevel = 'success'; + $classesNumber = '0' . $numSeparator . '0'; + $classesBar = $this->getCoverageBar(100); + } + + if ($data['numMethods'] > 0) { + $methodsLevel = $this->getColorLevel($data['testedMethodsPercent']); + + $methodsNumber = $data['numTestedMethods'] . $numSeparator . + $data['numMethods']; + + $methodsBar = $this->getCoverageBar( + $data['testedMethodsPercent'] + ); + } else { + $methodsLevel = 'success'; + $methodsNumber = '0' . $numSeparator . '0'; + $methodsBar = $this->getCoverageBar(100); + $data['testedMethodsPercentAsString'] = '100.00%'; + } + + if ($data['numExecutableLines'] > 0) { + $linesLevel = $this->getColorLevel($data['linesExecutedPercent']); + + $linesNumber = $data['numExecutedLines'] . $numSeparator . + $data['numExecutableLines']; + + $linesBar = $this->getCoverageBar( + $data['linesExecutedPercent'] + ); + } else { + $linesLevel = 'success'; + $linesNumber = '0' . $numSeparator . '0'; + $linesBar = $this->getCoverageBar(100); + $data['linesExecutedPercentAsString'] = '100.00%'; + } + + $template->setVar( + [ + 'icon' => isset($data['icon']) ? $data['icon'] : '', + 'crap' => isset($data['crap']) ? $data['crap'] : '', + 'name' => $data['name'], + 'lines_bar' => $linesBar, + 'lines_executed_percent' => $data['linesExecutedPercentAsString'], + 'lines_level' => $linesLevel, + 'lines_number' => $linesNumber, + 'methods_bar' => $methodsBar, + 'methods_tested_percent' => $data['testedMethodsPercentAsString'], + 'methods_level' => $methodsLevel, + 'methods_number' => $methodsNumber, + 'classes_bar' => $classesBar, + 'classes_tested_percent' => isset($data['testedClassesPercentAsString']) ? $data['testedClassesPercentAsString'] : '', + 'classes_level' => $classesLevel, + 'classes_number' => $classesNumber + ] + ); + + return $template->render(); + } + + /** + * @param \Text_Template $template + * @param AbstractNode $node + */ + protected function setCommonTemplateVariables(\Text_Template $template, AbstractNode $node) + { + $template->setVar( + [ + 'id' => $node->getId(), + 'full_path' => $node->getPath(), + 'path_to_root' => $this->getPathToRoot($node), + 'breadcrumbs' => $this->getBreadcrumbs($node), + 'date' => $this->date, + 'version' => $this->version, + 'runtime' => $this->getRuntimeString(), + 'generator' => $this->generator, + 'low_upper_bound' => $this->lowUpperBound, + 'high_lower_bound' => $this->highLowerBound + ] + ); + } + + protected function getBreadcrumbs(AbstractNode $node) + { + $breadcrumbs = ''; + $path = $node->getPathAsArray(); + $pathToRoot = []; + $max = count($path); + + if ($node instanceof FileNode) { + $max--; + } + + for ($i = 0; $i < $max; $i++) { + $pathToRoot[] = str_repeat('../', $i); + } + + foreach ($path as $step) { + if ($step !== $node) { + $breadcrumbs .= $this->getInactiveBreadcrumb( + $step, + array_pop($pathToRoot) + ); + } else { + $breadcrumbs .= $this->getActiveBreadcrumb($step); + } + } + + return $breadcrumbs; + } + + protected function getActiveBreadcrumb(AbstractNode $node) + { + $buffer = sprintf( + '

  • %s
  • ' . "\n", + $node->getName() + ); + + if ($node instanceof DirectoryNode) { + $buffer .= '
  • (Dashboard)
  • ' . "\n"; + } + + return $buffer; + } + + protected function getInactiveBreadcrumb(AbstractNode $node, $pathToRoot) + { + return sprintf( + '
  • %s
  • ' . "\n", + $pathToRoot, + $node->getName() + ); + } + + protected function getPathToRoot(AbstractNode $node) + { + $id = $node->getId(); + $depth = substr_count($id, '/'); + + if ($id != 'index' && + $node instanceof DirectoryNode) { + $depth++; + } + + return str_repeat('../', $depth); + } + + protected function getCoverageBar($percent) + { + $level = $this->getColorLevel($percent); + + $template = new \Text_Template( + $this->templatePath . 'coverage_bar.html', + '{{', + '}}' + ); + + $template->setVar(['level' => $level, 'percent' => sprintf('%.2F', $percent)]); + + return $template->render(); + } + + /** + * @param int $percent + * + * @return string + */ + protected function getColorLevel($percent) + { + if ($percent <= $this->lowUpperBound) { + return 'danger'; + } elseif ($percent > $this->lowUpperBound && + $percent < $this->highLowerBound) { + return 'warning'; + } else { + return 'success'; + } + } + + /** + * @return string + */ + private function getRuntimeString() + { + $runtime = new Runtime; + + $buffer = sprintf( + '%s %s', + $runtime->getVendorUrl(), + $runtime->getName(), + $runtime->getVersion() + ); + + if ($runtime->hasXdebug() && !$runtime->hasPHPDBGCodeCoverage()) { + $buffer .= sprintf( + ' with Xdebug %s', + phpversion('xdebug') + ); + } + + return $buffer; + } +} diff --git a/src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Dashboard.php b/src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Dashboard.php new file mode 100644 index 00000000..7cde1755 --- /dev/null +++ b/src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Dashboard.php @@ -0,0 +1,302 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SebastianBergmann\CodeCoverage\Report\Html; + +use SebastianBergmann\CodeCoverage\Node\AbstractNode; +use SebastianBergmann\CodeCoverage\Node\Directory as DirectoryNode; + +/** + * Renders the dashboard for a directory node. + */ +class Dashboard extends Renderer +{ + /** + * @param DirectoryNode $node + * @param string $file + */ + public function render(DirectoryNode $node, $file) + { + $classes = $node->getClassesAndTraits(); + $template = new \Text_Template( + $this->templatePath . 'dashboard.html', + '{{', + '}}' + ); + + $this->setCommonTemplateVariables($template, $node); + + $baseLink = $node->getId() . '/'; + $complexity = $this->complexity($classes, $baseLink); + $coverageDistribution = $this->coverageDistribution($classes); + $insufficientCoverage = $this->insufficientCoverage($classes, $baseLink); + $projectRisks = $this->projectRisks($classes, $baseLink); + + $template->setVar( + [ + 'insufficient_coverage_classes' => $insufficientCoverage['class'], + 'insufficient_coverage_methods' => $insufficientCoverage['method'], + 'project_risks_classes' => $projectRisks['class'], + 'project_risks_methods' => $projectRisks['method'], + 'complexity_class' => $complexity['class'], + 'complexity_method' => $complexity['method'], + 'class_coverage_distribution' => $coverageDistribution['class'], + 'method_coverage_distribution' => $coverageDistribution['method'] + ] + ); + + $template->renderTo($file); + } + + /** + * Returns the data for the Class/Method Complexity charts. + * + * @param array $classes + * @param string $baseLink + * + * @return array + */ + protected function complexity(array $classes, $baseLink) + { + $result = ['class' => [], 'method' => []]; + + foreach ($classes as $className => $class) { + foreach ($class['methods'] as $methodName => $method) { + if ($className != '*') { + $methodName = $className . '::' . $methodName; + } + + $result['method'][] = [ + $method['coverage'], + $method['ccn'], + sprintf( + '%s', + str_replace($baseLink, '', $method['link']), + $methodName + ) + ]; + } + + $result['class'][] = [ + $class['coverage'], + $class['ccn'], + sprintf( + '%s', + str_replace($baseLink, '', $class['link']), + $className + ) + ]; + } + + return [ + 'class' => json_encode($result['class']), + 'method' => json_encode($result['method']) + ]; + } + + /** + * Returns the data for the Class / Method Coverage Distribution chart. + * + * @param array $classes + * + * @return array + */ + protected function coverageDistribution(array $classes) + { + $result = [ + 'class' => [ + '0%' => 0, + '0-10%' => 0, + '10-20%' => 0, + '20-30%' => 0, + '30-40%' => 0, + '40-50%' => 0, + '50-60%' => 0, + '60-70%' => 0, + '70-80%' => 0, + '80-90%' => 0, + '90-100%' => 0, + '100%' => 0 + ], + 'method' => [ + '0%' => 0, + '0-10%' => 0, + '10-20%' => 0, + '20-30%' => 0, + '30-40%' => 0, + '40-50%' => 0, + '50-60%' => 0, + '60-70%' => 0, + '70-80%' => 0, + '80-90%' => 0, + '90-100%' => 0, + '100%' => 0 + ] + ]; + + foreach ($classes as $class) { + foreach ($class['methods'] as $methodName => $method) { + if ($method['coverage'] == 0) { + $result['method']['0%']++; + } elseif ($method['coverage'] == 100) { + $result['method']['100%']++; + } else { + $key = floor($method['coverage'] / 10) * 10; + $key = $key . '-' . ($key + 10) . '%'; + $result['method'][$key]++; + } + } + + if ($class['coverage'] == 0) { + $result['class']['0%']++; + } elseif ($class['coverage'] == 100) { + $result['class']['100%']++; + } else { + $key = floor($class['coverage'] / 10) * 10; + $key = $key . '-' . ($key + 10) . '%'; + $result['class'][$key]++; + } + } + + return [ + 'class' => json_encode(array_values($result['class'])), + 'method' => json_encode(array_values($result['method'])) + ]; + } + + /** + * Returns the classes / methods with insufficient coverage. + * + * @param array $classes + * @param string $baseLink + * + * @return array + */ + protected function insufficientCoverage(array $classes, $baseLink) + { + $leastTestedClasses = []; + $leastTestedMethods = []; + $result = ['class' => '', 'method' => '']; + + foreach ($classes as $className => $class) { + foreach ($class['methods'] as $methodName => $method) { + if ($method['coverage'] < $this->highLowerBound) { + if ($className != '*') { + $key = $className . '::' . $methodName; + } else { + $key = $methodName; + } + + $leastTestedMethods[$key] = $method['coverage']; + } + } + + if ($class['coverage'] < $this->highLowerBound) { + $leastTestedClasses[$className] = $class['coverage']; + } + } + + asort($leastTestedClasses); + asort($leastTestedMethods); + + foreach ($leastTestedClasses as $className => $coverage) { + $result['class'] .= sprintf( + ' %s%d%%' . "\n", + str_replace($baseLink, '', $classes[$className]['link']), + $className, + $coverage + ); + } + + foreach ($leastTestedMethods as $methodName => $coverage) { + list($class, $method) = explode('::', $methodName); + + $result['method'] .= sprintf( + ' %s%d%%' . "\n", + str_replace($baseLink, '', $classes[$class]['methods'][$method]['link']), + $methodName, + $method, + $coverage + ); + } + + return $result; + } + + /** + * Returns the project risks according to the CRAP index. + * + * @param array $classes + * @param string $baseLink + * + * @return array + */ + protected function projectRisks(array $classes, $baseLink) + { + $classRisks = []; + $methodRisks = []; + $result = ['class' => '', 'method' => '']; + + foreach ($classes as $className => $class) { + foreach ($class['methods'] as $methodName => $method) { + if ($method['coverage'] < $this->highLowerBound && + $method['ccn'] > 1) { + if ($className != '*') { + $key = $className . '::' . $methodName; + } else { + $key = $methodName; + } + + $methodRisks[$key] = $method['crap']; + } + } + + if ($class['coverage'] < $this->highLowerBound && + $class['ccn'] > count($class['methods'])) { + $classRisks[$className] = $class['crap']; + } + } + + arsort($classRisks); + arsort($methodRisks); + + foreach ($classRisks as $className => $crap) { + $result['class'] .= sprintf( + ' %s%d' . "\n", + str_replace($baseLink, '', $classes[$className]['link']), + $className, + $crap + ); + } + + foreach ($methodRisks as $methodName => $crap) { + list($class, $method) = explode('::', $methodName); + + $result['method'] .= sprintf( + ' %s%d' . "\n", + str_replace($baseLink, '', $classes[$class]['methods'][$method]['link']), + $methodName, + $method, + $crap + ); + } + + return $result; + } + + protected function getActiveBreadcrumb(AbstractNode $node) + { + return sprintf( + '
  • %s
  • ' . "\n" . + '
  • (Dashboard)
  • ' . "\n", + $node->getName() + ); + } +} diff --git a/src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Directory.php b/src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Directory.php new file mode 100644 index 00000000..a4b1b96f --- /dev/null +++ b/src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Directory.php @@ -0,0 +1,101 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SebastianBergmann\CodeCoverage\Report\Html; + +use SebastianBergmann\CodeCoverage\Node\AbstractNode as Node; +use SebastianBergmann\CodeCoverage\Node\Directory as DirectoryNode; + +/** + * Renders a directory node. + */ +class Directory extends Renderer +{ + /** + * @param DirectoryNode $node + * @param string $file + */ + public function render(DirectoryNode $node, $file) + { + $template = new \Text_Template($this->templatePath . 'directory.html', '{{', '}}'); + + $this->setCommonTemplateVariables($template, $node); + + $items = $this->renderItem($node, true); + + foreach ($node->getDirectories() as $item) { + $items .= $this->renderItem($item); + } + + foreach ($node->getFiles() as $item) { + $items .= $this->renderItem($item); + } + + $template->setVar( + [ + 'id' => $node->getId(), + 'items' => $items + ] + ); + + $template->renderTo($file); + } + + /** + * @param Node $node + * @param bool $total + * + * @return string + */ + protected function renderItem(Node $node, $total = false) + { + $data = [ + 'numClasses' => $node->getNumClassesAndTraits(), + 'numTestedClasses' => $node->getNumTestedClassesAndTraits(), + 'numMethods' => $node->getNumMethods(), + 'numTestedMethods' => $node->getNumTestedMethods(), + 'linesExecutedPercent' => $node->getLineExecutedPercent(false), + 'linesExecutedPercentAsString' => $node->getLineExecutedPercent(), + 'numExecutedLines' => $node->getNumExecutedLines(), + 'numExecutableLines' => $node->getNumExecutableLines(), + 'testedMethodsPercent' => $node->getTestedMethodsPercent(false), + 'testedMethodsPercentAsString' => $node->getTestedMethodsPercent(), + 'testedClassesPercent' => $node->getTestedClassesAndTraitsPercent(false), + 'testedClassesPercentAsString' => $node->getTestedClassesAndTraitsPercent() + ]; + + if ($total) { + $data['name'] = 'Total'; + } else { + if ($node instanceof DirectoryNode) { + $data['name'] = sprintf( + '%s', + $node->getName(), + $node->getName() + ); + + $data['icon'] = ' '; + } else { + $data['name'] = sprintf( + '%s', + $node->getName(), + $node->getName() + ); + + $data['icon'] = ' '; + } + } + + return $this->renderItemTemplate( + new \Text_Template($this->templatePath . 'directory_item.html', '{{', '}}'), + $data + ); + } +} diff --git a/src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/File.php b/src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/File.php new file mode 100644 index 00000000..e6b11ef0 --- /dev/null +++ b/src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/File.php @@ -0,0 +1,541 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SebastianBergmann\CodeCoverage\Report\Html; + +use SebastianBergmann\CodeCoverage\Node\File as FileNode; +use SebastianBergmann\CodeCoverage\Util; + +/** + * Renders a file node. + */ +class File extends Renderer +{ + /** + * @var int + */ + private $htmlspecialcharsFlags; + + /** + * Constructor. + * + * @param string $templatePath + * @param string $generator + * @param string $date + * @param int $lowUpperBound + * @param int $highLowerBound + */ + public function __construct($templatePath, $generator, $date, $lowUpperBound, $highLowerBound) + { + parent::__construct( + $templatePath, + $generator, + $date, + $lowUpperBound, + $highLowerBound + ); + + $this->htmlspecialcharsFlags = ENT_COMPAT; + + $this->htmlspecialcharsFlags = $this->htmlspecialcharsFlags | ENT_HTML401 | ENT_SUBSTITUTE; + } + + /** + * @param FileNode $node + * @param string $file + */ + public function render(FileNode $node, $file) + { + $template = new \Text_Template($this->templatePath . 'file.html', '{{', '}}'); + + $template->setVar( + [ + 'items' => $this->renderItems($node), + 'lines' => $this->renderSource($node) + ] + ); + + $this->setCommonTemplateVariables($template, $node); + + $template->renderTo($file); + } + + /** + * @param FileNode $node + * + * @return string + */ + protected function renderItems(FileNode $node) + { + $template = new \Text_Template($this->templatePath . 'file_item.html', '{{', '}}'); + + $methodItemTemplate = new \Text_Template( + $this->templatePath . 'method_item.html', + '{{', + '}}' + ); + + $items = $this->renderItemTemplate( + $template, + [ + 'name' => 'Total', + 'numClasses' => $node->getNumClassesAndTraits(), + 'numTestedClasses' => $node->getNumTestedClassesAndTraits(), + 'numMethods' => $node->getNumMethods(), + 'numTestedMethods' => $node->getNumTestedMethods(), + 'linesExecutedPercent' => $node->getLineExecutedPercent(false), + 'linesExecutedPercentAsString' => $node->getLineExecutedPercent(), + 'numExecutedLines' => $node->getNumExecutedLines(), + 'numExecutableLines' => $node->getNumExecutableLines(), + 'testedMethodsPercent' => $node->getTestedMethodsPercent(false), + 'testedMethodsPercentAsString' => $node->getTestedMethodsPercent(), + 'testedClassesPercent' => $node->getTestedClassesAndTraitsPercent(false), + 'testedClassesPercentAsString' => $node->getTestedClassesAndTraitsPercent(), + 'crap' => 'CRAP' + ] + ); + + $items .= $this->renderFunctionItems( + $node->getFunctions(), + $methodItemTemplate + ); + + $items .= $this->renderTraitOrClassItems( + $node->getTraits(), + $template, + $methodItemTemplate + ); + + $items .= $this->renderTraitOrClassItems( + $node->getClasses(), + $template, + $methodItemTemplate + ); + + return $items; + } + + /** + * @param array $items + * @param \Text_Template $template + * @param \Text_Template $methodItemTemplate + * + * @return string + */ + protected function renderTraitOrClassItems(array $items, \Text_Template $template, \Text_Template $methodItemTemplate) + { + if (empty($items)) { + return ''; + } + + $buffer = ''; + + foreach ($items as $name => $item) { + $numMethods = count($item['methods']); + $numTestedMethods = 0; + + foreach ($item['methods'] as $method) { + if ($method['executedLines'] == $method['executableLines']) { + $numTestedMethods++; + } + } + + $buffer .= $this->renderItemTemplate( + $template, + [ + 'name' => $name, + 'numClasses' => 1, + 'numTestedClasses' => $numTestedMethods == $numMethods ? 1 : 0, + 'numMethods' => $numMethods, + 'numTestedMethods' => $numTestedMethods, + 'linesExecutedPercent' => Util::percent( + $item['executedLines'], + $item['executableLines'], + false + ), + 'linesExecutedPercentAsString' => Util::percent( + $item['executedLines'], + $item['executableLines'], + true + ), + 'numExecutedLines' => $item['executedLines'], + 'numExecutableLines' => $item['executableLines'], + 'testedMethodsPercent' => Util::percent( + $numTestedMethods, + $numMethods, + false + ), + 'testedMethodsPercentAsString' => Util::percent( + $numTestedMethods, + $numMethods, + true + ), + 'testedClassesPercent' => Util::percent( + $numTestedMethods == $numMethods ? 1 : 0, + 1, + false + ), + 'testedClassesPercentAsString' => Util::percent( + $numTestedMethods == $numMethods ? 1 : 0, + 1, + true + ), + 'crap' => $item['crap'] + ] + ); + + foreach ($item['methods'] as $method) { + $buffer .= $this->renderFunctionOrMethodItem( + $methodItemTemplate, + $method, + ' ' + ); + } + } + + return $buffer; + } + + /** + * @param array $functions + * @param \Text_Template $template + * + * @return string + */ + protected function renderFunctionItems(array $functions, \Text_Template $template) + { + if (empty($functions)) { + return ''; + } + + $buffer = ''; + + foreach ($functions as $function) { + $buffer .= $this->renderFunctionOrMethodItem( + $template, + $function + ); + } + + return $buffer; + } + + /** + * @param \Text_Template $template + * + * @return string + */ + protected function renderFunctionOrMethodItem(\Text_Template $template, array $item, $indent = '') + { + $numTestedItems = $item['executedLines'] == $item['executableLines'] ? 1 : 0; + + return $this->renderItemTemplate( + $template, + [ + 'name' => sprintf( + '%s%s', + $indent, + $item['startLine'], + htmlspecialchars($item['signature']), + isset($item['functionName']) ? $item['functionName'] : $item['methodName'] + ), + 'numMethods' => 1, + 'numTestedMethods' => $numTestedItems, + 'linesExecutedPercent' => Util::percent( + $item['executedLines'], + $item['executableLines'], + false + ), + 'linesExecutedPercentAsString' => Util::percent( + $item['executedLines'], + $item['executableLines'], + true + ), + 'numExecutedLines' => $item['executedLines'], + 'numExecutableLines' => $item['executableLines'], + 'testedMethodsPercent' => Util::percent( + $numTestedItems, + 1, + false + ), + 'testedMethodsPercentAsString' => Util::percent( + $numTestedItems, + 1, + true + ), + 'crap' => $item['crap'] + ] + ); + } + + /** + * @param FileNode $node + * + * @return string + */ + protected function renderSource(FileNode $node) + { + $coverageData = $node->getCoverageData(); + $testData = $node->getTestData(); + $codeLines = $this->loadFile($node->getPath()); + $lines = ''; + $i = 1; + + foreach ($codeLines as $line) { + $trClass = ''; + $popoverContent = ''; + $popoverTitle = ''; + + if (array_key_exists($i, $coverageData)) { + $numTests = count($coverageData[$i]); + + if ($coverageData[$i] === null) { + $trClass = ' class="warning"'; + } elseif ($numTests == 0) { + $trClass = ' class="danger"'; + } else { + $lineCss = 'covered-by-large-tests'; + $popoverContent = '
      '; + + if ($numTests > 1) { + $popoverTitle = $numTests . ' tests cover line ' . $i; + } else { + $popoverTitle = '1 test covers line ' . $i; + } + + foreach ($coverageData[$i] as $test) { + if ($lineCss == 'covered-by-large-tests' && $testData[$test]['size'] == 'medium') { + $lineCss = 'covered-by-medium-tests'; + } elseif ($testData[$test]['size'] == 'small') { + $lineCss = 'covered-by-small-tests'; + } + + switch ($testData[$test]['status']) { + case 0: + switch ($testData[$test]['size']) { + case 'small': + $testCSS = ' class="covered-by-small-tests"'; + break; + + case 'medium': + $testCSS = ' class="covered-by-medium-tests"'; + break; + + default: + $testCSS = ' class="covered-by-large-tests"'; + break; + } + break; + + case 1: + case 2: + $testCSS = ' class="warning"'; + break; + + case 3: + $testCSS = ' class="danger"'; + break; + + case 4: + $testCSS = ' class="danger"'; + break; + + default: + $testCSS = ''; + } + + $popoverContent .= sprintf( + '%s', + $testCSS, + htmlspecialchars($test) + ); + } + + $popoverContent .= '
    '; + $trClass = ' class="' . $lineCss . ' popin"'; + } + } + + if (!empty($popoverTitle)) { + $popover = sprintf( + ' data-title="%s" data-content="%s" data-placement="bottom" data-html="true"', + $popoverTitle, + htmlspecialchars($popoverContent) + ); + } else { + $popover = ''; + } + + $lines .= sprintf( + ' %s' . "\n", + $trClass, + $popover, + $i, + $i, + $i, + $line + ); + + $i++; + } + + return $lines; + } + + /** + * @param string $file + * + * @return array + */ + protected function loadFile($file) + { + $buffer = file_get_contents($file); + $tokens = token_get_all($buffer); + $result = ['']; + $i = 0; + $stringFlag = false; + $fileEndsWithNewLine = substr($buffer, -1) == "\n"; + + unset($buffer); + + foreach ($tokens as $j => $token) { + if (is_string($token)) { + if ($token === '"' && $tokens[$j - 1] !== '\\') { + $result[$i] .= sprintf( + '%s', + htmlspecialchars($token) + ); + + $stringFlag = !$stringFlag; + } else { + $result[$i] .= sprintf( + '%s', + htmlspecialchars($token) + ); + } + + continue; + } + + list($token, $value) = $token; + + $value = str_replace( + ["\t", ' '], + ['    ', ' '], + htmlspecialchars($value, $this->htmlspecialcharsFlags) + ); + + if ($value === "\n") { + $result[++$i] = ''; + } else { + $lines = explode("\n", $value); + + foreach ($lines as $jj => $line) { + $line = trim($line); + + if ($line !== '') { + if ($stringFlag) { + $colour = 'string'; + } else { + switch ($token) { + case T_INLINE_HTML: + $colour = 'html'; + break; + + case T_COMMENT: + case T_DOC_COMMENT: + $colour = 'comment'; + break; + + case T_ABSTRACT: + case T_ARRAY: + case T_AS: + case T_BREAK: + case T_CALLABLE: + case T_CASE: + case T_CATCH: + case T_CLASS: + case T_CLONE: + case T_CONTINUE: + case T_DEFAULT: + case T_ECHO: + case T_ELSE: + case T_ELSEIF: + case T_EMPTY: + case T_ENDDECLARE: + case T_ENDFOR: + case T_ENDFOREACH: + case T_ENDIF: + case T_ENDSWITCH: + case T_ENDWHILE: + case T_EXIT: + case T_EXTENDS: + case T_FINAL: + case T_FINALLY: + case T_FOREACH: + case T_FUNCTION: + case T_GLOBAL: + case T_IF: + case T_IMPLEMENTS: + case T_INCLUDE: + case T_INCLUDE_ONCE: + case T_INSTANCEOF: + case T_INSTEADOF: + case T_INTERFACE: + case T_ISSET: + case T_LOGICAL_AND: + case T_LOGICAL_OR: + case T_LOGICAL_XOR: + case T_NAMESPACE: + case T_NEW: + case T_PRIVATE: + case T_PROTECTED: + case T_PUBLIC: + case T_REQUIRE: + case T_REQUIRE_ONCE: + case T_RETURN: + case T_STATIC: + case T_THROW: + case T_TRAIT: + case T_TRY: + case T_UNSET: + case T_USE: + case T_VAR: + case T_WHILE: + case T_YIELD: + $colour = 'keyword'; + break; + + default: + $colour = 'default'; + } + } + + $result[$i] .= sprintf( + '%s', + $colour, + $line + ); + } + + if (isset($lines[$jj + 1])) { + $result[++$i] = ''; + } + } + } + } + + if ($fileEndsWithNewLine) { + unset($result[count($result)-1]); + } + + return $result; + } +} diff --git a/src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/coverage_bar.html.dist b/src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/coverage_bar.html.dist new file mode 100644 index 00000000..5a09c354 --- /dev/null +++ b/src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/coverage_bar.html.dist @@ -0,0 +1,5 @@ +
    +
    + {{percent}}% covered ({{level}}) +
    +
    diff --git a/src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/css/bootstrap.min.css b/src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/css/bootstrap.min.css new file mode 100644 index 00000000..4cf729e4 --- /dev/null +++ b/src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/css/bootstrap.min.css @@ -0,0 +1,6 @@ +/*! + * Bootstrap v3.3.6 (http://getbootstrap.com) + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + *//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0;font-size:2em}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,:after,:before{color:#000!important;text-shadow:none!important;background:0 0!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="javascript:"]:after,a[href^="#"]:after{content:""}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff2) format('woff2'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\002a"}.glyphicon-plus:before{content:"\002b"}.glyphicon-eur:before,.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.glyphicon-cd:before{content:"\e201"}.glyphicon-save-file:before{content:"\e202"}.glyphicon-open-file:before{content:"\e203"}.glyphicon-level-up:before{content:"\e204"}.glyphicon-copy:before{content:"\e205"}.glyphicon-paste:before{content:"\e206"}.glyphicon-alert:before{content:"\e209"}.glyphicon-equalizer:before{content:"\e210"}.glyphicon-king:before{content:"\e211"}.glyphicon-queen:before{content:"\e212"}.glyphicon-pawn:before{content:"\e213"}.glyphicon-bishop:before{content:"\e214"}.glyphicon-knight:before{content:"\e215"}.glyphicon-baby-formula:before{content:"\e216"}.glyphicon-tent:before{content:"\26fa"}.glyphicon-blackboard:before{content:"\e218"}.glyphicon-bed:before{content:"\e219"}.glyphicon-apple:before{content:"\f8ff"}.glyphicon-erase:before{content:"\e221"}.glyphicon-hourglass:before{content:"\231b"}.glyphicon-lamp:before{content:"\e223"}.glyphicon-duplicate:before{content:"\e224"}.glyphicon-piggy-bank:before{content:"\e225"}.glyphicon-scissors:before{content:"\e226"}.glyphicon-bitcoin:before{content:"\e227"}.glyphicon-btc:before{content:"\e227"}.glyphicon-xbt:before{content:"\e227"}.glyphicon-yen:before{content:"\00a5"}.glyphicon-jpy:before{content:"\00a5"}.glyphicon-ruble:before{content:"\20bd"}.glyphicon-rub:before{content:"\20bd"}.glyphicon-scale:before{content:"\e230"}.glyphicon-ice-lolly:before{content:"\e231"}.glyphicon-ice-lolly-tasted:before{content:"\e232"}.glyphicon-education:before{content:"\e233"}.glyphicon-option-horizontal:before{content:"\e234"}.glyphicon-option-vertical:before{content:"\e235"}.glyphicon-menu-hamburger:before{content:"\e236"}.glyphicon-modal-window:before{content:"\e237"}.glyphicon-oil:before{content:"\e238"}.glyphicon-grain:before{content:"\e239"}.glyphicon-sunglasses:before{content:"\e240"}.glyphicon-text-size:before{content:"\e241"}.glyphicon-text-color:before{content:"\e242"}.glyphicon-text-background:before{content:"\e243"}.glyphicon-object-align-top:before{content:"\e244"}.glyphicon-object-align-bottom:before{content:"\e245"}.glyphicon-object-align-horizontal:before{content:"\e246"}.glyphicon-object-align-left:before{content:"\e247"}.glyphicon-object-align-vertical:before{content:"\e248"}.glyphicon-object-align-right:before{content:"\e249"}.glyphicon-triangle-right:before{content:"\e250"}.glyphicon-triangle-left:before{content:"\e251"}.glyphicon-triangle-bottom:before{content:"\e252"}.glyphicon-triangle-top:before{content:"\e253"}.glyphicon-console:before{content:"\e254"}.glyphicon-superscript:before{content:"\e255"}.glyphicon-subscript:before{content:"\e256"}.glyphicon-menu-left:before{content:"\e257"}.glyphicon-menu-right:before{content:"\e258"}.glyphicon-menu-down:before{content:"\e259"}.glyphicon-menu-up:before{content:"\e260"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:after,:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:focus,a:hover{color:#23527c;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.carousel-inner>.item>a>img,.carousel-inner>.item>img,.img-responsive,.thumbnail a>img,.thumbnail>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{display:inline-block;max-width:100%;height:auto;padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role=button]{cursor:pointer}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-weight:400;line-height:1;color:#777}.h1,.h2,.h3,h1,h2,h3{margin-top:20px;margin-bottom:10px}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small{font-size:65%}.h4,.h5,.h6,h4,h5,h6{margin-top:10px;margin-bottom:10px}.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-size:75%}.h1,h1{font-size:36px}.h2,h2{font-size:30px}.h3,h3{font-size:24px}.h4,h4{font-size:18px}.h5,h5{font-size:14px}.h6,h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}.small,small{font-size:85%}.mark,mark{padding:.2em;background-color:#fcf8e3}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:focus,a.text-primary:hover{color:#286090}.text-success{color:#3c763d}a.text-success:focus,a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:focus,a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:focus,a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:focus,a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:focus,a.bg-primary:hover{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:focus,a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:focus,a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:focus,a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:focus,a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ol,ul{margin-top:0;margin-bottom:10px}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;margin-left:-5px;list-style:none}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-top:0;margin-bottom:20px}dd,dt{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[data-original-title],abbr[title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote ol:last-child,blockquote p:last-child,blockquote ul:last-child{margin-bottom:0}blockquote .small,blockquote footer,blockquote small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote .small:before,blockquote footer:before,blockquote small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eee;border-left:0}.blockquote-reverse .small:before,.blockquote-reverse footer:before,.blockquote-reverse small:before,blockquote.pull-right .small:before,blockquote.pull-right footer:before,blockquote.pull-right small:before{content:''}.blockquote-reverse .small:after,.blockquote-reverse footer:after,.blockquote-reverse small:after,blockquote.pull-right .small:after,blockquote.pull-right footer:after,blockquote.pull-right small:after{content:'\00A0 \2014'}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}kbd kbd{padding:0;font-size:100%;font-weight:700;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{margin-right:-15px;margin-left:-15px}.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>tbody>tr>td,.table>tbody>tr>th,.table>tfoot>tr>td,.table>tfoot>tr>th,.table>thead>tr>td,.table>thead>tr>th{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>td,.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>td,.table>thead:first-child>tr:first-child>th{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>tbody>tr>td,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>td,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>thead>tr>th{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>tbody>tr>td,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>td,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border:1px solid #ddd}.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*=col-]{position:static;display:table-column;float:none}table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;float:none}.table>tbody>tr.active>td,.table>tbody>tr.active>th,.table>tbody>tr>td.active,.table>tbody>tr>th.active,.table>tfoot>tr.active>td,.table>tfoot>tr.active>th,.table>tfoot>tr>td.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>thead>tr.active>th,.table>thead>tr>td.active,.table>thead>tr>th.active{background-color:#f5f5f5}.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover{background-color:#e8e8e8}.table>tbody>tr.success>td,.table>tbody>tr.success>th,.table>tbody>tr>td.success,.table>tbody>tr>th.success,.table>tfoot>tr.success>td,.table>tfoot>tr.success>th,.table>tfoot>tr>td.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>thead>tr.success>th,.table>thead>tr>td.success,.table>thead>tr>th.success{background-color:#dff0d8}.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover{background-color:#d0e9c6}.table>tbody>tr.info>td,.table>tbody>tr.info>th,.table>tbody>tr>td.info,.table>tbody>tr>th.info,.table>tfoot>tr.info>td,.table>tfoot>tr.info>th,.table>tfoot>tr>td.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>thead>tr.info>th,.table>thead>tr>td.info,.table>thead>tr>th.info{background-color:#d9edf7}.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover{background-color:#c4e3f3}.table>tbody>tr.warning>td,.table>tbody>tr.warning>th,.table>tbody>tr>td.warning,.table>tbody>tr>th.warning,.table>tfoot>tr.warning>td,.table>tfoot>tr.warning>th,.table>tfoot>tr>td.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>thead>tr.warning>th,.table>thead>tr>td.warning,.table>thead>tr>th.warning{background-color:#fcf8e3}.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover{background-color:#faf2cc}.table>tbody>tr.danger>td,.table>tbody>tr.danger>th,.table>tbody>tr>td.danger,.table>tbody>tr>th.danger,.table>tfoot>tr.danger>td,.table>tfoot>tr.danger>th,.table>tfoot>tr>td.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>thead>tr.danger>th,.table>thead>tr>td.danger,.table>thead>tr>th.danger{background-color:#f2dede}.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover{background-color:#ebcccc}.table-responsive{min-height:.01%;overflow-x:auto}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>td,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>thead>tr>th{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=checkbox],input[type=radio]{margin:4px 0 0;margin-top:1px\9;line-height:normal}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=file]:focus,input[type=checkbox]:focus,input[type=radio]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control::-ms-expand{background-color:transparent;border:0}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#eee;opacity:1}.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed}textarea.form-control{height:auto}input[type=search]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type=date].form-control,input[type=time].form-control,input[type=datetime-local].form-control,input[type=month].form-control{line-height:34px}.input-group-sm input[type=date],.input-group-sm input[type=time],.input-group-sm input[type=datetime-local],.input-group-sm input[type=month],input[type=date].input-sm,input[type=time].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm{line-height:30px}.input-group-lg input[type=date],.input-group-lg input[type=time],.input-group-lg input[type=datetime-local],.input-group-lg input[type=month],input[type=date].input-lg,input[type=time].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg{line-height:46px}}.form-group{margin-bottom:15px}.checkbox,.radio{position:relative;display:block;margin-top:10px;margin-bottom:10px}.checkbox label,.radio label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox],.radio input[type=radio],.radio-inline input[type=radio]{position:absolute;margin-top:4px\9;margin-left:-20px}.checkbox+.checkbox,.radio+.radio{margin-top:-5px}.checkbox-inline,.radio-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.checkbox-inline+.checkbox-inline,.radio-inline+.radio-inline{margin-top:0;margin-left:10px}fieldset[disabled] input[type=checkbox],fieldset[disabled] input[type=radio],input[type=checkbox].disabled,input[type=checkbox][disabled],input[type=radio].disabled,input[type=radio][disabled]{cursor:not-allowed}.checkbox-inline.disabled,.radio-inline.disabled,fieldset[disabled] .checkbox-inline,fieldset[disabled] .radio-inline{cursor:not-allowed}.checkbox.disabled label,.radio.disabled label,fieldset[disabled] .checkbox label,fieldset[disabled] .radio label{cursor:not-allowed}.form-control-static{min-height:34px;padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-right:0;padding-left:0}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}select[multiple].input-sm,textarea.input-sm{height:auto}.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.form-group-sm select.form-control{height:30px;line-height:30px}.form-group-sm select[multiple].form-control,.form-group-sm textarea.form-control{height:auto}.form-group-sm .form-control-static{height:30px;min-height:32px;padding:6px 10px;font-size:12px;line-height:1.5}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-lg{height:46px;line-height:46px}select[multiple].input-lg,textarea.input-lg{height:auto}.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.form-group-lg select.form-control{height:46px;line-height:46px}.form-group-lg select[multiple].form-control,.form-group-lg textarea.form-control{height:auto}.form-group-lg .form-control-static{height:46px;min-height:38px;padding:11px 16px;font-size:18px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.form-group-lg .form-control+.form-control-feedback,.input-group-lg+.form-control-feedback,.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.form-group-sm .form-control+.form-control-feedback,.input-group-sm+.form-control-feedback,.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .checkbox,.has-success .checkbox-inline,.has-success .control-label,.has-success .help-block,.has-success .radio,.has-success .radio-inline,.has-success.checkbox label,.has-success.checkbox-inline label,.has-success.radio label,.has-success.radio-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.has-success .form-control-feedback{color:#3c763d}.has-warning .checkbox,.has-warning .checkbox-inline,.has-warning .control-label,.has-warning .help-block,.has-warning .radio,.has-warning .radio-inline,.has-warning.checkbox label,.has-warning.checkbox-inline label,.has-warning.radio label,.has-warning.radio-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .checkbox,.has-error .checkbox-inline,.has-error .control-label,.has-error .help-block,.has-error .radio,.has-error .radio-inline,.has-error.checkbox label,.has-error.checkbox-inline label,.has-error.radio label,.has-error.radio-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .form-control,.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .checkbox,.form-inline .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .checkbox label,.form-inline .radio label{padding-left:0}.form-inline .checkbox input[type=checkbox],.form-inline .radio input[type=radio]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .checkbox,.form-horizontal .checkbox-inline,.form-horizontal .radio,.form-horizontal .radio-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .checkbox,.form-horizontal .radio{min-height:27px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.form-horizontal .control-label{padding-top:7px;margin-bottom:0;text-align:right}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:11px;font-size:18px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px;font-size:12px}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px}.btn.active.focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn:active:focus,.btn:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.focus,.btn:focus,.btn:hover{color:#333;text-decoration:none}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none;opacity:.65}a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default.focus,.btn-default:focus{color:#333;background-color:#e6e6e6;border-color:#8c8c8c}.btn-default:hover{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active.focus,.btn-default.active:focus,.btn-default.active:hover,.btn-default:active.focus,.btn-default:active:focus,.btn-default:active:hover,.open>.dropdown-toggle.btn-default.focus,.open>.dropdown-toggle.btn-default:focus,.open>.dropdown-toggle.btn-default:hover{color:#333;background-color:#d4d4d4;border-color:#8c8c8c}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled.focus,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled].focus,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary.focus,.btn-primary:focus{color:#fff;background-color:#286090;border-color:#122b40}.btn-primary:hover{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active.focus,.btn-primary.active:focus,.btn-primary.active:hover,.btn-primary:active.focus,.btn-primary:active:focus,.btn-primary:active:hover,.open>.dropdown-toggle.btn-primary.focus,.open>.dropdown-toggle.btn-primary:focus,.open>.dropdown-toggle.btn-primary:hover{color:#fff;background-color:#204d74;border-color:#122b40}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled.focus,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled].focus,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success.focus,.btn-success:focus{color:#fff;background-color:#449d44;border-color:#255625}.btn-success:hover{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active.focus,.btn-success.active:focus,.btn-success.active:hover,.btn-success:active.focus,.btn-success:active:focus,.btn-success:active:hover,.open>.dropdown-toggle.btn-success.focus,.open>.dropdown-toggle.btn-success:focus,.open>.dropdown-toggle.btn-success:hover{color:#fff;background-color:#398439;border-color:#255625}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled.focus,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled].focus,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info.focus,.btn-info:focus{color:#fff;background-color:#31b0d5;border-color:#1b6d85}.btn-info:hover{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active.focus,.btn-info.active:focus,.btn-info.active:hover,.btn-info:active.focus,.btn-info:active:focus,.btn-info:active:hover,.open>.dropdown-toggle.btn-info.focus,.open>.dropdown-toggle.btn-info:focus,.open>.dropdown-toggle.btn-info:hover{color:#fff;background-color:#269abc;border-color:#1b6d85}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled.focus,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled].focus,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning.focus,.btn-warning:focus{color:#fff;background-color:#ec971f;border-color:#985f0d}.btn-warning:hover{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active.focus,.btn-warning.active:focus,.btn-warning.active:hover,.btn-warning:active.focus,.btn-warning:active:focus,.btn-warning:active:hover,.open>.dropdown-toggle.btn-warning.focus,.open>.dropdown-toggle.btn-warning:focus,.open>.dropdown-toggle.btn-warning:hover{color:#fff;background-color:#d58512;border-color:#985f0d}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled.focus,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled].focus,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger.focus,.btn-danger:focus{color:#fff;background-color:#c9302c;border-color:#761c19}.btn-danger:hover{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active.focus,.btn-danger.active:focus,.btn-danger.active:hover,.btn-danger:active.focus,.btn-danger:active:focus,.btn-danger:active:hover,.open>.dropdown-toggle.btn-danger.focus,.open>.dropdown-toggle.btn-danger:focus,.open>.dropdown-toggle.btn-danger:hover{color:#fff;background-color:#ac2925;border-color:#761c19}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled.focus,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled].focus,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:400;color:#337ab7;border-radius:0}.btn-link,.btn-link.active,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:active,.btn-link:focus,.btn-link:hover{border-color:transparent}.btn-link:focus,.btn-link:hover{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:focus,.btn-link[disabled]:hover,fieldset[disabled] .btn-link:focus,fieldset[disabled] .btn-link:hover{color:#777;text-decoration:none}.btn-group-lg>.btn,.btn-lg{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.btn-group-sm>.btn,.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-group-xs>.btn,.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease;-webkit-transition-duration:.35s;-o-transition-duration:.35s;transition-duration:.35s;-webkit-transition-property:height,visibility;-o-transition-property:height,visibility;transition-property:height,visibility}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-top:4px solid\9;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown,.dropup{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175)}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{color:#fff;text-decoration:none;background-color:#337ab7;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{color:#777}.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:"";border-top:0;border-bottom:4px dashed;border-bottom:4px solid\9}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{right:auto;left:0}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;float:left}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn,.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-left-radius:0;border-top-right-radius:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn input[type=radio],[data-toggle=buttons]>.btn-group>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group .form-control:focus{z-index:3}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn,textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn,textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn{height:auto}.input-group .form-control,.input-group-addon,.input-group-btn{display:table-cell}.input-group .form-control:not(:first-child):not(:last-child),.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=checkbox],.input-group-addon input[type=radio]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn-group:not(:last-child)>.btn,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:first-child>.btn-group:not(:first-child)>.btn,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:active,.input-group-btn>.btn:focus,.input-group-btn>.btn:hover{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{z-index:2;margin-left:-1px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:focus,.nav>li>a:hover{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:focus,.nav>li.disabled>a:hover{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:focus,.nav .open>a:hover{background-color:#eee;border-color:#337ab7}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:focus,.nav-tabs>li.active>a:hover{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:focus,.nav-pills>li.active>a:hover{color:#fff;background-color:#337ab7}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{padding-right:15px;padding-left:15px;overflow-x:visible;-webkit-overflow-scrolling:touch;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1)}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse{padding-right:0;padding-left:0}}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:340px}@media (max-device-width:480px) and (orientation:landscape){.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:200px}}.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-bottom,.navbar-fixed-top{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-bottom,.navbar-fixed-top{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;height:50px;padding:15px 15px;font-size:18px;line-height:20px}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-brand>img{display:block}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu .dropdown-header,.navbar-nav .open .dropdown-menu>li>a{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:focus,.navbar-nav .open .dropdown-menu>li>a:hover{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}.navbar-form{padding:10px 15px;margin-top:8px;margin-right:-15px;margin-bottom:8px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1)}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .form-control,.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .checkbox,.navbar-form .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .checkbox label,.navbar-form .radio label{padding-left:0}.navbar-form .checkbox input[type=checkbox],.navbar-form .radio input[type=radio]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:focus,.navbar-default .navbar-brand:hover{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:focus,.navbar-default .navbar-nav>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:focus,.navbar-default .navbar-nav>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:focus,.navbar-default .navbar-nav>.disabled>a:hover{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:focus,.navbar-default .navbar-toggle:hover{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:focus,.navbar-default .navbar-nav>.open>a:hover{color:#555;background-color:#e7e7e7}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:focus,.navbar-default .btn-link:hover{color:#333}.navbar-default .btn-link[disabled]:focus,.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:focus,fieldset[disabled] .navbar-default .btn-link:hover{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#9d9d9d}.navbar-inverse .navbar-brand:focus,.navbar-inverse .navbar-brand:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a:focus,.navbar-inverse .navbar-nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:focus,.navbar-inverse .navbar-nav>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:focus,.navbar-inverse .navbar-nav>.disabled>a:hover{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:focus,.navbar-inverse .navbar-toggle:hover{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:focus,.navbar-inverse .navbar-nav>.open>a:hover{color:#fff;background-color:#080808}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#9d9d9d}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#9d9d9d}.navbar-inverse .btn-link:focus,.navbar-inverse .btn-link:hover{color:#fff}.navbar-inverse .btn-link[disabled]:focus,.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:focus,fieldset[disabled] .navbar-inverse .btn-link:hover{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#337ab7;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>li>a:focus,.pagination>li>a:hover,.pagination>li>span:focus,.pagination>li>span:hover{z-index:2;color:#23527c;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>a:focus,.pagination>.active>a:hover,.pagination>.active>span,.pagination>.active>span:focus,.pagination>.active>span:hover{z-index:3;color:#fff;cursor:default;background-color:#337ab7;border-color:#337ab7}.pagination>.disabled>a,.pagination>.disabled>a:focus,.pagination>.disabled>a:hover,.pagination>.disabled>span,.pagination>.disabled>span:focus,.pagination>.disabled>span:hover{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px;line-height:1.3333333}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px;line-height:1.5}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:focus,.pager li>a:hover{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:focus,.pager .disabled>a:hover,.pager .disabled>span{color:#777;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:focus,a.label:hover{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:focus,.label-default[href]:hover{background-color:#5e5e5e}.label-primary{background-color:#337ab7}.label-primary[href]:focus,.label-primary[href]:hover{background-color:#286090}.label-success{background-color:#5cb85c}.label-success[href]:focus,.label-success[href]:hover{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:focus,.label-info[href]:hover{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:focus,.label-warning[href]:hover{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:focus,.label-danger[href]:hover{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:middle;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-group-xs>.btn .badge,.btn-xs .badge{top:0;padding:1px 5px}a.badge:focus,a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#337ab7;background-color:#fff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding-top:30px;padding-bottom:30px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron .h1,.jumbotron h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron,.container-fluid .jumbotron{padding-right:15px;padding-left:15px;border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron,.container-fluid .jumbotron{padding-right:60px;padding-left:60px}.jumbotron .h1,.jumbotron h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail a>img,.thumbnail>img{margin-right:auto;margin-left:auto}a.thumbnail.active,a.thumbnail:focus,a.thumbnail:hover{border-color:#337ab7}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#337ab7;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-bar-striped,.progress-striped .progress-bar{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress-bar.active,.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{overflow:hidden;zoom:1}.media-body{width:10000px}.media-object{display:block}.media-object.img-thumbnail{max-width:none}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-body,.media-left,.media-right{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}a.list-group-item,button.list-group-item{color:#555}a.list-group-item .list-group-item-heading,button.list-group-item .list-group-item-heading{color:#333}a.list-group-item:focus,a.list-group-item:hover,button.list-group-item:focus,button.list-group-item:hover{color:#555;text-decoration:none;background-color:#f5f5f5}button.list-group-item{width:100%;text-align:left}.list-group-item.disabled,.list-group-item.disabled:focus,.list-group-item.disabled:hover{color:#777;cursor:not-allowed;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{z-index:2;color:#fff;background-color:#337ab7;border-color:#337ab7}.list-group-item.active .list-group-item-heading,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:focus .list-group-item-text,.list-group-item.active:hover .list-group-item-text{color:#c7ddef}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success,button.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading,button.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:focus,a.list-group-item-success:hover,button.list-group-item-success:focus,button.list-group-item-success:hover{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:focus,a.list-group-item-success.active:hover,button.list-group-item-success.active,button.list-group-item-success.active:focus,button.list-group-item-success.active:hover{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info,button.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading,button.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:focus,a.list-group-item-info:hover,button.list-group-item-info:focus,button.list-group-item-info:hover{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:focus,a.list-group-item-info.active:hover,button.list-group-item-info.active,button.list-group-item-info.active:focus,button.list-group-item-info.active:hover{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning,button.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading,button.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:focus,a.list-group-item-warning:hover,button.list-group-item-warning:focus,button.list-group-item-warning:hover{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:focus,a.list-group-item-warning.active:hover,button.list-group-item-warning.active,button.list-group-item-warning.active:focus,button.list-group-item-warning.active:hover{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger,button.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading,button.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:focus,a.list-group-item-danger:hover,button.list-group-item-danger:focus,button.list-group-item-danger:hover{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:focus,a.list-group-item-danger.active:hover,button.list-group-item-danger.active,button.list-group-item-danger.active:focus,button.list-group-item-danger.active:hover{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-left-radius:3px;border-top-right-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>.small,.panel-title>.small>a,.panel-title>a,.panel-title>small,.panel-title>small>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.panel-heading+.panel-collapse>.list-group .list-group-item:first-child{border-top-left-radius:0;border-top-right-radius:0}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.panel-collapse>.table,.panel>.table,.panel>.table-responsive>.table{margin-bottom:0}.panel>.panel-collapse>.table caption,.panel>.table caption,.panel>.table-responsive>.table caption{padding-right:15px;padding-left:15px}.panel>.table-responsive:first-child>.table:first-child,.panel>.table:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table:first-child>thead:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table-responsive:last-child>.table:last-child,.panel>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child td,.panel>.table>tbody:first-child>tr:first-child th{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.list-group,.panel-group .panel-heading+.panel-collapse>.panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#337ab7}.panel-primary>.panel-heading{color:#fff;background-color:#337ab7;border-color:#337ab7}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#337ab7}.panel-primary>.panel-heading .badge{color:#337ab7;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#337ab7}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;filter:alpha(opacity=20);opacity:.2}.close:focus,.close:hover{color:#000;text-decoration:none;cursor:pointer;filter:alpha(opacity=50);opacity:.5}button.close{-webkit-appearance:none;padding:0;cursor:pointer;background:0 0;border:0}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;display:none;overflow:hidden;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out;-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);-o-transform:translate(0,-25%);transform:translate(0,-25%)}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0,0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5)}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{filter:alpha(opacity=0);opacity:0}.modal-backdrop.in{filter:alpha(opacity=50);opacity:.5}.modal-header{padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:12px;font-style:normal;font-weight:400;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;filter:alpha(opacity=0);opacity:0;line-break:auto}.tooltip.in{filter:alpha(opacity=90);opacity:.9}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{right:5px;bottom:0;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;font-style:normal;font-weight:400;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);line-break:auto}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{content:"";border-width:10px}.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,.25);border-bottom-width:0}.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:" ";border-top-color:#fff;border-bottom-width:0}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,.25);border-left-width:0}.popover.right>.arrow:after{bottom:-10px;left:1px;content:" ";border-right-color:#fff;border-left-width:0}.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25)}.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:" ";border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{right:1px;bottom:-10px;content:" ";border-right-width:0;border-left-color:#fff}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>a>img,.carousel-inner>.item>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px}.carousel-inner>.item.active.right,.carousel-inner>.item.next{left:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.carousel-inner>.item.active.left,.carousel-inner>.item.prev{left:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.carousel-inner>.item.active,.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right{left:0;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);background-color:rgba(0,0,0,0);filter:alpha(opacity=50);opacity:.5}.carousel-control.left{background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,.0001)));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);background-repeat:repeat-x}.carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.0001)),to(rgba(0,0,0,.5)));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);background-repeat:repeat-x}.carousel-control:focus,.carousel-control:hover{color:#fff;text-decoration:none;filter:alpha(opacity=90);outline:0;opacity:.9}.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{position:absolute;top:50%;z-index:5;display:inline-block;margin-top:-10px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{left:50%;margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{right:50%;margin-right:-10px}.carousel-control .icon-next,.carousel-control .icon-prev{width:20px;height:20px;font-family:serif;line-height:1}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000\9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{width:30px;height:30px;margin-top:-10px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-10px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.btn-group-vertical>.btn-group:after,.btn-group-vertical>.btn-group:before,.btn-toolbar:after,.btn-toolbar:before,.clearfix:after,.clearfix:before,.container-fluid:after,.container-fluid:before,.container:after,.container:before,.dl-horizontal dd:after,.dl-horizontal dd:before,.form-horizontal .form-group:after,.form-horizontal .form-group:before,.modal-footer:after,.modal-footer:before,.modal-header:after,.modal-header:before,.nav:after,.nav:before,.navbar-collapse:after,.navbar-collapse:before,.navbar-header:after,.navbar-header:before,.navbar:after,.navbar:before,.pager:after,.pager:before,.panel-body:after,.panel-body:before,.row:after,.row:before{display:table;content:" "}.btn-group-vertical>.btn-group:after,.btn-toolbar:after,.clearfix:after,.container-fluid:after,.container:after,.dl-horizontal dd:after,.form-horizontal .form-group:after,.modal-footer:after,.modal-header:after,.nav:after,.navbar-collapse:after,.navbar-header:after,.navbar:after,.pager:after,.panel-body:after,.row:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-lg,.visible-md,.visible-sm,.visible-xs{display:none!important}.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table!important}tr.visible-xs{display:table-row!important}td.visible-xs,th.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table!important}tr.visible-sm{display:table-row!important}td.visible-sm,th.visible-sm{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table!important}tr.visible-md{display:table-row!important}td.visible-md,th.visible-md{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table!important}tr.visible-lg{display:table-row!important}td.visible-lg,th.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table!important}tr.visible-print{display:table-row!important}td.visible-print,th.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}} +/*# sourceMappingURL=bootstrap.min.css.map */ \ No newline at end of file diff --git a/src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/css/nv.d3.min.css b/src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/css/nv.d3.min.css new file mode 100644 index 00000000..7a6f7fe9 --- /dev/null +++ b/src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/css/nv.d3.min.css @@ -0,0 +1 @@ +.nvd3 .nv-axis{pointer-events:none;opacity:1}.nvd3 .nv-axis path{fill:none;stroke:#000;stroke-opacity:.75;shape-rendering:crispEdges}.nvd3 .nv-axis path.domain{stroke-opacity:.75}.nvd3 .nv-axis.nv-x path.domain{stroke-opacity:0}.nvd3 .nv-axis line{fill:none;stroke:#e5e5e5;shape-rendering:crispEdges}.nvd3 .nv-axis .zero line,.nvd3 .nv-axis line.zero{stroke-opacity:.75}.nvd3 .nv-axis .nv-axisMaxMin text{font-weight:700}.nvd3 .x .nv-axis .nv-axisMaxMin text,.nvd3 .x2 .nv-axis .nv-axisMaxMin text,.nvd3 .x3 .nv-axis .nv-axisMaxMin text{text-anchor:middle}.nvd3 .nv-axis.nv-disabled{opacity:0}.nvd3 .nv-bars rect{fill-opacity:.75;transition:fill-opacity 250ms linear;-moz-transition:fill-opacity 250ms linear;-webkit-transition:fill-opacity 250ms linear}.nvd3 .nv-bars rect.hover{fill-opacity:1}.nvd3 .nv-bars .hover rect{fill:#add8e6}.nvd3 .nv-bars text{fill:rgba(0,0,0,0)}.nvd3 .nv-bars .hover text{fill:rgba(0,0,0,1)}.nvd3 .nv-multibar .nv-groups rect,.nvd3 .nv-multibarHorizontal .nv-groups rect,.nvd3 .nv-discretebar .nv-groups rect{stroke-opacity:0;transition:fill-opacity 250ms linear;-moz-transition:fill-opacity 250ms linear;-webkit-transition:fill-opacity 250ms linear}.nvd3 .nv-multibar .nv-groups rect:hover,.nvd3 .nv-multibarHorizontal .nv-groups rect:hover,.nvd3 .nv-candlestickBar .nv-ticks rect:hover,.nvd3 .nv-discretebar .nv-groups rect:hover{fill-opacity:1}.nvd3 .nv-discretebar .nv-groups text,.nvd3 .nv-multibarHorizontal .nv-groups text{font-weight:700;fill:rgba(0,0,0,1);stroke:rgba(0,0,0,0)}.nvd3 .nv-boxplot circle{fill-opacity:.5}.nvd3 .nv-boxplot circle:hover{fill-opacity:1}.nvd3 .nv-boxplot rect:hover{fill-opacity:1}.nvd3 line.nv-boxplot-median{stroke:#000}.nv-boxplot-tick:hover{stroke-width:2.5px}.nvd3.nv-bullet{font:10px sans-serif}.nvd3.nv-bullet .nv-measure{fill-opacity:.8}.nvd3.nv-bullet .nv-measure:hover{fill-opacity:1}.nvd3.nv-bullet .nv-marker{stroke:#000;stroke-width:2px}.nvd3.nv-bullet .nv-markerTriangle{stroke:#000;fill:#fff;stroke-width:1.5px}.nvd3.nv-bullet .nv-tick line{stroke:#666;stroke-width:.5px}.nvd3.nv-bullet .nv-range.nv-s0{fill:#eee}.nvd3.nv-bullet .nv-range.nv-s1{fill:#ddd}.nvd3.nv-bullet .nv-range.nv-s2{fill:#ccc}.nvd3.nv-bullet .nv-title{font-size:14px;font-weight:700}.nvd3.nv-bullet .nv-subtitle{fill:#999}.nvd3.nv-bullet .nv-range{fill:#bababa;fill-opacity:.4}.nvd3.nv-bullet .nv-range:hover{fill-opacity:.7}.nvd3.nv-candlestickBar .nv-ticks .nv-tick{stroke-width:1px}.nvd3.nv-candlestickBar .nv-ticks .nv-tick.hover{stroke-width:2px}.nvd3.nv-candlestickBar .nv-ticks .nv-tick.positive rect{stroke:#2ca02c;fill:#2ca02c}.nvd3.nv-candlestickBar .nv-ticks .nv-tick.negative rect{stroke:#d62728;fill:#d62728}.with-transitions .nv-candlestickBar .nv-ticks .nv-tick{transition:stroke-width 250ms linear,stroke-opacity 250ms linear;-moz-transition:stroke-width 250ms linear,stroke-opacity 250ms linear;-webkit-transition:stroke-width 250ms linear,stroke-opacity 250ms linear}.nvd3.nv-candlestickBar .nv-ticks line{stroke:#333}.nvd3 .nv-legend .nv-disabled rect{}.nvd3 .nv-check-box .nv-box{fill-opacity:0;stroke-width:2}.nvd3 .nv-check-box .nv-check{fill-opacity:0;stroke-width:4}.nvd3 .nv-series.nv-disabled .nv-check-box .nv-check{fill-opacity:0;stroke-opacity:0}.nvd3 .nv-controlsWrap .nv-legend .nv-check-box .nv-check{opacity:0}.nvd3.nv-linePlusBar .nv-bar rect{fill-opacity:.75}.nvd3.nv-linePlusBar .nv-bar rect:hover{fill-opacity:1}.nvd3 .nv-groups path.nv-line{fill:none}.nvd3 .nv-groups path.nv-area{stroke:none}.nvd3.nv-line .nvd3.nv-scatter .nv-groups .nv-point{fill-opacity:0;stroke-opacity:0}.nvd3.nv-scatter.nv-single-point .nv-groups .nv-point{fill-opacity:.5!important;stroke-opacity:.5!important}.with-transitions .nvd3 .nv-groups .nv-point{transition:stroke-width 250ms linear,stroke-opacity 250ms linear;-moz-transition:stroke-width 250ms linear,stroke-opacity 250ms linear;-webkit-transition:stroke-width 250ms linear,stroke-opacity 250ms linear}.nvd3.nv-scatter .nv-groups .nv-point.hover,.nvd3 .nv-groups .nv-point.hover{stroke-width:7px;fill-opacity:.95!important;stroke-opacity:.95!important}.nvd3 .nv-point-paths path{stroke:#aaa;stroke-opacity:0;fill:#eee;fill-opacity:0}.nvd3 .nv-indexLine{cursor:ew-resize}svg.nvd3-svg{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-ms-user-select:none;-moz-user-select:none;user-select:none;display:block;width:100%;height:100%}.nvtooltip.with-3d-shadow,.with-3d-shadow .nvtooltip{-moz-box-shadow:0 5px 10px rgba(0,0,0,.2);-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.nvd3 text{font:400 12px Arial}.nvd3 .title{font:700 14px Arial}.nvd3 .nv-background{fill:#fff;fill-opacity:0}.nvd3.nv-noData{font-size:18px;font-weight:700}.nv-brush .extent{fill-opacity:.125;shape-rendering:crispEdges}.nv-brush .resize path{fill:#eee;stroke:#666}.nvd3 .nv-legend .nv-series{cursor:pointer}.nvd3 .nv-legend .nv-disabled circle{fill-opacity:0}.nvd3 .nv-brush .extent{fill-opacity:0!important}.nvd3 .nv-brushBackground rect{stroke:#000;stroke-width:.4;fill:#fff;fill-opacity:.7}.nvd3.nv-ohlcBar .nv-ticks .nv-tick{stroke-width:1px}.nvd3.nv-ohlcBar .nv-ticks .nv-tick.hover{stroke-width:2px}.nvd3.nv-ohlcBar .nv-ticks .nv-tick.positive{stroke:#2ca02c}.nvd3.nv-ohlcBar .nv-ticks .nv-tick.negative{stroke:#d62728}.nvd3 .background path{fill:none;stroke:#EEE;stroke-opacity:.4;shape-rendering:crispEdges}.nvd3 .foreground path{fill:none;stroke-opacity:.7}.nvd3 .nv-parallelCoordinates-brush .extent{fill:#fff;fill-opacity:.6;stroke:gray;shape-rendering:crispEdges}.nvd3 .nv-parallelCoordinates .hover{fill-opacity:1;stroke-width:3px}.nvd3 .missingValuesline line{fill:none;stroke:#000;stroke-width:1;stroke-opacity:1;stroke-dasharray:5,5}.nvd3.nv-pie path{stroke-opacity:0;transition:fill-opacity 250ms linear,stroke-width 250ms linear,stroke-opacity 250ms linear;-moz-transition:fill-opacity 250ms linear,stroke-width 250ms linear,stroke-opacity 250ms linear;-webkit-transition:fill-opacity 250ms linear,stroke-width 250ms linear,stroke-opacity 250ms linear}.nvd3.nv-pie .nv-pie-title{font-size:24px;fill:rgba(19,196,249,.59)}.nvd3.nv-pie .nv-slice text{stroke:#000;stroke-width:0}.nvd3.nv-pie path{stroke:#fff;stroke-width:1px;stroke-opacity:1}.nvd3.nv-pie .hover path{fill-opacity:.7}.nvd3.nv-pie .nv-label{pointer-events:none}.nvd3.nv-pie .nv-label rect{fill-opacity:0;stroke-opacity:0}.nvd3 .nv-groups .nv-point.hover{stroke-width:20px;stroke-opacity:.5}.nvd3 .nv-scatter .nv-point.hover{fill-opacity:1}.nv-noninteractive{pointer-events:none}.nv-distx,.nv-disty{pointer-events:none}.nvd3.nv-sparkline path{fill:none}.nvd3.nv-sparklineplus g.nv-hoverValue{pointer-events:none}.nvd3.nv-sparklineplus .nv-hoverValue line{stroke:#333;stroke-width:1.5px}.nvd3.nv-sparklineplus,.nvd3.nv-sparklineplus g{pointer-events:all}.nvd3 .nv-hoverArea{fill-opacity:0;stroke-opacity:0}.nvd3.nv-sparklineplus .nv-xValue,.nvd3.nv-sparklineplus .nv-yValue{stroke-width:0;font-size:.9em;font-weight:400}.nvd3.nv-sparklineplus .nv-yValue{stroke:#f66}.nvd3.nv-sparklineplus .nv-maxValue{stroke:#2ca02c;fill:#2ca02c}.nvd3.nv-sparklineplus .nv-minValue{stroke:#d62728;fill:#d62728}.nvd3.nv-sparklineplus .nv-currentValue{font-weight:700;font-size:1.1em}.nvd3.nv-stackedarea path.nv-area{fill-opacity:.7;stroke-opacity:0;transition:fill-opacity 250ms linear,stroke-opacity 250ms linear;-moz-transition:fill-opacity 250ms linear,stroke-opacity 250ms linear;-webkit-transition:fill-opacity 250ms linear,stroke-opacity 250ms linear}.nvd3.nv-stackedarea path.nv-area.hover{fill-opacity:.9}.nvd3.nv-stackedarea .nv-groups .nv-point{stroke-opacity:0;fill-opacity:0}.nvtooltip{position:absolute;background-color:rgba(255,255,255,1);color:rgba(0,0,0,1);padding:1px;border:1px solid rgba(0,0,0,.2);z-index:10000;display:block;font-family:Arial;font-size:13px;text-align:left;pointer-events:none;white-space:nowrap;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.nvtooltip{background:rgba(255,255,255,.8);border:1px solid rgba(0,0,0,.5);border-radius:4px}.nvtooltip.with-transitions,.with-transitions .nvtooltip{transition:opacity 50ms linear;-moz-transition:opacity 50ms linear;-webkit-transition:opacity 50ms linear;transition-delay:200ms;-moz-transition-delay:200ms;-webkit-transition-delay:200ms}.nvtooltip.x-nvtooltip,.nvtooltip.y-nvtooltip{padding:8px}.nvtooltip h3{margin:0;padding:4px 14px;line-height:18px;font-weight:400;background-color:rgba(247,247,247,.75);color:rgba(0,0,0,1);text-align:center;border-bottom:1px solid #ebebeb;-webkit-border-radius:5px 5px 0 0;-moz-border-radius:5px 5px 0 0;border-radius:5px 5px 0 0}.nvtooltip p{margin:0;padding:5px 14px;text-align:center}.nvtooltip span{display:inline-block;margin:2px 0}.nvtooltip table{margin:6px;border-spacing:0}.nvtooltip table td{padding:2px 9px 2px 0;vertical-align:middle}.nvtooltip table td.key{font-weight:400}.nvtooltip table td.value{text-align:right;font-weight:700}.nvtooltip table tr.highlight td{padding:1px 9px 1px 0;border-bottom-style:solid;border-bottom-width:1px;border-top-style:solid;border-top-width:1px}.nvtooltip table td.legend-color-guide div{width:8px;height:8px;vertical-align:middle}.nvtooltip table td.legend-color-guide div{width:12px;height:12px;border:1px solid #999}.nvtooltip .footer{padding:3px;text-align:center}.nvtooltip-pending-removal{pointer-events:none;display:none}.nvd3 .nv-interactiveGuideLine{pointer-events:none}.nvd3 line.nv-guideline{stroke:#ccc} \ No newline at end of file diff --git a/src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/css/style.css b/src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/css/style.css new file mode 100644 index 00000000..824fb317 --- /dev/null +++ b/src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/css/style.css @@ -0,0 +1,122 @@ +body { + padding-top: 10px; +} + +.popover { + max-width: none; +} + +.glyphicon { + margin-right:.25em; +} + +.table-bordered>thead>tr>td { + border-bottom-width: 1px; +} + +.table tbody>tr>td, .table thead>tr>td { + padding-top: 3px; + padding-bottom: 3px; +} + +.table-condensed tbody>tr>td { + padding-top: 0; + padding-bottom: 0; +} + +.table .progress { + margin-bottom: inherit; +} + +.table-borderless th, .table-borderless td { + border: 0 !important; +} + +.table tbody tr.covered-by-large-tests, li.covered-by-large-tests, tr.success, td.success, li.success, span.success { + background-color: #dff0d8; +} + +.table tbody tr.covered-by-medium-tests, li.covered-by-medium-tests { + background-color: #c3e3b5; +} + +.table tbody tr.covered-by-small-tests, li.covered-by-small-tests { + background-color: #99cb84; +} + +.table tbody tr.danger, .table tbody td.danger, li.danger, span.danger { + background-color: #f2dede; +} + +.table tbody td.warning, li.warning, span.warning { + background-color: #fcf8e3; +} + +.table tbody td.info { + background-color: #d9edf7; +} + +td.big { + width: 117px; +} + +td.small { +} + +td.codeLine { + font-family: monospace; + white-space: pre; +} + +td span.comment { + color: #888a85; +} + +td span.default { + color: #2e3436; +} + +td span.html { + color: #888a85; +} + +td span.keyword { + color: #2e3436; + font-weight: bold; +} + +pre span.string { + color: #2e3436; +} + +span.success, span.warning, span.danger { + margin-right: 2px; + padding-left: 10px; + padding-right: 10px; + text-align: center; +} + +#classCoverageDistribution, #classComplexity { + height: 200px; + width: 475px; +} + +#toplink { + position: fixed; + left: 5px; + bottom: 5px; + outline: 0; +} + +svg text { + font-family: "Lucida Grande", "Lucida Sans Unicode", Verdana, Arial, Helvetica, sans-serif; + font-size: 11px; + color: #666; + fill: #666; +} + +.scrollbox { + height:245px; + overflow-x:hidden; + overflow-y:scroll; +} diff --git a/src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/dashboard.html.dist b/src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/dashboard.html.dist new file mode 100644 index 00000000..8bdf04d8 --- /dev/null +++ b/src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/dashboard.html.dist @@ -0,0 +1,284 @@ + + + + + Dashboard for {{full_path}} + + + + + + + +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    +

    Classes

    +
    +
    +
    +
    +

    Coverage Distribution

    +
    + +
    +
    +
    +

    Complexity

    +
    + +
    +
    +
    +
    +
    +

    Insufficient Coverage

    +
    + + + + + + + + +{{insufficient_coverage_classes}} + +
    ClassCoverage
    +
    +
    +
    +

    Project Risks

    +
    + + + + + + + + +{{project_risks_classes}} + +
    ClassCRAP
    +
    +
    +
    +
    +
    +

    Methods

    +
    +
    +
    +
    +

    Coverage Distribution

    +
    + +
    +
    +
    +

    Complexity

    +
    + +
    +
    +
    +
    +
    +

    Insufficient Coverage

    +
    + + + + + + + + +{{insufficient_coverage_methods}} + +
    MethodCoverage
    +
    +
    +
    +

    Project Risks

    +
    + + + + + + + + +{{project_risks_methods}} + +
    MethodCRAP
    +
    +
    +
    + +
    + + + + + + + + diff --git a/src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/directory.html.dist b/src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/directory.html.dist new file mode 100644 index 00000000..29fbf23e --- /dev/null +++ b/src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/directory.html.dist @@ -0,0 +1,61 @@ + + + + + Code Coverage for {{full_path}} + + + + + + +
    +
    +
    +
    + +
    +
    +
    +
    +
    + + + + + + + + + + + + + + +{{items}} + +
     
    Code Coverage
     
    Lines
    Functions and Methods
    Classes and Traits
    +
    +
    +

    Legend

    +

    + Low: 0% to {{low_upper_bound}}% + Medium: {{low_upper_bound}}% to {{high_lower_bound}}% + High: {{high_lower_bound}}% to 100% +

    +

    + Generated by php-code-coverage {{version}} using {{runtime}}{{generator}} at {{date}}. +

    +
    +
    + + + + + diff --git a/src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/directory_item.html.dist b/src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/directory_item.html.dist new file mode 100644 index 00000000..78dbb356 --- /dev/null +++ b/src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/directory_item.html.dist @@ -0,0 +1,13 @@ + + {{icon}}{{name}} + {{lines_bar}} +
    {{lines_executed_percent}}
    +
    {{lines_number}}
    + {{methods_bar}} +
    {{methods_tested_percent}}
    +
    {{methods_number}}
    + {{classes_bar}} +
    {{classes_tested_percent}}
    +
    {{classes_number}}
    + + diff --git a/src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/file.html.dist b/src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/file.html.dist new file mode 100644 index 00000000..8c42d4e8 --- /dev/null +++ b/src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/file.html.dist @@ -0,0 +1,90 @@ + + + + + Code Coverage for {{full_path}} + + + + + + +
    +
    +
    +
    + +
    +
    +
    +
    +
    + + + + + + + + + + + + + + +{{items}} + +
     
    Code Coverage
     
    Classes and Traits
    Functions and Methods
    Lines
    + + +{{lines}} + +
    +
    +
    +

    Legend

    +

    + Executed + Not Executed + Dead Code +

    +

    + Generated by php-code-coverage {{version}} using {{runtime}}{{generator}} at {{date}}. +

    + +
    +
    + + + + + + diff --git a/src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/file_item.html.dist b/src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/file_item.html.dist new file mode 100644 index 00000000..756fdd69 --- /dev/null +++ b/src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/file_item.html.dist @@ -0,0 +1,14 @@ + + {{name}} + {{classes_bar}} +
    {{classes_tested_percent}}
    +
    {{classes_number}}
    + {{methods_bar}} +
    {{methods_tested_percent}}
    +
    {{methods_number}}
    + {{crap}} + {{lines_bar}} +
    {{lines_executed_percent}}
    +
    {{lines_number}}
    + + diff --git a/src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/fonts/glyphicons-halflings-regular.eot b/src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/fonts/glyphicons-halflings-regular.eot new file mode 100644 index 0000000000000000000000000000000000000000..b93a4953fff68df523aa7656497ee339d6026d64 GIT binary patch literal 20127 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/fonts/glyphicons-halflings-regular.ttf b/src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/fonts/glyphicons-halflings-regular.ttf new file mode 100644 index 0000000000000000000000000000000000000000..1413fc609ab6f21774de0cb7e01360095584f65b GIT binary patch literal 45404 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 G`u_lkUM?>H literal 0 HcmV?d00001 diff --git a/src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/fonts/glyphicons-halflings-regular.woff2 b/src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/fonts/glyphicons-halflings-regular.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..64539b54c3751a6d9adb44c8e3a45ba5a73b77f0 GIT binary patch literal 18028 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 literal 0 HcmV?d00001 diff --git a/src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/bootstrap.min.js b/src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/bootstrap.min.js new file mode 100644 index 00000000..e79c0651 --- /dev/null +++ b/src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/bootstrap.min.js @@ -0,0 +1,7 @@ +/*! + * Bootstrap v3.3.6 (http://getbootstrap.com) + * Copyright 2011-2015 Twitter, Inc. + * Licensed under the MIT license + */ +if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1||b[0]>2)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher, but lower than version 3")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){return a(b.target).is(this)?b.handleObj.handler.apply(this,arguments):void 0}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.6",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a(f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.6",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")?(c.prop("checked")&&(a=!1),b.find(".active").removeClass("active"),this.$element.addClass("active")):"checkbox"==c.prop("type")&&(c.prop("checked")!==this.$element.hasClass("active")&&(a=!1),this.$element.toggleClass("active")),c.prop("checked",this.$element.hasClass("active")),a&&c.trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active")),this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target);d.hasClass("btn")||(d=d.closest(".btn")),b.call(d,"toggle"),a(c.target).is('input[type="radio"]')||a(c.target).is('input[type="checkbox"]')||c.preventDefault()}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.6",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.getItemForDirection=function(a,b){var c=this.getItemIndex(b),d="prev"==a&&0===c||"next"==a&&c==this.$items.length-1;if(d&&!this.options.wrap)return b;var e="prev"==a?-1:1,f=(c+e)%this.$items.length;return this.$items.eq(f)},c.prototype.to=function(a){var b=this,c=this.getItemIndex(this.$active=this.$element.find(".item.active"));return a>this.$items.length-1||0>a?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?"next":"prev",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){return this.sliding?void 0:this.slide("next")},c.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},c.prototype.slide=function(b,d){var e=this.$element.find(".item.active"),f=d||this.getItemForDirection(b,e),g=this.interval,h="next"==b?"left":"right",i=this;if(f.hasClass("active"))return this.sliding=!1;var j=f[0],k=a.Event("slide.bs.carousel",{relatedTarget:j,direction:h});if(this.$element.trigger(k),!k.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var l=a(this.$indicators.children()[this.getItemIndex(f)]);l&&l.addClass("active")}var m=a.Event("slid.bs.carousel",{relatedTarget:j,direction:h});return a.support.transition&&this.$element.hasClass("slide")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one("bsTransitionEnd",function(){f.removeClass([b,h].join(" ")).addClass("active"),e.removeClass(["active",h].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger(m)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass("active"),f.addClass("active"),this.sliding=!1,this.$element.trigger(m)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}};a(document).on("click.bs.carousel.data-api","[data-slide]",e).on("click.bs.carousel.data-api","[data-slide-to]",e),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){var c,d=b.attr("data-target")||(c=b.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data("bs.collapse"),f=a.extend({},d.DEFAULTS,c.data(),"object"==typeof b&&b);!e&&f.toggle&&/show|hide/.test(b)&&(f.toggle=!1),e||c.data("bs.collapse",e=new d(this,f)),"string"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a('[data-toggle="collapse"][href="#'+b.id+'"],[data-toggle="collapse"][data-target="#'+b.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION="3.3.6",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0},d.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b,e=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(!(e&&e.length&&(b=e.data("bs.collapse"),b&&b.transitioning))){var f=a.Event("show.bs.collapse");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,"hide"),b||e.data("bs.collapse",null));var g=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var h=function(){this.$element.removeClass("collapsing").addClass("collapse in")[g](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return h.call(this);var i=a.camelCase(["scroll",g].join("-"));this.$element.one("bsTransitionEnd",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass("in");a.attr("aria-expanded",c),b.toggleClass("collapsed",!c).attr("aria-expanded",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(d){var e=a(this);e.attr("data-target")||d.preventDefault();var f=b(e),g=f.data("bs.collapse"),h=g?"toggle":e.data();c.call(f,h)})}(jQuery),+function(a){"use strict";function b(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function c(c){c&&3===c.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=b(d),f={relatedTarget:this};e.hasClass("open")&&(c&&"click"==c.type&&/input|textarea/i.test(c.target.tagName)&&a.contains(e[0],c.target)||(e.trigger(c=a.Event("hide.bs.dropdown",f)),c.isDefaultPrevented()||(d.attr("aria-expanded","false"),e.removeClass("open").trigger(a.Event("hidden.bs.dropdown",f)))))}))}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.3.6",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=b(e),g=f.hasClass("open");if(c(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a(document.createElement("div")).addClass("dropdown-backdrop").insertAfter(a(this)).on("click",c);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;e.trigger("focus").attr("aria-expanded","true"),f.toggleClass("open").trigger(a.Event("shown.bs.dropdown",h))}return!1}},g.prototype.keydown=function(c){if(/(38|40|27|32)/.test(c.which)&&!/input|textarea/i.test(c.target.tagName)){var d=a(this);if(c.preventDefault(),c.stopPropagation(),!d.is(".disabled, :disabled")){var e=b(d),g=e.hasClass("open");if(!g&&27!=c.which||g&&27==c.which)return 27==c.which&&e.find(f).trigger("focus"),d.trigger("click");var h=" li:not(.disabled):visible a",i=e.find(".dropdown-menu"+h);if(i.length){var j=i.index(c.target);38==c.which&&j>0&&j--,40==c.which&&jdocument.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&a?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!a?this.scrollbarWidth:""})},c.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},c.prototype.checkScrollbar=function(){var a=window.innerWidth;if(!a){var b=document.documentElement.getBoundingClientRect();a=b.right-Math.abs(b.left)}this.bodyIsOverflowing=document.body.clientWidth
    ',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},c.prototype.init=function(b,c,d){if(this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(a.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport),this.inState={click:!1,hover:!1,focus:!1},this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusin"==b.type?"focus":"hover"]=!0),c.tip().hasClass("in")||"in"==c.hoverState?void(c.hoverState="in"):(clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show())},c.prototype.isInStateTrue=function(){for(var a in this.inState)if(this.inState[a])return!0;return!1},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusout"==b.type?"focus":"hover"]=!1),c.isInStateTrue()?void 0:(clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide())},c.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var d=a.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!d)return;var e=this,f=this.tip(),g=this.getUID(this.type);this.setContent(),f.attr("id",g),this.$element.attr("aria-describedby",g),this.options.animation&&f.addClass("fade");var h="function"==typeof this.options.placement?this.options.placement.call(this,f[0],this.$element[0]):this.options.placement,i=/\s?auto?\s?/i,j=i.test(h);j&&(h=h.replace(i,"")||"top"),f.detach().css({top:0,left:0,display:"block"}).addClass(h).data("bs."+this.type,this),this.options.container?f.appendTo(this.options.container):f.insertAfter(this.$element),this.$element.trigger("inserted.bs."+this.type);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.getPosition(this.$viewport);h="bottom"==h&&k.bottom+m>o.bottom?"top":"top"==h&&k.top-mo.width?"left":"left"==h&&k.left-lg.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;jg.right&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){if(!this.$tip&&(this.$tip=a(this.options.template),1!=this.$tip.length))throw new Error(this.type+" `template` option must consist of exactly 1 top-level element!");return this.$tip},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data("bs."+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c))),b?(c.inState.click=!c.inState.click,c.isInStateTrue()?c.enter(c):c.leave(c)):c.tip().hasClass("in")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){var a=this;clearTimeout(this.timeout),this.hide(function(){a.$element.off("."+a.type).removeData("bs."+a.type),a.$tip&&a.$tip.detach(),a.$tip=null,a.$arrow=null,a.$viewport=null})};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof b&&b;(e||!/destroy|hide/.test(b))&&(e||d.data("bs.popover",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");c.VERSION="3.3.6",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:''}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery),+function(a){"use strict";function b(c,d){this.$body=a(document.body),this.$scrollElement=a(a(c).is(document.body)?window:c),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",a.proxy(this.process,this)),this.refresh(),this.process()}function c(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})}b.VERSION="3.3.6",b.DEFAULTS={offset:10},b.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},b.prototype.refresh=function(){var b=this,c="offset",d=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),a.isWindow(this.$scrollElement[0])||(c="position",d=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var b=a(this),e=b.data("target")||b.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[c]().top+d,e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){b.offsets.push(this[0]),b.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.getScrollHeight(),d=this.options.offset+c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(this.scrollHeight!=c&&this.refresh(),b>=d)return g!=(a=f[f.length-1])&&this.activate(a);if(g&&b=e[a]&&(void 0===e[a+1]||b .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu").length&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.6",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return c>e?"top":!1;if("bottom"==this.affixed)return null!=c?e+this.unpin<=f.top?!1:"bottom":a-d>=e+g?!1:"bottom";var h=null==this.affixed,i=h?e:f.top,j=h?g:b;return null!=c&&c>=e?"top":null!=d&&i+j>=a-d?"bottom":!1},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=Math.max(a(document).height(),a(document.body).height());"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin="bottom"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix","affixed")+".bs.affix")}"bottom"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery); \ No newline at end of file diff --git a/src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/d3.min.js b/src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/d3.min.js new file mode 100644 index 00000000..16648730 --- /dev/null +++ b/src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/d3.min.js @@ -0,0 +1,5 @@ +!function(){function n(n){return n&&(n.ownerDocument||n.document||n).documentElement}function t(n){return n&&(n.ownerDocument&&n.ownerDocument.defaultView||n.document&&n||n.defaultView)}function e(n,t){return t>n?-1:n>t?1:n>=t?0:NaN}function r(n){return null===n?NaN:+n}function i(n){return!isNaN(n)}function u(n){return{left:function(t,e,r,i){for(arguments.length<3&&(r=0),arguments.length<4&&(i=t.length);i>r;){var u=r+i>>>1;n(t[u],e)<0?r=u+1:i=u}return r},right:function(t,e,r,i){for(arguments.length<3&&(r=0),arguments.length<4&&(i=t.length);i>r;){var u=r+i>>>1;n(t[u],e)>0?i=u:r=u+1}return r}}}function o(n){return n.length}function a(n){for(var t=1;n*t%1;)t*=10;return t}function l(n,t){for(var e in t)Object.defineProperty(n.prototype,e,{value:t[e],enumerable:!1})}function c(){this._=Object.create(null)}function f(n){return(n+="")===bo||n[0]===_o?_o+n:n}function s(n){return(n+="")[0]===_o?n.slice(1):n}function h(n){return f(n)in this._}function p(n){return(n=f(n))in this._&&delete this._[n]}function g(){var n=[];for(var t in this._)n.push(s(t));return n}function v(){var n=0;for(var t in this._)++n;return n}function d(){for(var n in this._)return!1;return!0}function y(){this._=Object.create(null)}function m(n){return n}function M(n,t,e){return function(){var r=e.apply(t,arguments);return r===t?n:r}}function x(n,t){if(t in n)return t;t=t.charAt(0).toUpperCase()+t.slice(1);for(var e=0,r=wo.length;r>e;++e){var i=wo[e]+t;if(i in n)return i}}function b(){}function _(){}function w(n){function t(){for(var t,r=e,i=-1,u=r.length;++ie;e++)for(var i,u=n[e],o=0,a=u.length;a>o;o++)(i=u[o])&&t(i,o,e);return n}function Z(n){return ko(n,qo),n}function V(n){var t,e;return function(r,i,u){var o,a=n[u].update,l=a.length;for(u!=e&&(e=u,t=0),i>=t&&(t=i+1);!(o=a[t])&&++t0&&(n=n.slice(0,a));var c=To.get(n);return c&&(n=c,l=B),a?t?i:r:t?b:u}function $(n,t){return function(e){var r=ao.event;ao.event=e,t[0]=this.__data__;try{n.apply(this,t)}finally{ao.event=r}}}function B(n,t){var e=$(n,t);return function(n){var t=this,r=n.relatedTarget;r&&(r===t||8&r.compareDocumentPosition(t))||e.call(t,n)}}function W(e){var r=".dragsuppress-"+ ++Do,i="click"+r,u=ao.select(t(e)).on("touchmove"+r,S).on("dragstart"+r,S).on("selectstart"+r,S);if(null==Ro&&(Ro="onselectstart"in e?!1:x(e.style,"userSelect")),Ro){var o=n(e).style,a=o[Ro];o[Ro]="none"}return function(n){if(u.on(r,null),Ro&&(o[Ro]=a),n){var t=function(){u.on(i,null)};u.on(i,function(){S(),t()},!0),setTimeout(t,0)}}}function J(n,e){e.changedTouches&&(e=e.changedTouches[0]);var r=n.ownerSVGElement||n;if(r.createSVGPoint){var i=r.createSVGPoint();if(0>Po){var u=t(n);if(u.scrollX||u.scrollY){r=ao.select("body").append("svg").style({position:"absolute",top:0,left:0,margin:0,padding:0,border:"none"},"important");var o=r[0][0].getScreenCTM();Po=!(o.f||o.e),r.remove()}}return Po?(i.x=e.pageX,i.y=e.pageY):(i.x=e.clientX,i.y=e.clientY),i=i.matrixTransform(n.getScreenCTM().inverse()),[i.x,i.y]}var a=n.getBoundingClientRect();return[e.clientX-a.left-n.clientLeft,e.clientY-a.top-n.clientTop]}function G(){return ao.event.changedTouches[0].identifier}function K(n){return n>0?1:0>n?-1:0}function Q(n,t,e){return(t[0]-n[0])*(e[1]-n[1])-(t[1]-n[1])*(e[0]-n[0])}function nn(n){return n>1?0:-1>n?Fo:Math.acos(n)}function tn(n){return n>1?Io:-1>n?-Io:Math.asin(n)}function en(n){return((n=Math.exp(n))-1/n)/2}function rn(n){return((n=Math.exp(n))+1/n)/2}function un(n){return((n=Math.exp(2*n))-1)/(n+1)}function on(n){return(n=Math.sin(n/2))*n}function an(){}function ln(n,t,e){return this instanceof ln?(this.h=+n,this.s=+t,void(this.l=+e)):arguments.length<2?n instanceof ln?new ln(n.h,n.s,n.l):_n(""+n,wn,ln):new ln(n,t,e)}function cn(n,t,e){function r(n){return n>360?n-=360:0>n&&(n+=360),60>n?u+(o-u)*n/60:180>n?o:240>n?u+(o-u)*(240-n)/60:u}function i(n){return Math.round(255*r(n))}var u,o;return n=isNaN(n)?0:(n%=360)<0?n+360:n,t=isNaN(t)?0:0>t?0:t>1?1:t,e=0>e?0:e>1?1:e,o=.5>=e?e*(1+t):e+t-e*t,u=2*e-o,new mn(i(n+120),i(n),i(n-120))}function fn(n,t,e){return this instanceof fn?(this.h=+n,this.c=+t,void(this.l=+e)):arguments.length<2?n instanceof fn?new fn(n.h,n.c,n.l):n instanceof hn?gn(n.l,n.a,n.b):gn((n=Sn((n=ao.rgb(n)).r,n.g,n.b)).l,n.a,n.b):new fn(n,t,e)}function sn(n,t,e){return isNaN(n)&&(n=0),isNaN(t)&&(t=0),new hn(e,Math.cos(n*=Yo)*t,Math.sin(n)*t)}function hn(n,t,e){return this instanceof hn?(this.l=+n,this.a=+t,void(this.b=+e)):arguments.length<2?n instanceof hn?new hn(n.l,n.a,n.b):n instanceof fn?sn(n.h,n.c,n.l):Sn((n=mn(n)).r,n.g,n.b):new hn(n,t,e)}function pn(n,t,e){var r=(n+16)/116,i=r+t/500,u=r-e/200;return i=vn(i)*na,r=vn(r)*ta,u=vn(u)*ea,new mn(yn(3.2404542*i-1.5371385*r-.4985314*u),yn(-.969266*i+1.8760108*r+.041556*u),yn(.0556434*i-.2040259*r+1.0572252*u))}function gn(n,t,e){return n>0?new fn(Math.atan2(e,t)*Zo,Math.sqrt(t*t+e*e),n):new fn(NaN,NaN,n)}function vn(n){return n>.206893034?n*n*n:(n-4/29)/7.787037}function dn(n){return n>.008856?Math.pow(n,1/3):7.787037*n+4/29}function yn(n){return Math.round(255*(.00304>=n?12.92*n:1.055*Math.pow(n,1/2.4)-.055))}function mn(n,t,e){return this instanceof mn?(this.r=~~n,this.g=~~t,void(this.b=~~e)):arguments.length<2?n instanceof mn?new mn(n.r,n.g,n.b):_n(""+n,mn,cn):new mn(n,t,e)}function Mn(n){return new mn(n>>16,n>>8&255,255&n)}function xn(n){return Mn(n)+""}function bn(n){return 16>n?"0"+Math.max(0,n).toString(16):Math.min(255,n).toString(16)}function _n(n,t,e){var r,i,u,o=0,a=0,l=0;if(r=/([a-z]+)\((.*)\)/.exec(n=n.toLowerCase()))switch(i=r[2].split(","),r[1]){case"hsl":return e(parseFloat(i[0]),parseFloat(i[1])/100,parseFloat(i[2])/100);case"rgb":return t(Nn(i[0]),Nn(i[1]),Nn(i[2]))}return(u=ua.get(n))?t(u.r,u.g,u.b):(null==n||"#"!==n.charAt(0)||isNaN(u=parseInt(n.slice(1),16))||(4===n.length?(o=(3840&u)>>4,o=o>>4|o,a=240&u,a=a>>4|a,l=15&u,l=l<<4|l):7===n.length&&(o=(16711680&u)>>16,a=(65280&u)>>8,l=255&u)),t(o,a,l))}function wn(n,t,e){var r,i,u=Math.min(n/=255,t/=255,e/=255),o=Math.max(n,t,e),a=o-u,l=(o+u)/2;return a?(i=.5>l?a/(o+u):a/(2-o-u),r=n==o?(t-e)/a+(e>t?6:0):t==o?(e-n)/a+2:(n-t)/a+4,r*=60):(r=NaN,i=l>0&&1>l?0:r),new ln(r,i,l)}function Sn(n,t,e){n=kn(n),t=kn(t),e=kn(e);var r=dn((.4124564*n+.3575761*t+.1804375*e)/na),i=dn((.2126729*n+.7151522*t+.072175*e)/ta),u=dn((.0193339*n+.119192*t+.9503041*e)/ea);return hn(116*i-16,500*(r-i),200*(i-u))}function kn(n){return(n/=255)<=.04045?n/12.92:Math.pow((n+.055)/1.055,2.4)}function Nn(n){var t=parseFloat(n);return"%"===n.charAt(n.length-1)?Math.round(2.55*t):t}function En(n){return"function"==typeof n?n:function(){return n}}function An(n){return function(t,e,r){return 2===arguments.length&&"function"==typeof e&&(r=e,e=null),Cn(t,e,n,r)}}function Cn(n,t,e,r){function i(){var n,t=l.status;if(!t&&Ln(l)||t>=200&&300>t||304===t){try{n=e.call(u,l)}catch(r){return void o.error.call(u,r)}o.load.call(u,n)}else o.error.call(u,l)}var u={},o=ao.dispatch("beforesend","progress","load","error"),a={},l=new XMLHttpRequest,c=null;return!this.XDomainRequest||"withCredentials"in l||!/^(http(s)?:)?\/\//.test(n)||(l=new XDomainRequest),"onload"in l?l.onload=l.onerror=i:l.onreadystatechange=function(){l.readyState>3&&i()},l.onprogress=function(n){var t=ao.event;ao.event=n;try{o.progress.call(u,l)}finally{ao.event=t}},u.header=function(n,t){return n=(n+"").toLowerCase(),arguments.length<2?a[n]:(null==t?delete a[n]:a[n]=t+"",u)},u.mimeType=function(n){return arguments.length?(t=null==n?null:n+"",u):t},u.responseType=function(n){return arguments.length?(c=n,u):c},u.response=function(n){return e=n,u},["get","post"].forEach(function(n){u[n]=function(){return u.send.apply(u,[n].concat(co(arguments)))}}),u.send=function(e,r,i){if(2===arguments.length&&"function"==typeof r&&(i=r,r=null),l.open(e,n,!0),null==t||"accept"in a||(a.accept=t+",*/*"),l.setRequestHeader)for(var f in a)l.setRequestHeader(f,a[f]);return null!=t&&l.overrideMimeType&&l.overrideMimeType(t),null!=c&&(l.responseType=c),null!=i&&u.on("error",i).on("load",function(n){i(null,n)}),o.beforesend.call(u,l),l.send(null==r?null:r),u},u.abort=function(){return l.abort(),u},ao.rebind(u,o,"on"),null==r?u:u.get(zn(r))}function zn(n){return 1===n.length?function(t,e){n(null==t?e:null)}:n}function Ln(n){var t=n.responseType;return t&&"text"!==t?n.response:n.responseText}function qn(n,t,e){var r=arguments.length;2>r&&(t=0),3>r&&(e=Date.now());var i=e+t,u={c:n,t:i,n:null};return aa?aa.n=u:oa=u,aa=u,la||(ca=clearTimeout(ca),la=1,fa(Tn)),u}function Tn(){var n=Rn(),t=Dn()-n;t>24?(isFinite(t)&&(clearTimeout(ca),ca=setTimeout(Tn,t)),la=0):(la=1,fa(Tn))}function Rn(){for(var n=Date.now(),t=oa;t;)n>=t.t&&t.c(n-t.t)&&(t.c=null),t=t.n;return n}function Dn(){for(var n,t=oa,e=1/0;t;)t.c?(t.t8?function(n){return n/e}:function(n){return n*e},symbol:n}}function jn(n){var t=n.decimal,e=n.thousands,r=n.grouping,i=n.currency,u=r&&e?function(n,t){for(var i=n.length,u=[],o=0,a=r[0],l=0;i>0&&a>0&&(l+a+1>t&&(a=Math.max(1,t-l)),u.push(n.substring(i-=a,i+a)),!((l+=a+1)>t));)a=r[o=(o+1)%r.length];return u.reverse().join(e)}:m;return function(n){var e=ha.exec(n),r=e[1]||" ",o=e[2]||">",a=e[3]||"-",l=e[4]||"",c=e[5],f=+e[6],s=e[7],h=e[8],p=e[9],g=1,v="",d="",y=!1,m=!0;switch(h&&(h=+h.substring(1)),(c||"0"===r&&"="===o)&&(c=r="0",o="="),p){case"n":s=!0,p="g";break;case"%":g=100,d="%",p="f";break;case"p":g=100,d="%",p="r";break;case"b":case"o":case"x":case"X":"#"===l&&(v="0"+p.toLowerCase());case"c":m=!1;case"d":y=!0,h=0;break;case"s":g=-1,p="r"}"$"===l&&(v=i[0],d=i[1]),"r"!=p||h||(p="g"),null!=h&&("g"==p?h=Math.max(1,Math.min(21,h)):"e"!=p&&"f"!=p||(h=Math.max(0,Math.min(20,h)))),p=pa.get(p)||Fn;var M=c&&s;return function(n){var e=d;if(y&&n%1)return"";var i=0>n||0===n&&0>1/n?(n=-n,"-"):"-"===a?"":a;if(0>g){var l=ao.formatPrefix(n,h);n=l.scale(n),e=l.symbol+d}else n*=g;n=p(n,h);var x,b,_=n.lastIndexOf(".");if(0>_){var w=m?n.lastIndexOf("e"):-1;0>w?(x=n,b=""):(x=n.substring(0,w),b=n.substring(w))}else x=n.substring(0,_),b=t+n.substring(_+1);!c&&s&&(x=u(x,1/0));var S=v.length+x.length+b.length+(M?0:i.length),k=f>S?new Array(S=f-S+1).join(r):"";return M&&(x=u(k+x,k.length?f-b.length:1/0)),i+=v,n=x+b,("<"===o?i+n+k:">"===o?k+i+n:"^"===o?k.substring(0,S>>=1)+i+n+k.substring(S):i+(M?n:k+n))+e}}}function Fn(n){return n+""}function Hn(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function On(n,t,e){function r(t){var e=n(t),r=u(e,1);return r-t>t-e?e:r}function i(e){return t(e=n(new va(e-1)),1),e}function u(n,e){return t(n=new va(+n),e),n}function o(n,r,u){var o=i(n),a=[];if(u>1)for(;r>o;)e(o)%u||a.push(new Date(+o)),t(o,1);else for(;r>o;)a.push(new Date(+o)),t(o,1);return a}function a(n,t,e){try{va=Hn;var r=new Hn;return r._=n,o(r,t,e)}finally{va=Date}}n.floor=n,n.round=r,n.ceil=i,n.offset=u,n.range=o;var l=n.utc=In(n);return l.floor=l,l.round=In(r),l.ceil=In(i),l.offset=In(u),l.range=a,n}function In(n){return function(t,e){try{va=Hn;var r=new Hn;return r._=t,n(r,e)._}finally{va=Date}}}function Yn(n){function t(n){function t(t){for(var e,i,u,o=[],a=-1,l=0;++aa;){if(r>=c)return-1;if(i=t.charCodeAt(a++),37===i){if(o=t.charAt(a++),u=C[o in ya?t.charAt(a++):o],!u||(r=u(n,e,r))<0)return-1}else if(i!=e.charCodeAt(r++))return-1}return r}function r(n,t,e){_.lastIndex=0;var r=_.exec(t.slice(e));return r?(n.w=w.get(r[0].toLowerCase()),e+r[0].length):-1}function i(n,t,e){x.lastIndex=0;var r=x.exec(t.slice(e));return r?(n.w=b.get(r[0].toLowerCase()),e+r[0].length):-1}function u(n,t,e){N.lastIndex=0;var r=N.exec(t.slice(e));return r?(n.m=E.get(r[0].toLowerCase()),e+r[0].length):-1}function o(n,t,e){S.lastIndex=0;var r=S.exec(t.slice(e));return r?(n.m=k.get(r[0].toLowerCase()),e+r[0].length):-1}function a(n,t,r){return e(n,A.c.toString(),t,r)}function l(n,t,r){return e(n,A.x.toString(),t,r)}function c(n,t,r){return e(n,A.X.toString(),t,r)}function f(n,t,e){var r=M.get(t.slice(e,e+=2).toLowerCase());return null==r?-1:(n.p=r,e)}var s=n.dateTime,h=n.date,p=n.time,g=n.periods,v=n.days,d=n.shortDays,y=n.months,m=n.shortMonths;t.utc=function(n){function e(n){try{va=Hn;var t=new va;return t._=n,r(t)}finally{va=Date}}var r=t(n);return e.parse=function(n){try{va=Hn;var t=r.parse(n);return t&&t._}finally{va=Date}},e.toString=r.toString,e},t.multi=t.utc.multi=ct;var M=ao.map(),x=Vn(v),b=Xn(v),_=Vn(d),w=Xn(d),S=Vn(y),k=Xn(y),N=Vn(m),E=Xn(m);g.forEach(function(n,t){M.set(n.toLowerCase(),t)});var A={a:function(n){return d[n.getDay()]},A:function(n){return v[n.getDay()]},b:function(n){return m[n.getMonth()]},B:function(n){return y[n.getMonth()]},c:t(s),d:function(n,t){return Zn(n.getDate(),t,2)},e:function(n,t){return Zn(n.getDate(),t,2)},H:function(n,t){return Zn(n.getHours(),t,2)},I:function(n,t){return Zn(n.getHours()%12||12,t,2)},j:function(n,t){return Zn(1+ga.dayOfYear(n),t,3)},L:function(n,t){return Zn(n.getMilliseconds(),t,3)},m:function(n,t){return Zn(n.getMonth()+1,t,2)},M:function(n,t){return Zn(n.getMinutes(),t,2)},p:function(n){return g[+(n.getHours()>=12)]},S:function(n,t){return Zn(n.getSeconds(),t,2)},U:function(n,t){return Zn(ga.sundayOfYear(n),t,2)},w:function(n){return n.getDay()},W:function(n,t){return Zn(ga.mondayOfYear(n),t,2)},x:t(h),X:t(p),y:function(n,t){return Zn(n.getFullYear()%100,t,2)},Y:function(n,t){return Zn(n.getFullYear()%1e4,t,4)},Z:at,"%":function(){return"%"}},C={a:r,A:i,b:u,B:o,c:a,d:tt,e:tt,H:rt,I:rt,j:et,L:ot,m:nt,M:it,p:f,S:ut,U:Bn,w:$n,W:Wn,x:l,X:c,y:Gn,Y:Jn,Z:Kn,"%":lt};return t}function Zn(n,t,e){var r=0>n?"-":"",i=(r?-n:n)+"",u=i.length;return r+(e>u?new Array(e-u+1).join(t)+i:i)}function Vn(n){return new RegExp("^(?:"+n.map(ao.requote).join("|")+")","i")}function Xn(n){for(var t=new c,e=-1,r=n.length;++e68?1900:2e3)}function nt(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.m=r[0]-1,e+r[0].length):-1}function tt(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.d=+r[0],e+r[0].length):-1}function et(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+3));return r?(n.j=+r[0],e+r[0].length):-1}function rt(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.H=+r[0],e+r[0].length):-1}function it(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.M=+r[0],e+r[0].length):-1}function ut(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.S=+r[0],e+r[0].length):-1}function ot(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+3));return r?(n.L=+r[0],e+r[0].length):-1}function at(n){var t=n.getTimezoneOffset(),e=t>0?"-":"+",r=xo(t)/60|0,i=xo(t)%60;return e+Zn(r,"0",2)+Zn(i,"0",2)}function lt(n,t,e){Ma.lastIndex=0;var r=Ma.exec(t.slice(e,e+1));return r?e+r[0].length:-1}function ct(n){for(var t=n.length,e=-1;++e=0?1:-1,a=o*e,l=Math.cos(t),c=Math.sin(t),f=u*c,s=i*l+f*Math.cos(a),h=f*o*Math.sin(a);ka.add(Math.atan2(h,s)),r=n,i=l,u=c}var t,e,r,i,u;Na.point=function(o,a){Na.point=n,r=(t=o)*Yo,i=Math.cos(a=(e=a)*Yo/2+Fo/4),u=Math.sin(a)},Na.lineEnd=function(){n(t,e)}}function dt(n){var t=n[0],e=n[1],r=Math.cos(e);return[r*Math.cos(t),r*Math.sin(t),Math.sin(e)]}function yt(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]}function mt(n,t){return[n[1]*t[2]-n[2]*t[1],n[2]*t[0]-n[0]*t[2],n[0]*t[1]-n[1]*t[0]]}function Mt(n,t){n[0]+=t[0],n[1]+=t[1],n[2]+=t[2]}function xt(n,t){return[n[0]*t,n[1]*t,n[2]*t]}function bt(n){var t=Math.sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);n[0]/=t,n[1]/=t,n[2]/=t}function _t(n){return[Math.atan2(n[1],n[0]),tn(n[2])]}function wt(n,t){return xo(n[0]-t[0])a;++a)i.point((e=n[a])[0],e[1]);return void i.lineEnd()}var l=new Tt(e,n,null,!0),c=new Tt(e,null,l,!1);l.o=c,u.push(l),o.push(c),l=new Tt(r,n,null,!1),c=new Tt(r,null,l,!0),l.o=c,u.push(l),o.push(c)}}),o.sort(t),qt(u),qt(o),u.length){for(var a=0,l=e,c=o.length;c>a;++a)o[a].e=l=!l;for(var f,s,h=u[0];;){for(var p=h,g=!0;p.v;)if((p=p.n)===h)return;f=p.z,i.lineStart();do{if(p.v=p.o.v=!0,p.e){if(g)for(var a=0,c=f.length;c>a;++a)i.point((s=f[a])[0],s[1]);else r(p.x,p.n.x,1,i);p=p.n}else{if(g){f=p.p.z;for(var a=f.length-1;a>=0;--a)i.point((s=f[a])[0],s[1])}else r(p.x,p.p.x,-1,i);p=p.p}p=p.o,f=p.z,g=!g}while(!p.v);i.lineEnd()}}}function qt(n){if(t=n.length){for(var t,e,r=0,i=n[0];++r0){for(b||(u.polygonStart(),b=!0),u.lineStart();++o1&&2&t&&e.push(e.pop().concat(e.shift())),p.push(e.filter(Dt))}var p,g,v,d=t(u),y=i.invert(r[0],r[1]),m={point:o,lineStart:l,lineEnd:c,polygonStart:function(){m.point=f,m.lineStart=s,m.lineEnd=h,p=[],g=[]},polygonEnd:function(){m.point=o,m.lineStart=l,m.lineEnd=c,p=ao.merge(p);var n=Ot(y,g);p.length?(b||(u.polygonStart(),b=!0),Lt(p,Ut,n,e,u)):n&&(b||(u.polygonStart(),b=!0),u.lineStart(),e(null,null,1,u),u.lineEnd()),b&&(u.polygonEnd(),b=!1),p=g=null},sphere:function(){u.polygonStart(),u.lineStart(),e(null,null,1,u),u.lineEnd(),u.polygonEnd()}},M=Pt(),x=t(M),b=!1;return m}}function Dt(n){return n.length>1}function Pt(){var n,t=[];return{lineStart:function(){t.push(n=[])},point:function(t,e){n.push([t,e])},lineEnd:b,buffer:function(){var e=t;return t=[],n=null,e},rejoin:function(){t.length>1&&t.push(t.pop().concat(t.shift()))}}}function Ut(n,t){return((n=n.x)[0]<0?n[1]-Io-Uo:Io-n[1])-((t=t.x)[0]<0?t[1]-Io-Uo:Io-t[1])}function jt(n){var t,e=NaN,r=NaN,i=NaN;return{lineStart:function(){n.lineStart(),t=1},point:function(u,o){var a=u>0?Fo:-Fo,l=xo(u-e);xo(l-Fo)0?Io:-Io),n.point(i,r),n.lineEnd(),n.lineStart(),n.point(a,r),n.point(u,r),t=0):i!==a&&l>=Fo&&(xo(e-i)Uo?Math.atan((Math.sin(t)*(u=Math.cos(r))*Math.sin(e)-Math.sin(r)*(i=Math.cos(t))*Math.sin(n))/(i*u*o)):(t+r)/2}function Ht(n,t,e,r){var i;if(null==n)i=e*Io,r.point(-Fo,i),r.point(0,i),r.point(Fo,i),r.point(Fo,0),r.point(Fo,-i),r.point(0,-i),r.point(-Fo,-i),r.point(-Fo,0),r.point(-Fo,i);else if(xo(n[0]-t[0])>Uo){var u=n[0]a;++a){var c=t[a],f=c.length;if(f)for(var s=c[0],h=s[0],p=s[1]/2+Fo/4,g=Math.sin(p),v=Math.cos(p),d=1;;){d===f&&(d=0),n=c[d];var y=n[0],m=n[1]/2+Fo/4,M=Math.sin(m),x=Math.cos(m),b=y-h,_=b>=0?1:-1,w=_*b,S=w>Fo,k=g*M;if(ka.add(Math.atan2(k*_*Math.sin(w),v*x+k*Math.cos(w))),u+=S?b+_*Ho:b,S^h>=e^y>=e){var N=mt(dt(s),dt(n));bt(N);var E=mt(i,N);bt(E);var A=(S^b>=0?-1:1)*tn(E[2]);(r>A||r===A&&(N[0]||N[1]))&&(o+=S^b>=0?1:-1)}if(!d++)break;h=y,g=M,v=x,s=n}}return(-Uo>u||Uo>u&&-Uo>ka)^1&o}function It(n){function t(n,t){return Math.cos(n)*Math.cos(t)>u}function e(n){var e,u,l,c,f;return{lineStart:function(){c=l=!1,f=1},point:function(s,h){var p,g=[s,h],v=t(s,h),d=o?v?0:i(s,h):v?i(s+(0>s?Fo:-Fo),h):0;if(!e&&(c=l=v)&&n.lineStart(),v!==l&&(p=r(e,g),(wt(e,p)||wt(g,p))&&(g[0]+=Uo,g[1]+=Uo,v=t(g[0],g[1]))),v!==l)f=0,v?(n.lineStart(),p=r(g,e),n.point(p[0],p[1])):(p=r(e,g),n.point(p[0],p[1]),n.lineEnd()),e=p;else if(a&&e&&o^v){var y;d&u||!(y=r(g,e,!0))||(f=0,o?(n.lineStart(),n.point(y[0][0],y[0][1]),n.point(y[1][0],y[1][1]),n.lineEnd()):(n.point(y[1][0],y[1][1]),n.lineEnd(),n.lineStart(),n.point(y[0][0],y[0][1])))}!v||e&&wt(e,g)||n.point(g[0],g[1]),e=g,l=v,u=d},lineEnd:function(){l&&n.lineEnd(),e=null},clean:function(){return f|(c&&l)<<1}}}function r(n,t,e){var r=dt(n),i=dt(t),o=[1,0,0],a=mt(r,i),l=yt(a,a),c=a[0],f=l-c*c;if(!f)return!e&&n;var s=u*l/f,h=-u*c/f,p=mt(o,a),g=xt(o,s),v=xt(a,h);Mt(g,v);var d=p,y=yt(g,d),m=yt(d,d),M=y*y-m*(yt(g,g)-1);if(!(0>M)){var x=Math.sqrt(M),b=xt(d,(-y-x)/m);if(Mt(b,g),b=_t(b),!e)return b;var _,w=n[0],S=t[0],k=n[1],N=t[1];w>S&&(_=w,w=S,S=_);var E=S-w,A=xo(E-Fo)E;if(!A&&k>N&&(_=k,k=N,N=_),C?A?k+N>0^b[1]<(xo(b[0]-w)Fo^(w<=b[0]&&b[0]<=S)){var z=xt(d,(-y+x)/m);return Mt(z,g),[b,_t(z)]}}}function i(t,e){var r=o?n:Fo-n,i=0;return-r>t?i|=1:t>r&&(i|=2),-r>e?i|=4:e>r&&(i|=8),i}var u=Math.cos(n),o=u>0,a=xo(u)>Uo,l=ve(n,6*Yo);return Rt(t,e,l,o?[0,-n]:[-Fo,n-Fo])}function Yt(n,t,e,r){return function(i){var u,o=i.a,a=i.b,l=o.x,c=o.y,f=a.x,s=a.y,h=0,p=1,g=f-l,v=s-c;if(u=n-l,g||!(u>0)){if(u/=g,0>g){if(h>u)return;p>u&&(p=u)}else if(g>0){if(u>p)return;u>h&&(h=u)}if(u=e-l,g||!(0>u)){if(u/=g,0>g){if(u>p)return;u>h&&(h=u)}else if(g>0){if(h>u)return;p>u&&(p=u)}if(u=t-c,v||!(u>0)){if(u/=v,0>v){if(h>u)return;p>u&&(p=u)}else if(v>0){if(u>p)return;u>h&&(h=u)}if(u=r-c,v||!(0>u)){if(u/=v,0>v){if(u>p)return;u>h&&(h=u)}else if(v>0){if(h>u)return;p>u&&(p=u)}return h>0&&(i.a={x:l+h*g,y:c+h*v}),1>p&&(i.b={x:l+p*g,y:c+p*v}),i}}}}}}function Zt(n,t,e,r){function i(r,i){return xo(r[0]-n)0?0:3:xo(r[0]-e)0?2:1:xo(r[1]-t)0?1:0:i>0?3:2}function u(n,t){return o(n.x,t.x)}function o(n,t){var e=i(n,1),r=i(t,1);return e!==r?e-r:0===e?t[1]-n[1]:1===e?n[0]-t[0]:2===e?n[1]-t[1]:t[0]-n[0]}return function(a){function l(n){for(var t=0,e=d.length,r=n[1],i=0;e>i;++i)for(var u,o=1,a=d[i],l=a.length,c=a[0];l>o;++o)u=a[o],c[1]<=r?u[1]>r&&Q(c,u,n)>0&&++t:u[1]<=r&&Q(c,u,n)<0&&--t,c=u;return 0!==t}function c(u,a,l,c){var f=0,s=0;if(null==u||(f=i(u,l))!==(s=i(a,l))||o(u,a)<0^l>0){do c.point(0===f||3===f?n:e,f>1?r:t);while((f=(f+l+4)%4)!==s)}else c.point(a[0],a[1])}function f(i,u){return i>=n&&e>=i&&u>=t&&r>=u}function s(n,t){f(n,t)&&a.point(n,t)}function h(){C.point=g,d&&d.push(y=[]),S=!0,w=!1,b=_=NaN}function p(){v&&(g(m,M),x&&w&&E.rejoin(),v.push(E.buffer())),C.point=s,w&&a.lineEnd()}function g(n,t){n=Math.max(-Ha,Math.min(Ha,n)),t=Math.max(-Ha,Math.min(Ha,t));var e=f(n,t);if(d&&y.push([n,t]),S)m=n,M=t,x=e,S=!1,e&&(a.lineStart(),a.point(n,t));else if(e&&w)a.point(n,t);else{var r={a:{x:b,y:_},b:{x:n,y:t}};A(r)?(w||(a.lineStart(),a.point(r.a.x,r.a.y)),a.point(r.b.x,r.b.y),e||a.lineEnd(),k=!1):e&&(a.lineStart(),a.point(n,t),k=!1)}b=n,_=t,w=e}var v,d,y,m,M,x,b,_,w,S,k,N=a,E=Pt(),A=Yt(n,t,e,r),C={point:s,lineStart:h,lineEnd:p,polygonStart:function(){a=E,v=[],d=[],k=!0},polygonEnd:function(){a=N,v=ao.merge(v);var t=l([n,r]),e=k&&t,i=v.length;(e||i)&&(a.polygonStart(),e&&(a.lineStart(),c(null,null,1,a),a.lineEnd()),i&&Lt(v,u,t,c,a),a.polygonEnd()),v=d=y=null}};return C}}function Vt(n){var t=0,e=Fo/3,r=ae(n),i=r(t,e);return i.parallels=function(n){return arguments.length?r(t=n[0]*Fo/180,e=n[1]*Fo/180):[t/Fo*180,e/Fo*180]},i}function Xt(n,t){function e(n,t){var e=Math.sqrt(u-2*i*Math.sin(t))/i;return[e*Math.sin(n*=i),o-e*Math.cos(n)]}var r=Math.sin(n),i=(r+Math.sin(t))/2,u=1+r*(2*i-r),o=Math.sqrt(u)/i;return e.invert=function(n,t){var e=o-t;return[Math.atan2(n,e)/i,tn((u-(n*n+e*e)*i*i)/(2*i))]},e}function $t(){function n(n,t){Ia+=i*n-r*t,r=n,i=t}var t,e,r,i;$a.point=function(u,o){$a.point=n,t=r=u,e=i=o},$a.lineEnd=function(){n(t,e)}}function Bt(n,t){Ya>n&&(Ya=n),n>Va&&(Va=n),Za>t&&(Za=t),t>Xa&&(Xa=t)}function Wt(){function n(n,t){o.push("M",n,",",t,u)}function t(n,t){o.push("M",n,",",t),a.point=e}function e(n,t){o.push("L",n,",",t)}function r(){a.point=n}function i(){o.push("Z")}var u=Jt(4.5),o=[],a={point:n,lineStart:function(){a.point=t},lineEnd:r,polygonStart:function(){a.lineEnd=i},polygonEnd:function(){a.lineEnd=r,a.point=n},pointRadius:function(n){return u=Jt(n),a},result:function(){if(o.length){var n=o.join("");return o=[],n}}};return a}function Jt(n){return"m0,"+n+"a"+n+","+n+" 0 1,1 0,"+-2*n+"a"+n+","+n+" 0 1,1 0,"+2*n+"z"}function Gt(n,t){Ca+=n,za+=t,++La}function Kt(){function n(n,r){var i=n-t,u=r-e,o=Math.sqrt(i*i+u*u);qa+=o*(t+n)/2,Ta+=o*(e+r)/2,Ra+=o,Gt(t=n,e=r)}var t,e;Wa.point=function(r,i){Wa.point=n,Gt(t=r,e=i)}}function Qt(){Wa.point=Gt}function ne(){function n(n,t){var e=n-r,u=t-i,o=Math.sqrt(e*e+u*u);qa+=o*(r+n)/2,Ta+=o*(i+t)/2,Ra+=o,o=i*n-r*t,Da+=o*(r+n),Pa+=o*(i+t),Ua+=3*o,Gt(r=n,i=t)}var t,e,r,i;Wa.point=function(u,o){Wa.point=n,Gt(t=r=u,e=i=o)},Wa.lineEnd=function(){n(t,e)}}function te(n){function t(t,e){n.moveTo(t+o,e),n.arc(t,e,o,0,Ho)}function e(t,e){n.moveTo(t,e),a.point=r}function r(t,e){n.lineTo(t,e)}function i(){a.point=t}function u(){n.closePath()}var o=4.5,a={point:t,lineStart:function(){a.point=e},lineEnd:i,polygonStart:function(){a.lineEnd=u},polygonEnd:function(){a.lineEnd=i,a.point=t},pointRadius:function(n){return o=n,a},result:b};return a}function ee(n){function t(n){return(a?r:e)(n)}function e(t){return ue(t,function(e,r){e=n(e,r),t.point(e[0],e[1])})}function r(t){function e(e,r){e=n(e,r),t.point(e[0],e[1])}function r(){M=NaN,S.point=u,t.lineStart()}function u(e,r){var u=dt([e,r]),o=n(e,r);i(M,x,m,b,_,w,M=o[0],x=o[1],m=e,b=u[0],_=u[1],w=u[2],a,t),t.point(M,x)}function o(){S.point=e,t.lineEnd()}function l(){ +r(),S.point=c,S.lineEnd=f}function c(n,t){u(s=n,h=t),p=M,g=x,v=b,d=_,y=w,S.point=u}function f(){i(M,x,m,b,_,w,p,g,s,v,d,y,a,t),S.lineEnd=o,o()}var s,h,p,g,v,d,y,m,M,x,b,_,w,S={point:e,lineStart:r,lineEnd:o,polygonStart:function(){t.polygonStart(),S.lineStart=l},polygonEnd:function(){t.polygonEnd(),S.lineStart=r}};return S}function i(t,e,r,a,l,c,f,s,h,p,g,v,d,y){var m=f-t,M=s-e,x=m*m+M*M;if(x>4*u&&d--){var b=a+p,_=l+g,w=c+v,S=Math.sqrt(b*b+_*_+w*w),k=Math.asin(w/=S),N=xo(xo(w)-1)u||xo((m*z+M*L)/x-.5)>.3||o>a*p+l*g+c*v)&&(i(t,e,r,a,l,c,A,C,N,b/=S,_/=S,w,d,y),y.point(A,C),i(A,C,N,b,_,w,f,s,h,p,g,v,d,y))}}var u=.5,o=Math.cos(30*Yo),a=16;return t.precision=function(n){return arguments.length?(a=(u=n*n)>0&&16,t):Math.sqrt(u)},t}function re(n){var t=ee(function(t,e){return n([t*Zo,e*Zo])});return function(n){return le(t(n))}}function ie(n){this.stream=n}function ue(n,t){return{point:t,sphere:function(){n.sphere()},lineStart:function(){n.lineStart()},lineEnd:function(){n.lineEnd()},polygonStart:function(){n.polygonStart()},polygonEnd:function(){n.polygonEnd()}}}function oe(n){return ae(function(){return n})()}function ae(n){function t(n){return n=a(n[0]*Yo,n[1]*Yo),[n[0]*h+l,c-n[1]*h]}function e(n){return n=a.invert((n[0]-l)/h,(c-n[1])/h),n&&[n[0]*Zo,n[1]*Zo]}function r(){a=Ct(o=se(y,M,x),u);var n=u(v,d);return l=p-n[0]*h,c=g+n[1]*h,i()}function i(){return f&&(f.valid=!1,f=null),t}var u,o,a,l,c,f,s=ee(function(n,t){return n=u(n,t),[n[0]*h+l,c-n[1]*h]}),h=150,p=480,g=250,v=0,d=0,y=0,M=0,x=0,b=Fa,_=m,w=null,S=null;return t.stream=function(n){return f&&(f.valid=!1),f=le(b(o,s(_(n)))),f.valid=!0,f},t.clipAngle=function(n){return arguments.length?(b=null==n?(w=n,Fa):It((w=+n)*Yo),i()):w},t.clipExtent=function(n){return arguments.length?(S=n,_=n?Zt(n[0][0],n[0][1],n[1][0],n[1][1]):m,i()):S},t.scale=function(n){return arguments.length?(h=+n,r()):h},t.translate=function(n){return arguments.length?(p=+n[0],g=+n[1],r()):[p,g]},t.center=function(n){return arguments.length?(v=n[0]%360*Yo,d=n[1]%360*Yo,r()):[v*Zo,d*Zo]},t.rotate=function(n){return arguments.length?(y=n[0]%360*Yo,M=n[1]%360*Yo,x=n.length>2?n[2]%360*Yo:0,r()):[y*Zo,M*Zo,x*Zo]},ao.rebind(t,s,"precision"),function(){return u=n.apply(this,arguments),t.invert=u.invert&&e,r()}}function le(n){return ue(n,function(t,e){n.point(t*Yo,e*Yo)})}function ce(n,t){return[n,t]}function fe(n,t){return[n>Fo?n-Ho:-Fo>n?n+Ho:n,t]}function se(n,t,e){return n?t||e?Ct(pe(n),ge(t,e)):pe(n):t||e?ge(t,e):fe}function he(n){return function(t,e){return t+=n,[t>Fo?t-Ho:-Fo>t?t+Ho:t,e]}}function pe(n){var t=he(n);return t.invert=he(-n),t}function ge(n,t){function e(n,t){var e=Math.cos(t),a=Math.cos(n)*e,l=Math.sin(n)*e,c=Math.sin(t),f=c*r+a*i;return[Math.atan2(l*u-f*o,a*r-c*i),tn(f*u+l*o)]}var r=Math.cos(n),i=Math.sin(n),u=Math.cos(t),o=Math.sin(t);return e.invert=function(n,t){var e=Math.cos(t),a=Math.cos(n)*e,l=Math.sin(n)*e,c=Math.sin(t),f=c*u-l*o;return[Math.atan2(l*u+c*o,a*r+f*i),tn(f*r-a*i)]},e}function ve(n,t){var e=Math.cos(n),r=Math.sin(n);return function(i,u,o,a){var l=o*t;null!=i?(i=de(e,i),u=de(e,u),(o>0?u>i:i>u)&&(i+=o*Ho)):(i=n+o*Ho,u=n-.5*l);for(var c,f=i;o>0?f>u:u>f;f-=l)a.point((c=_t([e,-r*Math.cos(f),-r*Math.sin(f)]))[0],c[1])}}function de(n,t){var e=dt(t);e[0]-=n,bt(e);var r=nn(-e[1]);return((-e[2]<0?-r:r)+2*Math.PI-Uo)%(2*Math.PI)}function ye(n,t,e){var r=ao.range(n,t-Uo,e).concat(t);return function(n){return r.map(function(t){return[n,t]})}}function me(n,t,e){var r=ao.range(n,t-Uo,e).concat(t);return function(n){return r.map(function(t){return[t,n]})}}function Me(n){return n.source}function xe(n){return n.target}function be(n,t,e,r){var i=Math.cos(t),u=Math.sin(t),o=Math.cos(r),a=Math.sin(r),l=i*Math.cos(n),c=i*Math.sin(n),f=o*Math.cos(e),s=o*Math.sin(e),h=2*Math.asin(Math.sqrt(on(r-t)+i*o*on(e-n))),p=1/Math.sin(h),g=h?function(n){var t=Math.sin(n*=h)*p,e=Math.sin(h-n)*p,r=e*l+t*f,i=e*c+t*s,o=e*u+t*a;return[Math.atan2(i,r)*Zo,Math.atan2(o,Math.sqrt(r*r+i*i))*Zo]}:function(){return[n*Zo,t*Zo]};return g.distance=h,g}function _e(){function n(n,i){var u=Math.sin(i*=Yo),o=Math.cos(i),a=xo((n*=Yo)-t),l=Math.cos(a);Ja+=Math.atan2(Math.sqrt((a=o*Math.sin(a))*a+(a=r*u-e*o*l)*a),e*u+r*o*l),t=n,e=u,r=o}var t,e,r;Ga.point=function(i,u){t=i*Yo,e=Math.sin(u*=Yo),r=Math.cos(u),Ga.point=n},Ga.lineEnd=function(){Ga.point=Ga.lineEnd=b}}function we(n,t){function e(t,e){var r=Math.cos(t),i=Math.cos(e),u=n(r*i);return[u*i*Math.sin(t),u*Math.sin(e)]}return e.invert=function(n,e){var r=Math.sqrt(n*n+e*e),i=t(r),u=Math.sin(i),o=Math.cos(i);return[Math.atan2(n*u,r*o),Math.asin(r&&e*u/r)]},e}function Se(n,t){function e(n,t){o>0?-Io+Uo>t&&(t=-Io+Uo):t>Io-Uo&&(t=Io-Uo);var e=o/Math.pow(i(t),u);return[e*Math.sin(u*n),o-e*Math.cos(u*n)]}var r=Math.cos(n),i=function(n){return Math.tan(Fo/4+n/2)},u=n===t?Math.sin(n):Math.log(r/Math.cos(t))/Math.log(i(t)/i(n)),o=r*Math.pow(i(n),u)/u;return u?(e.invert=function(n,t){var e=o-t,r=K(u)*Math.sqrt(n*n+e*e);return[Math.atan2(n,e)/u,2*Math.atan(Math.pow(o/r,1/u))-Io]},e):Ne}function ke(n,t){function e(n,t){var e=u-t;return[e*Math.sin(i*n),u-e*Math.cos(i*n)]}var r=Math.cos(n),i=n===t?Math.sin(n):(r-Math.cos(t))/(t-n),u=r/i+n;return xo(i)i;i++){for(;r>1&&Q(n[e[r-2]],n[e[r-1]],n[i])<=0;)--r;e[r++]=i}return e.slice(0,r)}function qe(n,t){return n[0]-t[0]||n[1]-t[1]}function Te(n,t,e){return(e[0]-t[0])*(n[1]-t[1])<(e[1]-t[1])*(n[0]-t[0])}function Re(n,t,e,r){var i=n[0],u=e[0],o=t[0]-i,a=r[0]-u,l=n[1],c=e[1],f=t[1]-l,s=r[1]-c,h=(a*(l-c)-s*(i-u))/(s*o-a*f);return[i+h*o,l+h*f]}function De(n){var t=n[0],e=n[n.length-1];return!(t[0]-e[0]||t[1]-e[1])}function Pe(){rr(this),this.edge=this.site=this.circle=null}function Ue(n){var t=cl.pop()||new Pe;return t.site=n,t}function je(n){Be(n),ol.remove(n),cl.push(n),rr(n)}function Fe(n){var t=n.circle,e=t.x,r=t.cy,i={x:e,y:r},u=n.P,o=n.N,a=[n];je(n);for(var l=u;l.circle&&xo(e-l.circle.x)f;++f)c=a[f],l=a[f-1],nr(c.edge,l.site,c.site,i);l=a[0],c=a[s-1],c.edge=Ke(l.site,c.site,null,i),$e(l),$e(c)}function He(n){for(var t,e,r,i,u=n.x,o=n.y,a=ol._;a;)if(r=Oe(a,o)-u,r>Uo)a=a.L;else{if(i=u-Ie(a,o),!(i>Uo)){r>-Uo?(t=a.P,e=a):i>-Uo?(t=a,e=a.N):t=e=a;break}if(!a.R){t=a;break}a=a.R}var l=Ue(n);if(ol.insert(t,l),t||e){if(t===e)return Be(t),e=Ue(t.site),ol.insert(l,e),l.edge=e.edge=Ke(t.site,l.site),$e(t),void $e(e);if(!e)return void(l.edge=Ke(t.site,l.site));Be(t),Be(e);var c=t.site,f=c.x,s=c.y,h=n.x-f,p=n.y-s,g=e.site,v=g.x-f,d=g.y-s,y=2*(h*d-p*v),m=h*h+p*p,M=v*v+d*d,x={x:(d*m-p*M)/y+f,y:(h*M-v*m)/y+s};nr(e.edge,c,g,x),l.edge=Ke(c,n,null,x),e.edge=Ke(n,g,null,x),$e(t),$e(e)}}function Oe(n,t){var e=n.site,r=e.x,i=e.y,u=i-t;if(!u)return r;var o=n.P;if(!o)return-(1/0);e=o.site;var a=e.x,l=e.y,c=l-t;if(!c)return a;var f=a-r,s=1/u-1/c,h=f/c;return s?(-h+Math.sqrt(h*h-2*s*(f*f/(-2*c)-l+c/2+i-u/2)))/s+r:(r+a)/2}function Ie(n,t){var e=n.N;if(e)return Oe(e,t);var r=n.site;return r.y===t?r.x:1/0}function Ye(n){this.site=n,this.edges=[]}function Ze(n){for(var t,e,r,i,u,o,a,l,c,f,s=n[0][0],h=n[1][0],p=n[0][1],g=n[1][1],v=ul,d=v.length;d--;)if(u=v[d],u&&u.prepare())for(a=u.edges,l=a.length,o=0;l>o;)f=a[o].end(),r=f.x,i=f.y,c=a[++o%l].start(),t=c.x,e=c.y,(xo(r-t)>Uo||xo(i-e)>Uo)&&(a.splice(o,0,new tr(Qe(u.site,f,xo(r-s)Uo?{x:s,y:xo(t-s)Uo?{x:xo(e-g)Uo?{x:h,y:xo(t-h)Uo?{x:xo(e-p)=-jo)){var p=l*l+c*c,g=f*f+s*s,v=(s*p-c*g)/h,d=(l*g-f*p)/h,s=d+a,y=fl.pop()||new Xe;y.arc=n,y.site=i,y.x=v+o,y.y=s+Math.sqrt(v*v+d*d),y.cy=s,n.circle=y;for(var m=null,M=ll._;M;)if(y.yd||d>=a)return;if(h>g){if(u){if(u.y>=c)return}else u={x:d,y:l};e={x:d,y:c}}else{if(u){if(u.yr||r>1)if(h>g){if(u){if(u.y>=c)return}else u={x:(l-i)/r,y:l};e={x:(c-i)/r,y:c}}else{if(u){if(u.yp){if(u){if(u.x>=a)return}else u={x:o,y:r*o+i};e={x:a,y:r*a+i}}else{if(u){if(u.xu||s>o||r>h||i>p)){if(g=n.point){var g,v=t-n.x,d=e-n.y,y=v*v+d*d;if(l>y){var m=Math.sqrt(l=y);r=t-m,i=e-m,u=t+m,o=e+m,a=g}}for(var M=n.nodes,x=.5*(f+h),b=.5*(s+p),_=t>=x,w=e>=b,S=w<<1|_,k=S+4;k>S;++S)if(n=M[3&S])switch(3&S){case 0:c(n,f,s,x,b);break;case 1:c(n,x,s,h,b);break;case 2:c(n,f,b,x,p);break;case 3:c(n,x,b,h,p)}}}(n,r,i,u,o),a}function vr(n,t){n=ao.rgb(n),t=ao.rgb(t);var e=n.r,r=n.g,i=n.b,u=t.r-e,o=t.g-r,a=t.b-i;return function(n){return"#"+bn(Math.round(e+u*n))+bn(Math.round(r+o*n))+bn(Math.round(i+a*n))}}function dr(n,t){var e,r={},i={};for(e in n)e in t?r[e]=Mr(n[e],t[e]):i[e]=n[e];for(e in t)e in n||(i[e]=t[e]);return function(n){for(e in r)i[e]=r[e](n);return i}}function yr(n,t){return n=+n,t=+t,function(e){return n*(1-e)+t*e}}function mr(n,t){var e,r,i,u=hl.lastIndex=pl.lastIndex=0,o=-1,a=[],l=[];for(n+="",t+="";(e=hl.exec(n))&&(r=pl.exec(t));)(i=r.index)>u&&(i=t.slice(u,i),a[o]?a[o]+=i:a[++o]=i),(e=e[0])===(r=r[0])?a[o]?a[o]+=r:a[++o]=r:(a[++o]=null,l.push({i:o,x:yr(e,r)})),u=pl.lastIndex;return ur;++r)a[(e=l[r]).i]=e.x(n);return a.join("")})}function Mr(n,t){for(var e,r=ao.interpolators.length;--r>=0&&!(e=ao.interpolators[r](n,t)););return e}function xr(n,t){var e,r=[],i=[],u=n.length,o=t.length,a=Math.min(n.length,t.length);for(e=0;a>e;++e)r.push(Mr(n[e],t[e]));for(;u>e;++e)i[e]=n[e];for(;o>e;++e)i[e]=t[e];return function(n){for(e=0;a>e;++e)i[e]=r[e](n);return i}}function br(n){return function(t){return 0>=t?0:t>=1?1:n(t)}}function _r(n){return function(t){return 1-n(1-t)}}function wr(n){return function(t){return.5*(.5>t?n(2*t):2-n(2-2*t))}}function Sr(n){return n*n}function kr(n){return n*n*n}function Nr(n){if(0>=n)return 0;if(n>=1)return 1;var t=n*n,e=t*n;return 4*(.5>n?e:3*(n-t)+e-.75)}function Er(n){return function(t){return Math.pow(t,n)}}function Ar(n){return 1-Math.cos(n*Io)}function Cr(n){return Math.pow(2,10*(n-1))}function zr(n){return 1-Math.sqrt(1-n*n)}function Lr(n,t){var e;return arguments.length<2&&(t=.45),arguments.length?e=t/Ho*Math.asin(1/n):(n=1,e=t/4),function(r){return 1+n*Math.pow(2,-10*r)*Math.sin((r-e)*Ho/t)}}function qr(n){return n||(n=1.70158),function(t){return t*t*((n+1)*t-n)}}function Tr(n){return 1/2.75>n?7.5625*n*n:2/2.75>n?7.5625*(n-=1.5/2.75)*n+.75:2.5/2.75>n?7.5625*(n-=2.25/2.75)*n+.9375:7.5625*(n-=2.625/2.75)*n+.984375}function Rr(n,t){n=ao.hcl(n),t=ao.hcl(t);var e=n.h,r=n.c,i=n.l,u=t.h-e,o=t.c-r,a=t.l-i;return isNaN(o)&&(o=0,r=isNaN(r)?t.c:r),isNaN(u)?(u=0,e=isNaN(e)?t.h:e):u>180?u-=360:-180>u&&(u+=360),function(n){return sn(e+u*n,r+o*n,i+a*n)+""}}function Dr(n,t){n=ao.hsl(n),t=ao.hsl(t);var e=n.h,r=n.s,i=n.l,u=t.h-e,o=t.s-r,a=t.l-i;return isNaN(o)&&(o=0,r=isNaN(r)?t.s:r),isNaN(u)?(u=0,e=isNaN(e)?t.h:e):u>180?u-=360:-180>u&&(u+=360),function(n){return cn(e+u*n,r+o*n,i+a*n)+""}}function Pr(n,t){n=ao.lab(n),t=ao.lab(t);var e=n.l,r=n.a,i=n.b,u=t.l-e,o=t.a-r,a=t.b-i;return function(n){return pn(e+u*n,r+o*n,i+a*n)+""}}function Ur(n,t){return t-=n,function(e){return Math.round(n+t*e)}}function jr(n){var t=[n.a,n.b],e=[n.c,n.d],r=Hr(t),i=Fr(t,e),u=Hr(Or(e,t,-i))||0;t[0]*e[1]180?t+=360:t-n>180&&(n+=360),r.push({i:e.push(Ir(e)+"rotate(",null,")")-2,x:yr(n,t)})):t&&e.push(Ir(e)+"rotate("+t+")")}function Vr(n,t,e,r){n!==t?r.push({i:e.push(Ir(e)+"skewX(",null,")")-2,x:yr(n,t)}):t&&e.push(Ir(e)+"skewX("+t+")")}function Xr(n,t,e,r){if(n[0]!==t[0]||n[1]!==t[1]){var i=e.push(Ir(e)+"scale(",null,",",null,")");r.push({i:i-4,x:yr(n[0],t[0])},{i:i-2,x:yr(n[1],t[1])})}else 1===t[0]&&1===t[1]||e.push(Ir(e)+"scale("+t+")")}function $r(n,t){var e=[],r=[];return n=ao.transform(n),t=ao.transform(t),Yr(n.translate,t.translate,e,r),Zr(n.rotate,t.rotate,e,r),Vr(n.skew,t.skew,e,r),Xr(n.scale,t.scale,e,r),n=t=null,function(n){for(var t,i=-1,u=r.length;++i=0;)e.push(i[r])}function oi(n,t){for(var e=[n],r=[];null!=(n=e.pop());)if(r.push(n),(u=n.children)&&(i=u.length))for(var i,u,o=-1;++oe;++e)(t=n[e][1])>i&&(r=e,i=t);return r}function yi(n){return n.reduce(mi,0)}function mi(n,t){return n+t[1]}function Mi(n,t){return xi(n,Math.ceil(Math.log(t.length)/Math.LN2+1))}function xi(n,t){for(var e=-1,r=+n[0],i=(n[1]-r)/t,u=[];++e<=t;)u[e]=i*e+r;return u}function bi(n){return[ao.min(n),ao.max(n)]}function _i(n,t){return n.value-t.value}function wi(n,t){var e=n._pack_next;n._pack_next=t,t._pack_prev=n,t._pack_next=e,e._pack_prev=t}function Si(n,t){n._pack_next=t,t._pack_prev=n}function ki(n,t){var e=t.x-n.x,r=t.y-n.y,i=n.r+t.r;return.999*i*i>e*e+r*r}function Ni(n){function t(n){f=Math.min(n.x-n.r,f),s=Math.max(n.x+n.r,s),h=Math.min(n.y-n.r,h),p=Math.max(n.y+n.r,p)}if((e=n.children)&&(c=e.length)){var e,r,i,u,o,a,l,c,f=1/0,s=-(1/0),h=1/0,p=-(1/0);if(e.forEach(Ei),r=e[0],r.x=-r.r,r.y=0,t(r),c>1&&(i=e[1],i.x=i.r,i.y=0,t(i),c>2))for(u=e[2],zi(r,i,u),t(u),wi(r,u),r._pack_prev=u,wi(u,i),i=r._pack_next,o=3;c>o;o++){zi(r,i,u=e[o]);var g=0,v=1,d=1;for(a=i._pack_next;a!==i;a=a._pack_next,v++)if(ki(a,u)){g=1;break}if(1==g)for(l=r._pack_prev;l!==a._pack_prev&&!ki(l,u);l=l._pack_prev,d++);g?(d>v||v==d&&i.ro;o++)u=e[o],u.x-=y,u.y-=m,M=Math.max(M,u.r+Math.sqrt(u.x*u.x+u.y*u.y));n.r=M,e.forEach(Ai)}}function Ei(n){n._pack_next=n._pack_prev=n}function Ai(n){delete n._pack_next,delete n._pack_prev}function Ci(n,t,e,r){var i=n.children;if(n.x=t+=r*n.x,n.y=e+=r*n.y,n.r*=r,i)for(var u=-1,o=i.length;++u=0;)t=i[u],t.z+=e,t.m+=e,e+=t.s+(r+=t.c)}function Pi(n,t,e){return n.a.parent===t.parent?n.a:e}function Ui(n){return 1+ao.max(n,function(n){return n.y})}function ji(n){return n.reduce(function(n,t){return n+t.x},0)/n.length}function Fi(n){var t=n.children;return t&&t.length?Fi(t[0]):n}function Hi(n){var t,e=n.children;return e&&(t=e.length)?Hi(e[t-1]):n}function Oi(n){return{x:n.x,y:n.y,dx:n.dx,dy:n.dy}}function Ii(n,t){var e=n.x+t[3],r=n.y+t[0],i=n.dx-t[1]-t[3],u=n.dy-t[0]-t[2];return 0>i&&(e+=i/2,i=0),0>u&&(r+=u/2,u=0),{x:e,y:r,dx:i,dy:u}}function Yi(n){var t=n[0],e=n[n.length-1];return e>t?[t,e]:[e,t]}function Zi(n){return n.rangeExtent?n.rangeExtent():Yi(n.range())}function Vi(n,t,e,r){var i=e(n[0],n[1]),u=r(t[0],t[1]);return function(n){return u(i(n))}}function Xi(n,t){var e,r=0,i=n.length-1,u=n[r],o=n[i];return u>o&&(e=r,r=i,i=e,e=u,u=o,o=e),n[r]=t.floor(u),n[i]=t.ceil(o),n}function $i(n){return n?{floor:function(t){return Math.floor(t/n)*n},ceil:function(t){return Math.ceil(t/n)*n}}:Sl}function Bi(n,t,e,r){var i=[],u=[],o=0,a=Math.min(n.length,t.length)-1;for(n[a]2?Bi:Vi,l=r?Wr:Br;return o=i(n,t,l,e),a=i(t,n,l,Mr),u}function u(n){return o(n)}var o,a;return u.invert=function(n){return a(n)},u.domain=function(t){return arguments.length?(n=t.map(Number),i()):n},u.range=function(n){return arguments.length?(t=n,i()):t},u.rangeRound=function(n){return u.range(n).interpolate(Ur)},u.clamp=function(n){return arguments.length?(r=n,i()):r},u.interpolate=function(n){return arguments.length?(e=n,i()):e},u.ticks=function(t){return Qi(n,t)},u.tickFormat=function(t,e){return nu(n,t,e)},u.nice=function(t){return Gi(n,t),i()},u.copy=function(){return Wi(n,t,e,r)},i()}function Ji(n,t){return ao.rebind(n,t,"range","rangeRound","interpolate","clamp")}function Gi(n,t){return Xi(n,$i(Ki(n,t)[2])),Xi(n,$i(Ki(n,t)[2])),n}function Ki(n,t){null==t&&(t=10);var e=Yi(n),r=e[1]-e[0],i=Math.pow(10,Math.floor(Math.log(r/t)/Math.LN10)),u=t/r*i;return.15>=u?i*=10:.35>=u?i*=5:.75>=u&&(i*=2),e[0]=Math.ceil(e[0]/i)*i,e[1]=Math.floor(e[1]/i)*i+.5*i,e[2]=i,e}function Qi(n,t){return ao.range.apply(ao,Ki(n,t))}function nu(n,t,e){var r=Ki(n,t);if(e){var i=ha.exec(e);if(i.shift(),"s"===i[8]){var u=ao.formatPrefix(Math.max(xo(r[0]),xo(r[1])));return i[7]||(i[7]="."+tu(u.scale(r[2]))),i[8]="f",e=ao.format(i.join("")),function(n){return e(u.scale(n))+u.symbol}}i[7]||(i[7]="."+eu(i[8],r)),e=i.join("")}else e=",."+tu(r[2])+"f";return ao.format(e)}function tu(n){return-Math.floor(Math.log(n)/Math.LN10+.01)}function eu(n,t){var e=tu(t[2]);return n in kl?Math.abs(e-tu(Math.max(xo(t[0]),xo(t[1]))))+ +("e"!==n):e-2*("%"===n)}function ru(n,t,e,r){function i(n){return(e?Math.log(0>n?0:n):-Math.log(n>0?0:-n))/Math.log(t)}function u(n){return e?Math.pow(t,n):-Math.pow(t,-n)}function o(t){return n(i(t))}return o.invert=function(t){return u(n.invert(t))},o.domain=function(t){return arguments.length?(e=t[0]>=0,n.domain((r=t.map(Number)).map(i)),o):r},o.base=function(e){return arguments.length?(t=+e,n.domain(r.map(i)),o):t},o.nice=function(){var t=Xi(r.map(i),e?Math:El);return n.domain(t),r=t.map(u),o},o.ticks=function(){var n=Yi(r),o=[],a=n[0],l=n[1],c=Math.floor(i(a)),f=Math.ceil(i(l)),s=t%1?2:t;if(isFinite(f-c)){if(e){for(;f>c;c++)for(var h=1;s>h;h++)o.push(u(c)*h);o.push(u(c))}else for(o.push(u(c));c++0;h--)o.push(u(c)*h);for(c=0;o[c]l;f--);o=o.slice(c,f)}return o},o.tickFormat=function(n,e){if(!arguments.length)return Nl;arguments.length<2?e=Nl:"function"!=typeof e&&(e=ao.format(e));var r=Math.max(1,t*n/o.ticks().length);return function(n){var o=n/u(Math.round(i(n)));return t-.5>o*t&&(o*=t),r>=o?e(n):""}},o.copy=function(){return ru(n.copy(),t,e,r)},Ji(o,n)}function iu(n,t,e){function r(t){return n(i(t))}var i=uu(t),u=uu(1/t);return r.invert=function(t){return u(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain((e=t.map(Number)).map(i)),r):e},r.ticks=function(n){return Qi(e,n)},r.tickFormat=function(n,t){return nu(e,n,t)},r.nice=function(n){return r.domain(Gi(e,n))},r.exponent=function(o){return arguments.length?(i=uu(t=o),u=uu(1/t),n.domain(e.map(i)),r):t},r.copy=function(){return iu(n.copy(),t,e)},Ji(r,n)}function uu(n){return function(t){return 0>t?-Math.pow(-t,n):Math.pow(t,n)}}function ou(n,t){function e(e){return u[((i.get(e)||("range"===t.t?i.set(e,n.push(e)):NaN))-1)%u.length]}function r(t,e){return ao.range(n.length).map(function(n){return t+e*n})}var i,u,o;return e.domain=function(r){if(!arguments.length)return n;n=[],i=new c;for(var u,o=-1,a=r.length;++oe?[NaN,NaN]:[e>0?a[e-1]:n[0],et?NaN:t/u+n,[t,t+1/u]},r.copy=function(){return lu(n,t,e)},i()}function cu(n,t){function e(e){return e>=e?t[ao.bisect(n,e)]:void 0}return e.domain=function(t){return arguments.length?(n=t,e):n},e.range=function(n){return arguments.length?(t=n,e):t},e.invertExtent=function(e){return e=t.indexOf(e),[n[e-1],n[e]]},e.copy=function(){return cu(n,t)},e}function fu(n){function t(n){return+n}return t.invert=t,t.domain=t.range=function(e){return arguments.length?(n=e.map(t),t):n},t.ticks=function(t){return Qi(n,t)},t.tickFormat=function(t,e){return nu(n,t,e)},t.copy=function(){return fu(n)},t}function su(){return 0}function hu(n){return n.innerRadius}function pu(n){return n.outerRadius}function gu(n){return n.startAngle}function vu(n){return n.endAngle}function du(n){return n&&n.padAngle}function yu(n,t,e,r){return(n-e)*t-(t-r)*n>0?0:1}function mu(n,t,e,r,i){var u=n[0]-t[0],o=n[1]-t[1],a=(i?r:-r)/Math.sqrt(u*u+o*o),l=a*o,c=-a*u,f=n[0]+l,s=n[1]+c,h=t[0]+l,p=t[1]+c,g=(f+h)/2,v=(s+p)/2,d=h-f,y=p-s,m=d*d+y*y,M=e-r,x=f*p-h*s,b=(0>y?-1:1)*Math.sqrt(Math.max(0,M*M*m-x*x)),_=(x*y-d*b)/m,w=(-x*d-y*b)/m,S=(x*y+d*b)/m,k=(-x*d+y*b)/m,N=_-g,E=w-v,A=S-g,C=k-v;return N*N+E*E>A*A+C*C&&(_=S,w=k),[[_-l,w-c],[_*e/M,w*e/M]]}function Mu(n){function t(t){function o(){c.push("M",u(n(f),a))}for(var l,c=[],f=[],s=-1,h=t.length,p=En(e),g=En(r);++s1?n.join("L"):n+"Z"}function bu(n){return n.join("L")+"Z"}function _u(n){for(var t=0,e=n.length,r=n[0],i=[r[0],",",r[1]];++t1&&i.push("H",r[0]),i.join("")}function wu(n){for(var t=0,e=n.length,r=n[0],i=[r[0],",",r[1]];++t1){a=t[1],u=n[l],l++,r+="C"+(i[0]+o[0])+","+(i[1]+o[1])+","+(u[0]-a[0])+","+(u[1]-a[1])+","+u[0]+","+u[1];for(var c=2;c9&&(i=3*t/Math.sqrt(i),o[a]=i*e,o[a+1]=i*r));for(a=-1;++a<=l;)i=(n[Math.min(l,a+1)][0]-n[Math.max(0,a-1)][0])/(6*(1+o[a]*o[a])),u.push([i||0,o[a]*i||0]);return u}function Fu(n){return n.length<3?xu(n):n[0]+Au(n,ju(n))}function Hu(n){for(var t,e,r,i=-1,u=n.length;++i=t?o(n-t):void(f.c=o)}function o(e){var i=g.active,u=g[i];u&&(u.timer.c=null,u.timer.t=NaN,--g.count,delete g[i],u.event&&u.event.interrupt.call(n,n.__data__,u.index));for(var o in g)if(r>+o){var c=g[o];c.timer.c=null,c.timer.t=NaN,--g.count,delete g[o]}f.c=a,qn(function(){return f.c&&a(e||1)&&(f.c=null,f.t=NaN),1},0,l),g.active=r,v.event&&v.event.start.call(n,n.__data__,t),p=[],v.tween.forEach(function(e,r){(r=r.call(n,n.__data__,t))&&p.push(r)}),h=v.ease,s=v.duration}function a(i){for(var u=i/s,o=h(u),a=p.length;a>0;)p[--a].call(n,o);return u>=1?(v.event&&v.event.end.call(n,n.__data__,t),--g.count?delete g[r]:delete n[e],1):void 0}var l,f,s,h,p,g=n[e]||(n[e]={active:0,count:0}),v=g[r];v||(l=i.time,f=qn(u,0,l),v=g[r]={tween:new c,time:l,timer:f,delay:i.delay,duration:i.duration,ease:i.ease,index:t},i=null,++g.count)}function no(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate("+(isFinite(r)?r:e(n))+",0)"})}function to(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate(0,"+(isFinite(r)?r:e(n))+")"})}function eo(n){return n.toISOString()}function ro(n,t,e){function r(t){return n(t)}function i(n,e){var r=n[1]-n[0],i=r/e,u=ao.bisect(Kl,i);return u==Kl.length?[t.year,Ki(n.map(function(n){return n/31536e6}),e)[2]]:u?t[i/Kl[u-1]1?{floor:function(t){for(;e(t=n.floor(t));)t=io(t-1);return t},ceil:function(t){for(;e(t=n.ceil(t));)t=io(+t+1);return t}}:n))},r.ticks=function(n,t){var e=Yi(r.domain()),u=null==n?i(e,10):"number"==typeof n?i(e,n):!n.range&&[{range:n},t];return u&&(n=u[0],t=u[1]),n.range(e[0],io(+e[1]+1),1>t?1:t)},r.tickFormat=function(){return e},r.copy=function(){return ro(n.copy(),t,e)},Ji(r,n)}function io(n){return new Date(n)}function uo(n){return JSON.parse(n.responseText)}function oo(n){var t=fo.createRange();return t.selectNode(fo.body),t.createContextualFragment(n.responseText)}var ao={version:"3.5.17"},lo=[].slice,co=function(n){return lo.call(n)},fo=this.document;if(fo)try{co(fo.documentElement.childNodes)[0].nodeType}catch(so){co=function(n){for(var t=n.length,e=new Array(t);t--;)e[t]=n[t];return e}}if(Date.now||(Date.now=function(){return+new Date}),fo)try{fo.createElement("DIV").style.setProperty("opacity",0,"")}catch(ho){var po=this.Element.prototype,go=po.setAttribute,vo=po.setAttributeNS,yo=this.CSSStyleDeclaration.prototype,mo=yo.setProperty;po.setAttribute=function(n,t){go.call(this,n,t+"")},po.setAttributeNS=function(n,t,e){vo.call(this,n,t,e+"")},yo.setProperty=function(n,t,e){mo.call(this,n,t+"",e)}}ao.ascending=e,ao.descending=function(n,t){return n>t?-1:t>n?1:t>=n?0:NaN},ao.min=function(n,t){var e,r,i=-1,u=n.length;if(1===arguments.length){for(;++i=r){e=r;break}for(;++ir&&(e=r)}else{for(;++i=r){e=r;break}for(;++ir&&(e=r)}return e},ao.max=function(n,t){var e,r,i=-1,u=n.length;if(1===arguments.length){for(;++i=r){e=r;break}for(;++ie&&(e=r)}else{for(;++i=r){e=r;break}for(;++ie&&(e=r)}return e},ao.extent=function(n,t){var e,r,i,u=-1,o=n.length;if(1===arguments.length){for(;++u=r){e=i=r;break}for(;++ur&&(e=r),r>i&&(i=r))}else{for(;++u=r){e=i=r;break}for(;++ur&&(e=r),r>i&&(i=r))}return[e,i]},ao.sum=function(n,t){var e,r=0,u=n.length,o=-1;if(1===arguments.length)for(;++o1?l/(f-1):void 0},ao.deviation=function(){var n=ao.variance.apply(this,arguments);return n?Math.sqrt(n):n};var Mo=u(e);ao.bisectLeft=Mo.left,ao.bisect=ao.bisectRight=Mo.right,ao.bisector=function(n){return u(1===n.length?function(t,r){return e(n(t),r)}:n)},ao.shuffle=function(n,t,e){(u=arguments.length)<3&&(e=n.length,2>u&&(t=0));for(var r,i,u=e-t;u;)i=Math.random()*u--|0,r=n[u+t],n[u+t]=n[i+t],n[i+t]=r;return n},ao.permute=function(n,t){for(var e=t.length,r=new Array(e);e--;)r[e]=n[t[e]];return r},ao.pairs=function(n){for(var t,e=0,r=n.length-1,i=n[0],u=new Array(0>r?0:r);r>e;)u[e]=[t=i,i=n[++e]];return u},ao.transpose=function(n){if(!(i=n.length))return[];for(var t=-1,e=ao.min(n,o),r=new Array(e);++t=0;)for(r=n[i],t=r.length;--t>=0;)e[--o]=r[t];return e};var xo=Math.abs;ao.range=function(n,t,e){if(arguments.length<3&&(e=1,arguments.length<2&&(t=n,n=0)),(t-n)/e===1/0)throw new Error("infinite range");var r,i=[],u=a(xo(e)),o=-1;if(n*=u,t*=u,e*=u,0>e)for(;(r=n+e*++o)>t;)i.push(r/u);else for(;(r=n+e*++o)=u.length)return r?r.call(i,o):e?o.sort(e):o;for(var l,f,s,h,p=-1,g=o.length,v=u[a++],d=new c;++p=u.length)return n;var r=[],i=o[e++];return n.forEach(function(n,i){r.push({key:n,values:t(i,e)})}),i?r.sort(function(n,t){return i(n.key,t.key)}):r}var e,r,i={},u=[],o=[];return i.map=function(t,e){return n(e,t,0)},i.entries=function(e){return t(n(ao.map,e,0),0)},i.key=function(n){return u.push(n),i},i.sortKeys=function(n){return o[u.length-1]=n,i},i.sortValues=function(n){return e=n,i},i.rollup=function(n){return r=n,i},i},ao.set=function(n){var t=new y;if(n)for(var e=0,r=n.length;r>e;++e)t.add(n[e]);return t},l(y,{has:h,add:function(n){return this._[f(n+="")]=!0,n},remove:p,values:g,size:v,empty:d,forEach:function(n){for(var t in this._)n.call(this,s(t))}}),ao.behavior={},ao.rebind=function(n,t){for(var e,r=1,i=arguments.length;++r=0&&(r=n.slice(e+1),n=n.slice(0,e)),n)return arguments.length<2?this[n].on(r):this[n].on(r,t);if(2===arguments.length){if(null==t)for(n in this)this.hasOwnProperty(n)&&this[n].on(r,null);return this}},ao.event=null,ao.requote=function(n){return n.replace(So,"\\$&")};var So=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g,ko={}.__proto__?function(n,t){n.__proto__=t}:function(n,t){for(var e in t)n[e]=t[e]},No=function(n,t){return t.querySelector(n)},Eo=function(n,t){return t.querySelectorAll(n)},Ao=function(n,t){var e=n.matches||n[x(n,"matchesSelector")];return(Ao=function(n,t){return e.call(n,t)})(n,t)};"function"==typeof Sizzle&&(No=function(n,t){return Sizzle(n,t)[0]||null},Eo=Sizzle,Ao=Sizzle.matchesSelector),ao.selection=function(){return ao.select(fo.documentElement)};var Co=ao.selection.prototype=[];Co.select=function(n){var t,e,r,i,u=[];n=A(n);for(var o=-1,a=this.length;++o=0&&"xmlns"!==(e=n.slice(0,t))&&(n=n.slice(t+1)),Lo.hasOwnProperty(e)?{space:Lo[e],local:n}:n}},Co.attr=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node();return n=ao.ns.qualify(n),n.local?e.getAttributeNS(n.space,n.local):e.getAttribute(n)}for(t in n)this.each(z(t,n[t]));return this}return this.each(z(n,t))},Co.classed=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node(),r=(n=T(n)).length,i=-1;if(t=e.classList){for(;++ii){if("string"!=typeof n){2>i&&(e="");for(r in n)this.each(P(r,n[r],e));return this}if(2>i){var u=this.node();return t(u).getComputedStyle(u,null).getPropertyValue(n)}r=""}return this.each(P(n,e,r))},Co.property=function(n,t){if(arguments.length<2){if("string"==typeof n)return this.node()[n];for(t in n)this.each(U(t,n[t]));return this}return this.each(U(n,t))},Co.text=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.textContent=null==t?"":t}:null==n?function(){this.textContent=""}:function(){this.textContent=n}):this.node().textContent},Co.html=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.innerHTML=null==t?"":t}:null==n?function(){this.innerHTML=""}:function(){this.innerHTML=n}):this.node().innerHTML},Co.append=function(n){return n=j(n),this.select(function(){return this.appendChild(n.apply(this,arguments))})},Co.insert=function(n,t){return n=j(n),t=A(t),this.select(function(){return this.insertBefore(n.apply(this,arguments),t.apply(this,arguments)||null)})},Co.remove=function(){return this.each(F)},Co.data=function(n,t){function e(n,e){var r,i,u,o=n.length,s=e.length,h=Math.min(o,s),p=new Array(s),g=new Array(s),v=new Array(o);if(t){var d,y=new c,m=new Array(o);for(r=-1;++rr;++r)g[r]=H(e[r]);for(;o>r;++r)v[r]=n[r]}g.update=p,g.parentNode=p.parentNode=v.parentNode=n.parentNode,a.push(g),l.push(p),f.push(v)}var r,i,u=-1,o=this.length;if(!arguments.length){for(n=new Array(o=(r=this[0]).length);++uu;u++){i.push(t=[]),t.parentNode=(e=this[u]).parentNode;for(var a=0,l=e.length;l>a;a++)(r=e[a])&&n.call(r,r.__data__,a,u)&&t.push(r)}return E(i)},Co.order=function(){for(var n=-1,t=this.length;++n=0;)(e=r[i])&&(u&&u!==e.nextSibling&&u.parentNode.insertBefore(e,u),u=e);return this},Co.sort=function(n){n=I.apply(this,arguments);for(var t=-1,e=this.length;++tn;n++)for(var e=this[n],r=0,i=e.length;i>r;r++){var u=e[r];if(u)return u}return null},Co.size=function(){var n=0;return Y(this,function(){++n}),n};var qo=[];ao.selection.enter=Z,ao.selection.enter.prototype=qo,qo.append=Co.append,qo.empty=Co.empty,qo.node=Co.node,qo.call=Co.call,qo.size=Co.size,qo.select=function(n){for(var t,e,r,i,u,o=[],a=-1,l=this.length;++ar){if("string"!=typeof n){2>r&&(t=!1);for(e in n)this.each(X(e,n[e],t));return this}if(2>r)return(r=this.node()["__on"+n])&&r._;e=!1}return this.each(X(n,t,e))};var To=ao.map({mouseenter:"mouseover",mouseleave:"mouseout"});fo&&To.forEach(function(n){"on"+n in fo&&To.remove(n)});var Ro,Do=0;ao.mouse=function(n){return J(n,k())};var Po=this.navigator&&/WebKit/.test(this.navigator.userAgent)?-1:0;ao.touch=function(n,t,e){if(arguments.length<3&&(e=t,t=k().changedTouches),t)for(var r,i=0,u=t.length;u>i;++i)if((r=t[i]).identifier===e)return J(n,r)},ao.behavior.drag=function(){function n(){this.on("mousedown.drag",u).on("touchstart.drag",o)}function e(n,t,e,u,o){return function(){function a(){var n,e,r=t(h,v);r&&(n=r[0]-M[0],e=r[1]-M[1],g|=n|e,M=r,p({type:"drag",x:r[0]+c[0],y:r[1]+c[1],dx:n,dy:e}))}function l(){t(h,v)&&(y.on(u+d,null).on(o+d,null),m(g),p({type:"dragend"}))}var c,f=this,s=ao.event.target.correspondingElement||ao.event.target,h=f.parentNode,p=r.of(f,arguments),g=0,v=n(),d=".drag"+(null==v?"":"-"+v),y=ao.select(e(s)).on(u+d,a).on(o+d,l),m=W(s),M=t(h,v);i?(c=i.apply(f,arguments),c=[c.x-M[0],c.y-M[1]]):c=[0,0],p({type:"dragstart"})}}var r=N(n,"drag","dragstart","dragend"),i=null,u=e(b,ao.mouse,t,"mousemove","mouseup"),o=e(G,ao.touch,m,"touchmove","touchend");return n.origin=function(t){return arguments.length?(i=t,n):i},ao.rebind(n,r,"on")},ao.touches=function(n,t){return arguments.length<2&&(t=k().touches),t?co(t).map(function(t){var e=J(n,t);return e.identifier=t.identifier,e}):[]};var Uo=1e-6,jo=Uo*Uo,Fo=Math.PI,Ho=2*Fo,Oo=Ho-Uo,Io=Fo/2,Yo=Fo/180,Zo=180/Fo,Vo=Math.SQRT2,Xo=2,$o=4;ao.interpolateZoom=function(n,t){var e,r,i=n[0],u=n[1],o=n[2],a=t[0],l=t[1],c=t[2],f=a-i,s=l-u,h=f*f+s*s;if(jo>h)r=Math.log(c/o)/Vo,e=function(n){return[i+n*f,u+n*s,o*Math.exp(Vo*n*r)]};else{var p=Math.sqrt(h),g=(c*c-o*o+$o*h)/(2*o*Xo*p),v=(c*c-o*o-$o*h)/(2*c*Xo*p),d=Math.log(Math.sqrt(g*g+1)-g),y=Math.log(Math.sqrt(v*v+1)-v);r=(y-d)/Vo,e=function(n){var t=n*r,e=rn(d),a=o/(Xo*p)*(e*un(Vo*t+d)-en(d));return[i+a*f,u+a*s,o*e/rn(Vo*t+d)]}}return e.duration=1e3*r,e},ao.behavior.zoom=function(){function n(n){n.on(L,s).on(Wo+".zoom",p).on("dblclick.zoom",g).on(R,h)}function e(n){return[(n[0]-k.x)/k.k,(n[1]-k.y)/k.k]}function r(n){return[n[0]*k.k+k.x,n[1]*k.k+k.y]}function i(n){k.k=Math.max(A[0],Math.min(A[1],n))}function u(n,t){t=r(t),k.x+=n[0]-t[0],k.y+=n[1]-t[1]}function o(t,e,r,o){t.__chart__={x:k.x,y:k.y,k:k.k},i(Math.pow(2,o)),u(d=e,r),t=ao.select(t),C>0&&(t=t.transition().duration(C)),t.call(n.event)}function a(){b&&b.domain(x.range().map(function(n){return(n-k.x)/k.k}).map(x.invert)),w&&w.domain(_.range().map(function(n){return(n-k.y)/k.k}).map(_.invert))}function l(n){z++||n({type:"zoomstart"})}function c(n){a(),n({type:"zoom",scale:k.k,translate:[k.x,k.y]})}function f(n){--z||(n({type:"zoomend"}),d=null)}function s(){function n(){a=1,u(ao.mouse(i),h),c(o)}function r(){s.on(q,null).on(T,null),p(a),f(o)}var i=this,o=D.of(i,arguments),a=0,s=ao.select(t(i)).on(q,n).on(T,r),h=e(ao.mouse(i)),p=W(i);Il.call(i),l(o)}function h(){function n(){var n=ao.touches(g);return p=k.k,n.forEach(function(n){n.identifier in d&&(d[n.identifier]=e(n))}),n}function t(){var t=ao.event.target;ao.select(t).on(x,r).on(b,a),_.push(t);for(var e=ao.event.changedTouches,i=0,u=e.length;u>i;++i)d[e[i].identifier]=null;var l=n(),c=Date.now();if(1===l.length){if(500>c-M){var f=l[0];o(g,f,d[f.identifier],Math.floor(Math.log(k.k)/Math.LN2)+1),S()}M=c}else if(l.length>1){var f=l[0],s=l[1],h=f[0]-s[0],p=f[1]-s[1];y=h*h+p*p}}function r(){var n,t,e,r,o=ao.touches(g);Il.call(g);for(var a=0,l=o.length;l>a;++a,r=null)if(e=o[a],r=d[e.identifier]){if(t)break;n=e,t=r}if(r){var f=(f=e[0]-n[0])*f+(f=e[1]-n[1])*f,s=y&&Math.sqrt(f/y);n=[(n[0]+e[0])/2,(n[1]+e[1])/2],t=[(t[0]+r[0])/2,(t[1]+r[1])/2],i(s*p)}M=null,u(n,t),c(v)}function a(){if(ao.event.touches.length){for(var t=ao.event.changedTouches,e=0,r=t.length;r>e;++e)delete d[t[e].identifier];for(var i in d)return void n()}ao.selectAll(_).on(m,null),w.on(L,s).on(R,h),N(),f(v)}var p,g=this,v=D.of(g,arguments),d={},y=0,m=".zoom-"+ao.event.changedTouches[0].identifier,x="touchmove"+m,b="touchend"+m,_=[],w=ao.select(g),N=W(g);t(),l(v),w.on(L,null).on(R,t)}function p(){var n=D.of(this,arguments);m?clearTimeout(m):(Il.call(this),v=e(d=y||ao.mouse(this)),l(n)),m=setTimeout(function(){m=null,f(n)},50),S(),i(Math.pow(2,.002*Bo())*k.k),u(d,v),c(n)}function g(){var n=ao.mouse(this),t=Math.log(k.k)/Math.LN2;o(this,n,e(n),ao.event.shiftKey?Math.ceil(t)-1:Math.floor(t)+1)}var v,d,y,m,M,x,b,_,w,k={x:0,y:0,k:1},E=[960,500],A=Jo,C=250,z=0,L="mousedown.zoom",q="mousemove.zoom",T="mouseup.zoom",R="touchstart.zoom",D=N(n,"zoomstart","zoom","zoomend");return Wo||(Wo="onwheel"in fo?(Bo=function(){return-ao.event.deltaY*(ao.event.deltaMode?120:1)},"wheel"):"onmousewheel"in fo?(Bo=function(){return ao.event.wheelDelta},"mousewheel"):(Bo=function(){return-ao.event.detail},"MozMousePixelScroll")),n.event=function(n){n.each(function(){var n=D.of(this,arguments),t=k;Hl?ao.select(this).transition().each("start.zoom",function(){k=this.__chart__||{x:0,y:0,k:1},l(n)}).tween("zoom:zoom",function(){var e=E[0],r=E[1],i=d?d[0]:e/2,u=d?d[1]:r/2,o=ao.interpolateZoom([(i-k.x)/k.k,(u-k.y)/k.k,e/k.k],[(i-t.x)/t.k,(u-t.y)/t.k,e/t.k]);return function(t){var r=o(t),a=e/r[2];this.__chart__=k={x:i-r[0]*a,y:u-r[1]*a,k:a},c(n)}}).each("interrupt.zoom",function(){f(n)}).each("end.zoom",function(){f(n)}):(this.__chart__=k,l(n),c(n),f(n))})},n.translate=function(t){return arguments.length?(k={x:+t[0],y:+t[1],k:k.k},a(),n):[k.x,k.y]},n.scale=function(t){return arguments.length?(k={x:k.x,y:k.y,k:null},i(+t),a(),n):k.k},n.scaleExtent=function(t){return arguments.length?(A=null==t?Jo:[+t[0],+t[1]],n):A},n.center=function(t){return arguments.length?(y=t&&[+t[0],+t[1]],n):y},n.size=function(t){return arguments.length?(E=t&&[+t[0],+t[1]],n):E},n.duration=function(t){return arguments.length?(C=+t,n):C},n.x=function(t){return arguments.length?(b=t,x=t.copy(),k={x:0,y:0,k:1},n):b},n.y=function(t){return arguments.length?(w=t,_=t.copy(),k={x:0,y:0,k:1},n):w},ao.rebind(n,D,"on")};var Bo,Wo,Jo=[0,1/0];ao.color=an,an.prototype.toString=function(){return this.rgb()+""},ao.hsl=ln;var Go=ln.prototype=new an;Go.brighter=function(n){return n=Math.pow(.7,arguments.length?n:1),new ln(this.h,this.s,this.l/n)},Go.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new ln(this.h,this.s,n*this.l)},Go.rgb=function(){return cn(this.h,this.s,this.l)},ao.hcl=fn;var Ko=fn.prototype=new an;Ko.brighter=function(n){return new fn(this.h,this.c,Math.min(100,this.l+Qo*(arguments.length?n:1)))},Ko.darker=function(n){return new fn(this.h,this.c,Math.max(0,this.l-Qo*(arguments.length?n:1)))},Ko.rgb=function(){return sn(this.h,this.c,this.l).rgb()},ao.lab=hn;var Qo=18,na=.95047,ta=1,ea=1.08883,ra=hn.prototype=new an;ra.brighter=function(n){return new hn(Math.min(100,this.l+Qo*(arguments.length?n:1)),this.a,this.b)},ra.darker=function(n){return new hn(Math.max(0,this.l-Qo*(arguments.length?n:1)),this.a,this.b)},ra.rgb=function(){return pn(this.l,this.a,this.b)},ao.rgb=mn;var ia=mn.prototype=new an;ia.brighter=function(n){n=Math.pow(.7,arguments.length?n:1);var t=this.r,e=this.g,r=this.b,i=30;return t||e||r?(t&&i>t&&(t=i),e&&i>e&&(e=i),r&&i>r&&(r=i),new mn(Math.min(255,t/n),Math.min(255,e/n),Math.min(255,r/n))):new mn(i,i,i)},ia.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new mn(n*this.r,n*this.g,n*this.b)},ia.hsl=function(){return wn(this.r,this.g,this.b)},ia.toString=function(){return"#"+bn(this.r)+bn(this.g)+bn(this.b)};var ua=ao.map({aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074});ua.forEach(function(n,t){ua.set(n,Mn(t))}),ao.functor=En,ao.xhr=An(m),ao.dsv=function(n,t){function e(n,e,u){arguments.length<3&&(u=e,e=null);var o=Cn(n,t,null==e?r:i(e),u);return o.row=function(n){return arguments.length?o.response(null==(e=n)?r:i(n)):e},o}function r(n){return e.parse(n.responseText)}function i(n){return function(t){return e.parse(t.responseText,n)}}function u(t){return t.map(o).join(n)}function o(n){return a.test(n)?'"'+n.replace(/\"/g,'""')+'"':n}var a=new RegExp('["'+n+"\n]"),l=n.charCodeAt(0);return e.parse=function(n,t){var r;return e.parseRows(n,function(n,e){if(r)return r(n,e-1);var i=new Function("d","return {"+n.map(function(n,t){return JSON.stringify(n)+": d["+t+"]"}).join(",")+"}");r=t?function(n,e){return t(i(n),e)}:i})},e.parseRows=function(n,t){function e(){if(f>=c)return o;if(i)return i=!1,u;var t=f;if(34===n.charCodeAt(t)){for(var e=t;e++f;){var r=n.charCodeAt(f++),a=1;if(10===r)i=!0;else if(13===r)i=!0,10===n.charCodeAt(f)&&(++f,++a);else if(r!==l)continue;return n.slice(t,f-a)}return n.slice(t)}for(var r,i,u={},o={},a=[],c=n.length,f=0,s=0;(r=e())!==o;){for(var h=[];r!==u&&r!==o;)h.push(r),r=e();t&&null==(h=t(h,s++))||a.push(h)}return a},e.format=function(t){if(Array.isArray(t[0]))return e.formatRows(t);var r=new y,i=[];return t.forEach(function(n){for(var t in n)r.has(t)||i.push(r.add(t))}),[i.map(o).join(n)].concat(t.map(function(t){return i.map(function(n){return o(t[n])}).join(n)})).join("\n")},e.formatRows=function(n){return n.map(u).join("\n")},e},ao.csv=ao.dsv(",","text/csv"),ao.tsv=ao.dsv(" ","text/tab-separated-values");var oa,aa,la,ca,fa=this[x(this,"requestAnimationFrame")]||function(n){setTimeout(n,17)};ao.timer=function(){qn.apply(this,arguments)},ao.timer.flush=function(){Rn(),Dn()},ao.round=function(n,t){return t?Math.round(n*(t=Math.pow(10,t)))/t:Math.round(n)};var sa=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"].map(Un);ao.formatPrefix=function(n,t){var e=0;return(n=+n)&&(0>n&&(n*=-1),t&&(n=ao.round(n,Pn(n,t))),e=1+Math.floor(1e-12+Math.log(n)/Math.LN10),e=Math.max(-24,Math.min(24,3*Math.floor((e-1)/3)))),sa[8+e/3]};var ha=/(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i,pa=ao.map({b:function(n){return n.toString(2)},c:function(n){return String.fromCharCode(n)},o:function(n){return n.toString(8)},x:function(n){return n.toString(16)},X:function(n){return n.toString(16).toUpperCase()},g:function(n,t){return n.toPrecision(t)},e:function(n,t){return n.toExponential(t)},f:function(n,t){return n.toFixed(t)},r:function(n,t){return(n=ao.round(n,Pn(n,t))).toFixed(Math.max(0,Math.min(20,Pn(n*(1+1e-15),t))))}}),ga=ao.time={},va=Date;Hn.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){da.setUTCDate.apply(this._,arguments)},setDay:function(){da.setUTCDay.apply(this._,arguments)},setFullYear:function(){da.setUTCFullYear.apply(this._,arguments)},setHours:function(){da.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){da.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){da.setUTCMinutes.apply(this._,arguments)},setMonth:function(){da.setUTCMonth.apply(this._,arguments)},setSeconds:function(){da.setUTCSeconds.apply(this._,arguments)},setTime:function(){da.setTime.apply(this._,arguments)}};var da=Date.prototype;ga.year=On(function(n){return n=ga.day(n),n.setMonth(0,1),n},function(n,t){n.setFullYear(n.getFullYear()+t)},function(n){return n.getFullYear()}),ga.years=ga.year.range,ga.years.utc=ga.year.utc.range,ga.day=On(function(n){var t=new va(2e3,0);return t.setFullYear(n.getFullYear(),n.getMonth(),n.getDate()),t},function(n,t){n.setDate(n.getDate()+t)},function(n){return n.getDate()-1}),ga.days=ga.day.range,ga.days.utc=ga.day.utc.range,ga.dayOfYear=function(n){var t=ga.year(n);return Math.floor((n-t-6e4*(n.getTimezoneOffset()-t.getTimezoneOffset()))/864e5)},["sunday","monday","tuesday","wednesday","thursday","friday","saturday"].forEach(function(n,t){t=7-t;var e=ga[n]=On(function(n){return(n=ga.day(n)).setDate(n.getDate()-(n.getDay()+t)%7),n},function(n,t){n.setDate(n.getDate()+7*Math.floor(t))},function(n){var e=ga.year(n).getDay();return Math.floor((ga.dayOfYear(n)+(e+t)%7)/7)-(e!==t)});ga[n+"s"]=e.range,ga[n+"s"].utc=e.utc.range,ga[n+"OfYear"]=function(n){var e=ga.year(n).getDay();return Math.floor((ga.dayOfYear(n)+(e+t)%7)/7)}}),ga.week=ga.sunday,ga.weeks=ga.sunday.range,ga.weeks.utc=ga.sunday.utc.range,ga.weekOfYear=ga.sundayOfYear;var ya={"-":"",_:" ",0:"0"},ma=/^\s*\d+/,Ma=/^%/;ao.locale=function(n){return{numberFormat:jn(n),timeFormat:Yn(n)}};var xa=ao.locale({decimal:".",thousands:",",grouping:[3],currency:["$",""],dateTime:"%a %b %e %X %Y",date:"%m/%d/%Y",time:"%H:%M:%S",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"], +shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});ao.format=xa.numberFormat,ao.geo={},ft.prototype={s:0,t:0,add:function(n){st(n,this.t,ba),st(ba.s,this.s,this),this.s?this.t+=ba.t:this.s=ba.t},reset:function(){this.s=this.t=0},valueOf:function(){return this.s}};var ba=new ft;ao.geo.stream=function(n,t){n&&_a.hasOwnProperty(n.type)?_a[n.type](n,t):ht(n,t)};var _a={Feature:function(n,t){ht(n.geometry,t)},FeatureCollection:function(n,t){for(var e=n.features,r=-1,i=e.length;++rn?4*Fo+n:n,Na.lineStart=Na.lineEnd=Na.point=b}};ao.geo.bounds=function(){function n(n,t){M.push(x=[f=n,h=n]),s>t&&(s=t),t>p&&(p=t)}function t(t,e){var r=dt([t*Yo,e*Yo]);if(y){var i=mt(y,r),u=[i[1],-i[0],0],o=mt(u,i);bt(o),o=_t(o);var l=t-g,c=l>0?1:-1,v=o[0]*Zo*c,d=xo(l)>180;if(d^(v>c*g&&c*t>v)){var m=o[1]*Zo;m>p&&(p=m)}else if(v=(v+360)%360-180,d^(v>c*g&&c*t>v)){var m=-o[1]*Zo;s>m&&(s=m)}else s>e&&(s=e),e>p&&(p=e);d?g>t?a(f,t)>a(f,h)&&(h=t):a(t,h)>a(f,h)&&(f=t):h>=f?(f>t&&(f=t),t>h&&(h=t)):t>g?a(f,t)>a(f,h)&&(h=t):a(t,h)>a(f,h)&&(f=t)}else n(t,e);y=r,g=t}function e(){b.point=t}function r(){x[0]=f,x[1]=h,b.point=n,y=null}function i(n,e){if(y){var r=n-g;m+=xo(r)>180?r+(r>0?360:-360):r}else v=n,d=e;Na.point(n,e),t(n,e)}function u(){Na.lineStart()}function o(){i(v,d),Na.lineEnd(),xo(m)>Uo&&(f=-(h=180)),x[0]=f,x[1]=h,y=null}function a(n,t){return(t-=n)<0?t+360:t}function l(n,t){return n[0]-t[0]}function c(n,t){return t[0]<=t[1]?t[0]<=n&&n<=t[1]:nka?(f=-(h=180),s=-(p=90)):m>Uo?p=90:-Uo>m&&(s=-90),x[0]=f,x[1]=h}};return function(n){p=h=-(f=s=1/0),M=[],ao.geo.stream(n,b);var t=M.length;if(t){M.sort(l);for(var e,r=1,i=M[0],u=[i];t>r;++r)e=M[r],c(e[0],i)||c(e[1],i)?(a(i[0],e[1])>a(i[0],i[1])&&(i[1]=e[1]),a(e[0],i[1])>a(i[0],i[1])&&(i[0]=e[0])):u.push(i=e);for(var o,e,g=-(1/0),t=u.length-1,r=0,i=u[t];t>=r;i=e,++r)e=u[r],(o=a(i[1],e[0]))>g&&(g=o,f=e[0],h=i[1])}return M=x=null,f===1/0||s===1/0?[[NaN,NaN],[NaN,NaN]]:[[f,s],[h,p]]}}(),ao.geo.centroid=function(n){Ea=Aa=Ca=za=La=qa=Ta=Ra=Da=Pa=Ua=0,ao.geo.stream(n,ja);var t=Da,e=Pa,r=Ua,i=t*t+e*e+r*r;return jo>i&&(t=qa,e=Ta,r=Ra,Uo>Aa&&(t=Ca,e=za,r=La),i=t*t+e*e+r*r,jo>i)?[NaN,NaN]:[Math.atan2(e,t)*Zo,tn(r/Math.sqrt(i))*Zo]};var Ea,Aa,Ca,za,La,qa,Ta,Ra,Da,Pa,Ua,ja={sphere:b,point:St,lineStart:Nt,lineEnd:Et,polygonStart:function(){ja.lineStart=At},polygonEnd:function(){ja.lineStart=Nt}},Fa=Rt(zt,jt,Ht,[-Fo,-Fo/2]),Ha=1e9;ao.geo.clipExtent=function(){var n,t,e,r,i,u,o={stream:function(n){return i&&(i.valid=!1),i=u(n),i.valid=!0,i},extent:function(a){return arguments.length?(u=Zt(n=+a[0][0],t=+a[0][1],e=+a[1][0],r=+a[1][1]),i&&(i.valid=!1,i=null),o):[[n,t],[e,r]]}};return o.extent([[0,0],[960,500]])},(ao.geo.conicEqualArea=function(){return Vt(Xt)}).raw=Xt,ao.geo.albers=function(){return ao.geo.conicEqualArea().rotate([96,0]).center([-.6,38.7]).parallels([29.5,45.5]).scale(1070)},ao.geo.albersUsa=function(){function n(n){var u=n[0],o=n[1];return t=null,e(u,o),t||(r(u,o),t)||i(u,o),t}var t,e,r,i,u=ao.geo.albers(),o=ao.geo.conicEqualArea().rotate([154,0]).center([-2,58.5]).parallels([55,65]),a=ao.geo.conicEqualArea().rotate([157,0]).center([-3,19.9]).parallels([8,18]),l={point:function(n,e){t=[n,e]}};return n.invert=function(n){var t=u.scale(),e=u.translate(),r=(n[0]-e[0])/t,i=(n[1]-e[1])/t;return(i>=.12&&.234>i&&r>=-.425&&-.214>r?o:i>=.166&&.234>i&&r>=-.214&&-.115>r?a:u).invert(n)},n.stream=function(n){var t=u.stream(n),e=o.stream(n),r=a.stream(n);return{point:function(n,i){t.point(n,i),e.point(n,i),r.point(n,i)},sphere:function(){t.sphere(),e.sphere(),r.sphere()},lineStart:function(){t.lineStart(),e.lineStart(),r.lineStart()},lineEnd:function(){t.lineEnd(),e.lineEnd(),r.lineEnd()},polygonStart:function(){t.polygonStart(),e.polygonStart(),r.polygonStart()},polygonEnd:function(){t.polygonEnd(),e.polygonEnd(),r.polygonEnd()}}},n.precision=function(t){return arguments.length?(u.precision(t),o.precision(t),a.precision(t),n):u.precision()},n.scale=function(t){return arguments.length?(u.scale(t),o.scale(.35*t),a.scale(t),n.translate(u.translate())):u.scale()},n.translate=function(t){if(!arguments.length)return u.translate();var c=u.scale(),f=+t[0],s=+t[1];return e=u.translate(t).clipExtent([[f-.455*c,s-.238*c],[f+.455*c,s+.238*c]]).stream(l).point,r=o.translate([f-.307*c,s+.201*c]).clipExtent([[f-.425*c+Uo,s+.12*c+Uo],[f-.214*c-Uo,s+.234*c-Uo]]).stream(l).point,i=a.translate([f-.205*c,s+.212*c]).clipExtent([[f-.214*c+Uo,s+.166*c+Uo],[f-.115*c-Uo,s+.234*c-Uo]]).stream(l).point,n},n.scale(1070)};var Oa,Ia,Ya,Za,Va,Xa,$a={point:b,lineStart:b,lineEnd:b,polygonStart:function(){Ia=0,$a.lineStart=$t},polygonEnd:function(){$a.lineStart=$a.lineEnd=$a.point=b,Oa+=xo(Ia/2)}},Ba={point:Bt,lineStart:b,lineEnd:b,polygonStart:b,polygonEnd:b},Wa={point:Gt,lineStart:Kt,lineEnd:Qt,polygonStart:function(){Wa.lineStart=ne},polygonEnd:function(){Wa.point=Gt,Wa.lineStart=Kt,Wa.lineEnd=Qt}};ao.geo.path=function(){function n(n){return n&&("function"==typeof a&&u.pointRadius(+a.apply(this,arguments)),o&&o.valid||(o=i(u)),ao.geo.stream(n,o)),u.result()}function t(){return o=null,n}var e,r,i,u,o,a=4.5;return n.area=function(n){return Oa=0,ao.geo.stream(n,i($a)),Oa},n.centroid=function(n){return Ca=za=La=qa=Ta=Ra=Da=Pa=Ua=0,ao.geo.stream(n,i(Wa)),Ua?[Da/Ua,Pa/Ua]:Ra?[qa/Ra,Ta/Ra]:La?[Ca/La,za/La]:[NaN,NaN]},n.bounds=function(n){return Va=Xa=-(Ya=Za=1/0),ao.geo.stream(n,i(Ba)),[[Ya,Za],[Va,Xa]]},n.projection=function(n){return arguments.length?(i=(e=n)?n.stream||re(n):m,t()):e},n.context=function(n){return arguments.length?(u=null==(r=n)?new Wt:new te(n),"function"!=typeof a&&u.pointRadius(a),t()):r},n.pointRadius=function(t){return arguments.length?(a="function"==typeof t?t:(u.pointRadius(+t),+t),n):a},n.projection(ao.geo.albersUsa()).context(null)},ao.geo.transform=function(n){return{stream:function(t){var e=new ie(t);for(var r in n)e[r]=n[r];return e}}},ie.prototype={point:function(n,t){this.stream.point(n,t)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}},ao.geo.projection=oe,ao.geo.projectionMutator=ae,(ao.geo.equirectangular=function(){return oe(ce)}).raw=ce.invert=ce,ao.geo.rotation=function(n){function t(t){return t=n(t[0]*Yo,t[1]*Yo),t[0]*=Zo,t[1]*=Zo,t}return n=se(n[0]%360*Yo,n[1]*Yo,n.length>2?n[2]*Yo:0),t.invert=function(t){return t=n.invert(t[0]*Yo,t[1]*Yo),t[0]*=Zo,t[1]*=Zo,t},t},fe.invert=ce,ao.geo.circle=function(){function n(){var n="function"==typeof r?r.apply(this,arguments):r,t=se(-n[0]*Yo,-n[1]*Yo,0).invert,i=[];return e(null,null,1,{point:function(n,e){i.push(n=t(n,e)),n[0]*=Zo,n[1]*=Zo}}),{type:"Polygon",coordinates:[i]}}var t,e,r=[0,0],i=6;return n.origin=function(t){return arguments.length?(r=t,n):r},n.angle=function(r){return arguments.length?(e=ve((t=+r)*Yo,i*Yo),n):t},n.precision=function(r){return arguments.length?(e=ve(t*Yo,(i=+r)*Yo),n):i},n.angle(90)},ao.geo.distance=function(n,t){var e,r=(t[0]-n[0])*Yo,i=n[1]*Yo,u=t[1]*Yo,o=Math.sin(r),a=Math.cos(r),l=Math.sin(i),c=Math.cos(i),f=Math.sin(u),s=Math.cos(u);return Math.atan2(Math.sqrt((e=s*o)*e+(e=c*f-l*s*a)*e),l*f+c*s*a)},ao.geo.graticule=function(){function n(){return{type:"MultiLineString",coordinates:t()}}function t(){return ao.range(Math.ceil(u/d)*d,i,d).map(h).concat(ao.range(Math.ceil(c/y)*y,l,y).map(p)).concat(ao.range(Math.ceil(r/g)*g,e,g).filter(function(n){return xo(n%d)>Uo}).map(f)).concat(ao.range(Math.ceil(a/v)*v,o,v).filter(function(n){return xo(n%y)>Uo}).map(s))}var e,r,i,u,o,a,l,c,f,s,h,p,g=10,v=g,d=90,y=360,m=2.5;return n.lines=function(){return t().map(function(n){return{type:"LineString",coordinates:n}})},n.outline=function(){return{type:"Polygon",coordinates:[h(u).concat(p(l).slice(1),h(i).reverse().slice(1),p(c).reverse().slice(1))]}},n.extent=function(t){return arguments.length?n.majorExtent(t).minorExtent(t):n.minorExtent()},n.majorExtent=function(t){return arguments.length?(u=+t[0][0],i=+t[1][0],c=+t[0][1],l=+t[1][1],u>i&&(t=u,u=i,i=t),c>l&&(t=c,c=l,l=t),n.precision(m)):[[u,c],[i,l]]},n.minorExtent=function(t){return arguments.length?(r=+t[0][0],e=+t[1][0],a=+t[0][1],o=+t[1][1],r>e&&(t=r,r=e,e=t),a>o&&(t=a,a=o,o=t),n.precision(m)):[[r,a],[e,o]]},n.step=function(t){return arguments.length?n.majorStep(t).minorStep(t):n.minorStep()},n.majorStep=function(t){return arguments.length?(d=+t[0],y=+t[1],n):[d,y]},n.minorStep=function(t){return arguments.length?(g=+t[0],v=+t[1],n):[g,v]},n.precision=function(t){return arguments.length?(m=+t,f=ye(a,o,90),s=me(r,e,m),h=ye(c,l,90),p=me(u,i,m),n):m},n.majorExtent([[-180,-90+Uo],[180,90-Uo]]).minorExtent([[-180,-80-Uo],[180,80+Uo]])},ao.geo.greatArc=function(){function n(){return{type:"LineString",coordinates:[t||r.apply(this,arguments),e||i.apply(this,arguments)]}}var t,e,r=Me,i=xe;return n.distance=function(){return ao.geo.distance(t||r.apply(this,arguments),e||i.apply(this,arguments))},n.source=function(e){return arguments.length?(r=e,t="function"==typeof e?null:e,n):r},n.target=function(t){return arguments.length?(i=t,e="function"==typeof t?null:t,n):i},n.precision=function(){return arguments.length?n:0},n},ao.geo.interpolate=function(n,t){return be(n[0]*Yo,n[1]*Yo,t[0]*Yo,t[1]*Yo)},ao.geo.length=function(n){return Ja=0,ao.geo.stream(n,Ga),Ja};var Ja,Ga={sphere:b,point:b,lineStart:_e,lineEnd:b,polygonStart:b,polygonEnd:b},Ka=we(function(n){return Math.sqrt(2/(1+n))},function(n){return 2*Math.asin(n/2)});(ao.geo.azimuthalEqualArea=function(){return oe(Ka)}).raw=Ka;var Qa=we(function(n){var t=Math.acos(n);return t&&t/Math.sin(t)},m);(ao.geo.azimuthalEquidistant=function(){return oe(Qa)}).raw=Qa,(ao.geo.conicConformal=function(){return Vt(Se)}).raw=Se,(ao.geo.conicEquidistant=function(){return Vt(ke)}).raw=ke;var nl=we(function(n){return 1/n},Math.atan);(ao.geo.gnomonic=function(){return oe(nl)}).raw=nl,Ne.invert=function(n,t){return[n,2*Math.atan(Math.exp(t))-Io]},(ao.geo.mercator=function(){return Ee(Ne)}).raw=Ne;var tl=we(function(){return 1},Math.asin);(ao.geo.orthographic=function(){return oe(tl)}).raw=tl;var el=we(function(n){return 1/(1+n)},function(n){return 2*Math.atan(n)});(ao.geo.stereographic=function(){return oe(el)}).raw=el,Ae.invert=function(n,t){return[-t,2*Math.atan(Math.exp(n))-Io]},(ao.geo.transverseMercator=function(){var n=Ee(Ae),t=n.center,e=n.rotate;return n.center=function(n){return n?t([-n[1],n[0]]):(n=t(),[n[1],-n[0]])},n.rotate=function(n){return n?e([n[0],n[1],n.length>2?n[2]+90:90]):(n=e(),[n[0],n[1],n[2]-90])},e([0,0,90])}).raw=Ae,ao.geom={},ao.geom.hull=function(n){function t(n){if(n.length<3)return[];var t,i=En(e),u=En(r),o=n.length,a=[],l=[];for(t=0;o>t;t++)a.push([+i.call(this,n[t],t),+u.call(this,n[t],t),t]);for(a.sort(qe),t=0;o>t;t++)l.push([a[t][0],-a[t][1]]);var c=Le(a),f=Le(l),s=f[0]===c[0],h=f[f.length-1]===c[c.length-1],p=[];for(t=c.length-1;t>=0;--t)p.push(n[a[c[t]][2]]);for(t=+s;t=r&&c.x<=u&&c.y>=i&&c.y<=o?[[r,o],[u,o],[u,i],[r,i]]:[];f.point=n[a]}),t}function e(n){return n.map(function(n,t){return{x:Math.round(u(n,t)/Uo)*Uo,y:Math.round(o(n,t)/Uo)*Uo,i:t}})}var r=Ce,i=ze,u=r,o=i,a=sl;return n?t(n):(t.links=function(n){return ar(e(n)).edges.filter(function(n){return n.l&&n.r}).map(function(t){return{source:n[t.l.i],target:n[t.r.i]}})},t.triangles=function(n){var t=[];return ar(e(n)).cells.forEach(function(e,r){for(var i,u,o=e.site,a=e.edges.sort(Ve),l=-1,c=a.length,f=a[c-1].edge,s=f.l===o?f.r:f.l;++l=c,h=r>=f,p=h<<1|s;n.leaf=!1,n=n.nodes[p]||(n.nodes[p]=hr()),s?i=c:a=c,h?o=f:l=f,u(n,t,e,r,i,o,a,l)}var f,s,h,p,g,v,d,y,m,M=En(a),x=En(l);if(null!=t)v=t,d=e,y=r,m=i;else if(y=m=-(v=d=1/0),s=[],h=[],g=n.length,o)for(p=0;g>p;++p)f=n[p],f.xy&&(y=f.x),f.y>m&&(m=f.y),s.push(f.x),h.push(f.y);else for(p=0;g>p;++p){var b=+M(f=n[p],p),_=+x(f,p);v>b&&(v=b),d>_&&(d=_),b>y&&(y=b),_>m&&(m=_),s.push(b),h.push(_)}var w=y-v,S=m-d;w>S?m=d+w:y=v+S;var k=hr();if(k.add=function(n){u(k,n,+M(n,++p),+x(n,p),v,d,y,m)},k.visit=function(n){pr(n,k,v,d,y,m)},k.find=function(n){return gr(k,n[0],n[1],v,d,y,m)},p=-1,null==t){for(;++p=0?n.slice(0,t):n,r=t>=0?n.slice(t+1):"in";return e=vl.get(e)||gl,r=dl.get(r)||m,br(r(e.apply(null,lo.call(arguments,1))))},ao.interpolateHcl=Rr,ao.interpolateHsl=Dr,ao.interpolateLab=Pr,ao.interpolateRound=Ur,ao.transform=function(n){var t=fo.createElementNS(ao.ns.prefix.svg,"g");return(ao.transform=function(n){if(null!=n){t.setAttribute("transform",n);var e=t.transform.baseVal.consolidate()}return new jr(e?e.matrix:yl)})(n)},jr.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var yl={a:1,b:0,c:0,d:1,e:0,f:0};ao.interpolateTransform=$r,ao.layout={},ao.layout.bundle=function(){return function(n){for(var t=[],e=-1,r=n.length;++ea*a/y){if(v>l){var c=t.charge/l;n.px-=u*c,n.py-=o*c}return!0}if(t.point&&l&&v>l){var c=t.pointCharge/l;n.px-=u*c,n.py-=o*c}}return!t.charge}}function t(n){n.px=ao.event.x,n.py=ao.event.y,l.resume()}var e,r,i,u,o,a,l={},c=ao.dispatch("start","tick","end"),f=[1,1],s=.9,h=ml,p=Ml,g=-30,v=xl,d=.1,y=.64,M=[],x=[];return l.tick=function(){if((i*=.99)<.005)return e=null,c.end({type:"end",alpha:i=0}),!0;var t,r,l,h,p,v,y,m,b,_=M.length,w=x.length;for(r=0;w>r;++r)l=x[r],h=l.source,p=l.target,m=p.x-h.x,b=p.y-h.y,(v=m*m+b*b)&&(v=i*o[r]*((v=Math.sqrt(v))-u[r])/v,m*=v,b*=v,p.x-=m*(y=h.weight+p.weight?h.weight/(h.weight+p.weight):.5),p.y-=b*y,h.x+=m*(y=1-y),h.y+=b*y);if((y=i*d)&&(m=f[0]/2,b=f[1]/2,r=-1,y))for(;++r<_;)l=M[r],l.x+=(m-l.x)*y,l.y+=(b-l.y)*y;if(g)for(ri(t=ao.geom.quadtree(M),i,a),r=-1;++r<_;)(l=M[r]).fixed||t.visit(n(l));for(r=-1;++r<_;)l=M[r],l.fixed?(l.x=l.px,l.y=l.py):(l.x-=(l.px-(l.px=l.x))*s,l.y-=(l.py-(l.py=l.y))*s);c.tick({type:"tick",alpha:i})},l.nodes=function(n){return arguments.length?(M=n,l):M},l.links=function(n){return arguments.length?(x=n,l):x},l.size=function(n){return arguments.length?(f=n,l):f},l.linkDistance=function(n){return arguments.length?(h="function"==typeof n?n:+n,l):h},l.distance=l.linkDistance,l.linkStrength=function(n){return arguments.length?(p="function"==typeof n?n:+n,l):p},l.friction=function(n){return arguments.length?(s=+n,l):s},l.charge=function(n){return arguments.length?(g="function"==typeof n?n:+n,l):g},l.chargeDistance=function(n){return arguments.length?(v=n*n,l):Math.sqrt(v)},l.gravity=function(n){return arguments.length?(d=+n,l):d},l.theta=function(n){return arguments.length?(y=n*n,l):Math.sqrt(y)},l.alpha=function(n){return arguments.length?(n=+n,i?n>0?i=n:(e.c=null,e.t=NaN,e=null,c.end({type:"end",alpha:i=0})):n>0&&(c.start({type:"start",alpha:i=n}),e=qn(l.tick)),l):i},l.start=function(){function n(n,r){if(!e){for(e=new Array(i),l=0;i>l;++l)e[l]=[];for(l=0;c>l;++l){var u=x[l];e[u.source.index].push(u.target),e[u.target.index].push(u.source)}}for(var o,a=e[t],l=-1,f=a.length;++lt;++t)(r=M[t]).index=t,r.weight=0;for(t=0;c>t;++t)r=x[t],"number"==typeof r.source&&(r.source=M[r.source]),"number"==typeof r.target&&(r.target=M[r.target]),++r.source.weight,++r.target.weight;for(t=0;i>t;++t)r=M[t],isNaN(r.x)&&(r.x=n("x",s)),isNaN(r.y)&&(r.y=n("y",v)),isNaN(r.px)&&(r.px=r.x),isNaN(r.py)&&(r.py=r.y);if(u=[],"function"==typeof h)for(t=0;c>t;++t)u[t]=+h.call(this,x[t],t);else for(t=0;c>t;++t)u[t]=h;if(o=[],"function"==typeof p)for(t=0;c>t;++t)o[t]=+p.call(this,x[t],t);else for(t=0;c>t;++t)o[t]=p;if(a=[],"function"==typeof g)for(t=0;i>t;++t)a[t]=+g.call(this,M[t],t);else for(t=0;i>t;++t)a[t]=g;return l.resume()},l.resume=function(){return l.alpha(.1)},l.stop=function(){return l.alpha(0)},l.drag=function(){return r||(r=ao.behavior.drag().origin(m).on("dragstart.force",Qr).on("drag.force",t).on("dragend.force",ni)),arguments.length?void this.on("mouseover.force",ti).on("mouseout.force",ei).call(r):r},ao.rebind(l,c,"on")};var ml=20,Ml=1,xl=1/0;ao.layout.hierarchy=function(){function n(i){var u,o=[i],a=[];for(i.depth=0;null!=(u=o.pop());)if(a.push(u),(c=e.call(n,u,u.depth))&&(l=c.length)){for(var l,c,f;--l>=0;)o.push(f=c[l]),f.parent=u,f.depth=u.depth+1;r&&(u.value=0),u.children=c}else r&&(u.value=+r.call(n,u,u.depth)||0),delete u.children;return oi(i,function(n){var e,i;t&&(e=n.children)&&e.sort(t),r&&(i=n.parent)&&(i.value+=n.value)}),a}var t=ci,e=ai,r=li;return n.sort=function(e){return arguments.length?(t=e,n):t},n.children=function(t){return arguments.length?(e=t,n):e},n.value=function(t){return arguments.length?(r=t,n):r},n.revalue=function(t){return r&&(ui(t,function(n){n.children&&(n.value=0)}),oi(t,function(t){var e;t.children||(t.value=+r.call(n,t,t.depth)||0),(e=t.parent)&&(e.value+=t.value)})),t},n},ao.layout.partition=function(){function n(t,e,r,i){var u=t.children;if(t.x=e,t.y=t.depth*i,t.dx=r,t.dy=i,u&&(o=u.length)){var o,a,l,c=-1;for(r=t.value?r/t.value:0;++cs?-1:1),g=ao.sum(c),v=g?(s-l*p)/g:0,d=ao.range(l),y=[];return null!=e&&d.sort(e===bl?function(n,t){return c[t]-c[n]}:function(n,t){return e(o[n],o[t])}),d.forEach(function(n){y[n]={data:o[n],value:a=c[n],startAngle:f,endAngle:f+=a*v+p,padAngle:h}}),y}var t=Number,e=bl,r=0,i=Ho,u=0;return n.value=function(e){return arguments.length?(t=e,n):t},n.sort=function(t){return arguments.length?(e=t,n):e},n.startAngle=function(t){return arguments.length?(r=t,n):r},n.endAngle=function(t){return arguments.length?(i=t,n):i},n.padAngle=function(t){return arguments.length?(u=t,n):u},n};var bl={};ao.layout.stack=function(){function n(a,l){if(!(h=a.length))return a;var c=a.map(function(e,r){return t.call(n,e,r)}),f=c.map(function(t){return t.map(function(t,e){return[u.call(n,t,e),o.call(n,t,e)]})}),s=e.call(n,f,l);c=ao.permute(c,s),f=ao.permute(f,s);var h,p,g,v,d=r.call(n,f,l),y=c[0].length;for(g=0;y>g;++g)for(i.call(n,c[0][g],v=d[g],f[0][g][1]),p=1;h>p;++p)i.call(n,c[p][g],v+=f[p-1][g][1],f[p][g][1]);return a}var t=m,e=gi,r=vi,i=pi,u=si,o=hi;return n.values=function(e){return arguments.length?(t=e,n):t},n.order=function(t){return arguments.length?(e="function"==typeof t?t:_l.get(t)||gi,n):e},n.offset=function(t){return arguments.length?(r="function"==typeof t?t:wl.get(t)||vi,n):r},n.x=function(t){return arguments.length?(u=t,n):u},n.y=function(t){return arguments.length?(o=t,n):o},n.out=function(t){return arguments.length?(i=t,n):i},n};var _l=ao.map({"inside-out":function(n){var t,e,r=n.length,i=n.map(di),u=n.map(yi),o=ao.range(r).sort(function(n,t){return i[n]-i[t]}),a=0,l=0,c=[],f=[];for(t=0;r>t;++t)e=o[t],l>a?(a+=u[e],c.push(e)):(l+=u[e],f.push(e));return f.reverse().concat(c)},reverse:function(n){return ao.range(n.length).reverse()},"default":gi}),wl=ao.map({silhouette:function(n){var t,e,r,i=n.length,u=n[0].length,o=[],a=0,l=[];for(e=0;u>e;++e){for(t=0,r=0;i>t;t++)r+=n[t][e][1];r>a&&(a=r),o.push(r)}for(e=0;u>e;++e)l[e]=(a-o[e])/2;return l},wiggle:function(n){var t,e,r,i,u,o,a,l,c,f=n.length,s=n[0],h=s.length,p=[];for(p[0]=l=c=0,e=1;h>e;++e){for(t=0,i=0;f>t;++t)i+=n[t][e][1];for(t=0,u=0,a=s[e][0]-s[e-1][0];f>t;++t){for(r=0,o=(n[t][e][1]-n[t][e-1][1])/(2*a);t>r;++r)o+=(n[r][e][1]-n[r][e-1][1])/a;u+=o*n[t][e][1]}p[e]=l-=i?u/i*a:0,c>l&&(c=l)}for(e=0;h>e;++e)p[e]-=c;return p},expand:function(n){var t,e,r,i=n.length,u=n[0].length,o=1/i,a=[];for(e=0;u>e;++e){for(t=0,r=0;i>t;t++)r+=n[t][e][1];if(r)for(t=0;i>t;t++)n[t][e][1]/=r;else for(t=0;i>t;t++)n[t][e][1]=o}for(e=0;u>e;++e)a[e]=0;return a},zero:vi});ao.layout.histogram=function(){function n(n,u){for(var o,a,l=[],c=n.map(e,this),f=r.call(this,c,u),s=i.call(this,f,c,u),u=-1,h=c.length,p=s.length-1,g=t?1:1/h;++u0)for(u=-1;++u=f[0]&&a<=f[1]&&(o=l[ao.bisect(s,a,1,p)-1],o.y+=g,o.push(n[u]));return l}var t=!0,e=Number,r=bi,i=Mi;return n.value=function(t){return arguments.length?(e=t,n):e},n.range=function(t){return arguments.length?(r=En(t),n):r},n.bins=function(t){return arguments.length?(i="number"==typeof t?function(n){return xi(n,t)}:En(t),n):i},n.frequency=function(e){return arguments.length?(t=!!e,n):t},n},ao.layout.pack=function(){function n(n,u){var o=e.call(this,n,u),a=o[0],l=i[0],c=i[1],f=null==t?Math.sqrt:"function"==typeof t?t:function(){return t};if(a.x=a.y=0,oi(a,function(n){n.r=+f(n.value)}),oi(a,Ni),r){var s=r*(t?1:Math.max(2*a.r/l,2*a.r/c))/2;oi(a,function(n){n.r+=s}),oi(a,Ni),oi(a,function(n){n.r-=s})}return Ci(a,l/2,c/2,t?1:1/Math.max(2*a.r/l,2*a.r/c)),o}var t,e=ao.layout.hierarchy().sort(_i),r=0,i=[1,1];return n.size=function(t){return arguments.length?(i=t,n):i},n.radius=function(e){return arguments.length?(t=null==e||"function"==typeof e?e:+e,n):t},n.padding=function(t){return arguments.length?(r=+t,n):r},ii(n,e)},ao.layout.tree=function(){function n(n,i){var f=o.call(this,n,i),s=f[0],h=t(s);if(oi(h,e),h.parent.m=-h.z,ui(h,r),c)ui(s,u);else{var p=s,g=s,v=s;ui(s,function(n){n.xg.x&&(g=n),n.depth>v.depth&&(v=n)});var d=a(p,g)/2-p.x,y=l[0]/(g.x+a(g,p)/2+d),m=l[1]/(v.depth||1);ui(s,function(n){n.x=(n.x+d)*y,n.y=n.depth*m})}return f}function t(n){for(var t,e={A:null,children:[n]},r=[e];null!=(t=r.pop());)for(var i,u=t.children,o=0,a=u.length;a>o;++o)r.push((u[o]=i={_:u[o],parent:t,children:(i=u[o].children)&&i.slice()||[],A:null,a:null,z:0,m:0,c:0,s:0,t:null,i:o}).a=i);return e.children[0]}function e(n){var t=n.children,e=n.parent.children,r=n.i?e[n.i-1]:null;if(t.length){Di(n);var u=(t[0].z+t[t.length-1].z)/2;r?(n.z=r.z+a(n._,r._),n.m=n.z-u):n.z=u}else r&&(n.z=r.z+a(n._,r._));n.parent.A=i(n,r,n.parent.A||e[0])}function r(n){n._.x=n.z+n.parent.m,n.m+=n.parent.m}function i(n,t,e){if(t){for(var r,i=n,u=n,o=t,l=i.parent.children[0],c=i.m,f=u.m,s=o.m,h=l.m;o=Ti(o),i=qi(i),o&&i;)l=qi(l),u=Ti(u),u.a=n,r=o.z+s-i.z-c+a(o._,i._),r>0&&(Ri(Pi(o,n,e),n,r),c+=r,f+=r),s+=o.m,c+=i.m,h+=l.m,f+=u.m;o&&!Ti(u)&&(u.t=o,u.m+=s-f),i&&!qi(l)&&(l.t=i,l.m+=c-h,e=n)}return e}function u(n){n.x*=l[0],n.y=n.depth*l[1]}var o=ao.layout.hierarchy().sort(null).value(null),a=Li,l=[1,1],c=null;return n.separation=function(t){return arguments.length?(a=t,n):a},n.size=function(t){return arguments.length?(c=null==(l=t)?u:null,n):c?null:l},n.nodeSize=function(t){return arguments.length?(c=null==(l=t)?null:u,n):c?l:null},ii(n,o)},ao.layout.cluster=function(){function n(n,u){var o,a=t.call(this,n,u),l=a[0],c=0;oi(l,function(n){var t=n.children;t&&t.length?(n.x=ji(t),n.y=Ui(t)):(n.x=o?c+=e(n,o):0,n.y=0,o=n)});var f=Fi(l),s=Hi(l),h=f.x-e(f,s)/2,p=s.x+e(s,f)/2;return oi(l,i?function(n){n.x=(n.x-l.x)*r[0],n.y=(l.y-n.y)*r[1]}:function(n){n.x=(n.x-h)/(p-h)*r[0],n.y=(1-(l.y?n.y/l.y:1))*r[1]}),a}var t=ao.layout.hierarchy().sort(null).value(null),e=Li,r=[1,1],i=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(i=null==(r=t),n):i?null:r},n.nodeSize=function(t){return arguments.length?(i=null!=(r=t),n):i?r:null},ii(n,t)},ao.layout.treemap=function(){function n(n,t){for(var e,r,i=-1,u=n.length;++it?0:t),e.area=isNaN(r)||0>=r?0:r}function t(e){var u=e.children;if(u&&u.length){var o,a,l,c=s(e),f=[],h=u.slice(),g=1/0,v="slice"===p?c.dx:"dice"===p?c.dy:"slice-dice"===p?1&e.depth?c.dy:c.dx:Math.min(c.dx,c.dy);for(n(h,c.dx*c.dy/e.value),f.area=0;(l=h.length)>0;)f.push(o=h[l-1]),f.area+=o.area,"squarify"!==p||(a=r(f,v))<=g?(h.pop(),g=a):(f.area-=f.pop().area,i(f,v,c,!1),v=Math.min(c.dx,c.dy),f.length=f.area=0,g=1/0);f.length&&(i(f,v,c,!0),f.length=f.area=0),u.forEach(t)}}function e(t){var r=t.children;if(r&&r.length){var u,o=s(t),a=r.slice(),l=[];for(n(a,o.dx*o.dy/t.value),l.area=0;u=a.pop();)l.push(u),l.area+=u.area,null!=u.z&&(i(l,u.z?o.dx:o.dy,o,!a.length),l.length=l.area=0);r.forEach(e)}}function r(n,t){for(var e,r=n.area,i=0,u=1/0,o=-1,a=n.length;++oe&&(u=e),e>i&&(i=e));return r*=r,t*=t,r?Math.max(t*i*g/r,r/(t*u*g)):1/0}function i(n,t,e,r){var i,u=-1,o=n.length,a=e.x,c=e.y,f=t?l(n.area/t):0; +if(t==e.dx){for((r||f>e.dy)&&(f=e.dy);++ue.dx)&&(f=e.dx);++ue&&(t=1),1>e&&(n=0),function(){var e,r,i;do e=2*Math.random()-1,r=2*Math.random()-1,i=e*e+r*r;while(!i||i>1);return n+t*e*Math.sqrt(-2*Math.log(i)/i)}},logNormal:function(){var n=ao.random.normal.apply(ao,arguments);return function(){return Math.exp(n())}},bates:function(n){var t=ao.random.irwinHall(n);return function(){return t()/n}},irwinHall:function(n){return function(){for(var t=0,e=0;n>e;e++)t+=Math.random();return t}}},ao.scale={};var Sl={floor:m,ceil:m};ao.scale.linear=function(){return Wi([0,1],[0,1],Mr,!1)};var kl={s:1,g:1,p:1,r:1,e:1};ao.scale.log=function(){return ru(ao.scale.linear().domain([0,1]),10,!0,[1,10])};var Nl=ao.format(".0e"),El={floor:function(n){return-Math.ceil(-n)},ceil:function(n){return-Math.floor(-n)}};ao.scale.pow=function(){return iu(ao.scale.linear(),1,[0,1])},ao.scale.sqrt=function(){return ao.scale.pow().exponent(.5)},ao.scale.ordinal=function(){return ou([],{t:"range",a:[[]]})},ao.scale.category10=function(){return ao.scale.ordinal().range(Al)},ao.scale.category20=function(){return ao.scale.ordinal().range(Cl)},ao.scale.category20b=function(){return ao.scale.ordinal().range(zl)},ao.scale.category20c=function(){return ao.scale.ordinal().range(Ll)};var Al=[2062260,16744206,2924588,14034728,9725885,9197131,14907330,8355711,12369186,1556175].map(xn),Cl=[2062260,11454440,16744206,16759672,2924588,10018698,14034728,16750742,9725885,12955861,9197131,12885140,14907330,16234194,8355711,13092807,12369186,14408589,1556175,10410725].map(xn),zl=[3750777,5395619,7040719,10264286,6519097,9216594,11915115,13556636,9202993,12426809,15186514,15190932,8666169,11356490,14049643,15177372,8077683,10834324,13528509,14589654].map(xn),Ll=[3244733,7057110,10406625,13032431,15095053,16616764,16625259,16634018,3253076,7652470,10607003,13101504,7695281,10394312,12369372,14342891,6513507,9868950,12434877,14277081].map(xn);ao.scale.quantile=function(){return au([],[])},ao.scale.quantize=function(){return lu(0,1,[0,1])},ao.scale.threshold=function(){return cu([.5],[0,1])},ao.scale.identity=function(){return fu([0,1])},ao.svg={},ao.svg.arc=function(){function n(){var n=Math.max(0,+e.apply(this,arguments)),c=Math.max(0,+r.apply(this,arguments)),f=o.apply(this,arguments)-Io,s=a.apply(this,arguments)-Io,h=Math.abs(s-f),p=f>s?0:1;if(n>c&&(g=c,c=n,n=g),h>=Oo)return t(c,p)+(n?t(n,1-p):"")+"Z";var g,v,d,y,m,M,x,b,_,w,S,k,N=0,E=0,A=[];if((y=(+l.apply(this,arguments)||0)/2)&&(d=u===ql?Math.sqrt(n*n+c*c):+u.apply(this,arguments),p||(E*=-1),c&&(E=tn(d/c*Math.sin(y))),n&&(N=tn(d/n*Math.sin(y)))),c){m=c*Math.cos(f+E),M=c*Math.sin(f+E),x=c*Math.cos(s-E),b=c*Math.sin(s-E);var C=Math.abs(s-f-2*E)<=Fo?0:1;if(E&&yu(m,M,x,b)===p^C){var z=(f+s)/2;m=c*Math.cos(z),M=c*Math.sin(z),x=b=null}}else m=M=0;if(n){_=n*Math.cos(s-N),w=n*Math.sin(s-N),S=n*Math.cos(f+N),k=n*Math.sin(f+N);var L=Math.abs(f-s+2*N)<=Fo?0:1;if(N&&yu(_,w,S,k)===1-p^L){var q=(f+s)/2;_=n*Math.cos(q),w=n*Math.sin(q),S=k=null}}else _=w=0;if(h>Uo&&(g=Math.min(Math.abs(c-n)/2,+i.apply(this,arguments)))>.001){v=c>n^p?0:1;var T=g,R=g;if(Fo>h){var D=null==S?[_,w]:null==x?[m,M]:Re([m,M],[S,k],[x,b],[_,w]),P=m-D[0],U=M-D[1],j=x-D[0],F=b-D[1],H=1/Math.sin(Math.acos((P*j+U*F)/(Math.sqrt(P*P+U*U)*Math.sqrt(j*j+F*F)))/2),O=Math.sqrt(D[0]*D[0]+D[1]*D[1]);R=Math.min(g,(n-O)/(H-1)),T=Math.min(g,(c-O)/(H+1))}if(null!=x){var I=mu(null==S?[_,w]:[S,k],[m,M],c,T,p),Y=mu([x,b],[_,w],c,T,p);g===T?A.push("M",I[0],"A",T,",",T," 0 0,",v," ",I[1],"A",c,",",c," 0 ",1-p^yu(I[1][0],I[1][1],Y[1][0],Y[1][1]),",",p," ",Y[1],"A",T,",",T," 0 0,",v," ",Y[0]):A.push("M",I[0],"A",T,",",T," 0 1,",v," ",Y[0])}else A.push("M",m,",",M);if(null!=S){var Z=mu([m,M],[S,k],n,-R,p),V=mu([_,w],null==x?[m,M]:[x,b],n,-R,p);g===R?A.push("L",V[0],"A",R,",",R," 0 0,",v," ",V[1],"A",n,",",n," 0 ",p^yu(V[1][0],V[1][1],Z[1][0],Z[1][1]),",",1-p," ",Z[1],"A",R,",",R," 0 0,",v," ",Z[0]):A.push("L",V[0],"A",R,",",R," 0 0,",v," ",Z[0])}else A.push("L",_,",",w)}else A.push("M",m,",",M),null!=x&&A.push("A",c,",",c," 0 ",C,",",p," ",x,",",b),A.push("L",_,",",w),null!=S&&A.push("A",n,",",n," 0 ",L,",",1-p," ",S,",",k);return A.push("Z"),A.join("")}function t(n,t){return"M0,"+n+"A"+n+","+n+" 0 1,"+t+" 0,"+-n+"A"+n+","+n+" 0 1,"+t+" 0,"+n}var e=hu,r=pu,i=su,u=ql,o=gu,a=vu,l=du;return n.innerRadius=function(t){return arguments.length?(e=En(t),n):e},n.outerRadius=function(t){return arguments.length?(r=En(t),n):r},n.cornerRadius=function(t){return arguments.length?(i=En(t),n):i},n.padRadius=function(t){return arguments.length?(u=t==ql?ql:En(t),n):u},n.startAngle=function(t){return arguments.length?(o=En(t),n):o},n.endAngle=function(t){return arguments.length?(a=En(t),n):a},n.padAngle=function(t){return arguments.length?(l=En(t),n):l},n.centroid=function(){var n=(+e.apply(this,arguments)+ +r.apply(this,arguments))/2,t=(+o.apply(this,arguments)+ +a.apply(this,arguments))/2-Io;return[Math.cos(t)*n,Math.sin(t)*n]},n};var ql="auto";ao.svg.line=function(){return Mu(m)};var Tl=ao.map({linear:xu,"linear-closed":bu,step:_u,"step-before":wu,"step-after":Su,basis:zu,"basis-open":Lu,"basis-closed":qu,bundle:Tu,cardinal:Eu,"cardinal-open":ku,"cardinal-closed":Nu,monotone:Fu});Tl.forEach(function(n,t){t.key=n,t.closed=/-closed$/.test(n)});var Rl=[0,2/3,1/3,0],Dl=[0,1/3,2/3,0],Pl=[0,1/6,2/3,1/6];ao.svg.line.radial=function(){var n=Mu(Hu);return n.radius=n.x,delete n.x,n.angle=n.y,delete n.y,n},wu.reverse=Su,Su.reverse=wu,ao.svg.area=function(){return Ou(m)},ao.svg.area.radial=function(){var n=Ou(Hu);return n.radius=n.x,delete n.x,n.innerRadius=n.x0,delete n.x0,n.outerRadius=n.x1,delete n.x1,n.angle=n.y,delete n.y,n.startAngle=n.y0,delete n.y0,n.endAngle=n.y1,delete n.y1,n},ao.svg.chord=function(){function n(n,a){var l=t(this,u,n,a),c=t(this,o,n,a);return"M"+l.p0+r(l.r,l.p1,l.a1-l.a0)+(e(l,c)?i(l.r,l.p1,l.r,l.p0):i(l.r,l.p1,c.r,c.p0)+r(c.r,c.p1,c.a1-c.a0)+i(c.r,c.p1,l.r,l.p0))+"Z"}function t(n,t,e,r){var i=t.call(n,e,r),u=a.call(n,i,r),o=l.call(n,i,r)-Io,f=c.call(n,i,r)-Io;return{r:u,a0:o,a1:f,p0:[u*Math.cos(o),u*Math.sin(o)],p1:[u*Math.cos(f),u*Math.sin(f)]}}function e(n,t){return n.a0==t.a0&&n.a1==t.a1}function r(n,t,e){return"A"+n+","+n+" 0 "+ +(e>Fo)+",1 "+t}function i(n,t,e,r){return"Q 0,0 "+r}var u=Me,o=xe,a=Iu,l=gu,c=vu;return n.radius=function(t){return arguments.length?(a=En(t),n):a},n.source=function(t){return arguments.length?(u=En(t),n):u},n.target=function(t){return arguments.length?(o=En(t),n):o},n.startAngle=function(t){return arguments.length?(l=En(t),n):l},n.endAngle=function(t){return arguments.length?(c=En(t),n):c},n},ao.svg.diagonal=function(){function n(n,i){var u=t.call(this,n,i),o=e.call(this,n,i),a=(u.y+o.y)/2,l=[u,{x:u.x,y:a},{x:o.x,y:a},o];return l=l.map(r),"M"+l[0]+"C"+l[1]+" "+l[2]+" "+l[3]}var t=Me,e=xe,r=Yu;return n.source=function(e){return arguments.length?(t=En(e),n):t},n.target=function(t){return arguments.length?(e=En(t),n):e},n.projection=function(t){return arguments.length?(r=t,n):r},n},ao.svg.diagonal.radial=function(){var n=ao.svg.diagonal(),t=Yu,e=n.projection;return n.projection=function(n){return arguments.length?e(Zu(t=n)):t},n},ao.svg.symbol=function(){function n(n,r){return(Ul.get(t.call(this,n,r))||$u)(e.call(this,n,r))}var t=Xu,e=Vu;return n.type=function(e){return arguments.length?(t=En(e),n):t},n.size=function(t){return arguments.length?(e=En(t),n):e},n};var Ul=ao.map({circle:$u,cross:function(n){var t=Math.sqrt(n/5)/2;return"M"+-3*t+","+-t+"H"+-t+"V"+-3*t+"H"+t+"V"+-t+"H"+3*t+"V"+t+"H"+t+"V"+3*t+"H"+-t+"V"+t+"H"+-3*t+"Z"},diamond:function(n){var t=Math.sqrt(n/(2*Fl)),e=t*Fl;return"M0,"+-t+"L"+e+",0 0,"+t+" "+-e+",0Z"},square:function(n){var t=Math.sqrt(n)/2;return"M"+-t+","+-t+"L"+t+","+-t+" "+t+","+t+" "+-t+","+t+"Z"},"triangle-down":function(n){var t=Math.sqrt(n/jl),e=t*jl/2;return"M0,"+e+"L"+t+","+-e+" "+-t+","+-e+"Z"},"triangle-up":function(n){var t=Math.sqrt(n/jl),e=t*jl/2;return"M0,"+-e+"L"+t+","+e+" "+-t+","+e+"Z"}});ao.svg.symbolTypes=Ul.keys();var jl=Math.sqrt(3),Fl=Math.tan(30*Yo);Co.transition=function(n){for(var t,e,r=Hl||++Zl,i=Ku(n),u=[],o=Ol||{time:Date.now(),ease:Nr,delay:0,duration:250},a=-1,l=this.length;++au;u++){i.push(t=[]);for(var e=this[u],a=0,l=e.length;l>a;a++)(r=e[a])&&n.call(r,r.__data__,a,u)&&t.push(r)}return Wu(i,this.namespace,this.id)},Yl.tween=function(n,t){var e=this.id,r=this.namespace;return arguments.length<2?this.node()[r][e].tween.get(n):Y(this,null==t?function(t){t[r][e].tween.remove(n)}:function(i){i[r][e].tween.set(n,t)})},Yl.attr=function(n,t){function e(){this.removeAttribute(a)}function r(){this.removeAttributeNS(a.space,a.local)}function i(n){return null==n?e:(n+="",function(){var t,e=this.getAttribute(a);return e!==n&&(t=o(e,n),function(n){this.setAttribute(a,t(n))})})}function u(n){return null==n?r:(n+="",function(){var t,e=this.getAttributeNS(a.space,a.local);return e!==n&&(t=o(e,n),function(n){this.setAttributeNS(a.space,a.local,t(n))})})}if(arguments.length<2){for(t in n)this.attr(t,n[t]);return this}var o="transform"==n?$r:Mr,a=ao.ns.qualify(n);return Ju(this,"attr."+n,t,a.local?u:i)},Yl.attrTween=function(n,t){function e(n,e){var r=t.call(this,n,e,this.getAttribute(i));return r&&function(n){this.setAttribute(i,r(n))}}function r(n,e){var r=t.call(this,n,e,this.getAttributeNS(i.space,i.local));return r&&function(n){this.setAttributeNS(i.space,i.local,r(n))}}var i=ao.ns.qualify(n);return this.tween("attr."+n,i.local?r:e)},Yl.style=function(n,e,r){function i(){this.style.removeProperty(n)}function u(e){return null==e?i:(e+="",function(){var i,u=t(this).getComputedStyle(this,null).getPropertyValue(n);return u!==e&&(i=Mr(u,e),function(t){this.style.setProperty(n,i(t),r)})})}var o=arguments.length;if(3>o){if("string"!=typeof n){2>o&&(e="");for(r in n)this.style(r,n[r],e);return this}r=""}return Ju(this,"style."+n,e,u)},Yl.styleTween=function(n,e,r){function i(i,u){var o=e.call(this,i,u,t(this).getComputedStyle(this,null).getPropertyValue(n));return o&&function(t){this.style.setProperty(n,o(t),r)}}return arguments.length<3&&(r=""),this.tween("style."+n,i)},Yl.text=function(n){return Ju(this,"text",n,Gu)},Yl.remove=function(){var n=this.namespace;return this.each("end.transition",function(){var t;this[n].count<2&&(t=this.parentNode)&&t.removeChild(this)})},Yl.ease=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].ease:("function"!=typeof n&&(n=ao.ease.apply(ao,arguments)),Y(this,function(r){r[e][t].ease=n}))},Yl.delay=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].delay:Y(this,"function"==typeof n?function(r,i,u){r[e][t].delay=+n.call(r,r.__data__,i,u)}:(n=+n,function(r){r[e][t].delay=n}))},Yl.duration=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].duration:Y(this,"function"==typeof n?function(r,i,u){r[e][t].duration=Math.max(1,n.call(r,r.__data__,i,u))}:(n=Math.max(1,n),function(r){r[e][t].duration=n}))},Yl.each=function(n,t){var e=this.id,r=this.namespace;if(arguments.length<2){var i=Ol,u=Hl;try{Hl=e,Y(this,function(t,i,u){Ol=t[r][e],n.call(t,t.__data__,i,u)})}finally{Ol=i,Hl=u}}else Y(this,function(i){var u=i[r][e];(u.event||(u.event=ao.dispatch("start","end","interrupt"))).on(n,t)});return this},Yl.transition=function(){for(var n,t,e,r,i=this.id,u=++Zl,o=this.namespace,a=[],l=0,c=this.length;c>l;l++){a.push(n=[]);for(var t=this[l],f=0,s=t.length;s>f;f++)(e=t[f])&&(r=e[o][i],Qu(e,f,o,u,{time:r.time,ease:r.ease,delay:r.delay+r.duration,duration:r.duration})),n.push(e)}return Wu(a,o,u)},ao.svg.axis=function(){function n(n){n.each(function(){var n,c=ao.select(this),f=this.__chart__||e,s=this.__chart__=e.copy(),h=null==l?s.ticks?s.ticks.apply(s,a):s.domain():l,p=null==t?s.tickFormat?s.tickFormat.apply(s,a):m:t,g=c.selectAll(".tick").data(h,s),v=g.enter().insert("g",".domain").attr("class","tick").style("opacity",Uo),d=ao.transition(g.exit()).style("opacity",Uo).remove(),y=ao.transition(g.order()).style("opacity",1),M=Math.max(i,0)+o,x=Zi(s),b=c.selectAll(".domain").data([0]),_=(b.enter().append("path").attr("class","domain"),ao.transition(b));v.append("line"),v.append("text");var w,S,k,N,E=v.select("line"),A=y.select("line"),C=g.select("text").text(p),z=v.select("text"),L=y.select("text"),q="top"===r||"left"===r?-1:1;if("bottom"===r||"top"===r?(n=no,w="x",k="y",S="x2",N="y2",C.attr("dy",0>q?"0em":".71em").style("text-anchor","middle"),_.attr("d","M"+x[0]+","+q*u+"V0H"+x[1]+"V"+q*u)):(n=to,w="y",k="x",S="y2",N="x2",C.attr("dy",".32em").style("text-anchor",0>q?"end":"start"),_.attr("d","M"+q*u+","+x[0]+"H0V"+x[1]+"H"+q*u)),E.attr(N,q*i),z.attr(k,q*M),A.attr(S,0).attr(N,q*i),L.attr(w,0).attr(k,q*M),s.rangeBand){var T=s,R=T.rangeBand()/2;f=s=function(n){return T(n)+R}}else f.rangeBand?f=s:d.call(n,s,f);v.call(n,f,s),y.call(n,s,s)})}var t,e=ao.scale.linear(),r=Vl,i=6,u=6,o=3,a=[10],l=null;return n.scale=function(t){return arguments.length?(e=t,n):e},n.orient=function(t){return arguments.length?(r=t in Xl?t+"":Vl,n):r},n.ticks=function(){return arguments.length?(a=co(arguments),n):a},n.tickValues=function(t){return arguments.length?(l=t,n):l},n.tickFormat=function(e){return arguments.length?(t=e,n):t},n.tickSize=function(t){var e=arguments.length;return e?(i=+t,u=+arguments[e-1],n):i},n.innerTickSize=function(t){return arguments.length?(i=+t,n):i},n.outerTickSize=function(t){return arguments.length?(u=+t,n):u},n.tickPadding=function(t){return arguments.length?(o=+t,n):o},n.tickSubdivide=function(){return arguments.length&&n},n};var Vl="bottom",Xl={top:1,right:1,bottom:1,left:1};ao.svg.brush=function(){function n(t){t.each(function(){var t=ao.select(this).style("pointer-events","all").style("-webkit-tap-highlight-color","rgba(0,0,0,0)").on("mousedown.brush",u).on("touchstart.brush",u),o=t.selectAll(".background").data([0]);o.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),t.selectAll(".extent").data([0]).enter().append("rect").attr("class","extent").style("cursor","move");var a=t.selectAll(".resize").data(v,m);a.exit().remove(),a.enter().append("g").attr("class",function(n){return"resize "+n}).style("cursor",function(n){return $l[n]}).append("rect").attr("x",function(n){return/[ew]$/.test(n)?-3:null}).attr("y",function(n){return/^[ns]/.test(n)?-3:null}).attr("width",6).attr("height",6).style("visibility","hidden"),a.style("display",n.empty()?"none":null);var l,s=ao.transition(t),h=ao.transition(o);c&&(l=Zi(c),h.attr("x",l[0]).attr("width",l[1]-l[0]),r(s)),f&&(l=Zi(f),h.attr("y",l[0]).attr("height",l[1]-l[0]),i(s)),e(s)})}function e(n){n.selectAll(".resize").attr("transform",function(n){return"translate("+s[+/e$/.test(n)]+","+h[+/^s/.test(n)]+")"})}function r(n){n.select(".extent").attr("x",s[0]),n.selectAll(".extent,.n>rect,.s>rect").attr("width",s[1]-s[0])}function i(n){n.select(".extent").attr("y",h[0]),n.selectAll(".extent,.e>rect,.w>rect").attr("height",h[1]-h[0])}function u(){function u(){32==ao.event.keyCode&&(C||(M=null,L[0]-=s[1],L[1]-=h[1],C=2),S())}function v(){32==ao.event.keyCode&&2==C&&(L[0]+=s[1],L[1]+=h[1],C=0,S())}function d(){var n=ao.mouse(b),t=!1;x&&(n[0]+=x[0],n[1]+=x[1]),C||(ao.event.altKey?(M||(M=[(s[0]+s[1])/2,(h[0]+h[1])/2]),L[0]=s[+(n[0]f?(i=r,r=f):i=f),v[0]!=r||v[1]!=i?(e?a=null:o=null,v[0]=r,v[1]=i,!0):void 0}function m(){d(),k.style("pointer-events","all").selectAll(".resize").style("display",n.empty()?"none":null),ao.select("body").style("cursor",null),q.on("mousemove.brush",null).on("mouseup.brush",null).on("touchmove.brush",null).on("touchend.brush",null).on("keydown.brush",null).on("keyup.brush",null),z(),w({type:"brushend"})}var M,x,b=this,_=ao.select(ao.event.target),w=l.of(b,arguments),k=ao.select(b),N=_.datum(),E=!/^(n|s)$/.test(N)&&c,A=!/^(e|w)$/.test(N)&&f,C=_.classed("extent"),z=W(b),L=ao.mouse(b),q=ao.select(t(b)).on("keydown.brush",u).on("keyup.brush",v);if(ao.event.changedTouches?q.on("touchmove.brush",d).on("touchend.brush",m):q.on("mousemove.brush",d).on("mouseup.brush",m),k.interrupt().selectAll("*").interrupt(),C)L[0]=s[0]-L[0],L[1]=h[0]-L[1];else if(N){var T=+/w$/.test(N),R=+/^n/.test(N);x=[s[1-T]-L[0],h[1-R]-L[1]],L[0]=s[T],L[1]=h[R]}else ao.event.altKey&&(M=L.slice());k.style("pointer-events","none").selectAll(".resize").style("display",null),ao.select("body").style("cursor",_.style("cursor")),w({type:"brushstart"}),d()}var o,a,l=N(n,"brushstart","brush","brushend"),c=null,f=null,s=[0,0],h=[0,0],p=!0,g=!0,v=Bl[0];return n.event=function(n){n.each(function(){var n=l.of(this,arguments),t={x:s,y:h,i:o,j:a},e=this.__chart__||t;this.__chart__=t,Hl?ao.select(this).transition().each("start.brush",function(){o=e.i,a=e.j,s=e.x,h=e.y,n({type:"brushstart"})}).tween("brush:brush",function(){var e=xr(s,t.x),r=xr(h,t.y);return o=a=null,function(i){s=t.x=e(i),h=t.y=r(i),n({type:"brush",mode:"resize"})}}).each("end.brush",function(){o=t.i,a=t.j,n({type:"brush",mode:"resize"}),n({type:"brushend"})}):(n({type:"brushstart"}),n({type:"brush",mode:"resize"}),n({type:"brushend"}))})},n.x=function(t){return arguments.length?(c=t,v=Bl[!c<<1|!f],n):c},n.y=function(t){return arguments.length?(f=t,v=Bl[!c<<1|!f],n):f},n.clamp=function(t){return arguments.length?(c&&f?(p=!!t[0],g=!!t[1]):c?p=!!t:f&&(g=!!t),n):c&&f?[p,g]:c?p:f?g:null},n.extent=function(t){var e,r,i,u,l;return arguments.length?(c&&(e=t[0],r=t[1],f&&(e=e[0],r=r[0]),o=[e,r],c.invert&&(e=c(e),r=c(r)),e>r&&(l=e,e=r,r=l),e==s[0]&&r==s[1]||(s=[e,r])),f&&(i=t[0],u=t[1],c&&(i=i[1],u=u[1]),a=[i,u],f.invert&&(i=f(i),u=f(u)),i>u&&(l=i,i=u,u=l),i==h[0]&&u==h[1]||(h=[i,u])),n):(c&&(o?(e=o[0],r=o[1]):(e=s[0],r=s[1],c.invert&&(e=c.invert(e),r=c.invert(r)),e>r&&(l=e,e=r,r=l))),f&&(a?(i=a[0],u=a[1]):(i=h[0],u=h[1],f.invert&&(i=f.invert(i),u=f.invert(u)),i>u&&(l=i,i=u,u=l))),c&&f?[[e,i],[r,u]]:c?[e,r]:f&&[i,u])},n.clear=function(){return n.empty()||(s=[0,0],h=[0,0],o=a=null),n},n.empty=function(){return!!c&&s[0]==s[1]||!!f&&h[0]==h[1]},ao.rebind(n,l,"on")};var $l={n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},Bl=[["n","e","s","w","nw","ne","se","sw"],["e","w"],["n","s"],[]],Wl=ga.format=xa.timeFormat,Jl=Wl.utc,Gl=Jl("%Y-%m-%dT%H:%M:%S.%LZ");Wl.iso=Date.prototype.toISOString&&+new Date("2000-01-01T00:00:00.000Z")?eo:Gl,eo.parse=function(n){var t=new Date(n);return isNaN(t)?null:t},eo.toString=Gl.toString,ga.second=On(function(n){return new va(1e3*Math.floor(n/1e3))},function(n,t){n.setTime(n.getTime()+1e3*Math.floor(t))},function(n){return n.getSeconds()}),ga.seconds=ga.second.range,ga.seconds.utc=ga.second.utc.range,ga.minute=On(function(n){return new va(6e4*Math.floor(n/6e4))},function(n,t){n.setTime(n.getTime()+6e4*Math.floor(t))},function(n){return n.getMinutes()}),ga.minutes=ga.minute.range,ga.minutes.utc=ga.minute.utc.range,ga.hour=On(function(n){var t=n.getTimezoneOffset()/60;return new va(36e5*(Math.floor(n/36e5-t)+t))},function(n,t){n.setTime(n.getTime()+36e5*Math.floor(t))},function(n){return n.getHours()}),ga.hours=ga.hour.range,ga.hours.utc=ga.hour.utc.range,ga.month=On(function(n){return n=ga.day(n),n.setDate(1),n},function(n,t){n.setMonth(n.getMonth()+t)},function(n){return n.getMonth()}),ga.months=ga.month.range,ga.months.utc=ga.month.utc.range;var Kl=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],Ql=[[ga.second,1],[ga.second,5],[ga.second,15],[ga.second,30],[ga.minute,1],[ga.minute,5],[ga.minute,15],[ga.minute,30],[ga.hour,1],[ga.hour,3],[ga.hour,6],[ga.hour,12],[ga.day,1],[ga.day,2],[ga.week,1],[ga.month,1],[ga.month,3],[ga.year,1]],nc=Wl.multi([[".%L",function(n){return n.getMilliseconds()}],[":%S",function(n){return n.getSeconds()}],["%I:%M",function(n){return n.getMinutes()}],["%I %p",function(n){return n.getHours()}],["%a %d",function(n){return n.getDay()&&1!=n.getDate()}],["%b %d",function(n){return 1!=n.getDate()}],["%B",function(n){return n.getMonth()}],["%Y",zt]]),tc={range:function(n,t,e){return ao.range(Math.ceil(n/e)*e,+t,e).map(io)},floor:m,ceil:m};Ql.year=ga.year,ga.scale=function(){return ro(ao.scale.linear(),Ql,nc)};var ec=Ql.map(function(n){return[n[0].utc,n[1]]}),rc=Jl.multi([[".%L",function(n){return n.getUTCMilliseconds()}],[":%S",function(n){return n.getUTCSeconds()}],["%I:%M",function(n){return n.getUTCMinutes()}],["%I %p",function(n){return n.getUTCHours()}],["%a %d",function(n){return n.getUTCDay()&&1!=n.getUTCDate()}],["%b %d",function(n){return 1!=n.getUTCDate()}],["%B",function(n){return n.getUTCMonth()}],["%Y",zt]]);ec.year=ga.year.utc,ga.scale.utc=function(){return ro(ao.scale.linear(),ec,rc)},ao.text=An(function(n){return n.responseText}),ao.json=function(n,t){return Cn(n,"application/json",uo,t)},ao.html=function(n,t){return Cn(n,"text/html",oo,t)},ao.xml=An(function(n){return n.responseXML}),"function"==typeof define&&define.amd?(this.d3=ao,define(ao)):"object"==typeof module&&module.exports?module.exports=ao:this.d3=ao}(); \ No newline at end of file diff --git a/src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/holder.min.js b/src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/holder.min.js new file mode 100644 index 00000000..6bfc844b --- /dev/null +++ b/src/composer/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/holder.min.js @@ -0,0 +1,12 @@ +/*! + +Holder - client side image placeholders +Version 2.7.1+6hydf +© 2015 Ivan Malopinsky - http://imsky.co + +Site: http://holderjs.com +Issues: https://github.com/imsky/holder/issues +License: http://opensource.org/licenses/MIT + +*/ +!function(a){if(a.document){var b=a.document;b.querySelectorAll||(b.querySelectorAll=function(c){var d,e=b.createElement("style"),f=[];for(b.documentElement.firstChild.appendChild(e),b._qsa=[],e.styleSheet.cssText=c+"{x-qsa:expression(document._qsa && document._qsa.push(this))}",a.scrollBy(0,0),e.parentNode.removeChild(e);b._qsa.length;)d=b._qsa.shift(),d.style.removeAttribute("x-qsa"),f.push(d);return b._qsa=null,f}),b.querySelector||(b.querySelector=function(a){var c=b.querySelectorAll(a);return c.length?c[0]:null}),b.getElementsByClassName||(b.getElementsByClassName=function(a){return a=String(a).replace(/^|\s+/g,"."),b.querySelectorAll(a)}),Object.keys||(Object.keys=function(a){if(a!==Object(a))throw TypeError("Object.keys called on non-object");var b,c=[];for(b in a)Object.prototype.hasOwnProperty.call(a,b)&&c.push(b);return c}),function(a){var b="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";a.atob=a.atob||function(a){a=String(a);var c,d=0,e=[],f=0,g=0;if(a=a.replace(/\s/g,""),a.length%4===0&&(a=a.replace(/=+$/,"")),a.length%4===1)throw Error("InvalidCharacterError");if(/[^+/0-9A-Za-z]/.test(a))throw Error("InvalidCharacterError");for(;d>16&255)),e.push(String.fromCharCode(f>>8&255)),e.push(String.fromCharCode(255&f)),g=0,f=0),d+=1;return 12===g?(f>>=4,e.push(String.fromCharCode(255&f))):18===g&&(f>>=2,e.push(String.fromCharCode(f>>8&255)),e.push(String.fromCharCode(255&f))),e.join("")},a.btoa=a.btoa||function(a){a=String(a);var c,d,e,f,g,h,i,j=0,k=[];if(/[^\x00-\xFF]/.test(a))throw Error("InvalidCharacterError");for(;j>2,g=(3&c)<<4|d>>4,h=(15&d)<<2|e>>6,i=63&e,j===a.length+2?(h=64,i=64):j===a.length+1&&(i=64),k.push(b.charAt(f),b.charAt(g),b.charAt(h),b.charAt(i));return k.join("")}}(a),Object.prototype.hasOwnProperty||(Object.prototype.hasOwnProperty=function(a){var b=this.__proto__||this.constructor.prototype;return a in this&&(!(a in b)||b[a]!==this[a])}),function(){if("performance"in a==!1&&(a.performance={}),Date.now=Date.now||function(){return(new Date).getTime()},"now"in a.performance==!1){var b=Date.now();performance.timing&&performance.timing.navigationStart&&(b=performance.timing.navigationStart),a.performance.now=function(){return Date.now()-b}}}(),a.requestAnimationFrame||(a.webkitRequestAnimationFrame?!function(a){a.requestAnimationFrame=function(b){return webkitRequestAnimationFrame(function(){b(a.performance.now())})},a.cancelAnimationFrame=webkitCancelAnimationFrame}(a):a.mozRequestAnimationFrame?!function(a){a.requestAnimationFrame=function(b){return mozRequestAnimationFrame(function(){b(a.performance.now())})},a.cancelAnimationFrame=mozCancelAnimationFrame}(a):!function(a){a.requestAnimationFrame=function(b){return a.setTimeout(b,1e3/60)},a.cancelAnimationFrame=a.clearTimeout}(a))}}(this),function(a,b){"object"==typeof exports&&"object"==typeof module?module.exports=b():"function"==typeof define&&define.amd?define(b):"object"==typeof exports?exports.Holder=b():a.Holder=b()}(this,function(){return function(a){function b(d){if(c[d])return c[d].exports;var e=c[d]={exports:{},id:d,loaded:!1};return a[d].call(e.exports,e,e.exports,b),e.loaded=!0,e.exports}var c={};return b.m=a,b.c=c,b.p="",b(0)}([function(a,b,c){(function(b){function d(a,b,c,d){var f=e(c.substr(c.lastIndexOf(a.domain)),a);f&&h({mode:null,el:d,flags:f,engineSettings:b})}function e(a,b){var c={theme:B(J.settings.themes.gray,null),stylesheets:b.stylesheets,instanceOptions:b};return a.match(/([\d]+p?)x([\d]+p?)(?:\?|$)/)?f(a,c):g(a,c)}function f(a,b){var c=a.split("?"),d=c[0].split("/");b.holderURL=a;var e=d[1],f=e.match(/([\d]+p?)x([\d]+p?)/);if(!f)return!1;if(b.fluid=-1!==e.indexOf("p"),b.dimensions={width:f[1].replace("p","%"),height:f[2].replace("p","%")},2===c.length){var g=A.parse(c[1]);if(g.bg&&(b.theme.background=(-1===g.bg.indexOf("#")?"#":"")+g.bg),g.fg&&(b.theme.foreground=(-1===g.fg.indexOf("#")?"#":"")+g.fg),g.theme&&b.instanceOptions.themes.hasOwnProperty(g.theme)&&(b.theme=B(b.instanceOptions.themes[g.theme],null)),g.text&&(b.text=g.text),g.textmode&&(b.textmode=g.textmode),g.size&&(b.size=g.size),g.font&&(b.font=g.font),g.align&&(b.align=g.align),b.nowrap=z.truthy(g.nowrap),b.auto=z.truthy(g.auto),z.truthy(g.random)){J.vars.cache.themeKeys=J.vars.cache.themeKeys||Object.keys(b.instanceOptions.themes);var h=J.vars.cache.themeKeys[0|Math.random()*J.vars.cache.themeKeys.length];b.theme=B(b.instanceOptions.themes[h],null)}}return b}function g(a,b){var c=!1,d=String.fromCharCode(11),e=a.replace(/([^\\])\//g,"$1"+d).split(d),f=/%[0-9a-f]{2}/gi,g=b.instanceOptions;b.holderURL=[];for(var h=e.length,i=0;h>i;i++){var j=e[i];if(j.match(f))try{j=decodeURIComponent(j)}catch(k){j=e[i]}var l=!1;if(J.flags.dimensions.match(j))c=!0,b.dimensions=J.flags.dimensions.output(j),l=!0;else if(J.flags.fluid.match(j))c=!0,b.dimensions=J.flags.fluid.output(j),b.fluid=!0,l=!0;else if(J.flags.textmode.match(j))b.textmode=J.flags.textmode.output(j),l=!0;else if(J.flags.colors.match(j)){var m=J.flags.colors.output(j);b.theme=B(b.theme,m),l=!0}else if(g.themes[j])g.themes.hasOwnProperty(j)&&(b.theme=B(g.themes[j],null)),l=!0;else if(J.flags.font.match(j))b.font=J.flags.font.output(j),l=!0;else if(J.flags.auto.match(j))b.auto=!0,l=!0;else if(J.flags.text.match(j))b.text=J.flags.text.output(j),l=!0;else if(J.flags.size.match(j))b.size=J.flags.size.output(j),l=!0;else if(J.flags.random.match(j)){null==J.vars.cache.themeKeys&&(J.vars.cache.themeKeys=Object.keys(g.themes));var n=J.vars.cache.themeKeys[0|Math.random()*J.vars.cache.themeKeys.length];b.theme=B(g.themes[n],null),l=!0}l&&b.holderURL.push(j)}return b.holderURL.unshift(g.domain),b.holderURL=b.holderURL.join("/"),c?b:!1}function h(a){var b=a.mode,c=a.el,d=a.flags,e=a.engineSettings,f=d.dimensions,g=d.theme,h=f.width+"x"+f.height;if(b=null==b?d.fluid?"fluid":"image":b,null!=d.text&&(g.text=d.text,"object"===c.nodeName.toLowerCase())){for(var j=g.text.split("\\n"),k=0;k1){var n,o=0,p=0,q=0;j=new e.Group("line"+q),("left"===a.align||"right"===a.align)&&(m=a.width*(1-2*(1-J.setup.lineWrapRatio)));for(var r=0;r=m||t===!0)&&(b(g,j,o,g.properties.leading),g.add(j),o=0,p+=g.properties.leading,q+=1,j=new e.Group("line"+q),j.y=p),t!==!0&&(i.moveTo(o,0),o+=h.spaceWidth+s.width,j.add(i))}if(b(g,j,o,g.properties.leading),g.add(j),"left"===a.align)g.moveTo(a.width-l,null,null);else if("right"===a.align){for(n in g.children)j=g.children[n],j.moveTo(a.width-j.width,null,null);g.moveTo(0-(a.width-l),null,null)}else{for(n in g.children)j=g.children[n],j.moveTo((g.width-j.width)/2,null,null);g.moveTo((a.width-g.width)/2,null,null)}g.moveTo(null,(a.height-g.height)/2,null),(a.height-g.height)/2<0&&g.moveTo(null,0,null)}else i=new e.Text(a.text),j=new e.Group("line0"),j.add(i),g.add(j),"left"===a.align?g.moveTo(a.width-l,null,null):"right"===a.align?g.moveTo(0-(a.width-l),null,null):g.moveTo((a.width-h.boundingBox.width)/2,null,null),g.moveTo(null,(a.height-h.boundingBox.height)/2,null);return d}function k(a,b,c){var d=parseInt(a,10),e=parseInt(b,10),f=Math.max(d,e),g=Math.min(d,e),h=.8*Math.min(g,f*J.defaults.scale);return Math.round(Math.max(c,h))}function l(a){var b;b=null==a||null==a.nodeType?J.vars.resizableImages:[a];for(var c=0,d=b.length;d>c;c++){var e=b[c];if(e.holderData){var f=e.holderData.flags,g=D(e);if(g){if(!e.holderData.resizeUpdate)continue;if(f.fluid&&f.auto){var h=e.holderData.fluidConfig;switch(h.mode){case"width":g.height=g.width/h.ratio;break;case"height":g.width=g.height*h.ratio}}var j={mode:"image",holderSettings:{dimensions:g,theme:f.theme,flags:f},el:e,engineSettings:e.holderData.engineSettings};"exact"==f.textmode&&(f.exactDimensions=g,j.holderSettings.dimensions=f.dimensions),i(j)}else p(e)}}}function m(a){if(a.holderData){var b=D(a);if(b){var c=a.holderData.flags,d={fluidHeight:"%"==c.dimensions.height.slice(-1),fluidWidth:"%"==c.dimensions.width.slice(-1),mode:null,initialDimensions:b};d.fluidWidth&&!d.fluidHeight?(d.mode="width",d.ratio=d.initialDimensions.width/parseFloat(c.dimensions.height)):!d.fluidWidth&&d.fluidHeight&&(d.mode="height",d.ratio=parseFloat(c.dimensions.width)/d.initialDimensions.height),a.holderData.fluidConfig=d}else p(a)}}function n(){for(var a,c=[],d=Object.keys(J.vars.invisibleImages),e=0,f=d.length;f>e;e++)a=J.vars.invisibleImages[d[e]],D(a)&&"img"==a.nodeName.toLowerCase()&&(c.push(a),delete J.vars.invisibleImages[d[e]]);c.length&&I.run({images:c}),b.requestAnimationFrame(n)}function o(){J.vars.visibilityCheckStarted||(b.requestAnimationFrame(n),J.vars.visibilityCheckStarted=!0)}function p(a){a.holderData.invisibleId||(J.vars.invisibleId+=1,J.vars.invisibleImages["i"+J.vars.invisibleId]=a,a.holderData.invisibleId=J.vars.invisibleId)}function q(a,b){return null==b?document.createElement(a):document.createElementNS(b,a)}function r(a,b){for(var c in b)a.setAttribute(c,b[c])}function s(a,b,c){var d,e;null==a?(a=q("svg",E),d=q("defs",E),e=q("style",E),r(e,{type:"text/css"}),d.appendChild(e),a.appendChild(d)):e=a.querySelector("style"),a.webkitMatchesSelector&&a.setAttribute("xmlns",E);for(var f=0;f=0;h--){var i=g.createProcessingInstruction("xml-stylesheet",'href="'+f[h]+'" rel="stylesheet"');g.insertBefore(i,g.firstChild)}g.removeChild(g.documentElement),e=d.serializeToString(g)}var j=d.serializeToString(a);return j=j.replace(/\&(\#[0-9]{2,}\;)/g,"&$1"),e+j}}function u(){return b.DOMParser?(new DOMParser).parseFromString("","application/xml"):void 0}function v(a){J.vars.debounceTimer||a.call(this),J.vars.debounceTimer&&b.clearTimeout(J.vars.debounceTimer),J.vars.debounceTimer=b.setTimeout(function(){J.vars.debounceTimer=null,a.call(this)},J.setup.debounce)}function w(){v(function(){l(null)})}var x=c(1),y=c(2),z=c(3),A=c(4),B=z.extend,C=z.getNodeArray,D=z.dimensionCheck,E="http://www.w3.org/2000/svg",F=8,G="2.7.1",H="\nCreated with Holder.js "+G+".\nLearn more at http://holderjs.com\n(c) 2012-2015 Ivan Malopinsky - http://imsky.co\n",I={version:G,addTheme:function(a,b){return null!=a&&null!=b&&(J.settings.themes[a]=b),delete J.vars.cache.themeKeys,this},addImage:function(a,b){var c=document.querySelectorAll(b);if(c.length)for(var d=0,e=c.length;e>d;d++){var f=q("img"),g={};g[J.vars.dataAttr]=a,r(f,g),c[d].appendChild(f)}return this},setResizeUpdate:function(a,b){a.holderData&&(a.holderData.resizeUpdate=!!b,a.holderData.resizeUpdate&&l(a))},run:function(a){a=a||{};var c={},f=B(J.settings,a);J.vars.preempted=!0,J.vars.dataAttr=f.dataAttr||J.vars.dataAttr,c.renderer=f.renderer?f.renderer:J.setup.renderer,-1===J.setup.renderers.join(",").indexOf(c.renderer)&&(c.renderer=J.setup.supportsSVG?"svg":J.setup.supportsCanvas?"canvas":"html");var g=C(f.images),i=C(f.bgnodes),j=C(f.stylenodes),k=C(f.objects);c.stylesheets=[],c.svgXMLStylesheet=!0,c.noFontFallback=f.noFontFallback?f.noFontFallback:!1;for(var l=0;l1){c.nodeValue="";for(var u=0;u=0?b:1)}function f(a){v?e(a):w.push(a)}null==document.readyState&&document.addEventListener&&(document.addEventListener("DOMContentLoaded",function y(){document.removeEventListener("DOMContentLoaded",y,!1),document.readyState="complete"},!1),document.readyState="loading");var g=a.document,h=g.documentElement,i="load",j=!1,k="on"+i,l="complete",m="readyState",n="attachEvent",o="detachEvent",p="addEventListener",q="DOMContentLoaded",r="onreadystatechange",s="removeEventListener",t=p in g,u=j,v=j,w=[];if(g[m]===l)e(b);else if(t)g[p](q,c,j),a[p](i,c,j);else{g[n](r,c),a[n](k,c);try{u=null==a.frameElement&&h}catch(x){}u&&u.doScroll&&!function z(){if(!v){try{u.doScroll("left")}catch(a){return e(z,50)}d(),b()}}()}return f.version="1.4.0",f.isReady=function(){return v},f}a.exports="undefined"!=typeof window&&b(window)},function(a,b,c){var d=c(5),e=function(a){function b(a,b){for(var c in b)a[c]=b[c];return a}var c=1,e=d.defclass({constructor:function(a){c++,this.parent=null,this.children={},this.id=c,this.name="n"+c,null!=a&&(this.name=a),this.x=0,this.y=0,this.z=0,this.width=0,this.height=0},resize:function(a,b){null!=a&&(this.width=a),null!=b&&(this.height=b)},moveTo:function(a,b,c){this.x=null!=a?a:this.x,this.y=null!=b?b:this.y,this.z=null!=c?c:this.z},add:function(a){var b=a.name;if(null!=this.children[b])throw"SceneGraph: child with that name already exists: "+b;this.children[b]=a,a.parent=this}}),f=d(e,function(b){this.constructor=function(){b.constructor.call(this,"root"),this.properties=a}}),g=d(e,function(a){function c(c,d){if(a.constructor.call(this,c),this.properties={fill:"#000"},null!=d)b(this.properties,d);else if(null!=c&&"string"!=typeof c)throw"SceneGraph: invalid node name"}this.Group=d.extend(this,{constructor:c,type:"group"}),this.Rect=d.extend(this,{constructor:c,type:"rect"}),this.Text=d.extend(this,{constructor:function(a){c.call(this),this.properties.text=a},type:"text"})}),h=new f;return this.Shape=g,this.root=h,this};a.exports=e},function(a,b){(function(a){b.extend=function(a,b){var c={};for(var d in a)a.hasOwnProperty(d)&&(c[d]=a[d]);if(null!=b)for(var e in b)b.hasOwnProperty(e)&&(c[e]=b[e]);return c},b.cssProps=function(a){var b=[];for(var c in a)a.hasOwnProperty(c)&&b.push(c+":"+a[c]);return b.join(";")},b.encodeHtmlEntity=function(a){for(var b=[],c=0,d=a.length-1;d>=0;d--)c=a.charCodeAt(d),b.unshift(c>128?["&#",c,";"].join(""):a[d]);return b.join("")},b.getNodeArray=function(b){var c=null;return"string"==typeof b?c=document.querySelectorAll(b):a.NodeList&&b instanceof a.NodeList?c=b:a.Node&&b instanceof a.Node?c=[b]:a.HTMLCollection&&b instanceof a.HTMLCollection?c=b:b instanceof Array?c=b:null===b&&(c=[]),c},b.imageExists=function(a,b){var c=new Image;c.onerror=function(){b.call(this,!1)},c.onload=function(){b.call(this,!0)},c.src=a},b.decodeHtmlEntity=function(a){return a.replace(/&#(\d+);/g,function(a,b){return String.fromCharCode(b)})},b.dimensionCheck=function(a){var b={height:a.clientHeight,width:a.clientWidth};return b.height&&b.width?b:!1},b.truthy=function(a){return"string"==typeof a?"true"===a||"yes"===a||"1"===a||"on"===a||"✓"===a:!!a}}).call(b,function(){return this}())},function(a,b,c){var d=encodeURIComponent,e=decodeURIComponent,f=c(6),g=c(7),h=/(\w+)\[(\d+)\]/,i=/\w+\.\w+/;b.parse=function(a){if("string"!=typeof a)return{};if(a=f(a),""===a)return{};"?"===a.charAt(0)&&(a=a.slice(1));for(var b={},c=a.split("&"),d=0;d