Security update for permissions_by_term
authorjenny <jenny@fennel.follybridge>
Fri, 10 Nov 2017 09:11:28 +0000 (09:11 +0000)
committerjenny <jenny@fennel.follybridge>
Fri, 10 Nov 2017 09:11:28 +0000 (09:11 +0000)
1290 files changed:
composer.lock
vendor/behat/behat/CHANGELOG.md [new file with mode: 0644]
vendor/behat/behat/LICENSE [new file with mode: 0644]
vendor/behat/behat/README.md [new file with mode: 0644]
vendor/behat/behat/bin/behat [new file with mode: 0755]
vendor/behat/behat/composer.json [new file with mode: 0644]
vendor/behat/behat/i18n.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/ApplicationFactory.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Context/Annotation/AnnotationReader.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Context/Argument/ArgumentResolver.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Context/Argument/ArgumentResolverFactory.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Context/Argument/CompositeArgumentResolverFactory.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Context/Argument/CompositeFactory.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Context/Argument/NullFactory.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Context/Argument/SuiteScopedResolverFactory.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Context/Argument/SuiteScopedResolverFactoryAdapter.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Context/Cli/ContextSnippetsController.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Context/Cli/InteractiveContextIdentifier.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Context/Context.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Context/ContextClass/ClassGenerator.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Context/ContextClass/ClassResolver.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Context/ContextClass/SimpleClassGenerator.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Context/ContextFactory.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Context/CustomSnippetAcceptingContext.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Context/Environment/ContextEnvironment.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Context/Environment/Handler/ContextEnvironmentHandler.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Context/Environment/InitializedContextEnvironment.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Context/Environment/Reader/ContextEnvironmentReader.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Context/Environment/UninitializedContextEnvironment.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Context/Exception/ContextException.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Context/Exception/ContextNotFoundException.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Context/Exception/UnknownTranslationResourceException.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Context/Exception/WrongContextClassException.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Context/Initializer/ContextInitializer.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Context/Reader/AnnotatedContextReader.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Context/Reader/ContextReader.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Context/Reader/ContextReaderCachedPerContext.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Context/Reader/ContextReaderCachedPerSuite.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Context/Reader/TranslatableContextReader.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Context/ServiceContainer/ContextExtension.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Context/Snippet/Appender/ContextSnippetAppender.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Context/Snippet/ContextSnippet.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Context/Snippet/Generator/AggregateContextIdentifier.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Context/Snippet/Generator/AggregatePatternIdentifier.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Context/Snippet/Generator/CachedContextIdentifier.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Context/Snippet/Generator/ContextInterfaceBasedContextIdentifier.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Context/Snippet/Generator/ContextInterfaceBasedPatternIdentifier.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Context/Snippet/Generator/ContextSnippetGenerator.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Context/Snippet/Generator/FixedContextIdentifier.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Context/Snippet/Generator/FixedPatternIdentifier.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Context/Snippet/Generator/PatternIdentifier.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Context/Snippet/Generator/TargetContextIdentifier.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Context/SnippetAcceptingContext.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Context/Suite/Setup/SuiteWithContextsSetup.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Context/TranslatableContext.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Definition/Call/DefinitionCall.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Definition/Call/Given.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Definition/Call/RuntimeDefinition.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Definition/Call/Then.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Definition/Call/When.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Definition/Cli/AvailableDefinitionsController.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Definition/Context/Annotation/DefinitionAnnotationReader.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Definition/Definition.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Definition/DefinitionFinder.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Definition/DefinitionRepository.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Definition/DefinitionWriter.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Definition/Exception/AmbiguousMatchException.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Definition/Exception/DefinitionException.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Definition/Exception/InvalidPatternException.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Definition/Exception/RedundantStepException.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Definition/Exception/SearchException.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Definition/Exception/UnknownPatternException.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Definition/Exception/UnsupportedPatternTypeException.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Definition/Pattern/Pattern.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Definition/Pattern/PatternTransformer.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Definition/Pattern/Policy/PatternPolicy.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Definition/Pattern/Policy/RegexPatternPolicy.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Definition/Pattern/Policy/TurnipPatternPolicy.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Definition/Printer/ConsoleDefinitionInformationPrinter.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Definition/Printer/ConsoleDefinitionListPrinter.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Definition/Printer/ConsoleDefinitionPrinter.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Definition/Printer/DefinitionPrinter.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Definition/Search/RepositorySearchEngine.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Definition/Search/SearchEngine.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Definition/SearchResult.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Definition/ServiceContainer/DefinitionExtension.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Definition/Translator/DefinitionTranslator.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Definition/Translator/TranslatedDefinition.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/EventDispatcher/Cli/StopOnFailureController.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/AfterBackgroundSetup.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/AfterBackgroundTested.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/AfterFeatureSetup.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/AfterFeatureTested.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/AfterOutlineSetup.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/AfterOutlineTested.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/AfterScenarioSetup.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/AfterScenarioTested.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/AfterStepSetup.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/AfterStepTested.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/BackgroundTested.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/BeforeBackgroundTeardown.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/BeforeBackgroundTested.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/BeforeFeatureTeardown.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/BeforeFeatureTested.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/BeforeOutlineTeardown.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/BeforeOutlineTested.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/BeforeScenarioTeardown.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/BeforeScenarioTested.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/BeforeStepTeardown.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/BeforeStepTested.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/ExampleTested.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/FeatureTested.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/GherkinNodeTested.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/OutlineTested.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/ScenarioLikeTested.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/ScenarioTested.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/StepTested.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/EventDispatcher/ServiceContainer/EventDispatcherExtension.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/EventDispatcher/Tester/EventDispatchingBackgroundTester.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/EventDispatcher/Tester/EventDispatchingFeatureTester.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/EventDispatcher/Tester/EventDispatchingOutlineTester.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/EventDispatcher/Tester/EventDispatchingScenarioTester.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/EventDispatcher/Tester/EventDispatchingStepTester.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/EventDispatcher/Tester/TickingStepTester.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Gherkin/Cli/FilterController.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Gherkin/Cli/SyntaxController.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Gherkin/ServiceContainer/GherkinExtension.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Gherkin/Specification/LazyFeatureIterator.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Gherkin/Specification/Locator/FilesystemFeatureLocator.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Gherkin/Specification/Locator/FilesystemRerunScenariosListLocator.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Gherkin/Specification/Locator/FilesystemScenariosListLocator.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Gherkin/Suite/Setup/SuiteWithPathsSetup.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/HelperContainer/Argument/AutowiringResolver.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/HelperContainer/Argument/ServicesResolver.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/HelperContainer/Argument/ServicesResolverFactory.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/HelperContainer/ArgumentAutowirer.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/HelperContainer/BuiltInServiceContainer.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/HelperContainer/Call/Filter/ServicesResolver.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/HelperContainer/Environment/ServiceContainerEnvironment.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/HelperContainer/Exception/HelperContainerException.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/HelperContainer/Exception/ServiceNotFoundException.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/HelperContainer/Exception/UnsupportedCallException.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/HelperContainer/Exception/WrongContainerClassException.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/HelperContainer/Exception/WrongServicesConfigurationException.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/HelperContainer/ServiceContainer/HelperContainerExtension.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Hook/Call/AfterFeature.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Hook/Call/AfterScenario.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Hook/Call/AfterStep.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Hook/Call/BeforeFeature.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Hook/Call/BeforeScenario.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Hook/Call/BeforeStep.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Hook/Call/RuntimeFeatureHook.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Hook/Call/RuntimeScenarioHook.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Hook/Call/RuntimeStepHook.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Hook/Context/Annotation/HookAnnotationReader.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Hook/Scope/AfterFeatureScope.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Hook/Scope/AfterScenarioScope.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Hook/Scope/AfterStepScope.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Hook/Scope/BeforeFeatureScope.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Hook/Scope/BeforeScenarioScope.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Hook/Scope/BeforeStepScope.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Hook/Scope/FeatureScope.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Hook/Scope/ScenarioScope.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Hook/Scope/StepScope.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Hook/ServiceContainer/HookExtension.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Hook/Tester/HookableFeatureTester.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Hook/Tester/HookableScenarioTester.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Hook/Tester/HookableStepTester.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Output/Exception/NodeVisitorNotFoundException.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Output/Node/EventListener/AST/FeatureListener.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Output/Node/EventListener/AST/OutlineListener.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Output/Node/EventListener/AST/OutlineTableListener.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Output/Node/EventListener/AST/ScenarioNodeListener.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Output/Node/EventListener/AST/StepListener.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Output/Node/EventListener/AST/SuiteListener.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Output/Node/EventListener/Flow/FireOnlySiblingsListener.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Output/Node/EventListener/Flow/FirstBackgroundFiresFirstListener.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Output/Node/EventListener/Flow/OnlyFirstBackgroundFiresListener.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Output/Node/EventListener/JUnit/JUnitFeatureElementListener.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Output/Node/EventListener/JUnit/JUnitOutlineStoreListener.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Output/Node/EventListener/Statistics/HookStatsListener.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Output/Node/EventListener/Statistics/ScenarioStatsListener.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Output/Node/EventListener/Statistics/StatisticsListener.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Output/Node/EventListener/Statistics/StepStatsListener.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/CounterPrinter.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/ExamplePrinter.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/ExampleRowPrinter.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/FeaturePrinter.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/Helper/ResultToStringConverter.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/Helper/StepTextPainter.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/Helper/WidthCalculator.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/JUnit/JUnitFeaturePrinter.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/JUnit/JUnitScenarioPrinter.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/JUnit/JUnitSetupPrinter.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/JUnit/JUnitStepPrinter.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/JUnit/JUnitSuitePrinter.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/ListPrinter.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/OutlinePrinter.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/OutlineTablePrinter.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/Pretty/PrettyExamplePrinter.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/Pretty/PrettyExampleRowPrinter.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/Pretty/PrettyFeaturePrinter.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/Pretty/PrettyOutlinePrinter.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/Pretty/PrettyOutlineTablePrinter.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/Pretty/PrettyPathPrinter.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/Pretty/PrettyScenarioPrinter.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/Pretty/PrettySetupPrinter.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/Pretty/PrettySkippedStepPrinter.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/Pretty/PrettyStatisticsPrinter.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/Pretty/PrettyStepPrinter.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/Progress/ProgressStatisticsPrinter.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/Progress/ProgressStepPrinter.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/ScenarioPrinter.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/SetupPrinter.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/StatisticsPrinter.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/StepPrinter.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/SuitePrinter.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Output/Printer/ConsoleOutputFactory.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Output/Printer/Formatter/ConsoleFormatter.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Output/ServiceContainer/Formatter/JUnitFormatterFactory.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Output/ServiceContainer/Formatter/PrettyFormatterFactory.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Output/ServiceContainer/Formatter/ProgressFormatterFactory.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Output/Statistics/HookStat.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Output/Statistics/PhaseStatistics.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Output/Statistics/ScenarioStat.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Output/Statistics/Statistics.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Output/Statistics/StepStat.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Output/Statistics/StepStatV2.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Output/Statistics/TotalStatistics.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Snippet/AggregateSnippet.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Snippet/Appender/SnippetAppender.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Snippet/Cli/SnippetsController.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Snippet/Exception/EnvironmentSnippetGenerationException.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Snippet/Exception/SnippetException.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Snippet/Generator/SnippetGenerator.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Snippet/Printer/ConsoleSnippetPrinter.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Snippet/Printer/SnippetPrinter.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Snippet/ServiceContainer/SnippetExtension.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Snippet/Snippet.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Snippet/SnippetRegistry.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Snippet/SnippetRepository.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Snippet/SnippetWriter.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Snippet/UndefinedStep.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Tester/BackgroundTester.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Tester/Cli/RerunController.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Tester/Exception/FeatureHasNoBackgroundException.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Tester/Exception/PendingException.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Tester/Exception/Stringer/PendingExceptionStringer.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Tester/OutlineTester.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Tester/Result/DefinedStepResult.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Tester/Result/ExecutedStepResult.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Tester/Result/FailedStepSearchResult.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Tester/Result/SkippedStepResult.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Tester/Result/StepResult.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Tester/Result/UndefinedStepResult.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Tester/Runtime/IsolatingScenarioTester.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Tester/Runtime/RuntimeBackgroundTester.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Tester/Runtime/RuntimeFeatureTester.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Tester/Runtime/RuntimeOutlineTester.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Tester/Runtime/RuntimeScenarioTester.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Tester/Runtime/RuntimeStepTester.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Tester/ScenarioTester.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Tester/ServiceContainer/TesterExtension.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Tester/StepContainerTester.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Tester/StepTester.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Transformation/Call/Filter/DefinitionArgumentsTransformer.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Transformation/Call/RuntimeTransformation.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Transformation/Call/TransformationCall.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Transformation/Context/Annotation/TransformationAnnotationReader.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Transformation/Exception/TransformationException.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Transformation/Exception/UnsupportedCallException.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Transformation/RegexGenerator.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Transformation/ServiceContainer/TransformationExtension.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Transformation/SimpleArgumentTransformation.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Transformation/Transformation.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Transformation/Transformation/ColumnBasedTableTransformation.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Transformation/Transformation/PatternTransformation.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Transformation/Transformation/ReturnTypeTransformation.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Transformation/Transformation/RowBasedTableTransformation.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Transformation/Transformation/TableRowTransformation.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Transformation/Transformation/TokenNameAndReturnTypeTransformation.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Transformation/Transformation/TokenNameTransformation.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Transformation/TransformationRepository.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Transformation/Transformer/ArgumentTransformer.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Transformation/Transformer/RepositoryArgumentTransformer.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Translator/Cli/GherkinTranslationsController.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Behat/Translator/ServiceContainer/GherkinTranslationsExtension.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/ApplicationFactory.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Argument/ArgumentOrganiser.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Argument/ConstructorArgumentOrganiser.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Argument/Exception/ArgumentException.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Argument/Exception/UnknownParameterValueException.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Argument/Exception/UnsupportedFunctionException.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Argument/MixedArgumentOrganiser.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Argument/PregMatchArgumentOrganiser.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Argument/ServiceContainer/ArgumentExtension.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Argument/Validator.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Autoloader/Cli/AutoloaderController.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Autoloader/ServiceContainer/AutoloaderExtension.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Call/Call.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Call/CallCenter.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Call/CallResult.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Call/CallResults.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Call/Callee.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Call/Exception/BadCallbackException.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Call/Exception/CallErrorException.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Call/Exception/CallException.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Call/Exception/CallHandlingException.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Call/Exception/FatalThrowableError.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Call/Filter/CallFilter.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Call/Filter/ResultFilter.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Call/Handler/CallHandler.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Call/Handler/Exception/ClassNotFoundHandler.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Call/Handler/Exception/MethodNotFoundHandler.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Call/Handler/ExceptionHandler.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Call/Handler/RuntimeCallHandler.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Call/RuntimeCallee.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Call/ServiceContainer/CallExtension.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Cli/Application.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Cli/Command.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Cli/Controller.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Cli/DebugCommand.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Cli/DumpReferenceCommand.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Cli/ServiceContainer/CliExtension.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Counter/Exception/TimerException.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Counter/Memory.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Counter/Timer.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Environment/Call/EnvironmentCall.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Environment/Environment.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Environment/EnvironmentManager.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Environment/Exception/EnvironmentBuildException.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Environment/Exception/EnvironmentException.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Environment/Exception/EnvironmentIsolationException.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Environment/Exception/EnvironmentReadException.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Environment/Handler/EnvironmentHandler.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Environment/Handler/StaticEnvironmentHandler.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Environment/Reader/EnvironmentReader.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Environment/ServiceContainer/EnvironmentExtension.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Environment/StaticEnvironment.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/EventDispatcher/Cli/SigintController.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/EventDispatcher/Event/AfterExerciseAborted.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/EventDispatcher/Event/AfterExerciseCompleted.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/EventDispatcher/Event/AfterExerciseSetup.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/EventDispatcher/Event/AfterSetup.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/EventDispatcher/Event/AfterSuiteAborted.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/EventDispatcher/Event/AfterSuiteSetup.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/EventDispatcher/Event/AfterSuiteTested.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/EventDispatcher/Event/AfterTested.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/EventDispatcher/Event/BeforeExerciseCompleted.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/EventDispatcher/Event/BeforeExerciseTeardown.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/EventDispatcher/Event/BeforeSuiteTeardown.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/EventDispatcher/Event/BeforeSuiteTested.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/EventDispatcher/Event/BeforeTeardown.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/EventDispatcher/Event/BeforeTested.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/EventDispatcher/Event/ExerciseCompleted.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/EventDispatcher/Event/LifecycleEvent.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/EventDispatcher/Event/SuiteTested.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/EventDispatcher/ServiceContainer/EventDispatcherExtension.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/EventDispatcher/Tester/EventDispatchingExercise.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/EventDispatcher/Tester/EventDispatchingSuiteTester.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/EventDispatcher/TestworkEventDispatcher.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Exception/Cli/VerbosityController.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Exception/ExceptionPresenter.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Exception/ServiceContainer/ExceptionExtension.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Exception/Stringer/ExceptionStringer.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Exception/Stringer/PHPUnitExceptionStringer.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Exception/Stringer/TestworkExceptionStringer.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Exception/TestworkException.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Filesystem/ConsoleFilesystemLogger.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Filesystem/FilesystemLogger.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Filesystem/ServiceContainer/FilesystemExtension.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Hook/Call/AfterSuite.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Hook/Call/BeforeSuite.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Hook/Call/HookCall.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Hook/Call/RuntimeFilterableHook.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Hook/Call/RuntimeHook.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Hook/Call/RuntimeSuiteHook.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Hook/FilterableHook.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Hook/Hook.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Hook/HookDispatcher.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Hook/HookRepository.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Hook/Scope/AfterSuiteScope.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Hook/Scope/AfterTestScope.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Hook/Scope/BeforeSuiteScope.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Hook/Scope/HookScope.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Hook/Scope/SuiteScope.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Hook/ServiceContainer/HookExtension.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Hook/Tester/HookableSuiteTester.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Hook/Tester/Setup/HookedSetup.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Hook/Tester/Setup/HookedTeardown.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Ordering/Cli/OrderController.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Ordering/Exception/InvalidOrderException.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Ordering/OrderedExercise.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Ordering/Orderer/NoopOrderer.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Ordering/Orderer/Orderer.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Ordering/Orderer/RandomOrderer.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Ordering/Orderer/ReverseOrderer.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Ordering/ServiceContainer/OrderingExtension.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Output/Cli/OutputController.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Output/Exception/BadOutputPathException.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Output/Exception/FormatterNotFoundException.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Output/Exception/OutputException.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Output/Exception/PrinterException.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Output/Formatter.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Output/Node/EventListener/ChainEventListener.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Output/Node/EventListener/EventListener.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Output/Node/EventListener/Flow/FireOnlyIfFormatterParameterListener.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Output/NodeEventListeningFormatter.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Output/OutputManager.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Output/Printer/Factory/ConsoleOutputFactory.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Output/Printer/Factory/FilesystemOutputFactory.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Output/Printer/Factory/OutputFactory.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Output/Printer/JUnitOutputPrinter.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Output/Printer/OutputPrinter.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Output/Printer/StreamOutputPrinter.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Output/ServiceContainer/Formatter/FormatterFactory.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Output/ServiceContainer/OutputExtension.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/ServiceContainer/Configuration/ConfigurationLoader.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/ServiceContainer/Configuration/ConfigurationTree.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/ServiceContainer/ContainerLoader.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/ServiceContainer/Exception/ConfigurationLoadingException.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/ServiceContainer/Exception/ExtensionException.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/ServiceContainer/Exception/ExtensionInitializationException.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/ServiceContainer/Exception/ProcessingException.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/ServiceContainer/Exception/ServiceContainerException.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/ServiceContainer/Extension.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/ServiceContainer/ExtensionManager.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/ServiceContainer/ServiceProcessor.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Specification/GroupedSpecificationIterator.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Specification/Locator/SpecificationLocator.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Specification/NoSpecificationsIterator.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Specification/ServiceContainer/SpecificationExtension.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Specification/SpecificationArrayIterator.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Specification/SpecificationFinder.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Specification/SpecificationIterator.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Suite/Cli/InitializationController.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Suite/Cli/SuiteController.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Suite/Exception/ParameterNotFoundException.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Suite/Exception/SuiteConfigurationException.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Suite/Exception/SuiteException.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Suite/Exception/SuiteGenerationException.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Suite/Exception/SuiteNotFoundException.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Suite/Exception/SuiteSetupException.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Suite/Generator/GenericSuiteGenerator.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Suite/Generator/SuiteGenerator.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Suite/GenericSuite.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Suite/ServiceContainer/SuiteExtension.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Suite/Setup/SuiteSetup.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Suite/Suite.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Suite/SuiteBootstrapper.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Suite/SuiteRegistry.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Suite/SuiteRepository.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Tester/Cli/ExerciseController.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Tester/Cli/StrictController.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Tester/Exception/TesterException.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Tester/Exception/WrongPathsException.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Tester/Exercise.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Tester/Result/ExceptionResult.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Tester/Result/IntegerTestResult.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Tester/Result/Interpretation/ResultInterpretation.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Tester/Result/Interpretation/SoftInterpretation.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Tester/Result/Interpretation/StrictInterpretation.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Tester/Result/ResultInterpreter.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Tester/Result/TestResult.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Tester/Result/TestResults.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Tester/Result/TestWithSetupResult.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Tester/Runtime/RuntimeExercise.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Tester/Runtime/RuntimeSuiteTester.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Tester/ServiceContainer/TesterExtension.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Tester/Setup/FailedSetup.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Tester/Setup/FailedTeardown.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Tester/Setup/Setup.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Tester/Setup/SuccessfulSetup.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Tester/Setup/SuccessfulTeardown.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Tester/Setup/Teardown.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Tester/SpecificationTester.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Tester/SuiteTester.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Translator/Cli/LanguageController.php [new file with mode: 0644]
vendor/behat/behat/src/Behat/Testwork/Translator/ServiceContainer/TranslatorExtension.php [new file with mode: 0644]
vendor/behat/gherkin/.gitignore [new file with mode: 0644]
vendor/behat/gherkin/.travis.yml [new file with mode: 0644]
vendor/behat/gherkin/CHANGES.md [new file with mode: 0644]
vendor/behat/gherkin/CONTRIBUTING.md [new file with mode: 0644]
vendor/behat/gherkin/LICENSE [new file with mode: 0644]
vendor/behat/gherkin/README.md [new file with mode: 0644]
vendor/behat/gherkin/bin/update_i18n [new file with mode: 0755]
vendor/behat/gherkin/composer.json [new file with mode: 0644]
vendor/behat/gherkin/i18n.php [new file with mode: 0644]
vendor/behat/gherkin/libpath.php [new file with mode: 0644]
vendor/behat/gherkin/package.xml.tpl [new file with mode: 0644]
vendor/behat/gherkin/phpdoc.ini.dist [new file with mode: 0644]
vendor/behat/gherkin/phpunit.xml.dist [new file with mode: 0644]
vendor/behat/gherkin/src/Behat/Gherkin/Cache/CacheInterface.php [new file with mode: 0644]
vendor/behat/gherkin/src/Behat/Gherkin/Cache/FileCache.php [new file with mode: 0644]
vendor/behat/gherkin/src/Behat/Gherkin/Cache/MemoryCache.php [new file with mode: 0644]
vendor/behat/gherkin/src/Behat/Gherkin/Exception/CacheException.php [new file with mode: 0644]
vendor/behat/gherkin/src/Behat/Gherkin/Exception/Exception.php [new file with mode: 0644]
vendor/behat/gherkin/src/Behat/Gherkin/Exception/LexerException.php [new file with mode: 0644]
vendor/behat/gherkin/src/Behat/Gherkin/Exception/NodeException.php [new file with mode: 0644]
vendor/behat/gherkin/src/Behat/Gherkin/Exception/ParserException.php [new file with mode: 0644]
vendor/behat/gherkin/src/Behat/Gherkin/Filter/ComplexFilter.php [new file with mode: 0644]
vendor/behat/gherkin/src/Behat/Gherkin/Filter/ComplexFilterInterface.php [new file with mode: 0644]
vendor/behat/gherkin/src/Behat/Gherkin/Filter/FeatureFilterInterface.php [new file with mode: 0644]
vendor/behat/gherkin/src/Behat/Gherkin/Filter/FilterInterface.php [new file with mode: 0644]
vendor/behat/gherkin/src/Behat/Gherkin/Filter/LineFilter.php [new file with mode: 0644]
vendor/behat/gherkin/src/Behat/Gherkin/Filter/LineRangeFilter.php [new file with mode: 0644]
vendor/behat/gherkin/src/Behat/Gherkin/Filter/NameFilter.php [new file with mode: 0644]
vendor/behat/gherkin/src/Behat/Gherkin/Filter/NarrativeFilter.php [new file with mode: 0644]
vendor/behat/gherkin/src/Behat/Gherkin/Filter/PathsFilter.php [new file with mode: 0644]
vendor/behat/gherkin/src/Behat/Gherkin/Filter/RoleFilter.php [new file with mode: 0644]
vendor/behat/gherkin/src/Behat/Gherkin/Filter/SimpleFilter.php [new file with mode: 0644]
vendor/behat/gherkin/src/Behat/Gherkin/Filter/TagFilter.php [new file with mode: 0644]
vendor/behat/gherkin/src/Behat/Gherkin/Gherkin.php [new file with mode: 0644]
vendor/behat/gherkin/src/Behat/Gherkin/Keywords/ArrayKeywords.php [new file with mode: 0644]
vendor/behat/gherkin/src/Behat/Gherkin/Keywords/CachedArrayKeywords.php [new file with mode: 0644]
vendor/behat/gherkin/src/Behat/Gherkin/Keywords/CucumberKeywords.php [new file with mode: 0644]
vendor/behat/gherkin/src/Behat/Gherkin/Keywords/KeywordsDumper.php [new file with mode: 0644]
vendor/behat/gherkin/src/Behat/Gherkin/Keywords/KeywordsInterface.php [new file with mode: 0644]
vendor/behat/gherkin/src/Behat/Gherkin/Lexer.php [new file with mode: 0644]
vendor/behat/gherkin/src/Behat/Gherkin/Loader/AbstractFileLoader.php [new file with mode: 0644]
vendor/behat/gherkin/src/Behat/Gherkin/Loader/ArrayLoader.php [new file with mode: 0644]
vendor/behat/gherkin/src/Behat/Gherkin/Loader/DirectoryLoader.php [new file with mode: 0644]
vendor/behat/gherkin/src/Behat/Gherkin/Loader/FileLoaderInterface.php [new file with mode: 0644]
vendor/behat/gherkin/src/Behat/Gherkin/Loader/GherkinFileLoader.php [new file with mode: 0644]
vendor/behat/gherkin/src/Behat/Gherkin/Loader/LoaderInterface.php [new file with mode: 0644]
vendor/behat/gherkin/src/Behat/Gherkin/Loader/YamlFileLoader.php [new file with mode: 0644]
vendor/behat/gherkin/src/Behat/Gherkin/Node/ArgumentInterface.php [new file with mode: 0644]
vendor/behat/gherkin/src/Behat/Gherkin/Node/BackgroundNode.php [new file with mode: 0644]
vendor/behat/gherkin/src/Behat/Gherkin/Node/ExampleNode.php [new file with mode: 0644]
vendor/behat/gherkin/src/Behat/Gherkin/Node/ExampleTableNode.php [new file with mode: 0644]
vendor/behat/gherkin/src/Behat/Gherkin/Node/FeatureNode.php [new file with mode: 0644]
vendor/behat/gherkin/src/Behat/Gherkin/Node/KeywordNodeInterface.php [new file with mode: 0644]
vendor/behat/gherkin/src/Behat/Gherkin/Node/NodeInterface.php [new file with mode: 0644]
vendor/behat/gherkin/src/Behat/Gherkin/Node/OutlineNode.php [new file with mode: 0644]
vendor/behat/gherkin/src/Behat/Gherkin/Node/PyStringNode.php [new file with mode: 0644]
vendor/behat/gherkin/src/Behat/Gherkin/Node/ScenarioInterface.php [new file with mode: 0644]
vendor/behat/gherkin/src/Behat/Gherkin/Node/ScenarioLikeInterface.php [new file with mode: 0644]
vendor/behat/gherkin/src/Behat/Gherkin/Node/ScenarioNode.php [new file with mode: 0644]
vendor/behat/gherkin/src/Behat/Gherkin/Node/StepContainerInterface.php [new file with mode: 0644]
vendor/behat/gherkin/src/Behat/Gherkin/Node/StepNode.php [new file with mode: 0644]
vendor/behat/gherkin/src/Behat/Gherkin/Node/TableNode.php [new file with mode: 0644]
vendor/behat/gherkin/src/Behat/Gherkin/Node/TaggedNodeInterface.php [new file with mode: 0644]
vendor/behat/gherkin/src/Behat/Gherkin/Parser.php [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Cache/FileCacheTest.php [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Cache/MemoryCacheTest.php [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Filter/FilterTest.php [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Filter/Fixtures/full/file1 [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Filter/Fixtures/full/file2 [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Filter/Fixtures/full_path/file1 [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Filter/LineFilterTest.php [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Filter/LineRangeFilterTest.php [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Filter/NameFilterTest.php [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Filter/NarrativeFilterTest.php [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Filter/PathsFilterTest.php [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Filter/RoleFilterTest.php [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Filter/TagFilterTest.php [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/directories/phps/some_file.php [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/addition.yml [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/background.yml [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/background_title.yml [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/big_pystring.yml [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/clean_tags.yml [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/commented_out.yml [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/comments.yml [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/complex_descriptions.yml [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/empty.yml [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/empty_scenario.yml [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/empty_scenario_without_linefeed.yml [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/empty_scenarios.yml [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/fibonacci.yml [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/hashes_in_quotes.yml [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/issue_13.yml [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/ja_addition.yml [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/long_title_feature.yml [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/multiline_name.yml [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/multiline_name_with_newlines.yml [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/multiplepystrings.yml [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/outline_with_spaces.yml [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/outline_with_step_table.yml [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/pystring.yml [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/ru_addition.yml [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/ru_commented.yml [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/ru_consecutive_calculations.yml [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/ru_division.yml [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/start_comments.yml [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/tables.yml [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/tags_sample.yml [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/test_unit.yml [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/trimpystring.yml [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/undefined_multiline_args.yml [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/addition.feature [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/background.feature [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/background_title.feature [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/big_pystring.feature [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/clean_tags.feature [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/commented_out.feature [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/comments.feature [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/complex_descriptions.feature [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/empty.feature [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/empty_scenario.feature [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/empty_scenario_without_linefeed.feature [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/empty_scenarios.feature [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/fibonacci.feature [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/hashes_in_quotes.feature [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/issue_13.feature [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/ja_addition.feature [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/long_title_feature.feature [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/multiline_name.feature [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/multiline_name_with_newlines.feature [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/multiplepystrings.feature [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/outline_with_spaces.feature [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/outline_with_step_table.feature [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/pystring.feature [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/ru_addition.feature [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/ru_commented.feature [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/ru_consecutive_calculations.feature [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/ru_division.feature [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/start_comments.feature [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/tables.feature [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/tags_sample.feature [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/test_unit.feature [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/trimpystring.feature [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/undefined_multiline_args.feature [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/i18n.yml [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/GherkinTest.php [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Keywords/ArrayKeywordsTest.php [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Keywords/CachedArrayKeywordsTest.php [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Keywords/CucumberKeywordsTest.php [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Keywords/KeywordsDumperTest.php [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Keywords/KeywordsTest.php [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Loader/ArrayLoaderTest.php [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Loader/DirectoryLoaderTest.php [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Loader/GherkinFileLoaderTest.php [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Loader/YamlFileLoaderTest.php [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Node/ExampleNodeTest.php [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Node/OutlineNodeTest.php [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Node/PyStringNodeTest.php [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Node/StepNodeTest.php [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/Node/TableNodeTest.php [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/ParserExceptionsTest.php [new file with mode: 0644]
vendor/behat/gherkin/tests/Behat/Gherkin/ParserTest.php [new file with mode: 0644]
vendor/behat/mink-extension/.gitignore [new file with mode: 0644]
vendor/behat/mink-extension/.travis.yml [new file with mode: 0644]
vendor/behat/mink-extension/LICENSE [new file with mode: 0644]
vendor/behat/mink-extension/README.md [new file with mode: 0755]
vendor/behat/mink-extension/behat.yml.dist [new file with mode: 0644]
vendor/behat/mink-extension/build.php [new file with mode: 0755]
vendor/behat/mink-extension/composer.json [new file with mode: 0644]
vendor/behat/mink-extension/doc/index.rst [new file with mode: 0644]
vendor/behat/mink-extension/features/search.feature [new file with mode: 0644]
vendor/behat/mink-extension/i18n/cs.xliff [new file with mode: 0644]
vendor/behat/mink-extension/i18n/da.xliff [new file with mode: 0644]
vendor/behat/mink-extension/i18n/de.xliff [new file with mode: 0644]
vendor/behat/mink-extension/i18n/es.xliff [new file with mode: 0644]
vendor/behat/mink-extension/i18n/fr.xliff [new file with mode: 0644]
vendor/behat/mink-extension/i18n/hu.xliff [new file with mode: 0644]
vendor/behat/mink-extension/i18n/id.xliff [new file with mode: 0644]
vendor/behat/mink-extension/i18n/it.xliff [new file with mode: 0644]
vendor/behat/mink-extension/i18n/ja.xliff [new file with mode: 0644]
vendor/behat/mink-extension/i18n/nl.xliff [new file with mode: 0644]
vendor/behat/mink-extension/i18n/pl.xliff [new file with mode: 0644]
vendor/behat/mink-extension/i18n/pt-br.xliff [new file with mode: 0644]
vendor/behat/mink-extension/i18n/pt.xliff [new file with mode: 0644]
vendor/behat/mink-extension/i18n/ro.xliff [new file with mode: 0644]
vendor/behat/mink-extension/i18n/ru.xliff [new file with mode: 0644]
vendor/behat/mink-extension/i18n/sk.xliff [new file with mode: 0644]
vendor/behat/mink-extension/i18n/sv.xliff [new file with mode: 0644]
vendor/behat/mink-extension/i18n/zh-CN.xliff [new file with mode: 0644]
vendor/behat/mink-extension/init.php [new file with mode: 0644]
vendor/behat/mink-extension/spec/Behat/MinkExtension/Context/Initializer/MinkAwareInitializerSpec.php [new file with mode: 0644]
vendor/behat/mink-extension/spec/Behat/MinkExtension/Listener/SessionsListenerSpec.php [new file with mode: 0644]
vendor/behat/mink-extension/spec/Behat/MinkExtension/ServiceContainer/Driver/BrowserStackFactorySpec.php [new file with mode: 0644]
vendor/behat/mink-extension/spec/Behat/MinkExtension/ServiceContainer/Driver/GoutteFactorySpec.php [new file with mode: 0644]
vendor/behat/mink-extension/spec/Behat/MinkExtension/ServiceContainer/Driver/SahiFactorySpec.php [new file with mode: 0644]
vendor/behat/mink-extension/spec/Behat/MinkExtension/ServiceContainer/Driver/SauceLabsFactorySpec.php [new file with mode: 0644]
vendor/behat/mink-extension/spec/Behat/MinkExtension/ServiceContainer/Driver/Selenium2FactorySpec.php [new file with mode: 0644]
vendor/behat/mink-extension/spec/Behat/MinkExtension/ServiceContainer/Driver/SeleniumFactorySpec.php [new file with mode: 0644]
vendor/behat/mink-extension/spec/Behat/MinkExtension/ServiceContainer/Driver/ZombieFactorySpec.php [new file with mode: 0644]
vendor/behat/mink-extension/spec/Behat/MinkExtension/ServiceContainer/MinkExtensionSpec.php [new file with mode: 0644]
vendor/behat/mink-extension/src/Behat/MinkExtension/Context/Initializer/MinkAwareInitializer.php [new file with mode: 0644]
vendor/behat/mink-extension/src/Behat/MinkExtension/Context/MinkAwareContext.php [new file with mode: 0644]
vendor/behat/mink-extension/src/Behat/MinkExtension/Context/MinkContext.php [new file with mode: 0644]
vendor/behat/mink-extension/src/Behat/MinkExtension/Context/RawMinkContext.php [new file with mode: 0644]
vendor/behat/mink-extension/src/Behat/MinkExtension/Listener/FailureShowListener.php [new file with mode: 0644]
vendor/behat/mink-extension/src/Behat/MinkExtension/Listener/SessionsListener.php [new file with mode: 0644]
vendor/behat/mink-extension/src/Behat/MinkExtension/ServiceContainer/Driver/BrowserStackFactory.php [new file with mode: 0644]
vendor/behat/mink-extension/src/Behat/MinkExtension/ServiceContainer/Driver/DriverFactory.php [new file with mode: 0644]
vendor/behat/mink-extension/src/Behat/MinkExtension/ServiceContainer/Driver/GoutteFactory.php [new file with mode: 0644]
vendor/behat/mink-extension/src/Behat/MinkExtension/ServiceContainer/Driver/SahiFactory.php [new file with mode: 0644]
vendor/behat/mink-extension/src/Behat/MinkExtension/ServiceContainer/Driver/SauceLabsFactory.php [new file with mode: 0644]
vendor/behat/mink-extension/src/Behat/MinkExtension/ServiceContainer/Driver/Selenium2Factory.php [new file with mode: 0644]
vendor/behat/mink-extension/src/Behat/MinkExtension/ServiceContainer/Driver/SeleniumFactory.php [new file with mode: 0644]
vendor/behat/mink-extension/src/Behat/MinkExtension/ServiceContainer/Driver/ZombieFactory.php [new file with mode: 0644]
vendor/behat/mink-extension/src/Behat/MinkExtension/ServiceContainer/MinkExtension.php [new file with mode: 0644]
vendor/behat/mink-selenium2-driver/.gitignore [new file with mode: 0644]
vendor/behat/mink-selenium2-driver/.travis.yml [new file with mode: 0644]
vendor/behat/mink-selenium2-driver/CHANGELOG.md [new file with mode: 0644]
vendor/behat/mink-selenium2-driver/README.md [new file with mode: 0644]
vendor/behat/mink-selenium2-driver/bin/run-phantomjs.sh [new file with mode: 0644]
vendor/behat/mink-selenium2-driver/bin/run-selenium.sh [new file with mode: 0644]
vendor/behat/mink-selenium2-driver/composer.json [new file with mode: 0644]
vendor/behat/mink-selenium2-driver/phpunit.xml.dist [new file with mode: 0644]
vendor/behat/mink-selenium2-driver/src/Resources/syn.js [new file with mode: 0644]
vendor/behat/mink-selenium2-driver/src/Selenium2Driver.php [new file with mode: 0755]
vendor/behat/mink-selenium2-driver/tests/Custom/TimeoutTest.php [new file with mode: 0644]
vendor/behat/mink-selenium2-driver/tests/Custom/WebDriverTest.php [new file with mode: 0644]
vendor/behat/mink-selenium2-driver/tests/Custom/WindowNameTest.php [new file with mode: 0644]
vendor/behat/mink-selenium2-driver/tests/Selenium2Config.php [new file with mode: 0644]
vendor/behat/transliterator/CHANGELOG.md [new file with mode: 0644]
vendor/behat/transliterator/CONTRIBUTING.md [new file with mode: 0644]
vendor/behat/transliterator/LICENSE [new file with mode: 0644]
vendor/behat/transliterator/README.md [new file with mode: 0644]
vendor/behat/transliterator/composer.json [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/SyncTool.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/Transliterator.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x00.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x01.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x02.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x03.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x04.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x05.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x06.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x07.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x09.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x0a.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x0b.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x0c.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x0d.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x0e.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x0f.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x10.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x11.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x12.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x13.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x14.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x15.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x16.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x17.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x18.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x1e.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x1f.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x20.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x21.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x24.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x25.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x26.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x27.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x28.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x30.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x31.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x32.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x33.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x4e.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x4f.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x50.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x51.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x52.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x53.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x54.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x55.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x56.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x57.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x58.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x59.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x5a.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x5b.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x5c.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x5d.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x5e.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x5f.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x60.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x61.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x62.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x63.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x64.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x65.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x66.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x67.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x68.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x69.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x6a.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x6b.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x6c.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x6d.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x6e.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x6f.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x70.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x71.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x72.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x73.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x74.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x75.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x76.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x77.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x78.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x79.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x7a.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x7b.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x7c.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x7d.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x7e.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x7f.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x80.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x81.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x82.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x83.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x84.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x85.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x86.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x87.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x88.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x89.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x8a.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x8b.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x8c.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x8d.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x8e.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x8f.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x90.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x91.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x92.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x93.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x94.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x95.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x96.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x97.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x98.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x99.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x9a.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x9b.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x9c.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x9d.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x9e.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/x9f.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/xa0.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/xa1.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/xa2.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/xa3.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/xa4.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/xac.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/xad.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/xae.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/xaf.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/xb0.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/xb1.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/xb2.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/xb3.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/xb4.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/xb5.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/xb6.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/xb7.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/xb8.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/xb9.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/xba.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/xbb.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/xbc.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/xbd.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/xbe.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/xbf.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/xc0.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/xc1.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/xc2.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/xc3.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/xc4.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/xc5.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/xc6.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/xc7.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/xc8.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/xc9.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/xca.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/xcb.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/xcc.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/xcd.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/xce.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/xcf.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/xd0.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/xd1.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/xd2.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/xd3.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/xd4.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/xd5.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/xd6.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/xd7.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/xf9.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/xfa.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/xfb.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/xfc.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/xfd.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/xfe.php [new file with mode: 0644]
vendor/behat/transliterator/src/Behat/Transliterator/data/xff.php [new file with mode: 0644]
vendor/bin/behat [new symlink]
vendor/composer/autoload_namespaces.php
vendor/composer/autoload_psr4.php
vendor/composer/autoload_static.php
vendor/composer/installed.json
vendor/container-interop/container-interop/.gitignore [new file with mode: 0644]
vendor/container-interop/container-interop/LICENSE [new file with mode: 0644]
vendor/container-interop/container-interop/README.md [new file with mode: 0644]
vendor/container-interop/container-interop/composer.json [new file with mode: 0644]
vendor/container-interop/container-interop/docs/ContainerInterface-meta.md [new file with mode: 0644]
vendor/container-interop/container-interop/docs/ContainerInterface.md [new file with mode: 0644]
vendor/container-interop/container-interop/docs/Delegate-lookup-meta.md [new file with mode: 0644]
vendor/container-interop/container-interop/docs/Delegate-lookup.md [new file with mode: 0644]
vendor/container-interop/container-interop/docs/images/interoperating_containers.png [new file with mode: 0644]
vendor/container-interop/container-interop/docs/images/priority.png [new file with mode: 0644]
vendor/container-interop/container-interop/docs/images/side_by_side_containers.png [new file with mode: 0644]
vendor/container-interop/container-interop/src/Interop/Container/ContainerInterface.php [new file with mode: 0644]
vendor/container-interop/container-interop/src/Interop/Container/Exception/ContainerException.php [new file with mode: 0644]
vendor/container-interop/container-interop/src/Interop/Container/Exception/NotFoundException.php [new file with mode: 0644]
vendor/drupal/drupal-driver/.gitignore [new file with mode: 0644]
vendor/drupal/drupal-driver/.travis.yml [new file with mode: 0644]
vendor/drupal/drupal-driver/LICENSE [new file with mode: 0644]
vendor/drupal/drupal-driver/README.md [new file with mode: 0644]
vendor/drupal/drupal-driver/composer.json [new file with mode: 0644]
vendor/drupal/drupal-driver/doc/.gitignore [new file with mode: 0644]
vendor/drupal/drupal-driver/doc/Makefile [new file with mode: 0644]
vendor/drupal/drupal-driver/doc/_static/snippets/composer.bash [new file with mode: 0644]
vendor/drupal/drupal-driver/doc/_static/snippets/composer.json [new file with mode: 0644]
vendor/drupal/drupal-driver/doc/_static/snippets/phpunit-composer.json [new file with mode: 0644]
vendor/drupal/drupal-driver/doc/_static/snippets/phpunitDrupalDriver.php [new file with mode: 0644]
vendor/drupal/drupal-driver/doc/_static/snippets/usage-blackbox.php [new file with mode: 0644]
vendor/drupal/drupal-driver/doc/_static/snippets/usage-drupal.php [new file with mode: 0644]
vendor/drupal/drupal-driver/doc/_static/snippets/usage-drush.php [new file with mode: 0644]
vendor/drupal/drupal-driver/doc/conf.py [new file with mode: 0644]
vendor/drupal/drupal-driver/doc/drivers.rst [new file with mode: 0644]
vendor/drupal/drupal-driver/doc/index.rst [new file with mode: 0644]
vendor/drupal/drupal-driver/doc/install.rst [new file with mode: 0644]
vendor/drupal/drupal-driver/doc/make.bat [new file with mode: 0644]
vendor/drupal/drupal-driver/doc/usage.rst [new file with mode: 0644]
vendor/drupal/drupal-driver/phpcs-ruleset.xml [new file with mode: 0644]
vendor/drupal/drupal-driver/phpunit.xml.dist [new file with mode: 0644]
vendor/drupal/drupal-driver/spec/Drupal/Driver/BlackboxDriverSpec.php [new file with mode: 0644]
vendor/drupal/drupal-driver/spec/Drupal/Driver/Cores/Drupal6Spec.php [new file with mode: 0644]
vendor/drupal/drupal-driver/spec/Drupal/Driver/Cores/Drupal7Spec.php [new file with mode: 0644]
vendor/drupal/drupal-driver/spec/Drupal/Driver/Cores/Drupal8Spec.php [new file with mode: 0644]
vendor/drupal/drupal-driver/spec/Drupal/Driver/Exception/BootstrapExceptionSpec.php [new file with mode: 0644]
vendor/drupal/drupal-driver/spec/Drupal/Driver/Exception/UnsupportedDriverActionExceptionSpec.php [new file with mode: 0644]
vendor/drupal/drupal-driver/src/Drupal/Component/Utility/Random.php [new file with mode: 0644]
vendor/drupal/drupal-driver/src/Drupal/Driver/BaseDriver.php [new file with mode: 0644]
vendor/drupal/drupal-driver/src/Drupal/Driver/BlackboxDriver.php [new file with mode: 0644]
vendor/drupal/drupal-driver/src/Drupal/Driver/Cores/AbstractCore.php [new file with mode: 0644]
vendor/drupal/drupal-driver/src/Drupal/Driver/Cores/CoreInterface.php [new file with mode: 0644]
vendor/drupal/drupal-driver/src/Drupal/Driver/Cores/Drupal6.php [new file with mode: 0644]
vendor/drupal/drupal-driver/src/Drupal/Driver/Cores/Drupal7.php [new file with mode: 0644]
vendor/drupal/drupal-driver/src/Drupal/Driver/Cores/Drupal8.php [new file with mode: 0644]
vendor/drupal/drupal-driver/src/Drupal/Driver/DriverInterface.php [new file with mode: 0644]
vendor/drupal/drupal-driver/src/Drupal/Driver/DrupalDriver.php [new file with mode: 0644]
vendor/drupal/drupal-driver/src/Drupal/Driver/DrushDriver.php [new file with mode: 0644]
vendor/drupal/drupal-driver/src/Drupal/Driver/Exception/BootstrapException.php [new file with mode: 0644]
vendor/drupal/drupal-driver/src/Drupal/Driver/Exception/Exception.php [new file with mode: 0644]
vendor/drupal/drupal-driver/src/Drupal/Driver/Exception/UnsupportedDriverActionException.php [new file with mode: 0644]
vendor/drupal/drupal-driver/src/Drupal/Driver/Fields/Drupal6/TaxonomyHandler.php [new file with mode: 0644]
vendor/drupal/drupal-driver/src/Drupal/Driver/Fields/Drupal7/AbstractHandler.php [new file with mode: 0644]
vendor/drupal/drupal-driver/src/Drupal/Driver/Fields/Drupal7/DatetimeHandler.php [new file with mode: 0644]
vendor/drupal/drupal-driver/src/Drupal/Driver/Fields/Drupal7/DefaultHandler.php [new file with mode: 0644]
vendor/drupal/drupal-driver/src/Drupal/Driver/Fields/Drupal7/EntityreferenceHandler.php [new file with mode: 0644]
vendor/drupal/drupal-driver/src/Drupal/Driver/Fields/Drupal7/FileHandler.php [new file with mode: 0644]
vendor/drupal/drupal-driver/src/Drupal/Driver/Fields/Drupal7/ImageHandler.php [new file with mode: 0644]
vendor/drupal/drupal-driver/src/Drupal/Driver/Fields/Drupal7/LinkFieldHandler.php [new file with mode: 0644]
vendor/drupal/drupal-driver/src/Drupal/Driver/Fields/Drupal7/ListBooleanHandler.php [new file with mode: 0644]
vendor/drupal/drupal-driver/src/Drupal/Driver/Fields/Drupal7/ListTextHandler.php [new file with mode: 0644]
vendor/drupal/drupal-driver/src/Drupal/Driver/Fields/Drupal7/TaxonomyTermReferenceHandler.php [new file with mode: 0644]
vendor/drupal/drupal-driver/src/Drupal/Driver/Fields/Drupal8/AbstractHandler.php [new file with mode: 0644]
vendor/drupal/drupal-driver/src/Drupal/Driver/Fields/Drupal8/DatetimeHandler.php [new file with mode: 0644]
vendor/drupal/drupal-driver/src/Drupal/Driver/Fields/Drupal8/DefaultHandler.php [new file with mode: 0644]
vendor/drupal/drupal-driver/src/Drupal/Driver/Fields/Drupal8/EntityReferenceHandler.php [new file with mode: 0644]
vendor/drupal/drupal-driver/src/Drupal/Driver/Fields/Drupal8/ImageHandler.php [new file with mode: 0644]
vendor/drupal/drupal-driver/src/Drupal/Driver/Fields/Drupal8/LinkHandler.php [new file with mode: 0644]
vendor/drupal/drupal-driver/src/Drupal/Driver/Fields/Drupal8/TaxonomyTermReferenceHandler.php [new file with mode: 0644]
vendor/drupal/drupal-driver/src/Drupal/Driver/Fields/Drupal8/TextWithSummaryHandler.php [new file with mode: 0644]
vendor/drupal/drupal-driver/src/Drupal/Driver/Fields/FieldHandlerInterface.php [new file with mode: 0644]
vendor/drupal/drupal-driver/src/Drupal/Driver/SubDriverFinderInterface.php [new file with mode: 0644]
vendor/drupal/drupal-driver/tests/Drupal/Tests/Driver/Drupal7FieldHandlerTest.php [new file with mode: 0644]
vendor/drupal/drupal-driver/tests/Drupal/Tests/Driver/DrushDriverTest.php [new file with mode: 0644]
vendor/drupal/drupal-driver/tests/Drupal/Tests/Driver/FieldHandlerAbstractTest.php [new file with mode: 0644]
vendor/drupal/drupal-extension/.gitignore [new file with mode: 0644]
vendor/drupal/drupal-extension/.travis.yml [new file with mode: 0644]
vendor/drupal/drupal-extension/LICENSE [new file with mode: 0644]
vendor/drupal/drupal-extension/README.md [new file with mode: 0644]
vendor/drupal/drupal-extension/behat.yml.dist [new file with mode: 0644]
vendor/drupal/drupal-extension/composer.json [new file with mode: 0644]
vendor/drupal/drupal-extension/doc/.gitignore [new file with mode: 0644]
vendor/drupal/drupal-extension/doc/Makefile [new file with mode: 0644]
vendor/drupal/drupal-extension/doc/_static/beehat-drupalicon.png [new file with mode: 0644]
vendor/drupal/drupal-extension/doc/_static/beehat.png [new file with mode: 0644]
vendor/drupal/drupal-extension/doc/_static/composer.json.d8 [new file with mode: 0644]
vendor/drupal/drupal-extension/doc/_static/custom.css [new file with mode: 0644]
vendor/drupal/drupal-extension/doc/_static/drupalize-purchase-1024.swf [new file with mode: 0644]
vendor/drupal/drupal-extension/doc/_static/favicon.ico [new file with mode: 0644]
vendor/drupal/drupal-extension/doc/_static/snippets/FeatureContext.php.inc [new file with mode: 0644]
vendor/drupal/drupal-extension/doc/_static/snippets/aliases.drushrc.php [new file with mode: 0644]
vendor/drupal/drupal-extension/doc/_static/snippets/api.feature [new file with mode: 0644]
vendor/drupal/drupal-extension/doc/_static/snippets/apitag.feature [new file with mode: 0644]
vendor/drupal/drupal-extension/doc/_static/snippets/apitag.output [new file with mode: 0644]
vendor/drupal/drupal-extension/doc/_static/snippets/behat-1.yml [new file with mode: 0644]
vendor/drupal/drupal-extension/doc/_static/snippets/behat-api.yml [new file with mode: 0644]
vendor/drupal/drupal-extension/doc/_static/snippets/behat-auto.yml [new file with mode: 0644]
vendor/drupal/drupal-extension/doc/_static/snippets/behat-bb.yml [new file with mode: 0644]
vendor/drupal/drupal-extension/doc/_static/snippets/behat-drush.yml [new file with mode: 0644]
vendor/drupal/drupal-extension/doc/_static/snippets/behat-sub.yml [new file with mode: 0644]
vendor/drupal/drupal-extension/doc/_static/snippets/blackbox.feature [new file with mode: 0644]
vendor/drupal/drupal-extension/doc/_static/snippets/composer.json [new file with mode: 0644]
vendor/drupal/drupal-extension/doc/_static/snippets/composer.json.d8 [new file with mode: 0644]
vendor/drupal/drupal-extension/doc/_static/snippets/context-communication.inc [new file with mode: 0644]
vendor/drupal/drupal-extension/doc/_static/snippets/drush.feature [new file with mode: 0644]
vendor/drupal/drupal-extension/doc/_static/snippets/subcontext.inc [new file with mode: 0644]
vendor/drupal/drupal-extension/doc/blackbox.rst [new file with mode: 0644]
vendor/drupal/drupal-extension/doc/conf.py [new file with mode: 0644]
vendor/drupal/drupal-extension/doc/contexts.rst [new file with mode: 0644]
vendor/drupal/drupal-extension/doc/drivers.rst [new file with mode: 0644]
vendor/drupal/drupal-extension/doc/drupalapi.rst [new file with mode: 0644]
vendor/drupal/drupal-extension/doc/drush.rst [new file with mode: 0644]
vendor/drupal/drupal-extension/doc/environment.rst [new file with mode: 0644]
vendor/drupal/drupal-extension/doc/globalinstall.rst [new file with mode: 0644]
vendor/drupal/drupal-extension/doc/index.rst [new file with mode: 0644]
vendor/drupal/drupal-extension/doc/intro.rst [new file with mode: 0644]
vendor/drupal/drupal-extension/doc/localinstall.rst [new file with mode: 0644]
vendor/drupal/drupal-extension/doc/requirements.rst [new file with mode: 0644]
vendor/drupal/drupal-extension/doc/subcontexts.rst [new file with mode: 0644]
vendor/drupal/drupal-extension/features/api.feature [new file with mode: 0644]
vendor/drupal/drupal-extension/features/api_background.feature [new file with mode: 0644]
vendor/drupal/drupal-extension/features/blackbox.feature [new file with mode: 0644]
vendor/drupal/drupal-extension/features/bootstrap/FeatureContext.php [new file with mode: 0644]
vendor/drupal/drupal-extension/features/config.feature [new file with mode: 0644]
vendor/drupal/drupal-extension/features/d6.feature [new file with mode: 0644]
vendor/drupal/drupal-extension/features/d8.feature [new file with mode: 0644]
vendor/drupal/drupal-extension/features/drush.feature [new file with mode: 0644]
vendor/drupal/drupal-extension/features/field_handlers.feature [new file with mode: 0644]
vendor/drupal/drupal-extension/features/language.feature [new file with mode: 0644]
vendor/drupal/drupal-extension/features/messages.feature [new file with mode: 0644]
vendor/drupal/drupal-extension/features/subcontexts/find.feature [new file with mode: 0644]
vendor/drupal/drupal-extension/fixtures/blackbox/community.html [new file with mode: 0644]
vendor/drupal/drupal-extension/fixtures/blackbox/download.html [new file with mode: 0644]
vendor/drupal/drupal-extension/fixtures/blackbox/form.html [new file with mode: 0644]
vendor/drupal/drupal-extension/fixtures/blackbox/index.html [new file with mode: 0644]
vendor/drupal/drupal-extension/fixtures/blackbox/irc.html [new file with mode: 0644]
vendor/drupal/drupal-extension/fixtures/blackbox/user.html [new file with mode: 0644]
vendor/drupal/drupal-extension/fixtures/drupal6/modules/behat_test/behat_test.info [new file with mode: 0644]
vendor/drupal/drupal-extension/fixtures/drupal6/modules/behat_test/behat_test.install [new file with mode: 0644]
vendor/drupal/drupal-extension/fixtures/drupal6/modules/behat_test/behat_test.module [new file with mode: 0644]
vendor/drupal/drupal-extension/fixtures/drupal7/modules/behat_test/behat_test.features.field_base.inc [new file with mode: 0644]
vendor/drupal/drupal-extension/fixtures/drupal7/modules/behat_test/behat_test.features.field_instance.inc [new file with mode: 0644]
vendor/drupal/drupal-extension/fixtures/drupal7/modules/behat_test/behat_test.features.inc [new file with mode: 0644]
vendor/drupal/drupal-extension/fixtures/drupal7/modules/behat_test/behat_test.features.taxonomy.inc [new file with mode: 0644]
vendor/drupal/drupal-extension/fixtures/drupal7/modules/behat_test/behat_test.features.user_permission.inc [new file with mode: 0644]
vendor/drupal/drupal-extension/fixtures/drupal7/modules/behat_test/behat_test.info [new file with mode: 0644]
vendor/drupal/drupal-extension/fixtures/drupal7/modules/behat_test/behat_test.module [new file with mode: 0644]
vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/behat_test.info.yml [new file with mode: 0644]
vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/behat_test.install [new file with mode: 0644]
vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/behat_test.services.yml [new file with mode: 0644]
vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/config/install/core.entity_form_display.node.post.default.yml [new file with mode: 0644]
vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/config/install/core.entity_view_display.node.post.default.yml [new file with mode: 0644]
vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/config/install/core.entity_view_display.node.post.teaser.yml [new file with mode: 0644]
vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/config/install/field.field.node.post.body.yml [new file with mode: 0644]
vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/config/install/field.field.node.post.field_post_address.yml [new file with mode: 0644]
vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/config/install/field.field.node.post.field_post_date.yml [new file with mode: 0644]
vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/config/install/field.field.node.post.field_post_links.yml [new file with mode: 0644]
vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/config/install/field.field.node.post.field_post_reference.yml [new file with mode: 0644]
vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/config/install/field.field.node.post.field_post_select.yml [new file with mode: 0644]
vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/config/install/field.field.user.user.field_post_address.yml [new file with mode: 0644]
vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/config/install/field.field.user.user.field_post_reference.yml [new file with mode: 0644]
vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/config/install/field.field.user.user.field_tags.yml [new file with mode: 0644]
vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/config/install/field.storage.node.field_post_adress.yml [new file with mode: 0644]
vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/config/install/field.storage.node.field_post_date.yml [new file with mode: 0644]
vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/config/install/field.storage.node.field_post_links.yml [new file with mode: 0644]
vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/config/install/field.storage.node.field_post_reference.yml [new file with mode: 0644]
vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/config/install/field.storage.node.field_post_select.yml [new file with mode: 0644]
vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/config/install/field.storage.user.field_post_address.yml [new file with mode: 0644]
vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/config/install/field.storage.user.field_post_reference.yml [new file with mode: 0644]
vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/config/install/field.storage.user.field_tags.yml [new file with mode: 0644]
vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/config/install/node.type.post.yml [new file with mode: 0644]
vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/config/schema/behat_test.schema.yml [new file with mode: 0644]
vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/override_config/core.entity_form_display.user.user.default.yml [new file with mode: 0644]
vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/override_config/core.entity_form_mode.user.register.yml [new file with mode: 0644]
vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/override_config/core.entity_view_display.user.user.compact.yml [new file with mode: 0644]
vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/override_config/core.entity_view_display.user.user.default.yml [new file with mode: 0644]
vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/override_config/core.entity_view_mode.user.compact.yml [new file with mode: 0644]
vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/override_config/core.entity_view_mode.user.full.yml [new file with mode: 0644]
vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/src/Config/BehatTestExtensionInstallStorage.php [new file with mode: 0644]
vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/src/Plugin/Field/FieldFormatter/AddressFieldFormatter.php [new file with mode: 0644]
vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/src/Plugin/Field/FieldType/AddressFieldItem.php [new file with mode: 0644]
vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/src/Plugin/Field/FieldWidget/AddressFieldWidget.php [new file with mode: 0644]
vendor/drupal/drupal-extension/i18n/da.xliff [new file with mode: 0644]
vendor/drupal/drupal-extension/i18n/es.xliff [new file with mode: 0644]
vendor/drupal/drupal-extension/i18n/fr.xliff [new file with mode: 0644]
vendor/drupal/drupal-extension/package.json [new file with mode: 0644]
vendor/drupal/drupal-extension/spec/Drupal/DrupalDriverManagerSpec.php [new file with mode: 0644]
vendor/drupal/drupal-extension/spec/Drupal/DrupalExtension/Context/Annotation/ReaderSpec.php [new file with mode: 0644]
vendor/drupal/drupal-extension/spec/Drupal/DrupalExtension/Context/DrupalContextSpec.php [new file with mode: 0644]
vendor/drupal/drupal-extension/spec/Drupal/DrupalExtension/Context/DrushContextSpec.php [new file with mode: 0644]
vendor/drupal/drupal-extension/spec/Drupal/DrupalExtension/Context/Environment/Reader/ReaderSpec.php [new file with mode: 0644]
vendor/drupal/drupal-extension/spec/Drupal/DrupalExtension/Context/Initializer/DrupalAwareInitializerSpec.php [new file with mode: 0644]
vendor/drupal/drupal-extension/spec/Drupal/DrupalExtension/Context/MessageContextSpec.php [new file with mode: 0644]
vendor/drupal/drupal-extension/spec/Drupal/DrupalExtension/Context/MinkContextSpec.php [new file with mode: 0644]
vendor/drupal/drupal-extension/spec/Drupal/DrupalExtension/Context/RawDrupalContextSpec.php [new file with mode: 0644]
vendor/drupal/drupal-extension/spec/Drupal/DrupalExtension/Hook/Scope/BeforeNodeCreateScopeSpec.php [new file with mode: 0644]
vendor/drupal/drupal-extension/spec/Drupal/DrupalExtension/Listener/DriverListenerSpec.php [new file with mode: 0644]
vendor/drupal/drupal-extension/spec/Drupal/DrupalExtension/Selector/RegionSelectorSpec.php [new file with mode: 0644]
vendor/drupal/drupal-extension/spec/Drupal/DrupalExtension/ServiceContainer/DrupalExtensionSpec.php [new file with mode: 0644]
vendor/drupal/drupal-extension/src/Drupal/DrupalDriverManager.php [new file with mode: 0644]
vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Compiler/DriverPass.php [new file with mode: 0644]
vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Compiler/EventSubscriberPass.php [new file with mode: 0644]
vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Context/Annotation/Reader.php [new file with mode: 0644]
vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Context/BatchContext.php [new file with mode: 0644]
vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Context/ConfigContext.php [new file with mode: 0644]
vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Context/ContextClass/ClassGenerator.php [new file with mode: 0644]
vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Context/DrupalAwareInterface.php [new file with mode: 0644]
vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Context/DrupalContext.php [new file with mode: 0644]
vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Context/DrupalSubContextBase.php [new file with mode: 0644]
vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Context/DrupalSubContextInterface.php [new file with mode: 0644]
vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Context/DrushContext.php [new file with mode: 0644]
vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Context/Environment/Reader/Reader.php [new file with mode: 0644]
vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Context/Initializer/DrupalAwareInitializer.php [new file with mode: 0644]
vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Context/MarkupContext.php [new file with mode: 0644]
vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Context/MessageContext.php [new file with mode: 0644]
vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Context/MinkContext.php [new file with mode: 0644]
vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Context/RawDrupalContext.php [new file with mode: 0644]
vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Definition/Proposal/AnnotatedDefinitionProposal.php [new file with mode: 0644]
vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Hook/Call/AfterNodeCreate.php [new file with mode: 0644]
vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Hook/Call/AfterTermCreate.php [new file with mode: 0644]
vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Hook/Call/AfterUserCreate.php [new file with mode: 0644]
vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Hook/Call/BeforeNodeCreate.php [new file with mode: 0644]
vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Hook/Call/BeforeTermCreate.php [new file with mode: 0644]
vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Hook/Call/BeforeUserCreate.php [new file with mode: 0644]
vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Hook/Call/EntityHook.php [new file with mode: 0644]
vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Hook/Scope/AfterLanguageCreateScope.php [new file with mode: 0644]
vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Hook/Scope/AfterNodeCreateScope.php [new file with mode: 0644]
vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Hook/Scope/AfterTermCreateScope.php [new file with mode: 0644]
vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Hook/Scope/AfterUserCreateScope.php [new file with mode: 0644]
vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Hook/Scope/BaseEntityScope.php [new file with mode: 0644]
vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Hook/Scope/BeforeLanguageCreateScope.php [new file with mode: 0644]
vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Hook/Scope/BeforeNodeCreateScope.php [new file with mode: 0644]
vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Hook/Scope/BeforeTermCreateScope.php [new file with mode: 0644]
vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Hook/Scope/BeforeUserCreateScope.php [new file with mode: 0644]
vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Hook/Scope/EntityScope.php [new file with mode: 0644]
vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Hook/Scope/LanguageScope.php [new file with mode: 0644]
vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Hook/Scope/NodeScope.php [new file with mode: 0644]
vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Hook/Scope/TermScope [new file with mode: 0644]
vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Hook/Scope/TermScope.php [new file with mode: 0644]
vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Hook/Scope/UserScope.php [new file with mode: 0644]
vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Listener/DriverListener.php [new file with mode: 0644]
vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Selector/RegionSelector.php [new file with mode: 0644]
vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/ServiceContainer/DrupalExtension.php [new file with mode: 0644]
vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/ServiceContainer/config/drivers/blackbox.yml [new file with mode: 0644]
vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/ServiceContainer/config/drivers/drupal.yml [new file with mode: 0644]
vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/ServiceContainer/config/drivers/drush.yml [new file with mode: 0644]
vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/ServiceContainer/config/services.yml [new file with mode: 0644]
vendor/instaclick/php-webdriver/.coveralls.yml [new file with mode: 0644]
vendor/instaclick/php-webdriver/.gitignore [new file with mode: 0644]
vendor/instaclick/php-webdriver/.travis.yml [new file with mode: 0644]
vendor/instaclick/php-webdriver/README.md [new file with mode: 0644]
vendor/instaclick/php-webdriver/composer.json [new file with mode: 0644]
vendor/instaclick/php-webdriver/doc/README.md [new file with mode: 0644]
vendor/instaclick/php-webdriver/lib/WebDriver/AbstractWebDriver.php [new file with mode: 0644]
vendor/instaclick/php-webdriver/lib/WebDriver/AppCacheStatus.php [new file with mode: 0644]
vendor/instaclick/php-webdriver/lib/WebDriver/ApplicationCache.php [new file with mode: 0644]
vendor/instaclick/php-webdriver/lib/WebDriver/Browser.php [new file with mode: 0644]
vendor/instaclick/php-webdriver/lib/WebDriver/Capability.php [new file with mode: 0644]
vendor/instaclick/php-webdriver/lib/WebDriver/ClassLoader.php [new file with mode: 0644]
vendor/instaclick/php-webdriver/lib/WebDriver/Container.php [new file with mode: 0644]
vendor/instaclick/php-webdriver/lib/WebDriver/Element.php [new file with mode: 0644]
vendor/instaclick/php-webdriver/lib/WebDriver/Exception.php [new file with mode: 0644]
vendor/instaclick/php-webdriver/lib/WebDriver/Exception/CurlExec.php [new file with mode: 0644]
vendor/instaclick/php-webdriver/lib/WebDriver/Exception/ElementIsNotSelectable.php [new file with mode: 0644]
vendor/instaclick/php-webdriver/lib/WebDriver/Exception/ElementNotVisible.php [new file with mode: 0644]
vendor/instaclick/php-webdriver/lib/WebDriver/Exception/IMEEngineActivationFailed.php [new file with mode: 0644]
vendor/instaclick/php-webdriver/lib/WebDriver/Exception/IMENotAvailable.php [new file with mode: 0644]
vendor/instaclick/php-webdriver/lib/WebDriver/Exception/InvalidCookieDomain.php [new file with mode: 0644]
vendor/instaclick/php-webdriver/lib/WebDriver/Exception/InvalidElementCoordinates.php [new file with mode: 0644]
vendor/instaclick/php-webdriver/lib/WebDriver/Exception/InvalidElementState.php [new file with mode: 0644]
vendor/instaclick/php-webdriver/lib/WebDriver/Exception/InvalidRequest.php [new file with mode: 0644]
vendor/instaclick/php-webdriver/lib/WebDriver/Exception/InvalidSelector.php [new file with mode: 0644]
vendor/instaclick/php-webdriver/lib/WebDriver/Exception/JavaScriptError.php [new file with mode: 0644]
vendor/instaclick/php-webdriver/lib/WebDriver/Exception/JsonParameterExpected.php [new file with mode: 0644]
vendor/instaclick/php-webdriver/lib/WebDriver/Exception/MoveTargetOutOfBounds.php [new file with mode: 0644]
vendor/instaclick/php-webdriver/lib/WebDriver/Exception/NoAlertOpenError.php [new file with mode: 0644]
vendor/instaclick/php-webdriver/lib/WebDriver/Exception/NoParametersExpected.php [new file with mode: 0644]
vendor/instaclick/php-webdriver/lib/WebDriver/Exception/NoSuchDriver.php [new file with mode: 0644]
vendor/instaclick/php-webdriver/lib/WebDriver/Exception/NoSuchElement.php [new file with mode: 0644]
vendor/instaclick/php-webdriver/lib/WebDriver/Exception/NoSuchFrame.php [new file with mode: 0644]
vendor/instaclick/php-webdriver/lib/WebDriver/Exception/NoSuchWindow.php [new file with mode: 0644]
vendor/instaclick/php-webdriver/lib/WebDriver/Exception/ObsoleteCommand.php [new file with mode: 0644]
vendor/instaclick/php-webdriver/lib/WebDriver/Exception/ScriptTimeout.php [new file with mode: 0644]
vendor/instaclick/php-webdriver/lib/WebDriver/Exception/SessionNotCreated.php [new file with mode: 0644]
vendor/instaclick/php-webdriver/lib/WebDriver/Exception/StaleElementReference.php [new file with mode: 0644]
vendor/instaclick/php-webdriver/lib/WebDriver/Exception/Timeout.php [new file with mode: 0644]
vendor/instaclick/php-webdriver/lib/WebDriver/Exception/UnableToSetCookie.php [new file with mode: 0644]
vendor/instaclick/php-webdriver/lib/WebDriver/Exception/UnexpectedAlertOpen.php [new file with mode: 0644]
vendor/instaclick/php-webdriver/lib/WebDriver/Exception/UnexpectedParameters.php [new file with mode: 0644]
vendor/instaclick/php-webdriver/lib/WebDriver/Exception/UnknownCommand.php [new file with mode: 0644]
vendor/instaclick/php-webdriver/lib/WebDriver/Exception/UnknownError.php [new file with mode: 0644]
vendor/instaclick/php-webdriver/lib/WebDriver/Exception/UnknownLocatorStrategy.php [new file with mode: 0644]
vendor/instaclick/php-webdriver/lib/WebDriver/Exception/XPathLookupError.php [new file with mode: 0644]
vendor/instaclick/php-webdriver/lib/WebDriver/Frame.php [new file with mode: 0644]
vendor/instaclick/php-webdriver/lib/WebDriver/Ime.php [new file with mode: 0644]
vendor/instaclick/php-webdriver/lib/WebDriver/Key.php [new file with mode: 0644]
vendor/instaclick/php-webdriver/lib/WebDriver/LocatorStrategy.php [new file with mode: 0644]
vendor/instaclick/php-webdriver/lib/WebDriver/Log.php [new file with mode: 0644]
vendor/instaclick/php-webdriver/lib/WebDriver/LogType.php [new file with mode: 0644]
vendor/instaclick/php-webdriver/lib/WebDriver/SauceLabs/Capability.php [new file with mode: 0644]
vendor/instaclick/php-webdriver/lib/WebDriver/SauceLabs/SauceRest.php [new file with mode: 0644]
vendor/instaclick/php-webdriver/lib/WebDriver/Service/CurlService.php [new file with mode: 0755]
vendor/instaclick/php-webdriver/lib/WebDriver/Service/CurlServiceInterface.php [new file with mode: 0755]
vendor/instaclick/php-webdriver/lib/WebDriver/ServiceFactory.php [new file with mode: 0755]
vendor/instaclick/php-webdriver/lib/WebDriver/Session.php [new file with mode: 0644]
vendor/instaclick/php-webdriver/lib/WebDriver/Storage.php [new file with mode: 0644]
vendor/instaclick/php-webdriver/lib/WebDriver/Timeouts.php [new file with mode: 0644]
vendor/instaclick/php-webdriver/lib/WebDriver/Touch.php [new file with mode: 0644]
vendor/instaclick/php-webdriver/lib/WebDriver/WebDriver.php [new file with mode: 0644]
vendor/instaclick/php-webdriver/lib/WebDriver/WebDriverInterface.php [new file with mode: 0644]
vendor/instaclick/php-webdriver/lib/WebDriver/Window.php [new file with mode: 0644]
vendor/instaclick/php-webdriver/phpdoc.dist.xml [new file with mode: 0644]
vendor/instaclick/php-webdriver/phpunit.xml.dist [new file with mode: 0644]
vendor/instaclick/php-webdriver/test/Assets/index.html [new file with mode: 0644]
vendor/instaclick/php-webdriver/test/CI/Travis/setup_apache.sh [new file with mode: 0644]
vendor/instaclick/php-webdriver/test/CI/Travis/setup_selenium.sh [new file with mode: 0644]
vendor/instaclick/php-webdriver/test/Test/WebDriver/ExceptionTest.php [new file with mode: 0644]
vendor/instaclick/php-webdriver/test/Test/WebDriver/StorageTest.php [new file with mode: 0644]
vendor/instaclick/php-webdriver/test/Test/WebDriver/WebDriverTest.php [new file with mode: 0644]
vendor/psr/container/.gitignore [new file with mode: 0644]
vendor/psr/container/LICENSE [new file with mode: 0644]
vendor/psr/container/README.md [new file with mode: 0644]
vendor/psr/container/composer.json [new file with mode: 0644]
vendor/psr/container/src/ContainerExceptionInterface.php [new file with mode: 0644]
vendor/psr/container/src/ContainerInterface.php [new file with mode: 0644]
vendor/psr/container/src/NotFoundExceptionInterface.php [new file with mode: 0644]
web/modules/contrib/permissions_by_term/.gitignore
web/modules/contrib/permissions_by_term/README.md [new file with mode: 0755]
web/modules/contrib/permissions_by_term/README.txt [deleted file]
web/modules/contrib/permissions_by_term/composer.json [new file with mode: 0644]
web/modules/contrib/permissions_by_term/config/install/permissions_by_term.settings.single_term_permission.yml [new file with mode: 0644]
web/modules/contrib/permissions_by_term/config/schema/permissions_by_term.schema.yml [new file with mode: 0644]
web/modules/contrib/permissions_by_term/js/README.md [new file with mode: 0644]
web/modules/contrib/permissions_by_term/js/node-form.js [new file with mode: 0644]
web/modules/contrib/permissions_by_term/js/node-form.prototype.js [new file with mode: 0644]
web/modules/contrib/permissions_by_term/js/package.json [new file with mode: 0644]
web/modules/contrib/permissions_by_term/js/spec/node-form.spec.js [new file with mode: 0644]
web/modules/contrib/permissions_by_term/js/spec/support/jasmine.json [new file with mode: 0644]
web/modules/contrib/permissions_by_term/js/yarn.lock [new file with mode: 0644]
web/modules/contrib/permissions_by_term/modules/permissions_by_entity/LICENSE.txt [new file with mode: 0644]
web/modules/contrib/permissions_by_term/modules/permissions_by_entity/README.txt [new file with mode: 0644]
web/modules/contrib/permissions_by_term/modules/permissions_by_entity/permissions_by_entity.info.yml [new file with mode: 0644]
web/modules/contrib/permissions_by_term/modules/permissions_by_entity/permissions_by_entity.services.yml [new file with mode: 0644]
web/modules/contrib/permissions_by_term/modules/permissions_by_entity/src/Event/EntityFieldValueAccessDeniedEvent.php [new file with mode: 0644]
web/modules/contrib/permissions_by_term/modules/permissions_by_entity/src/Event/PermissionsByEntityEvents.php [new file with mode: 0644]
web/modules/contrib/permissions_by_term/modules/permissions_by_entity/src/EventSubscriber/PermissionsByEntityKernelEventSubscriber.php [new file with mode: 0644]
web/modules/contrib/permissions_by_term/modules/permissions_by_entity/src/EventSubscriber/RemoveEntityFromViewEventSubscriber.php [new file with mode: 0644]
web/modules/contrib/permissions_by_term/modules/permissions_by_entity/src/Service/AccessChecker.php [new file with mode: 0644]
web/modules/contrib/permissions_by_term/modules/permissions_by_entity/src/Service/AccessCheckerInterface.php [new file with mode: 0644]
web/modules/contrib/permissions_by_term/modules/permissions_by_entity/src/Service/CheckedEntityCache.php [new file with mode: 0644]
web/modules/contrib/permissions_by_term/permissions_by_term.info.yml
web/modules/contrib/permissions_by_term/permissions_by_term.install
web/modules/contrib/permissions_by_term/permissions_by_term.libraries.yml [new file with mode: 0644]
web/modules/contrib/permissions_by_term/permissions_by_term.links.menu.yml [new file with mode: 0644]
web/modules/contrib/permissions_by_term/permissions_by_term.module
web/modules/contrib/permissions_by_term/permissions_by_term.permissions.yml
web/modules/contrib/permissions_by_term/permissions_by_term.routing.yml
web/modules/contrib/permissions_by_term/permissions_by_term.services.yml
web/modules/contrib/permissions_by_term/phpunit.xml [deleted file]
web/modules/contrib/permissions_by_term/src/AccessCheck.php [deleted file]
web/modules/contrib/permissions_by_term/src/AccessCheckInterface.php [deleted file]
web/modules/contrib/permissions_by_term/src/AccessStorageInterface.php [deleted file]
web/modules/contrib/permissions_by_term/src/Controller/NodeEntityBundleController.php [new file with mode: 0644]
web/modules/contrib/permissions_by_term/src/Controller/PermissionsByTermController.php
web/modules/contrib/permissions_by_term/src/Entity/Config/Settings.php [new file with mode: 0644]
web/modules/contrib/permissions_by_term/src/Event/PermissionsByTermDeniedEvent.php [new file with mode: 0644]
web/modules/contrib/permissions_by_term/src/Form/SettingsForm.php [new file with mode: 0644]
web/modules/contrib/permissions_by_term/src/Listener/KernelEventListener.php [moved from web/modules/contrib/permissions_by_term/src/KernelEventListener.php with 79% similarity]
web/modules/contrib/permissions_by_term/src/Plugin/views/filter/PermissionsByTerm.php [deleted file]
web/modules/contrib/permissions_by_term/src/Service/AccessCheck.php [new file with mode: 0644]
web/modules/contrib/permissions_by_term/src/Service/AccessStorage.php [moved from web/modules/contrib/permissions_by_term/src/AccessStorage.php with 59% similarity]
web/modules/contrib/permissions_by_term/src/Service/NodeAccess.php [moved from web/modules/contrib/permissions_by_term/src/NodeAccess.php with 50% similarity]
web/modules/contrib/permissions_by_term/src/Service/NodeEntityBundleInfo.php [new file with mode: 0644]
web/modules/contrib/permissions_by_term/src/Service/Term.php [new file with mode: 0644]
web/modules/contrib/permissions_by_term/src/View/node-details.html.twig [new file with mode: 0644]
web/modules/contrib/permissions_by_term/tests/bootstrap.php [deleted file]
web/modules/contrib/permissions_by_term/tests/build.xml.example [deleted file]
web/modules/contrib/permissions_by_term/tests/phpunit.xml.dist [new file with mode: 0644]
web/modules/contrib/permissions_by_term/tests/src/Behat/Context/PermissionsByTermContext.php [new file with mode: 0644]
web/modules/contrib/permissions_by_term/tests/src/Behat/Features/access.feature [new file with mode: 0644]
web/modules/contrib/permissions_by_term/tests/src/Behat/Features/entityMetaInfo.feature [new file with mode: 0644]
web/modules/contrib/permissions_by_term/tests/src/Behat/behat.yml.dist [new file with mode: 0644]
web/modules/contrib/permissions_by_term/tests/src/Behat/composer.json [new file with mode: 0644]
web/modules/contrib/permissions_by_term/tests/src/Behat/fixtures/db.sqlite [new file with mode: 0755]
web/modules/contrib/permissions_by_term/tests/src/Kernel/AccessCheckTest.php [new file with mode: 0644]
web/modules/contrib/permissions_by_term/tests/src/Kernel/NodeEntityBundleInfoTest.php [new file with mode: 0644]
web/modules/contrib/permissions_by_term/tests/src/Kernel/PBTKernelTestBase.php [new file with mode: 0644]
web/modules/contrib/permissions_by_term/tests/src/Unit/Base.php [deleted file]
web/modules/contrib/permissions_by_term/tests/src/Unit/NodeAccessTest.php [deleted file]
web/modules/contrib/permissions_by_term/tests/src/Unit/README.md [new file with mode: 0644]

index ec4a0f43c64311cbe478be938e746ee3c169ea36..1e3d12385ab408e03d669f4d6e587093867328ef 100644 (file)
             ],
             "time": "2017-04-11T20:03:41+00:00"
         },
+        {
+            "name": "behat/behat",
+            "version": "v3.4.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/Behat/Behat.git",
+                "reference": "cb51d4b0b11ea6d3897f3589a871a63a33632692"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/Behat/Behat/zipball/cb51d4b0b11ea6d3897f3589a871a63a33632692",
+                "reference": "cb51d4b0b11ea6d3897f3589a871a63a33632692",
+                "shasum": ""
+            },
+            "require": {
+                "behat/gherkin": "^4.5.1",
+                "behat/transliterator": "^1.2",
+                "container-interop/container-interop": "^1.2",
+                "ext-mbstring": "*",
+                "php": ">=5.3.3",
+                "psr/container": "^1.0",
+                "symfony/class-loader": "~2.1||~3.0",
+                "symfony/config": "~2.3||~3.0",
+                "symfony/console": "~2.5||~3.0",
+                "symfony/dependency-injection": "~2.1||~3.0",
+                "symfony/event-dispatcher": "~2.1||~3.0",
+                "symfony/translation": "~2.3||~3.0",
+                "symfony/yaml": "~2.1||~3.0"
+            },
+            "require-dev": {
+                "herrera-io/box": "~1.6.1",
+                "phpunit/phpunit": "~4.5",
+                "symfony/process": "~2.5|~3.0"
+            },
+            "suggest": {
+                "behat/mink-extension": "for integration with Mink testing framework",
+                "behat/symfony2-extension": "for integration with Symfony2 web framework",
+                "behat/yii-extension": "for integration with Yii web framework"
+            },
+            "bin": [
+                "bin/behat"
+            ],
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "3.2.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-0": {
+                    "Behat\\Behat": "src/",
+                    "Behat\\Testwork": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Konstantin Kudryashov",
+                    "email": "ever.zet@gmail.com",
+                    "homepage": "http://everzet.com"
+                }
+            ],
+            "description": "Scenario-oriented BDD framework for PHP 5.3",
+            "homepage": "http://behat.org/",
+            "keywords": [
+                "Agile",
+                "BDD",
+                "ScenarioBDD",
+                "Scrum",
+                "StoryBDD",
+                "User story",
+                "business",
+                "development",
+                "documentation",
+                "examples",
+                "symfony",
+                "testing"
+            ],
+            "time": "2017-09-18T11:10:28+00:00"
+        },
+        {
+            "name": "behat/gherkin",
+            "version": "v4.5.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/Behat/Gherkin.git",
+                "reference": "74ac03d52c5e23ad8abd5c5cce4ab0e8dc1b530a"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/Behat/Gherkin/zipball/74ac03d52c5e23ad8abd5c5cce4ab0e8dc1b530a",
+                "reference": "74ac03d52c5e23ad8abd5c5cce4ab0e8dc1b530a",
+                "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": "2017-08-30T11:04:43+00:00"
+        },
+        {
+            "name": "behat/mink",
+            "version": "v1.7.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/minkphp/Mink.git",
+                "reference": "e6930b9c74693dff7f4e58577e1b1743399f3ff9"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/minkphp/Mink/zipball/e6930b9c74693dff7f4e58577e1b1743399f3ff9",
+                "reference": "e6930b9c74693dff7f4e58577e1b1743399f3ff9",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.1",
+                "symfony/css-selector": "~2.1|~3.0"
+            },
+            "require-dev": {
+                "symfony/phpunit-bridge": "~2.7|~3.0"
+            },
+            "suggest": {
+                "behat/mink-browserkit-driver": "extremely fast headless driver for Symfony\\Kernel-based apps (Sf2, Silex)",
+                "behat/mink-goutte-driver": "fast headless driver for any app without JS emulation",
+                "behat/mink-selenium2-driver": "slow, but JS-enabled driver for any app (requires Selenium2)",
+                "behat/mink-zombie-driver": "fast and JS-enabled headless driver for any app (requires node.js)"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.7.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Behat\\Mink\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Konstantin Kudryashov",
+                    "email": "ever.zet@gmail.com",
+                    "homepage": "http://everzet.com"
+                }
+            ],
+            "description": "Browser controller/emulator abstraction for PHP",
+            "homepage": "http://mink.behat.org/",
+            "keywords": [
+                "browser",
+                "testing",
+                "web"
+            ],
+            "time": "2016-03-05T08:26:18+00:00"
+        },
+        {
+            "name": "behat/mink-browserkit-driver",
+            "version": "v1.3.2",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/minkphp/MinkBrowserKitDriver.git",
+                "reference": "10e67fb4a295efcd62ea0bf16025a85ea19534fb"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/minkphp/MinkBrowserKitDriver/zipball/10e67fb4a295efcd62ea0bf16025a85ea19534fb",
+                "reference": "10e67fb4a295efcd62ea0bf16025a85ea19534fb",
+                "shasum": ""
+            },
+            "require": {
+                "behat/mink": "^1.7.1@dev",
+                "php": ">=5.3.6",
+                "symfony/browser-kit": "~2.3|~3.0",
+                "symfony/dom-crawler": "~2.3|~3.0"
+            },
+            "require-dev": {
+                "silex/silex": "~1.2",
+                "symfony/phpunit-bridge": "~2.7|~3.0"
+            },
+            "type": "mink-driver",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.3.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Behat\\Mink\\Driver\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Konstantin Kudryashov",
+                    "email": "ever.zet@gmail.com",
+                    "homepage": "http://everzet.com"
+                }
+            ],
+            "description": "Symfony2 BrowserKit driver for Mink framework",
+            "homepage": "http://mink.behat.org/",
+            "keywords": [
+                "Mink",
+                "Symfony2",
+                "browser",
+                "testing"
+            ],
+            "time": "2016-03-05T08:59:47+00:00"
+        },
+        {
+            "name": "behat/mink-extension",
+            "version": "v2.2",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/Behat/MinkExtension.git",
+                "reference": "5b4bda64ff456104564317e212c823e45cad9d59"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/Behat/MinkExtension/zipball/5b4bda64ff456104564317e212c823e45cad9d59",
+                "reference": "5b4bda64ff456104564317e212c823e45cad9d59",
+                "shasum": ""
+            },
+            "require": {
+                "behat/behat": "~3.0,>=3.0.5",
+                "behat/mink": "~1.5",
+                "php": ">=5.3.2",
+                "symfony/config": "~2.2|~3.0"
+            },
+            "require-dev": {
+                "behat/mink-goutte-driver": "~1.1",
+                "phpspec/phpspec": "~2.0"
+            },
+            "type": "behat-extension",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.1.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-0": {
+                    "Behat\\MinkExtension": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Christophe Coevoet",
+                    "email": "stof@notk.org"
+                },
+                {
+                    "name": "Konstantin Kudryashov",
+                    "email": "ever.zet@gmail.com"
+                }
+            ],
+            "description": "Mink extension for Behat",
+            "homepage": "http://extensions.behat.org/mink",
+            "keywords": [
+                "browser",
+                "gui",
+                "test",
+                "web"
+            ],
+            "time": "2016-02-15T07:55:18+00:00"
+        },
+        {
+            "name": "behat/mink-goutte-driver",
+            "version": "v1.2.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/minkphp/MinkGoutteDriver.git",
+                "reference": "8b9ad6d2d95bc70b840d15323365f52fcdaea6ca"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/minkphp/MinkGoutteDriver/zipball/8b9ad6d2d95bc70b840d15323365f52fcdaea6ca",
+                "reference": "8b9ad6d2d95bc70b840d15323365f52fcdaea6ca",
+                "shasum": ""
+            },
+            "require": {
+                "behat/mink": "~1.6@dev",
+                "behat/mink-browserkit-driver": "~1.2@dev",
+                "fabpot/goutte": "~1.0.4|~2.0|~3.1",
+                "php": ">=5.3.1"
+            },
+            "require-dev": {
+                "symfony/phpunit-bridge": "~2.7|~3.0"
+            },
+            "type": "mink-driver",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.2.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Behat\\Mink\\Driver\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Konstantin Kudryashov",
+                    "email": "ever.zet@gmail.com",
+                    "homepage": "http://everzet.com"
+                }
+            ],
+            "description": "Goutte driver for Mink framework",
+            "homepage": "http://mink.behat.org/",
+            "keywords": [
+                "browser",
+                "goutte",
+                "headless",
+                "testing"
+            ],
+            "time": "2016-03-05T09:04:22+00:00"
+        },
+        {
+            "name": "behat/mink-selenium2-driver",
+            "version": "v1.3.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/minkphp/MinkSelenium2Driver.git",
+                "reference": "473a9f3ebe0c134ee1e623ce8a9c852832020288"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/minkphp/MinkSelenium2Driver/zipball/473a9f3ebe0c134ee1e623ce8a9c852832020288",
+                "reference": "473a9f3ebe0c134ee1e623ce8a9c852832020288",
+                "shasum": ""
+            },
+            "require": {
+                "behat/mink": "~1.7@dev",
+                "instaclick/php-webdriver": "~1.1",
+                "php": ">=5.3.1"
+            },
+            "require-dev": {
+                "symfony/phpunit-bridge": "~2.7"
+            },
+            "type": "mink-driver",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.3.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Behat\\Mink\\Driver\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Konstantin Kudryashov",
+                    "email": "ever.zet@gmail.com",
+                    "homepage": "http://everzet.com"
+                },
+                {
+                    "name": "Pete Otaqui",
+                    "email": "pete@otaqui.com",
+                    "homepage": "https://github.com/pete-otaqui"
+                }
+            ],
+            "description": "Selenium2 (WebDriver) driver for Mink framework",
+            "homepage": "http://mink.behat.org/",
+            "keywords": [
+                "ajax",
+                "browser",
+                "javascript",
+                "selenium",
+                "testing",
+                "webdriver"
+            ],
+            "time": "2016-03-05T09:10:18+00:00"
+        },
+        {
+            "name": "behat/transliterator",
+            "version": "v1.2.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/Behat/Transliterator.git",
+                "reference": "826ce7e9c2a6664c0d1f381cbb38b1fb80a7ee2c"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/Behat/Transliterator/zipball/826ce7e9c2a6664c0d1f381cbb38b1fb80a7ee2c",
+                "reference": "826ce7e9c2a6664c0d1f381cbb38b1fb80a7ee2c",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.3"
+            },
+            "require-dev": {
+                "chuyskywalker/rolling-curl": "^3.1",
+                "php-yaoi/php-yaoi": "^1.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.2-dev"
+                }
+            },
+            "autoload": {
+                "psr-0": {
+                    "Behat\\Transliterator": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "Artistic-1.0"
+            ],
+            "description": "String transliterator",
+            "keywords": [
+                "i18n",
+                "slug",
+                "transliterator"
+            ],
+            "time": "2017-04-04T11:38:05+00:00"
+        },
         {
             "name": "caxy/php-htmldiff",
             "version": "v0.1.5",
             "description": "Format text by applying transformations provided by plug-in formatters.",
             "time": "2017-06-06T19:08:54+00:00"
         },
+        {
+            "name": "container-interop/container-interop",
+            "version": "1.2.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/container-interop/container-interop.git",
+                "reference": "79cbf1341c22ec75643d841642dd5d6acd83bdb8"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/container-interop/container-interop/zipball/79cbf1341c22ec75643d841642dd5d6acd83bdb8",
+                "reference": "79cbf1341c22ec75643d841642dd5d6acd83bdb8",
+                "shasum": ""
+            },
+            "require": {
+                "psr/container": "^1.0"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Interop\\Container\\": "src/Interop/Container/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "description": "Promoting the interoperability of container objects (DIC, SL, etc.)",
+            "homepage": "https://github.com/container-interop/container-interop",
+            "time": "2017-02-14T19:40:03+00:00"
+        },
         {
             "name": "cweagans/composer-patches",
             "version": "1.6.1",
                 "source": "https://cgit.drupalcode.org/advanced_help",
                 "issues": "https://www.drupal.org/project/issues/advanced_help",
                 "irc": "irc://irc.freenode.org/drupal-contribute"
-            }
+            },
+            "time": "2017-03-31T05:17:03+00:00"
         },
         {
             "name": "drupal/better_formats",
                 "source": "http://cgit.drupalcode.org/dropzonejs"
             }
         },
+        {
+            "name": "drupal/drupal-driver",
+            "version": "v1.2.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/jhedstrom/DrupalDriver.git",
+                "reference": "125d39918c97f7a08e3110d456a0a1db864dae46"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/jhedstrom/DrupalDriver/zipball/125d39918c97f7a08e3110d456a0a1db864dae46",
+                "reference": "125d39918c97f7a08e3110d456a0a1db864dae46",
+                "shasum": ""
+            },
+            "require": {
+                "symfony/dependency-injection": "~2.6|~3.0",
+                "symfony/process": "~2.5|~3.0"
+            },
+            "require-dev": {
+                "drupal/coder": "~8.2.0",
+                "drush-ops/behat-drush-endpoint": "*",
+                "mockery/mockery": "0.9.4",
+                "phpspec/phpspec": "~2.0",
+                "phpunit/phpunit": "~4.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.2.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-0": {
+                    "Drupal\\Component": "src/",
+                    "Drupal\\Driver": "src/",
+                    "Drupal\\Tests\\Driver": "tests/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "GPL-2.0+"
+            ],
+            "authors": [
+                {
+                    "name": "Jonathan Hedstrom",
+                    "email": "jhedstrom@gmail.com"
+                }
+            ],
+            "description": "A collection of reusable Drupal drivers",
+            "homepage": "http://github.com/jhedstrom/DrupalDriver",
+            "keywords": [
+                "drupal",
+                "test",
+                "web"
+            ],
+            "time": "2016-06-20T16:29:51+00:00"
+        },
+        {
+            "name": "drupal/drupal-extension",
+            "version": "v3.3.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/jhedstrom/drupalextension.git",
+                "reference": "2a858760208856391f7e5e4d269fba2c1df110a4"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/jhedstrom/drupalextension/zipball/2a858760208856391f7e5e4d269fba2c1df110a4",
+                "reference": "2a858760208856391f7e5e4d269fba2c1df110a4",
+                "shasum": ""
+            },
+            "require": {
+                "behat/behat": "~3.2",
+                "behat/mink": "~1.5",
+                "behat/mink-extension": "~2.0",
+                "behat/mink-goutte-driver": "~1.0",
+                "behat/mink-selenium2-driver": "~1.1",
+                "drupal/drupal-driver": "~1.2",
+                "symfony/dependency-injection": "~2.7|~3.0",
+                "symfony/event-dispatcher": "~2.7|~3.0"
+            },
+            "require-dev": {
+                "behat/mink-zombie-driver": "^1.2",
+                "phpspec/phpspec": "~2.0",
+                "phpunit/phpunit": "3.7.*"
+            },
+            "type": "behat-extension",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "3.2.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-0": {
+                    "Drupal\\Drupal": "src/",
+                    "Drupal\\Exception": "src/",
+                    "Drupal\\DrupalExtension": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "GPL-2.0+"
+            ],
+            "authors": [
+                {
+                    "name": "Jonathan Hedstrom",
+                    "email": "jhedstrom@gmail.com"
+                }
+            ],
+            "description": "Drupal extension for Behat",
+            "homepage": "http://drupal.org/project/drupalextension",
+            "keywords": [
+                "drupal",
+                "test",
+                "web"
+            ],
+            "time": "2017-09-13T19:54:23+00:00"
+        },
         {
             "name": "drupal/drupalmoduleupgrader",
             "version": "dev-1.x",
         },
         {
             "name": "drupal/permissions_by_term",
-            "version": "1.19.0",
+            "version": "1.35.0",
             "source": {
                 "type": "git",
                 "url": "https://git.drupal.org/project/permissions_by_term",
-                "reference": "8.x-1.19"
+                "reference": "8.x-1.35"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://ftp.drupal.org/files/projects/permissions_by_term-8.x-1.19.zip",
-                "reference": "8.x-1.19",
-                "shasum": "87ecf60dda39138f648ee57fe4e3ce334b187100"
+                "url": "https://ftp.drupal.org/files/projects/permissions_by_term-8.x-1.35.zip",
+                "reference": "8.x-1.35",
+                "shasum": "4f9a7406a81a2e03f90e278fd6921f8fc962f07b"
             },
             "require": {
-                "drupal/core": "*"
+                "behat/behat": "^3.1",
+                "behat/mink": "^1.7",
+                "behat/mink-extension": "^2.2",
+                "behat/mink-goutte-driver": "^1.2",
+                "behat/mink-selenium2-driver": "^1.3",
+                "drupal/core": "*",
+                "drupal/drupal-driver": "~1.0",
+                "drupal/drupal-extension": "~3.0",
+                "guzzlehttp/guzzle": "^6.0@dev"
             },
             "type": "drupal-module",
             "extra": {
                     "dev-1.x": "1.x-dev"
                 },
                 "drupal": {
-                    "version": "8.x-1.19",
-                    "datestamp": "1494360188"
+                    "version": "8.x-1.35",
+                    "datestamp": "1509945000",
+                    "security-coverage": {
+                        "status": "covered",
+                        "message": "Covered by Drupal's security advisory policy"
+                    }
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "PermissionsByTerm\\": "tests/src/Behat/Context/"
                 }
             },
             "notification-url": "https://packages.drupal.org/8/downloads",
             "authors": [
                 {
                     "name": "Peter Majmesku",
-                    "homepage": "https://www.drupal.org/user/786132"
+                    "homepage": "https://www.drupal.org/user/786132",
+                    "email": "p.majmesku@gmail.com"
+                },
+                {
+                    "name": "dakku",
+                    "homepage": "https://www.drupal.org/user/97634"
+                },
+                {
+                    "name": "rackberg",
+                    "homepage": "https://www.drupal.org/user/2806873"
                 }
             ],
-            "description": "Limits the selection of specific taxonomy terms by users or roles. Prevents users to display nodes and nodes on views pages, for which which they do not have access by taxonomy term restriction.",
+            "description": "Restricts access to nodes by taxonomy terms in relation to users and their roles.",
             "homepage": "https://www.drupal.org/project/permissions_by_term",
             "support": {
                 "source": "http://cgit.drupalcode.org/permissions_by_term"
             ],
             "support": {
                 "source": "http://cgit.drupalcode.org/views_bootstrap"
-            }
+            },
+            "time": "2017-03-29T14:23:33+00:00"
         },
         {
             "name": "drupal/views_responsive_grid",
             ],
             "time": "2017-06-03T02:28:16+00:00"
         },
+        {
+            "name": "fabpot/goutte",
+            "version": "v3.2.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/FriendsOfPHP/Goutte.git",
+                "reference": "db5c28f4a010b4161d507d5304e28a7ebf211638"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/FriendsOfPHP/Goutte/zipball/db5c28f4a010b4161d507d5304e28a7ebf211638",
+                "reference": "db5c28f4a010b4161d507d5304e28a7ebf211638",
+                "shasum": ""
+            },
+            "require": {
+                "guzzlehttp/guzzle": "^6.0",
+                "php": ">=5.5.0",
+                "symfony/browser-kit": "~2.1|~3.0",
+                "symfony/css-selector": "~2.1|~3.0",
+                "symfony/dom-crawler": "~2.1|~3.0"
+            },
+            "type": "application",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "3.2-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Goutte\\": "Goutte"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Fabien Potencier",
+                    "email": "fabien@symfony.com"
+                }
+            ],
+            "description": "A simple PHP Web Scraper",
+            "homepage": "https://github.com/FriendsOfPHP/Goutte",
+            "keywords": [
+                "scraper"
+            ],
+            "time": "2017-01-03T13:21:43+00:00"
+        },
         {
             "name": "gabordemooij/redbean",
             "version": "v4.3.4",
             ],
             "time": "2017-03-20T17:10:46+00:00"
         },
+        {
+            "name": "instaclick/php-webdriver",
+            "version": "1.4.5",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/instaclick/php-webdriver.git",
+                "reference": "6fa959452e774dcaed543faad3a9d1a37d803327"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/instaclick/php-webdriver/zipball/6fa959452e774dcaed543faad3a9d1a37d803327",
+                "reference": "6fa959452e774dcaed543faad3a9d1a37d803327",
+                "shasum": ""
+            },
+            "require": {
+                "ext-curl": "*",
+                "php": ">=5.3.2"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^4.8",
+                "satooshi/php-coveralls": "^1.0||^2.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.4.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-0": {
+                    "WebDriver": "lib/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "Apache-2.0"
+            ],
+            "authors": [
+                {
+                    "name": "Justin Bishop",
+                    "email": "jubishop@gmail.com",
+                    "role": "Developer"
+                },
+                {
+                    "name": "Anthon Pang",
+                    "email": "apang@softwaredevelopment.ca",
+                    "role": "Fork Maintainer"
+                }
+            ],
+            "description": "PHP WebDriver for Selenium 2",
+            "homepage": "http://instaclick.com/",
+            "keywords": [
+                "browser",
+                "selenium",
+                "webdriver",
+                "webtest"
+            ],
+            "time": "2017-06-30T04:02:48+00:00"
+        },
         {
             "name": "ircmaxell/password-compat",
             "version": "v1.0.4",
             "keywords": [
                 "console"
             ],
-            "time": "2016-01-21T16:14:31+00:00"
+            "time": "2016-01-21T16:14:31+00:00"
+        },
+        {
+            "name": "phpdocumentor/reflection-docblock",
+            "version": "2.0.5",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
+                "reference": "e6a969a640b00d8daa3c66518b0405fb41ae0c4b"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/e6a969a640b00d8daa3c66518b0405fb41ae0c4b",
+                "reference": "e6a969a640b00d8daa3c66518b0405fb41ae0c4b",
+                "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": "2016-01-25T08:17:30+00:00"
         },
         {
-            "name": "phpdocumentor/reflection-docblock",
-            "version": "2.0.5",
+            "name": "psr/container",
+            "version": "1.0.0",
             "source": {
                 "type": "git",
-                "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
-                "reference": "e6a969a640b00d8daa3c66518b0405fb41ae0c4b"
+                "url": "https://github.com/php-fig/container.git",
+                "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/e6a969a640b00d8daa3c66518b0405fb41ae0c4b",
-                "reference": "e6a969a640b00d8daa3c66518b0405fb41ae0c4b",
+                "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
+                "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
                 "shasum": ""
             },
             "require": {
-                "php": ">=5.3.3"
-            },
-            "require-dev": {
-                "phpunit/phpunit": "~4.0"
-            },
-            "suggest": {
-                "dflydev/markdown": "~1.0",
-                "erusev/parsedown": "~1.0"
+                "php": ">=5.3.0"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "2.0.x-dev"
+                    "dev-master": "1.0.x-dev"
                 }
             },
             "autoload": {
-                "psr-0": {
-                    "phpDocumentor": [
-                        "src/"
-                    ]
+                "psr-4": {
+                    "Psr\\Container\\": "src/"
                 }
             },
             "notification-url": "https://packagist.org/downloads/",
             ],
             "authors": [
                 {
-                    "name": "Mike van Riel",
-                    "email": "mike.vanriel@naenius.com"
+                    "name": "PHP-FIG",
+                    "homepage": "http://www.php-fig.org/"
                 }
             ],
-            "time": "2016-01-25T08:17:30+00:00"
+            "description": "Common Container Interface (PHP FIG PSR-11)",
+            "homepage": "https://github.com/php-fig/container",
+            "keywords": [
+                "PSR-11",
+                "container",
+                "container-interface",
+                "container-interop",
+                "psr"
+            ],
+            "time": "2017-02-14T16:28:37+00:00"
         },
         {
             "name": "psr/http-message",
             ],
             "time": "2017-05-09T08:10:41+00:00"
         },
+        {
+            "name": "symfony/browser-kit",
+            "version": "v3.3.2",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/browser-kit.git",
+                "reference": "c2c8ceb1aa9dab9eae54e9150e6a588ce3e53be1"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/browser-kit/zipball/c2c8ceb1aa9dab9eae54e9150e6a588ce3e53be1",
+                "reference": "c2c8ceb1aa9dab9eae54e9150e6a588ce3e53be1",
+                "shasum": ""
+            },
+            "require": {
+                "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.3-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": "2017-04-12T14:14:56+00:00"
+        },
         {
             "name": "symfony/class-loader",
             "version": "v2.8.22",
             "require": {
                 "php": "^5.6 || ^7.0",
                 "zendframework/zend-escaper": "^2.5",
-                "zendframework/zend-stdlib": "^2.7 || ^3.1"
-            },
-            "require-dev": {
-                "phpunit/phpunit": "^6.0.8 || ^5.7.15",
-                "psr/http-message": "^1.0",
-                "zendframework/zend-cache": "^2.6",
-                "zendframework/zend-coding-standard": "~1.0.0",
-                "zendframework/zend-db": "^2.7",
-                "zendframework/zend-http": "^2.5.4",
-                "zendframework/zend-servicemanager": "^2.7.5 || ^3.0.3",
-                "zendframework/zend-validator": "^2.6"
-            },
-            "suggest": {
-                "psr/http-message": "PSR-7 ^1.0, if you wish to use Zend\\Feed\\Reader\\Http\\Psr7ResponseDecorator",
-                "zendframework/zend-cache": "Zend\\Cache component, for optionally caching feeds between requests",
-                "zendframework/zend-db": "Zend\\Db component, for use with PubSubHubbub",
-                "zendframework/zend-http": "Zend\\Http for PubSubHubbub, and optionally for use with Zend\\Feed\\Reader",
-                "zendframework/zend-servicemanager": "Zend\\ServiceManager component, for easily extending ExtensionManager implementations",
-                "zendframework/zend-validator": "Zend\\Validator component, for validating email addresses used in Atom feeds and entries ehen using the Writer subcomponent"
-            },
-            "type": "library",
-            "extra": {
-                "branch-alias": {
-                    "dev-master": "2.8-dev",
-                    "dev-develop": "2.9-dev"
-                }
-            },
-            "autoload": {
-                "psr-4": {
-                    "Zend\\Feed\\": "src/"
-                }
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "BSD-3-Clause"
-            ],
-            "description": "provides functionality for consuming RSS and Atom feeds",
-            "homepage": "https://github.com/zendframework/zend-feed",
-            "keywords": [
-                "feed",
-                "zf2"
-            ],
-            "time": "2017-04-01T15:03:14+00:00"
-        },
-        {
-            "name": "zendframework/zend-stdlib",
-            "version": "3.1.0",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/zendframework/zend-stdlib.git",
-                "reference": "debedcfc373a293f9250cc9aa03cf121428c8e78"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/zendframework/zend-stdlib/zipball/debedcfc373a293f9250cc9aa03cf121428c8e78",
-                "reference": "debedcfc373a293f9250cc9aa03cf121428c8e78",
-                "shasum": ""
-            },
-            "require": {
-                "php": "^5.6 || ^7.0"
-            },
-            "require-dev": {
-                "athletic/athletic": "~0.1",
-                "phpunit/phpunit": "~4.0",
-                "squizlabs/php_codesniffer": "^2.6.2"
-            },
-            "type": "library",
-            "extra": {
-                "branch-alias": {
-                    "dev-master": "3.1-dev",
-                    "dev-develop": "3.2-dev"
-                }
-            },
-            "autoload": {
-                "psr-4": {
-                    "Zend\\Stdlib\\": "src/"
-                }
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "BSD-3-Clause"
-            ],
-            "homepage": "https://github.com/zendframework/zend-stdlib",
-            "keywords": [
-                "stdlib",
-                "zf2"
-            ],
-            "time": "2016-09-13T14:38:50+00:00"
-        }
-    ],
-    "packages-dev": [
-        {
-            "name": "ajgl/breakpoint-twig-extension",
-            "version": "0.3.0",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/ajgarlag/AjglBreakpointTwigExtension.git",
-                "reference": "0dfa4f0ae3bbeb6c8036e3e6d6c204c43b090155"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/ajgarlag/AjglBreakpointTwigExtension/zipball/0dfa4f0ae3bbeb6c8036e3e6d6c204c43b090155",
-                "reference": "0dfa4f0ae3bbeb6c8036e3e6d6c204c43b090155",
-                "shasum": ""
-            },
-            "require": {
-                "php": ">=5.4.0",
-                "twig/twig": "^1.14"
-            },
-            "require-dev": {
-                "symfony/framework-bundle": "^2.3",
-                "symfony/twig-bundle": "^2.3"
-            },
-            "suggest": {
-                "ext-xdebug": "The Xdebug extension is required for the breakpoint to work",
-                "symfony/framework-bundle": "The framework bundle to integrate the extension into Symfony",
-                "symfony/twig-bundle": "The twig bundle to integrate the extension into Symfony"
-            },
-            "type": "library",
-            "extra": {
-                "branch-alias": {
-                    "dev-master": "0.4.x-dev"
-                }
-            },
-            "autoload": {
-                "psr-4": {
-                    "Ajgl\\Twig\\Extension\\": "src/"
-                }
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "MIT"
-            ],
-            "authors": [
-                {
-                    "name": "Antonio J. García Lagar",
-                    "email": "aj@garcialagar.es",
-                    "homepage": "http://aj.garcialagar.es",
-                    "role": "developer"
-                }
-            ],
-            "description": "Twig extension to set breakpoints",
-            "homepage": "https://github.com/ajgarlag/AjglBreakpointTwigExtension",
-            "keywords": [
-                "Xdebug",
-                "breakpoint",
-                "twig"
-            ],
-            "time": "2016-03-31T18:09:32+00:00"
-        },
-        {
-            "name": "behat/mink",
-            "version": "v1.7.1",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/minkphp/Mink.git",
-                "reference": "e6930b9c74693dff7f4e58577e1b1743399f3ff9"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/minkphp/Mink/zipball/e6930b9c74693dff7f4e58577e1b1743399f3ff9",
-                "reference": "e6930b9c74693dff7f4e58577e1b1743399f3ff9",
-                "shasum": ""
-            },
-            "require": {
-                "php": ">=5.3.1",
-                "symfony/css-selector": "~2.1|~3.0"
+                "zendframework/zend-stdlib": "^2.7 || ^3.1"
             },
             "require-dev": {
-                "symfony/phpunit-bridge": "~2.7|~3.0"
+                "phpunit/phpunit": "^6.0.8 || ^5.7.15",
+                "psr/http-message": "^1.0",
+                "zendframework/zend-cache": "^2.6",
+                "zendframework/zend-coding-standard": "~1.0.0",
+                "zendframework/zend-db": "^2.7",
+                "zendframework/zend-http": "^2.5.4",
+                "zendframework/zend-servicemanager": "^2.7.5 || ^3.0.3",
+                "zendframework/zend-validator": "^2.6"
             },
             "suggest": {
-                "behat/mink-browserkit-driver": "extremely fast headless driver for Symfony\\Kernel-based apps (Sf2, Silex)",
-                "behat/mink-goutte-driver": "fast headless driver for any app without JS emulation",
-                "behat/mink-selenium2-driver": "slow, but JS-enabled driver for any app (requires Selenium2)",
-                "behat/mink-zombie-driver": "fast and JS-enabled headless driver for any app (requires node.js)"
+                "psr/http-message": "PSR-7 ^1.0, if you wish to use Zend\\Feed\\Reader\\Http\\Psr7ResponseDecorator",
+                "zendframework/zend-cache": "Zend\\Cache component, for optionally caching feeds between requests",
+                "zendframework/zend-db": "Zend\\Db component, for use with PubSubHubbub",
+                "zendframework/zend-http": "Zend\\Http for PubSubHubbub, and optionally for use with Zend\\Feed\\Reader",
+                "zendframework/zend-servicemanager": "Zend\\ServiceManager component, for easily extending ExtensionManager implementations",
+                "zendframework/zend-validator": "Zend\\Validator component, for validating email addresses used in Atom feeds and entries ehen using the Writer subcomponent"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "1.7.x-dev"
+                    "dev-master": "2.8-dev",
+                    "dev-develop": "2.9-dev"
                 }
             },
             "autoload": {
                 "psr-4": {
-                    "Behat\\Mink\\": "src/"
+                    "Zend\\Feed\\": "src/"
                 }
             },
             "notification-url": "https://packagist.org/downloads/",
             "license": [
-                "MIT"
-            ],
-            "authors": [
-                {
-                    "name": "Konstantin Kudryashov",
-                    "email": "ever.zet@gmail.com",
-                    "homepage": "http://everzet.com"
-                }
+                "BSD-3-Clause"
             ],
-            "description": "Browser controller/emulator abstraction for PHP",
-            "homepage": "http://mink.behat.org/",
+            "description": "provides functionality for consuming RSS and Atom feeds",
+            "homepage": "https://github.com/zendframework/zend-feed",
             "keywords": [
-                "browser",
-                "testing",
-                "web"
+                "feed",
+                "zf2"
             ],
-            "time": "2016-03-05T08:26:18+00:00"
+            "time": "2017-04-01T15:03:14+00:00"
         },
         {
-            "name": "behat/mink-browserkit-driver",
-            "version": "v1.3.2",
+            "name": "zendframework/zend-stdlib",
+            "version": "3.1.0",
             "source": {
                 "type": "git",
-                "url": "https://github.com/minkphp/MinkBrowserKitDriver.git",
-                "reference": "10e67fb4a295efcd62ea0bf16025a85ea19534fb"
+                "url": "https://github.com/zendframework/zend-stdlib.git",
+                "reference": "debedcfc373a293f9250cc9aa03cf121428c8e78"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/minkphp/MinkBrowserKitDriver/zipball/10e67fb4a295efcd62ea0bf16025a85ea19534fb",
-                "reference": "10e67fb4a295efcd62ea0bf16025a85ea19534fb",
+                "url": "https://api.github.com/repos/zendframework/zend-stdlib/zipball/debedcfc373a293f9250cc9aa03cf121428c8e78",
+                "reference": "debedcfc373a293f9250cc9aa03cf121428c8e78",
                 "shasum": ""
             },
             "require": {
-                "behat/mink": "^1.7.1@dev",
-                "php": ">=5.3.6",
-                "symfony/browser-kit": "~2.3|~3.0",
-                "symfony/dom-crawler": "~2.3|~3.0"
+                "php": "^5.6 || ^7.0"
             },
             "require-dev": {
-                "silex/silex": "~1.2",
-                "symfony/phpunit-bridge": "~2.7|~3.0"
+                "athletic/athletic": "~0.1",
+                "phpunit/phpunit": "~4.0",
+                "squizlabs/php_codesniffer": "^2.6.2"
             },
-            "type": "mink-driver",
+            "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "1.3.x-dev"
+                    "dev-master": "3.1-dev",
+                    "dev-develop": "3.2-dev"
                 }
             },
             "autoload": {
                 "psr-4": {
-                    "Behat\\Mink\\Driver\\": "src/"
+                    "Zend\\Stdlib\\": "src/"
                 }
             },
             "notification-url": "https://packagist.org/downloads/",
             "license": [
-                "MIT"
-            ],
-            "authors": [
-                {
-                    "name": "Konstantin Kudryashov",
-                    "email": "ever.zet@gmail.com",
-                    "homepage": "http://everzet.com"
-                }
+                "BSD-3-Clause"
             ],
-            "description": "Symfony2 BrowserKit driver for Mink framework",
-            "homepage": "http://mink.behat.org/",
+            "homepage": "https://github.com/zendframework/zend-stdlib",
             "keywords": [
-                "Mink",
-                "Symfony2",
-                "browser",
-                "testing"
+                "stdlib",
+                "zf2"
             ],
-            "time": "2016-03-05T08:59:47+00:00"
-        },
+            "time": "2016-09-13T14:38:50+00:00"
+        }
+    ],
+    "packages-dev": [
         {
-            "name": "behat/mink-goutte-driver",
-            "version": "v1.2.1",
+            "name": "ajgl/breakpoint-twig-extension",
+            "version": "0.3.0",
             "source": {
                 "type": "git",
-                "url": "https://github.com/minkphp/MinkGoutteDriver.git",
-                "reference": "8b9ad6d2d95bc70b840d15323365f52fcdaea6ca"
+                "url": "https://github.com/ajgarlag/AjglBreakpointTwigExtension.git",
+                "reference": "0dfa4f0ae3bbeb6c8036e3e6d6c204c43b090155"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/minkphp/MinkGoutteDriver/zipball/8b9ad6d2d95bc70b840d15323365f52fcdaea6ca",
-                "reference": "8b9ad6d2d95bc70b840d15323365f52fcdaea6ca",
+                "url": "https://api.github.com/repos/ajgarlag/AjglBreakpointTwigExtension/zipball/0dfa4f0ae3bbeb6c8036e3e6d6c204c43b090155",
+                "reference": "0dfa4f0ae3bbeb6c8036e3e6d6c204c43b090155",
                 "shasum": ""
             },
             "require": {
-                "behat/mink": "~1.6@dev",
-                "behat/mink-browserkit-driver": "~1.2@dev",
-                "fabpot/goutte": "~1.0.4|~2.0|~3.1",
-                "php": ">=5.3.1"
+                "php": ">=5.4.0",
+                "twig/twig": "^1.14"
             },
             "require-dev": {
-                "symfony/phpunit-bridge": "~2.7|~3.0"
+                "symfony/framework-bundle": "^2.3",
+                "symfony/twig-bundle": "^2.3"
             },
-            "type": "mink-driver",
+            "suggest": {
+                "ext-xdebug": "The Xdebug extension is required for the breakpoint to work",
+                "symfony/framework-bundle": "The framework bundle to integrate the extension into Symfony",
+                "symfony/twig-bundle": "The twig bundle to integrate the extension into Symfony"
+            },
+            "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "1.2.x-dev"
+                    "dev-master": "0.4.x-dev"
                 }
             },
             "autoload": {
                 "psr-4": {
-                    "Behat\\Mink\\Driver\\": "src/"
+                    "Ajgl\\Twig\\Extension\\": "src/"
                 }
             },
             "notification-url": "https://packagist.org/downloads/",
             ],
             "authors": [
                 {
-                    "name": "Konstantin Kudryashov",
-                    "email": "ever.zet@gmail.com",
-                    "homepage": "http://everzet.com"
+                    "name": "Antonio J. García Lagar",
+                    "email": "aj@garcialagar.es",
+                    "homepage": "http://aj.garcialagar.es",
+                    "role": "developer"
                 }
             ],
-            "description": "Goutte driver for Mink framework",
-            "homepage": "http://mink.behat.org/",
+            "description": "Twig extension to set breakpoints",
+            "homepage": "https://github.com/ajgarlag/AjglBreakpointTwigExtension",
             "keywords": [
-                "browser",
-                "goutte",
-                "headless",
-                "testing"
+                "Xdebug",
+                "breakpoint",
+                "twig"
             ],
-            "time": "2016-03-05T09:04:22+00:00"
+            "time": "2016-03-31T18:09:32+00:00"
         },
         {
             "name": "doctrine/instantiator",
                 "source": "http://cgit.drupalcode.org/twig_xdebug"
             }
         },
-        {
-            "name": "fabpot/goutte",
-            "version": "v3.2.1",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/FriendsOfPHP/Goutte.git",
-                "reference": "db5c28f4a010b4161d507d5304e28a7ebf211638"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/FriendsOfPHP/Goutte/zipball/db5c28f4a010b4161d507d5304e28a7ebf211638",
-                "reference": "db5c28f4a010b4161d507d5304e28a7ebf211638",
-                "shasum": ""
-            },
-            "require": {
-                "guzzlehttp/guzzle": "^6.0",
-                "php": ">=5.5.0",
-                "symfony/browser-kit": "~2.1|~3.0",
-                "symfony/css-selector": "~2.1|~3.0",
-                "symfony/dom-crawler": "~2.1|~3.0"
-            },
-            "type": "application",
-            "extra": {
-                "branch-alias": {
-                    "dev-master": "3.2-dev"
-                }
-            },
-            "autoload": {
-                "psr-4": {
-                    "Goutte\\": "Goutte"
-                }
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "MIT"
-            ],
-            "authors": [
-                {
-                    "name": "Fabien Potencier",
-                    "email": "fabien@symfony.com"
-                }
-            ],
-            "description": "A simple PHP Web Scraper",
-            "homepage": "https://github.com/FriendsOfPHP/Goutte",
-            "keywords": [
-                "scraper"
-            ],
-            "time": "2017-01-03T13:21:43+00:00"
-        },
         {
             "name": "jcalderonzumba/gastonjs",
             "version": "v1.0.3",
             "description": "Library that helps with managing the version number of Git-hosted PHP projects",
             "homepage": "https://github.com/sebastianbergmann/version",
             "time": "2015-06-21T13:59:46+00:00"
-        },
-        {
-            "name": "symfony/browser-kit",
-            "version": "v3.3.2",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/symfony/browser-kit.git",
-                "reference": "c2c8ceb1aa9dab9eae54e9150e6a588ce3e53be1"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/symfony/browser-kit/zipball/c2c8ceb1aa9dab9eae54e9150e6a588ce3e53be1",
-                "reference": "c2c8ceb1aa9dab9eae54e9150e6a588ce3e53be1",
-                "shasum": ""
-            },
-            "require": {
-                "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.3-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": "2017-04-12T14:14:56+00:00"
         }
     ],
     "aliases": [],
diff --git a/vendor/behat/behat/CHANGELOG.md b/vendor/behat/behat/CHANGELOG.md
new file mode 100644 (file)
index 0000000..26c9c25
--- /dev/null
@@ -0,0 +1,890 @@
+# Change Log
+All notable changes to this project will be documented in this file.
+
+The format is based on [Keep a Changelog](http://keepachangelog.com/)
+and this project adheres to [Semantic Versioning](http://semver.org/).
+
+## [Unreleased]
+
+## [3.4.1] - 2017-09-18
+### Fixed
+  * PHP 5.3 style cleanup.
+
+## [3.4.0] - 2017-09-10
+### Added
+  * [#1071](https://github.com/Behat/Behat/pull/1071): Services auto-wiring
+  * [#1054](https://github.com/Behat/Behat/pull/1054): [PSR-11](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-11-container.md)
+    support for helper containers.
+  * Support for modern PHPUnit.
+
+### Fixed
+  * [#1056](https://github.com/Behat/Behat/pull/1056): Make Gherkin aware of the
+  base path so it can filter correctly
+
+### Changed
+  * [#1069](https://github.com/Behat/Behat/pull/1069): Rework argument validators
+
+### Deprecated
+  * [#1054](https://github.com/Behat/Behat/pull/1054): Deprecated usage
+    of `Interop\Container`. Versions prior to `1.2` are not supported, but `1.2`
+    is a non-breaking change. If you depend heavily on `Interop`, upgrade to
+    `1.2`, which is still supported by helper containers. Aim to migrate to
+    `Psr` before Behat 4.0 shows up on horizon
+  * PHP versions prior to 5.6 and HHVM were dropped from CI build matrix. It
+    doesn't mean that we'll start using features of 5.6 yet, it just means we
+    don't get out of our way to support 5.3 and 5.4 anymore. In 4.0 support will
+    be completely dropped.
+
+## [3.3.1] - 2017-05-15
+### Added
+  * [#976](https://github.com/Behat/Behat/pull/1001): Add tests to check that
+    snippets treat words containing apostrophes as a single word
+
+### Fixed
+  * [#993](https://github.com/Behat/Behat/pull/993) Fix mixed arguments
+    organizer not marking typehinted arguments as "defined"
+  * [#992](https://github.com/Behat/Behat/pull/993) Do not misinterpret first
+    argument as a numbered argument if it is in fact typehinted
+  * [#1028](https://github.com/Behat/Behat/pull/1028) Parent / Child class
+    argument ambiguity issue with `MixedArgumentResolver`
+
+## [3.3.0] - 2016-12-25
+### Added
+  * [#973](https://github.com/Behat/Behat/pull/974): Added helper containers
+  * [#973](https://github.com/Behat/Behat/pull/974): Added
+    `SuiteScopedResolverFactory` extension point
+
+### Removed
+  * Removed php 5.3 from the Travis build matrix. You can consider it official
+    end of support. 5.4 and 5.5 will follow shortly.
+
+## [3.2.3] - 2016-12-25
+### Fixed
+  * [#971](https://github.com/Behat/Behat/pull/971): Added support for suite
+    names with hyphens
+
+## [3.2.2] - 2016-11-05
+### Fixed
+  * [#959](https://github.com/Behat/Behat/issues/959): Fix transformations not
+    sorted properly on different php version
+
+## [3.2.1] - 2016-09-25
+### Changed
+  * [#955](https://github.com/Behat/Behat/pull/955): `--snippets-for` is not
+    required now as interactive mode is the new default
+  * [#954](https://github.com/Behat/Behat/pull/954): Stop execution on missing
+    steps when running with `--stop-on-failure` and `--strict` options
+
+## [3.2.0] - 2016-09-20
+### Added
+  * [#910](https://github.com/Behat/Behat/pull/910): Return type based
+    transformations
+  * [#903](https://github.com/Behat/Behat/pull/903): Multiline step definitions
+    support
+  * [#930](https://github.com/Behat/Behat/pull/930): Whole table transformation
+  * [#935](https://github.com/Behat/Behat/pull/935): Narrative filters in suites
+  * [#936](https://github.com/Behat/Behat/pull/936): Debug command
+  * [#931](https://github.com/Behat/Behat/pull/931): Exception handlers
+    extension point
+  * [#870](https://github.com/Behat/Behat/pull/870): Added build-related files
+    and folders to .gitattributes
+  * [#946](https://github.com/Behat/Behat/pull/946): Official full Windows
+    support with CI ([AppVeyor](http://appveyor.com)) on every build
+
+### Changed
+  * [#922](https://github.com/Behat/Behat/pull/922): Snippets generation revamp
+  * [#920](https://github.com/Behat/Behat/pull/920): More context for
+    pending/failed steps with progress formatter
+  * [#905](https://github.com/Behat/Behat/pull/905): Transformations refactoring
+  * [#864](https://github.com/Behat/Behat/pull/864): Use only one autoloader if
+    possible
+  * [#920](https://github.com/Behat/Behat/pull/920): Improve "No specifications
+    found" error message
+  * Refactor changelog to follow [Keep a Changelog](http://keepachangelog.com/)
+  * Refreshed [CONTRIBUTING.md](CONTRIBUTING.md)
+  * Refreshed Scrutinizer config
+
+### Fixed
+  * [#911](https://github.com/Behat/Behat/pull/911): Fix context isolation for
+    Scenario Outlines
+  * [#860](https://github.com/Behat/Behat/pull/860): Include basepath in
+    `generateKey`
+  * [#857](https://github.com/Behat/Behat/pull/857): Only cache failed
+    scenario's for rerun
+  * [#933](https://github.com/Behat/Behat/pull/933): Save failed runs with suite
+    information
+  * [#833](https://github.com/Behat/Behat/pull/833): Properly handle interupts
+    on PHP7
+  * [#904](https://github.com/Behat/Behat/pull/904): Provide clearer exception
+    message when long token names used
+  * [#941](https://github.com/Behat/Behat/pull/941): Transformation should be
+    allowed if printable chars are used
+
+### Deprecated
+  * [#922](https://github.com/Behat/Behat/pull/922): `*SnippetAcceptingContext`
+    interfaces
+  * [#905](https://github.com/Behat/Behat/pull/905): `RuntimeTransformation`
+  * [#905](https://github.com/Behat/Behat/pull/905): `Transformation::getPattern`
+  * [#920](https://github.com/Behat/Behat/pull/920): `StepStat`
+
+### Removed
+  * Remove behat.bat (by Konstantin Kudryashov)
+
+## [3.1.0] - 2016-03-28
+### Changed
+  * Add support for Symfony 3 (thanks @benji07)
+  * Add ability to specify execution order of suite (thanks @ciaranmcnulty)
+  * Add translated keywords in definition printer (thanks @WouterJ)
+  * Add 'rowtable' transformations (thanks @PurpleBooth)
+  * Add 'narrative' filters (thanks @WouterJ)
+  * Add JUnit formatter (thanks @WouterJ and @james75)
+  * Add Japanese translation (thanks @SNakano)
+  * Add romanian translation for formatters (thanks @Chriton)
+  * Add table row transformations (thanks @ciaranmcnulty)
+  * Add support for negative numbers without surrounding quotes (thanks
+    @ryancookdev)
+  * Handle case when non-existent config file is used (thanks @watermanio)
+  * Handle non-default `error_reporting()`
+  * Handle PHP7 errors implementing `Throwable`
+  * Fix autoloading from the global installation (thanks @sroze)
+  * Fix scenario scope naming (thanks @Taluu)
+  * Fix output buffering errors (thanks @tscheepers)
+  * Fix xdebug maximum nesting level errors (thanks @WorkingDevel)
+  * Fix weird edge case in GroupedSpecificationIterator
+  * Allow --verbose flag at CLI (thanks @pfrenssen)
+  * Allow hyphens in suite names (thanks @WouterJ)
+  * Allow suite settings with null values to exist (thanks @docteurklein)
+  * Improve "can not generate snippets" message
+  * Improve performance of Turnip parsing (thanks @Sam-Burns)
+  * Improve the snippet generation by auto-importing needed classes (thanks
+    @stof)
+
+## [3.0.15] - 2015-02-22
+### Changed
+  * Fix broken null-transformations (Issue #669)
+  * Improve exception messages (thanks @dantleech)
+
+## [3.0.14] - 2014-09-23
+### Changed
+  * Improve generated context class
+
+## [3.0.13] - 2014-08-28
+### Changed
+  * Add support for typehinted parameters
+  * Allow any whitespace characters at the end of context class
+  * Fix scenario with decimal number following string in Turnip pattern
+  * Fix scenario with empty string in step with Turnip pattern
+  * Fix scenario where step has slashes in Turnip pattern
+
+## [3.0.12] - 2014-07-17
+### Changed
+  * Fix remaining issues with the definition arguments parsing
+  * Introduce `Testwork\Argument` component
+
+## [3.0.11] - 2014-07-09
+### Changed
+  * Fix argument resolution for functions with default values (thanks @alesblaznik)
+  * Fix step colouring of internationalised definitions
+  * Refactor `ContextFactory` and `RepositorySearchEngine` arguments resolution into the new
+    Testwork component - `ArgumentResolver`
+
+## [3.0.10] - 2014-06-29
+### Changed
+  * Fix argument resolution when named arguments used and method has defaults (thanks @WouterJ)
+  * Fix support for decimal numbers in turnip placeholders
+
+## [3.0.9] - 2014-06-20
+### Changed
+  * Fix definition translations reading bug with multi-suite configurations (thanks @WouterJ for reporting)
+  * Fix pretty printer bug with failing background and 2 scenarios (thanks @andytson for reporting)
+  * Fix memory footprint calculation (thanks @dready for reporting)
+
+## [3.0.8] - 2014-06-06
+### Changed
+  * Profile level Gherkin filters are now overridable by CLI filter options
+  * Rerun cache path is now configurable
+  * Fix turnip-based step definitions starting from token
+  * Fix token-based transformations interfering with regex-based ones
+  * Rerun cache dump have been optimised
+
+## [3.0.7] - 2014-05-27
+### Changed
+  * Properly generate keywords in snippets for non-english and `And`, `But` steps (thanks @kibao)
+  * Fix regex check bug with transformations that return objects (thanks @vaidasm)
+  * Return ability to use custom formatters by specifiying their class names
+
+## [3.0.6] - 2014-05-06
+### Changed
+  * Fix a small extension registration shortcut issue introduced in previous release (thanks @FrenkyNet)
+
+## [3.0.5] - 2014-05-06
+### Changed
+  * Fix a suite initialization bug when suite contexts have arguments
+  * Fix wrong handling of an empty `behat.yml`
+  * Explicitly fail when provided context argument is not supported by constructor
+  * Fix extension registration shortcut for 3rd-part plugins
+
+## [3.0.4] - 2014-04-29
+### Changed
+  * Make sure that `Before*Tested` is always executed before `Before*` hooks
+  * Introduce additional `After*Setup` and `Before*Teardown` events
+  * Improved the error reporting for invalid regexes in step definitions (thanks @stof)
+
+## [3.0.3] - 2014-04-27
+### Changed
+  * Support definition transformations without capture groups
+  * Override gherkin filters in custom profiles instead of merging them
+  * Refactored the handling of colors to set them earlier
+    ([#513](https://github.com/Behat/Behat/pull/513) thanks to @stof)
+
+## [3.0.2] - 2014-04-26
+### Changed
+  * Fix warning on empty scenarios
+
+## [3.0.1] - 2014-04-26
+### Changed
+  * Make sure that `AfterStep` hook is running even if step is failed
+    ([504](https://github.com/Behat/Behat/issues/504))
+  * Optimised the way service wrappers are registered (thanks @stof)
+
+## [3.0.0] - 2014-04-20
+### Changed
+  * Brand new highly extendable and clear architecture
+  * Support for multiple suites per profile
+  * Support for multiple contexts per suite
+  * Support for multiple feature paths per suite
+  * Support for filtered suites
+  * Support for unique context constructor parameters
+  * Hooks are first class citizens and thus have their own error and output buffering
+  * Turnip syntax in definitions
+  * Reworked formatters with improved error and output buffering
+  * Rerun does not require precache run
+  * New gherkin role filter
+  * Improved error handling with 3 levels of error reporting (-v, -vv, -vvv)
+  * Dropped subcontexts
+  * Dropped chained steps
+  * Dropped closured definitions
+
+## 3.0.0rc3 - 2014-03-16
+### Changed
+  * Multiline step description support ([082da36b7db2525700287616babe982e485330d1](https://github.com/Behat/Behat/commit/082da36b7db2525700287616babe982e485330d1))
+  * Added ability to choose all 3 verbosity levels and moved stack traces to the 2nd one ([d550f72d6aa49f0f87a6ce0e50721356a5d04c45](https://github.com/Behat/Behat/commit/d550f72d6aa49f0f87a6ce0e50721356a5d04c45))
+  * Renamed Subject to Specification ([#447](https://github.com/Behat/Behat/pull/447))
+  * Refactored ContextSnippetGenerator ([#445](https://github.com/Behat/Behat/pull/445))
+  * Refactored context arguments handling ([#446](https://github.com/Behat/Behat/pull/446))
+  * Refactored testers to use composition over inheritance and added setUp/tearDown phase to them ([#457](https://github.com/Behat/Behat/pull/457))
+  * Refactored output formatters to be chain of event listeners
+  * Refactored hooks to use [scopes](https://github.com/Behat/Behat/tree/3.0/src/Behat/Behat/Hook/Scope) instead of events
+  * Fixed the GroupedSubjectIterator when dealing with an empty iterator ([2c1312780d610f01116ac42fb958c0c09a64c041](https://github.com/Behat/Behat/commit/2c1312780d610f01116ac42fb958c0c09a64c041))
+  * Forced the paths.base to use a real path all the time ([b## [4477d7cf3f9550874c609d4edc5a4f55390672c](https://github.com/Behat/Behat/commit/b4477d7cf3f9550874c609d4edc5a4f55390672c))
+
+3.0.0rc2] - 2014-01-10
+
+### Changed
+  * Fixed progress formatter hooks support
+  * Reintroduced suite hooks (with an additional functionality of name filtering)
+  * Behat tells about steps that it couldn't generate snippets for
+  * Memory consumption optimizations
+  * Fixed contexts inheritance
+  * New formatter translations
+
+  * Added constructor arguments and class resolving extension points to context creation routine
+  * Simplified and cleaned `Context` package of the Behat
+  * Minor public API changes across the board (simplification)
+  * Optimized subject finding routine and cleaned extension points (`SubjectLocator`)
+  * Both `ExampleTested` and `ScenarioTested` now use same method name - `getScenario()`
+  * Added exception accessors to `StepTestResult`
+  * Renamed `ExerciseTester` to `Exercise`
+  * Added `HookableEvent` to Testwork, which extends `LifecycleEvent`
+  * Made `priority` attribute of a tag optional
+  * Changed all occurrences of `classname` to `class` across public API
+  * Renamed `GherkinSuite` to `GenericSuite` and moved it into the Testwork
+  * Added `initialize` call to extension lifecycle and Extension interface
+  * Renamed some extensions config keys to be more intuitive
+
+## 3.0.0rc1 - 2014-01-01
+### Changed
+  * New layered and highly extendable architecture
+  * Standard output buffering of definitions and hooks
+  * Hooks as first class citizens
+  * New pretty and progress formatters
+  * Huge speed and memory footprint improvements
+  * Moved 40% of non-Behat related codebase into a shared foundation called Testwork
+
+## 3.0.0beta8 - 2013-10-01
+### Changed
+  * Add `*SnippetsFriendlyInterface`(s) that are now required to generate snippets
+  * Add support for turnip-style definitions
+  * Use turnip-style definitions by default from `--init`
+  * Rename `SuitesLoader` to `SuitesRegistry` to clarify purpose
+  * Extract snippet generators into extendable component
+  * Extract context generators into extendable component
+
+## 3.0.0beta7 - 2013-09-29
+### Changed
+  * Multivalue options are now array options (format, output, name and tags)
+  * Added back junit formatter (should support all junit formats from 4 to 7)
+  * Added back html formatter
+  * Small optimizations and refactorings
+  * Proper handling of hook failures
+
+## 3.0.0beta6 - 2013-09-25
+### Changed
+  * Skip step execution and `AfterStep` hook if its `BeforeStep` hook failed
+  * Fix failure-initiated skips of hooks in Scenario and Example testers
+  * Refactor Suite routines
+  * Cleanup Context Pools
+  * Enhance `--definitions` option with suites output and regex search
+  * Add `toString()` methods to `DefinitionInterface` and `TransformationInterface`
+  * Add `SnippetlessContextInterface` to `Snippet` namespace - to prevent snippet generation for
+    custom contexts
+
+## 3.0.0beta5 - 2013-09-15
+### Changed
+  * Switch to Gherkin 3.0 parser
+  * Complete rewrite of pretty formatter (much better outline handling)
+  * Automatically add `use` for `PendingException` to contexts during `--append-snippets`
+  * Lots of optimizations
+
+## 3.0.0beta4 - 2013-08-17
+### Changed
+  * Cleanup suite configuration sub-system
+  * New ability to turn off specific suites through `behat.yml`
+  * Support for danish language
+
+## 3.0.0beta3 - 2013-08-13
+### Changed
+  * Refactor extension sub-system. Update `ExtensionInterface`
+  * Avoid trying to create folders for non-fs suites
+
+## 3.0.0beta2 - 2013-08-13
+### Changed
+  * Remove support for Symfony 2.0 components
+
+## 3.0.0beta1 - 2013-08-13
+### Changed
+  * New suite-centric architecture
+  * New context pools sub-system with multi-context support
+  * New dynamic event-driven testing core
+  * Refactored console processors sub-system
+  * Refactored formatters management sub-system
+  * 8 new process extension points and 36 generic execution extension points
+  * Gherkin caching is enabled by default
+  * Rerun is enabled by default (use `--rerun` to rerun failed scenarios)
+  * New Gherkin Role filter
+  * Subcontexts removed in favor of context pools
+  * Chained steps extracted into [separate extension](https://github.com/Behat/ChainedStepsExtension)
+  * Closured step definitions removed
+
+## 2.5.0 - 2013-08-11
+### Changed
+  * First Behat LTS release
+  * Update Junit formatter to reflect latest junit format (thanks @alistairstead)
+  * Fix some container options
+
+## 2.4.6 - 2013-06-06
+### Changed
+  * New --stop-on-failure option
+  * Support JSON in environment variables
+  * Update Gherkin
+  * Support Symfony 2.3
+  * Out-of-the-box support for PHPUnit assertions pretty output
+
+## 2.4.5 - 2013-01-27
+### Changed
+  * Added wrapping of lines in progress formatter
+  * Added `--append-to` option to be able to add snippets to custom class
+  * Both `ScenarioEvent` and `OutlineExampleEvent` now extend same `BaseScenarioEvent` class
+  * Highly improved ability to create simple custom extensions
+  * Always hide stack traces for `PendingException`
+  * Ensured compatibility with all major symfony versions
+  * Fixed configs import directive and loading precedence
+  * Fixed path to vendor dir (solves problem of custom vendor dirs)
+
+## 2.4.4 - 2012-09-12
+### Changed
+  * Fixed `RuntimeException` namespacing error
+  * Added `FormatterManager::disableFormatter(s)` method
+  * Updated Gherkin parser and fixed couple of helper bugs
+
+## 2.4.3 - 2012-07-28
+### Changed
+  * Fixed broken `output_path` setting ([issue #169](https://github.com/Behat/Behat/issues/169))
+  * Added shellbang to phar executable ([issue #167](https://github.com/Behat/Behat/issues/167))
+  * Added feature title to progress exceptions ([issue #166](https://github.com/Behat/Behat/issues/166))
+  * Tuned failed formatter to print only failed examples in outline ([issue #154](https://github.com/Behat/Behat/issues/154))
+  * Small bugfixes
+
+## 2.4.2 - 2012-06-26
+### Changed
+  * Fixed broken autoloading with Composer installation
+
+## 2.4.1 - 2012-06-26
+### Changed
+  * Force custom context class usage if user changed it from `FeatureContext`
+  * Clarified `Context class not found` exception
+  * Use CWD for CLI options, basepath (config path) for everything else
+  * Pass `behat.extension.classes` container param to extensions during their load
+  * Tuned `event_subscriber` priorities
+  * Use `require_once` instead of `require` in closured loaders
+  * Fixed transformers bug with falsy transformations (that return **falsy** values)
+  * Fixed custom formatters definition bug
+  * Fixed formatter manager exception bug
+  * Fixed czech translation
+  * Fixed CS to be PSR2 compliant
+
+## 2.4.0 - 2012-05-15
+### Changed
+  * New extension system based on Symfony2 DIC component
+  * Refactored paths reading system (now relative paths are fully supported)
+  * Support latest Composer changes
+  * Removed static constraint for transformations
+  * Updated to latest Gherkin with immutable AST
+  * Fixed couple of definition snippet generator bugs
+  * Option for HTML formatter to provide step definition links
+  * Added fallback locale (in case if provided lang is unsupported yet)
+  * Print step snippets in HTML formatter only if they're enabled
+  * Escape placeholder brackets in HTML formatter
+  * Use different names for examples in JUnit formatter
+  * Major core cleanup
+
+## 2.3.5 - 2012-03-30
+### Changed
+  * Fixed formatter language configuration and locale guesser
+
+## 2.3.4 - 2012-03-28
+### Changed
+  * Added `StepEvent::getLogicalParent()`. Fixed issue ### 115
+
+2.3.3 - 2012-03-09
+
+### Changed
+  * Implemented Gherkin caching support ([--cache](https://github.com/Behat/Behat/commit/753c4f6e392a873a640543306191d92e6dc91099))
+  * Line ranges filtering support (`behat features/some.feature:12-19`. Thanks @headrevision)
+  * `behat.yml.dist` configs support out of the box
+  * Minor bug fixes
+  * Updated Gherkin
+
+## 2.3.2 - 2012-01-29
+### Changed
+  * Fixed bug in `ErrorException`, that caused wrong exceptions on warnings and notices
+
+## 2.3.1 - 2012-01-26
+### Changed
+  * Updated error handler to avoid suppressed exceptions
+  * Autoload bootstrap scripts in their name order
+  * Updated Gherkin dependency to v## 2.0.1
+
+2.3.0 - 2012-01-19
+
+### Changed
+  * Switch to the Behat\Gherkin 2.0 usage
+  * Migration to the single-file translation
+  * Support for callables inside steps chains
+  * Support for `*.yml` and `*.php` as definition translations
+  * Added opposite options to option switchers (`--[no-]colors`, `--[no-]multiline`, etc.)
+  * Redesigned `--story-syntax`
+  * Refactored Runner
+  * Performance improvements
+  * Bugfixes
+
+## 2.2.7 - 2012-01-13
+### Changed
+  * Added ability to search translated definitions with `--definitions`
+  * Fixed custom formatters use bug
+
+## 2.2.6 - 2012-01-09
+### Changed
+  * Fixed pretty and html formatters printing of undefined steps in outlines
+
+## 2.2.5 - 2012-01-07
+### Changed
+  * `BEHAT_PARAMS` env variable support (083092e)
+  * HTML formatter print styles optimization (@davedevelopment)
+
+## 2.2.4 - 2012-01-04
+### Changed
+  * Prevent method name duplication with definition snippets
+
+## 2.2.3 - 2012-01-04
+### Changed
+  * Fixed couple of `--append-snippets` bugs
+
+## 2.2.2 - 2011-12-21
+### Changed
+  * Fixed Composer deps
+
+## 2.2.1 - 2011-12-21
+### Changed
+  * Fixed Composer package bin
+
+## 2.2.0 - 2011-12-14
+### Changed
+  * Multiple formats and outputs support
+  * New `snippets` formatter
+  * New `failed` formatter
+  * Updated output of `-d` option
+  * Search abilities added to `-d` option
+  * New `--dry-run` option
+  * New `--append-snippets` option
+  * Rerun functionality refactored to use `failed` formatter internally
+  * Overall code refactoring and cleaning
+  * Polish translation added (Joseph Bielawski)
+  * Spanish translation updated (Andrés Botero)
+  * Locale autodetect
+
+## 2.1.3 - 2011-11-04
+### Changed
+  * Substep translations support
+  * Correctly print undefined substeps in pretty printer
+  * @Transform callback now gets all provided matches
+  * Always set proper encoding (UTF## 8)
+
+2.1.2 - 2011-10-12
+
+### Changed
+  * Fixed filtered feature hooks
+  * Fixed JUnit formatter time output in some locales
+
+## 2.1.1 - 2011-10-09
+### Changed
+  * Fixed multiline titles printing bug
+  * Fixed outline parameter inside step argument printing bug
+
+## 2.1.0 - 2011-09-12
+### Changed
+  * Totally revamped HTML formatter template
+  * Added transliteration support to definition snippets (for most langs)
+  * Written missed features and fixed some bugs
+  * Stabilization fixes for 3 major OS: MacOS/Ubuntu/Windows
+
+## 2.0.5 - 2011-08-07
+### Changed
+  * Cleaned ContextDispatcher extension points
+  * Cleaned context-parameters passing behavior
+
+## 2.0.4 - 2011-08-02
+### Changed
+  * Subcontexts aliasing and retrieving
+  * Multiple steps chaining
+  * `--snippets-paths` option to show steps alongside the snippets
+  * getContextParameters() method in SuiteEvent and FeatureEvent
+  * Updated to Symfony2 stable components
+  * Spanish translation
+  * Dutch translation
+
+## 2.0.3 - 2011-07-20
+### Changed
+  * Fixed JUnit formatter CDATA output
+
+## 2.0.2 - 2011-07-17
+### Changed
+  * Added extra checks to context instance mapper
+  * Fixed i18n support in definitions printer
+  * Refactored Gherkin tags inheritance
+
+## 2.0.1 - 2011-07-12
+### Changed
+  * Exception prefix added to statuses. Now you should throw `PendingException` instead of just
+    `Pending`
+
+## 2.0.0 - 2011-07-12
+### Changed
+  * Brand new Context-oriented architecture
+  * Refactored --definitions (--steps) to print more useful info
+  * Rafactored --story-syntax (--usage) to print more useful info
+  * Refactored Command to use separate processors
+  * Added --no-paths option
+  * Added --no-snippets option
+  * Added --expand option to expand outlines
+  * phar package
+  * Faster autoloader
+  * Steps chaining added
+  * Added BEHAT_ERROR_REPORTING constant to change error_repoting level
+  * Fixed some Gherkin bugs
+  * Fixed lots of bugs in Behat itself
+
+## 1.1.9 - 2011-06-17
+### Changed
+  * Updated to the latest Symfony components
+
+## 1.1.8 - 2011-06-09
+### Changed
+  * Fixed empty match printing in Pretty and HTML formatters
+  * Updated to latest Symfony components
+
+## 1.1.7 - 2011-06-03
+### Changed
+  * Fixed steps colorization bug in outline
+  * Additional checks in config import routine
+
+## 1.1.6 - 2011-05-27
+### Changed
+  * Updated Symfony vendors
+  * Refactored console formatters
+
+## 1.1.5 - 2011-05-17
+### Changed
+  * Fixed CWD path finding
+  * Fixed HTML formatter (thanks @glenjamin)
+
+## 1.1.4 - 2011-05-03
+### Changed
+  * Fixed `--out` option usage critical bug
+  * Added ability to specify `output_path` from config file
+
+## 1.1.3 - 2011-04-28
+### Changed
+  * JUnit formatter fix
+  * Formatters basePath fix. Now formatters uses CWD as path trimmer
+  * Relative paths locator bug fix
+  * Show table argument header in HTML formatter
+
+## 1.1.2 - 2011-04-27
+### Changed
+  * Fixed custom features path locator bug(issue ### 020)
+
+1.1.1 - 2011-04-21
+
+### Changed
+  * Fixed paths finding routines
+  * Totally refactored BehatCommand
+  * Added rerun functionality (`--rerun`)
+  * Ability to remove previously specified paths in `behat.yml`
+  * Bugfixes and little tweaks
+
+## 1.1.0 - 2011-04-04
+### Changed
+  * New configuration system with profiles and imports support
+  * New event system
+  * Environment parameters support
+  * Named regex arguments support
+  * Japanese translation for formatters
+  * JUnit formatter bugfixes
+  * HTML and Pretty formatters multiple arguments print bugfix
+  * Step snippets (proposals) bugfixes
+  * Updated vendor libraries
+
+## 1.0.0 - 2011-03-08
+### Changed
+  * Changed XSD
+  * Updated vendors
+
+## 1.0.0RC6 - 2011-03-03
+### Changed
+  * Cleaned command options
+  * Added --init option
+  * Multiple paths support in behat.yml
+  * Application options refactoring
+
+## 1.0.0RC5 - 2011-02-25
+### Changed
+  * Windows support
+  * Bundled features hooks optimizations
+
+## 1.0.0RC4 - 2011-02-23
+### Changed
+  * Pretty formatter tag printing fix
+  * Custom formatter specification fix in `behat.yml`
+  * Symfony components updated
+  * Extension configuration manager (Symfony\Component\Config component)
+  * Cleaning of `behat.yml` configurator (thanks to Symfony\Component\Config)
+  * Additional formatter parameters support in `behat.yml`
+
+## 1.0.0RC3 - 2011-02-18
+### Changed
+  * Event dispatcher binding optimizations
+  * Command API optimizations for easier overloading
+  * Formatter path trimming bugfix
+  * BehatExtension config merging support
+
+## 1.0.0RC2 - 2011-02-15
+### Changed
+  * Step printing option bugfix
+
+## 1.0.0RC1 - 2011-02-15
+### Changed
+  * Gherkin DSL parser is standalone project
+  * Own Behat namespace for both Behat & Gherkin
+  * Fully rewritten formatters (much cleaner & beautifull API)
+  * Big refactoring of whole Behat code (clean code DRYing)
+  * Config file is now handled by standart-driven DIC extension (cleaner `behat.yml`)
+  * API documentation retouched
+  * New `--strict` option
+  * New `--no-multiline` option
+  * Feature examples in your language with `--usage`
+  * Available definitions listing with `--steps`
+  * Definition i18n
+  * Command refactoring (much cleaner API & actions)
+  * Event system refactoring
+  * 42 new languages with new Gherkin DSL parser
+
+## 0.3.6 - 2010-12-07
+### Changed
+  * [Behat,Gherkin] Fixed French support includes (fr)
+
+## 0.3.6 - 2010-12-06
+### Changed
+  * [Behat] Updated Symfony2 Components to latest PR4
+  * [Gherkin] Added French support (fr)
+  * [Gherkin] Added German support (de)
+  * [Behat] Small bugfixes
+
+## 0.3.5 - 2010-11-19
+### Changed
+  * [Behat] Refactored EnvironmentBuilder to allow Environment service definition overload
+
+## 0.3.4 - 2010-11-18
+### Changed
+  * [Behat] Introduced environment builder
+  * [Gherkin,Behat] id locale support
+
+## 0.3.3 - 2010-11-07
+### Changed
+  * [Gherkin] Added ability to create Table & PyString nodes with hands (in your step to step calls for example)
+  * [Gherkin] Added getRowsHash() method to TableNode, so now you can "rotate" given tables
+  * [Gherkin] You now can add comments before language specification in your feature files
+
+## 0.3.2 - 2010-11-06
+### Changed
+  * [Gherkin] Added ability to specify extended langs (en-US)
+  * [Behat,Gherkin] Added pt-BR translation
+
+## 0.3.1 - 2010-11-02
+### Changed
+  * [Behat] JUnit formatter
+  * [Behat] Pretty & HTML formatter background hooks fix
+  * [Behat] Other small fixes
+
+## 0.3.0 - 2010-11-02
+### Changed
+  * [Behat] Refactored tags filter
+  * [Behat] Added name filter
+  * [Behat] Refactored hooks
+  * [Behat] Added tagged/named hooks
+  * [Behat] Customizable HTML formatter with w3c valid default markup
+  * [Behat] Ability to specify out path for formatters
+  * [Behat] Bunch of new options
+  * [Behat] DIC optimisations
+
+## 0.2.5 - 2010-10-22
+### Changed
+  * [Behat] Format manager introduced
+  * [Behat] Formatters refactoring
+  * [Behat] Optmized container parameters to support EverzetBehatBundle
+  * [Behat] --no-color => --no-colors
+
+## 0.2.4 - 2010-10-19
+### Changed
+  * [Behat] Autoguess of colors support
+  * [Behat] Formatter setup bugfix (properl casing)
+
+## 0.2.3 - 2010-10-19
+### Changed
+  * [Behat] Filters optimisations
+  * [Behat] Changed Core Loaders with topic-specific (`StepDefinition\Loader\PHPLoader`,
+    `Features\Loader\GherkinLoader`)
+  * [Behat] Simplified TestCommand in prepare of Symfony2 BehatBundle
+  * [Behat] Configuration file/path setting update (you can now create `behat.yml` inside `./config/behat.yml` & Behat
+    will load it
+  * [Behat] Updated Redundant & Ambiguous exceptions behavior
+
+## 0.2.2 - 2010-10-10
+### Changed
+  * [Behat] Configuration file/path setting update
+
+## 0.2.1 - 2010-10-10
+### Changed
+  * [PEAR] Fix path to phpbin on installation
+
+## 0.2.0 - 2010-10-08
+### Changed
+  * [Behat] Brand new stateless testers, based on Visitor pattern
+  * [Behat] Refactored event listeners & event names
+  * [Behat] Refactored formatters to confirm with new stateless testers (statuses now sent as event parameters)
+  * [Behat] Refactored ConsoleFormatter (and removed base formatter)
+  * [Behat] Removed custom I18n classes & refactored Translator routines in flavor of Symfony\Component\Translation
+  * [Behat] Added missed translation strings into XLIFF files
+  * [Behat] Optimised multiline arguments (Node instances are sent to definitions instead of their plain representations)
+  * [Behat] Support for Scenario Outline tokens replace in multiline arguments (tables & pystrings)
+  * [Behat] Step arguments transformations (including table transformations)
+  * [Behat] Colorize inline step arguments
+  * [Behat] Optimized exit statuses of CLI
+  * [Behat] Added ability to turn-off colors
+  * [Behat] Added ability to translate formatters output with `--i18n` option
+  * [Behat] Bunch of new core feature tests
+  * [Gherkin] Parser now uses Symfony Dependency Injection to
+  * [Gherkin] Refactored parser to be like AST (Nodes that supports Visitor pattern)
+  * [Gherkin] Comments support
+  * [Gherkin] Fixed PHPUnit warnings
+  * [Behat,Gherkin] PEAR release script to support http://pear.everzet.com release model
+  * [Behat,Gherkin] DIC naming refactoring
+  * [Behat,Gherkin] Autoloader refactoring
+  * [Behat,Gherkin] Removed Zend & Goutte depencies
+
+## 0.1.5 - 2010-09-25
+### Changed
+  * Added ability to call other steps inside step definition
+  * Added profiles
+  * Refactored container creation routine
+  * Single quotes support in step definitions
+  * Added tests for hooks, profiles, inline steps
+
+## 0.1.4 - 2010-09-16
+### Changed
+  * Refactored code
+  * Removed logic from object constructors
+  * Added Loader & Filter interfaces
+
+## 0.1.3 - 2010-09-14
+### Changed
+  * Ability to specify arrays of paths/files for loaders
+  * Event hooks and support for `support/hooks.php`
+  * Formatters listens events with smallest priority
+  * Don't try to load steps if `steps` folder doesn't exists
+  * Bugfixes/refactoring
+
+## 0.1.2 - 2010-09-10
+### Changed
+  * Added ability to read from `behat.yml` and `behat.xml`
+  * Moved tags filter to separate object
+  * Refactored injection controller
+  * Optimized event names in event dispatcher
+  * Other small fixes/refactorings
+
+## 0.1.1 - 2010-09-09
+### Changed
+  * Added `--tags` option
+  * Changed environment (world) routines
+  * Added lots of core tests (writed in Behat itself)
+
+## 0.1.0 - 2010-09-08
+### Changed
+  * Initial release
+
+[Unreleased]: https://github.com/Behat/Behat/compare/v3.4.1...HEAD
+[3.4.1]: https://github.com/Behat/Behat/compare/v3.4.0...v3.4.1
+[3.4.0]: https://github.com/Behat/Behat/compare/v3.3.1...v3.4.0
+[3.3.1]: https://github.com/Behat/Behat/compare/v3.3.0...v3.3.1
+[3.3.0]: https://github.com/Behat/Behat/compare/v3.2.3...v3.3.0
+[3.2.3]: https://github.com/Behat/Behat/compare/v3.2.2...v3.2.3
+[3.2.2]: https://github.com/Behat/Behat/compare/v3.2.1...v3.2.2
+[3.2.1]: https://github.com/Behat/Behat/compare/v3.2.0...v3.2.1
+[3.2.0]: https://github.com/Behat/Behat/compare/v3.1.0...v3.2.0
+[3.1.0]: https://github.com/Behat/Behat/compare/v3.0.15...v3.1.0
+[3.0.15]: https://github.com/Behat/Behat/compare/v3.0.14...v3.0.15
+[3.0.14]: https://github.com/Behat/Behat/compare/v3.0.13...v3.0.14
+[3.0.13]: https://github.com/Behat/Behat/compare/v3.0.12...v3.0.13
+[3.0.12]: https://github.com/Behat/Behat/compare/v3.0.11...v3.0.12
+[3.0.11]: https://github.com/Behat/Behat/compare/v3.0.10...v3.0.11
+[3.0.10]: https://github.com/Behat/Behat/compare/v3.0.9...v3.0.10
+[3.0.9]: https://github.com/Behat/Behat/compare/v3.0.8...v3.0.9
+[3.0.8]: https://github.com/Behat/Behat/compare/v3.0.7...v3.0.8
+[3.0.7]: https://github.com/Behat/Behat/compare/v3.0.6...v3.0.7
+[3.0.6]: https://github.com/Behat/Behat/compare/v3.0.5...v3.0.6
+[3.0.5]: https://github.com/Behat/Behat/compare/v3.0.4...v3.0.5
+[3.0.4]: https://github.com/Behat/Behat/compare/v3.0.3...v3.0.4
+[3.0.3]: https://github.com/Behat/Behat/compare/v3.0.2...v3.0.3
+[3.0.2]: https://github.com/Behat/Behat/compare/v3.0.1...v3.0.2
+[3.0.1]: https://github.com/Behat/Behat/compare/v3.0.0...v3.0.1
+[3.0.0]: https://github.com/Behat/Behat/compare/v2.5.5...v3.0.0
diff --git a/vendor/behat/behat/LICENSE b/vendor/behat/behat/LICENSE
new file mode 100644 (file)
index 0000000..86ebfc8
--- /dev/null
@@ -0,0 +1,22 @@
+Copyright (c) 2016 Konstantin Kudryashov <ever.zet@gmail.com>
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
diff --git a/vendor/behat/behat/README.md b/vendor/behat/behat/README.md
new file mode 100644 (file)
index 0000000..22543cb
--- /dev/null
@@ -0,0 +1,73 @@
+![Behat](https://github.com/Behat/logo/raw/master/logo.png)
+
+Behat is a BDD framework for PHP to help you test business expectations.
+
+[![Gitter chat](https://badges.gitter.im/Behat/Behat.svg)](https://gitter.im/Behat/Behat)
+[![License](https://poser.pugx.org/behat/behat/license.svg)](https://packagist.org/packages/behat/behat)
+[![Unix Status](https://travis-ci.org/Behat/Behat.svg?branch=master)](https://travis-ci.org/Behat/Behat)
+[![Windows status](https://ci.appveyor.com/api/projects/status/9uc5sellmvbv02ei/branch/master?svg=true)](https://ci.appveyor.com/project/everzet/behat/branch/master)
+[![Scrutinizer Quality Score](https://scrutinizer-ci.com/g/Behat/Behat/badges/quality-score.png?s=ad84e95fc2405712f88a96d89b4f31dfe5c80fae)](https://scrutinizer-ci.com/g/Behat/Behat/)
+
+Installing Behat
+----------------
+
+The easiest way to install Behat is by using [Composer](https://getcomposer.org):
+
+```bash
+$> curl -sS https://getcomposer.org/installer | php
+$> php composer.phar require behat/behat
+```
+
+After that you'll be able to run Behat via:
+
+```bash
+$> vendor/bin/behat
+```
+
+Installing Development Version
+------------------------------
+
+Clone the repository and install dependencies via [Composer](https://getcomposer.org):
+
+```bash
+$> curl -sS https://getcomposer.org/installer | php
+$> php composer.phar install
+```
+
+After that you will be able to run development version of Behat via:
+
+```bash
+$> bin/behat
+```
+
+Contributing
+------------
+
+Before contributing to Behat, please take a look at the [CONTRIBUTING.md](CONTRIBUTING.md) document.
+
+Versioning
+----------
+
+Starting from `v3.0.0`, Behat is following [Semantic Versioning v2.0.0](http://semver.org/spec/v2.0.0.html).
+This basically means that if all you do is implement interfaces (like [this one](https://github.com/Behat/Behat/blob/v3.1.0/src/Behat/Behat/Context/ContextClass/ClassResolver.php#L15-L22))
+and use service constants (like [this one](https://github.com/Behat/Behat/blob/v3.1.0/src/Behat/Behat/Context/ServiceContainer/ContextExtension.php#L46)),
+you would not have any backwards compatibility issues with Behat up until `v4.0.0` (or later major)
+is released. Exception could be an extremely rare case where BC break is introduced as a measure
+to fix a serious issue.
+
+You can read detailed guidance on what BC means in [Symfony2 BC guide](http://symfony.com/doc/current/contributing/code/bc.html).
+
+Useful Links
+------------
+
+- The main website is at [http://behat.org](http://behat.org)
+- The documentation is at [http://docs.behat.org/en/latest/](http://docs.behat.org/en/latest/)
+- Official Google Group is at [http://groups.google.com/group/behat](http://groups.google.com/group/behat)
+- IRC channel on [#freenode](http://freenode.net/) is `#behat`
+- [Note on Patches/Pull Requests](CONTRIBUTING.md)
+
+Contributors
+------------
+
+- Konstantin Kudryashov [everzet](http://github.com/everzet) [lead developer]
+- Other [awesome developers](https://github.com/Behat/Behat/graphs/contributors)
diff --git a/vendor/behat/behat/bin/behat b/vendor/behat/behat/bin/behat
new file mode 100755 (executable)
index 0000000..b7dad59
--- /dev/null
@@ -0,0 +1,34 @@
+#!/usr/bin/env php
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+define('BEHAT_BIN_PATH',     __FILE__);
+
+if (is_file($autoload = getcwd() . '/vendor/autoload.php')) {
+    require $autoload;
+}
+
+if (!class_exists('Behat\Behat\ApplicationFactory', true)) {
+    if (is_file($autoload = __DIR__ . '/../vendor/autoload.php')) {
+        require($autoload);
+    } elseif (is_file($autoload = __DIR__ . '/../../../autoload.php')) {
+        require($autoload);
+    } else {
+        fwrite(STDERR,
+            'You must set up the project dependencies, run the following commands:'.PHP_EOL.
+            'curl -s http://getcomposer.org/installer | php'.PHP_EOL.
+            'php composer.phar install'.PHP_EOL
+        );
+        exit(1);
+    }
+}
+
+$factory = new \Behat\Behat\ApplicationFactory();
+$factory->createApplication()->run();
diff --git a/vendor/behat/behat/composer.json b/vendor/behat/behat/composer.json
new file mode 100644 (file)
index 0000000..b3dbd81
--- /dev/null
@@ -0,0 +1,58 @@
+{
+    "name": "behat/behat",
+    "description": "Scenario-oriented BDD framework for PHP 5.3",
+    "keywords": ["BDD", "ScenarioBDD", "StoryBDD", "Examples", "Scrum", "Agile", "User story", "Symfony", "business", "development", "testing", "documentation"],
+    "homepage": "http://behat.org/",
+    "type": "library",
+    "license": "MIT",
+    "authors": [
+        {
+            "name": "Konstantin Kudryashov",
+            "email": "ever.zet@gmail.com",
+            "homepage": "http://everzet.com"
+        }
+    ],
+
+    "require": {
+        "php": ">=5.3.3",
+        "ext-mbstring": "*",
+        "behat/gherkin": "^4.5.1",
+        "behat/transliterator": "^1.2",
+        "symfony/console": "~2.5||~3.0",
+        "symfony/config": "~2.3||~3.0",
+        "symfony/dependency-injection": "~2.1||~3.0",
+        "symfony/event-dispatcher": "~2.1||~3.0",
+        "symfony/translation": "~2.3||~3.0",
+        "symfony/yaml": "~2.1||~3.0",
+        "symfony/class-loader": "~2.1||~3.0",
+        "psr/container": "^1.0",
+        "container-interop/container-interop": "^1.2"
+    },
+
+    "require-dev": {
+        "symfony/process": "~2.5|~3.0",
+        "phpunit/phpunit": "~4.5",
+        "herrera-io/box": "~1.6.1"
+    },
+
+    "suggest": {
+        "behat/symfony2-extension": "for integration with Symfony2 web framework",
+        "behat/yii-extension": "for integration with Yii web framework",
+        "behat/mink-extension": "for integration with Mink testing framework"
+    },
+
+    "autoload": {
+        "psr-0": {
+            "Behat\\Behat": "src/",
+            "Behat\\Testwork": "src/"
+        }
+    },
+
+    "extra": {
+        "branch-alias": {
+            "dev-master": "3.2.x-dev"
+        }
+    },
+
+    "bin": ["bin/behat"]
+}
diff --git a/vendor/behat/behat/i18n.php b/vendor/behat/behat/i18n.php
new file mode 100644 (file)
index 0000000..44eda3c
--- /dev/null
@@ -0,0 +1,217 @@
+<?php return array(
+    'en'    => array(
+        'snippet_context_choice'  => '<snippet_undefined><snippet_keyword>%1%</snippet_keyword> suite has undefined steps. Please choose the context to generate snippets:</snippet_undefined>',
+        'snippet_proposal_title'  => '<snippet_undefined><snippet_keyword>%1%</snippet_keyword> has missing steps. Define them with these snippets:</snippet_undefined>',
+        'snippet_missing_title'   => '<snippet_undefined>Use <snippet_keyword>--snippets-for</snippet_keyword> CLI option to generate snippets for following <snippet_keyword>%1%</snippet_keyword> suite steps:</snippet_undefined>',
+        'skipped_scenarios_title' => 'Skipped scenarios:',
+        'failed_scenarios_title'  => 'Failed scenarios:',
+        'failed_hooks_title'      => 'Failed hooks:',
+        'failed_steps_title'      => 'Failed steps:',
+        'pending_steps_title'     => 'Pending steps:',
+        'scenarios_count'         => '{0} No scenarios|{1} 1 scenario|]1,Inf] %1% scenarios',
+        'steps_count'             => '{0} No steps|{1} 1 step|]1,Inf] %1% steps',
+        'passed_count'            => '[1,Inf] %1% passed',
+        'failed_count'            => '[1,Inf] %1% failed',
+        'pending_count'           => '[1,Inf] %1% pending',
+        'undefined_count'         => '[1,Inf] %1% undefined',
+        'skipped_count'           => '[1,Inf] %1% skipped',
+    ),
+    'cs'    => array(
+        'snippet_proposal_title' => '<snippet_undefined><snippet_keyword>%1%</snippet_keyword> obsahuje chybné kroky. Definujte je za použití následujícího kódu:</snippet_undefined>',
+        'snippet_missing_title'  => '<snippet_undefined>Snippety pro následující kroky v sadě <snippet_keyword>%1%</snippet_keyword> nebyly vygenerovány (zkontrolujte správnost konfigurace):</snippet_undefined>',
+        'failed_scenarios_title' => 'Chybné scénáře:',
+        'failed_hooks_title'     => 'Chybné hooky:',
+        'failed_steps_title'     => 'Chybné kroky:',
+        'pending_steps_title'    => 'Čekající kroky:',
+        'scenarios_count'        => '{0} Žádný scénář|{1} 1 scénář|{2,3,4} %1% scénáře|]4,Inf] %1% scénářů',
+        'steps_count'            => '{0} Žádné kroky|{1} 1 krok|{2,3,4} %1% kroky|]4,Inf] %1% kroků',
+        'passed_count'           => '{1} %1% prošel|{2,3,4} %1% prošly|]4,Inf] %1% prošlo',
+        'failed_count'           => '{1} %1% selhal|{2,3,4} %1% selhaly|]4,Inf] %1% selhalo',
+        'pending_count'          => '{1} %1% čeká|{2,3,4} %1% čekají|]4,Inf] %1% čeká',
+        'undefined_count'        => '{1} %1% nedefinován|{2,3,4} %1% nedefinovány|]4,Inf] %1% nedefinováno',
+        'skipped_count'          => '{1} %1% přeskočen|{2,3,4} %1% přeskočeny|]4,Inf] %1% přeskočeno',
+    ),
+    'de'    => array(
+        'snippet_proposal_title' => '<snippet_undefined><snippet_keyword>%1%</snippet_keyword> hat fehlende Schritte. Definiere diese mit den folgenden Snippets:</snippet_undefined>',
+        'snippet_missing_title'  => '<snippet_undefined>Snippets für die folgenden Schritte in der <snippet_keyword>%1%</snippet_keyword> Suite wurden nicht generiert (Konfiguration überprüfen):</snippet_undefined>',
+        'failed_scenarios_title' => 'Fehlgeschlagene Szenarien:',
+        'failed_hooks_title'     => 'Fehlgeschlagene Hooks:',
+        'failed_steps_title'     => 'Fehlgeschlagene Schritte:',
+        'pending_steps_title'    => 'Ausstehende Schritte:',
+        'scenarios_count'        => '{0} Kein Szenario|{1} 1 Szenario|]1,Inf] %1% Szenarien',
+        'steps_count'            => '{0} Kein Schritt|{1} 1 Schritt|]1,Inf] %1% Schritte',
+        'passed_count'           => '[1,Inf] %1% bestanden',
+        'failed_count'           => '[1,Inf] %1% fehlgeschlagen',
+        'pending_count'          => '[1,Inf] %1% ausstehend',
+        'undefined_count'        => '[1,Inf] %1% nicht definiert',
+        'skipped_count'          => '[1,Inf] %1% übersprungen',
+    ),
+    'es'    => array(
+        'snippet_proposal_title' => '<snippet_undefined>A <snippet_keyword>%1%</snippet_keyword> le faltan pasos. Defínelos con estos pasos:</snippet_undefined>',
+        'snippet_missing_title'  => '<snippet_undefined>Las plantillas para los siguientes pasos en <snippet_keyword>%1%</snippet_keyword> no fueron generadas (revisa tu configuración):</snippet_undefined>',
+        'failed_scenarios_title' => 'Escenarios fallidos:',
+        'failed_hooks_title'     => 'Hooks fallidos:',
+        'failed_steps_title'     => 'Pasos fallidos:',
+        'pending_steps_title'    => 'Pasos pendientes:',
+        'scenarios_count'        => '{0} Ningún escenario|{1} 1 escenario|]1,Inf] %1% escenarios',
+        'steps_count'            => '{0} Ningún paso|{1} 1 paso|]1,Inf] %1% pasos',
+        'passed_count'           => '[1,Inf] %1% pasaron',
+        'failed_count'           => '[1,Inf] %1% fallaron',
+        'pending_count'          => '[1,Inf] %1% pendientes',
+        'undefined_count'        => '[1,Inf] %1% por definir',
+        'skipped_count'          => '[1,Inf] %1% saltadas',
+    ),
+    'fr'    => array(
+        'snippet_proposal_title' => '<snippet_undefined><snippet_keyword>%1%</snippet_keyword> a des étapes manquantes. Définissez-les avec les modèles suivants :</snippet_undefined>',
+        'snippet_missing_title'  => '<snippet_undefined>Les modèles des étapes de la suite <snippet_keyword>%1%</snippet_keyword> n\'ont pas été générés (vérifiez votre configuration):</snippet_undefined>',
+        'failed_scenarios_title' => 'Scénarios échoués:',
+        'failed_hooks_title'     => 'Hooks échoués:',
+        'failed_steps_title'     => 'Etapes échouées:',
+        'pending_steps_title'    => 'Etapes en attente:',
+        'scenarios_count'        => '{0} Pas de scénario|{1} 1 scénario|]1,Inf] %1% scénarios',
+        'steps_count'            => '{0} Pas d\'étape|{1} 1 étape|]1,Inf] %1% étapes',
+        'passed_count'           => '[1,Inf] %1% succès',
+        'failed_count'           => '[1,Inf] %1% échecs',
+        'pending_count'          => '[1,Inf] %1% en attente',
+        'undefined_count'        => '[1,Inf] %1% indéfinis',
+        'skipped_count'          => '[1,Inf] %1% ignorés',
+    ),
+    'it'    => array(
+        'snippet_proposal_title' => '<snippet_undefined><snippet_keyword>%1%</snippet_keyword> ha dei passaggi mancanti. Definiscili con questi snippet:</snippet_undefined>',
+        'snippet_missing_title'  => '<snippet_undefined>Gli snippet per i seguenti passaggi della suite <snippet_keyword>%1%</snippet_keyword> non sono stati generati (verifica la configurazione):</snippet_undefined>',
+        'failed_scenarios_title' => 'Scenari falliti:',
+        'failed_hooks_title'     => 'Hook falliti:',
+        'failed_steps_title'     => 'Passaggi falliti:',
+        'pending_steps_title'    => 'Passaggi in sospeso:',
+        'scenarios_count'        => '{0} Nessuno scenario|{1} 1 scenario|]1,Inf] %1% scenari',
+        'steps_count'            => '{0} Nessun passaggio|{1} 1 passaggio|]1,Inf] %1% passaggi',
+        'passed_count'           => '{1} 1 superato|]1,Inf] %1% superati',
+        'failed_count'           => '{1} 1 fallito|]1,Inf] %1% falliti',
+        'pending_count'          => '[1,Inf] %1% in sospeso',
+        'undefined_count'        => '{1} 1 non definito|]1,Inf] %1% non definiti',
+        'skipped_count'          => '{1} 1 ignorato|]1,Inf] %1% ignorati',
+    ),
+    'ja'    => array(
+        'snippet_proposal_title'  => '<snippet_undefined><snippet_keyword>%1%</snippet_keyword> のステップが見つかりません。 次のスニペットで定義できます:</snippet_undefined>',
+        'snippet_missing_title'   => '<snippet_undefined>以下のステップのスニペットは<snippet_keyword>%1%</snippet_keyword>スイートに生成されませんでした(設定を確認してください):</snippet_undefined>',
+        'skipped_scenarios_title' => 'スキップした シナリオ:',
+        'failed_scenarios_title'  => '失敗した シナリオ:',
+        'failed_hooks_title'      => '失敗した フック:',
+        'failed_steps_title'      => '失敗した ステップ:',
+        'pending_steps_title'     => '保留中のステップ:',
+        'scenarios_count'         => '{0} No scenarios|{1} 1 個のシナリオ|]1,Inf] %1% 個のシナリオ',
+        'steps_count'             => '{0} ステップがありません|{1} 1 個のステップ|]1,Inf] %1% 個のステップ',
+        'passed_count'            => '[1,Inf] %1% 個成功',
+        'failed_count'            => '[1,Inf] %1% 個失敗',
+        'pending_count'           => '[1,Inf] %1% 個保留',
+        'undefined_count'         => '[1,Inf] %1% 個未定義',
+        'skipped_count'           => '[1,Inf] %1% 個スキップ',
+    ),
+    'nl'    => array(
+        'snippet_proposal_title' => '<snippet_undefined>Ontbrekende stappen in <snippet_keyword>%1%</snippet_keyword>. Definieer ze met de volgende fragmenten:</snippet_undefined>',
+        'snippet_missing_title'  => '<snippet_undefined>Fragmenten voor de volgende stappen in de <snippet_keyword>%1%</snippet_keyword> suite werden niet gegenereerd (controleer de configuratie):</snippet_undefined>',
+        'failed_scenarios_title' => 'Gefaalde scenario\'s:',
+        'failed_hooks_title'     => 'Gefaalde hooks:',
+        'failed_steps_title'     => 'Gefaalde stappen:',
+        'pending_steps_title'    => 'Onafgewerkte stappen:',
+        'scenarios_count'        => '{0} Geen scenario\'s|{1} 1 scenario|]1,Inf] %1% scenario\'s',
+        'steps_count'            => '{0} Geen stappen|{1} 1 stap|]1,Inf] %1% stappen',
+        'passed_count'           => '[1,Inf] %1% geslaagd',
+        'failed_count'           => '[1,Inf] %1% gefaald',
+        'pending_count'          => '[1,Inf] %1% wachtende',
+        'undefined_count'        => '[1,Inf] %1% niet gedefinieerd',
+        'skipped_count'          => '[1,Inf] %1% overgeslagen',
+    ),
+    'no'    => array(
+        'snippet_proposal_title' => '<snippet_undefined><snippet_keyword>%1%</snippet_keyword> mangler steg. Definer dem med disse snuttene:</snippet_undefined>',
+        'snippet_missing_title'  => '<snippet_undefined>Snutter for de følgende stegene i <snippet_keyword>%1%</snippet_keyword>-samlingen ble ikke laget. (Sjekk konfigurasjonen din.):</snippet_undefined>',
+        'failed_scenarios_title' => 'Feilende scenarier:',
+        'failed_hooks_title'     => 'Feilende hooks:',
+        'failed_steps_title'     => 'Feilende steg:',
+        'pending_steps_title'    => 'Ikke implementerte steg:',
+        'scenarios_count'        => '{0} Ingen scenarier|{1} 1 scenario|]1,Inf] %1% scenarier',
+        'steps_count'            => '{0} Ingen steg|{1} 1 steg|]1,Inf] %1% steg',
+        'passed_count'           => '[1,Inf] %1% ok',
+        'failed_count'           => '[1,Inf] %1% feilet',
+        'pending_count'          => '[1,Inf] %1% ikke implementert',
+        'undefined_count'        => '[1,Inf] %1% ikke definert',
+        'skipped_count'          => '[1,Inf] %1% hoppet over',
+    ),
+    'pl'    => array(
+        'snippet_proposal_title' => '<snippet_undefined><snippet_keyword>%1%</snippet_keyword> zawiera brakujące kroki. Utwórz je korzystając z tych fragmentów kodu:</snippet_undefined>',
+        'snippet_missing_title'  => '<snippet_undefined>Fragmenty kodu dla następujących kroków <snippet_keyword>%1%</snippet_keyword> nie zostały wygenerowane (sprawdź swoją konfigurację):</snippet_undefined>',
+        'failed_scenarios_title' => 'Nieudane scenariusze:',
+        'failed_hooks_title'     => 'Nieudane hooki:',
+        'failed_steps_title'     => 'Nieudane kroki',
+        'pending_steps_title'    => 'Oczekujące kroki',
+        'scenarios_count'        => '{0} Brak scenariuszy|{1} 1 scenariusz|{2,3,4,22,23,24,32,33,34,42,43,44} %1% scenariusze|]4,Inf] %1% scenariuszy',
+        'steps_count'            => '{0} Brak kroków|{1} 1 krok|{2,3,4,22,23,24,32,33,34,42,43,44} %1% kroki|]4,Inf] %1% kroków',
+        'passed_count'           => '{1} %1% udany|{2,3,4,22,23,24,32,33,34,42,43,44} %1% udane|]4,Inf] %1% udanych',
+        'failed_count'           => '{1} %1% nieudany|{2,3,4,22,23,24,32,33,34,42,43,44} %1% nieudane|]4,Inf] %1% nieudanych',
+        'pending_count'          => '{1} %1% oczekujący|{2,3,4,22,23,24,32,33,34,42,43,44} %1% oczekujące|]4,Inf] %1% oczekujących',
+        'undefined_count'        => '{1} %1% niezdefiniowany|{2,3,4,22,23,24,32,33,34,42,43,44} %1% niezdefiniowane|]4,Inf] %1% niezdefiniowanych',
+        'skipped_count'          => '{1} %1% pominięty|{2,3,4,22,23,24,32,33,34,42,43,44} %1% pominięte|]4,Inf] %1% pominiętych',
+    ),
+    'pt'    => array(
+        'snippet_proposal_title' => '<snippet_undefined><snippet_keyword>%1%</snippet_keyword> contém definições em falta. Defina-as com estes exemplos:</snippet_undefined>',
+        'snippet_missing_title'  => '<snippet_undefined>Os exemplos para as seguintes definições da suite <snippet_keyword>%1%</snippet_keyword> não foram gerados (verifique a configuração):</snippet_undefined>',
+        'failed_scenarios_title' => 'Cenários que falharam:',
+        'failed_hooks_title'     => 'Hooks que falharam:',
+        'failed_steps_title'     => 'Definições que falharam:',
+        'pending_steps_title'    => 'Definições por definir:',
+        'scenarios_count'        => '{0} Nenhum cenário|{1} 1 cenário|]1,Inf] %1% cenários',
+        'steps_count'            => '{0} Nenhuma definição|{1} 1 definição|]1,Inf] %1% definições',
+        'passed_count'           => '{1} passou|]1,Inf] %1% passaram',
+        'failed_count'           => '{1} falhou|]1,Inf] %1% falharam',
+        'pending_count'          => '[1,Inf] %1% por definir',
+        'undefined_count'        => '{1} indefinido|]1,Inf] %1% indefinidos',
+        'skipped_count'          => '{1} omitido|]1,Inf] %1% omitidos',
+    ),
+    'pt-BR' => array(
+        'snippet_proposal_title' => '<snippet_undefined><snippet_keyword>%1%</snippet_keyword> possue etapas faltando. Defina elas com esse(s) trecho(s) de código:</snippet_undefined>',
+        'snippet_missing_title'  => '<snippet_undefined>Trecho de códigos para as seguintes etapas em <snippet_keyword>%1%</snippet_keyword> suite não foram geradas (verique sua configuração):</snippet_undefined>',
+        'failed_scenarios_title' => 'Cenários falhados:',
+        'failed_hooks_title'     => 'Hooks falhados:',
+        'failed_steps_title'     => 'Etapas falhadas:',
+        'pending_steps_title'    => 'Etapas pendentes:',
+        'scenarios_count'        => '{0} Nenhum cenário|{1} 1 cenário|]1,Inf] %1% cenários',
+        'steps_count'            => '{0} Nenhuma etapa|{1} 1 etapa|]1,Inf] %1% etapas',
+        'passed_count'           => '[1,Inf] %1% passou',
+        'failed_count'           => '[1,Inf] %1% falhou',
+        'pending_count'          => '[1,Inf] %1% pendente',
+        'undefined_count'        => '[1,Inf] %1% indefinido',
+        'skipped_count'          => '[1,Inf] %1% pulado',
+    ),
+    'ro'    => array(
+        'snippet_proposal_title'  => '<snippet_undefined><snippet_keyword>%1%</snippet_keyword> are pași lipsa. Puteți implementa pașii cu ajutorul acestor fragmente de cod:</snippet_undefined>',
+        'snippet_missing_title'   => '<snippet_undefined>Fragmentele de cod pentru urmatorii pași din suita <snippet_keyword>%1%</snippet_keyword> nu au fost generate (contextul tau implementeaza interfata SnippetAcceptingContext?):</snippet_undefined>',
+        'skipped_scenarios_title' => 'Scenarii omise:',
+        'failed_scenarios_title'  => 'Scenarii eșuate:',
+        'failed_hooks_title'      => 'Hook-uri eșuate:',
+        'failed_steps_title'      => 'Pași esuați:',
+        'pending_steps_title'     => 'Pași in așteptare:',
+        'scenarios_count'         => '{0} Niciun scenariu|{1} 1 scenariu|]1,Inf] %1% scenarii',
+        'steps_count'             => '{0} Niciun pas|{1} 1 pas|]1,Inf] %1% pasi',
+        'passed_count'            => '[1,Inf] %1% cu succes',
+        'failed_count'            => '[1,Inf] %1% fara success',
+        'pending_count'           => '[1,Inf] %1% in așteptare',
+        'undefined_count'         => '[1,Inf] %1% fara implementare',
+        'skipped_count'           => '{1} %1% omis|]1,Inf] %1% omiși',
+    ),
+    'ru'    => array(
+        'snippet_proposal_title'  => '<snippet_keyword>%1%</snippet_keyword> <snippet_undefined>не содержит необходимых определений. Вы можете добавить их используя шаблоны:</snippet_undefined>',
+        'snippet_missing_title'   => '<snippet_undefined>Шаблоны для следующих шагов в среде <snippet_keyword>%1%</snippet_keyword> не были сгенерированы (проверьте ваши настройки):</snippet_undefined>',
+        'skipped_scenarios_title' => 'Пропущенные сценарии:',
+        'failed_scenarios_title'  => 'Проваленные сценарии:',
+        'failed_hooks_title'      => 'Проваленные хуки:',
+        'failed_steps_title'      => 'Проваленные шаги:',
+        'pending_steps_title'     => 'Шаги в ожидании:',
+        'scenarios_count'         => '{0} Нет сценариев|{1,21,31} %1% сценарий|{2,3,4,22,23,24} %1% сценария|]4,Inf] %1% сценариев',
+        'steps_count'             => '{0} Нет шагов|{1,21,31} %1% шаг|{2,3,4,22,23,24} %1% шага|]4,Inf] %1% шагов',
+        'passed_count'            => '{1,21,31} %1% пройден|]1,Inf] %1% пройдено',
+        'failed_count'            => '{1,21,31} %1% провален|]1,Inf] %1% провалено',
+        'pending_count'           => '[1,Inf] %1% в ожидании',
+        'undefined_count'         => '{1,21,31} %1% не определен|]1,Inf] %1% не определено',
+        'skipped_count'           => '{1,21,31} %1% пропущен|]1,Inf] %1% пропущено',
+    ),
+);
diff --git a/vendor/behat/behat/src/Behat/Behat/ApplicationFactory.php b/vendor/behat/behat/src/Behat/Behat/ApplicationFactory.php
new file mode 100644 (file)
index 0000000..46a0640
--- /dev/null
@@ -0,0 +1,150 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat;
+
+use Behat\Behat\Context\ServiceContainer\ContextExtension;
+use Behat\Behat\Definition\ServiceContainer\DefinitionExtension;
+use Behat\Behat\EventDispatcher\ServiceContainer\EventDispatcherExtension;
+use Behat\Behat\Gherkin\ServiceContainer\GherkinExtension;
+use Behat\Behat\Hook\ServiceContainer\HookExtension;
+use Behat\Behat\Output\ServiceContainer\Formatter\JUnitFormatterFactory;
+use Behat\Behat\Output\ServiceContainer\Formatter\PrettyFormatterFactory;
+use Behat\Behat\Output\ServiceContainer\Formatter\ProgressFormatterFactory;
+use Behat\Behat\HelperContainer\ServiceContainer\HelperContainerExtension;
+use Behat\Behat\Snippet\ServiceContainer\SnippetExtension;
+use Behat\Behat\Tester\ServiceContainer\TesterExtension;
+use Behat\Behat\Transformation\ServiceContainer\TransformationExtension;
+use Behat\Behat\Translator\ServiceContainer\GherkinTranslationsExtension;
+use Behat\Testwork\ApplicationFactory as BaseFactory;
+use Behat\Testwork\Argument\ServiceContainer\ArgumentExtension;
+use Behat\Testwork\Autoloader\ServiceContainer\AutoloaderExtension;
+use Behat\Testwork\Call\ServiceContainer\CallExtension;
+use Behat\Testwork\Cli\ServiceContainer\CliExtension;
+use Behat\Testwork\Environment\ServiceContainer\EnvironmentExtension;
+use Behat\Testwork\Exception\ServiceContainer\ExceptionExtension;
+use Behat\Testwork\Filesystem\ServiceContainer\FilesystemExtension;
+use Behat\Testwork\Ordering\ServiceContainer\OrderingExtension;
+use Behat\Testwork\Output\ServiceContainer\Formatter\FormatterFactory;
+use Behat\Testwork\Output\ServiceContainer\OutputExtension;
+use Behat\Testwork\ServiceContainer\ServiceProcessor;
+use Behat\Testwork\Specification\ServiceContainer\SpecificationExtension;
+use Behat\Testwork\Suite\ServiceContainer\SuiteExtension;
+use Behat\Testwork\Translator\ServiceContainer\TranslatorExtension;
+
+/**
+ * Defines the way behat is created.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class ApplicationFactory extends BaseFactory
+{
+    const VERSION = '3.4.1';
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function getName()
+    {
+        return 'behat';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function getVersion()
+    {
+        return self::VERSION;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function getDefaultExtensions()
+    {
+        $processor = new ServiceProcessor();
+
+        return array(
+            new ArgumentExtension(),
+            new AutoloaderExtension(array('' => '%paths.base%/features/bootstrap')),
+            new SuiteExtension($processor),
+            new OutputExtension('pretty', $this->getDefaultFormatterFactories($processor), $processor),
+            new ExceptionExtension($processor),
+            new GherkinExtension($processor),
+            new CallExtension($processor),
+            new TranslatorExtension(),
+            new GherkinTranslationsExtension(),
+            new TesterExtension($processor),
+            new CliExtension($processor),
+            new EnvironmentExtension($processor),
+            new SpecificationExtension($processor),
+            new FilesystemExtension(),
+            new ContextExtension($processor),
+            new SnippetExtension($processor),
+            new DefinitionExtension($processor),
+            new EventDispatcherExtension($processor),
+            new HookExtension(),
+            new TransformationExtension($processor),
+            new OrderingExtension($processor),
+            new HelperContainerExtension($processor)
+        );
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function getEnvironmentVariableName()
+    {
+        return 'BEHAT_PARAMS';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function getConfigPath()
+    {
+        $cwd = rtrim(getcwd(), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
+        $configDir = $cwd . 'config' . DIRECTORY_SEPARATOR;
+        $paths = array(
+            $cwd . 'behat.yaml',
+            $cwd . 'behat.yml',
+            $cwd . 'behat.yaml.dist',
+            $cwd . 'behat.yml.dist',
+            $configDir . 'behat.yaml',
+            $configDir . 'behat.yml',
+            $configDir . 'behat.yaml.dist',
+            $configDir . 'behat.yml.dist',
+        );
+
+        foreach ($paths as $path) {
+            if (is_file($path)) {
+                return $path;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Returns default formatter factories.
+     *
+     * @param ServiceProcessor $processor
+     *
+     * @return FormatterFactory[]
+     */
+    private function getDefaultFormatterFactories(ServiceProcessor $processor)
+    {
+        return array(
+            new PrettyFormatterFactory($processor),
+            new ProgressFormatterFactory($processor),
+            new JUnitFormatterFactory(),
+        );
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Context/Annotation/AnnotationReader.php b/vendor/behat/behat/src/Behat/Behat/Context/Annotation/AnnotationReader.php
new file mode 100644 (file)
index 0000000..84f7ac9
--- /dev/null
@@ -0,0 +1,37 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Context\Annotation;
+
+use Behat\Behat\Context\Reader\AnnotatedContextReader;
+use Behat\Testwork\Call\Callee;
+use ReflectionMethod;
+
+/**
+ * Reads custom annotation of a provided context method into a Callee.
+ *
+ * @see AnnotatedContextReader
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface AnnotationReader
+{
+    /**
+     * Reads all callees associated with a provided method.
+     *
+     * @param string           $contextClass
+     * @param ReflectionMethod $method
+     * @param string           $docLine
+     * @param string           $description
+     *
+     * @return null|Callee
+     */
+    public function readCallee($contextClass, ReflectionMethod $method, $docLine, $description);
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Context/Argument/ArgumentResolver.php b/vendor/behat/behat/src/Behat/Behat/Context/Argument/ArgumentResolver.php
new file mode 100644 (file)
index 0000000..e218276
--- /dev/null
@@ -0,0 +1,34 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Context\Argument;
+
+use Behat\Behat\Context\Environment\Handler\ContextEnvironmentHandler;
+use ReflectionClass;
+
+/**
+ * Resolves arguments of context constructors.
+ *
+ * @see ContextEnvironmentHandler
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface ArgumentResolver
+{
+    /**
+     * Resolves context constructor arguments.
+     *
+     * @param ReflectionClass $classReflection
+     * @param mixed[]         $arguments
+     *
+     * @return mixed[]
+     */
+    public function resolveArguments(ReflectionClass $classReflection, array $arguments);
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Context/Argument/ArgumentResolverFactory.php b/vendor/behat/behat/src/Behat/Behat/Context/Argument/ArgumentResolverFactory.php
new file mode 100644 (file)
index 0000000..708c38b
--- /dev/null
@@ -0,0 +1,32 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Context\Argument;
+
+use Behat\Testwork\Environment\Environment;
+
+/**
+ * Creates argument resolvers for provided environment.
+ *
+ * @see ContextEnvironmentHandler
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface ArgumentResolverFactory
+{
+    /**
+     * Builds argument resolvers for provided suite.
+     *
+     * @param Environment $environment
+     *
+     * @return ArgumentResolver[]
+     */
+    public function createArgumentResolvers(Environment $environment);
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Context/Argument/CompositeArgumentResolverFactory.php b/vendor/behat/behat/src/Behat/Behat/Context/Argument/CompositeArgumentResolverFactory.php
new file mode 100644 (file)
index 0000000..fbfd69c
--- /dev/null
@@ -0,0 +1,52 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Context\Argument;
+
+use Behat\Testwork\Environment\Environment;
+
+/**
+ * Composite factory. Delegates to other (registered) factories to do the job.
+ *
+ * @see ContextEnvironmentHandler
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class CompositeArgumentResolverFactory implements ArgumentResolverFactory
+{
+    /**
+     * @var ArgumentResolverFactory[]
+     */
+    private $factories = array();
+
+    /**
+     * Registers factory.
+     *
+     * @param ArgumentResolverFactory $factory
+     */
+    public function registerFactory(ArgumentResolverFactory $factory)
+    {
+        $this->factories[] = $factory;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function createArgumentResolvers(Environment $environment)
+    {
+        return array_reduce(
+            $this->factories,
+            function (array $resolvers, ArgumentResolverFactory $factory) use ($environment) {
+                return array_merge($resolvers, $factory->createArgumentResolvers($environment));
+            },
+            array()
+        );
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Context/Argument/CompositeFactory.php b/vendor/behat/behat/src/Behat/Behat/Context/Argument/CompositeFactory.php
new file mode 100644 (file)
index 0000000..5b3d93f
--- /dev/null
@@ -0,0 +1,54 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Context\Argument;
+
+use Behat\Testwork\Suite\Suite;
+
+/**
+ * Composite factory. Delegates to other (registered) factories to do the job.
+ *
+ * @see ContextEnvironmentHandler
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * @deprecated and will be removed in 4.0. Use CompositeArgumentResolverFactory instead
+ */
+final class CompositeFactory implements SuiteScopedResolverFactory
+{
+    /**
+     * @var SuiteScopedResolverFactory[]
+     */
+    private $factories = array();
+
+    /**
+     * Registers factory.
+     *
+     * @param SuiteScopedResolverFactory $factory
+     */
+    public function registerFactory(SuiteScopedResolverFactory $factory)
+    {
+        $this->factories[] = $factory;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function generateArgumentResolvers(Suite $suite)
+    {
+        return array_reduce(
+            $this->factories,
+            function (array $resolvers, SuiteScopedResolverFactory $factory) use ($suite) {
+                return array_merge($resolvers, $factory->generateArgumentResolvers($suite));
+            },
+            array()
+        );
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Context/Argument/NullFactory.php b/vendor/behat/behat/src/Behat/Behat/Context/Argument/NullFactory.php
new file mode 100644 (file)
index 0000000..c2e070c
--- /dev/null
@@ -0,0 +1,40 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Context\Argument;
+
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\Suite\Suite;
+
+/**
+ * NoOp factory. Always returns zero resolvers.
+ *
+ * @see ContextEnvironmentHandler
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class NullFactory implements ArgumentResolverFactory, SuiteScopedResolverFactory
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function generateArgumentResolvers(Suite $suite)
+    {
+        return array();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function createArgumentResolvers(Environment $environment)
+    {
+        return array();
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Context/Argument/SuiteScopedResolverFactory.php b/vendor/behat/behat/src/Behat/Behat/Context/Argument/SuiteScopedResolverFactory.php
new file mode 100644 (file)
index 0000000..9f953fc
--- /dev/null
@@ -0,0 +1,34 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Context\Argument;
+
+use Behat\Testwork\Suite\Suite;
+
+/**
+ * Creates argument resolvers for provided suite.
+ *
+ * @see ContextEnvironmentHandler
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * @deprecated since 3.4. Use `ArgumentResolverFactory` instead
+ */
+interface SuiteScopedResolverFactory
+{
+    /**
+     * Creates argument resolvers for provided suite.
+     *
+     * @param Suite $suite
+     *
+     * @return ArgumentResolver[]
+     */
+    public function generateArgumentResolvers(Suite $suite);
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Context/Argument/SuiteScopedResolverFactoryAdapter.php b/vendor/behat/behat/src/Behat/Behat/Context/Argument/SuiteScopedResolverFactoryAdapter.php
new file mode 100644 (file)
index 0000000..2317c8e
--- /dev/null
@@ -0,0 +1,48 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Context\Argument;
+
+use Behat\Testwork\Environment\Environment;
+
+/**
+ * Adapts SuiteScopedResolverFactory to new ArgumentResolverFactory interface.
+ *
+ * @see ContextEnvironmentHandler
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * @deprecated since 3.4. Use `ArgumentResolverFactory` instead
+ */
+final class SuiteScopedResolverFactoryAdapter implements ArgumentResolverFactory
+{
+    /**
+     * @var SuiteScopedResolverFactory
+     */
+    private $factory;
+
+    /**
+     * Initialises adapter.
+     *
+     * @param SuiteScopedResolverFactory $factory
+     */
+    public function __construct(SuiteScopedResolverFactory $factory)
+    {
+        $this->factory = $factory;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function createArgumentResolvers(Environment $environment)
+    {
+        return $this->factory->generateArgumentResolvers($environment->getSuite());
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Context/Cli/ContextSnippetsController.php b/vendor/behat/behat/src/Behat/Behat/Context/Cli/ContextSnippetsController.php
new file mode 100644 (file)
index 0000000..3a6edf6
--- /dev/null
@@ -0,0 +1,91 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Context\Cli;
+
+use Behat\Behat\Context\Snippet\Generator\AggregatePatternIdentifier;
+use Behat\Behat\Context\Snippet\Generator\ContextInterfaceBasedContextIdentifier;
+use Behat\Behat\Context\Snippet\Generator\ContextInterfaceBasedPatternIdentifier;
+use Behat\Behat\Context\Snippet\Generator\ContextSnippetGenerator;
+use Behat\Behat\Context\Snippet\Generator\FixedContextIdentifier;
+use Behat\Behat\Context\Snippet\Generator\FixedPatternIdentifier;
+use Behat\Behat\Context\Snippet\Generator\AggregateContextIdentifier;
+use Behat\Testwork\Cli\Controller;
+use Symfony\Component\Console\Command\Command as SymfonyCommand;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Translation\TranslatorInterface;
+
+/**
+ * Configures which context snippets are generated for.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class ContextSnippetsController implements Controller
+{
+    /**
+     * @var ContextSnippetGenerator
+     */
+    private $generator;
+    /**
+     * @var TranslatorInterface
+     */
+    private $translator;
+
+    /**
+     * Initialises controller.
+     *
+     * @param ContextSnippetGenerator $generator
+     * @param TranslatorInterface     $translator
+     */
+    public function __construct(ContextSnippetGenerator $generator, TranslatorInterface $translator)
+    {
+        $this->generator = $generator;
+        $this->translator = $translator;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function configure(SymfonyCommand $command)
+    {
+        $command
+            ->addOption(
+                '--snippets-for', null, InputOption::VALUE_OPTIONAL,
+                "Specifies which context class to generate snippets for."
+            )
+            ->addOption(
+                '--snippets-type', null, InputOption::VALUE_REQUIRED,
+                "Specifies which type of snippets (turnip, regex) to generate."
+            );
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function execute(InputInterface $input, OutputInterface $output)
+    {
+        $this->generator->setContextIdentifier(
+            new AggregateContextIdentifier(array(
+                new ContextInterfaceBasedContextIdentifier(),
+                new FixedContextIdentifier($input->getOption('snippets-for')),
+                new InteractiveContextIdentifier($this->translator, $input, $output)
+            ))
+        );
+
+        $this->generator->setPatternIdentifier(
+            new AggregatePatternIdentifier(array(
+                new ContextInterfaceBasedPatternIdentifier(),
+                new FixedPatternIdentifier($input->getOption('snippets-type'))
+            ))
+        );
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Context/Cli/InteractiveContextIdentifier.php b/vendor/behat/behat/src/Behat/Behat/Context/Cli/InteractiveContextIdentifier.php
new file mode 100644 (file)
index 0000000..c39488a
--- /dev/null
@@ -0,0 +1,114 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Context\Cli;
+
+use Behat\Behat\Context\Environment\ContextEnvironment;
+use Behat\Behat\Context\Snippet\Generator\TargetContextIdentifier;
+use Symfony\Component\Console\Helper\QuestionHelper;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Question\ChoiceQuestion;
+use Symfony\Component\Translation\TranslatorInterface;
+
+/**
+ * Interactive identifier that asks user for input.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class InteractiveContextIdentifier implements TargetContextIdentifier
+{
+    /**
+     * @var TranslatorInterface
+     */
+    private $translator;
+    /**
+     * @var InputInterface
+     */
+    private $input;
+    /**
+     * @var OutputInterface
+     */
+    private $output;
+
+    /**
+     * Initialises identifier.
+     *
+     * @param TranslatorInterface $translator
+     * @param InputInterface      $input
+     * @param OutputInterface     $output
+     */
+    public function __construct(TranslatorInterface $translator, InputInterface $input, OutputInterface $output)
+    {
+        $this->translator = $translator;
+        $this->input = $input;
+        $this->output = $output;
+    }
+    
+    /**
+     * {@inheritdoc}
+     */
+    public function guessTargetContextClass(ContextEnvironment $environment)
+    {
+        if ($this->interactionIsNotSupported()) {
+            return null;
+        }
+
+        $suiteName = $environment->getSuite()->getName();
+        $contextClasses = $environment->getContextClasses();
+
+        if (!count($contextClasses)) {
+            return null;
+        }
+
+        $message = $this->translator->trans('snippet_context_choice', array('%1%' => $suiteName), 'output');
+        $choices = array_values(array_merge(array('None'), $contextClasses));
+        $default = current($contextClasses);
+
+        $answer = $this->askQuestion('>> ' . $message, $choices, $default);
+
+        return 'None' !== $answer ? $answer : null;
+    }
+
+    /**
+     * Asks user question.
+     *
+     * @param string   $message
+     * @param string[] $choices
+     * @param string   $default
+     *
+     * @return string
+     */
+    private function askQuestion($message, $choices, $default)
+    {
+        $this->output->writeln('');
+        $helper = new QuestionHelper();
+        $question = new ChoiceQuestion(' ' . $message . "\n", $choices, $default);
+
+        return $helper->ask($this->input, $this->output, $question);
+    }
+
+    /**
+     * Checks if interactive mode is supported.
+     *
+     * @return Boolean
+     *
+     * @deprecated there is a better way to do it - `InputInterface::isInteractive()` method.
+     *             Sadly, this doesn't work properly prior Symfony\Console 2.7 and as we need
+     *             to support 2.5+ until the next major, we are forced to do a more explicit
+     *             check for the CLI option. This should be reverted back to proper a
+     *             `InputInterface::isInteractive()` call as soon as we bump dependencies
+     *             to Symfony\Console 3.x in Behat 4.x.
+     */
+    private function interactionIsNotSupported()
+    {
+        return $this->input->hasParameterOption('--no-interaction');
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Context/Context.php b/vendor/behat/behat/src/Behat/Behat/Context/Context.php
new file mode 100644 (file)
index 0000000..b9ac895
--- /dev/null
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Context;
+
+/**
+ * Marks a custom user-defined class as a behat context.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface Context
+{
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Context/ContextClass/ClassGenerator.php b/vendor/behat/behat/src/Behat/Behat/Context/ContextClass/ClassGenerator.php
new file mode 100644 (file)
index 0000000..d2a7409
--- /dev/null
@@ -0,0 +1,44 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Context\ContextClass;
+
+use Behat\Behat\Context\Suite\Setup\SuiteWithContextsSetup;
+use Behat\Testwork\Suite\Suite;
+
+/**
+ * Generates context classes (as a string).
+ *
+ * @see SuiteWithContextsSetup
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface ClassGenerator
+{
+    /**
+     * Checks if generator supports provided context class.
+     *
+     * @param Suite  $suite
+     * @param string $contextClass
+     *
+     * @return Boolean
+     */
+    public function supportsSuiteAndClass(Suite $suite, $contextClass);
+
+    /**
+     * Generates context class code.
+     *
+     * @param Suite  $suite
+     * @param string $contextClass
+     *
+     * @return string The context class source code
+     */
+    public function generateClass(Suite $suite, $contextClass);
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Context/ContextClass/ClassResolver.php b/vendor/behat/behat/src/Behat/Behat/Context/ContextClass/ClassResolver.php
new file mode 100644 (file)
index 0000000..464f68f
--- /dev/null
@@ -0,0 +1,41 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Context\ContextClass;
+
+use Behat\Behat\Context\Environment\Handler\ContextEnvironmentHandler;
+
+/**
+ * Resolves arbitrary context strings into a context classes.
+ *
+ * @see ContextEnvironmentHandler
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface ClassResolver
+{
+    /**
+     * Checks if resolvers supports provided class.
+     *
+     * @param string $contextString
+     *
+     * @return Boolean
+     */
+    public function supportsClass($contextString);
+
+    /**
+     * Resolves context class.
+     *
+     * @param string $contextClass
+     *
+     * @return string
+     */
+    public function resolveClass($contextClass);
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Context/ContextClass/SimpleClassGenerator.php b/vendor/behat/behat/src/Behat/Behat/Context/ContextClass/SimpleClassGenerator.php
new file mode 100644 (file)
index 0000000..f37ac44
--- /dev/null
@@ -0,0 +1,80 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Context\ContextClass;
+
+use Behat\Testwork\Suite\Suite;
+
+/**
+ * Generates basic PHP 5.3+ class with an optional namespace.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class SimpleClassGenerator implements ClassGenerator
+{
+    /**
+     * @var string
+     */
+    protected static $template = <<<'PHP'
+<?php
+
+{namespace}use Behat\Behat\Context\Context;
+use Behat\Gherkin\Node\PyStringNode;
+use Behat\Gherkin\Node\TableNode;
+
+/**
+ * Defines application features from the specific context.
+ */
+class {className} implements Context
+{
+    /**
+     * Initializes context.
+     *
+     * Every scenario gets its own context instance.
+     * You can also pass arbitrary arguments to the
+     * context constructor through behat.yml.
+     */
+    public function __construct()
+    {
+    }
+}
+
+PHP;
+
+    /**
+     * {@inheritdoc}
+     */
+    public function supportsSuiteAndClass(Suite $suite, $contextClass)
+    {
+        return true;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function generateClass(Suite $suite, $contextClass)
+    {
+        $fqn = $contextClass;
+
+        $namespace = '';
+        if (false !== $pos = strrpos($fqn, '\\')) {
+            $namespace = 'namespace ' . substr($fqn, 0, $pos) . ";\n\n";
+            $contextClass = substr($fqn, $pos + 1);
+        }
+
+        return strtr(
+            static::$template,
+            array(
+                '{namespace}' => $namespace,
+                '{className}' => $contextClass,
+            )
+        );
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Context/ContextFactory.php b/vendor/behat/behat/src/Behat/Behat/Context/ContextFactory.php
new file mode 100644 (file)
index 0000000..b7a2442
--- /dev/null
@@ -0,0 +1,150 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Context;
+
+use Behat\Testwork\Argument\Validator;
+use Behat\Behat\Context\Argument\ArgumentResolver;
+use Behat\Behat\Context\Initializer\ContextInitializer;
+use Behat\Testwork\Argument\ArgumentOrganiser;
+use ReflectionClass;
+
+/**
+ * Instantiates contexts using registered argument resolvers and context initializers.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class ContextFactory
+{
+    /**
+     * @var ArgumentOrganiser
+     */
+    private $argumentOrganiser;
+    /**
+     * @var ArgumentResolver[]
+     */
+    private $argumentResolvers = array();
+    /**
+     * @var ContextInitializer[]
+     */
+    private $contextInitializers = array();
+    /**
+     * @var Validator
+     */
+    private $validator;
+
+    /**
+     * Initialises factory.
+     *
+     * @param ArgumentOrganiser $argumentOrganiser
+     */
+    public function __construct(ArgumentOrganiser $argumentOrganiser)
+    {
+        $this->argumentOrganiser = $argumentOrganiser;
+        $this->validator = new Validator();
+    }
+
+    /**
+     * Registers context argument resolver.
+     *
+     * @param ArgumentResolver $resolver
+     */
+    public function registerArgumentResolver(ArgumentResolver $resolver)
+    {
+        $this->argumentResolvers[] = $resolver;
+    }
+
+    /**
+     * Registers context initializer.
+     *
+     * @param ContextInitializer $initializer
+     */
+    public function registerContextInitializer(ContextInitializer $initializer)
+    {
+        $this->contextInitializers[] = $initializer;
+    }
+
+    /**
+     * Creates and initializes context class.
+     *
+     * @param string             $class
+     * @param array              $arguments
+     * @param ArgumentResolver[] $singleUseResolvers
+     *
+     * @return Context
+     */
+    public function createContext($class, array $arguments = array(), array $singleUseResolvers = array())
+    {
+        $reflection = new ReflectionClass($class);
+        $resolvers = array_merge($singleUseResolvers, $this->argumentResolvers);
+        $resolvedArguments = $this->resolveArguments($reflection, $arguments, $resolvers);
+        $context = $this->createInstance($reflection, $resolvedArguments);
+        $this->initializeInstance($context);
+
+        return $context;
+    }
+
+    /**
+     * Resolves arguments for a specific class using registered argument resolvers.
+     *
+     * @param ReflectionClass    $reflection
+     * @param array              $arguments
+     * @param ArgumentResolver[] $resolvers
+     *
+     * @return mixed[]
+     */
+    private function resolveArguments(ReflectionClass $reflection, array $arguments, array $resolvers)
+    {
+        $newArguments = $arguments;
+
+        foreach ($resolvers as $resolver) {
+            $newArguments = $resolver->resolveArguments($reflection, $newArguments);
+        }
+
+        if (!$reflection->hasMethod('__construct')) {
+            return $newArguments;
+        }
+
+        $constructor = $reflection->getConstructor();
+        $newArguments = $this->argumentOrganiser->organiseArguments($constructor, $newArguments);
+        $this->validator->validateArguments($constructor, $newArguments);
+
+        return $newArguments;
+    }
+
+    /**
+     * Creates context instance.
+     *
+     * @param ReflectionClass $reflection
+     * @param array           $arguments
+     *
+     * @return mixed
+     */
+    private function createInstance(ReflectionClass $reflection, array $arguments)
+    {
+        if (count($arguments)) {
+            return $reflection->newInstanceArgs($arguments);
+        }
+
+        return $reflection->newInstance();
+    }
+
+    /**
+     * Initializes context class and returns new context instance.
+     *
+     * @param Context $context
+     */
+    private function initializeInstance(Context $context)
+    {
+        foreach ($this->contextInitializers as $initializer) {
+            $initializer->initializeContext($context);
+        }
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Context/CustomSnippetAcceptingContext.php b/vendor/behat/behat/src/Behat/Behat/Context/CustomSnippetAcceptingContext.php
new file mode 100644 (file)
index 0000000..5090d30
--- /dev/null
@@ -0,0 +1,34 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Context;
+
+use Behat\Behat\Context\Snippet\Generator\ContextSnippetGenerator;
+
+/**
+ * Context that implements this interface is treated as a custom-snippet-friendly context.
+ *
+ * @see ContextSnippetGenerator
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * @deprecated will be removed in 4.0. Use --snippets-for and --snippets-type CLI options instead
+ */
+interface CustomSnippetAcceptingContext extends SnippetAcceptingContext
+{
+    /**
+     * Returns type of the snippets that this context accepts. 
+     * 
+     * Behat implements a couple of types by default: "regex" and "turnip"
+     *
+     * @return string
+     */
+    public static function getAcceptedSnippetType();
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Context/Environment/ContextEnvironment.php b/vendor/behat/behat/src/Behat/Behat/Context/Environment/ContextEnvironment.php
new file mode 100644 (file)
index 0000000..690eebb
--- /dev/null
@@ -0,0 +1,47 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Context\Environment;
+
+use Behat\Behat\Context\Environment\Handler\ContextEnvironmentHandler;
+use Behat\Testwork\Environment\Environment;
+
+/**
+ * Represents test environment based on a collection of contexts.
+ *
+ * @see ContextEnvironmentHandler
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface ContextEnvironment extends Environment
+{
+    /**
+     * Checks if environment has any contexts registered.
+     *
+     * @return Boolean
+     */
+    public function hasContexts();
+
+    /**
+     * Returns list of registered context classes.
+     *
+     * @return string[]
+     */
+    public function getContextClasses();
+
+    /**
+     * Checks if environment contains context with the specified class name.
+     *
+     * @param string $class
+     *
+     * @return Boolean
+     */
+    public function hasContextClass($class);
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Context/Environment/Handler/ContextEnvironmentHandler.php b/vendor/behat/behat/src/Behat/Behat/Context/Environment/Handler/ContextEnvironmentHandler.php
new file mode 100644 (file)
index 0000000..d686400
--- /dev/null
@@ -0,0 +1,194 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Context\Environment\Handler;
+
+use Behat\Behat\Context\Argument\SuiteScopedResolverFactory;
+use Behat\Behat\Context\Argument\SuiteScopedResolverFactoryAdapter;
+use Behat\Behat\Context\Argument\ArgumentResolverFactory;
+use Behat\Behat\Context\Argument\NullFactory;
+use Behat\Behat\Context\ContextClass\ClassResolver;
+use Behat\Behat\Context\ContextFactory;
+use Behat\Behat\Context\Environment\InitializedContextEnvironment;
+use Behat\Behat\Context\Environment\UninitializedContextEnvironment;
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\Environment\Exception\EnvironmentIsolationException;
+use Behat\Testwork\Environment\Handler\EnvironmentHandler;
+use Behat\Testwork\Suite\Exception\SuiteConfigurationException;
+use Behat\Testwork\Suite\Suite;
+
+/**
+ * Handles build and initialisation of the context-based environments.
+ *
+ * @see ContextFactory
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class ContextEnvironmentHandler implements EnvironmentHandler
+{
+    /**
+     * @var ContextFactory
+     */
+    private $contextFactory;
+    /**
+     * @var ArgumentResolverFactory
+     */
+    private $resolverFactory;
+    /**
+     * @var ClassResolver[]
+     */
+    private $classResolvers = array();
+
+    /**
+     * Initializes handler.
+     *
+     * @param ContextFactory                                     $factory
+     * @param ArgumentResolverFactory|SuiteScopedResolverFactory $resolverFactory
+     */
+    public function __construct(ContextFactory $factory, $resolverFactory = null)
+    {
+        $this->contextFactory = $factory;
+
+        if ($resolverFactory && !$resolverFactory instanceof ArgumentResolverFactory) {
+            $resolverFactory = new SuiteScopedResolverFactoryAdapter($resolverFactory);
+        }
+
+        $this->resolverFactory = $resolverFactory ?: new NullFactory();
+    }
+
+    /**
+     * Registers context class resolver.
+     *
+     * @param ClassResolver $resolver
+     */
+    public function registerClassResolver(ClassResolver $resolver)
+    {
+        $this->classResolvers[] = $resolver;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function supportsSuite(Suite $suite)
+    {
+        return $suite->hasSetting('contexts');
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function buildEnvironment(Suite $suite)
+    {
+        $environment = new UninitializedContextEnvironment($suite);
+        foreach ($this->getNormalizedContextSettings($suite) as $context) {
+            $environment->registerContextClass($this->resolveClass($context[0]), $context[1]);
+        }
+
+        return $environment;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function supportsEnvironmentAndSubject(Environment $environment, $testSubject = null)
+    {
+        return $environment instanceof UninitializedContextEnvironment;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function isolateEnvironment(Environment $uninitializedEnvironment, $testSubject = null)
+    {
+        if (!$uninitializedEnvironment instanceof UninitializedContextEnvironment) {
+            throw new EnvironmentIsolationException(sprintf(
+                'ContextEnvironmentHandler does not support isolation of `%s` environment.',
+                get_class($uninitializedEnvironment)
+            ), $uninitializedEnvironment);
+        }
+
+        $environment = new InitializedContextEnvironment($uninitializedEnvironment->getSuite());
+        $resolvers = $this->resolverFactory->createArgumentResolvers($environment);
+
+        foreach ($uninitializedEnvironment->getContextClassesWithArguments() as $class => $arguments) {
+            $context = $this->contextFactory->createContext($class, $arguments, $resolvers);
+            $environment->registerContext($context);
+        }
+
+        return $environment;
+    }
+
+    /**
+     * Returns normalized suite context settings.
+     *
+     * @param Suite $suite
+     *
+     * @return array
+     */
+    private function getNormalizedContextSettings(Suite $suite)
+    {
+        return array_map(
+            function ($context) {
+                $class = $context;
+                $arguments = array();
+
+                if (is_array($context)) {
+                    $class = current(array_keys($context));
+                    $arguments = $context[$class];
+                }
+
+                return array($class, $arguments);
+            },
+            $this->getSuiteContexts($suite)
+        );
+    }
+
+    /**
+     * Returns array of context classes configured for the provided suite.
+     *
+     * @param Suite $suite
+     *
+     * @return string[]
+     *
+     * @throws SuiteConfigurationException If `contexts` setting is not an array
+     */
+    private function getSuiteContexts(Suite $suite)
+    {
+        if (!is_array($suite->getSetting('contexts'))) {
+            throw new SuiteConfigurationException(
+                sprintf('`contexts` setting of the "%s" suite is expected to be an array, %s given.',
+                    $suite->getName(),
+                    gettype($suite->getSetting('contexts'))
+                ),
+                $suite->getName()
+            );
+        }
+
+        return $suite->getSetting('contexts');
+    }
+
+    /**
+     * Resolves class using registered class resolvers.
+     *
+     * @param string $class
+     *
+     * @return string
+     */
+    private function resolveClass($class)
+    {
+        foreach ($this->classResolvers as $resolver) {
+            if ($resolver->supportsClass($class)) {
+                return $resolver->resolveClass($class);
+            }
+        }
+
+        return $class;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Context/Environment/InitializedContextEnvironment.php b/vendor/behat/behat/src/Behat/Behat/Context/Environment/InitializedContextEnvironment.php
new file mode 100644 (file)
index 0000000..0533549
--- /dev/null
@@ -0,0 +1,155 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Context\Environment;
+
+use Behat\Behat\Context\Context;
+use Behat\Behat\Context\Environment\Handler\ContextEnvironmentHandler;
+use Behat\Behat\Context\Exception\ContextNotFoundException;
+use Behat\Behat\HelperContainer\Environment\ServiceContainerEnvironment;
+use Behat\Testwork\Call\Callee;
+use Behat\Testwork\Suite\Suite;
+use Psr\Container\ContainerInterface;
+
+/**
+ * Context environment based on a list of instantiated context objects.
+ *
+ * @see ContextEnvironmentHandler
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class InitializedContextEnvironment implements ContextEnvironment, ServiceContainerEnvironment
+{
+    /**
+     * @var string
+     */
+    private $suite;
+    /**
+     * @var ContainerInterface
+     */
+    private $serviceContainer;
+    /**
+     * @var Context[]
+     */
+    private $contexts = array();
+
+    /**
+     * Initializes environment.
+     *
+     * @param Suite $suite
+     */
+    public function __construct(Suite $suite)
+    {
+        $this->suite = $suite;
+    }
+
+    /**
+     * Registers context instance in the environment.
+     *
+     * @param Context $context
+     */
+    public function registerContext(Context $context)
+    {
+        $this->contexts[get_class($context)] = $context;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setServiceContainer(ContainerInterface $container = null)
+    {
+        $this->serviceContainer = $container;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getSuite()
+    {
+        return $this->suite;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function hasContexts()
+    {
+        return count($this->contexts) > 0;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getContextClasses()
+    {
+        return array_keys($this->contexts);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function hasContextClass($class)
+    {
+        return isset($this->contexts[$class]);
+    }
+
+    /**
+     * Returns list of registered context instances.
+     *
+     * @return Context[]
+     */
+    public function getContexts()
+    {
+        return array_values($this->contexts);
+    }
+
+    /**
+     * Returns registered context by its class name.
+     *
+     * @param string $class
+     *
+     * @return Context
+     *
+     * @throws ContextNotFoundException If context is not in the environment
+     */
+    public function getContext($class)
+    {
+        if (!$this->hasContextClass($class)) {
+            throw new ContextNotFoundException(sprintf(
+                '`%s` context is not found in the suite environment. Have you registered it?',
+                $class
+            ), $class);
+        }
+
+        return $this->contexts[$class];
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getServiceContainer()
+    {
+        return $this->serviceContainer;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function bindCallee(Callee $callee)
+    {
+        $callable = $callee->getCallable();
+
+        if ($callee->isAnInstanceMethod()) {
+            return array($this->getContext($callable[0]), $callable[1]);
+        }
+
+        return $callable;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Context/Environment/Reader/ContextEnvironmentReader.php b/vendor/behat/behat/src/Behat/Behat/Context/Environment/Reader/ContextEnvironmentReader.php
new file mode 100644 (file)
index 0000000..71759e9
--- /dev/null
@@ -0,0 +1,93 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Context\Environment\Reader;
+
+use Behat\Behat\Context\Environment\ContextEnvironment;
+use Behat\Behat\Context\Reader\ContextReader;
+use Behat\Testwork\Call\Callee;
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\Environment\Exception\EnvironmentReadException;
+use Behat\Testwork\Environment\Reader\EnvironmentReader;
+
+/**
+ * Reads context-based environment callees using registered context loaders.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class ContextEnvironmentReader implements EnvironmentReader
+{
+    /**
+     * @var ContextReader[]
+     */
+    private $contextReaders = array();
+
+    /**
+     * Registers context loader.
+     *
+     * @param ContextReader $contextReader
+     */
+    public function registerContextReader(ContextReader $contextReader)
+    {
+        $this->contextReaders[] = $contextReader;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function supportsEnvironment(Environment $environment)
+    {
+        return $environment instanceof ContextEnvironment;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function readEnvironmentCallees(Environment $environment)
+    {
+        if (!$environment instanceof ContextEnvironment) {
+            throw new EnvironmentReadException(sprintf(
+                'ContextEnvironmentReader does not support `%s` environment.',
+                get_class($environment)
+            ), $environment);
+        }
+
+        $callees = array();
+        foreach ($environment->getContextClasses() as $contextClass) {
+            $callees = array_merge(
+                $callees,
+                $this->readContextCallees($environment, $contextClass)
+            );
+        }
+
+        return $callees;
+    }
+
+    /**
+     * Reads callees from a specific suite's context.
+     *
+     * @param ContextEnvironment $environment
+     * @param string             $contextClass
+     *
+     * @return Callee[]
+     */
+    private function readContextCallees(ContextEnvironment $environment, $contextClass)
+    {
+        $callees = array();
+        foreach ($this->contextReaders as $loader) {
+            $callees = array_merge(
+                $callees,
+                $loader->readContextCallees($environment, $contextClass)
+            );
+        }
+
+        return $callees;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Context/Environment/UninitializedContextEnvironment.php b/vendor/behat/behat/src/Behat/Behat/Context/Environment/UninitializedContextEnvironment.php
new file mode 100644 (file)
index 0000000..d0ff985
--- /dev/null
@@ -0,0 +1,95 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Context\Environment;
+
+use Behat\Behat\Context\Environment\Handler\ContextEnvironmentHandler;
+use Behat\Behat\Context\Exception\ContextNotFoundException;
+use Behat\Behat\Context\Exception\WrongContextClassException;
+use Behat\Testwork\Environment\StaticEnvironment;
+
+/**
+ * Context environment based on a list of context classes.
+ *
+ * @see ContextEnvironmentHandler
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class UninitializedContextEnvironment extends StaticEnvironment implements ContextEnvironment
+{
+    /**
+     * @var array[]
+     */
+    private $contextClasses = array();
+
+    /**
+     * Registers context class.
+     *
+     * @param string     $contextClass
+     * @param null|array $arguments
+     *
+     * @throws ContextNotFoundException   If class does not exist
+     * @throws WrongContextClassException if class does not implement Context interface
+     */
+    public function registerContextClass($contextClass, array $arguments = null)
+    {
+        if (!class_exists($contextClass)) {
+            throw new ContextNotFoundException(sprintf(
+                '`%s` context class not found and can not be used.',
+                $contextClass
+            ), $contextClass);
+        }
+
+        $reflClass = new \ReflectionClass($contextClass);
+
+        if (!$reflClass->implementsInterface('Behat\Behat\Context\Context')) {
+            throw new WrongContextClassException(sprintf(
+                'Every context class must implement Behat Context interface, but `%s` does not.',
+                $contextClass
+            ), $contextClass);
+        }
+
+        $this->contextClasses[$contextClass] = $arguments ? : array();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function hasContexts()
+    {
+        return count($this->contextClasses) > 0;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getContextClasses()
+    {
+        return array_keys($this->contextClasses);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function hasContextClass($class)
+    {
+        return isset($this->contextClasses[$class]);
+    }
+
+    /**
+     * Returns context classes with their arguments.
+     *
+     * @return array[]
+     */
+    public function getContextClassesWithArguments()
+    {
+        return $this->contextClasses;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Context/Exception/ContextException.php b/vendor/behat/behat/src/Behat/Behat/Context/Exception/ContextException.php
new file mode 100644 (file)
index 0000000..bc1a427
--- /dev/null
@@ -0,0 +1,22 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Context\Exception;
+
+use Behat\Testwork\Exception\TestworkException;
+
+/**
+ * Represents an exception thrown during context handling.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface ContextException extends TestworkException
+{
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Context/Exception/ContextNotFoundException.php b/vendor/behat/behat/src/Behat/Behat/Context/Exception/ContextNotFoundException.php
new file mode 100644 (file)
index 0000000..64cfde9
--- /dev/null
@@ -0,0 +1,49 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Context\Exception;
+
+use InvalidArgumentException;
+
+/**
+ * Represents an exception thrown when provided context class is not found.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class ContextNotFoundException extends InvalidArgumentException implements ContextException
+{
+    /**
+     * @var string
+     */
+    private $class;
+
+    /**
+     * Initializes exception.
+     *
+     * @param string $message
+     * @param string $class
+     */
+    public function __construct($message, $class)
+    {
+        $this->class = $class;
+
+        parent::__construct($message);
+    }
+
+    /**
+     * Returns not found classname.
+     *
+     * @return string
+     */
+    public function getClass()
+    {
+        return $this->class;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Context/Exception/UnknownTranslationResourceException.php b/vendor/behat/behat/src/Behat/Behat/Context/Exception/UnknownTranslationResourceException.php
new file mode 100644 (file)
index 0000000..2c4a761
--- /dev/null
@@ -0,0 +1,49 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Context\Exception;
+
+use InvalidArgumentException;
+
+/**
+ * Represents an exception when provided translation resource is not recognised.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class UnknownTranslationResourceException extends InvalidArgumentException implements ContextException
+{
+    /**
+     * @var string
+     */
+    private $resource;
+
+    /**
+     * Initializes exception.
+     *
+     * @param string $message
+     * @param string $class
+     */
+    public function __construct($message, $class)
+    {
+        $this->resource = $class;
+
+        parent::__construct($message);
+    }
+
+    /**
+     * Returns unsupported resource.
+     *
+     * @return string
+     */
+    public function getResource()
+    {
+        return $this->resource;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Context/Exception/WrongContextClassException.php b/vendor/behat/behat/src/Behat/Behat/Context/Exception/WrongContextClassException.php
new file mode 100644 (file)
index 0000000..69ccc8c
--- /dev/null
@@ -0,0 +1,49 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Context\Exception;
+
+use InvalidArgumentException;
+
+/**
+ * Represents an exception when provided class exists, but is not an acceptable as a context.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class WrongContextClassException extends InvalidArgumentException implements ContextException
+{
+    /**
+     * @var string
+     */
+    private $class;
+
+    /**
+     * Initializes exception.
+     *
+     * @param integer $message
+     * @param string  $class
+     */
+    public function __construct($message, $class)
+    {
+        $this->class = $class;
+
+        parent::__construct($message);
+    }
+
+    /**
+     * Returns not found classname.
+     *
+     * @return string
+     */
+    public function getClass()
+    {
+        return $this->class;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Context/Initializer/ContextInitializer.php b/vendor/behat/behat/src/Behat/Behat/Context/Initializer/ContextInitializer.php
new file mode 100644 (file)
index 0000000..3d2b356
--- /dev/null
@@ -0,0 +1,28 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Context\Initializer;
+
+use Behat\Behat\Context\Context;
+
+/**
+ * Initializes contexts using custom logic.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface ContextInitializer
+{
+    /**
+     * Initializes provided context.
+     *
+     * @param Context $context
+     */
+    public function initializeContext(Context $context);
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Context/Reader/AnnotatedContextReader.php b/vendor/behat/behat/src/Behat/Behat/Context/Reader/AnnotatedContextReader.php
new file mode 100644 (file)
index 0000000..a314474
--- /dev/null
@@ -0,0 +1,245 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Context\Reader;
+
+use Behat\Behat\Context\Annotation\AnnotationReader;
+use Behat\Behat\Context\Environment\ContextEnvironment;
+use Behat\Testwork\Call\Callee;
+use ReflectionClass;
+use ReflectionException;
+use ReflectionMethod;
+
+/**
+ * Reads context callees by annotations using registered annotation readers.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class AnnotatedContextReader implements ContextReader
+{
+    const DOCLINE_TRIMMER_REGEX = '/^\/\*\*\s*|^\s*\*\s*|\s*\*\/$|\s*$/';
+
+    /**
+     * @var string[]
+     */
+    private static $ignoreAnnotations = array(
+        '@param',
+        '@return',
+        '@throws',
+        '@see',
+        '@uses',
+        '@todo'
+    );
+    /**
+     * @var AnnotationReader[]
+     */
+    private $readers = array();
+
+    /**
+     * Registers annotation reader.
+     *
+     * @param AnnotationReader $reader
+     */
+    public function registerAnnotationReader(AnnotationReader $reader)
+    {
+        $this->readers[] = $reader;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function readContextCallees(ContextEnvironment $environment, $contextClass)
+    {
+        $reflection = new ReflectionClass($contextClass);
+
+        $callees = array();
+        foreach ($reflection->getMethods(ReflectionMethod::IS_PUBLIC) as $method) {
+            foreach ($this->readMethodCallees($reflection->getName(), $method) as $callee) {
+                $callees[] = $callee;
+            }
+        }
+
+        return $callees;
+    }
+
+    /**
+     * Loads callees associated with specific method.
+     *
+     * @param string           $class
+     * @param ReflectionMethod $method
+     *
+     * @return Callee[]
+     */
+    private function readMethodCallees($class, ReflectionMethod $method)
+    {
+        $callees = array();
+
+        // read parent annotations
+        try {
+            $prototype = $method->getPrototype();
+            // error occurs on every second PHP stable release - getPrototype() returns itself
+            if ($prototype->getDeclaringClass()->getName() !== $method->getDeclaringClass()->getName()) {
+                $callees = array_merge($callees, $this->readMethodCallees($class, $prototype));
+            }
+        } catch (ReflectionException $e) {
+        }
+
+        if ($docBlock = $method->getDocComment()) {
+            $callees = array_merge($callees, $this->readDocBlockCallees($class, $method, $docBlock));
+        }
+
+        return $callees;
+    }
+
+    /**
+     * Reads callees from the method doc block.
+     *
+     * @param string           $class
+     * @param ReflectionMethod $method
+     * @param string           $docBlock
+     *
+     * @return Callee[]
+     */
+    private function readDocBlockCallees($class, ReflectionMethod $method, $docBlock)
+    {
+        $callees = array();
+        $description = $this->readDescription($docBlock);
+        $docBlock = $this->mergeMultilines($docBlock);
+
+        foreach (explode("\n", $docBlock) as $docLine) {
+            $docLine = preg_replace(self::DOCLINE_TRIMMER_REGEX, '', $docLine);
+
+            if ($this->isEmpty($docLine)) {
+                continue;
+            }
+
+            if ($this->isNotAnnotation($docLine)) {
+                continue;
+            }
+
+            if ($callee = $this->readDocLineCallee($class, $method, $docLine, $description)) {
+                $callees[] = $callee;
+            }
+        }
+
+        return $callees;
+    }
+
+    /**
+     * Merges multiline strings (strings ending with "\")
+     *
+     * @param string $docBlock
+     *
+     * @return string
+     */
+    private function mergeMultilines($docBlock)
+    {
+        return preg_replace("#\\\\$\s*+\*\s*+([^\\\\$]++)#m", '$1', $docBlock);
+    }
+
+    /**
+     * Extracts a description from the provided docblock,
+     * with support for multiline descriptions.
+     *
+     * @param string $docBlock
+     *
+     * @return string
+     */
+    private function readDescription($docBlock)
+    {
+        // Remove indentation
+        $description = preg_replace('/^[\s\t]*/m', '', $docBlock);
+
+        // Remove block comment syntax
+        $description = preg_replace('/^\/\*\*\s*|^\s*\*\s|^\s*\*\/$/m', '', $description);
+
+        // Remove annotations
+        $description = preg_replace('/^@.*$/m', '', $description);
+
+        // Ignore docs after a "--" separator
+        if (preg_match('/^--.*$/m', $description)) {
+            $descriptionParts = preg_split('/^--.*$/m', $description);
+            $description = array_shift($descriptionParts);
+        }
+
+        // Trim leading and trailing newlines
+        $description = trim($description, "\r\n");
+
+        return $description;
+    }
+
+    /**
+     * Checks if provided doc lien is empty.
+     *
+     * @param string $docLine
+     *
+     * @return Boolean
+     */
+    private function isEmpty($docLine)
+    {
+        return '' == $docLine;
+    }
+
+    /**
+     * Checks if provided doc line is not an annotation.
+     *
+     * @param string $docLine
+     *
+     * @return Boolean
+     */
+    private function isNotAnnotation($docLine)
+    {
+        return '@' !== substr($docLine, 0, 1);
+    }
+
+    /**
+     * Reads callee from provided doc line using registered annotation readers.
+     *
+     * @param string           $class
+     * @param ReflectionMethod $method
+     * @param string           $docLine
+     * @param null|string      $description
+     *
+     * @return null|Callee
+     */
+    private function readDocLineCallee($class, ReflectionMethod $method, $docLine, $description = null)
+    {
+        if ($this->isIgnoredAnnotation($docLine)) {
+            return null;
+        }
+
+        foreach ($this->readers as $reader) {
+            if ($callee = $reader->readCallee($class, $method, $docLine, $description)) {
+                return $callee;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Checks if provided doc line is one of the ignored annotations.
+     *
+     * @param string $docLine
+     *
+     * @return Boolean
+     */
+    private function isIgnoredAnnotation($docLine)
+    {
+        $lowDocLine = strtolower($docLine);
+        foreach (self::$ignoreAnnotations as $ignoredAnnotation) {
+            if ($ignoredAnnotation == substr($lowDocLine, 0, strlen($ignoredAnnotation))) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Context/Reader/ContextReader.php b/vendor/behat/behat/src/Behat/Behat/Context/Reader/ContextReader.php
new file mode 100644 (file)
index 0000000..b8a9156
--- /dev/null
@@ -0,0 +1,32 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Context\Reader;
+
+use Behat\Behat\Context\Environment\ContextEnvironment;
+use Behat\Testwork\Call\Callee;
+
+/**
+ * Reads callees from a context class.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface ContextReader
+{
+    /**
+     * Reads callees from specific environment & context.
+     *
+     * @param ContextEnvironment $environment
+     * @param string             $contextClass
+     *
+     * @return Callee[]
+     */
+    public function readContextCallees(ContextEnvironment $environment, $contextClass);
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Context/Reader/ContextReaderCachedPerContext.php b/vendor/behat/behat/src/Behat/Behat/Context/Reader/ContextReaderCachedPerContext.php
new file mode 100644 (file)
index 0000000..8a51662
--- /dev/null
@@ -0,0 +1,54 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Context\Reader;
+
+use Behat\Behat\Context\Environment\ContextEnvironment;
+
+/**
+ * Proxies call to another reader and caches context callees for a length of an entire exercise.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class ContextReaderCachedPerContext implements ContextReader
+{
+    /**
+     * @var ContextReader
+     */
+    private $childReader;
+    /**
+     * @var array[]
+     */
+    private $cachedCallees = array();
+
+    /**
+     * Initializes reader.
+     *
+     * @param ContextReader $childReader
+     */
+    public function __construct(ContextReader $childReader)
+    {
+        $this->childReader = $childReader;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function readContextCallees(ContextEnvironment $environment, $contextClass)
+    {
+        if (isset($this->cachedCallees[$contextClass])) {
+            return $this->cachedCallees[$contextClass];
+        }
+
+        return $this->cachedCallees[$contextClass] = $this->childReader->readContextCallees(
+            $environment, $contextClass
+        );
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Context/Reader/ContextReaderCachedPerSuite.php b/vendor/behat/behat/src/Behat/Behat/Context/Reader/ContextReaderCachedPerSuite.php
new file mode 100644 (file)
index 0000000..4a8bfd5
--- /dev/null
@@ -0,0 +1,69 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Context\Reader;
+
+use Behat\Behat\Context\Environment\ContextEnvironment;
+
+/**
+ * Proxies call to another reader and caches callees for a length of an entire suite.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class ContextReaderCachedPerSuite implements ContextReader
+{
+    /**
+     * @var ContextReader
+     */
+    private $childReader;
+    /**
+     * @var array[]
+     */
+    private $cachedCallees = array();
+
+    /**
+     * Initializes reader.
+     *
+     * @param ContextReader $childReader
+     */
+    public function __construct(ContextReader $childReader)
+    {
+        $this->childReader = $childReader;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function readContextCallees(ContextEnvironment $environment, $contextClass)
+    {
+        $key = $this->generateCacheKey($environment, $contextClass);
+
+        if (isset($this->cachedCallees[$key])) {
+            return $this->cachedCallees[$key];
+        }
+
+        return $this->cachedCallees[$key] = $this->childReader->readContextCallees(
+            $environment, $contextClass
+        );
+    }
+
+    /**
+     * Generates cache key.
+     *
+     * @param ContextEnvironment $environment
+     * @param string             $contextClass
+     *
+     * @return string
+     */
+    private function generateCacheKey(ContextEnvironment $environment, $contextClass)
+    {
+        return $environment->getSuite()->getName() . $contextClass;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Context/Reader/TranslatableContextReader.php b/vendor/behat/behat/src/Behat/Behat/Context/Reader/TranslatableContextReader.php
new file mode 100644 (file)
index 0000000..11327ee
--- /dev/null
@@ -0,0 +1,101 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Context\Reader;
+
+use Behat\Behat\Context\Environment\ContextEnvironment;
+use Behat\Behat\Context\Exception\UnknownTranslationResourceException;
+use Behat\Behat\Context\TranslatableContext;
+use Symfony\Component\Translation\Translator;
+
+/**
+ * Reads translation resources from translatable contexts.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class TranslatableContextReader implements ContextReader
+{
+    /**
+     * @var Translator
+     */
+    private $translator;
+
+    /**
+     * Initializes loader.
+     *
+     * @param Translator $translator
+     */
+    public function __construct(Translator $translator)
+    {
+        $this->translator = $translator;
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @see TranslatableContext
+     */
+    public function readContextCallees(ContextEnvironment $environment, $contextClass)
+    {
+        $reflClass = new \ReflectionClass($contextClass);
+
+        if (!$reflClass->implementsInterface('Behat\Behat\Context\TranslatableContext')) {
+            return array();
+        }
+
+        $assetsId = $environment->getSuite()->getName();
+        foreach (call_user_func(array($contextClass, 'getTranslationResources')) as $path) {
+            $this->addTranslationResource($path, $assetsId);
+        }
+
+        return array();
+    }
+
+    /**
+     * Adds translation resource.
+     *
+     * @param string $path
+     * @param string $assetsId
+     *
+     * @throws UnknownTranslationResourceException
+     */
+    private function addTranslationResource($path, $assetsId)
+    {
+        switch ($ext = pathinfo($path, PATHINFO_EXTENSION)) {
+            case 'yml':
+                $this->addTranslatorResource('yaml', $path, basename($path, '.' . $ext), $assetsId);
+                break;
+            case 'xliff':
+                $this->addTranslatorResource('xliff', $path, basename($path, '.' . $ext), $assetsId);
+                break;
+            case 'php':
+                $this->addTranslatorResource('php', $path, basename($path, '.' . $ext), $assetsId);
+                break;
+            default:
+                throw new UnknownTranslationResourceException(sprintf(
+                    'Can not read translations from `%s`. File type is not supported.',
+                    $path
+                ), $path);
+        }
+    }
+
+    /**
+     * Adds resource to translator instance.
+     *
+     * @param string $type
+     * @param string $path
+     * @param string $language
+     * @param string $assetsId
+     */
+    private function addTranslatorResource($type, $path, $language, $assetsId)
+    {
+        $this->translator->addResource($type, $path, $language, $assetsId);
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Context/ServiceContainer/ContextExtension.php b/vendor/behat/behat/src/Behat/Behat/Context/ServiceContainer/ContextExtension.php
new file mode 100644 (file)
index 0000000..f4c6917
--- /dev/null
@@ -0,0 +1,416 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Context\ServiceContainer;
+
+use Behat\Behat\Definition\ServiceContainer\DefinitionExtension;
+use Behat\Behat\Snippet\ServiceContainer\SnippetExtension;
+use Behat\Testwork\Argument\ServiceContainer\ArgumentExtension;
+use Behat\Testwork\Autoloader\ServiceContainer\AutoloaderExtension;
+use Behat\Testwork\Cli\ServiceContainer\CliExtension;
+use Behat\Testwork\Environment\ServiceContainer\EnvironmentExtension;
+use Behat\Testwork\Filesystem\ServiceContainer\FilesystemExtension;
+use Behat\Testwork\ServiceContainer\Extension;
+use Behat\Testwork\ServiceContainer\ExtensionManager;
+use Behat\Testwork\ServiceContainer\ServiceProcessor;
+use Behat\Testwork\Suite\ServiceContainer\SuiteExtension;
+use Behat\Testwork\Translator\ServiceContainer\TranslatorExtension;
+use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Definition;
+use Symfony\Component\DependencyInjection\Reference;
+
+/**
+ * Behat context extension.
+ *
+ * Extends Behat with context services.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class ContextExtension implements Extension
+{
+    /**
+     * Available services
+     */
+    const FACTORY_ID = 'context.factory';
+    const CONTEXT_SNIPPET_GENERATOR_ID = 'snippet.generator.context';
+    const AGGREGATE_RESOLVER_FACTORY_ID = 'context.argument.aggregate_resolver_factory';
+
+    /*
+     * Available extension points
+     */
+    const CLASS_RESOLVER_TAG = 'context.class_resolver';
+    const ARGUMENT_RESOLVER_TAG = 'context.argument_resolver';
+    const INITIALIZER_TAG = 'context.initializer';
+    const READER_TAG = 'context.reader';
+    const ANNOTATION_READER_TAG = 'context.annotation_reader';
+    const CLASS_GENERATOR_TAG = 'context.class_generator';
+    const SUITE_SCOPED_RESOLVER_FACTORY_TAG = 'context.argument.suite_resolver_factory';
+
+    /**
+     * @var ServiceProcessor
+     */
+    private $processor;
+
+    /**
+     * Initializes compiler pass.
+     *
+     * @param null|ServiceProcessor $processor
+     */
+    public function __construct(ServiceProcessor $processor = null)
+    {
+        $this->processor = $processor ? : new ServiceProcessor();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getConfigKey()
+    {
+        return 'contexts';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function initialize(ExtensionManager $extensionManager)
+    {
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function configure(ArrayNodeDefinition $builder)
+    {
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function load(ContainerBuilder $container, array $config)
+    {
+        $this->loadFactory($container);
+        $this->loadArgumentResolverFactory($container);
+        $this->loadEnvironmentHandler($container);
+        $this->loadEnvironmentReader($container);
+        $this->loadSuiteSetup($container);
+        $this->loadSnippetAppender($container);
+        $this->loadSnippetGenerators($container);
+        $this->loadSnippetsController($container);
+        $this->loadDefaultClassGenerators($container);
+        $this->loadDefaultContextReaders($container);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function process(ContainerBuilder $container)
+    {
+        $this->processClassResolvers($container);
+        $this->processArgumentResolverFactories($container);
+        $this->processArgumentResolvers($container);
+        $this->processContextInitializers($container);
+        $this->processContextReaders($container);
+        $this->processClassGenerators($container);
+        $this->processAnnotationReaders($container);
+    }
+
+    /**
+     * Loads context factory.
+     *
+     * @param ContainerBuilder $container
+     */
+    private function loadFactory(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Behat\Context\ContextFactory', array(
+            new Reference(ArgumentExtension::CONSTRUCTOR_ARGUMENT_ORGANISER_ID)
+        ));
+        $container->setDefinition(self::FACTORY_ID, $definition);
+    }
+
+    /**
+     * Loads argument resolver factory used in the environment handler.
+     *
+     * @param ContainerBuilder $container
+     */
+    private function loadArgumentResolverFactory(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Behat\Context\Argument\CompositeArgumentResolverFactory');
+        $container->setDefinition(self::AGGREGATE_RESOLVER_FACTORY_ID, $definition);
+    }
+
+    /**
+     * Loads context environment handlers.
+     *
+     * @param ContainerBuilder $container
+     */
+    private function loadEnvironmentHandler(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Behat\Context\Environment\Handler\ContextEnvironmentHandler', array(
+            new Reference(self::FACTORY_ID),
+            new Reference(self::AGGREGATE_RESOLVER_FACTORY_ID)
+        ));
+        $definition->addTag(EnvironmentExtension::HANDLER_TAG, array('priority' => 50));
+        $container->setDefinition(self::getEnvironmentHandlerId(), $definition);
+    }
+
+    /**
+     * Loads context environment readers.
+     *
+     * @param ContainerBuilder $container
+     */
+    private function loadEnvironmentReader(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Behat\Context\Environment\Reader\ContextEnvironmentReader');
+        $definition->addTag(EnvironmentExtension::READER_TAG, array('priority' => 50));
+        $container->setDefinition(self::getEnvironmentReaderId(), $definition);
+    }
+
+    /**
+     * Loads context environment setup.
+     *
+     * @param ContainerBuilder $container
+     */
+    private function loadSuiteSetup(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Behat\Context\Suite\Setup\SuiteWithContextsSetup', array(
+            new Reference(AutoloaderExtension::CLASS_LOADER_ID),
+            new Reference(FilesystemExtension::LOGGER_ID)
+        ));
+        $definition->addTag(SuiteExtension::SETUP_TAG, array('priority' => 20));
+        $container->setDefinition(self::getSuiteSetupId(), $definition);
+    }
+
+    /**
+     * Loads context snippet appender.
+     *
+     * @param ContainerBuilder $container
+     */
+    private function loadSnippetAppender(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Behat\Context\Snippet\Appender\ContextSnippetAppender', array(
+            new Reference(FilesystemExtension::LOGGER_ID)
+        ));
+        $definition->addTag(SnippetExtension::APPENDER_TAG, array('priority' => 50));
+        $container->setDefinition(SnippetExtension::APPENDER_TAG . '.context', $definition);
+    }
+
+    /**
+     * Loads context snippet generators.
+     *
+     * @param ContainerBuilder $container
+     */
+    private function loadSnippetGenerators(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Behat\Context\Snippet\Generator\ContextSnippetGenerator', array(
+            new Reference(DefinitionExtension::PATTERN_TRANSFORMER_ID)
+        ));
+        $definition->addTag(SnippetExtension::GENERATOR_TAG, array('priority' => 50));
+        $container->setDefinition(self::CONTEXT_SNIPPET_GENERATOR_ID, $definition);
+    }
+
+    /**
+     * @param ContainerBuilder $container
+     */
+    protected function loadSnippetsController(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Behat\Context\Cli\ContextSnippetsController', array(
+            new Reference(self::CONTEXT_SNIPPET_GENERATOR_ID),
+            new Reference(TranslatorExtension::TRANSLATOR_ID)
+        ));
+        $definition->addTag(CliExtension::CONTROLLER_TAG, array('priority' => 410));
+        $container->setDefinition(CliExtension::CONTROLLER_TAG . '.context_snippets', $definition);
+    }
+
+    /**
+     * Loads default context class generators.
+     *
+     * @param ContainerBuilder $container
+     */
+    private function loadDefaultClassGenerators(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Behat\Context\ContextClass\SimpleClassGenerator');
+        $definition->addTag(self::CLASS_GENERATOR_TAG, array('priority' => 50));
+        $container->setDefinition(self::CLASS_GENERATOR_TAG . '.simple', $definition);
+    }
+
+    /**
+     * Loads default context readers.
+     *
+     * @param ContainerBuilder $container
+     */
+    private function loadDefaultContextReaders(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Behat\Context\Reader\AnnotatedContextReader');
+        $container->setDefinition(self::getAnnotatedContextReaderId(), $definition);
+
+        $definition = new Definition('Behat\Behat\Context\Reader\ContextReaderCachedPerContext', array(
+            new Reference(self::getAnnotatedContextReaderId())
+        ));
+        $definition->addTag(self::READER_TAG, array('priority' => 50));
+        $container->setDefinition(self::getAnnotatedContextReaderId() . '.cached', $definition);
+
+        $definition = new Definition('Behat\Behat\Context\Reader\TranslatableContextReader', array(
+            new Reference(TranslatorExtension::TRANSLATOR_ID)
+        ));
+        $container->setDefinition(self::READER_TAG . '.translatable', $definition);
+
+        $definition = new Definition('Behat\Behat\Context\Reader\ContextReaderCachedPerSuite', array(
+            new Reference(self::READER_TAG . '.translatable')
+        ));
+        $definition->addTag(self::READER_TAG, array('priority' => 50));
+        $container->setDefinition(self::READER_TAG . '.translatable.cached', $definition);
+    }
+
+    /**
+     * Processes all class resolvers.
+     *
+     * @param ContainerBuilder $container
+     */
+    private function processClassResolvers(ContainerBuilder $container)
+    {
+        $references = $this->processor->findAndSortTaggedServices($container, self::CLASS_RESOLVER_TAG);
+        $definition = $container->getDefinition(self::getEnvironmentHandlerId());
+
+        foreach ($references as $reference) {
+            $definition->addMethodCall('registerClassResolver', array($reference));
+        }
+    }
+
+    /**
+     * Processes all argument resolver factories.
+     *
+     * @param ContainerBuilder $container
+     */
+    private function processArgumentResolverFactories($container)
+    {
+        $references = $this->processor->findAndSortTaggedServices($container, self::SUITE_SCOPED_RESOLVER_FACTORY_TAG);
+        $definition = $container->getDefinition(self::AGGREGATE_RESOLVER_FACTORY_ID);
+
+        foreach ($references as $reference) {
+            $definition->addMethodCall('registerFactory', array($reference));
+        }
+    }
+
+    /**
+     * Processes all argument resolvers.
+     *
+     * @param ContainerBuilder $container
+     */
+    private function processArgumentResolvers(ContainerBuilder $container)
+    {
+        $references = $this->processor->findAndSortTaggedServices($container, self::ARGUMENT_RESOLVER_TAG);
+        $definition = $container->getDefinition(self::FACTORY_ID);
+
+        foreach ($references as $reference) {
+            $definition->addMethodCall('registerArgumentResolver', array($reference));
+        }
+    }
+
+    /**
+     * Processes all context initializers.
+     *
+     * @param ContainerBuilder $container
+     */
+    private function processContextInitializers(ContainerBuilder $container)
+    {
+        $references = $this->processor->findAndSortTaggedServices($container, self::INITIALIZER_TAG);
+        $definition = $container->getDefinition(self::FACTORY_ID);
+
+        foreach ($references as $reference) {
+            $definition->addMethodCall('registerContextInitializer', array($reference));
+        }
+    }
+
+    /**
+     * Processes all context readers.
+     *
+     * @param ContainerBuilder $container
+     */
+    private function processContextReaders(ContainerBuilder $container)
+    {
+        $references = $this->processor->findAndSortTaggedServices($container, self::READER_TAG);
+        $definition = $container->getDefinition(self::getEnvironmentReaderId());
+
+        foreach ($references as $reference) {
+            $definition->addMethodCall('registerContextReader', array($reference));
+        }
+    }
+
+    /**
+     * Processes all class generators.
+     *
+     * @param ContainerBuilder $container
+     */
+    private function processClassGenerators(ContainerBuilder $container)
+    {
+        $references = $this->processor->findAndSortTaggedServices($container, self::CLASS_GENERATOR_TAG);
+        $definition = $container->getDefinition(self::getSuiteSetupId());
+
+        foreach ($references as $reference) {
+            $definition->addMethodCall('registerClassGenerator', array($reference));
+        }
+    }
+
+    /**
+     * Processes all annotation readers.
+     *
+     * @param ContainerBuilder $container
+     */
+    private function processAnnotationReaders(ContainerBuilder $container)
+    {
+        $references = $this->processor->findAndSortTaggedServices($container, self::ANNOTATION_READER_TAG);
+        $definition = $container->getDefinition(self::getAnnotatedContextReaderId());
+
+        foreach ($references as $reference) {
+            $definition->addMethodCall('registerAnnotationReader', array($reference));
+        }
+    }
+
+    /**
+     * Returns context environment handler service id.
+     *
+     * @return string
+     */
+    private static function getEnvironmentHandlerId()
+    {
+        return EnvironmentExtension::HANDLER_TAG . '.context';
+    }
+
+    /**
+     * Returns context environment reader id.
+     *
+     * @return string
+     */
+    private static function getEnvironmentReaderId()
+    {
+        return EnvironmentExtension::READER_TAG . '.context';
+    }
+
+    /**
+     * Returns context suite setup id.
+     *
+     * @return string
+     */
+    private static function getSuiteSetupId()
+    {
+        return SuiteExtension::SETUP_TAG . '.suite_with_contexts';
+    }
+
+    /**
+     * Returns annotated context reader id.
+     *
+     * @return string
+     */
+    private static function getAnnotatedContextReaderId()
+    {
+        return self::READER_TAG . '.annotated';
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Context/Snippet/Appender/ContextSnippetAppender.php b/vendor/behat/behat/src/Behat/Behat/Context/Snippet/Appender/ContextSnippetAppender.php
new file mode 100644 (file)
index 0000000..5a881f9
--- /dev/null
@@ -0,0 +1,128 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Context\Snippet\Appender;
+
+use Behat\Behat\Snippet\AggregateSnippet;
+use Behat\Behat\Snippet\Appender\SnippetAppender;
+use Behat\Testwork\Filesystem\FilesystemLogger;
+use ReflectionClass;
+
+/**
+ * Appends context-related snippets to their context classes.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class ContextSnippetAppender implements SnippetAppender
+{
+    /**
+     * @const PendingException class
+     */
+    const PENDING_EXCEPTION_CLASS = 'Behat\Behat\Tester\Exception\PendingException';
+
+    /**
+     * @var FilesystemLogger
+     */
+    private $logger;
+
+    /**
+     * Initializes appender.
+     *
+     * @param null|FilesystemLogger $logger
+     */
+    public function __construct(FilesystemLogger $logger = null)
+    {
+        $this->logger = $logger;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function supportsSnippet(AggregateSnippet $snippet)
+    {
+        return 'context' === $snippet->getType();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function appendSnippet(AggregateSnippet $snippet)
+    {
+        foreach ($snippet->getTargets() as $contextClass) {
+            $reflection = new ReflectionClass($contextClass);
+            $content = file_get_contents($reflection->getFileName());
+
+            foreach ($snippet->getUsedClasses() as $class) {
+                if (!$this->isClassImported($class, $content)) {
+                    $content = $this->importClass($class, $content);
+                }
+            }
+
+            $generated = rtrim(strtr($snippet->getSnippet(), array('\\' => '\\\\', '$' => '\\$')));
+            $content = preg_replace('/}\s*$/', "\n" . $generated . "\n}\n", $content);
+            $path = $reflection->getFileName();
+
+            file_put_contents($path, $content);
+
+            $this->logSnippetAddition($snippet, $path);
+        }
+    }
+
+    /**
+     * Checks if context file already has class in it.
+     *
+     * @param string $class
+     * @param string $contextFileContent
+     *
+     * @return Boolean
+     */
+    private function isClassImported($class, $contextFileContent)
+    {
+        $classImportRegex = sprintf(
+            '@use[^;]*%s.*;@ms',
+            preg_quote($class, '@')
+        );
+
+        return 1 === preg_match($classImportRegex, $contextFileContent);
+    }
+
+    /**
+     * Adds use-block for class.
+     *
+     * @param string $class
+     * @param string $contextFileContent
+     *
+     * @return string
+     */
+    private function importClass($class, $contextFileContent)
+    {
+        $replaceWith = "\$1" . 'use ' . $class . ";\n\$2;";
+
+        return preg_replace('@^(.*)(use\s+[^;]*);@m', $replaceWith, $contextFileContent, 1);
+    }
+
+    /**
+     * Logs snippet addition to the provided path (if logger is given).
+     *
+     * @param AggregateSnippet $snippet
+     * @param string           $path
+     */
+    private function logSnippetAddition(AggregateSnippet $snippet, $path)
+    {
+        if (!$this->logger) {
+            return;
+        }
+
+        $steps = $snippet->getSteps();
+        $reason = sprintf("`<comment>%s</comment>` definition added", $steps[0]->getText());
+
+        $this->logger->fileUpdated($path, $reason);
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Context/Snippet/ContextSnippet.php b/vendor/behat/behat/src/Behat/Behat/Context/Snippet/ContextSnippet.php
new file mode 100644 (file)
index 0000000..6ece5f1
--- /dev/null
@@ -0,0 +1,105 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Context\Snippet;
+
+use Behat\Behat\Snippet\Snippet;
+use Behat\Gherkin\Node\StepNode;
+
+/**
+ * Represents a definition snippet for a context class.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class ContextSnippet implements Snippet
+{
+    /**
+     * @var StepNode
+     */
+    private $step;
+    /**
+     * @var string
+     */
+    private $template;
+    /**
+     * @var string
+     */
+    private $contextClass;
+    /**
+     * @var string[]
+     */
+    private $usedClasses;
+
+    /**
+     * Initializes definition snippet.
+     *
+     * @param StepNode $step
+     * @param string   $template
+     * @param string   $contextClass
+     * @param string[] $usedClasses
+     */
+    public function __construct(StepNode $step, $template, $contextClass, array $usedClasses = array())
+    {
+        $this->step = $step;
+        $this->template = $template;
+        $this->contextClass = $contextClass;
+        $this->usedClasses = $usedClasses;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getType()
+    {
+        return 'context';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getHash()
+    {
+        return md5($this->template);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getSnippet()
+    {
+        return sprintf($this->template, $this->step->getKeywordType());
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getStep()
+    {
+        return $this->step;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getTarget()
+    {
+        return $this->contextClass;
+    }
+
+    /**
+     * Returns the classes used in the snippet which should be imported.
+     *
+     * @return string[]
+     */
+    public function getUsedClasses()
+    {
+        return $this->usedClasses;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Context/Snippet/Generator/AggregateContextIdentifier.php b/vendor/behat/behat/src/Behat/Behat/Context/Snippet/Generator/AggregateContextIdentifier.php
new file mode 100644 (file)
index 0000000..632d937
--- /dev/null
@@ -0,0 +1,56 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Context\Snippet\Generator;
+
+use Behat\Behat\Context\Environment\ContextEnvironment;
+
+/**
+ * Uses multiple child identifiers - the first one that returns non-null result would
+ * be the winner.
+ *
+ * This behaviour was introduced in 3.x to support the BC for interface-focused
+ * context identifier, while providing better user experience (no need to explicitly
+ * call `--snippets-for` on `--append-snippets` when contexts do not implement any
+ * snippet accepting interfaces).
+ */
+final class AggregateContextIdentifier implements TargetContextIdentifier
+{
+    /**
+     * @var TargetContextIdentifier[]
+     */
+    private $identifiers;
+
+    /**
+     * Initialises identifier.
+     *
+     * @param TargetContextIdentifier[] $identifiers
+     */
+    public function __construct(array $identifiers)
+    {
+        $this->identifiers = $identifiers;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function guessTargetContextClass(ContextEnvironment $environment)
+    {
+        foreach ($this->identifiers as $identifier) {
+            $contextClass = $identifier->guessTargetContextClass($environment);
+
+            if (null !== $contextClass) {
+                return $contextClass;
+            }
+        }
+
+        return null;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Context/Snippet/Generator/AggregatePatternIdentifier.php b/vendor/behat/behat/src/Behat/Behat/Context/Snippet/Generator/AggregatePatternIdentifier.php
new file mode 100644 (file)
index 0000000..1e1fc27
--- /dev/null
@@ -0,0 +1,49 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Context\Snippet\Generator;
+
+/**
+ * Uses multiple child identifiers - the first one that returns non-null result would
+ * be the winner.
+ */
+final class AggregatePatternIdentifier implements PatternIdentifier
+{
+    /**
+     * @var PatternIdentifier[]
+     */
+    private $identifiers;
+
+    /**
+     * Initialises identifier.
+     *
+     * @param PatternIdentifier[] $identifiers
+     */
+    public function __construct(array $identifiers)
+    {
+        $this->identifiers = $identifiers;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function guessPatternType($contextClass)
+    {
+        foreach ($this->identifiers as $identifier) {
+            $pattern = $identifier->guessPatternType($contextClass);
+
+            if (null !== $pattern) {
+                return $pattern;
+            }
+        }
+
+        return null;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Context/Snippet/Generator/CachedContextIdentifier.php b/vendor/behat/behat/src/Behat/Behat/Context/Snippet/Generator/CachedContextIdentifier.php
new file mode 100644 (file)
index 0000000..6ff1bb6
--- /dev/null
@@ -0,0 +1,54 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Context\Snippet\Generator;
+
+use Behat\Behat\Context\Environment\ContextEnvironment;
+
+/**
+ * Decorates actual identifier and caches its answers per suite.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class CachedContextIdentifier implements TargetContextIdentifier
+{
+    /**
+     * @var TargetContextIdentifier
+     */
+    private $decoratedIdentifier;
+    /**
+     * @var array
+     */
+    private $contextClasses = array();
+
+    /**
+     * Initialise the identifier.
+     *
+     * @param TargetContextIdentifier $identifier
+     */
+    public function __construct(TargetContextIdentifier $identifier)
+    {
+        $this->decoratedIdentifier = $identifier;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function guessTargetContextClass(ContextEnvironment $environment)
+    {
+        $suiteKey = $environment->getSuite()->getName();
+
+        if (array_key_exists($suiteKey, $this->contextClasses)) {
+            return $this->contextClasses[$suiteKey];
+        }
+
+        return $this->contextClasses[$suiteKey] = $this->decoratedIdentifier->guessTargetContextClass($environment);
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Context/Snippet/Generator/ContextInterfaceBasedContextIdentifier.php b/vendor/behat/behat/src/Behat/Behat/Context/Snippet/Generator/ContextInterfaceBasedContextIdentifier.php
new file mode 100644 (file)
index 0000000..7e1c154
--- /dev/null
@@ -0,0 +1,37 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Context\Snippet\Generator;
+
+use Behat\Behat\Context\Environment\ContextEnvironment;
+
+/**
+ * Identifier that uses context interfaces to guess which one is target.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * @deprecated in favour of --snippets-for and will be removed in 4.0
+ */
+final class ContextInterfaceBasedContextIdentifier implements TargetContextIdentifier
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function guessTargetContextClass(ContextEnvironment $environment)
+    {
+        foreach ($environment->getContextClasses() as $class) {
+            if (in_array('Behat\Behat\Context\SnippetAcceptingContext', class_implements($class))) {
+                return $class;
+            }
+        }
+
+        return null;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Context/Snippet/Generator/ContextInterfaceBasedPatternIdentifier.php b/vendor/behat/behat/src/Behat/Behat/Context/Snippet/Generator/ContextInterfaceBasedPatternIdentifier.php
new file mode 100644 (file)
index 0000000..31e956a
--- /dev/null
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Context\Snippet\Generator;
+
+/**
+ * Identifier that uses context interfaces to guess the pattern type.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * @deprecated in favour of --snippet-type and will be removed in 4.0
+ */
+final class ContextInterfaceBasedPatternIdentifier implements PatternIdentifier
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function guessPatternType($contextClass)
+    {
+        if (!in_array('Behat\Behat\Context\CustomSnippetAcceptingContext', class_implements($contextClass))) {
+            return null;
+        }
+
+        return $contextClass::getAcceptedSnippetType();
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Context/Snippet/Generator/ContextSnippetGenerator.php b/vendor/behat/behat/src/Behat/Behat/Context/Snippet/Generator/ContextSnippetGenerator.php
new file mode 100644 (file)
index 0000000..edb2227
--- /dev/null
@@ -0,0 +1,360 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Context\Snippet\Generator;
+
+use Behat\Behat\Context\Environment\ContextEnvironment;
+use Behat\Behat\Context\Snippet\ContextSnippet;
+use Behat\Behat\Definition\Pattern\PatternTransformer;
+use Behat\Behat\Snippet\Exception\EnvironmentSnippetGenerationException;
+use Behat\Behat\Snippet\Generator\SnippetGenerator;
+use Behat\Gherkin\Node\PyStringNode;
+use Behat\Gherkin\Node\StepNode;
+use Behat\Gherkin\Node\TableNode;
+use Behat\Testwork\Environment\Environment;
+use ReflectionClass;
+
+/**
+ * Generates snippets for a context class.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class ContextSnippetGenerator implements SnippetGenerator
+{
+    /**
+     * @var string[string]
+     */
+    private static $proposedMethods = array();
+    /**
+     * @var string
+     */
+    private static $templateTemplate = <<<TPL
+    /**
+     * @%%s %s
+     */
+    public function %s(%s)
+    {
+        throw new PendingException();
+    }
+TPL;
+    /**
+     * @var PatternTransformer
+     */
+    private $patternTransformer;
+    /**
+     * @var TargetContextIdentifier
+     */
+    private $contextIdentifier;
+    /**
+     * @var PatternIdentifier
+     */
+    private $patternIdentifier;
+
+    /**
+     * Initializes snippet generator.
+     *
+     * @param PatternTransformer $patternTransformer
+     */
+    public function __construct(PatternTransformer $patternTransformer)
+    {
+        $this->patternTransformer = $patternTransformer;
+
+        $this->setContextIdentifier(new FixedContextIdentifier(null));
+        $this->setPatternIdentifier(new FixedPatternIdentifier(null));
+    }
+
+    /**
+     * Sets target context identifier.
+     *
+     * @param TargetContextIdentifier $identifier
+     */
+    public function setContextIdentifier(TargetContextIdentifier $identifier)
+    {
+        $this->contextIdentifier = new CachedContextIdentifier($identifier);
+    }
+
+    /**
+     * Sets target pattern type identifier.
+     *
+     * @param PatternIdentifier $identifier
+     */
+    public function setPatternIdentifier(PatternIdentifier $identifier)
+    {
+        $this->patternIdentifier = $identifier;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function supportsEnvironmentAndStep(Environment $environment, StepNode $step)
+    {
+        if (!$environment instanceof ContextEnvironment) {
+            return false;
+        }
+
+        if (!$environment->hasContexts()) {
+            return false;
+        }
+
+        return null !== $this->contextIdentifier->guessTargetContextClass($environment);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function generateSnippet(Environment $environment, StepNode $step)
+    {
+        if (!$environment instanceof ContextEnvironment) {
+            throw new EnvironmentSnippetGenerationException(sprintf(
+                'ContextSnippetGenerator does not support `%s` environment.',
+                get_class($environment)
+            ), $environment);
+        }
+
+        $contextClass = $this->contextIdentifier->guessTargetContextClass($environment);
+        $patternType = $this->patternIdentifier->guessPatternType($contextClass);
+        $stepText = $step->getText();
+        $pattern = $this->patternTransformer->generatePattern($patternType, $stepText);
+
+        $methodName = $this->getMethodName($contextClass, $pattern->getCanonicalText(), $pattern->getPattern());
+        $methodArguments = $this->getMethodArguments($step, $pattern->getPlaceholderCount());
+        $snippetTemplate = $this->getSnippetTemplate($pattern->getPattern(), $methodName, $methodArguments);
+
+        $usedClasses = $this->getUsedClasses($step);
+
+        return new ContextSnippet($step, $snippetTemplate, $contextClass, $usedClasses);
+    }
+
+    /**
+     * Generates method name using step text and regex.
+     *
+     * @param string $contextClass
+     * @param string $canonicalText
+     * @param string $pattern
+     *
+     * @return string
+     */
+    private function getMethodName($contextClass, $canonicalText, $pattern)
+    {
+        $methodName = $this->deduceMethodName($canonicalText);
+        $methodName = $this->getUniqueMethodName($contextClass, $pattern, $methodName);
+
+        return $methodName;
+    }
+
+    /**
+     * Returns an array of method argument names from step and token count.
+     *
+     * @param StepNode $step
+     * @param integer  $tokenCount
+     *
+     * @return string[]
+     */
+    private function getMethodArguments(StepNode $step, $tokenCount)
+    {
+        $args = array();
+        for ($i = 0; $i < $tokenCount; $i++) {
+            $args[] = '$arg' . ($i + 1);
+        }
+
+        foreach ($step->getArguments() as $argument) {
+            $args[] = $this->getMethodArgument($argument);
+        }
+
+        return $args;
+    }
+
+    /**
+     * Returns an array of classes used by the snippet template
+     *
+     * @param StepNode $step
+     *
+     * @return string[]
+     */
+    private function getUsedClasses(StepNode $step)
+    {
+        $usedClasses = array('Behat\Behat\Tester\Exception\PendingException');
+
+        foreach ($step->getArguments() as $argument) {
+            if ($argument instanceof TableNode) {
+                $usedClasses[] = 'Behat\Gherkin\Node\TableNode';
+            } elseif ($argument instanceof PyStringNode) {
+                $usedClasses[] = 'Behat\Gherkin\Node\PyStringNode';
+            }
+        }
+
+        return $usedClasses;
+    }
+
+    /**
+     * Generates snippet template using regex, method name and arguments.
+     *
+     * @param string   $pattern
+     * @param string   $methodName
+     * @param string[] $methodArguments
+     *
+     * @return string
+     */
+    private function getSnippetTemplate($pattern, $methodName, array $methodArguments)
+    {
+        return sprintf(
+            self::$templateTemplate,
+            str_replace('%', '%%', $pattern),
+            $methodName,
+            implode(', ', $methodArguments)
+        );
+    }
+
+    /**
+     * Generates definition method name based on the step text.
+     *
+     * @param string $canonicalText
+     *
+     * @return string
+     */
+    private function deduceMethodName($canonicalText)
+    {
+        // check that method name is not empty
+        if (0 !== strlen($canonicalText)) {
+            $canonicalText[0] = strtolower($canonicalText[0]);
+
+            return $canonicalText;
+        }
+
+        return 'stepDefinition1';
+    }
+
+    /**
+     * Ensures uniqueness of the method name in the context.
+     *
+     * @param string $contextClass
+     * @param string $stepPattern
+     * @param string $name
+     *
+     * @return string
+     */
+    private function getUniqueMethodName($contextClass, $stepPattern, $name)
+    {
+        $reflection = new ReflectionClass($contextClass);
+
+        $number = $this->getMethodNumberFromTheMethodName($name);
+        list($name, $number) = $this->getMethodNameNotExistentInContext($reflection, $name, $number);
+        $name = $this->getMethodNameNotProposedEarlier($contextClass, $stepPattern, $name, $number);
+
+        return $name;
+    }
+
+    /**
+     * Tries to deduct method number from the provided method name.
+     *
+     * @param string $methodName
+     *
+     * @return integer
+     */
+    private function getMethodNumberFromTheMethodName($methodName)
+    {
+        $methodNumber = 2;
+        if (preg_match('/(\d+)$/', $methodName, $matches)) {
+            $methodNumber = intval($matches[1]);
+        }
+
+        return $methodNumber;
+    }
+
+    /**
+     * Tries to guess method name that is not yet defined in the context class.
+     *
+     * @param ReflectionClass $reflection
+     * @param string          $methodName
+     * @param integer         $methodNumber
+     *
+     * @return array
+     */
+    private function getMethodNameNotExistentInContext(ReflectionClass $reflection, $methodName, $methodNumber)
+    {
+        while ($reflection->hasMethod($methodName)) {
+            $methodName = preg_replace('/\d+$/', '', $methodName);
+            $methodName .= $methodNumber++;
+        }
+
+        return array($methodName, $methodNumber);
+    }
+
+    /**
+     * Tries to guess method name that is not yet proposed to the context class.
+     *
+     * @param string  $contextClass
+     * @param string  $stepPattern
+     * @param string  $name
+     * @param integer $number
+     *
+     * @return string
+     */
+    private function getMethodNameNotProposedEarlier($contextClass, $stepPattern, $name, $number)
+    {
+        foreach ($this->getAlreadyProposedMethods($contextClass) as $proposedPattern => $proposedMethod) {
+            if ($proposedPattern === $stepPattern) {
+                continue;
+            }
+
+            while ($proposedMethod === $name) {
+                $name = preg_replace('/\d+$/', '', $name);
+                $name .= $number++;
+            }
+        }
+
+        $this->markMethodAsAlreadyProposed($contextClass, $stepPattern, $name);
+
+        return $name;
+    }
+
+    /**
+     * Returns already proposed method names.
+     *
+     * @param string $contextClass
+     *
+     * @return string[]
+     */
+    private function getAlreadyProposedMethods($contextClass)
+    {
+        return isset(self::$proposedMethods[$contextClass]) ? self::$proposedMethods[$contextClass] : array();
+    }
+
+    /**
+     * Marks method as proposed one.
+     *
+     * @param string $contextClass
+     * @param string $stepPattern
+     * @param string $methodName
+     */
+    private function markMethodAsAlreadyProposed($contextClass, $stepPattern, $methodName)
+    {
+        self::$proposedMethods[$contextClass][$stepPattern] = $methodName;
+    }
+
+    /**
+     * Returns method argument.
+     *
+     * @param string $argument
+     *
+     * @return string
+     */
+    private function getMethodArgument($argument)
+    {
+        $arg = '__unknown__';
+        if ($argument instanceof PyStringNode) {
+            $arg = 'PyStringNode $string';
+        } elseif ($argument instanceof TableNode) {
+            $arg = 'TableNode $table';
+        }
+
+        return $arg;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Context/Snippet/Generator/FixedContextIdentifier.php b/vendor/behat/behat/src/Behat/Behat/Context/Snippet/Generator/FixedContextIdentifier.php
new file mode 100644 (file)
index 0000000..0d4b8e6
--- /dev/null
@@ -0,0 +1,48 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Context\Snippet\Generator;
+
+use Behat\Behat\Context\Environment\ContextEnvironment;
+
+/**
+ * Identifier that always returns same context, if it is defined in the suite.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class FixedContextIdentifier implements TargetContextIdentifier
+{
+    /**
+     * @var
+     */
+    private $contextClass;
+
+    /**
+     * Initialises identifier.
+     *
+     * @param string $contextClass
+     */
+    public function __construct($contextClass)
+    {
+        $this->contextClass = $contextClass;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function guessTargetContextClass(ContextEnvironment $environment)
+    {
+        if ($environment->hasContextClass($this->contextClass)) {
+            return $this->contextClass;
+        }
+
+        return null;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Context/Snippet/Generator/FixedPatternIdentifier.php b/vendor/behat/behat/src/Behat/Behat/Context/Snippet/Generator/FixedPatternIdentifier.php
new file mode 100644 (file)
index 0000000..7358bd4
--- /dev/null
@@ -0,0 +1,44 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Context\Snippet\Generator;
+
+use Behat\Behat\Context\Context;
+
+/**
+ * Identifier that always returns same pattern type.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class FixedPatternIdentifier implements PatternIdentifier
+{
+    /**
+     * @var string
+     */
+    private $patternType;
+
+    /**
+     * Initialises identifier.
+     *
+     * @param string $patternType
+     */
+    public function __construct($patternType)
+    {
+        $this->patternType = $patternType;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function guessPatternType($contextClass)
+    {
+        return $this->patternType;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Context/Snippet/Generator/PatternIdentifier.php b/vendor/behat/behat/src/Behat/Behat/Context/Snippet/Generator/PatternIdentifier.php
new file mode 100644 (file)
index 0000000..c10b7f8
--- /dev/null
@@ -0,0 +1,30 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Context\Snippet\Generator;
+
+use Behat\Behat\Context\Context;
+
+/**
+ * Identifies target pattern for snippets.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface PatternIdentifier
+{
+    /**
+     * Attempts to guess the target pattern type from the context.
+     *
+     * @param string $contextClass
+     *
+     * @return null|string
+     */
+    public function guessPatternType($contextClass);
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Context/Snippet/Generator/TargetContextIdentifier.php b/vendor/behat/behat/src/Behat/Behat/Context/Snippet/Generator/TargetContextIdentifier.php
new file mode 100644 (file)
index 0000000..d7e534d
--- /dev/null
@@ -0,0 +1,30 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Context\Snippet\Generator;
+
+use Behat\Behat\Context\Environment\ContextEnvironment;
+
+/**
+ * Identifies target context for snippets.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface TargetContextIdentifier
+{
+    /**
+     * Attempts to guess the target context class from the environment.
+     *
+     * @param ContextEnvironment $environment
+     *
+     * @return null|string
+     */
+    public function guessTargetContextClass(ContextEnvironment $environment);
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Context/SnippetAcceptingContext.php b/vendor/behat/behat/src/Behat/Behat/Context/SnippetAcceptingContext.php
new file mode 100644 (file)
index 0000000..2d6f7e9
--- /dev/null
@@ -0,0 +1,26 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Context;
+
+use Behat\Behat\Context\Snippet\Generator\ContextSnippetGenerator;
+
+/**
+ * Context that implements this interface is treated as a snippet-friendly context.
+ *
+ * @see ContextSnippetGenerator
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * @deprecated will be removed in 4.0. Use --snippets-for CLI option instead
+ */
+interface SnippetAcceptingContext extends Context
+{
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Context/Suite/Setup/SuiteWithContextsSetup.php b/vendor/behat/behat/src/Behat/Behat/Context/Suite/Setup/SuiteWithContextsSetup.php
new file mode 100644 (file)
index 0000000..0bc41db
--- /dev/null
@@ -0,0 +1,246 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Context\Suite\Setup;
+
+use Behat\Behat\Context\ContextClass\ClassGenerator;
+use Behat\Behat\Context\Exception\ContextNotFoundException;
+use Behat\Testwork\Filesystem\FilesystemLogger;
+use Behat\Testwork\Suite\Exception\SuiteConfigurationException;
+use Behat\Testwork\Suite\Setup\SuiteSetup;
+use Behat\Testwork\Suite\Suite;
+use Symfony\Component\ClassLoader\ClassLoader;
+
+/**
+ * Generates classes for all contexts in the suite using autoloader.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class SuiteWithContextsSetup implements SuiteSetup
+{
+    /**
+     * @var ClassLoader
+     */
+    private $autoloader;
+    /**
+     * @var null|FilesystemLogger
+     */
+    private $logger;
+    /**
+     * @var ClassGenerator[]
+     */
+    private $classGenerators = array();
+
+    /**
+     * Initializes setup.
+     *
+     * @param ClassLoader           $autoloader
+     * @param null|FilesystemLogger $logger
+     */
+    public function __construct(ClassLoader $autoloader, FilesystemLogger $logger = null)
+    {
+        $this->autoloader = $autoloader;
+        $this->logger = $logger;
+    }
+
+    /**
+     * Registers class generator.
+     *
+     * @param ClassGenerator $generator
+     */
+    public function registerClassGenerator(ClassGenerator $generator)
+    {
+        $this->classGenerators[] = $generator;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function supportsSuite(Suite $suite)
+    {
+        return $suite->hasSetting('contexts');
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setupSuite(Suite $suite)
+    {
+        foreach ($this->getNormalizedContextClasses($suite) as $class) {
+            if (class_exists($class)) {
+                continue;
+            }
+
+            $this->ensureContextDirectory($path = $this->findClassFile($class));
+
+            if ($content = $this->generateClass($suite, $class)) {
+                $this->createContextFile($path, $content);
+            }
+        }
+    }
+
+    /**
+     * Returns normalized context classes.
+     *
+     * @param Suite $suite
+     *
+     * @return string[]
+     */
+    private function getNormalizedContextClasses(Suite $suite)
+    {
+        return array_map(
+            function ($context) {
+                return is_array($context) ? current(array_keys($context)) : $context;
+            },
+            $this->getSuiteContexts($suite)
+        );
+    }
+
+    /**
+     * Returns array of context classes configured for the provided suite.
+     *
+     * @param Suite $suite
+     *
+     * @return string[]
+     *
+     * @throws SuiteConfigurationException If `contexts` setting is not an array
+     */
+    private function getSuiteContexts(Suite $suite)
+    {
+        $contexts = $suite->getSetting('contexts');
+
+        if (!is_array($contexts)) {
+            throw new SuiteConfigurationException(
+                sprintf('`contexts` setting of the "%s" suite is expected to be an array, `%s` given.',
+                    $suite->getName(),
+                    gettype($contexts)
+                ),
+                $suite->getName()
+            );
+        }
+
+        return $contexts;
+    }
+
+    /**
+     * Creates context directory in the filesystem.
+     *
+     * @param string $path
+     */
+    private function createContextDirectory($path)
+    {
+        mkdir($path, 0777, true);
+
+        if ($this->logger) {
+            $this->logger->directoryCreated($path, 'place your context classes here');
+        }
+    }
+
+    /**
+     * Creates context class file in the filesystem.
+     *
+     * @param string $path
+     * @param string $content
+     */
+    private function createContextFile($path, $content)
+    {
+        file_put_contents($path, $content);
+
+        if ($this->logger) {
+            $this->logger->fileCreated($path, 'place your definitions, transformations and hooks here');
+        }
+    }
+
+    /**
+     * Finds file to store a class.
+     *
+     * @param string $class
+     *
+     * @return string
+     *
+     * @throws ContextNotFoundException If class file could not be determined
+     */
+    private function findClassFile($class)
+    {
+        list($classpath, $classname) = $this->findClasspathAndClass($class);
+        $classpath .= str_replace('_', DIRECTORY_SEPARATOR, $classname) . '.php';
+
+        foreach ($this->autoloader->getPrefixes() as $prefix => $dirs) {
+            if (0 === strpos($class, $prefix)) {
+                return current($dirs) . DIRECTORY_SEPARATOR . $classpath;
+            }
+        }
+
+        if ($dirs = $this->autoloader->getFallbackDirs()) {
+            return current($dirs) . DIRECTORY_SEPARATOR . $classpath;
+        }
+
+        throw new ContextNotFoundException(sprintf(
+            'Could not find where to put "%s" class. Have you configured autoloader properly?',
+            $class
+        ), $class);
+    }
+
+    /**
+     * Generates class using registered class generators.
+     *
+     * @param Suite  $suite
+     * @param string $class
+     *
+     * @return null|string
+     */
+    private function generateClass(Suite $suite, $class)
+    {
+        $content = null;
+        foreach ($this->classGenerators as $generator) {
+            if ($generator->supportsSuiteAndClass($suite, $class)) {
+                $content = $generator->generateClass($suite, $class);
+            }
+        }
+
+        return $content;
+    }
+
+    /**
+     * Ensures that directory for a classpath exists.
+     *
+     * @param string $classpath
+     */
+    private function ensureContextDirectory($classpath)
+    {
+        if (!is_dir(dirname($classpath))) {
+            $this->createContextDirectory(dirname($classpath));
+        }
+    }
+
+    /**
+     * Finds classpath and classname from class.
+     *
+     * @param string $class
+     *
+     * @return array
+     */
+    private function findClasspathAndClass($class)
+    {
+        if (false !== $pos = strrpos($class, '\\')) {
+            // namespaced class name
+            $classpath = str_replace('\\', DIRECTORY_SEPARATOR, substr($class, 0, $pos)) . DIRECTORY_SEPARATOR;
+            $classname = substr($class, $pos + 1);
+
+            return array($classpath, $classname);
+        }
+
+        // PEAR-like class name
+        $classpath = null;
+        $classname = $class;
+
+        return array($classpath, $classname);
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Context/TranslatableContext.php b/vendor/behat/behat/src/Behat/Behat/Context/TranslatableContext.php
new file mode 100644 (file)
index 0000000..91bbb05
--- /dev/null
@@ -0,0 +1,36 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Context;
+
+use Behat\Behat\Context\Reader\TranslatableContextReader;
+
+/**
+ * Context that implements this interface is also treated as a translation provider for all it's callees.
+ *
+ * @see TranslatableContextReader
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface TranslatableContext extends Context
+{
+    /**
+     * Returns array of Translator-supported resource paths.
+     *
+     * For instance:
+     *
+     *  * array(__DIR__.'/../'ru.yml)
+     *  * array(__DIR__.'/../'en.xliff)
+     *  * array(__DIR__.'/../'de.php)
+     *
+     * @return string[]
+     */
+    public static function getTranslationResources();
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Definition/Call/DefinitionCall.php b/vendor/behat/behat/src/Behat/Behat/Definition/Call/DefinitionCall.php
new file mode 100644 (file)
index 0000000..0c68af2
--- /dev/null
@@ -0,0 +1,78 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Definition\Call;
+
+use Behat\Behat\Definition\Definition;
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\StepNode;
+use Behat\Testwork\Environment\Call\EnvironmentCall;
+use Behat\Testwork\Environment\Environment;
+
+/**
+ * Enhances environment call with definition information.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class DefinitionCall extends EnvironmentCall
+{
+    /**
+     * @var FeatureNode
+     */
+    private $feature;
+    /**
+     * @var StepNode
+     */
+    private $step;
+
+    /**
+     * Initializes definition call.
+     *
+     * @param Environment  $environment
+     * @param FeatureNode  $feature
+     * @param StepNode     $step
+     * @param Definition   $definition
+     * @param array        $arguments
+     * @param null|integer $errorReportingLevel
+     */
+    public function __construct(
+        Environment $environment,
+        FeatureNode $feature,
+        StepNode $step,
+        Definition $definition,
+        array $arguments,
+        $errorReportingLevel = null
+    ) {
+        parent::__construct($environment, $definition, $arguments, $errorReportingLevel);
+
+        $this->feature = $feature;
+        $this->step = $step;
+    }
+
+    /**
+     * Returns step feature node.
+     *
+     * @return FeatureNode
+     */
+    public function getFeature()
+    {
+        return $this->feature;
+    }
+
+    /**
+     * Returns definition step node.
+     *
+     * @return StepNode
+     */
+    public function getStep()
+    {
+        return $this->step;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Definition/Call/Given.php b/vendor/behat/behat/src/Behat/Behat/Definition/Call/Given.php
new file mode 100644 (file)
index 0000000..324ffb8
--- /dev/null
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Definition\Call;
+
+/**
+ * Given steps definition.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class Given extends RuntimeDefinition
+{
+    /**
+     * Initializes definition.
+     *
+     * @param string      $pattern
+     * @param callable    $callable
+     * @param null|string $description
+     */
+    public function __construct($pattern, $callable, $description = null)
+    {
+        parent::__construct('Given', $pattern, $callable, $description);
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Definition/Call/RuntimeDefinition.php b/vendor/behat/behat/src/Behat/Behat/Definition/Call/RuntimeDefinition.php
new file mode 100644 (file)
index 0000000..4c2c494
--- /dev/null
@@ -0,0 +1,71 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Definition\Call;
+
+use Behat\Behat\Definition\Definition;
+use Behat\Testwork\Call\RuntimeCallee;
+
+/**
+ * Represents a step definition created and executed in the runtime.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+abstract class RuntimeDefinition extends RuntimeCallee implements Definition
+{
+    /**
+     * @var string
+     */
+    private $type;
+    /**
+     * @var string
+     */
+    private $pattern;
+
+    /**
+     * Initializes definition.
+     *
+     * @param string      $type
+     * @param string      $pattern
+     * @param callable    $callable
+     * @param null|string $description
+     */
+    public function __construct($type, $pattern, $callable, $description = null)
+    {
+        $this->type = $type;
+        $this->pattern = $pattern;
+
+        parent::__construct($callable, $description);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getType()
+    {
+        return $this->type;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getPattern()
+    {
+        return $this->pattern;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function __toString()
+    {
+        return $this->getType() . ' ' . $this->getPattern();
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Definition/Call/Then.php b/vendor/behat/behat/src/Behat/Behat/Definition/Call/Then.php
new file mode 100644 (file)
index 0000000..50dabc1
--- /dev/null
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Definition\Call;
+
+/**
+ * Then steps definition.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class Then extends RuntimeDefinition
+{
+    /**
+     * Initializes definition.
+     *
+     * @param string      $pattern
+     * @param callable    $callable
+     * @param null|string $description
+     */
+    public function __construct($pattern, $callable, $description = null)
+    {
+        parent::__construct('Then', $pattern, $callable, $description);
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Definition/Call/When.php b/vendor/behat/behat/src/Behat/Behat/Definition/Call/When.php
new file mode 100644 (file)
index 0000000..1ff6560
--- /dev/null
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Definition\Call;
+
+/**
+ * When steps definition.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class When extends RuntimeDefinition
+{
+    /**
+     * Initializes definition.
+     *
+     * @param string      $pattern
+     * @param callable    $callable
+     * @param null|string $description
+     */
+    public function __construct($pattern, $callable, $description = null)
+    {
+        parent::__construct('When', $pattern, $callable, $description);
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Definition/Cli/AvailableDefinitionsController.php b/vendor/behat/behat/src/Behat/Behat/Definition/Cli/AvailableDefinitionsController.php
new file mode 100644 (file)
index 0000000..eaa22d4
--- /dev/null
@@ -0,0 +1,118 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Definition\Cli;
+
+use Behat\Behat\Definition\DefinitionWriter;
+use Behat\Behat\Definition\Printer\ConsoleDefinitionInformationPrinter;
+use Behat\Behat\Definition\Printer\ConsoleDefinitionListPrinter;
+use Behat\Behat\Definition\Printer\DefinitionPrinter;
+use Behat\Testwork\Cli\Controller;
+use Behat\Testwork\Suite\SuiteRepository;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * Shows all currently available definitions to the user.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class AvailableDefinitionsController implements Controller
+{
+    /**
+     * @var SuiteRepository
+     */
+    private $suiteRepository;
+    /**
+     * @var DefinitionWriter
+     */
+    private $writer;
+    /**
+     * @var ConsoleDefinitionListPrinter
+     */
+    private $listPrinter;
+    /**
+     * @var ConsoleDefinitionInformationPrinter
+     */
+    private $infoPrinter;
+
+    /**
+     * Initializes controller.
+     *
+     * @param SuiteRepository                     $suiteRepository
+     * @param DefinitionWriter                    $writer
+     * @param ConsoleDefinitionListPrinter        $listPrinter
+     * @param ConsoleDefinitionInformationPrinter $infoPrinter
+     */
+    public function __construct(
+        SuiteRepository $suiteRepository,
+        DefinitionWriter $writer,
+        ConsoleDefinitionListPrinter $listPrinter,
+        ConsoleDefinitionInformationPrinter $infoPrinter
+    ) {
+        $this->suiteRepository = $suiteRepository;
+        $this->writer = $writer;
+        $this->listPrinter = $listPrinter;
+        $this->infoPrinter = $infoPrinter;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function configure(Command $command)
+    {
+        $command->addOption('--definitions', '-d', InputOption::VALUE_REQUIRED,
+            "Print all available step definitions:" . PHP_EOL .
+            "- use <info>--definitions l</info> to just list definition expressions." . PHP_EOL .
+            "- use <info>--definitions i</info> to show definitions with extended info." . PHP_EOL .
+            "- use <info>--definitions 'needle'</info> to find specific definitions." . PHP_EOL .
+            "Use <info>--lang</info> to see definitions in specific language."
+        );
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function execute(InputInterface $input, OutputInterface $output)
+    {
+        if (null === $argument = $input->getOption('definitions')) {
+            return null;
+        }
+
+        $printer = $this->getDefinitionPrinter($argument);
+        foreach ($this->suiteRepository->getSuites() as $suite) {
+            $this->writer->printSuiteDefinitions($printer, $suite);
+        }
+
+        return 0;
+    }
+
+    /**
+     * Returns definition printer for provided option argument.
+     *
+     * @param string $argument
+     *
+     * @return DefinitionPrinter
+     */
+    private function getDefinitionPrinter($argument)
+    {
+        if ('l' === $argument) {
+            return $this->listPrinter;
+        }
+
+        if ('i' !== $argument) {
+            $this->infoPrinter->setSearchCriterion($argument);
+        }
+
+        return $this->infoPrinter;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Definition/Context/Annotation/DefinitionAnnotationReader.php b/vendor/behat/behat/src/Behat/Behat/Definition/Context/Annotation/DefinitionAnnotationReader.php
new file mode 100644 (file)
index 0000000..baa6c88
--- /dev/null
@@ -0,0 +1,52 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Definition\Context\Annotation;
+
+use Behat\Behat\Context\Annotation\AnnotationReader;
+use ReflectionMethod;
+
+/**
+ * Reads definition annotations from the context class.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class DefinitionAnnotationReader implements AnnotationReader
+{
+    /**
+     * @var string
+     */
+    private static $regex = '/^\@(given|when|then)\s+(.+)$/i';
+    /**
+     * @var string[]
+     */
+    private static $classes = array(
+        'given' => 'Behat\Behat\Definition\Call\Given',
+        'when'  => 'Behat\Behat\Definition\Call\When',
+        'then'  => 'Behat\Behat\Definition\Call\Then',
+    );
+
+    /**
+     * {@inheritdoc}
+     */
+    public function readCallee($contextClass, ReflectionMethod $method, $docLine, $description)
+    {
+        if (!preg_match(self::$regex, $docLine, $match)) {
+            return null;
+        }
+
+        $type = strtolower($match[1]);
+        $class = self::$classes[$type];
+        $pattern = $match[2];
+        $callable = array($contextClass, $method->getName());
+
+        return new $class($pattern, $callable, $description);
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Definition/Definition.php b/vendor/behat/behat/src/Behat/Behat/Definition/Definition.php
new file mode 100644 (file)
index 0000000..43b78b5
--- /dev/null
@@ -0,0 +1,42 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Definition;
+
+use Behat\Testwork\Call\Callee;
+
+/**
+ * Represents a step definition.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface Definition extends Callee
+{
+    /**
+     * Returns definition type (Given|When|Then).
+     *
+     * @return string
+     */
+    public function getType();
+
+    /**
+     * Returns step pattern exactly as it was defined.
+     *
+     * @return string
+     */
+    public function getPattern();
+
+    /**
+     * Represents definition as a string.
+     *
+     * @return string
+     */
+    public function __toString();
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Definition/DefinitionFinder.php b/vendor/behat/behat/src/Behat/Behat/Definition/DefinitionFinder.php
new file mode 100644 (file)
index 0000000..14d2763
--- /dev/null
@@ -0,0 +1,61 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Definition;
+
+use Behat\Behat\Definition\Search\SearchEngine;
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\StepNode;
+use Behat\Testwork\Environment\Environment;
+
+/**
+ * Finds specific step definition in environment using registered search engines.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class DefinitionFinder
+{
+    /**
+     * @var SearchEngine[]
+     */
+    private $engines = array();
+
+    /**
+     * Registers definition search engine.
+     *
+     * @param SearchEngine $searchEngine
+     */
+    public function registerSearchEngine(SearchEngine $searchEngine)
+    {
+        $this->engines[] = $searchEngine;
+    }
+
+    /**
+     * Searches definition for a provided step in a provided environment.
+     *
+     * @param Environment $environment
+     * @param FeatureNode $feature
+     * @param StepNode    $step
+     *
+     * @return SearchResult
+     */
+    public function findDefinition(Environment $environment, FeatureNode $feature, StepNode $step)
+    {
+        foreach ($this->engines as $engine) {
+            $result = $engine->searchDefinition($environment, $feature, $step);
+
+            if (null !== $result && $result->hasMatch()) {
+                return $result;
+            }
+        }
+
+        return new SearchResult();
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Definition/DefinitionRepository.php b/vendor/behat/behat/src/Behat/Behat/Definition/DefinitionRepository.php
new file mode 100644 (file)
index 0000000..b1db15a
--- /dev/null
@@ -0,0 +1,70 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Definition;
+
+use Behat\Behat\Definition\Exception\RedundantStepException;
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\Environment\EnvironmentManager;
+
+/**
+ * Provides step definitions using environment manager.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class DefinitionRepository
+{
+    /**
+     * @var EnvironmentManager
+     */
+    private $environmentManager;
+
+    /**
+     * Initializes repository.
+     *
+     * @param EnvironmentManager $environmentManager
+     */
+    public function __construct(EnvironmentManager $environmentManager)
+    {
+        $this->environmentManager = $environmentManager;
+    }
+
+    /**
+     * Returns all available definitions for a specific environment.
+     *
+     * @param Environment $environment
+     *
+     * @return Definition[]
+     *
+     * @throws RedundantStepException
+     */
+    public function getEnvironmentDefinitions(Environment $environment)
+    {
+        $patterns = array();
+        $definitions = array();
+
+        foreach ($this->environmentManager->readEnvironmentCallees($environment) as $callee) {
+            if (!$callee instanceof Definition) {
+                continue;
+            }
+
+            $pattern = $callee->getPattern();
+            if (isset($patterns[$pattern])) {
+                throw new RedundantStepException($callee, $patterns[$pattern]);
+            }
+
+            $patterns[$pattern] = $callee;
+
+            $definitions[] = $callee;
+        }
+
+        return $definitions;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Definition/DefinitionWriter.php b/vendor/behat/behat/src/Behat/Behat/Definition/DefinitionWriter.php
new file mode 100644 (file)
index 0000000..204d1ae
--- /dev/null
@@ -0,0 +1,58 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Definition;
+
+use Behat\Behat\Definition\Printer\DefinitionPrinter;
+use Behat\Testwork\Environment\EnvironmentManager;
+use Behat\Testwork\Suite\Suite;
+
+/**
+ * Prints definitions using provided printer.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class DefinitionWriter
+{
+    /**
+     * @var EnvironmentManager
+     */
+    private $environmentManager;
+    /**
+     * @var DefinitionRepository
+     */
+    private $repository;
+
+    /**
+     * Initializes writer.
+     *
+     * @param EnvironmentManager   $environmentManager
+     * @param DefinitionRepository $repository
+     */
+    public function __construct(EnvironmentManager $environmentManager, DefinitionRepository $repository)
+    {
+        $this->environmentManager = $environmentManager;
+        $this->repository = $repository;
+    }
+
+    /**
+     * Prints definitions for provided suite using printer.
+     *
+     * @param DefinitionPrinter $printer
+     * @param Suite             $suite
+     */
+    public function printSuiteDefinitions(DefinitionPrinter $printer, $suite)
+    {
+        $environment = $this->environmentManager->buildEnvironment($suite);
+        $definitions = $this->repository->getEnvironmentDefinitions($environment);
+
+        $printer->printDefinitions($suite, $definitions);
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Definition/Exception/AmbiguousMatchException.php b/vendor/behat/behat/src/Behat/Behat/Definition/Exception/AmbiguousMatchException.php
new file mode 100644 (file)
index 0000000..bb5ba33
--- /dev/null
@@ -0,0 +1,57 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Definition\Exception;
+
+use Behat\Behat\Definition\Definition;
+use RuntimeException;
+
+/**
+ * Represents an exception caused by an ambiguous step definition match.
+ *
+ * If multiple definitions match the same step, behat is not able to determine which one is better and thus this
+ * exception is thrown and test suite is stopped.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class AmbiguousMatchException extends RuntimeException implements SearchException
+{
+    /**
+     * @var string
+     */
+    private $text;
+    /**
+     * @var Definition[]
+     */
+    private $matches = array();
+
+    /**
+     * Initializes ambiguous exception.
+     *
+     * @param string       $text    step description
+     * @param Definition[] $matches ambiguous matches (array of Definition's)
+     */
+    public function __construct($text, array $matches)
+    {
+        $this->text = $text;
+        $this->matches = $matches;
+
+        $message = sprintf("Ambiguous match of \"%s\":", $text);
+        foreach ($matches as $definition) {
+            $message .= sprintf(
+                "\nto `%s` from %s",
+                $definition->getPattern(),
+                $definition->getPath()
+            );
+        }
+
+        parent::__construct($message);
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Definition/Exception/DefinitionException.php b/vendor/behat/behat/src/Behat/Behat/Definition/Exception/DefinitionException.php
new file mode 100644 (file)
index 0000000..07ee2e4
--- /dev/null
@@ -0,0 +1,22 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Definition\Exception;
+
+use Behat\Testwork\Exception\TestworkException;
+
+/**
+ * Represents an exception thrown during step definition handling.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface DefinitionException extends TestworkException
+{
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Definition/Exception/InvalidPatternException.php b/vendor/behat/behat/src/Behat/Behat/Definition/Exception/InvalidPatternException.php
new file mode 100644 (file)
index 0000000..1990bea
--- /dev/null
@@ -0,0 +1,22 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Definition\Exception;
+
+use InvalidArgumentException;
+
+/**
+ * Represents an exception caused by an invalid definition pattern (not able to transform it to a regex).
+ *
+ * @author Christophe Coevoet <stof@notk.org>
+ */
+final class InvalidPatternException extends InvalidArgumentException implements DefinitionException
+{
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Definition/Exception/RedundantStepException.php b/vendor/behat/behat/src/Behat/Behat/Definition/Exception/RedundantStepException.php
new file mode 100644 (file)
index 0000000..8a47c5e
--- /dev/null
@@ -0,0 +1,41 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Definition\Exception;
+
+use Behat\Behat\Definition\Definition;
+use RuntimeException;
+
+/**
+ * Represents an exception caused by a redundant step definition.
+ *
+ * If multiple step definitions in the boundaries of the same suite use same regular expression, behat is not able
+ * to determine which one is better and thus this exception is thrown and test suite is stopped.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class RedundantStepException extends RuntimeException implements SearchException
+{
+    /**
+     * Initializes redundant exception.
+     *
+     * @param Definition $step2 duplicate step definition
+     * @param Definition $step1 firstly matched step definition
+     */
+    public function __construct(Definition $step2, Definition $step1)
+    {
+        $message = sprintf(
+            "Step \"%s\" is already defined in %s\n\n%s\n%s",
+            $step2->getPattern(), $step1->getPath(), $step1->getPath(), $step2->getPath()
+        );
+
+        parent::__construct($message);
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Definition/Exception/SearchException.php b/vendor/behat/behat/src/Behat/Behat/Definition/Exception/SearchException.php
new file mode 100644 (file)
index 0000000..bc3457b
--- /dev/null
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Definition\Exception;
+
+/**
+ * Represents an exception caused by a definition search.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface SearchException extends DefinitionException
+{
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Definition/Exception/UnknownPatternException.php b/vendor/behat/behat/src/Behat/Behat/Definition/Exception/UnknownPatternException.php
new file mode 100644 (file)
index 0000000..bc23cb3
--- /dev/null
@@ -0,0 +1,49 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Definition\Exception;
+
+use InvalidArgumentException;
+
+/**
+ * Represents an exception caused by an unrecognised definition pattern.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class UnknownPatternException extends InvalidArgumentException implements DefinitionException
+{
+    /**
+     * @var string
+     */
+    private $pattern;
+
+    /**
+     * Initializes exception.
+     *
+     * @param string  $message
+     * @param integer $pattern
+     */
+    public function __construct($message, $pattern)
+    {
+        $this->pattern = $pattern;
+
+        parent::__construct($message);
+    }
+
+    /**
+     * Returns pattern that caused exception.
+     *
+     * @return string
+     */
+    public function getPattern()
+    {
+        return $this->pattern;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Definition/Exception/UnsupportedPatternTypeException.php b/vendor/behat/behat/src/Behat/Behat/Definition/Exception/UnsupportedPatternTypeException.php
new file mode 100644 (file)
index 0000000..17114e6
--- /dev/null
@@ -0,0 +1,49 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Definition\Exception;
+
+use InvalidArgumentException;
+
+/**
+ * Represents an exception caused by an unsupported pattern type.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class UnsupportedPatternTypeException extends InvalidArgumentException implements DefinitionException
+{
+    /**
+     * @var string
+     */
+    private $type;
+
+    /**
+     * Initializes exception.
+     *
+     * @param string $message
+     * @param string $type
+     */
+    public function __construct($message, $type)
+    {
+        $this->type = $type;
+
+        parent::__construct($message);
+    }
+
+    /**
+     * Returns pattern type that caused exception.
+     *
+     * @return string
+     */
+    public function getType()
+    {
+        return $this->type;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Definition/Pattern/Pattern.php b/vendor/behat/behat/src/Behat/Behat/Definition/Pattern/Pattern.php
new file mode 100644 (file)
index 0000000..0a3834f
--- /dev/null
@@ -0,0 +1,76 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Definition\Pattern;
+
+/**
+ * Step definition pattern.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class Pattern
+{
+    /**
+     * @var string
+     */
+    private $canonicalText;
+    /**
+     * @var string
+     */
+    private $pattern;
+    /**
+     * @var integer
+     */
+    private $placeholderCount;
+
+    /**
+     * Initializes pattern.
+     *
+     * @param string  $canonicalText
+     * @param string  $pattern
+     * @param integer $placeholderCount
+     */
+    public function __construct($canonicalText, $pattern, $placeholderCount = 0)
+    {
+        $this->canonicalText = $canonicalText;
+        $this->pattern = $pattern;
+        $this->placeholderCount = $placeholderCount;
+    }
+
+    /**
+     * Returns canonical step text.
+     *
+     * @return string
+     */
+    public function getCanonicalText()
+    {
+        return $this->canonicalText;
+    }
+
+    /**
+     * Returns pattern.
+     *
+     * @return string
+     */
+    public function getPattern()
+    {
+        return $this->pattern;
+    }
+
+    /**
+     * Returns pattern placeholder count.
+     *
+     * @return integer
+     */
+    public function getPlaceholderCount()
+    {
+        return $this->placeholderCount;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Definition/Pattern/PatternTransformer.php b/vendor/behat/behat/src/Behat/Behat/Definition/Pattern/PatternTransformer.php
new file mode 100644 (file)
index 0000000..6af5bac
--- /dev/null
@@ -0,0 +1,79 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Definition\Pattern;
+
+use Behat\Behat\Definition\Exception\UnknownPatternException;
+use Behat\Behat\Definition\Exception\UnsupportedPatternTypeException;
+use Behat\Behat\Definition\Pattern\Policy\PatternPolicy;
+
+/**
+ * Transforms patterns using registered policies.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class PatternTransformer
+{
+    /**
+     * @var PatternPolicy[]
+     */
+    private $policies = array();
+
+    /**
+     * Registers pattern policy.
+     *
+     * @param PatternPolicy $policy
+     */
+    public function registerPatternPolicy(PatternPolicy $policy)
+    {
+        $this->policies[] = $policy;
+    }
+
+    /**
+     * Generates pattern.
+     *
+     * @param string $type
+     * @param string $stepText
+     *
+     * @return Pattern
+     *
+     * @throws UnsupportedPatternTypeException
+     */
+    public function generatePattern($type, $stepText)
+    {
+        foreach ($this->policies as $policy) {
+            if ($policy->supportsPatternType($type)) {
+                return $policy->generatePattern($stepText);
+            }
+        }
+
+        throw new UnsupportedPatternTypeException(sprintf('Can not find policy for a pattern type `%s`.', $type), $type);
+    }
+
+    /**
+     * Transforms pattern string to regex.
+     *
+     * @param string $pattern
+     *
+     * @return string
+     *
+     * @throws UnknownPatternException
+     */
+    public function transformPatternToRegex($pattern)
+    {
+        foreach ($this->policies as $policy) {
+            if ($policy->supportsPattern($pattern)) {
+                return $policy->transformPatternToRegex($pattern);
+            }
+        }
+
+        throw new UnknownPatternException(sprintf('Can not find policy for a pattern `%s`.', $pattern), $pattern);
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Definition/Pattern/Policy/PatternPolicy.php b/vendor/behat/behat/src/Behat/Behat/Definition/Pattern/Policy/PatternPolicy.php
new file mode 100644 (file)
index 0000000..2476241
--- /dev/null
@@ -0,0 +1,60 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Definition\Pattern\Policy;
+
+use Behat\Behat\Definition\Pattern\Pattern;
+use Behat\Behat\Definition\Pattern\PatternTransformer;
+
+/**
+ * Defines a way to handle custom definition patterns.
+ *
+ * @see PatternTransformer
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface PatternPolicy
+{
+    /**
+     * Checks if policy supports pattern type.
+     *
+     * @param string $type
+     *
+     * @return Boolean
+     */
+    public function supportsPatternType($type);
+
+    /**
+     * Generates pattern for step text.
+     *
+     * @param string $stepText
+     *
+     * @return Pattern
+     */
+    public function generatePattern($stepText);
+
+    /**
+     * Checks if policy supports pattern.
+     *
+     * @param string $pattern
+     *
+     * @return Boolean
+     */
+    public function supportsPattern($pattern);
+
+    /**
+     * Transforms pattern string to regex.
+     *
+     * @param string $pattern
+     *
+     * @return string
+     */
+    public function transformPatternToRegex($pattern);
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Definition/Pattern/Policy/RegexPatternPolicy.php b/vendor/behat/behat/src/Behat/Behat/Definition/Pattern/Policy/RegexPatternPolicy.php
new file mode 100644 (file)
index 0000000..6ea50a2
--- /dev/null
@@ -0,0 +1,135 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Definition\Pattern\Policy;
+
+use Behat\Behat\Definition\Exception\InvalidPatternException;
+use Behat\Behat\Definition\Pattern\Pattern;
+use Behat\Transliterator\Transliterator;
+
+/**
+ * Defines a way to handle regex patterns.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class RegexPatternPolicy implements PatternPolicy
+{
+    /**
+     * @var string[string]
+     */
+    private static $replacePatterns = array(
+        "/(?<=\W|^)\\\'(?:((?!\\').)*)\\\'(?=\W|$)/" => "'([^']*)'", // Single quoted strings
+        '/(?<=\W|^)\"(?:[^\"]*)\"(?=\W|$)/'          => "\"([^\"]*)\"", // Double quoted strings
+        '/(?<=\W|^)(\d+)(?=\W|$)/'                   => "(\\d+)", // Numbers
+    );
+
+    /**
+     * {@inheritdoc}
+     */
+    public function supportsPatternType($type)
+    {
+        return 'regex' === $type;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function generatePattern($stepText)
+    {
+        $canonicalText = $this->generateCanonicalText($stepText);
+        $stepRegex = $this->generateRegex($stepText);
+        $placeholderCount = $this->countPlaceholders($stepText, $stepRegex);
+
+        return new Pattern($canonicalText, '/^' . $stepRegex . '$/', $placeholderCount);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function supportsPattern($pattern)
+    {
+        return (bool) preg_match('/^(?:\\{.*\\}|([~\\/#`]).*\1)[imsxADSUXJu]*$/s', $pattern);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function transformPatternToRegex($pattern)
+    {
+        if (false === @preg_match($pattern, 'anything')) {
+            $error = error_get_last();
+            $errorMessage = isset($error['message']) ? $error['message'] : '';
+
+            throw new InvalidPatternException(sprintf('The regex `%s` is invalid: %s', $pattern, $errorMessage));
+        }
+
+        return $pattern;
+    }
+
+    /**
+     * Generates regex from step text.
+     *
+     * @param string $stepText
+     *
+     * @return string
+     */
+    private function generateRegex($stepText)
+    {
+        return preg_replace(
+            array_keys(self::$replacePatterns),
+            array_values(self::$replacePatterns),
+            $this->escapeStepText($stepText)
+        );
+    }
+
+    /**
+     * Generates canonical text for step text.
+     *
+     * @param string $stepText
+     *
+     * @return string
+     */
+    private function generateCanonicalText($stepText)
+    {
+        $canonicalText = preg_replace(array_keys(self::$replacePatterns), '', $stepText);
+        $canonicalText = Transliterator::transliterate($canonicalText, ' ');
+        $canonicalText = preg_replace('/[^a-zA-Z\_\ ]/', '', $canonicalText);
+        $canonicalText = str_replace(' ', '', ucwords($canonicalText));
+
+        return $canonicalText;
+    }
+
+    /**
+     * Counts regex placeholders using provided text.
+     *
+     * @param string $stepText
+     * @param string $stepRegex
+     *
+     * @return integer
+     */
+    private function countPlaceholders($stepText, $stepRegex)
+    {
+        preg_match('/^' . $stepRegex . '$/', $stepText, $matches);
+
+        return count($matches) ? count($matches) - 1 : 0;
+    }
+
+    /**
+     * Returns escaped step text.
+     *
+     * @param string $stepText
+     *
+     * @return string
+     */
+    private function escapeStepText($stepText)
+    {
+        return preg_replace('/([\/\[\]\(\)\\\^\$\.\|\?\*\+\'])/', '\\\\$1', $stepText);
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Definition/Pattern/Policy/TurnipPatternPolicy.php b/vendor/behat/behat/src/Behat/Behat/Definition/Pattern/Policy/TurnipPatternPolicy.php
new file mode 100644 (file)
index 0000000..c073268
--- /dev/null
@@ -0,0 +1,212 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Definition\Pattern\Policy;
+
+use Behat\Behat\Definition\Pattern\Pattern;
+use Behat\Behat\Definition\Exception\InvalidPatternException;
+use Behat\Transliterator\Transliterator;
+
+/**
+ * Defines a way to handle turnip patterns.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class TurnipPatternPolicy implements PatternPolicy
+{
+    const TOKEN_REGEX = "[\"']?(?P<%s>(?<=\")[^\"]*(?=\")|(?<=')[^']*(?=')|\-?[\w\.\,]+)['\"]?";
+
+    const PLACEHOLDER_REGEXP = "/\\\:(\w+)/";
+    const OPTIONAL_WORD_REGEXP = '/(\s)?\\\\\(([^\\\]+)\\\\\)(\s)?/';
+    const ALTERNATIVE_WORD_REGEXP = '/(\w+)\\\\\/(\w+)/';
+
+    /**
+     * @var string[]
+     */
+    private $regexCache = array();
+
+    /**
+     * @var string[]
+     */
+    private static $placeholderPatterns = array(
+        "/(?<!\w)\"[^\"]+\"(?!\w)/",
+        "/(?<!\w)'[^']+'(?!\w)/",
+        "/(?<!\w|\.|\,)\-?\d+(?:[\.\,]\d+)?(?!\w|\.|\,)/"
+    );
+
+    /**
+     * {@inheritdoc}
+     */
+    public function supportsPatternType($type)
+    {
+        return null === $type || 'turnip' === $type;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function generatePattern($stepText)
+    {
+        $count = 0;
+        $pattern = $stepText;
+        foreach (self::$placeholderPatterns as $replacePattern) {
+            $pattern = preg_replace_callback(
+                $replacePattern,
+                function () use (&$count) { return ':arg' . ++$count; },
+                $pattern
+            );
+        }
+        $pattern = $this->escapeAlternationSyntax($pattern);
+        $canonicalText = $this->generateCanonicalText($stepText);
+
+        return new Pattern($canonicalText, $pattern, $count);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function supportsPattern($pattern)
+    {
+        return true;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function transformPatternToRegex($pattern)
+    {
+        if (!isset($this->regexCache[$pattern])) {
+            $this->regexCache[$pattern] = $this->createTransformedRegex($pattern);
+        }
+        return $this->regexCache[$pattern];
+    }
+
+    /**
+     * @param string $pattern
+     * @return string
+     */
+    private function createTransformedRegex($pattern)
+    {
+        $regex = preg_quote($pattern, '/');
+
+        $regex = $this->replaceTokensWithRegexCaptureGroups($regex);
+        $regex = $this->replaceTurnipOptionalEndingWithRegex($regex);
+        $regex = $this->replaceTurnipAlternativeWordsWithRegex($regex);
+
+        return '/^' . $regex . '$/i';
+    }
+
+    /**
+     * Generates canonical text for step text.
+     *
+     * @param string $stepText
+     *
+     * @return string
+     */
+    private function generateCanonicalText($stepText)
+    {
+        $canonicalText = preg_replace(self::$placeholderPatterns, '', $stepText);
+        $canonicalText = Transliterator::transliterate($canonicalText, ' ');
+        $canonicalText = preg_replace('/[^a-zA-Z\_\ ]/', '', $canonicalText);
+        $canonicalText = str_replace(' ', '', ucwords($canonicalText));
+
+        return $canonicalText;
+    }
+
+    /**
+     * Replaces turnip tokens with regex capture groups.
+     *
+     * @param string $regex
+     *
+     * @return string
+     */
+    private function replaceTokensWithRegexCaptureGroups($regex)
+    {
+        $tokenRegex = self::TOKEN_REGEX;
+
+        return preg_replace_callback(
+            self::PLACEHOLDER_REGEXP,
+            array($this, 'replaceTokenWithRegexCaptureGroup'),
+            $regex
+        );
+    }
+
+    private function replaceTokenWithRegexCaptureGroup($tokenMatch)
+    {
+        if (strlen($tokenMatch[1]) >= 32) {
+            throw new InvalidPatternException(
+                "Token name should not exceed 32 characters, but `{$tokenMatch[1]}` was used."
+            );
+        }
+
+        return sprintf(self::TOKEN_REGEX, $tokenMatch[1]);
+    }
+
+    /**
+     * Replaces turnip optional ending with regex non-capturing optional group.
+     *
+     * @param string $regex
+     *
+     * @return string
+     */
+    private function replaceTurnipOptionalEndingWithRegex($regex)
+    {
+        return preg_replace(self::OPTIONAL_WORD_REGEXP, '(?:\1)?(?:\2)?(?:\3)?', $regex);
+    }
+
+    /**
+     * Replaces turnip alternative words with regex non-capturing alternating group.
+     *
+     * @param string $regex
+     *
+     * @return string
+     */
+    private function replaceTurnipAlternativeWordsWithRegex($regex)
+    {
+        $regex = preg_replace(self::ALTERNATIVE_WORD_REGEXP, '(?:\1|\2)', $regex);
+        $regex = $this->removeEscapingOfAlternationSyntax($regex);
+
+        return $regex;
+    }
+
+    /**
+     * Adds escaping to alternation syntax in pattern.
+     *
+     * By default, Turnip treats `/` as alternation syntax. Meaning `one/two` for Turnip
+     * means either `one` or `two`. Sometimes though you'll want to use slash character
+     * with different purpose (URL, UNIX paths). In this case, you would escape slashes
+     * with backslash.
+     *
+     * This method adds escaping to all slashes in generated snippets.
+     *
+     * @param string $pattern
+     *
+     * @return string
+     */
+    private function escapeAlternationSyntax($pattern)
+    {
+        return str_replace('/', '\/', $pattern);
+    }
+
+    /**
+     * Removes escaping of alternation syntax from regex.
+     *
+     * This method removes those escaping backslashes from your slashes, so your steps
+     * could be matched against your escaped definitions.
+     *
+     * @param string $regex
+     *
+     * @return string
+     */
+    private function removeEscapingOfAlternationSyntax($regex)
+    {
+        return str_replace('\\\/', '/', $regex);
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Definition/Printer/ConsoleDefinitionInformationPrinter.php b/vendor/behat/behat/src/Behat/Behat/Definition/Printer/ConsoleDefinitionInformationPrinter.php
new file mode 100644 (file)
index 0000000..d690982
--- /dev/null
@@ -0,0 +1,147 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Definition\Printer;
+
+use Behat\Behat\Definition\Definition;
+use Behat\Testwork\Suite\Suite;
+
+/**
+ * Prints definitions with full information about them.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class ConsoleDefinitionInformationPrinter extends ConsoleDefinitionPrinter
+{
+    /**
+     * @var null|string
+     */
+    private $searchCriterion;
+
+    /**
+     * Sets search criterion.
+     *
+     * @param string $criterion
+     */
+    public function setSearchCriterion($criterion)
+    {
+        $this->searchCriterion = $criterion;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function printDefinitions(Suite $suite, $definitions)
+    {
+        $search = $this->searchCriterion;
+        $output = array();
+
+        foreach ($definitions as $definition) {
+            $definition = $this->translateDefinition($suite, $definition);
+            $pattern = $definition->getPattern();
+
+            if (null !== $search && false === mb_strpos($pattern, $search, 0, 'utf8')) {
+                continue;
+            }
+
+            $lines = array_merge(
+                $this->extractHeader($suite, $definition),
+                $this->extractDescription($suite, $definition),
+                $this->extractFooter($suite, $definition)
+            );
+
+            $output[] = implode(PHP_EOL, $lines) . PHP_EOL;
+        }
+
+        $this->write(rtrim(implode(PHP_EOL, $output)));
+    }
+
+    /**
+     * Extracts the formatted header from the definition.
+     *
+     * @param Suite      $suite
+     * @param Definition $definition
+     *
+     * @return string[]
+     */
+    private function extractHeader(Suite $suite, Definition $definition)
+    {
+        $pattern = $definition->getPattern();
+        $lines = array();
+        $lines[] = strtr(
+            '{suite} <def_dimmed>|</def_dimmed> <info>{type}</info> <def_regex>{regex}</def_regex>', array(
+                '{suite}' => $suite->getName(),
+                '{type}'  => $this->getDefinitionType($definition),
+                '{regex}' => $pattern,
+            )
+        );
+
+        return $lines;
+    }
+
+    /**
+     * Extracts the formatted description from the definition.
+     *
+     * @param Suite      $suite
+     * @param Definition $definition
+     *
+     * @return string[]
+     */
+    private function extractDescription(Suite $suite, Definition $definition)
+    {
+        $definition = $this->translateDefinition($suite, $definition);
+
+        $lines = array();
+        if ($description = $definition->getDescription()) {
+            foreach (explode("\n", $description) as $descriptionLine) {
+                $lines[] = strtr(
+                    '{space}<def_dimmed>|</def_dimmed> {description}', array(
+                        '{space}'       => str_pad('', mb_strlen($suite->getName(), 'utf8') + 1),
+                        '{description}' => $descriptionLine
+                    )
+                );
+            }
+        }
+
+        return $lines;
+    }
+
+    /**
+     * Extracts the formatted footer from the definition.
+     *
+     * @param Suite      $suite
+     * @param Definition $definition
+     *
+     * @return string[]
+     */
+    private function extractFooter(Suite $suite, Definition $definition)
+    {
+        $lines = array();
+        $lines[] = strtr(
+            '{space}<def_dimmed>|</def_dimmed> at `{path}`', array(
+                '{space}' => str_pad('', mb_strlen($suite->getName(), 'utf8') + 1),
+                '{path}'  => $definition->getPath()
+            )
+        );
+
+        if ($this->isVerbose()) {
+            $lines[] = strtr(
+                '{space}<def_dimmed>|</def_dimmed> on `{filepath}[{start}:{end}]`', array(
+                    '{space}' => str_pad('', mb_strlen($suite->getName(), 'utf8') + 1),
+                    '{filepath}' => $definition->getReflection()->getFileName(),
+                    '{start}' => $definition->getReflection()->getStartLine(),
+                    '{end}' => $definition->getReflection()->getEndLine()
+                )
+            );
+        }
+
+        return $lines;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Definition/Printer/ConsoleDefinitionListPrinter.php b/vendor/behat/behat/src/Behat/Behat/Definition/Printer/ConsoleDefinitionListPrinter.php
new file mode 100644 (file)
index 0000000..d155d94
--- /dev/null
@@ -0,0 +1,43 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Definition\Printer;
+
+use Behat\Testwork\Suite\Suite;
+
+/**
+ * Prints simple definitions list.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class ConsoleDefinitionListPrinter extends ConsoleDefinitionPrinter
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function printDefinitions(Suite $suite, $definitions)
+    {
+        $output = array();
+
+        foreach ($definitions as $definition) {
+            $definition = $this->translateDefinition($suite, $definition);
+
+            $output[] = strtr(
+                '{suite} <def_dimmed>|</def_dimmed> <info>{type}</info> <def_regex>{regex}</def_regex>', array(
+                    '{suite}' => $suite->getName(),
+                    '{type}'  => $this->getDefinitionType($definition, true),
+                    '{regex}' => $definition->getPattern(),
+                )
+            );
+        }
+
+        $this->write(rtrim(implode(PHP_EOL, $output)));
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Definition/Printer/ConsoleDefinitionPrinter.php b/vendor/behat/behat/src/Behat/Behat/Definition/Printer/ConsoleDefinitionPrinter.php
new file mode 100644 (file)
index 0000000..bd0546f
--- /dev/null
@@ -0,0 +1,123 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Definition\Printer;
+
+use Behat\Behat\Definition\Definition;
+use Behat\Behat\Definition\Pattern\PatternTransformer;
+use Behat\Behat\Definition\Translator\DefinitionTranslator;
+use Behat\Gherkin\Keywords\KeywordsInterface;
+use Behat\Testwork\Suite\Suite;
+use Symfony\Component\Console\Formatter\OutputFormatterStyle;
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * Represents console-based definition printer.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+abstract class ConsoleDefinitionPrinter implements DefinitionPrinter
+{
+    /**
+     * @var OutputInterface
+     */
+    private $output;
+    /**
+     * @var PatternTransformer
+     */
+    private $patternTransformer;
+    /**
+     * @var DefinitionTranslator
+     */
+    private $translator;
+    /**
+     * @var KeywordsInterface
+     */
+    private $keywords;
+
+    /**
+     * Initializes printer.
+     *
+     * @param OutputInterface     $output
+     * @param PatternTransformer  $patternTransformer
+     * @param DefinitionTranslator $translator
+     * @param KeywordsInterface   $keywords
+     */
+    public function __construct(
+        OutputInterface $output,
+        PatternTransformer $patternTransformer,
+        DefinitionTranslator $translator,
+        KeywordsInterface $keywords
+    ) {
+        $this->output = $output;
+        $this->patternTransformer = $patternTransformer;
+        $this->translator = $translator;
+        $this->keywords = $keywords;
+
+        $output->getFormatter()->setStyle('def_regex', new OutputFormatterStyle('yellow'));
+        $output->getFormatter()->setStyle(
+            'def_regex_capture',
+            new OutputFormatterStyle('yellow', null, array('bold'))
+        );
+        $output->getFormatter()->setStyle(
+            'def_dimmed',
+            new OutputFormatterStyle('black', null, array('bold'))
+        );
+    }
+
+    /**
+     * Writes text to the console.
+     *
+     * @param string $text
+     */
+    final protected function write($text)
+    {
+        $this->output->writeln($text);
+        $this->output->writeln('');
+    }
+
+    final protected function getDefinitionType(Definition $definition, $onlyOne = false)
+    {
+        $this->keywords->setLanguage($this->translator->getLocale());
+
+        $method = 'get'.ucfirst($definition->getType()).'Keywords';
+
+        $keywords = explode('|', $this->keywords->$method());
+
+        if ($onlyOne) {
+            return current($keywords);
+        }
+
+        return 1 < count($keywords) ? '['.implode('|', $keywords).']' : implode('|', $keywords);
+    }
+
+    /**
+     * Translates definition using translator.
+     *
+     * @param Suite      $suite
+     * @param Definition $definition
+     *
+     * @return Definition
+     */
+    final protected function translateDefinition(Suite $suite, Definition $definition)
+    {
+        return $this->translator->translateDefinition($suite, $definition);
+    }
+
+    /**
+     * Returns whether verbosity is verbose (-v).
+     *
+     * @return bool true if verbosity is set to VERBOSITY_VERBOSE, false otherwise
+     */
+    final protected function isVerbose()
+    {
+        return $this->output->isVerbose();
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Definition/Printer/DefinitionPrinter.php b/vendor/behat/behat/src/Behat/Behat/Definition/Printer/DefinitionPrinter.php
new file mode 100644 (file)
index 0000000..826ce5b
--- /dev/null
@@ -0,0 +1,30 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Definition\Printer;
+
+use Behat\Behat\Definition\Definition;
+use Behat\Testwork\Suite\Suite;
+
+/**
+ * Prints provided definition.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface DefinitionPrinter
+{
+    /**
+     * Prints definition.
+     *
+     * @param Suite        $suite
+     * @param Definition[] $definitions
+     */
+    public function printDefinitions(Suite $suite, $definitions);
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Definition/Search/RepositorySearchEngine.php b/vendor/behat/behat/src/Behat/Behat/Definition/Search/RepositorySearchEngine.php
new file mode 100644 (file)
index 0000000..6b69485
--- /dev/null
@@ -0,0 +1,130 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Definition\Search;
+
+use Behat\Behat\Definition\Definition;
+use Behat\Behat\Definition\DefinitionRepository;
+use Behat\Behat\Definition\Exception\AmbiguousMatchException;
+use Behat\Behat\Definition\Pattern\PatternTransformer;
+use Behat\Behat\Definition\SearchResult;
+use Behat\Behat\Definition\Translator\DefinitionTranslator;
+use Behat\Gherkin\Node\ArgumentInterface;
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\StepNode;
+use Behat\Testwork\Argument\ArgumentOrganiser;
+use Behat\Testwork\Environment\Environment;
+
+/**
+ * Searches for a step definition using definition repository.
+ *
+ * @see DefinitionRepository
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class RepositorySearchEngine implements SearchEngine
+{
+    /**
+     * @var DefinitionRepository
+     */
+    private $repository;
+    /**
+     * @var PatternTransformer
+     */
+    private $patternTransformer;
+    /**
+     * @var DefinitionTranslator
+     */
+    private $translator;
+    /**
+     * @var ArgumentOrganiser
+     */
+    private $argumentOrganiser;
+
+    /**
+     * Initializes search engine.
+     *
+     * @param DefinitionRepository $repository
+     * @param PatternTransformer   $patternTransformer
+     * @param DefinitionTranslator $translator
+     * @param ArgumentOrganiser    $argumentOrganiser
+     */
+    public function __construct(
+        DefinitionRepository $repository,
+        PatternTransformer $patternTransformer,
+        DefinitionTranslator $translator,
+        ArgumentOrganiser $argumentOrganiser
+    ) {
+        $this->repository = $repository;
+        $this->patternTransformer = $patternTransformer;
+        $this->translator = $translator;
+        $this->argumentOrganiser = $argumentOrganiser;
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @throws AmbiguousMatchException
+     */
+    public function searchDefinition(
+        Environment $environment,
+        FeatureNode $feature,
+        StepNode $step
+    ) {
+        $suite = $environment->getSuite();
+        $language = $feature->getLanguage();
+        $stepText = $step->getText();
+        $multi = $step->getArguments();
+
+        $definitions = array();
+        $result = null;
+
+        foreach ($this->repository->getEnvironmentDefinitions($environment) as $definition) {
+            $definition = $this->translator->translateDefinition($suite, $definition, $language);
+
+            if (!$newResult = $this->match($definition, $stepText, $multi)) {
+                continue;
+            }
+
+            $result = $newResult;
+            $definitions[] = $newResult->getMatchedDefinition();
+        }
+
+        if (count($definitions) > 1) {
+            throw new AmbiguousMatchException($result->getMatchedText(), $definitions);
+        }
+
+        return $result;
+    }
+
+    /**
+     * Attempts to match provided definition against a step text.
+     *
+     * @param Definition          $definition
+     * @param string              $stepText
+     * @param ArgumentInterface[] $multiline
+     *
+     * @return null|SearchResult
+     */
+    private function match(Definition $definition, $stepText, array $multiline)
+    {
+        $regex = $this->patternTransformer->transformPatternToRegex($definition->getPattern());
+
+        if (!preg_match($regex, $stepText, $match)) {
+            return null;
+        }
+
+        $function = $definition->getReflection();
+        $match = array_merge($match, array_values($multiline));
+        $arguments = $this->argumentOrganiser->organiseArguments($function, $match);
+
+        return new SearchResult($definition, $stepText, $arguments);
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Definition/Search/SearchEngine.php b/vendor/behat/behat/src/Behat/Behat/Definition/Search/SearchEngine.php
new file mode 100644 (file)
index 0000000..a869adc
--- /dev/null
@@ -0,0 +1,38 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Definition\Search;
+
+use Behat\Behat\Definition\DefinitionFinder;
+use Behat\Behat\Definition\SearchResult;
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\StepNode;
+use Behat\Testwork\Environment\Environment;
+
+/**
+ * Searches for a step definition in a specific environment.
+ *
+ * @see DefinitionFinder
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface SearchEngine
+{
+    /**
+     * Searches for a step definition.
+     *
+     * @param Environment $environment
+     * @param FeatureNode $feature
+     * @param StepNode    $step
+     *
+     * @return null|SearchResult
+     */
+    public function searchDefinition(Environment $environment, FeatureNode $feature, StepNode $step);
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Definition/SearchResult.php b/vendor/behat/behat/src/Behat/Behat/Definition/SearchResult.php
new file mode 100644 (file)
index 0000000..158f635
--- /dev/null
@@ -0,0 +1,86 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Definition;
+
+/**
+ * Step definition search result.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class SearchResult
+{
+    /**
+     * @var null|Definition
+     */
+    private $definition;
+    /**
+     * @var null|string
+     */
+    private $matchedText;
+    /**
+     * @var null|array
+     */
+    private $arguments;
+
+    /**
+     * Registers search match.
+     *
+     * @param null|Definition $definition
+     * @param null|string     $matchedText
+     * @param null|array      $arguments
+     */
+    public function __construct(Definition $definition = null, $matchedText = null, array $arguments = null)
+    {
+        $this->definition = $definition;
+        $this->matchedText = $matchedText;
+        $this->arguments = $arguments;
+    }
+
+    /**
+     * Checks if result contains a match.
+     *
+     * @return Boolean
+     */
+    public function hasMatch()
+    {
+        return null !== $this->definition;
+    }
+
+    /**
+     * Returns matched definition.
+     *
+     * @return null|Definition
+     */
+    public function getMatchedDefinition()
+    {
+        return $this->definition;
+    }
+
+    /**
+     * Returns matched text.
+     *
+     * @return null|string
+     */
+    public function getMatchedText()
+    {
+        return $this->matchedText;
+    }
+
+    /**
+     * Returns matched definition arguments.
+     *
+     * @return null|array
+     */
+    public function getMatchedArguments()
+    {
+        return $this->arguments;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Definition/ServiceContainer/DefinitionExtension.php b/vendor/behat/behat/src/Behat/Behat/Definition/ServiceContainer/DefinitionExtension.php
new file mode 100644 (file)
index 0000000..cce4341
--- /dev/null
@@ -0,0 +1,310 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Definition\ServiceContainer;
+
+use Behat\Behat\Context\ServiceContainer\ContextExtension;
+use Behat\Testwork\Argument\ServiceContainer\ArgumentExtension;
+use Behat\Behat\Gherkin\ServiceContainer\GherkinExtension;
+use Behat\Testwork\Cli\ServiceContainer\CliExtension;
+use Behat\Testwork\Environment\ServiceContainer\EnvironmentExtension;
+use Behat\Testwork\ServiceContainer\Extension;
+use Behat\Testwork\ServiceContainer\ExtensionManager;
+use Behat\Testwork\ServiceContainer\ServiceProcessor;
+use Behat\Testwork\Suite\ServiceContainer\SuiteExtension;
+use Behat\Testwork\Translator\ServiceContainer\TranslatorExtension;
+use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Definition;
+use Symfony\Component\DependencyInjection\Reference;
+
+/**
+ * Extends Behat with definition services.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class DefinitionExtension implements Extension
+{
+    /*
+     * Available services
+     */
+    const FINDER_ID = 'definition.finder';
+    const REPOSITORY_ID = 'definition.repository';
+    const PATTERN_TRANSFORMER_ID = 'definition.pattern_transformer';
+    const WRITER_ID = 'definition.writer';
+    const DEFINITION_TRANSLATOR_ID = 'definition.translator';
+
+    /*
+     * Available extension points
+     */
+    const SEARCH_ENGINE_TAG = 'definition.search_engine';
+    const PATTERN_POLICY_TAG = 'definition.pattern_policy';
+
+    /**
+     * @var ServiceProcessor
+     */
+    private $processor;
+
+    /**
+     * Initializes compiler pass.
+     *
+     * @param null|ServiceProcessor $processor
+     */
+    public function __construct(ServiceProcessor $processor = null)
+    {
+        $this->processor = $processor ? : new ServiceProcessor();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getConfigKey()
+    {
+        return 'definitions';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function initialize(ExtensionManager $extensionManager)
+    {
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function configure(ArrayNodeDefinition $builder)
+    {
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function load(ContainerBuilder $container, array $config)
+    {
+        $this->loadFinder($container);
+        $this->loadRepository($container);
+        $this->loadWriter($container);
+        $this->loadPatternTransformer($container);
+        $this->loadDefinitionTranslator($container);
+        $this->loadDefaultSearchEngines($container);
+        $this->loadDefaultPatternPolicies($container);
+        $this->loadAnnotationReader($container);
+        $this->loadDefinitionPrinters($container);
+        $this->loadController($container);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function process(ContainerBuilder $container)
+    {
+        $this->processSearchEngines($container);
+        $this->processPatternPolicies($container);
+    }
+
+    /**
+     * Loads definition finder.
+     *
+     * @param ContainerBuilder $container
+     */
+    private function loadFinder(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Behat\Definition\DefinitionFinder');
+        $container->setDefinition(self::FINDER_ID, $definition);
+    }
+
+    /**
+     * Loads definition repository.
+     *
+     * @param ContainerBuilder $container
+     */
+    private function loadRepository(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Behat\Definition\DefinitionRepository', array(
+            new Reference(EnvironmentExtension::MANAGER_ID)
+        ));
+        $container->setDefinition(self::REPOSITORY_ID, $definition);
+    }
+
+    /**
+     * Loads definition writer.
+     *
+     * @param ContainerBuilder $container
+     */
+    private function loadWriter(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Behat\Definition\DefinitionWriter', array(
+            new Reference(EnvironmentExtension::MANAGER_ID),
+            new Reference(self::REPOSITORY_ID)
+        ));
+        $container->setDefinition(self::WRITER_ID, $definition);
+    }
+
+    /**
+     * Loads definition pattern transformer.
+     *
+     * @param ContainerBuilder $container
+     */
+    private function loadPatternTransformer(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Behat\Definition\Pattern\PatternTransformer');
+        $container->setDefinition(self::PATTERN_TRANSFORMER_ID, $definition);
+    }
+
+    /**
+     * Loads definition translator.
+     *
+     * @param ContainerBuilder $container
+     */
+    private function loadDefinitionTranslator(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Behat\Definition\Translator\DefinitionTranslator', array(
+            new Reference(TranslatorExtension::TRANSLATOR_ID)
+        ));
+        $container->setDefinition(self::DEFINITION_TRANSLATOR_ID, $definition);
+    }
+
+    /**
+     * Loads default search engines.
+     *
+     * @param ContainerBuilder $container
+     */
+    private function loadDefaultSearchEngines(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Behat\Definition\Search\RepositorySearchEngine', array(
+            new Reference(self::REPOSITORY_ID),
+            new Reference(self::PATTERN_TRANSFORMER_ID),
+            new Reference(self::DEFINITION_TRANSLATOR_ID),
+            new Reference(ArgumentExtension::PREG_MATCH_ARGUMENT_ORGANISER_ID)
+        ));
+        $definition->addTag(self::SEARCH_ENGINE_TAG, array('priority' => 50));
+        $container->setDefinition(self::SEARCH_ENGINE_TAG . '.repository', $definition);
+    }
+
+    /**
+     * Loads default pattern policies.
+     *
+     * @param ContainerBuilder $container
+     */
+    private function loadDefaultPatternPolicies(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Behat\Definition\Pattern\Policy\TurnipPatternPolicy');
+        $definition->addTag(self::PATTERN_POLICY_TAG, array('priority' => 50));
+        $container->setDefinition(self::PATTERN_POLICY_TAG . '.turnip', $definition);
+
+        $definition = new Definition('Behat\Behat\Definition\Pattern\Policy\RegexPatternPolicy');
+        $definition->addTag(self::PATTERN_POLICY_TAG, array('priority' => 60));
+        $container->setDefinition(self::PATTERN_POLICY_TAG . '.regex', $definition);
+    }
+
+    /**
+     * Loads definition annotation reader.
+     *
+     * @param ContainerBuilder $container
+     */
+    private function loadAnnotationReader(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Behat\Definition\Context\Annotation\DefinitionAnnotationReader');
+        $definition->addTag(ContextExtension::ANNOTATION_READER_TAG, array('priority' => 50));
+        $container->setDefinition(ContextExtension::ANNOTATION_READER_TAG . '.definition', $definition);
+    }
+
+    /**
+     * Loads definition printers.
+     *
+     * @param ContainerBuilder $container
+     */
+    private function loadDefinitionPrinters(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Behat\Definition\Printer\ConsoleDefinitionInformationPrinter', array(
+            new Reference(CliExtension::OUTPUT_ID),
+            new Reference(self::PATTERN_TRANSFORMER_ID),
+            new Reference(self::DEFINITION_TRANSLATOR_ID),
+            new Reference(GherkinExtension::KEYWORDS_ID)
+        ));
+        $container->setDefinition($this->getInformationPrinterId(), $definition);
+
+        $definition = new Definition('Behat\Behat\Definition\Printer\ConsoleDefinitionListPrinter', array(
+            new Reference(CliExtension::OUTPUT_ID),
+            new Reference(self::PATTERN_TRANSFORMER_ID),
+            new Reference(self::DEFINITION_TRANSLATOR_ID),
+            new Reference(GherkinExtension::KEYWORDS_ID)
+        ));
+        $container->setDefinition($this->getListPrinterId(), $definition);
+    }
+
+    /**
+     * Loads definition controller.
+     *
+     * @param ContainerBuilder $container
+     */
+    private function loadController(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Behat\Definition\Cli\AvailableDefinitionsController', array(
+            new Reference(SuiteExtension::REGISTRY_ID),
+            new Reference(self::WRITER_ID),
+            new Reference($this->getListPrinterId()),
+            new Reference($this->getInformationPrinterId())
+        ));
+        $definition->addTag(CliExtension::CONTROLLER_TAG, array('priority' => 500));
+        $container->setDefinition(CliExtension::CONTROLLER_TAG . '.available_definitions', $definition);
+    }
+
+    /**
+     * Processes all search engines in the container.
+     *
+     * @param ContainerBuilder $container
+     */
+    private function processSearchEngines(ContainerBuilder $container)
+    {
+        $references = $this->processor->findAndSortTaggedServices($container, self::SEARCH_ENGINE_TAG);
+        $definition = $container->getDefinition(self::FINDER_ID);
+
+        foreach ($references as $reference) {
+            $definition->addMethodCall('registerSearchEngine', array($reference));
+        }
+    }
+
+    /**
+     * Processes all pattern policies.
+     *
+     * @param ContainerBuilder $container
+     */
+    private function processPatternPolicies(ContainerBuilder $container)
+    {
+        $references = $this->processor->findAndSortTaggedServices($container, self::PATTERN_POLICY_TAG);
+        $definition = $container->getDefinition(self::PATTERN_TRANSFORMER_ID);
+
+        foreach ($references as $reference) {
+            $definition->addMethodCall('registerPatternPolicy', array($reference));
+        }
+    }
+
+    /**
+     * returns list printer service id.
+     *
+     * @return string
+     */
+    private function getListPrinterId()
+    {
+        return 'definition.list_printer';
+    }
+
+    /**
+     * Returns information printer service id.
+     *
+     * @return string
+     */
+    private function getInformationPrinterId()
+    {
+        return 'definition.information_printer';
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Definition/Translator/DefinitionTranslator.php b/vendor/behat/behat/src/Behat/Behat/Definition/Translator/DefinitionTranslator.php
new file mode 100644 (file)
index 0000000..3192a3d
--- /dev/null
@@ -0,0 +1,65 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Definition\Translator;
+
+use Behat\Behat\Definition\Definition;
+use Behat\Testwork\Suite\Suite;
+use Symfony\Component\Translation\TranslatorInterface;
+
+/**
+ * Translates definitions using translator component.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class DefinitionTranslator
+{
+    /**
+     * @var TranslatorInterface
+     */
+    private $translator;
+
+    /**
+     * Initialises definition translator.
+     *
+     * @param TranslatorInterface $translator
+     */
+    public function __construct(TranslatorInterface $translator)
+    {
+        $this->translator = $translator;
+    }
+
+    /**
+     * Attempts to translate definition using translator and produce translated one on success.
+     *
+     * @param Suite       $suite
+     * @param Definition  $definition
+     * @param null|string $language
+     *
+     * @return Definition|TranslatedDefinition
+     */
+    public function translateDefinition(Suite $suite, Definition $definition, $language = null)
+    {
+        $assetsId = $suite->getName();
+        $pattern = $definition->getPattern();
+
+        $translatedPattern = $this->translator->trans($pattern, array(), $assetsId, $language);
+        if ($pattern != $translatedPattern) {
+            return new TranslatedDefinition($definition, $translatedPattern, $language);
+        }
+
+        return $definition;
+    }
+
+    public function getLocale()
+    {
+        return $this->translator->getLocale();
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Definition/Translator/TranslatedDefinition.php b/vendor/behat/behat/src/Behat/Behat/Definition/Translator/TranslatedDefinition.php
new file mode 100644 (file)
index 0000000..69813fa
--- /dev/null
@@ -0,0 +1,140 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Definition\Translator;
+
+use Behat\Behat\Definition\Definition;
+
+/**
+ * Represents definition translated to the specific language.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class TranslatedDefinition implements Definition
+{
+    /**
+     * @var Definition
+     */
+    private $definition;
+    /**
+     * @var string
+     */
+    private $translatedPattern;
+    /**
+     * @var string
+     */
+    private $language;
+
+    /**
+     * Initialises translated definition.
+     *
+     * @param Definition $definition
+     * @param string     $translatedPattern
+     * @param string     $language
+     */
+    public function __construct(Definition $definition, $translatedPattern, $language)
+    {
+        $this->definition = $definition;
+        $this->translatedPattern = $translatedPattern;
+        $this->language = $language;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getType()
+    {
+        return $this->definition->getType();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getPattern()
+    {
+        return $this->translatedPattern;
+    }
+
+    /**
+     * Returns original (not translated) pattern.
+     *
+     * @return string
+     */
+    public function getOriginalPattern()
+    {
+        return $this->definition->getPattern();
+    }
+
+    /**
+     * Returns language definition was translated to.
+     *
+     * @return string
+     */
+    public function getLanguage()
+    {
+        return $this->language;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getDescription()
+    {
+        return $this->definition->getDescription();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getPath()
+    {
+        return $this->definition->getPath();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function isAMethod()
+    {
+        return $this->definition->isAMethod();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function isAnInstanceMethod()
+    {
+        return $this->definition->isAnInstanceMethod();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getCallable()
+    {
+        return $this->definition->getCallable();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getReflection()
+    {
+        return $this->definition->getReflection();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function __toString()
+    {
+        return $this->definition->__toString();
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Cli/StopOnFailureController.php b/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Cli/StopOnFailureController.php
new file mode 100644 (file)
index 0000000..d86b345
--- /dev/null
@@ -0,0 +1,108 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\EventDispatcher\Cli;
+
+use Behat\Behat\EventDispatcher\Event\AfterScenarioTested;
+use Behat\Behat\EventDispatcher\Event\ExampleTested;
+use Behat\Behat\EventDispatcher\Event\ScenarioTested;
+use Behat\Testwork\Cli\Controller;
+use Behat\Testwork\EventDispatcher\Event\AfterExerciseAborted;
+use Behat\Testwork\EventDispatcher\Event\AfterSuiteAborted;
+use Behat\Testwork\EventDispatcher\Event\ExerciseCompleted;
+use Behat\Testwork\EventDispatcher\Event\SuiteTested;
+use Behat\Testwork\Tester\Result\Interpretation\ResultInterpretation;
+use Behat\Testwork\Tester\Result\Interpretation\SoftInterpretation;
+use Behat\Testwork\Tester\Result\Interpretation\StrictInterpretation;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\EventDispatcher\EventDispatcherInterface;
+
+/**
+ * Stops tests on first scenario failure.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class StopOnFailureController implements Controller
+{
+    /**
+     * @var EventDispatcherInterface
+     */
+    private $eventDispatcher;
+
+    /**
+     * @var ResultInterpretation
+     */
+    private $resultInterpretation;
+
+    /**
+     * Initializes controller.
+     *
+     * @param EventDispatcherInterface $eventDispatcher
+     */
+    public function __construct(EventDispatcherInterface $eventDispatcher)
+    {
+        $this->eventDispatcher = $eventDispatcher;
+        $this->resultInterpretation = new SoftInterpretation();
+    }
+
+    /**
+     * Configures command to be executable by the controller.
+     *
+     * @param Command $command
+     */
+    public function configure(Command $command)
+    {
+        $command->addOption('--stop-on-failure', null, InputOption::VALUE_NONE,
+            'Stop processing on first failed scenario.'
+        );
+    }
+
+    /**
+     * Executes controller.
+     *
+     * @param InputInterface  $input
+     * @param OutputInterface $output
+     *
+     * @return null|integer
+     */
+    public function execute(InputInterface $input, OutputInterface $output)
+    {
+        if (!$input->getOption('stop-on-failure')) {
+            return null;
+        }
+
+        if ($input->getOption('strict')) {
+            $this->resultInterpretation = new StrictInterpretation();
+        }
+
+        $this->eventDispatcher->addListener(ScenarioTested::AFTER, array($this, 'exitOnFailure'), -100);
+        $this->eventDispatcher->addListener(ExampleTested::AFTER, array($this, 'exitOnFailure'), -100);
+    }
+
+    /**
+     * Exits if scenario is a failure and if stopper is enabled.
+     *
+     * @param AfterScenarioTested $event
+     */
+    public function exitOnFailure(AfterScenarioTested $event)
+    {
+        if (!$this->resultInterpretation->isFailure($event->getTestResult())) {
+            return;
+        }
+
+        $this->eventDispatcher->dispatch(SuiteTested::AFTER, new AfterSuiteAborted($event->getEnvironment()));
+        $this->eventDispatcher->dispatch(ExerciseCompleted::AFTER, new AfterExerciseAborted());
+
+        exit(1);
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/AfterBackgroundSetup.php b/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/AfterBackgroundSetup.php
new file mode 100644 (file)
index 0000000..59b32ad
--- /dev/null
@@ -0,0 +1,96 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\EventDispatcher\Event;
+
+use Behat\Gherkin\Node\BackgroundNode;
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\ScenarioInterface;
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\EventDispatcher\Event\AfterSetup;
+use Behat\Testwork\Tester\Setup\Setup;
+
+/**
+ * Represents an event right after background was setup for testing.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class AfterBackgroundSetup extends BackgroundTested implements AfterSetup
+{
+    /**
+     * @var FeatureNode
+     */
+    private $feature;
+    /**
+     * @var BackgroundNode
+     */
+    private $background;
+    /**
+     * @var Setup
+     */
+    private $setup;
+
+    /**
+     * Initializes event.
+     *
+     * @param Environment    $env
+     * @param FeatureNode    $feature
+     * @param BackgroundNode $background
+     * @param Setup          $setup
+     */
+    public function __construct(Environment $env, FeatureNode $feature, BackgroundNode $background, Setup $setup)
+    {
+        parent::__construct($env);
+
+        $this->feature = $feature;
+        $this->background = $background;
+        $this->setup = $setup;
+    }
+
+    /**
+     * Returns feature.
+     *
+     * @return FeatureNode
+     */
+    public function getFeature()
+    {
+        return $this->feature;
+    }
+
+    /**
+     * Returns scenario node.
+     *
+     * @return ScenarioInterface
+     */
+    public function getScenario()
+    {
+        return $this->background;
+    }
+
+    /**
+     * Returns background node.
+     *
+     * @return BackgroundNode
+     */
+    public function getBackground()
+    {
+        return $this->background;
+    }
+
+    /**
+     * Returns current test setup.
+     *
+     * @return Setup
+     */
+    public function getSetup()
+    {
+        return $this->setup;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/AfterBackgroundTested.php b/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/AfterBackgroundTested.php
new file mode 100644 (file)
index 0000000..76e1577
--- /dev/null
@@ -0,0 +1,118 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\EventDispatcher\Event;
+
+use Behat\Gherkin\Node\BackgroundNode;
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\ScenarioInterface;
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\EventDispatcher\Event\AfterTested;
+use Behat\Testwork\Tester\Result\TestResult;
+use Behat\Testwork\Tester\Setup\Teardown;
+
+/**
+ * Represents an event in which background was tested.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class AfterBackgroundTested extends BackgroundTested implements AfterTested
+{
+    /**
+     * @var FeatureNode
+     */
+    private $feature;
+    /**
+     * @var BackgroundNode
+     */
+    private $background;
+    /**
+     * @var TestResult
+     */
+    private $result;
+    /**
+     * @var Teardown
+     */
+    private $teardown;
+
+    /**
+     * Initializes event.
+     *
+     * @param Environment    $env
+     * @param FeatureNode    $feature
+     * @param BackgroundNode $background
+     * @param TestResult     $result
+     * @param Teardown       $teardown
+     */
+    public function __construct(
+        Environment $env,
+        FeatureNode $feature,
+        BackgroundNode $background,
+        TestResult $result,
+        Teardown $teardown
+    ) {
+        parent::__construct($env);
+
+        $this->feature = $feature;
+        $this->background = $background;
+        $this->result = $result;
+        $this->teardown = $teardown;
+    }
+
+    /**
+     * Returns feature.
+     *
+     * @return FeatureNode
+     */
+    public function getFeature()
+    {
+        return $this->feature;
+    }
+
+    /**
+     * Returns scenario node.
+     *
+     * @return ScenarioInterface
+     */
+    public function getScenario()
+    {
+        return $this->background;
+    }
+
+    /**
+     * Returns background node.
+     *
+     * @return BackgroundNode
+     */
+    public function getBackground()
+    {
+        return $this->background;
+    }
+
+    /**
+     * Returns current test result.
+     *
+     * @return TestResult
+     */
+    public function getTestResult()
+    {
+        return $this->result;
+    }
+
+    /**
+     * Returns current test teardown.
+     *
+     * @return Teardown
+     */
+    public function getTeardown()
+    {
+        return $this->teardown;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/AfterFeatureSetup.php b/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/AfterFeatureSetup.php
new file mode 100644 (file)
index 0000000..73076ea
--- /dev/null
@@ -0,0 +1,68 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\EventDispatcher\Event;
+
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\EventDispatcher\Event\AfterSetup;
+use Behat\Testwork\Tester\Setup\Setup;
+
+/**
+ * Represents an event right after feature is setup for a test.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class AfterFeatureSetup extends FeatureTested implements AfterSetup
+{
+    /**
+     * @var FeatureNode
+     */
+    private $feature;
+    /**
+     * @var Setup
+     */
+    private $setup;
+
+    /**
+     * Initializes event.
+     *
+     * @param Environment $env
+     * @param FeatureNode $feature
+     * @param Setup       $setup
+     */
+    public function __construct(Environment $env, FeatureNode $feature, Setup $setup)
+    {
+        parent::__construct($env);
+
+        $this->feature = $feature;
+        $this->setup = $setup;
+    }
+
+    /**
+     * Returns feature.
+     *
+     * @return FeatureNode
+     */
+    public function getFeature()
+    {
+        return $this->feature;
+    }
+
+    /**
+     * Returns current test setup.
+     *
+     * @return Setup
+     */
+    public function getSetup()
+    {
+        return $this->setup;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/AfterFeatureTested.php b/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/AfterFeatureTested.php
new file mode 100644 (file)
index 0000000..ed19128
--- /dev/null
@@ -0,0 +1,85 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\EventDispatcher\Event;
+
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\EventDispatcher\Event\AfterTested;
+use Behat\Testwork\Tester\Result\TestResult;
+use Behat\Testwork\Tester\Setup\Teardown;
+
+/**
+ * Represents an event right after feature was tested.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class AfterFeatureTested extends FeatureTested implements AfterTested
+{
+    /**
+     * @var FeatureNode
+     */
+    private $feature;
+    /**
+     * @var TestResult
+     */
+    private $result;
+    /**
+     * @var Teardown
+     */
+    private $teardown;
+
+    /**
+     * Initializes event.
+     *
+     * @param Environment $env
+     * @param FeatureNode $feature
+     * @param TestResult  $result
+     * @param Teardown    $teardown
+     */
+    public function __construct(Environment $env, FeatureNode $feature, TestResult $result, Teardown $teardown)
+    {
+        parent::__construct($env);
+
+        $this->feature = $feature;
+        $this->result = $result;
+        $this->teardown = $teardown;
+    }
+
+    /**
+     * Returns feature.
+     *
+     * @return FeatureNode
+     */
+    public function getFeature()
+    {
+        return $this->feature;
+    }
+
+    /**
+     * Returns current test result.
+     *
+     * @return TestResult
+     */
+    public function getTestResult()
+    {
+        return $this->result;
+    }
+
+    /**
+     * Returns current test teardown.
+     *
+     * @return Teardown
+     */
+    public function getTeardown()
+    {
+        return $this->teardown;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/AfterOutlineSetup.php b/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/AfterOutlineSetup.php
new file mode 100644 (file)
index 0000000..3251d24
--- /dev/null
@@ -0,0 +1,85 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\EventDispatcher\Event;
+
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\OutlineNode;
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\EventDispatcher\Event\AfterSetup;
+use Behat\Testwork\Tester\Setup\Setup;
+
+/**
+ * Represents an event right after outline setup.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class AfterOutlineSetup extends OutlineTested implements AfterSetup
+{
+    /**
+     * @var FeatureNode
+     */
+    private $feature;
+    /**
+     * @var OutlineNode
+     */
+    private $outline;
+    /**
+     * @var Setup
+     */
+    private $setup;
+
+    /**
+     * Initializes event.
+     *
+     * @param Environment $env
+     * @param FeatureNode $feature
+     * @param OutlineNode $outline
+     * @param Setup       $setup
+     */
+    public function __construct(Environment $env, FeatureNode $feature, OutlineNode $outline, Setup $setup)
+    {
+        parent::__construct($env);
+
+        $this->feature = $feature;
+        $this->outline = $outline;
+        $this->setup = $setup;
+    }
+
+    /**
+     * Returns feature.
+     *
+     * @return FeatureNode
+     */
+    public function getFeature()
+    {
+        return $this->feature;
+    }
+
+    /**
+     * Returns outline node.
+     *
+     * @return OutlineNode
+     */
+    public function getOutline()
+    {
+        return $this->outline;
+    }
+
+    /**
+     * Returns current test setup.
+     *
+     * @return Setup
+     */
+    public function getSetup()
+    {
+        return $this->setup;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/AfterOutlineTested.php b/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/AfterOutlineTested.php
new file mode 100644 (file)
index 0000000..b4fd1a2
--- /dev/null
@@ -0,0 +1,107 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\EventDispatcher\Event;
+
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\OutlineNode;
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\EventDispatcher\Event\AfterTested;
+use Behat\Testwork\Tester\Result\TestResult;
+use Behat\Testwork\Tester\Setup\Teardown;
+
+/**
+ * Represents an event after outline was tested.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class AfterOutlineTested extends OutlineTested implements AfterTested
+{
+    /**
+     * @var FeatureNode
+     */
+    private $feature;
+    /**
+     * @var OutlineNode
+     */
+    private $outline;
+    /**
+     * @var TestResult
+     */
+    private $result;
+    /**
+     * @var Teardown
+     */
+    private $teardown;
+
+    /**
+     * Initializes event.
+     *
+     * @param Environment $env
+     * @param FeatureNode $feature
+     * @param OutlineNode $outline
+     * @param TestResult  $result
+     * @param Teardown    $teardown
+     */
+    public function __construct(
+        Environment $env,
+        FeatureNode $feature,
+        OutlineNode $outline,
+        TestResult $result,
+        Teardown $teardown
+    ) {
+        parent::__construct($env);
+
+        $this->feature = $feature;
+        $this->outline = $outline;
+        $this->result = $result;
+        $this->teardown = $teardown;
+    }
+
+    /**
+     * Returns feature.
+     *
+     * @return FeatureNode
+     */
+    public function getFeature()
+    {
+        return $this->feature;
+    }
+
+    /**
+     * Returns outline node.
+     *
+     * @return OutlineNode
+     */
+    public function getOutline()
+    {
+        return $this->outline;
+    }
+
+    /**
+     * Returns current test result.
+     *
+     * @return TestResult
+     */
+    public function getTestResult()
+    {
+        return $this->result;
+    }
+
+    /**
+     * Returns current test teardown.
+     *
+     * @return Teardown
+     */
+    public function getTeardown()
+    {
+        return $this->teardown;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/AfterScenarioSetup.php b/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/AfterScenarioSetup.php
new file mode 100644 (file)
index 0000000..38666bf
--- /dev/null
@@ -0,0 +1,86 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\EventDispatcher\Event;
+
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\ScenarioLikeInterface as Scenario;
+use Behat\Gherkin\Node\ScenarioNode;
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\EventDispatcher\Event\AfterSetup;
+use Behat\Testwork\Tester\Setup\Setup;
+
+/**
+ * Represents an event after scenario setup.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class AfterScenarioSetup extends ScenarioTested implements AfterSetup
+{
+    /**
+     * @var FeatureNode
+     */
+    private $feature;
+    /**
+     * @var Scenario
+     */
+    private $scenario;
+    /**
+     * @var Setup
+     */
+    private $setup;
+
+    /**
+     * Initializes event
+     *
+     * @param Environment $env
+     * @param FeatureNode $feature
+     * @param Scenario    $scenario
+     * @param Setup       $setup
+     */
+    public function __construct(Environment $env, FeatureNode $feature, Scenario $scenario, Setup $setup)
+    {
+        parent::__construct($env);
+
+        $this->feature = $feature;
+        $this->scenario = $scenario;
+        $this->setup = $setup;
+    }
+
+    /**
+     * Returns feature.
+     *
+     * @return FeatureNode
+     */
+    public function getFeature()
+    {
+        return $this->feature;
+    }
+
+    /**
+     * Returns scenario node.
+     *
+     * @return ScenarioNode
+     */
+    public function getScenario()
+    {
+        return $this->scenario;
+    }
+
+    /**
+     * Returns current test setup.
+     *
+     * @return Setup
+     */
+    public function getSetup()
+    {
+        return $this->setup;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/AfterScenarioTested.php b/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/AfterScenarioTested.php
new file mode 100644 (file)
index 0000000..6af6f18
--- /dev/null
@@ -0,0 +1,108 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\EventDispatcher\Event;
+
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\ScenarioLikeInterface as Scenario;
+use Behat\Gherkin\Node\ScenarioNode;
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\EventDispatcher\Event\AfterTested;
+use Behat\Testwork\Tester\Result\TestResult;
+use Behat\Testwork\Tester\Setup\Teardown;
+
+/**
+ * Represents an event after scenario has been tested.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class AfterScenarioTested extends ScenarioTested implements AfterTested
+{
+    /**
+     * @var FeatureNode
+     */
+    private $feature;
+    /**
+     * @var Scenario
+     */
+    private $scenario;
+    /**
+     * @var TestResult
+     */
+    private $result;
+    /**
+     * @var Teardown
+     */
+    private $teardown;
+
+    /**
+     * Initializes event
+     *
+     * @param Environment $env
+     * @param FeatureNode $feature
+     * @param Scenario    $scenario
+     * @param TestResult  $result
+     * @param Teardown    $teardown
+     */
+    public function __construct(
+        Environment $env,
+        FeatureNode $feature,
+        Scenario $scenario,
+        TestResult $result,
+        Teardown $teardown
+    ) {
+        parent::__construct($env);
+
+        $this->feature = $feature;
+        $this->scenario = $scenario;
+        $this->result = $result;
+        $this->teardown = $teardown;
+    }
+
+    /**
+     * Returns feature.
+     *
+     * @return FeatureNode
+     */
+    public function getFeature()
+    {
+        return $this->feature;
+    }
+
+    /**
+     * Returns scenario node.
+     *
+     * @return ScenarioNode
+     */
+    public function getScenario()
+    {
+        return $this->scenario;
+    }
+
+    /**
+     * Returns current test result.
+     *
+     * @return TestResult
+     */
+    public function getTestResult()
+    {
+        return $this->result;
+    }
+
+    /**
+     * Returns current test teardown.
+     *
+     * @return Teardown
+     */
+    public function getTeardown()
+    {
+        return $this->teardown;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/AfterStepSetup.php b/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/AfterStepSetup.php
new file mode 100644 (file)
index 0000000..cf9b6c5
--- /dev/null
@@ -0,0 +1,95 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\EventDispatcher\Event;
+
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\StepNode;
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\EventDispatcher\Event\AfterSetup;
+use Behat\Testwork\Tester\Setup\Setup;
+
+/**
+ * Represents an event after step setup.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class AfterStepSetup extends StepTested implements AfterSetup
+{
+    /**
+     * @var FeatureNode
+     */
+    private $feature;
+    /**
+     * @var StepNode
+     */
+    private $step;
+    /**
+     * @var Setup
+     */
+    private $setup;
+
+    /**
+     * Initializes event.
+     *
+     * @param Environment $env
+     * @param FeatureNode $feature
+     * @param StepNode    $step
+     * @param Setup       $setup
+     */
+    public function __construct(Environment $env, FeatureNode $feature, StepNode $step, Setup $setup)
+    {
+        parent::__construct($env);
+
+        $this->feature = $feature;
+        $this->step = $step;
+        $this->setup = $setup;
+    }
+
+    /**
+     * Returns feature.
+     *
+     * @return FeatureNode
+     */
+    public function getFeature()
+    {
+        return $this->feature;
+    }
+
+    /**
+     * Returns step node.
+     *
+     * @return StepNode
+     */
+    public function getStep()
+    {
+        return $this->step;
+    }
+
+    /**
+     * Returns current test setup.
+     *
+     * @return Setup
+     */
+    public function getSetup()
+    {
+        return $this->setup;
+    }
+
+    /**
+     * Checks if step call, setup or teardown produced any output (stdOut or exception).
+     *
+     * @return Boolean
+     */
+    public function hasOutput()
+    {
+        return $this->setup->hasOutput();
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/AfterStepTested.php b/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/AfterStepTested.php
new file mode 100644 (file)
index 0000000..37b497b
--- /dev/null
@@ -0,0 +1,154 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\EventDispatcher\Event;
+
+use Behat\Behat\Tester\Result\ExecutedStepResult;
+use Behat\Behat\Tester\Result\StepResult;
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\StepNode;
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\EventDispatcher\Event\AfterTested;
+use Behat\Testwork\Tester\Result\ExceptionResult;
+use Behat\Testwork\Tester\Result\TestResult;
+use Behat\Testwork\Tester\Setup\Teardown;
+
+/**
+ * Represents an event after step has been tested.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class AfterStepTested extends StepTested implements AfterTested
+{
+    /**
+     * @var FeatureNode
+     */
+    private $feature;
+    /**
+     * @var StepNode
+     */
+    private $step;
+    /**
+     * @var StepResult
+     */
+    private $result;
+    /**
+     * @var Teardown
+     */
+    private $teardown;
+
+    /**
+     * Initializes event.
+     *
+     * @param Environment $env
+     * @param FeatureNode $feature
+     * @param StepNode    $step
+     * @param StepResult  $result
+     * @param Teardown    $teardown
+     */
+    public function __construct(
+        Environment $env,
+        FeatureNode $feature,
+        StepNode $step,
+        StepResult $result,
+        Teardown $teardown
+    ) {
+        parent::__construct($env);
+
+        $this->feature = $feature;
+        $this->step = $step;
+        $this->result = $result;
+        $this->teardown = $teardown;
+    }
+
+    /**
+     * Returns feature.
+     *
+     * @return FeatureNode
+     */
+    public function getFeature()
+    {
+        return $this->feature;
+    }
+
+    /**
+     * Returns step node.
+     *
+     * @return StepNode
+     */
+    public function getStep()
+    {
+        return $this->step;
+    }
+
+    /**
+     * Returns current test result.
+     *
+     * @return TestResult
+     */
+    public function getTestResult()
+    {
+        return $this->result;
+    }
+
+    /**
+     * Returns current test teardown.
+     *
+     * @return Teardown
+     */
+    public function getTeardown()
+    {
+        return $this->teardown;
+    }
+
+    /**
+     * Checks if step call, setup or teardown produced any output (stdOut or exception).
+     *
+     * @return Boolean
+     */
+    public function hasOutput()
+    {
+        return $this->teardownHasOutput() || $this->resultHasException() || $this->resultCallHasOutput();
+    }
+
+    /**
+     * Checks if step teardown has output.
+     *
+     * @return Boolean
+     */
+    private function teardownHasOutput()
+    {
+        return $this->teardown->hasOutput();
+    }
+
+    /**
+     * Checks if result has produced exception.
+     *
+     * @return Boolean
+     */
+    private function resultHasException()
+    {
+        return $this->result instanceof ExceptionResult && $this->result->getException();
+    }
+
+    /**
+     * Checks if result is executed and call result has produced exception or stdOut.
+     *
+     * @return Boolean
+     */
+    private function resultCallHasOutput()
+    {
+        if (!$this->result instanceof ExecutedStepResult) {
+            return false;
+        }
+
+        return $this->result->getCallResult()->hasStdOut() || $this->result->getCallResult()->hasException();
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/BackgroundTested.php b/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/BackgroundTested.php
new file mode 100644 (file)
index 0000000..f67f855
--- /dev/null
@@ -0,0 +1,45 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\EventDispatcher\Event;
+
+use Behat\Gherkin\Node\BackgroundNode;
+use Behat\Gherkin\Node\NodeInterface;
+use Behat\Testwork\EventDispatcher\Event\LifecycleEvent;
+
+/**
+ * Represents a background event.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+abstract class BackgroundTested extends LifecycleEvent implements ScenarioLikeTested
+{
+    const BEFORE = 'tester.background_tested.before';
+    const AFTER_SETUP = 'tester.background_tested.after_setup';
+    const BEFORE_TEARDOWN = 'tester.background_tested.before_teardown';
+    const AFTER = 'tester.background_tested.after';
+
+    /**
+     * Returns background node.
+     *
+     * @return BackgroundNode
+     */
+    abstract public function getBackground();
+
+    /**
+     * Returns node.
+     *
+     * @return NodeInterface
+     */
+    final public function getNode()
+    {
+        return $this->getBackground();
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/BeforeBackgroundTeardown.php b/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/BeforeBackgroundTeardown.php
new file mode 100644 (file)
index 0000000..b416717
--- /dev/null
@@ -0,0 +1,100 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\EventDispatcher\Event;
+
+use Behat\Gherkin\Node\BackgroundNode;
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\ScenarioInterface;
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\EventDispatcher\Event\BeforeTeardown;
+use Behat\Testwork\Tester\Result\TestResult;
+
+/**
+ * Represents an event right before background teardown.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class BeforeBackgroundTeardown extends BackgroundTested implements BeforeTeardown
+{
+    /**
+     * @var FeatureNode
+     */
+    private $feature;
+    /**
+     * @var BackgroundNode
+     */
+    private $background;
+    /**
+     * @var TestResult
+     */
+    private $result;
+
+    /**
+     * Initializes event.
+     *
+     * @param Environment    $env
+     * @param FeatureNode    $feature
+     * @param BackgroundNode $background
+     * @param TestResult     $result
+     */
+    public function __construct(
+        Environment $env,
+        FeatureNode $feature,
+        BackgroundNode $background,
+        TestResult $result
+    ) {
+        parent::__construct($env);
+
+        $this->feature = $feature;
+        $this->background = $background;
+        $this->result = $result;
+    }
+
+    /**
+     * Returns feature.
+     *
+     * @return FeatureNode
+     */
+    public function getFeature()
+    {
+        return $this->feature;
+    }
+
+    /**
+     * Returns scenario node.
+     *
+     * @return ScenarioInterface
+     */
+    public function getScenario()
+    {
+        return $this->background;
+    }
+
+    /**
+     * Returns background node.
+     *
+     * @return BackgroundNode
+     */
+    public function getBackground()
+    {
+        return $this->background;
+    }
+
+    /**
+     * Returns current test result.
+     *
+     * @return TestResult
+     */
+    public function getTestResult()
+    {
+        return $this->result;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/BeforeBackgroundTested.php b/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/BeforeBackgroundTested.php
new file mode 100644 (file)
index 0000000..d88a6f9
--- /dev/null
@@ -0,0 +1,79 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\EventDispatcher\Event;
+
+use Behat\Gherkin\Node\BackgroundNode;
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\ScenarioInterface;
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\EventDispatcher\Event\BeforeTested;
+
+/**
+ * Represents a BeforeBackgroundTested event.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class BeforeBackgroundTested extends BackgroundTested implements BeforeTested
+{
+    /**
+     * @var FeatureNode
+     */
+    private $feature;
+    /**
+     * @var BackgroundNode
+     */
+    private $background;
+
+    /**
+     * Initializes event.
+     *
+     * @param Environment    $env
+     * @param FeatureNode    $feature
+     * @param BackgroundNode $background
+     */
+    public function __construct(Environment $env, FeatureNode $feature, BackgroundNode $background)
+    {
+        parent::__construct($env);
+
+        $this->feature = $feature;
+        $this->background = $background;
+    }
+
+    /**
+     * Returns feature.
+     *
+     * @return FeatureNode
+     */
+    public function getFeature()
+    {
+        return $this->feature;
+    }
+
+    /**
+     * Returns scenario node.
+     *
+     * @return ScenarioInterface
+     */
+    public function getScenario()
+    {
+        return $this->background;
+    }
+
+    /**
+     * Returns background node.
+     *
+     * @return BackgroundNode
+     */
+    public function getBackground()
+    {
+        return $this->background;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/BeforeFeatureTeardown.php b/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/BeforeFeatureTeardown.php
new file mode 100644 (file)
index 0000000..82c9c7b
--- /dev/null
@@ -0,0 +1,68 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\EventDispatcher\Event;
+
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\EventDispatcher\Event\BeforeTeardown;
+use Behat\Testwork\Tester\Result\TestResult;
+
+/**
+ * Represents an event right before feature is teardown.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class BeforeFeatureTeardown extends FeatureTested implements BeforeTeardown
+{
+    /**
+     * @var FeatureNode
+     */
+    private $feature;
+    /**
+     * @var TestResult
+     */
+    private $result;
+
+    /**
+     * Initializes event.
+     *
+     * @param Environment $env
+     * @param FeatureNode $feature
+     * @param TestResult  $result
+     */
+    public function __construct(Environment $env, FeatureNode $feature, TestResult $result)
+    {
+        parent::__construct($env);
+
+        $this->feature = $feature;
+        $this->result = $result;
+    }
+
+    /**
+     * Returns feature.
+     *
+     * @return FeatureNode
+     */
+    public function getFeature()
+    {
+        return $this->feature;
+    }
+
+    /**
+     * Returns current test result.
+     *
+     * @return TestResult
+     */
+    public function getTestResult()
+    {
+        return $this->result;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/BeforeFeatureTested.php b/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/BeforeFeatureTested.php
new file mode 100644 (file)
index 0000000..1f2f4ea
--- /dev/null
@@ -0,0 +1,51 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\EventDispatcher\Event;
+
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\EventDispatcher\Event\BeforeTested;
+
+/**
+ * Represents an event before feature tested.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class BeforeFeatureTested extends FeatureTested implements BeforeTested
+{
+    /**
+     * @var FeatureNode
+     */
+    private $feature;
+
+    /**
+     * Initializes event.
+     *
+     * @param Environment $env
+     * @param FeatureNode $feature
+     */
+    public function __construct(Environment $env, FeatureNode $feature)
+    {
+        parent::__construct($env);
+
+        $this->feature = $feature;
+    }
+
+    /**
+     * Returns feature.
+     *
+     * @return FeatureNode
+     */
+    public function getFeature()
+    {
+        return $this->feature;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/BeforeOutlineTeardown.php b/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/BeforeOutlineTeardown.php
new file mode 100644 (file)
index 0000000..7980267
--- /dev/null
@@ -0,0 +1,89 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\EventDispatcher\Event;
+
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\OutlineNode;
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\EventDispatcher\Event\BeforeTeardown;
+use Behat\Testwork\Tester\Result\TestResult;
+
+/**
+ * Represents an event right before outline teardown.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class BeforeOutlineTeardown extends OutlineTested implements BeforeTeardown
+{
+    /**
+     * @var FeatureNode
+     */
+    private $feature;
+    /**
+     * @var OutlineNode
+     */
+    private $outline;
+    /**
+     * @var TestResult
+     */
+    private $result;
+
+    /**
+     * Initializes event.
+     *
+     * @param Environment $env
+     * @param FeatureNode $feature
+     * @param OutlineNode $outline
+     * @param TestResult  $result
+     */
+    public function __construct(
+        Environment $env,
+        FeatureNode $feature,
+        OutlineNode $outline,
+        TestResult $result
+    ) {
+        parent::__construct($env);
+
+        $this->feature = $feature;
+        $this->outline = $outline;
+        $this->result = $result;
+    }
+
+    /**
+     * Returns feature.
+     *
+     * @return FeatureNode
+     */
+    public function getFeature()
+    {
+        return $this->feature;
+    }
+
+    /**
+     * Returns outline node.
+     *
+     * @return OutlineNode
+     */
+    public function getOutline()
+    {
+        return $this->outline;
+    }
+
+    /**
+     * Returns current test result.
+     *
+     * @return TestResult
+     */
+    public function getTestResult()
+    {
+        return $this->result;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/BeforeOutlineTested.php b/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/BeforeOutlineTested.php
new file mode 100644 (file)
index 0000000..25aa4fd
--- /dev/null
@@ -0,0 +1,68 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\EventDispatcher\Event;
+
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\OutlineNode;
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\EventDispatcher\Event\BeforeTested;
+
+/**
+ * Represents an event before outline is tested.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class BeforeOutlineTested extends OutlineTested implements BeforeTested
+{
+    /**
+     * @var FeatureNode
+     */
+    private $feature;
+    /**
+     * @var OutlineNode
+     */
+    private $outline;
+
+    /**
+     * Initializes event.
+     *
+     * @param Environment $env
+     * @param FeatureNode $feature
+     * @param OutlineNode $outline
+     */
+    public function __construct(Environment $env, FeatureNode $feature, OutlineNode $outline)
+    {
+        parent::__construct($env);
+
+        $this->feature = $feature;
+        $this->outline = $outline;
+    }
+
+    /**
+     * Returns feature.
+     *
+     * @return FeatureNode
+     */
+    public function getFeature()
+    {
+        return $this->feature;
+    }
+
+    /**
+     * Returns outline node.
+     *
+     * @return OutlineNode
+     */
+    public function getOutline()
+    {
+        return $this->outline;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/BeforeScenarioTeardown.php b/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/BeforeScenarioTeardown.php
new file mode 100644 (file)
index 0000000..da413b4
--- /dev/null
@@ -0,0 +1,90 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\EventDispatcher\Event;
+
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\ScenarioLikeInterface as Scenario;
+use Behat\Gherkin\Node\ScenarioNode;
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\EventDispatcher\Event\BeforeTeardown;
+use Behat\Testwork\Tester\Result\TestResult;
+
+/**
+ * Represents an event before scenario teardown.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class BeforeScenarioTeardown extends ScenarioTested implements BeforeTeardown
+{
+    /**
+     * @var FeatureNode
+     */
+    private $feature;
+    /**
+     * @var Scenario
+     */
+    private $scenario;
+    /**
+     * @var TestResult
+     */
+    private $result;
+
+    /**
+     * Initializes event
+     *
+     * @param Environment $env
+     * @param FeatureNode $feature
+     * @param Scenario    $scenario
+     * @param TestResult  $result
+     */
+    public function __construct(
+        Environment $env,
+        FeatureNode $feature,
+        Scenario $scenario,
+        TestResult $result
+    ) {
+        parent::__construct($env);
+
+        $this->feature = $feature;
+        $this->scenario = $scenario;
+        $this->result = $result;
+    }
+
+    /**
+     * Returns feature.
+     *
+     * @return FeatureNode
+     */
+    public function getFeature()
+    {
+        return $this->feature;
+    }
+
+    /**
+     * Returns scenario node.
+     *
+     * @return ScenarioNode
+     */
+    public function getScenario()
+    {
+        return $this->scenario;
+    }
+
+    /**
+     * Returns current test result.
+     *
+     * @return TestResult
+     */
+    public function getTestResult()
+    {
+        return $this->result;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/BeforeScenarioTested.php b/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/BeforeScenarioTested.php
new file mode 100644 (file)
index 0000000..d2737b8
--- /dev/null
@@ -0,0 +1,69 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\EventDispatcher\Event;
+
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\ScenarioLikeInterface as Scenario;
+use Behat\Gherkin\Node\ScenarioNode;
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\EventDispatcher\Event\BeforeTested;
+
+/**
+ * Represents an event before scenario is tested.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class BeforeScenarioTested extends ScenarioTested implements BeforeTested
+{
+    /**
+     * @var FeatureNode
+     */
+    private $feature;
+    /**
+     * @var Scenario
+     */
+    private $scenario;
+
+    /**
+     * Initializes event
+     *
+     * @param Environment $env
+     * @param FeatureNode $feature
+     * @param Scenario    $scenario
+     */
+    public function __construct(Environment $env, FeatureNode $feature, Scenario $scenario)
+    {
+        parent::__construct($env);
+
+        $this->feature = $feature;
+        $this->scenario = $scenario;
+    }
+
+    /**
+     * Returns feature.
+     *
+     * @return FeatureNode
+     */
+    public function getFeature()
+    {
+        return $this->feature;
+    }
+
+    /**
+     * Returns scenario node.
+     *
+     * @return ScenarioNode
+     */
+    public function getScenario()
+    {
+        return $this->scenario;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/BeforeStepTeardown.php b/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/BeforeStepTeardown.php
new file mode 100644 (file)
index 0000000..6d9b9c6
--- /dev/null
@@ -0,0 +1,126 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\EventDispatcher\Event;
+
+use Behat\Behat\Tester\Result\ExecutedStepResult;
+use Behat\Behat\Tester\Result\StepResult;
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\StepNode;
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\EventDispatcher\Event\BeforeTeardown;
+use Behat\Testwork\Tester\Result\ExceptionResult;
+use Behat\Testwork\Tester\Result\TestResult;
+
+/**
+ * Represents an event before step teardown.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class BeforeStepTeardown extends StepTested implements BeforeTeardown
+{
+    /**
+     * @var FeatureNode
+     */
+    private $feature;
+    /**
+     * @var StepNode
+     */
+    private $step;
+    /**
+     * @var StepResult
+     */
+    private $result;
+
+    /**
+     * Initializes event.
+     *
+     * @param Environment $env
+     * @param FeatureNode $feature
+     * @param StepNode    $step
+     * @param StepResult  $result
+     */
+    public function __construct(
+        Environment $env,
+        FeatureNode $feature,
+        StepNode $step,
+        StepResult $result
+    ) {
+        parent::__construct($env);
+
+        $this->feature = $feature;
+        $this->step = $step;
+        $this->result = $result;
+    }
+
+    /**
+     * Returns feature.
+     *
+     * @return FeatureNode
+     */
+    public function getFeature()
+    {
+        return $this->feature;
+    }
+
+    /**
+     * Returns step node.
+     *
+     * @return StepNode
+     */
+    public function getStep()
+    {
+        return $this->step;
+    }
+
+    /**
+     * Returns current test result.
+     *
+     * @return TestResult
+     */
+    public function getTestResult()
+    {
+        return $this->result;
+    }
+
+    /**
+     * Checks if step call produced any output (stdOut or exception).
+     *
+     * @return Boolean
+     */
+    public function hasOutput()
+    {
+        return $this->resultHasException() || $this->resultCallHasOutput();
+    }
+
+    /**
+     * Checks if result has produced exception.
+     *
+     * @return Boolean
+     */
+    private function resultHasException()
+    {
+        return $this->result instanceof ExceptionResult && $this->result->getException();
+    }
+
+    /**
+     * Checks if result is executed and call result has produced exception or stdOut.
+     *
+     * @return Boolean
+     */
+    private function resultCallHasOutput()
+    {
+        if (!$this->result instanceof ExecutedStepResult) {
+            return false;
+        }
+
+        return $this->result->getCallResult()->hasStdOut() || $this->result->getCallResult()->hasException();
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/BeforeStepTested.php b/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/BeforeStepTested.php
new file mode 100644 (file)
index 0000000..22b1e09
--- /dev/null
@@ -0,0 +1,68 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\EventDispatcher\Event;
+
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\StepNode;
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\EventDispatcher\Event\BeforeTested;
+
+/**
+ * Represents an event before step test.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class BeforeStepTested extends StepTested implements BeforeTested
+{
+    /**
+     * @var FeatureNode
+     */
+    private $feature;
+    /**
+     * @var StepNode
+     */
+    private $step;
+
+    /**
+     * Initializes event.
+     *
+     * @param Environment $env
+     * @param FeatureNode $feature
+     * @param StepNode    $step
+     */
+    public function __construct(Environment $env, FeatureNode $feature, StepNode $step)
+    {
+        parent::__construct($env);
+
+        $this->feature = $feature;
+        $this->step = $step;
+    }
+
+    /**
+     * Returns feature.
+     *
+     * @return FeatureNode
+     */
+    public function getFeature()
+    {
+        return $this->feature;
+    }
+
+    /**
+     * Returns step node.
+     *
+     * @return StepNode
+     */
+    public function getStep()
+    {
+        return $this->step;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/ExampleTested.php b/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/ExampleTested.php
new file mode 100644 (file)
index 0000000..1bb1a42
--- /dev/null
@@ -0,0 +1,24 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\EventDispatcher\Event;
+
+/**
+ * Represents an example event.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface ExampleTested
+{
+    const BEFORE = 'tester.example_tested.before';
+    const AFTER_SETUP = 'tester.example_tested.after_setup';
+    const BEFORE_TEARDOWN = 'tester.example_tested.before_teardown';
+    const AFTER = 'tester.example_tested.after';
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/FeatureTested.php b/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/FeatureTested.php
new file mode 100644 (file)
index 0000000..f29c31c
--- /dev/null
@@ -0,0 +1,45 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\EventDispatcher\Event;
+
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\NodeInterface;
+use Behat\Testwork\EventDispatcher\Event\LifecycleEvent;
+
+/**
+ * Represents a feature event.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+abstract class FeatureTested extends LifecycleEvent implements GherkinNodeTested
+{
+    const BEFORE = 'tester.feature_tested.before';
+    const AFTER_SETUP = 'tester.feature_tested.after_setup';
+    const BEFORE_TEARDOWN = 'tester.feature_tested.before_teardown';
+    const AFTER = 'tester.feature_tested.after';
+
+    /**
+     * Returns feature.
+     *
+     * @return FeatureNode
+     */
+    abstract public function getFeature();
+
+    /**
+     * Returns node.
+     *
+     * @return NodeInterface
+     */
+    final public function getNode()
+    {
+        return $this->getFeature();
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/GherkinNodeTested.php b/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/GherkinNodeTested.php
new file mode 100644 (file)
index 0000000..3d1fe07
--- /dev/null
@@ -0,0 +1,28 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\EventDispatcher\Event;
+
+use Behat\Gherkin\Node\NodeInterface;
+
+/**
+ * Represents a Gherkin node based event.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface GherkinNodeTested
+{
+    /**
+     * Returns node.
+     *
+     * @return NodeInterface
+     */
+    public function getNode();
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/OutlineTested.php b/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/OutlineTested.php
new file mode 100644 (file)
index 0000000..149fc4f
--- /dev/null
@@ -0,0 +1,53 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\EventDispatcher\Event;
+
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\NodeInterface;
+use Behat\Gherkin\Node\OutlineNode;
+use Behat\Testwork\EventDispatcher\Event\LifecycleEvent;
+
+/**
+ * Represents an outline event.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+abstract class OutlineTested extends LifecycleEvent implements GherkinNodeTested
+{
+    const BEFORE = 'tester.outline_tested.before';
+    const AFTER_SETUP = 'tester.outline_tested.after_setup';
+    const BEFORE_TEARDOWN = 'tester.outline_tested.before_teardown';
+    const AFTER = 'tester.outline_tested.after';
+
+    /**
+     * Returns feature.
+     *
+     * @return FeatureNode
+     */
+    abstract public function getFeature();
+
+    /**
+     * Returns outline node.
+     *
+     * @return OutlineNode
+     */
+    abstract public function getOutline();
+
+    /**
+     * Returns node.
+     *
+     * @return NodeInterface
+     */
+    final public function getNode()
+    {
+        return $this->getOutline();
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/ScenarioLikeTested.php b/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/ScenarioLikeTested.php
new file mode 100644 (file)
index 0000000..bd74185
--- /dev/null
@@ -0,0 +1,36 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\EventDispatcher\Event;
+
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\ScenarioInterface;
+
+/**
+ * Represents an event of scenario-like structure (Scenario, Background, Example).
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface ScenarioLikeTested extends GherkinNodeTested
+{
+    /**
+     * Returns feature node.
+     *
+     * @return FeatureNode
+     */
+    public function getFeature();
+
+    /**
+     * Returns scenario node.
+     *
+     * @return ScenarioInterface
+     */
+    public function getScenario();
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/ScenarioTested.php b/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/ScenarioTested.php
new file mode 100644 (file)
index 0000000..2251b4a
--- /dev/null
@@ -0,0 +1,34 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\EventDispatcher\Event;
+
+use Behat\Testwork\EventDispatcher\Event\LifecycleEvent;
+
+/**
+ * Represents a scenario event.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+abstract class ScenarioTested extends LifecycleEvent implements ScenarioLikeTested
+{
+    const BEFORE = 'tester.scenario_tested.before';
+    const AFTER_SETUP = 'tester.scenario_tested.after_setup';
+    const BEFORE_TEARDOWN = 'tester.scenario_tested.before_teardown';
+    const AFTER = 'tester.scenario_tested.after';
+
+    /**
+     * {@inheritdoc}
+     */
+    final public function getNode()
+    {
+        return $this->getScenario();
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/StepTested.php b/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Event/StepTested.php
new file mode 100644 (file)
index 0000000..7053d0d
--- /dev/null
@@ -0,0 +1,50 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\EventDispatcher\Event;
+
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\StepNode;
+use Behat\Testwork\EventDispatcher\Event\LifecycleEvent;
+
+/**
+ * Represents a step event.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+abstract class StepTested extends LifecycleEvent implements GherkinNodeTested
+{
+    const BEFORE = 'tester.step_tested.before';
+    const AFTER_SETUP = 'tester.step_tested.after_setup';
+    const BEFORE_TEARDOWN = 'tester.step_tested.before_teardown';
+    const AFTER = 'tester.step_tested.after';
+
+    /**
+     * Returns feature.
+     *
+     * @return FeatureNode
+     */
+    abstract public function getFeature();
+
+    /**
+     * Returns step node.
+     *
+     * @return StepNode
+     */
+    abstract public function getStep();
+
+    /**
+     * {@inheritdoc}
+     */
+    final public function getNode()
+    {
+        return $this->getStep();
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/EventDispatcher/ServiceContainer/EventDispatcherExtension.php b/vendor/behat/behat/src/Behat/Behat/EventDispatcher/ServiceContainer/EventDispatcherExtension.php
new file mode 100644 (file)
index 0000000..252cd03
--- /dev/null
@@ -0,0 +1,175 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\EventDispatcher\ServiceContainer;
+
+use Behat\Behat\EventDispatcher\Event\ExampleTested;
+use Behat\Behat\EventDispatcher\Event\ScenarioTested;
+use Behat\Behat\Tester\ServiceContainer\TesterExtension;
+use Behat\Testwork\Cli\ServiceContainer\CliExtension;
+use Behat\Testwork\EventDispatcher\ServiceContainer\EventDispatcherExtension as BaseExtension;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Definition;
+use Symfony\Component\DependencyInjection\Reference;
+
+/**
+ * Extends Testwork EventDispatcherExtension with additional event-dispatching testers.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class EventDispatcherExtension extends BaseExtension
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function load(ContainerBuilder $container, array $config)
+    {
+        parent::load($container, $config);
+
+        $this->loadStopOnFailureController($container);
+        $this->loadEventDispatchingBackgroundTester($container);
+        $this->loadEventDispatchingFeatureTester($container);
+        $this->loadEventDispatchingOutlineTester($container);
+        $this->loadEventDispatchingScenarioTester($container);
+        $this->loadEventDispatchingExampleTester($container);
+        $this->loadEventDispatchingStepTester($container);
+        $this->loadTickingStepTester($container);
+    }
+
+    /**
+     * Loads stop on failure controller.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function loadStopOnFailureController(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Behat\EventDispatcher\Cli\StopOnFailureController', array(
+            new Reference(EventDispatcherExtension::DISPATCHER_ID)
+        ));
+        $definition->addTag(CliExtension::CONTROLLER_TAG, array('priority' => 100));
+        $container->setDefinition(CliExtension::CONTROLLER_TAG . '.stop_on_failure', $definition);
+    }
+
+    /**
+     * Loads event-dispatching background tester.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function loadEventDispatchingBackgroundTester(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Behat\EventDispatcher\Tester\EventDispatchingBackgroundTester', array(
+            new Reference(TesterExtension::BACKGROUND_TESTER_ID),
+            new Reference(self::DISPATCHER_ID)
+        ));
+        $definition->addTag(TesterExtension::BACKGROUND_TESTER_WRAPPER_TAG, array('priority' => -9999));
+        $container->setDefinition(TesterExtension::BACKGROUND_TESTER_WRAPPER_TAG . '.event_dispatching', $definition);
+    }
+
+    /**
+     * Loads event-dispatching feature tester.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function loadEventDispatchingFeatureTester(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Behat\EventDispatcher\Tester\EventDispatchingFeatureTester', array(
+            new Reference(TesterExtension::SPECIFICATION_TESTER_ID),
+            new Reference(self::DISPATCHER_ID)
+        ));
+        $definition->addTag(TesterExtension::SPECIFICATION_TESTER_WRAPPER_TAG, array('priority' => -9999));
+        $container->setDefinition(TesterExtension::SPECIFICATION_TESTER_WRAPPER_TAG . '.event_dispatching', $definition);
+    }
+
+    /**
+     * Loads event-dispatching outline tester.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function loadEventDispatchingOutlineTester(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Behat\EventDispatcher\Tester\EventDispatchingOutlineTester', array(
+            new Reference(TesterExtension::OUTLINE_TESTER_ID),
+            new Reference(self::DISPATCHER_ID)
+        ));
+        $definition->addTag(TesterExtension::OUTLINE_TESTER_WRAPPER_TAG, array('priority' => -9999));
+        $container->setDefinition(TesterExtension::OUTLINE_TESTER_WRAPPER_TAG . '.event_dispatching', $definition);
+    }
+
+    /**
+     * Loads event-dispatching scenario tester.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function loadEventDispatchingScenarioTester(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Behat\EventDispatcher\Tester\EventDispatchingScenarioTester', array(
+            new Reference(TesterExtension::SCENARIO_TESTER_ID),
+            new Reference(self::DISPATCHER_ID),
+            ScenarioTested::BEFORE,
+            ScenarioTested::AFTER_SETUP,
+            ScenarioTested::BEFORE_TEARDOWN,
+            ScenarioTested::AFTER
+        ));
+        $definition->addTag(TesterExtension::SCENARIO_TESTER_WRAPPER_TAG, array('priority' => -9999));
+        $container->setDefinition(TesterExtension::SCENARIO_TESTER_WRAPPER_TAG . '.event_dispatching', $definition);
+    }
+
+    /**
+     * Loads event-dispatching example tester.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function loadEventDispatchingExampleTester(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Behat\EventDispatcher\Tester\EventDispatchingScenarioTester', array(
+            new Reference(TesterExtension::EXAMPLE_TESTER_ID),
+            new Reference(self::DISPATCHER_ID),
+            ExampleTested::BEFORE,
+            ExampleTested::AFTER_SETUP,
+            ExampleTested::BEFORE_TEARDOWN,
+            ExampleTested::AFTER
+        ));
+        $definition->addTag(TesterExtension::EXAMPLE_TESTER_WRAPPER_TAG, array('priority' => -9999));
+        $container->setDefinition(TesterExtension::EXAMPLE_TESTER_WRAPPER_TAG . '.event_dispatching', $definition);
+    }
+
+    /**
+     * Loads event-dispatching step tester.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function loadEventDispatchingStepTester(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Behat\EventDispatcher\Tester\EventDispatchingStepTester', array(
+            new Reference(TesterExtension::STEP_TESTER_ID),
+            new Reference(self::DISPATCHER_ID)
+        ));
+        $definition->addTag(TesterExtension::STEP_TESTER_WRAPPER_TAG, array('priority' => -9999));
+        $container->setDefinition(TesterExtension::STEP_TESTER_WRAPPER_TAG . '.event_dispatching', $definition);
+    }
+
+    /**
+     * Loads ticking step tester.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function loadTickingStepTester(ContainerBuilder $container)
+    {
+        if (!function_exists('pcntl_signal')) {
+            return;
+        }
+
+        $definition = new Definition('Behat\Behat\EventDispatcher\Tester\TickingStepTester', array(
+            new Reference(TesterExtension::STEP_TESTER_ID)
+        ));
+        $definition->addTag(TesterExtension::STEP_TESTER_WRAPPER_TAG, array('priority' => 9999));
+        $container->setDefinition(TesterExtension::STEP_TESTER_WRAPPER_TAG . '.ticking', $definition);
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Tester/EventDispatchingBackgroundTester.php b/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Tester/EventDispatchingBackgroundTester.php
new file mode 100644 (file)
index 0000000..d947df5
--- /dev/null
@@ -0,0 +1,91 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\EventDispatcher\Tester;
+
+use Behat\Behat\EventDispatcher\Event\AfterBackgroundSetup;
+use Behat\Behat\EventDispatcher\Event\AfterBackgroundTested;
+use Behat\Behat\EventDispatcher\Event\BackgroundTested;
+use Behat\Behat\EventDispatcher\Event\BeforeBackgroundTeardown;
+use Behat\Behat\EventDispatcher\Event\BeforeBackgroundTested;
+use Behat\Behat\Tester\BackgroundTester;
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\Tester\Result\TestResult;
+use Symfony\Component\EventDispatcher\EventDispatcherInterface;
+
+/**
+ * Background tester dispatching BEFORE/AFTER events.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class EventDispatchingBackgroundTester implements BackgroundTester
+{
+    /**
+     * @var BackgroundTester
+     */
+    private $baseTester;
+    /**
+     * @var EventDispatcherInterface
+     */
+    private $eventDispatcher;
+
+    /**
+     * Initializes tester.
+     *
+     * @param BackgroundTester         $baseTester
+     * @param EventDispatcherInterface $eventDispatcher
+     */
+    public function __construct(BackgroundTester $baseTester, EventDispatcherInterface $eventDispatcher)
+    {
+        $this->baseTester = $baseTester;
+        $this->eventDispatcher = $eventDispatcher;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setUp(Environment $env, FeatureNode $feature, $skip)
+    {
+        $event = new BeforeBackgroundTested($env, $feature, $feature->getBackground());
+        $this->eventDispatcher->dispatch($event::BEFORE, $event);
+
+        $setup = $this->baseTester->setUp($env, $feature, $skip);
+
+        $event = new AfterBackgroundSetup($env, $feature, $feature->getBackground(), $setup);
+        $this->eventDispatcher->dispatch($event::AFTER_SETUP, $event);
+
+        return $setup;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function test(Environment $env, FeatureNode $feature, $skip)
+    {
+        return $this->baseTester->test($env, $feature, $skip);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function tearDown(Environment $env, FeatureNode $feature, $skip, TestResult $result)
+    {
+        $event = new BeforeBackgroundTeardown($env, $feature, $feature->getBackground(), $result);
+        $this->eventDispatcher->dispatch(BackgroundTested::BEFORE_TEARDOWN, $event);
+
+        $teardown = $this->baseTester->tearDown($env, $feature, $skip, $result);
+
+        $event = new AfterBackgroundTested($env, $feature, $feature->getBackground(), $result, $teardown);
+        $this->eventDispatcher->dispatch(BackgroundTested::AFTER, $event);
+
+        return $teardown;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Tester/EventDispatchingFeatureTester.php b/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Tester/EventDispatchingFeatureTester.php
new file mode 100644 (file)
index 0000000..2bd0ad5
--- /dev/null
@@ -0,0 +1,89 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\EventDispatcher\Tester;
+
+use Behat\Behat\EventDispatcher\Event\AfterFeatureSetup;
+use Behat\Behat\EventDispatcher\Event\AfterFeatureTested;
+use Behat\Behat\EventDispatcher\Event\BeforeFeatureTeardown;
+use Behat\Behat\EventDispatcher\Event\BeforeFeatureTested;
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\Tester\Result\TestResult;
+use Behat\Testwork\Tester\SpecificationTester;
+use Symfony\Component\EventDispatcher\EventDispatcherInterface;
+
+/**
+ * Feature tester dispatching BEFORE/AFTER events during tests.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class EventDispatchingFeatureTester implements SpecificationTester
+{
+    /**
+     * @var SpecificationTester
+     */
+    private $baseTester;
+    /**
+     * @var EventDispatcherInterface
+     */
+    private $eventDispatcher;
+
+    /**
+     * Initializes tester.
+     *
+     * @param SpecificationTester      $baseTester
+     * @param EventDispatcherInterface $eventDispatcher
+     */
+    public function __construct(SpecificationTester $baseTester, EventDispatcherInterface $eventDispatcher)
+    {
+        $this->baseTester = $baseTester;
+        $this->eventDispatcher = $eventDispatcher;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setUp(Environment $env, $feature, $skip)
+    {
+        $event = new BeforeFeatureTested($env, $feature);
+        $this->eventDispatcher->dispatch($event::BEFORE, $event);
+
+        $setup = $this->baseTester->setUp($env, $feature, $skip);
+
+        $event = new AfterFeatureSetup($env, $feature, $setup);
+        $this->eventDispatcher->dispatch($event::AFTER_SETUP, $event);
+
+        return $setup;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function test(Environment $env, $feature, $skip)
+    {
+        return $this->baseTester->test($env, $feature, $skip);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function tearDown(Environment $env, $feature, $skip, TestResult $result)
+    {
+        $event = new BeforeFeatureTeardown($env, $feature, $result);
+        $this->eventDispatcher->dispatch($event::BEFORE_TEARDOWN, $event);
+
+        $teardown = $this->baseTester->tearDown($env, $feature, $skip, $result);
+
+        $event = new AfterFeatureTested($env, $feature, $result, $teardown);
+        $this->eventDispatcher->dispatch($event::AFTER, $event);
+
+        return $teardown;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Tester/EventDispatchingOutlineTester.php b/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Tester/EventDispatchingOutlineTester.php
new file mode 100644 (file)
index 0000000..13d257c
--- /dev/null
@@ -0,0 +1,91 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\EventDispatcher\Tester;
+
+use Behat\Behat\EventDispatcher\Event\AfterOutlineSetup;
+use Behat\Behat\EventDispatcher\Event\AfterOutlineTested;
+use Behat\Behat\EventDispatcher\Event\BeforeOutlineTeardown;
+use Behat\Behat\EventDispatcher\Event\BeforeOutlineTested;
+use Behat\Behat\Tester\OutlineTester;
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\OutlineNode;
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\Tester\Result\TestResult;
+use Symfony\Component\EventDispatcher\EventDispatcherInterface;
+
+/**
+ * Outline tester dispatching BEFORE/AFTER events during tests.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class EventDispatchingOutlineTester implements OutlineTester
+{
+    /**
+     * @var OutlineTester
+     */
+    private $baseTester;
+    /**
+     * @var EventDispatcherInterface
+     */
+    private $eventDispatcher;
+
+    /**
+     * Initializes tester.
+     *
+     * @param OutlineTester            $baseTester
+     * @param EventDispatcherInterface $eventDispatcher
+     */
+    public function __construct(OutlineTester $baseTester, EventDispatcherInterface $eventDispatcher)
+    {
+        $this->baseTester = $baseTester;
+        $this->eventDispatcher = $eventDispatcher;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setUp(Environment $env, FeatureNode $feature, OutlineNode $outline, $skip)
+    {
+        $event = new BeforeOutlineTested($env, $feature, $outline);
+        $this->eventDispatcher->dispatch($event::BEFORE, $event);
+
+        $setup = $this->baseTester->setUp($env, $feature, $outline, $skip);
+
+        $event = new AfterOutlineSetup($env, $feature, $outline, $setup);
+        $this->eventDispatcher->dispatch($event::AFTER_SETUP, $event);
+
+        return $setup;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function test(Environment $env, FeatureNode $feature, OutlineNode $outline, $skip)
+    {
+        return $this->baseTester->test($env, $feature, $outline, $skip);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function tearDown(Environment $env, FeatureNode $feature, OutlineNode $outline, $skip, TestResult $result)
+    {
+        $event = new BeforeOutlineTeardown($env, $feature, $outline, $result);
+        $this->eventDispatcher->dispatch($event::BEFORE_TEARDOWN, $event);
+
+        $teardown = $this->baseTester->tearDown($env, $feature, $outline, $skip, $result);
+
+        $event = new AfterOutlineTested($env, $feature, $outline, $result, $teardown);
+        $this->eventDispatcher->dispatch($event::AFTER, $event);
+
+        return $teardown;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Tester/EventDispatchingScenarioTester.php b/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Tester/EventDispatchingScenarioTester.php
new file mode 100644 (file)
index 0000000..44eb131
--- /dev/null
@@ -0,0 +1,121 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\EventDispatcher\Tester;
+
+use Behat\Behat\EventDispatcher\Event\AfterScenarioSetup;
+use Behat\Behat\EventDispatcher\Event\AfterScenarioTested;
+use Behat\Behat\EventDispatcher\Event\BeforeScenarioTeardown;
+use Behat\Behat\EventDispatcher\Event\BeforeScenarioTested;
+use Behat\Behat\Tester\ScenarioTester;
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\ScenarioInterface as Scenario;
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\Tester\Result\TestResult;
+use Symfony\Component\EventDispatcher\EventDispatcherInterface;
+
+/**
+ * Scenario tester dispatching BEFORE/AFTER events during tests.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class EventDispatchingScenarioTester implements ScenarioTester
+{
+    /**
+     * @var ScenarioTester
+     */
+    private $baseTester;
+    /**
+     * @var EventDispatcherInterface
+     */
+    private $eventDispatcher;
+    /**
+     * @var string
+     */
+    private $beforeEventName;
+    /**
+     * @var string
+     */
+    private $afterSetupEventName;
+    /**
+     * @var string
+     */
+    private $beforeTeardownEventName;
+    /**
+     * @var string
+     */
+    private $afterEventName;
+
+    /**
+     * Initializes tester.
+     *
+     * @param ScenarioTester           $baseTester
+     * @param EventDispatcherInterface $eventDispatcher
+     * @param string                   $beforeEventName
+     * @param string                   $afterSetupEventName
+     * @param string                   $beforeTeardownEventName
+     * @param string                   $afterEventName
+     */
+    public function __construct(
+        ScenarioTester $baseTester,
+        EventDispatcherInterface $eventDispatcher,
+        $beforeEventName,
+        $afterSetupEventName,
+        $beforeTeardownEventName,
+        $afterEventName
+    ) {
+        $this->baseTester = $baseTester;
+        $this->eventDispatcher = $eventDispatcher;
+        $this->beforeEventName = $beforeEventName;
+        $this->afterSetupEventName = $afterSetupEventName;
+        $this->beforeTeardownEventName = $beforeTeardownEventName;
+        $this->afterEventName = $afterEventName;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setUp(Environment $env, FeatureNode $feature, Scenario $scenario, $skip)
+    {
+        $event = new BeforeScenarioTested($env, $feature, $scenario);
+        $this->eventDispatcher->dispatch($this->beforeEventName, $event);
+
+        $setup = $this->baseTester->setUp($env, $feature, $scenario, $skip);
+
+        $event = new AfterScenarioSetup($env, $feature, $scenario, $setup);
+        $this->eventDispatcher->dispatch($this->afterSetupEventName, $event);
+
+        return $setup;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function test(Environment $env, FeatureNode $feature, Scenario $scenario, $skip)
+    {
+        return $this->baseTester->test($env, $feature, $scenario, $skip);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function tearDown(Environment $env, FeatureNode $feature, Scenario $scenario, $skip, TestResult $result)
+    {
+        $event = new BeforeScenarioTeardown($env, $feature, $scenario, $result);
+        $this->eventDispatcher->dispatch($this->beforeTeardownEventName, $event);
+
+        $teardown = $this->baseTester->tearDown($env, $feature, $scenario, $skip, $result);
+
+        $event = new AfterScenarioTested($env, $feature, $scenario, $result, $teardown);
+        $this->eventDispatcher->dispatch($this->afterEventName, $event);
+
+        return $teardown;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Tester/EventDispatchingStepTester.php b/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Tester/EventDispatchingStepTester.php
new file mode 100644 (file)
index 0000000..6bf3c46
--- /dev/null
@@ -0,0 +1,91 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\EventDispatcher\Tester;
+
+use Behat\Behat\EventDispatcher\Event\AfterStepSetup;
+use Behat\Behat\EventDispatcher\Event\AfterStepTested;
+use Behat\Behat\EventDispatcher\Event\BeforeStepTeardown;
+use Behat\Behat\EventDispatcher\Event\BeforeStepTested;
+use Behat\Behat\Tester\Result\StepResult;
+use Behat\Behat\Tester\StepTester;
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\StepNode;
+use Behat\Testwork\Environment\Environment;
+use Symfony\Component\EventDispatcher\EventDispatcherInterface;
+
+/**
+ * Step tester dispatching BEFORE/AFTER events during tests.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class EventDispatchingStepTester implements StepTester
+{
+    /**
+     * @var StepTester
+     */
+    private $baseTester;
+    /**
+     * @var EventDispatcherInterface
+     */
+    private $eventDispatcher;
+
+    /**
+     * Initializes tester.
+     *
+     * @param StepTester               $baseTester
+     * @param EventDispatcherInterface $eventDispatcher
+     */
+    public function __construct(StepTester $baseTester, EventDispatcherInterface $eventDispatcher)
+    {
+        $this->baseTester = $baseTester;
+        $this->eventDispatcher = $eventDispatcher;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setUp(Environment $env, FeatureNode $feature, StepNode $step, $skip)
+    {
+        $event = new BeforeStepTested($env, $feature, $step);
+        $this->eventDispatcher->dispatch($event::BEFORE, $event);
+
+        $setup = $this->baseTester->setUp($env, $feature, $step, $skip);
+
+        $event = new AfterStepSetup($env, $feature, $step, $setup);
+        $this->eventDispatcher->dispatch($event::AFTER_SETUP, $event);
+
+        return $setup;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function test(Environment $env, FeatureNode $feature, StepNode $step, $skip)
+    {
+        return $this->baseTester->test($env, $feature, $step, $skip);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function tearDown(Environment $env, FeatureNode $feature, StepNode $step, $skip, StepResult $result)
+    {
+        $event = new BeforeStepTeardown($env, $feature, $step, $result);
+        $this->eventDispatcher->dispatch($event::BEFORE_TEARDOWN, $event);
+
+        $teardown = $this->baseTester->tearDown($env, $feature, $step, $skip, $result);
+
+        $event = new AfterStepTested($env, $feature, $step, $result, $teardown);
+        $this->eventDispatcher->dispatch($event::AFTER, $event);
+
+        return $teardown;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Tester/TickingStepTester.php b/vendor/behat/behat/src/Behat/Behat/EventDispatcher/Tester/TickingStepTester.php
new file mode 100644 (file)
index 0000000..4017254
--- /dev/null
@@ -0,0 +1,69 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\EventDispatcher\Tester;
+
+use Behat\Behat\Tester\Result\StepResult;
+use Behat\Behat\Tester\StepTester;
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\StepNode;
+use Behat\Testwork\Environment\Environment;
+
+/**
+ * Enable ticks during step testing to allow SigintController in Testwork
+ * to handle an interupt (on PHP7)
+ *
+ * @see Behat\Testwork\EventDispatcher\Cli\SigintController
+ *
+ * @author Peter Mitchell <peterjmit@gmail.com>
+ */
+final class TickingStepTester implements StepTester
+{
+    /**
+     * @var StepTester
+     */
+    private $baseTester;
+
+    /**
+     * Initializes tester.
+     *
+     * @param StepTester  $baseTester
+     */
+    public function __construct(StepTester $baseTester)
+    {
+        $this->baseTester = $baseTester;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setUp(Environment $env, FeatureNode $feature, StepNode $step, $skip)
+    {
+        return $this->baseTester->setUp($env, $feature, $step, $skip);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function test(Environment $env, FeatureNode $feature, StepNode $step, $skip)
+    {
+        declare(ticks = 1);
+
+        return $this->baseTester->test($env, $feature, $step, $skip);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function tearDown(Environment $env, FeatureNode $feature, StepNode $step, $skip, StepResult $result)
+    {
+        return $this->baseTester->tearDown($env, $feature, $step, $skip, $result);
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Gherkin/Cli/FilterController.php b/vendor/behat/behat/src/Behat/Behat/Gherkin/Cli/FilterController.php
new file mode 100644 (file)
index 0000000..7f13989
--- /dev/null
@@ -0,0 +1,98 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Gherkin\Cli;
+
+use Behat\Gherkin\Filter\NameFilter;
+use Behat\Gherkin\Filter\RoleFilter;
+use Behat\Gherkin\Filter\TagFilter;
+use Behat\Gherkin\Gherkin;
+use Behat\Testwork\Cli\Controller;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * Configures default Gherkin filters.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class FilterController implements Controller
+{
+    /**
+     * @var Gherkin
+     */
+    private $gherkin;
+
+    /**
+     * Initializes controller.
+     *
+     * @param Gherkin $gherkin
+     */
+    public function __construct(Gherkin $gherkin)
+    {
+        $this->gherkin = $gherkin;
+    }
+
+    /**
+     * Configures command to be executable by the controller.
+     *
+     * @param Command $command
+     */
+    public function configure(Command $command)
+    {
+        $command
+            ->addOption(
+                '--name', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
+                "Only executeCall the feature elements which match part" . PHP_EOL .
+                "of the given name or regex."
+            )
+            ->addOption(
+                '--tags', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
+                "Only executeCall the features or scenarios with tags" . PHP_EOL .
+                "matching tag filter expression."
+            )
+            ->addOption(
+                '--role', null, InputOption::VALUE_REQUIRED,
+                "Only executeCall the features with actor role matching" . PHP_EOL .
+                "a wildcard."
+            );
+    }
+
+    /**
+     * Executes controller.
+     *
+     * @param InputInterface  $input
+     * @param OutputInterface $output
+     *
+     * @return null|integer
+     */
+    public function execute(InputInterface $input, OutputInterface $output)
+    {
+        $filters = array();
+
+        foreach ($input->getOption('name') as $name) {
+            $filters[] = new NameFilter($name);
+        }
+
+        foreach ($input->getOption('tags') as $tags) {
+            $filters[] = new TagFilter($tags);
+        }
+
+        if ($role = $input->getOption('role')) {
+            $filters[] = new RoleFilter($role);
+        }
+
+        if (count($filters)) {
+            $this->gherkin->setFilters($filters);
+        }
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Gherkin/Cli/SyntaxController.php b/vendor/behat/behat/src/Behat/Behat/Gherkin/Cli/SyntaxController.php
new file mode 100644 (file)
index 0000000..a3e3f6c
--- /dev/null
@@ -0,0 +1,108 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Gherkin\Cli;
+
+use Behat\Gherkin\Keywords\KeywordsDumper;
+use Behat\Testwork\Cli\Controller;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Formatter\OutputFormatterStyle;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Translation\TranslatorInterface;
+
+/**
+ * Prints example of the feature to present all available syntax keywords.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class SyntaxController implements Controller
+{
+    /**
+     * @var KeywordsDumper
+     */
+    private $keywordsDumper;
+    /**
+     * @var TranslatorInterface
+     */
+    private $translator;
+
+    /**
+     * Initializes controller.
+     *
+     * @param KeywordsDumper      $dumper
+     * @param TranslatorInterface $translator
+     */
+    public function __construct(KeywordsDumper $dumper, TranslatorInterface $translator)
+    {
+        $dumper->setKeywordsDumperFunction(array($this, 'dumpKeywords'));
+        $this->keywordsDumper = $dumper;
+        $this->translator = $translator;
+    }
+
+    /**
+     * Configures command to be executable by the controller.
+     *
+     * @param Command $command
+     */
+    public function configure(Command $command)
+    {
+        $command
+            ->addOption(
+                '--story-syntax', null, InputOption::VALUE_NONE,
+                "Print <comment>*.feature</comment> example." . PHP_EOL .
+                "Use <info>--lang</info> to see specific language."
+            );
+    }
+
+    /**
+     * Executes controller.
+     *
+     * @param InputInterface  $input
+     * @param OutputInterface $output
+     *
+     * @return null|integer
+     */
+    public function execute(InputInterface $input, OutputInterface $output)
+    {
+        if (!$input->getOption('story-syntax')) {
+            return null;
+        }
+
+        $output->getFormatter()->setStyle('gherkin_keyword', new OutputFormatterStyle('green', null, array('bold')));
+        $output->getFormatter()->setStyle('gherkin_comment', new OutputFormatterStyle('yellow'));
+
+        $story = $this->keywordsDumper->dump($this->translator->getLocale());
+        $story = preg_replace('/^\#.*/', '<gherkin_comment>$0</gherkin_comment>', $story);
+        $output->writeln($story);
+        $output->writeln('');
+
+        return 0;
+    }
+
+    /**
+     * Keywords dumper.
+     *
+     * @param array $keywords keywords list
+     *
+     * @return string
+     */
+    public function dumpKeywords(array $keywords)
+    {
+        $dump = '<gherkin_keyword>' . implode('</gherkin_keyword>|<gherkin_keyword>', $keywords) . '</gherkin_keyword>';
+
+        if (1 < count($keywords)) {
+            return '[' . $dump . ']';
+        }
+
+        return $dump;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Gherkin/ServiceContainer/GherkinExtension.php b/vendor/behat/behat/src/Behat/Behat/Gherkin/ServiceContainer/GherkinExtension.php
new file mode 100644 (file)
index 0000000..c24ddce
--- /dev/null
@@ -0,0 +1,384 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Gherkin\ServiceContainer;
+
+use Behat\Testwork\Cli\ServiceContainer\CliExtension;
+use Behat\Testwork\Filesystem\ServiceContainer\FilesystemExtension;
+use Behat\Testwork\ServiceContainer\Exception\ExtensionException;
+use Behat\Testwork\ServiceContainer\Extension;
+use Behat\Testwork\ServiceContainer\ExtensionManager;
+use Behat\Testwork\ServiceContainer\ServiceProcessor;
+use Behat\Testwork\Specification\ServiceContainer\SpecificationExtension;
+use Behat\Testwork\Suite\ServiceContainer\SuiteExtension;
+use Behat\Testwork\Translator\ServiceContainer\TranslatorExtension;
+use ReflectionClass;
+use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Definition;
+use Symfony\Component\DependencyInjection\Reference;
+
+/**
+ * Extends Behat with gherkin suites and features.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class GherkinExtension implements Extension
+{
+    /*
+     * Available services
+     */
+    const MANAGER_ID = 'gherkin';
+    const KEYWORDS_DUMPER_ID = 'gherkin.keywords_dumper';
+    const KEYWORDS_ID = 'gherkin.keywords';
+
+    /*
+     * Available extension points
+     */
+    const LOADER_TAG = 'gherkin.loader';
+
+    /**
+     * @var ServiceProcessor
+     */
+    private $processor;
+
+    /**
+     * Initializes extension.
+     *
+     * @param null|ServiceProcessor $processor
+     */
+    public function __construct(ServiceProcessor $processor = null)
+    {
+        $this->processor = $processor ? : new ServiceProcessor();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getConfigKey()
+    {
+        return 'gherkin';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function initialize(ExtensionManager $extensionManager)
+    {
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function configure(ArrayNodeDefinition $builder)
+    {
+        $builder
+            ->addDefaultsIfNotSet()
+            ->children()
+                ->scalarNode('cache')
+                    ->info('Sets the gherkin parser cache folder')
+                    ->defaultValue(
+                        is_writable(sys_get_temp_dir())
+                            ? sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'behat_gherkin_cache'
+                            : null
+                    )
+                ->end()
+                ->arrayNode('filters')
+                    ->info('Sets the gherkin filters (overridable by CLI options)')
+                    ->performNoDeepMerging()
+                    ->defaultValue(array())
+                    ->useAttributeAsKey('name')
+                    ->prototype('scalar')->end()
+                ->end()
+            ->end()
+        ;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function load(ContainerBuilder $container, array $config)
+    {
+        $this->loadParameters($container);
+        $this->loadGherkin($container);
+        $this->loadKeywords($container);
+        $this->loadParser($container);
+        $this->loadDefaultLoaders($container, $config['cache']);
+        $this->loadProfileFilters($container, $config['filters']);
+        $this->loadSyntaxController($container);
+        $this->loadFilterController($container);
+        $this->loadSuiteWithPathsSetup($container);
+        $this->loadFilesystemFeatureLocator($container);
+        $this->loadFilesystemScenariosListLocator($container);
+        $this->loadFilesystemRerunScenariosListLocator($container);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function process(ContainerBuilder $container)
+    {
+        $this->processLoaders($container);
+    }
+
+    /**
+     * Loads default container parameters.
+     *
+     * @param ContainerBuilder $container
+     */
+    private function loadParameters(ContainerBuilder $container)
+    {
+        $container->setParameter('gherkin.paths.lib', $this->getLibPath());
+        $container->setParameter('gherkin.paths.i18n', '%gherkin.paths.lib%/i18n.php');
+        $container->setParameter(
+            'suite.generic.default_settings',
+            array(
+                'paths'    => array('%paths.base%/features'),
+                'contexts' => array('FeatureContext')
+            )
+        );
+    }
+
+    /**
+     * Returns gherkin library path.
+     *
+     * @return string
+     */
+    private function getLibPath()
+    {
+        $reflection = new ReflectionClass('Behat\Gherkin\Gherkin');
+        $libPath = rtrim(dirname($reflection->getFilename()) . '/../../../', DIRECTORY_SEPARATOR);
+
+        return $libPath;
+    }
+
+    /**
+     * Loads gherkin service.
+     *
+     * @param ContainerBuilder $container
+     */
+    private function loadGherkin(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Gherkin\Gherkin');
+        $container->setDefinition(self::MANAGER_ID, $definition);
+    }
+
+    /**
+     * Loads keyword services.
+     *
+     * @param ContainerBuilder $container
+     */
+    private function loadKeywords(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Gherkin\Keywords\CachedArrayKeywords', array(
+            '%gherkin.paths.i18n%'
+        ));
+        $container->setDefinition(self::KEYWORDS_ID, $definition);
+
+        $definition = new Definition('Behat\Gherkin\Keywords\KeywordsDumper', array(
+            new Reference(self::KEYWORDS_ID)
+        ));
+        $container->setDefinition(self::KEYWORDS_DUMPER_ID, $definition);
+    }
+
+    /**
+     * Loads gherkin parser.
+     *
+     * @param ContainerBuilder $container
+     */
+    private function loadParser(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Gherkin\Parser', array(
+            new Reference('gherkin.lexer')
+        ));
+        $container->setDefinition('gherkin.parser', $definition);
+
+        $definition = new Definition('Behat\Gherkin\Lexer', array(
+            new Reference('gherkin.keywords')
+        ));
+        $container->setDefinition('gherkin.lexer', $definition);
+    }
+
+    /**
+     * Loads gherkin loaders.
+     *
+     * @param ContainerBuilder $container
+     * @param string           $cachePath
+     */
+    private function loadDefaultLoaders(ContainerBuilder $container, $cachePath)
+    {
+        $definition = new Definition('Behat\Gherkin\Loader\GherkinFileLoader', array(
+            new Reference('gherkin.parser')
+        ));
+
+        if ($cachePath) {
+            $cacheDefinition = new Definition('Behat\Gherkin\Cache\FileCache', array($cachePath));
+        } else {
+            $cacheDefinition = new Definition('Behat\Gherkin\Cache\MemoryCache');
+        }
+
+        $definition->addMethodCall('setCache', array($cacheDefinition));
+        $definition->addMethodCall('setBasePath', array('%paths.base%'));
+        $definition->addTag(self::LOADER_TAG, array('priority' => 50));
+        $container->setDefinition('gherkin.loader.gherkin_file', $definition);
+    }
+
+    /**
+     * Loads profile-level gherkin filters.
+     *
+     * @param ContainerBuilder $container
+     * @param array            $filters
+     */
+    private function loadProfileFilters(ContainerBuilder $container, array $filters)
+    {
+        $gherkin = $container->getDefinition(self::MANAGER_ID);
+        foreach ($filters as $type => $filterString) {
+            $filter = $this->createFilterDefinition($type, $filterString);
+            $gherkin->addMethodCall('addFilter', array($filter));
+        }
+    }
+
+    /**
+     * Loads syntax controller.
+     *
+     * @param ContainerBuilder $container
+     */
+    private function loadSyntaxController(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Behat\Gherkin\Cli\SyntaxController', array(
+            new Reference(self::KEYWORDS_DUMPER_ID),
+            new Reference(TranslatorExtension::TRANSLATOR_ID)
+        ));
+        $definition->addTag(CliExtension::CONTROLLER_TAG, array('priority' => 600));
+        $container->setDefinition(CliExtension::CONTROLLER_TAG . '.gherkin_syntax', $definition);
+    }
+
+    /**
+     * Loads filter controller.
+     *
+     * @param ContainerBuilder $container
+     */
+    private function loadFilterController(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Behat\Gherkin\Cli\FilterController', array(
+            new Reference(self::MANAGER_ID)
+        ));
+        $definition->addTag(CliExtension::CONTROLLER_TAG, array('priority' => 700));
+        $container->setDefinition(CliExtension::CONTROLLER_TAG . '.gherkin_filters', $definition);
+    }
+
+    /**
+     * Loads suite with paths setup.
+     *
+     * @param ContainerBuilder $container
+     */
+    private function loadSuiteWithPathsSetup(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Behat\Gherkin\Suite\Setup\SuiteWithPathsSetup', array(
+            '%paths.base%',
+            new Reference(FilesystemExtension::LOGGER_ID)
+        ));
+        $definition->addTag(SuiteExtension::SETUP_TAG, array('priority' => 50));
+        $container->setDefinition(SuiteExtension::SETUP_TAG . '.suite_with_paths', $definition);
+    }
+
+    /**
+     * Loads filesystem feature locator.
+     *
+     * @param ContainerBuilder $container
+     */
+    private function loadFilesystemFeatureLocator(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Behat\Gherkin\Specification\Locator\FilesystemFeatureLocator', array(
+            new Reference(self::MANAGER_ID),
+            '%paths.base%'
+        ));
+        $definition->addTag(SpecificationExtension::LOCATOR_TAG, array('priority' => 60));
+        $container->setDefinition(SpecificationExtension::LOCATOR_TAG . '.filesystem_feature', $definition);
+    }
+
+    /**
+     * Loads filesystem scenarios list locator.
+     *
+     * @param ContainerBuilder $container
+     */
+    private function loadFilesystemScenariosListLocator(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Behat\Gherkin\Specification\Locator\FilesystemScenariosListLocator', array(
+            new Reference(self::MANAGER_ID)
+        ));
+        $definition->addTag(SpecificationExtension::LOCATOR_TAG, array('priority' => 50));
+        $container->setDefinition(SpecificationExtension::LOCATOR_TAG . '.filesystem_scenarios_list', $definition);
+    }
+
+    /**
+     * Loads filesystem rerun scenarios list locator.
+     *
+     * @param ContainerBuilder $container
+     */
+    private function loadFilesystemRerunScenariosListLocator(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Behat\Gherkin\Specification\Locator\FilesystemRerunScenariosListLocator', array(
+            new Reference(self::MANAGER_ID)
+        ));
+        $definition->addTag(SpecificationExtension::LOCATOR_TAG, array('priority' => 50));
+        $container->setDefinition(SpecificationExtension::LOCATOR_TAG . '.filesystem_rerun_scenarios_list', $definition);
+    }
+
+    /**
+     * Processes all available gherkin loaders.
+     *
+     * @param ContainerBuilder $container
+     */
+    private function processLoaders(ContainerBuilder $container)
+    {
+        $references = $this->processor->findAndSortTaggedServices($container, self::LOADER_TAG);
+        $definition = $container->getDefinition(self::MANAGER_ID);
+
+        foreach ($references as $reference) {
+            $definition->addMethodCall('addLoader', array($reference));
+        }
+    }
+
+    /**
+     * Creates filter definition of provided type.
+     *
+     * @param string $type
+     * @param string $filterString
+     *
+     * @return Definition
+     *
+     * @throws ExtensionException If filter type is not recognised
+     */
+    private function createFilterDefinition($type, $filterString)
+    {
+        if ('role' === $type) {
+            return new Definition('Behat\Gherkin\Filter\RoleFilter', array($filterString));
+        }
+
+        if ('name' === $type) {
+            return new Definition('Behat\Gherkin\Filter\NameFilter', array($filterString));
+        }
+
+        if ('tags' === $type) {
+            return new Definition('Behat\Gherkin\Filter\TagFilter', array($filterString));
+        }
+
+        if ('narrative' === $type) {
+            return new Definition('Behat\Gherkin\Filter\NarrativeFilter', array($filterString));
+        }
+
+        throw new ExtensionException(sprintf(
+            '`%s` filter is not supported by the `filters` option of gherkin extension. Supported types are `%s`.',
+            $type,
+            implode('`, `', array('narrative', 'role', 'name', 'tags'))
+        ), 'gherkin');
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Gherkin/Specification/LazyFeatureIterator.php b/vendor/behat/behat/src/Behat/Behat/Gherkin/Specification/LazyFeatureIterator.php
new file mode 100644 (file)
index 0000000..61dd9bd
--- /dev/null
@@ -0,0 +1,207 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Gherkin\Specification;
+
+use Behat\Gherkin\Filter\FilterInterface;
+use Behat\Gherkin\Filter\NameFilter;
+use Behat\Gherkin\Filter\NarrativeFilter;
+use Behat\Gherkin\Filter\RoleFilter;
+use Behat\Gherkin\Filter\TagFilter;
+use Behat\Gherkin\Gherkin;
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Testwork\Specification\SpecificationIterator;
+use Behat\Testwork\Suite\Exception\SuiteConfigurationException;
+use Behat\Testwork\Suite\Suite;
+
+/**
+ * Lazily iterates (parses one-by-one) over features.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class LazyFeatureIterator implements SpecificationIterator
+{
+    /**
+     * @var Suite
+     */
+    private $suite;
+    /**
+     * @var Gherkin
+     */
+    private $gherkin;
+    /**
+     * @var string[]
+     */
+    private $paths = array();
+    /**
+     * @var FilterInterface[]
+     */
+    private $filters = array();
+    /**
+     * @var integer
+     */
+    private $position = 0;
+    /**
+     * @var FeatureNode[]
+     */
+    private $features = array();
+    /**
+     * @var FeatureNode
+     */
+    private $currentFeature;
+
+    /**
+     * Initializes specifications.
+     *
+     * @param Suite             $suite
+     * @param Gherkin           $gherkin
+     * @param string[]          $paths
+     * @param FilterInterface[] $filters
+     */
+    public function __construct(Suite $suite, Gherkin $gherkin, array $paths, array $filters = array())
+    {
+        $this->suite = $suite;
+        $this->gherkin = $gherkin;
+        $this->paths = array_values($paths);
+        $this->filters = array_merge($this->getSuiteFilters($suite), $filters);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getSuite()
+    {
+        return $this->suite;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function rewind()
+    {
+        $this->position = 0;
+        $this->moveToNextAvailableFeature();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function next()
+    {
+        $this->moveToNextAvailableFeature();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function valid()
+    {
+        return null !== $this->currentFeature;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function key()
+    {
+        return $this->position;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function current()
+    {
+        return $this->currentFeature;
+    }
+
+    /**
+     * Returns list of filters from suite settings.
+     *
+     * @param Suite $suite
+     *
+     * @return FilterInterface[]
+     */
+    private function getSuiteFilters(Suite $suite)
+    {
+        if (!$suite->hasSetting('filters') || !is_array($suite->getSetting('filters'))) {
+            return array();
+        }
+
+        $filters = array();
+        foreach ($suite->getSetting('filters') as $type => $filterString) {
+            $filters[] = $this->createFilter($type, $filterString, $suite);
+        }
+
+        return $filters;
+    }
+
+    /**
+     * Creates filter of provided type.
+     *
+     * @param string $type
+     * @param string $filterString
+     * @param Suite  $suite
+     *
+     * @return FilterInterface
+     *
+     * @throws SuiteConfigurationException If filter type is not recognised
+     */
+    private function createFilter($type, $filterString, Suite $suite)
+    {
+        if ('role' === $type) {
+            return new RoleFilter($filterString);
+        }
+
+        if ('name' === $type) {
+            return new NameFilter($filterString);
+        }
+
+        if ('tags' === $type) {
+            return new TagFilter($filterString);
+        }
+
+        if ('narrative' === $type) {
+            return new NarrativeFilter($filterString);
+        }
+
+        throw new SuiteConfigurationException(sprintf(
+            '`%s` filter is not supported by the `%s` suite. Supported types are `%s`.',
+            $type,
+            $suite->getName(),
+            implode('`, `', array('role', 'name', 'tags'))
+        ), $suite->getName());
+    }
+
+    /**
+     * Parses paths consequently.
+     */
+    private function moveToNextAvailableFeature()
+    {
+        while (!count($this->features) && $this->position < count($this->paths)) {
+            $this->features = $this->parseFeature($this->paths[$this->position]);
+            $this->position++;
+        }
+
+        $this->currentFeature = array_shift($this->features);
+    }
+
+    /**
+     * Parses feature at path.
+     *
+     * @param string $path
+     *
+     * @return FeatureNode[]
+     */
+    private function parseFeature($path)
+    {
+        return $this->gherkin->load($path, $this->filters);
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Gherkin/Specification/Locator/FilesystemFeatureLocator.php b/vendor/behat/behat/src/Behat/Behat/Gherkin/Specification/Locator/FilesystemFeatureLocator.php
new file mode 100644 (file)
index 0000000..d96cf8e
--- /dev/null
@@ -0,0 +1,176 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Gherkin\Specification\Locator;
+
+use Behat\Behat\Gherkin\Specification\LazyFeatureIterator;
+use Behat\Gherkin\Filter\PathsFilter;
+use Behat\Gherkin\Gherkin;
+use Behat\Testwork\Specification\Locator\SpecificationLocator;
+use Behat\Testwork\Specification\NoSpecificationsIterator;
+use Behat\Testwork\Suite\Exception\SuiteConfigurationException;
+use Behat\Testwork\Suite\Suite;
+use RecursiveDirectoryIterator;
+use RecursiveIteratorIterator;
+use RegexIterator;
+
+/**
+ * Loads gherkin features from the filesystem using gherkin parser.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class FilesystemFeatureLocator implements SpecificationLocator
+{
+    /**
+     * @var Gherkin
+     */
+    private $gherkin;
+    /**
+     * @var string
+     */
+    private $basePath;
+
+    /**
+     * Initializes loader.
+     *
+     * @param Gherkin $gherkin
+     * @param string  $basePath
+     */
+    public function __construct(Gherkin $gherkin, $basePath)
+    {
+        $this->gherkin = $gherkin;
+        $this->basePath = $basePath;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getLocatorExamples()
+    {
+        return array(
+            "a dir <comment>(features/)</comment>",
+            "a feature <comment>(*.feature)</comment>",
+            "a scenario at specific line <comment>(*.feature:10)</comment>.",
+            "all scenarios at or after a specific line <comment>(*.feature:10-*)</comment>.",
+            "all scenarios at a line within a specific range <comment>(*.feature:10-20)</comment>."
+        );
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function locateSpecifications(Suite $suite, $locator)
+    {
+        if (!$suite->hasSetting('paths')) {
+            return new NoSpecificationsIterator($suite);
+        }
+
+        $suiteLocators = $this->getSuitePaths($suite);
+
+        if ($locator) {
+            $filters = array(new PathsFilter($suiteLocators));
+
+            return new LazyFeatureIterator($suite, $this->gherkin, $this->findFeatureFiles($locator), $filters);
+        }
+
+        $featurePaths = array();
+        foreach ($suiteLocators as $suiteLocator) {
+            $featurePaths = array_merge($featurePaths, $this->findFeatureFiles($suiteLocator));
+        }
+
+        return new LazyFeatureIterator($suite, $this->gherkin, $featurePaths);
+    }
+
+    /**
+     * Returns array of feature paths configured for the provided suite.
+     *
+     * @param Suite $suite
+     *
+     * @return string[]
+     *
+     * @throws SuiteConfigurationException If `paths` setting is not an array
+     */
+    private function getSuitePaths(Suite $suite)
+    {
+        if (!is_array($suite->getSetting('paths'))) {
+            throw new SuiteConfigurationException(
+                sprintf('`paths` setting of the "%s" suite is expected to be an array, %s given.',
+                    $suite->getName(),
+                    gettype($suite->getSetting('paths'))
+                ),
+                $suite->getName()
+            );
+        }
+
+        return $suite->getSetting('paths');
+    }
+
+    /**
+     * Loads feature files paths from provided path.
+     *
+     * @param string $path
+     *
+     * @return string[]
+     */
+    private function findFeatureFiles($path)
+    {
+        $absolutePath = $this->findAbsolutePath($path);
+
+        if (!$absolutePath) {
+            return array($path);
+        }
+
+        if (is_file($absolutePath)) {
+            return array($absolutePath);
+        }
+
+        $iterator = new RegexIterator(
+            new RecursiveIteratorIterator(
+                new RecursiveDirectoryIterator(
+                    $absolutePath,
+                    RecursiveDirectoryIterator::FOLLOW_SYMLINKS | RecursiveDirectoryIterator::SKIP_DOTS
+                )
+            ),
+            '/^.+\.feature$/i',
+            RegexIterator::MATCH
+        );
+
+        $paths = array_map('strval', iterator_to_array($iterator));
+        uasort($paths, 'strnatcasecmp');
+
+        return $paths;
+    }
+
+    /**
+     * Finds absolute path for provided relative (relative to base features path).
+     *
+     * @param string $path Relative path
+     *
+     * @return string
+     */
+    private function findAbsolutePath($path)
+    {
+        if (is_file($path) || is_dir($path)) {
+            return realpath($path);
+        }
+
+        if (null === $this->basePath) {
+            return false;
+        }
+
+        if (is_file($this->basePath . DIRECTORY_SEPARATOR . $path)
+            || is_dir($this->basePath . DIRECTORY_SEPARATOR . $path)
+        ) {
+            return realpath($this->basePath . DIRECTORY_SEPARATOR . $path);
+        }
+
+        return false;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Gherkin/Specification/Locator/FilesystemRerunScenariosListLocator.php b/vendor/behat/behat/src/Behat/Behat/Gherkin/Specification/Locator/FilesystemRerunScenariosListLocator.php
new file mode 100644 (file)
index 0000000..d5ac5b3
--- /dev/null
@@ -0,0 +1,65 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Gherkin\Specification\Locator;
+
+use Behat\Behat\Gherkin\Specification\LazyFeatureIterator;
+use Behat\Gherkin\Gherkin;
+use Behat\Testwork\Specification\Locator\SpecificationLocator;
+use Behat\Testwork\Specification\NoSpecificationsIterator;
+use Behat\Testwork\Suite\Suite;
+
+/**
+ * Loads gherkin features using a file with the list of scenarios.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class FilesystemRerunScenariosListLocator implements SpecificationLocator
+{
+    /**
+     * @var Gherkin
+     */
+    private $gherkin;
+
+    /**
+     * Initializes locator.
+     *
+     * @param Gherkin $gherkin
+     */
+    public function __construct(Gherkin $gherkin)
+    {
+        $this->gherkin = $gherkin;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getLocatorExamples()
+    {
+        return array();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function locateSpecifications(Suite $suite, $locator)
+    {
+        if (!is_file($locator) || 'rerun' !== pathinfo($locator, PATHINFO_EXTENSION)) {
+            return new NoSpecificationsIterator($suite);
+        }
+
+        $scenarios = json_decode(trim(file_get_contents($locator)), true);
+        if (empty($scenarios) || empty($scenarios[$suite->getName()])) {
+            return new NoSpecificationsIterator($suite);
+        }
+
+        return new LazyFeatureIterator($suite, $this->gherkin, $scenarios[$suite->getName()]);
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Gherkin/Specification/Locator/FilesystemScenariosListLocator.php b/vendor/behat/behat/src/Behat/Behat/Gherkin/Specification/Locator/FilesystemScenariosListLocator.php
new file mode 100644 (file)
index 0000000..59141df
--- /dev/null
@@ -0,0 +1,62 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Gherkin\Specification\Locator;
+
+use Behat\Behat\Gherkin\Specification\LazyFeatureIterator;
+use Behat\Gherkin\Gherkin;
+use Behat\Testwork\Specification\Locator\SpecificationLocator;
+use Behat\Testwork\Specification\NoSpecificationsIterator;
+use Behat\Testwork\Suite\Suite;
+
+/**
+ * Loads gherkin features using a file with the list of scenarios.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class FilesystemScenariosListLocator implements SpecificationLocator
+{
+    /**
+     * @var Gherkin
+     */
+    private $gherkin;
+
+    /**
+     * Initializes locator.
+     *
+     * @param Gherkin $gherkin
+     */
+    public function __construct(Gherkin $gherkin)
+    {
+        $this->gherkin = $gherkin;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getLocatorExamples()
+    {
+        return array("a scenarios list file <comment>(*.scenarios)</comment>.");
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function locateSpecifications(Suite $suite, $locator)
+    {
+        if (!is_file($locator) || 'scenarios' !== pathinfo($locator, PATHINFO_EXTENSION)) {
+            return new NoSpecificationsIterator($suite);
+        }
+
+        $scenarios = explode("\n", trim(file_get_contents($locator)));
+
+        return new LazyFeatureIterator($suite, $this->gherkin, $scenarios);
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Gherkin/Suite/Setup/SuiteWithPathsSetup.php b/vendor/behat/behat/src/Behat/Behat/Gherkin/Suite/Setup/SuiteWithPathsSetup.php
new file mode 100644 (file)
index 0000000..65c7c8f
--- /dev/null
@@ -0,0 +1,116 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Gherkin\Suite\Setup;
+
+use Behat\Testwork\Filesystem\FilesystemLogger;
+use Behat\Testwork\Suite\Setup\SuiteSetup;
+use Behat\Testwork\Suite\Suite;
+
+/**
+ * Sets up gherkin suite in the filesystem (creates feature folders).
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class SuiteWithPathsSetup implements SuiteSetup
+{
+    /**
+     * @var string
+     */
+    private $basePath;
+    /**
+     * @var null|FilesystemLogger
+     */
+    private $logger;
+
+    /**
+     * Initializes setup.
+     *
+     * @param string                $basePath
+     * @param null|FilesystemLogger $logger
+     */
+    public function __construct($basePath, FilesystemLogger $logger = null)
+    {
+        $this->basePath = $basePath;
+        $this->logger = $logger;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function supportsSuite(Suite $suite)
+    {
+        return $suite->hasSetting('paths') && is_array($suite->getSetting('paths'));
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setupSuite(Suite $suite)
+    {
+        foreach ($suite->getSetting('paths') as $locator) {
+            if (0 !== strpos($locator, '@') && !is_dir($path = $this->locatePath($locator))) {
+                $this->createFeatureDirectory($path);
+            }
+        }
+    }
+
+    /**
+     * Creates feature directory.
+     *
+     * @param string $path
+     */
+    private function createFeatureDirectory($path)
+    {
+        mkdir($path, 0777, true);
+
+        if ($this->logger) {
+            $this->logger->directoryCreated($path, 'place your *.feature files here');
+        }
+    }
+
+    /**
+     * Locates path from a relative one.
+     *
+     * @param string $path
+     *
+     * @return string
+     */
+    private function locatePath($path)
+    {
+        if ($this->isAbsolutePath($path)) {
+            return $path;
+        }
+
+        return $this->basePath . DIRECTORY_SEPARATOR . $path;
+    }
+
+    /**
+     * Returns whether the file path is an absolute path.
+     *
+     * @param string $file A file path
+     *
+     * @return Boolean
+     */
+    private function isAbsolutePath($file)
+    {
+        if ($file[0] == '/' || $file[0] == '\\'
+            || (strlen($file) > 3 && ctype_alpha($file[0])
+                && $file[1] == ':'
+                && ($file[2] == '\\' || $file[2] == '/')
+            )
+            || null !== parse_url($file, PHP_URL_SCHEME)
+        ) {
+            return true;
+        }
+
+        return false;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/HelperContainer/Argument/AutowiringResolver.php b/vendor/behat/behat/src/Behat/Behat/HelperContainer/Argument/AutowiringResolver.php
new file mode 100644 (file)
index 0000000..11dde13
--- /dev/null
@@ -0,0 +1,53 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\HelperContainer\Argument;
+
+use Behat\Behat\Context\Argument\ArgumentResolver;
+use Behat\Behat\HelperContainer\ArgumentAutowirer;
+use Psr\Container\ContainerInterface;
+use ReflectionClass;
+
+/**
+ * Resolves arguments that weren't resolved before by autowiring.
+ *
+ * @see ContextFactory
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class AutowiringResolver implements ArgumentResolver
+{
+    /**
+     * @var ArgumentAutowirer
+     */
+    private $autowirer;
+
+    /**
+     * Initialises resolver.
+     *
+     * @param ContainerInterface $container
+     */
+    public function __construct(ContainerInterface $container)
+    {
+        $this->autowirer = new ArgumentAutowirer($container);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function resolveArguments(ReflectionClass $classReflection, array $arguments)
+    {
+        if ($constructor = $classReflection->getConstructor()) {
+            return $this->autowirer->autowireArguments($constructor, $arguments);
+        }
+
+        return $arguments;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/HelperContainer/Argument/ServicesResolver.php b/vendor/behat/behat/src/Behat/Behat/HelperContainer/Argument/ServicesResolver.php
new file mode 100644 (file)
index 0000000..9e16f32
--- /dev/null
@@ -0,0 +1,72 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\HelperContainer\Argument;
+
+use Behat\Behat\Context\Argument\ArgumentResolver;
+use Psr\Container\ContainerExceptionInterface;
+use Psr\Container\ContainerInterface;
+use ReflectionClass;
+
+/**
+ * Resolves arguments using provided service container.
+ *
+ * @see ContextFactory
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class ServicesResolver implements ArgumentResolver
+{
+    /**
+     * @var ContainerInterface
+     */
+    private $container;
+
+    /**
+     * Initialises resolver.
+     *
+     * @param ContainerInterface $container
+     */
+    public function __construct(ContainerInterface $container)
+    {
+        $this->container = $container;
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @throws ContainerExceptionInterface
+     */
+    public function resolveArguments(ReflectionClass $classReflection, array $arguments)
+    {
+        return array_map(array($this, 'resolveArgument'), $arguments);
+    }
+
+    /**
+     * Attempts to resolve singular argument from container.
+     *
+     * Convention is strings starting with `@` are considered services and
+     * are expected to be present in the container.
+     *
+     * @param mixed $value
+     *
+     * @return mixed
+     *
+     * @throws ContainerExceptionInterface
+     */
+    private function resolveArgument($value)
+    {
+        if (0 === mb_strpos($value, '@')) {
+            return $this->container->get(mb_substr($value, 1));
+        }
+
+        return $value;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/HelperContainer/Argument/ServicesResolverFactory.php b/vendor/behat/behat/src/Behat/Behat/HelperContainer/Argument/ServicesResolverFactory.php
new file mode 100644 (file)
index 0000000..8820288
--- /dev/null
@@ -0,0 +1,220 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\HelperContainer\Argument;
+
+use Behat\Behat\Context\Argument\ArgumentResolver;
+use Behat\Behat\HelperContainer\Environment\ServiceContainerEnvironment;
+use Behat\Behat\Context\Argument\ArgumentResolverFactory;
+use Behat\Behat\Context\Argument\SuiteScopedResolverFactory;
+use Behat\Behat\HelperContainer\BuiltInServiceContainer;
+use Behat\Behat\HelperContainer\Exception\WrongContainerClassException;
+use Behat\Behat\HelperContainer\Exception\WrongServicesConfigurationException;
+use Behat\Behat\HelperContainer\ServiceContainer\HelperContainerExtension;
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\Suite\Suite;
+use Psr\Container\ContainerInterface;
+use Symfony\Component\DependencyInjection\TaggedContainerInterface;
+
+/**
+ * Generates ServiceContainer argument resolvers based on suite's `services` setting.
+ *
+ * @see ContextEnvironmentHandler
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class ServicesResolverFactory implements SuiteScopedResolverFactory, ArgumentResolverFactory
+{
+    /**
+     * @var TaggedContainerInterface
+     */
+    private $container;
+
+    /**
+     * Initialises factory.
+     *
+     * @param TaggedContainerInterface $container
+     */
+    public function __construct(TaggedContainerInterface $container)
+    {
+        $this->container = $container;
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @deprecated as part of SuiteScopedResolverFactory deprecation. Would be removed in 4.0
+     *
+     * @throws WrongServicesConfigurationException
+     * @throws WrongContainerClassException
+     */
+    public function generateArgumentResolvers(Suite $suite)
+    {
+        @trigger_error(
+            'SuiteScopedResolverFactory::generateArgumentResolvers() was deprecated and will be removed in 4.0',
+            E_USER_DEPRECATED
+        );
+
+        if (!$suite->hasSetting('services')) {
+            return array();
+        }
+
+        $container = $this->createContainer($suite->getSetting('services'));
+
+        return $this->createResolvers($container, false);
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @throws WrongServicesConfigurationException
+     * @throws WrongContainerClassException
+     */
+    public function createArgumentResolvers(Environment $environment)
+    {
+        $suite = $environment->getSuite();
+
+        if (!$suite->hasSetting('services')) {
+            return array();
+        }
+
+        $container = $this->createContainer($suite->getSetting('services'));
+        $autowire = $suite->hasSetting('autowire') && $suite->getSetting('autowire');
+
+        if ($environment instanceof ServiceContainerEnvironment) {
+            $environment->setServiceContainer($container);
+        }
+
+        return $this->createResolvers($container, $autowire);
+    }
+
+    /**
+     * Creates container from the setting passed.
+     *
+     * @param string $settings
+     *
+     * @return mixed
+     *
+     * @throws WrongServicesConfigurationException
+     */
+    private function createContainer($settings)
+    {
+        if (is_string($settings)) {
+            return $this->createContainerFromString($settings);
+        }
+
+        if (is_array($settings)) {
+            return $this->createContainerFromArray($settings);
+        }
+
+        throw new WrongServicesConfigurationException(
+            sprintf('`services` must be either string or an array, but `%s` given.', gettype($settings))
+        );
+    }
+
+    /**
+     * Creates custom container using class/constructor given.
+     *
+     * @param string $settings
+     *
+     * @return mixed
+     *
+     * @throws WrongServicesConfigurationException
+     */
+    private function createContainerFromString($settings)
+    {
+        if (0 === mb_strpos($settings, '@')) {
+            return $this->loadContainerFromContainer(mb_substr($settings, 1));
+        }
+
+        return $this->createContainerFromClassSpec($settings);
+    }
+
+    /**
+     * Creates built-in service container with provided settings.
+     *
+     * @param array $settings
+     *
+     * @return BuiltInServiceContainer
+     */
+    private function createContainerFromArray(array $settings)
+    {
+        return new BuiltInServiceContainer($settings);
+    }
+
+    /**
+     * Loads container from string.
+     *
+     * @param string $name
+     *
+     * @return mixed
+     *
+     * @throws WrongServicesConfigurationException
+     */
+    private function loadContainerFromContainer($name)
+    {
+        $services = $this->container->findTaggedServiceIds(HelperContainerExtension::HELPER_CONTAINER_TAG);
+
+        if (!array_key_exists($name, $services)) {
+            throw new WrongServicesConfigurationException(
+                sprintf('Service container `@%s` was not found.', $name)
+            );
+        }
+
+        return $this->container->get($name);
+    }
+
+    /**
+     * Creates container from string-based class spec.
+     *
+     * @param string $classSpec
+     *
+     * @return mixed
+     */
+    private function createContainerFromClassSpec($classSpec)
+    {
+        $constructor = explode('::', $classSpec);
+
+        if (2 === count($constructor)) {
+            return call_user_func($constructor);
+        }
+
+        return new $constructor[0];
+    }
+
+    /**
+     * Checks if container implements the correct interface and creates resolver using it.
+     *
+     * @param mixed $container
+     * @param bool  $autowire
+     *
+     * @return ArgumentResolver[]
+     *
+     * @throws WrongContainerClassException
+     */
+    private function createResolvers($container, $autowire)
+    {
+        if (!$container instanceof ContainerInterface) {
+            throw new WrongContainerClassException(
+                sprintf(
+                    'Service container is expected to implement `Psr\Container\ContainerInterface`, but `%s` does not.',
+                    get_class($container)
+                ),
+                get_class($container)
+            );
+        }
+
+        if ($autowire) {
+            return array(new ServicesResolver($container), new AutowiringResolver($container));
+        }
+
+        return array(new ServicesResolver($container));
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/HelperContainer/ArgumentAutowirer.php b/vendor/behat/behat/src/Behat/Behat/HelperContainer/ArgumentAutowirer.php
new file mode 100644 (file)
index 0000000..d4d5147
--- /dev/null
@@ -0,0 +1,77 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\HelperContainer;
+
+use Psr\Container\ContainerExceptionInterface;
+use Psr\Container\ContainerInterface;
+use ReflectionFunctionAbstract;
+use ReflectionParameter;
+
+/**
+ * Automatically wires arguments of a given function from inside the container by using type-hitns.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class ArgumentAutowirer
+{
+    /**
+     * @var ContainerInterface
+     */
+    private $container;
+
+    /**
+     * Initialises wirer.
+     *
+     * @param ContainerInterface $container
+     */
+    public function __construct(ContainerInterface $container)
+    {
+        $this->container = $container;
+    }
+
+    /**
+     * Autowires given arguments using provided container.
+     *
+     * @param ReflectionFunctionAbstract $reflection
+     * @param array $arguments
+     *
+     * @return array
+     *
+     * @throws ContainerExceptionInterface if unset argument typehint can not be resolved from container
+     */
+    public function autowireArguments(ReflectionFunctionAbstract $reflection, array $arguments)
+    {
+        $newArguments = $arguments;
+        foreach ($reflection->getParameters() as $index => $parameter) {
+            if ($this->isArgumentWireable($newArguments, $index, $parameter)) {
+                $newArguments[$index] = $this->container->get($parameter->getClass()->getName());
+            }
+        }
+
+        return $newArguments;
+    }
+
+    /**
+     * Checks if given argument is wireable.
+     *
+     * Argument is wireable if it was not previously set and it has a class type-hint.
+     *
+     * @param array               $arguments
+     * @param integer             $index
+     * @param ReflectionParameter $parameter
+     *
+     * @return bool
+     */
+    private function isArgumentWireable(array $arguments, $index, ReflectionParameter $parameter)
+    {
+        return !isset($arguments[$index]) && !isset($arguments[$parameter->getName()]) && $parameter->getClass();
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/HelperContainer/BuiltInServiceContainer.php b/vendor/behat/behat/src/Behat/Behat/HelperContainer/BuiltInServiceContainer.php
new file mode 100644 (file)
index 0000000..624bd28
--- /dev/null
@@ -0,0 +1,203 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\HelperContainer;
+
+use Behat\Behat\HelperContainer\Exception\ServiceNotFoundException;
+use Behat\Behat\HelperContainer\Exception\WrongServicesConfigurationException;
+use Interop\Container\ContainerInterface;
+use ReflectionClass;
+use ReflectionMethod;
+
+/**
+ * Built-in service container.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class BuiltInServiceContainer implements ContainerInterface
+{
+    /**
+     * @var array
+     */
+    private $schema;
+    /**
+     * @var array
+     */
+    private $instances;
+
+    /**
+     * Initialises container using provided service configuration.
+     *
+     * @param array $schema
+     */
+    public function __construct(array $schema)
+    {
+        $this->schema = $schema;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function has($id)
+    {
+        return array_key_exists($id, $this->schema);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function get($id)
+    {
+        if (!$this->has($id)) {
+            throw new ServiceNotFoundException(
+                sprintf('Service with id `%s` was not defined inside the `services` setting`.', $id),
+                $id
+            );
+        }
+
+        return $this->instances[$id] = isset($this->instances[$id]) ? $this->instances[$id] : $this->createInstance($id);
+    }
+
+    /**
+     * Creates an instance of given service.
+     *
+     * @param string $id
+     *
+     * @return mixed
+     */
+    private function createInstance($id)
+    {
+        $schema = $this->getAndValidateServiceSchema($id);
+
+        $reflection = new ReflectionClass($schema['class']);
+        $arguments = $schema['arguments'];
+
+        if ($factoryMethod = $this->getAndValidateFactoryMethod($reflection, $schema)) {
+            return $factoryMethod->invokeArgs(null, $arguments);
+        }
+
+        return $reflection->newInstanceArgs($arguments);
+    }
+
+    /**
+     * Gets and validates a service configuration for a service with given ID.
+     *
+     * @param string $id
+     *
+     * @throws WrongServicesConfigurationException
+     *
+     * @return array|string
+     */
+    private function getAndValidateServiceSchema($id)
+    {
+        $schema = $this->schema[$id];
+
+        if (null === $schema) {
+            $schema = array('class' => $id);
+        }
+
+        if (is_string($schema)) {
+            $schema = array('class' => $schema);
+        }
+
+        $schema['class'] = $this->getAndValidateClass($id, $schema);
+        $schema['arguments'] = $this->getAndValidateArguments($schema);
+
+        return $schema;
+    }
+
+    /**
+     * Gets and validates a class from schema.
+     *
+     * @param string       $id
+     * @param string|array $schema
+     *
+     * @return string
+     */
+    private function getAndValidateClass($id, array $schema)
+    {
+        if (!isset($schema['class'])) {
+            $schema['class'] = $id;
+        }
+
+        return $schema['class'];
+    }
+
+    /**
+     * Gets and validates arguments from schema.
+     *
+     * @param array $schema
+     *
+     * @return array
+     */
+    private function getAndValidateArguments(array $schema)
+    {
+        return isset($schema['arguments']) ? (array)$schema['arguments'] : array();
+    }
+
+    /**
+     * Gets and validates a factory method.
+     *
+     * @param ReflectionClass $reflection
+     * @param array           $schema
+     *
+     * @return null|ReflectionMethod
+     */
+    private function getAndValidateFactoryMethod(ReflectionClass $reflection, array $schema)
+    {
+        if (!isset($schema['factory_method'])) {
+            return null;
+        }
+
+        $factoryMethod = $schema['factory_method'];
+        $this->assertFactoryMethodExists($reflection, $factoryMethod);
+        $method = $reflection->getMethod($factoryMethod);
+        $this->assertFactoryMethodIsStatic($method);
+
+        return $method;
+    }
+
+    /**
+     * Checks if factory method exists.
+     *
+     * @param ReflectionClass $class
+     * @param string          $methodName
+     *
+     * @throws WrongServicesConfigurationException
+     */
+    private function assertFactoryMethodExists(ReflectionClass $class, $methodName)
+    {
+        if (!$class->hasMethod($methodName)) {
+            throw new WrongServicesConfigurationException(sprintf(
+                'Factory method `%s::%s` does not exist.',
+                $class->getName(),
+                $methodName
+            ));
+        }
+    }
+
+    /**
+     * Checks if factory method is static.
+     *
+     * @param ReflectionMethod $method
+     *
+     * @throws WrongServicesConfigurationException
+     */
+    private function assertFactoryMethodIsStatic(ReflectionMethod $method)
+    {
+        if (!$method->isStatic()) {
+            throw new WrongServicesConfigurationException(sprintf(
+                'Service factory methods must be static, but `%s::%s` is not.',
+                $method->getDeclaringClass()->getName(),
+                $method->getName()
+            ));
+        }
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/HelperContainer/Call/Filter/ServicesResolver.php b/vendor/behat/behat/src/Behat/Behat/HelperContainer/Call/Filter/ServicesResolver.php
new file mode 100644 (file)
index 0000000..0c70fef
--- /dev/null
@@ -0,0 +1,204 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\HelperContainer\Call\Filter;
+
+use Behat\Behat\Definition\Definition;
+use Behat\Behat\HelperContainer\Environment\ServiceContainerEnvironment;
+use Behat\Behat\Definition\Call\DefinitionCall;
+use Behat\Behat\HelperContainer\ArgumentAutowirer;
+use Behat\Behat\HelperContainer\Exception\UnsupportedCallException;
+use Behat\Behat\Transformation\Call\TransformationCall;
+use Behat\Behat\Transformation\Transformation;
+use Behat\Testwork\Call\Call;
+use Behat\Testwork\Call\Filter\CallFilter;
+use Behat\Testwork\Environment\Call\EnvironmentCall;
+use Psr\Container\ContainerExceptionInterface;
+use Psr\Container\ContainerInterface;
+
+/**
+ * Dynamically resolves call arguments using the service container.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class ServicesResolver implements CallFilter
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function supportsCall(Call $call)
+    {
+        return ($call instanceof DefinitionCall || $call instanceof TransformationCall)
+            && $call->getEnvironment() instanceof ServiceContainerEnvironment;
+    }
+
+    /**
+     * Filters a call and returns a new one.
+     *
+     * @param Call $call
+     *
+     * @return Call
+     *
+     * @throws UnsupportedCallException
+     * @throws ContainerExceptionInterface
+     */
+    public function filterCall(Call $call)
+    {
+        if ($container = $this->getContainer($call)) {
+            $autowirer = new ArgumentAutowirer($container);
+            $newArguments = $autowirer->autowireArguments($call->getCallee()->getReflection(), $call->getArguments());
+
+            return $this->repackageCallIfNewArguments($call, $newArguments);
+        }
+
+        return $call;
+    }
+
+    /**
+     * Gets container from the call.
+     *
+     * @param Call $call
+     *
+     * @return null|ContainerInterface
+     *
+     * @throws UnsupportedCallException if given call is not EnvironmentCall or environment is not ServiceContainerEnvironment
+     */
+    private function getContainer(Call $call)
+    {
+        if (!$call instanceof EnvironmentCall) {
+            throw new UnsupportedCallException(sprintf(
+                'ServicesResolver can not filter `%s` call.',
+                get_class($call)
+            ), $call);
+        }
+
+        $environment = $call->getEnvironment();
+
+        if (!$environment instanceof ServiceContainerEnvironment) {
+            throw new UnsupportedCallException(sprintf(
+                'ServicesResolver can not filter `%s` call.',
+                get_class($call)
+            ), $call);
+        }
+
+        return $environment->getServiceContainer();
+    }
+
+    /**
+     * Repackages old calls with new arguments, but only if two differ.
+     *
+     * @param Call $call
+     * @param array $arguments
+     *
+     * @return Call
+     *
+     * @throws UnsupportedCallException if given call is not DefinitionCall or TransformationCall
+     */
+    private function repackageCallIfNewArguments(Call $call, array $arguments)
+    {
+        if ($arguments === $call->getArguments()) {
+            return $call;
+        }
+
+        return $this->repackageCallWithNewArguments($call, $arguments);
+    }
+
+    /**
+     * Repackages old calls with new arguments.
+     *
+     * @param Call  $call
+     * @param array $newArguments
+     *
+     * @return DefinitionCall|TransformationCall
+     *
+     * @throws UnsupportedCallException
+     */
+    private function repackageCallWithNewArguments(Call $call, array $newArguments)
+    {
+        if ($call instanceof DefinitionCall) {
+            return $this->repackageDefinitionCall($call, $newArguments);
+        }
+
+        if ($call instanceof TransformationCall) {
+            return $this->repackageTransformationCall($call, $newArguments);
+        }
+
+        throw new UnsupportedCallException(
+            sprintf(
+                'ServicesResolver can not filter `%s` call.',
+                get_class($call)
+            ), $call
+        );
+    }
+
+    /**
+     * Repackages definition call with new arguments.
+     *
+     * @param DefinitionCall $call
+     * @param array $newArguments
+     *
+     * @return DefinitionCall
+     *
+     * @throws UnsupportedCallException
+     */
+    private function repackageDefinitionCall(DefinitionCall $call, array $newArguments)
+    {
+        $definition = $call->getCallee();
+
+        if (!$definition instanceof Definition) {
+            throw new UnsupportedCallException(
+                sprintf(
+                    'Something is wrong in callee associated with `%s` call.',
+                    get_class($call)
+                ), $call
+            );
+        }
+
+        return new DefinitionCall(
+            $call->getEnvironment(),
+            $call->getFeature(),
+            $call->getStep(),
+            $definition,
+            $newArguments,
+            $call->getErrorReportingLevel()
+        );
+    }
+
+    /**
+     * Repackages transformation call with new arguments.
+     *
+     * @param TransformationCall $call
+     * @param array $newArguments
+     *
+     * @return TransformationCall
+     *
+     * @throws UnsupportedCallException
+     */
+    private function repackageTransformationCall(TransformationCall $call, array $newArguments)
+    {
+        $transformation = $call->getCallee();
+
+        if (!$transformation instanceof Transformation) {
+            throw new UnsupportedCallException(
+                sprintf(
+                    'Something is wrong in callee associated with `%s` call.',
+                    get_class($call)
+                ), $call
+            );
+        }
+
+        return new TransformationCall(
+            $call->getEnvironment(),
+            $call->getDefinition(),
+            $transformation,
+            $newArguments
+        );
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/HelperContainer/Environment/ServiceContainerEnvironment.php b/vendor/behat/behat/src/Behat/Behat/HelperContainer/Environment/ServiceContainerEnvironment.php
new file mode 100644 (file)
index 0000000..8f58ba6
--- /dev/null
@@ -0,0 +1,38 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\HelperContainer\Environment;
+
+use Behat\Testwork\Environment\Environment;
+use Psr\Container\ContainerInterface;
+
+/**
+ * Represents test environment based on a service locator pattern.
+ *
+ * @see ContextEnvironmentHandler
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface ServiceContainerEnvironment extends Environment
+{
+    /**
+     * Sets/unsets service container for the environment.
+     *
+     * @param ContainerInterface|null $container
+     */
+    public function setServiceContainer(ContainerInterface $container = null);
+
+    /**
+     * Returns environment service container if set.
+     *
+     * @return null|ContainerInterface
+     */
+    public function getServiceContainer();
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/HelperContainer/Exception/HelperContainerException.php b/vendor/behat/behat/src/Behat/Behat/HelperContainer/Exception/HelperContainerException.php
new file mode 100644 (file)
index 0000000..04ab35f
--- /dev/null
@@ -0,0 +1,23 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\HelperContainer\Exception;
+
+use Behat\Testwork\Environment\Exception\EnvironmentException;
+use Interop\Container\Exception\ContainerException;
+
+/**
+ * All HelperContainer exceptions implement this interface.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface HelperContainerException extends ContainerException, EnvironmentException
+{
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/HelperContainer/Exception/ServiceNotFoundException.php b/vendor/behat/behat/src/Behat/Behat/HelperContainer/Exception/ServiceNotFoundException.php
new file mode 100644 (file)
index 0000000..02bd601
--- /dev/null
@@ -0,0 +1,50 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\HelperContainer\Exception;
+
+use Interop\Container\Exception\NotFoundException;
+use InvalidArgumentException;
+
+/**
+ * Represents an exception thrown when service ID is not found inside the container.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class ServiceNotFoundException extends InvalidArgumentException implements HelperContainerException, NotFoundException
+{
+    /**
+     * @var string
+     */
+    private $serviceId;
+
+    /**
+     * Initializes exception.
+     *
+     * @param string $message
+     * @param string $serviceId
+     */
+    public function __construct($message, $serviceId)
+    {
+        $this->serviceId = $serviceId;
+
+        parent::__construct($message);
+    }
+
+    /**
+     * Returns service ID that caused exception.
+     *
+     * @return string
+     */
+    public function getServiceId()
+    {
+        return $this->serviceId;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/HelperContainer/Exception/UnsupportedCallException.php b/vendor/behat/behat/src/Behat/Behat/HelperContainer/Exception/UnsupportedCallException.php
new file mode 100644 (file)
index 0000000..7f16ca8
--- /dev/null
@@ -0,0 +1,50 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\HelperContainer\Exception;
+
+use Behat\Testwork\Call\Call;
+use InvalidArgumentException;
+
+/**
+ * Represents an exception caused by an attempt to filter an unsupported call.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class UnsupportedCallException extends InvalidArgumentException implements HelperContainerException
+{
+    /**
+     * @var Call
+     */
+    private $call;
+
+    /**
+     * Initializes exception.
+     *
+     * @param string $message
+     * @param Call   $call
+     */
+    public function __construct($message, Call $call)
+    {
+        parent::__construct($message);
+
+        $this->call = $call;
+    }
+
+    /**
+     * Returns a call that caused exception.
+     *
+     * @return Call
+     */
+    public function getCall()
+    {
+        return $this->call;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/HelperContainer/Exception/WrongContainerClassException.php b/vendor/behat/behat/src/Behat/Behat/HelperContainer/Exception/WrongContainerClassException.php
new file mode 100644 (file)
index 0000000..5dd8321
--- /dev/null
@@ -0,0 +1,49 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\HelperContainer\Exception;
+
+use InvalidArgumentException;
+
+/**
+ * Represents an exception when provided class exists, but is not an acceptable as a container.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class WrongContainerClassException extends InvalidArgumentException implements HelperContainerException
+{
+    /**
+     * @var string
+     */
+    private $class;
+
+    /**
+     * Initializes exception.
+     *
+     * @param integer $message
+     * @param string  $class
+     */
+    public function __construct($message, $class)
+    {
+        $this->class = $class;
+
+        parent::__construct($message);
+    }
+
+    /**
+     * Returns not found classname.
+     *
+     * @return string
+     */
+    public function getClass()
+    {
+        return $this->class;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/HelperContainer/Exception/WrongServicesConfigurationException.php b/vendor/behat/behat/src/Behat/Behat/HelperContainer/Exception/WrongServicesConfigurationException.php
new file mode 100644 (file)
index 0000000..fd65f02
--- /dev/null
@@ -0,0 +1,22 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\HelperContainer\Exception;
+
+use RuntimeException;
+
+/**
+ * Represents an exception when wrong value passed into `services` setting.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class WrongServicesConfigurationException extends RuntimeException implements HelperContainerException
+{
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/HelperContainer/ServiceContainer/HelperContainerExtension.php b/vendor/behat/behat/src/Behat/Behat/HelperContainer/ServiceContainer/HelperContainerExtension.php
new file mode 100644 (file)
index 0000000..1d5100f
--- /dev/null
@@ -0,0 +1,123 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\HelperContainer\ServiceContainer;
+
+use Behat\Behat\Context\ServiceContainer\ContextExtension;
+use Behat\Behat\HelperContainer\Exception\WrongServicesConfigurationException;
+use Behat\Testwork\Call\ServiceContainer\CallExtension;
+use Behat\Testwork\ServiceContainer\Extension;
+use Behat\Testwork\ServiceContainer\ExtensionManager;
+use Behat\Testwork\ServiceContainer\ServiceProcessor;
+use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Definition;
+
+/**
+ * Behat helper container extension.
+ *
+ * Extends Behat with helper containers support.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class HelperContainerExtension implements Extension
+{
+    /*
+     * Available extension points
+     */
+    const HELPER_CONTAINER_TAG = 'helper_container.container';
+
+    /**
+     * @var ServiceProcessor
+     */
+    private $processor;
+
+    /**
+     * Initializes compiler pass.
+     *
+     * @param null|ServiceProcessor $processor
+     */
+    public function __construct(ServiceProcessor $processor = null)
+    {
+        $this->processor = $processor ? : new ServiceProcessor();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getConfigKey()
+    {
+        return 'helper_container';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function initialize(ExtensionManager $extensionManager)
+    {
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function configure(ArrayNodeDefinition $builder)
+    {
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function load(ContainerBuilder $container, array $config)
+    {
+        $definition = new Definition('Behat\Behat\HelperContainer\Argument\ServicesResolverFactory', array($container));
+        $definition->addTag(ContextExtension::SUITE_SCOPED_RESOLVER_FACTORY_TAG, array('priority' => 0));
+        $container->setDefinition(ContextExtension::SUITE_SCOPED_RESOLVER_FACTORY_TAG . '.helper_container', $definition);
+
+        $definition = new Definition('Behat\Behat\HelperContainer\Call\Filter\ServicesResolver');
+        $definition->addTag(CallExtension::CALL_FILTER_TAG, array('priority' => 0));
+        $container->setDefinition(CallExtension::CALL_FILTER_TAG . '.helper_container', $definition);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function process(ContainerBuilder $container)
+    {
+        $references = $this->processor->findAndSortTaggedServices($container, self::HELPER_CONTAINER_TAG);
+
+        foreach ($references as $reference) {
+            if ($this->isDefinitionShared($container->getDefinition((string) $reference))) {
+                throw new WrongServicesConfigurationException(sprintf(
+                    'Container services must not be configured as shared, but `@%s` is.', $reference
+                ));
+            }
+        }
+    }
+
+    /**
+     * Checks if provided definition is shared.
+     *
+     * @param Definition $definition
+     *
+     * @return bool
+     *
+     * @todo Remove after upgrading to Symfony 2.8+
+     */
+    private function isDefinitionShared(Definition $definition)
+    {
+        if (method_exists($definition, 'isShared')) {
+            return $definition->isShared();
+        } else if (method_exists($definition, 'getScope')) {
+            return $definition->getScope() !== ContainerBuilder::SCOPE_PROTOTYPE;
+        }
+
+        return false;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Hook/Call/AfterFeature.php b/vendor/behat/behat/src/Behat/Behat/Hook/Call/AfterFeature.php
new file mode 100644 (file)
index 0000000..9041f1b
--- /dev/null
@@ -0,0 +1,41 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Hook\Call;
+
+use Behat\Behat\Hook\Scope\FeatureScope;
+
+/**
+ * Represents an AfterFeature hook.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class AfterFeature extends RuntimeFeatureHook
+{
+    /**
+     * Initializes hook.
+     *
+     * @param null|string $filterString
+     * @param callable    $callable
+     * @param null|string $description
+     */
+    public function __construct($filterString, $callable, $description = null)
+    {
+        parent::__construct(FeatureScope::AFTER, $filterString, $callable, $description);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getName()
+    {
+        return 'AfterFeature';
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Hook/Call/AfterScenario.php b/vendor/behat/behat/src/Behat/Behat/Hook/Call/AfterScenario.php
new file mode 100644 (file)
index 0000000..70fbaaf
--- /dev/null
@@ -0,0 +1,41 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Hook\Call;
+
+use Behat\Behat\Hook\Scope\ScenarioScope;
+
+/**
+ * Represents an AfterScenario hook.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class AfterScenario extends RuntimeScenarioHook
+{
+    /**
+     * Initializes hook.
+     *
+     * @param null|string $filterString
+     * @param callable    $callable
+     * @param null|string $description
+     */
+    public function __construct($filterString, $callable, $description = null)
+    {
+        parent::__construct(ScenarioScope::AFTER, $filterString, $callable, $description);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getName()
+    {
+        return 'AfterScenario';
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Hook/Call/AfterStep.php b/vendor/behat/behat/src/Behat/Behat/Hook/Call/AfterStep.php
new file mode 100644 (file)
index 0000000..684ef79
--- /dev/null
@@ -0,0 +1,41 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Hook\Call;
+
+use Behat\Behat\Hook\Scope\StepScope;
+
+/**
+ * Represents an AfterStep hook.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class AfterStep extends RuntimeStepHook
+{
+    /**
+     * Initializes hook.
+     *
+     * @param null|string $filterString
+     * @param callable    $callable
+     * @param null|string $description
+     */
+    public function __construct($filterString, $callable, $description = null)
+    {
+        parent::__construct(StepScope::AFTER, $filterString, $callable, $description);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getName()
+    {
+        return 'AfterStep';
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Hook/Call/BeforeFeature.php b/vendor/behat/behat/src/Behat/Behat/Hook/Call/BeforeFeature.php
new file mode 100644 (file)
index 0000000..60e326d
--- /dev/null
@@ -0,0 +1,41 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Hook\Call;
+
+use Behat\Behat\Hook\Scope\FeatureScope;
+
+/**
+ * Represents a BeforeFeature hook.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class BeforeFeature extends RuntimeFeatureHook
+{
+    /**
+     * Initializes hook.
+     *
+     * @param null|string $filterString
+     * @param callable    $callable
+     * @param null|string $description
+     */
+    public function __construct($filterString, $callable, $description = null)
+    {
+        parent::__construct(FeatureScope::BEFORE, $filterString, $callable, $description);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getName()
+    {
+        return 'BeforeFeature';
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Hook/Call/BeforeScenario.php b/vendor/behat/behat/src/Behat/Behat/Hook/Call/BeforeScenario.php
new file mode 100644 (file)
index 0000000..114def0
--- /dev/null
@@ -0,0 +1,41 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Hook\Call;
+
+use Behat\Behat\Hook\Scope\ScenarioScope;
+
+/**
+ * Represents a BeforeScenario hook.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class BeforeScenario extends RuntimeScenarioHook
+{
+    /**
+     * Initializes hook.
+     *
+     * @param null|string $filterString
+     * @param callable    $callable
+     * @param null|string $description
+     */
+    public function __construct($filterString, $callable, $description = null)
+    {
+        parent::__construct(ScenarioScope::BEFORE, $filterString, $callable, $description);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getName()
+    {
+        return 'BeforeScenario';
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Hook/Call/BeforeStep.php b/vendor/behat/behat/src/Behat/Behat/Hook/Call/BeforeStep.php
new file mode 100644 (file)
index 0000000..390f918
--- /dev/null
@@ -0,0 +1,41 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Hook\Call;
+
+use Behat\Behat\Hook\Scope\StepScope;
+
+/**
+ * Represents a BeforeStep hook.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class BeforeStep extends RuntimeStepHook
+{
+    /**
+     * Initializes hook.
+     *
+     * @param null|string $filterString
+     * @param callable    $callable
+     * @param null|string $description
+     */
+    public function __construct($filterString, $callable, $description = null)
+    {
+        parent::__construct(StepScope::BEFORE, $filterString, $callable, $description);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getName()
+    {
+        return 'BeforeStep';
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Hook/Call/RuntimeFeatureHook.php b/vendor/behat/behat/src/Behat/Behat/Hook/Call/RuntimeFeatureHook.php
new file mode 100644 (file)
index 0000000..b3d4fb2
--- /dev/null
@@ -0,0 +1,115 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Hook\Call;
+
+use Behat\Behat\Hook\Scope\FeatureScope;
+use Behat\Gherkin\Filter\NameFilter;
+use Behat\Gherkin\Filter\TagFilter;
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Testwork\Call\Exception\BadCallbackException;
+use Behat\Testwork\Hook\Call\RuntimeFilterableHook;
+use Behat\Testwork\Hook\Scope\HookScope;
+
+/**
+ * Represents a feature hook.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+abstract class RuntimeFeatureHook extends RuntimeFilterableHook
+{
+    /**
+     * Initializes hook.
+     *
+     * @param string      $scopeName
+     * @param null|string $filterString
+     * @param callable    $callable
+     * @param null|string $description
+     *
+     * @throws BadCallbackException If callback is method, but not a static one
+     */
+    public function __construct($scopeName, $filterString, $callable, $description = null)
+    {
+        parent::__construct($scopeName, $filterString, $callable, $description);
+
+        if ($this->isAnInstanceMethod()) {
+            throw new BadCallbackException(sprintf(
+                'Feature hook callback: %s::%s() must be a static method',
+                $callable[0],
+                $callable[1]
+            ), $callable);
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function filterMatches(HookScope $scope)
+    {
+        if (!$scope instanceof FeatureScope) {
+            return false;
+        }
+
+        if (null === ($filterString = $this->getFilterString())) {
+            return true;
+        }
+
+        return $this->isMatch($scope->getFeature(), $filterString);
+    }
+
+    /**
+     * @param FeatureNode $feature
+     * @param string      $filterString
+     *
+     * @return Boolean
+     */
+    private function isMatch(FeatureNode $feature, $filterString)
+    {
+        if (false !== strpos($filterString, '@')) {
+            return $this->isMatchTagFilter($feature, $filterString);
+        }
+
+        if (!empty($filterString)) {
+            return $this->isMatchNameFilter($feature, $filterString);
+        }
+
+        return false;
+    }
+
+    /**
+     * Checks if feature matches tag filter.
+     *
+     * @param FeatureNode $feature
+     * @param string      $filterString
+     *
+     * @return Boolean
+     */
+    private function isMatchTagFilter(FeatureNode $feature, $filterString)
+    {
+        $filter = new TagFilter($filterString);
+
+        return $filter->isFeatureMatch($feature);
+    }
+
+    /**
+     * Checks if feature matches name filter.
+     *
+     * @param FeatureNode $feature
+     * @param string      $filterString
+     *
+     * @return Boolean
+     */
+    private function isMatchNameFilter(FeatureNode $feature, $filterString)
+    {
+        $filter = new NameFilter($filterString);
+
+        return $filter->isFeatureMatch($feature);
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Hook/Call/RuntimeScenarioHook.php b/vendor/behat/behat/src/Behat/Behat/Hook/Call/RuntimeScenarioHook.php
new file mode 100644 (file)
index 0000000..56e25f9
--- /dev/null
@@ -0,0 +1,100 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Hook\Call;
+
+use Behat\Behat\Hook\Scope\ScenarioScope;
+use Behat\Gherkin\Filter\NameFilter;
+use Behat\Gherkin\Filter\TagFilter;
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\ScenarioInterface;
+use Behat\Testwork\Hook\Call\RuntimeFilterableHook;
+use Behat\Testwork\Hook\Scope\HookScope;
+
+/**
+ * Represents a scenario hook.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+abstract class RuntimeScenarioHook extends RuntimeFilterableHook
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function filterMatches(HookScope $scope)
+    {
+        if (!$scope instanceof ScenarioScope) {
+            return false;
+        }
+
+        if (null === ($filterString = $this->getFilterString())) {
+            return true;
+        }
+
+        return $this->isMatch($scope->getFeature(), $scope->getScenario(), $filterString);
+    }
+
+    /**
+     * Checks if nodes match filter.
+     *
+     * @param FeatureNode       $feature
+     * @param ScenarioInterface $scenario
+     * @param string            $filterString
+     *
+     * @return Boolean
+     */
+    protected function isMatch(FeatureNode $feature, ScenarioInterface $scenario, $filterString)
+    {
+        if (false !== strpos($filterString, '@')) {
+            return $this->isMatchTagFilter($feature, $scenario, $filterString);
+        }
+
+        if (!empty($filterString)) {
+            return $this->isMatchNameFilter($scenario, $filterString);
+        }
+
+        return false;
+    }
+
+    /**
+     * Checks if node match tag filter.
+     *
+     * @param FeatureNode       $feature
+     * @param ScenarioInterface $scenario
+     * @param string            $filterString
+     *
+     * @return Boolean
+     */
+    protected function isMatchTagFilter(FeatureNode $feature, ScenarioInterface $scenario, $filterString)
+    {
+        $filter = new TagFilter($filterString);
+
+        if ($filter->isFeatureMatch($feature)) {
+            return true;
+        }
+
+        return $filter->isScenarioMatch($feature, $scenario);
+    }
+
+    /**
+     * Checks if scenario matches name filter.
+     *
+     * @param ScenarioInterface $scenario
+     * @param string            $filterString
+     *
+     * @return Boolean
+     */
+    protected function isMatchNameFilter(ScenarioInterface $scenario, $filterString)
+    {
+        $filter = new NameFilter($filterString);
+
+        return $filter->isScenarioMatch($scenario);
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Hook/Call/RuntimeStepHook.php b/vendor/behat/behat/src/Behat/Behat/Hook/Call/RuntimeStepHook.php
new file mode 100644 (file)
index 0000000..a1326c3
--- /dev/null
@@ -0,0 +1,68 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Hook\Call;
+
+use Behat\Behat\Hook\Scope\StepScope;
+use Behat\Gherkin\Filter\NameFilter;
+use Behat\Gherkin\Node\StepNode;
+use Behat\Testwork\Hook\Call\RuntimeFilterableHook;
+use Behat\Testwork\Hook\Scope\HookScope;
+
+/**
+ * Represents a step hook.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+abstract class RuntimeStepHook extends RuntimeFilterableHook
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function filterMatches(HookScope $scope)
+    {
+        if (!$scope instanceof StepScope) {
+            return false;
+        }
+
+        if (null === ($filterString = $this->getFilterString())) {
+            return true;
+        }
+
+        if (!empty($filterString)) {
+            $filter = new NameFilter($filterString);
+
+            if ($filter->isFeatureMatch($scope->getFeature())) {
+                return true;
+            }
+
+            return $this->isStepMatch($scope->getStep(), $filterString);
+        }
+
+        return false;
+    }
+
+    /**
+     * Checks if Feature matches specified filter.
+     *
+     * @param StepNode $step
+     * @param string   $filterString
+     *
+     * @return Boolean
+     */
+    private function isStepMatch(StepNode $step, $filterString)
+    {
+        if ('/' === $filterString[0]) {
+            return 1 === preg_match($filterString, $step->getText());
+        }
+
+        return false !== mb_strpos($step->getText(), $filterString, 0, 'utf8');
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Hook/Context/Annotation/HookAnnotationReader.php b/vendor/behat/behat/src/Behat/Behat/Hook/Context/Annotation/HookAnnotationReader.php
new file mode 100644 (file)
index 0000000..86a95cc
--- /dev/null
@@ -0,0 +1,65 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Hook\Context\Annotation;
+
+use Behat\Behat\Context\Annotation\AnnotationReader;
+use Behat\Testwork\Hook\Call\RuntimeHook;
+use ReflectionMethod;
+
+/**
+ * Reads hook callees from context method annotations.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class HookAnnotationReader implements AnnotationReader
+{
+    /**
+     * @var string
+     */
+    private static $regex = '/^\@(beforesuite|aftersuite|beforefeature|afterfeature|beforescenario|afterscenario|beforestep|afterstep)(?:\s+(.+))?$/i';
+    /**
+     * @var string[]
+     */
+    private static $classes = array(
+        'beforesuite'    => 'Behat\Testwork\Hook\Call\BeforeSuite',
+        'aftersuite'     => 'Behat\Testwork\Hook\Call\AfterSuite',
+        'beforefeature'  => 'Behat\Behat\Hook\Call\BeforeFeature',
+        'afterfeature'   => 'Behat\Behat\Hook\Call\AfterFeature',
+        'beforescenario' => 'Behat\Behat\Hook\Call\BeforeScenario',
+        'afterscenario'  => 'Behat\Behat\Hook\Call\AfterScenario',
+        'beforestep'     => 'Behat\Behat\Hook\Call\BeforeStep',
+        'afterstep'      => 'Behat\Behat\Hook\Call\AfterStep'
+    );
+
+    /**
+     * Loads step callees (if exist) associated with specific method.
+     *
+     * @param string           $contextClass
+     * @param ReflectionMethod $method
+     * @param string           $docLine
+     * @param string           $description
+     *
+     * @return null|RuntimeHook
+     */
+    public function readCallee($contextClass, ReflectionMethod $method, $docLine, $description)
+    {
+        if (!preg_match(self::$regex, $docLine, $match)) {
+            return null;
+        }
+
+        $type = strtolower($match[1]);
+        $class = self::$classes[$type];
+        $pattern = isset($match[2]) ? $match[2] : null;
+        $callable = array($contextClass, $method->getName());
+
+        return new $class($pattern, $callable, $description);
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Hook/Scope/AfterFeatureScope.php b/vendor/behat/behat/src/Behat/Behat/Hook/Scope/AfterFeatureScope.php
new file mode 100644 (file)
index 0000000..4a321e9
--- /dev/null
@@ -0,0 +1,102 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Hook\Scope;
+
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\Hook\Scope\AfterTestScope;
+use Behat\Testwork\Suite\Suite;
+use Behat\Testwork\Tester\Result\TestResult;
+
+/**
+ * Represents an AfterFeature hook scope.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class AfterFeatureScope implements FeatureScope, AfterTestScope
+{
+    /**
+     * @var Environment
+     */
+    private $environment;
+    /**
+     * @var FeatureNode
+     */
+    private $feature;
+    /**
+     * @var TestResult
+     */
+    private $result;
+
+    /**
+     * Initializes scope.
+     *
+     * @param Environment $env
+     * @param FeatureNode $feature
+     * @param TestResult  $result
+     */
+    public function __construct(Environment $env, FeatureNode $feature, TestResult $result)
+    {
+        $this->environment = $env;
+        $this->feature = $feature;
+        $this->result = $result;
+    }
+
+    /**
+     * Returns hook scope name.
+     *
+     * @return string
+     */
+    public function getName()
+    {
+        return self::AFTER;
+    }
+
+    /**
+     * Returns hook suite.
+     *
+     * @return Suite
+     */
+    public function getSuite()
+    {
+        return $this->environment->getSuite();
+    }
+
+    /**
+     * Returns hook environment.
+     *
+     * @return Environment
+     */
+    public function getEnvironment()
+    {
+        return $this->environment;
+    }
+
+    /**
+     * Returns scope feature.
+     *
+     * @return FeatureNode
+     */
+    public function getFeature()
+    {
+        return $this->feature;
+    }
+
+    /**
+     * Returns test result.
+     *
+     * @return TestResult
+     */
+    public function getTestResult()
+    {
+        return $this->result;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Hook/Scope/AfterScenarioScope.php b/vendor/behat/behat/src/Behat/Behat/Hook/Scope/AfterScenarioScope.php
new file mode 100644 (file)
index 0000000..45985d9
--- /dev/null
@@ -0,0 +1,119 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Hook\Scope;
+
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\ScenarioInterface as Scenario;
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\Hook\Scope\AfterTestScope;
+use Behat\Testwork\Suite\Suite;
+use Behat\Testwork\Tester\Result\TestResult;
+
+/**
+ * Represents an AfterScenario hook scope.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class AfterScenarioScope implements ScenarioScope, AfterTestScope
+{
+    /**
+     * @var Environment
+     */
+    private $environment;
+    /**
+     * @var FeatureNode
+     */
+    private $feature;
+    /**
+     * @var Scenario
+     */
+    private $scenario;
+    /**
+     * @var TestResult
+     */
+    private $result;
+
+    /**
+     * Initializes scope.
+     *
+     * @param Environment $env
+     * @param FeatureNode $feature
+     * @param Scenario    $scenario
+     * @param TestResult  $result
+     */
+    public function __construct(Environment $env, FeatureNode $feature, Scenario $scenario, TestResult $result)
+    {
+        $this->environment = $env;
+        $this->feature = $feature;
+        $this->scenario = $scenario;
+        $this->result = $result;
+    }
+
+    /**
+     * Returns hook scope name.
+     *
+     * @return string
+     */
+    public function getName()
+    {
+        return self::AFTER;
+    }
+
+    /**
+     * Returns hook suite.
+     *
+     * @return Suite
+     */
+    public function getSuite()
+    {
+        return $this->environment->getSuite();
+    }
+
+    /**
+     * Returns hook environment.
+     *
+     * @return Environment
+     */
+    public function getEnvironment()
+    {
+        return $this->environment;
+    }
+
+    /**
+     * Returns scope feature.
+     *
+     * @return FeatureNode
+     */
+    public function getFeature()
+    {
+        return $this->feature;
+    }
+
+    /**
+     * Returns scenario.
+     *
+     * @return Scenario
+     */
+    public function getScenario()
+    {
+        return $this->scenario;
+    }
+
+    /**
+     * Returns test result.
+     *
+     * @return TestResult
+     */
+    public function getTestResult()
+    {
+        return $this->result;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Hook/Scope/AfterStepScope.php b/vendor/behat/behat/src/Behat/Behat/Hook/Scope/AfterStepScope.php
new file mode 100644 (file)
index 0000000..54d63f0
--- /dev/null
@@ -0,0 +1,120 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Hook\Scope;
+
+use Behat\Behat\Tester\Result\StepResult;
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\StepNode;
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\Hook\Scope\AfterTestScope;
+use Behat\Testwork\Suite\Suite;
+use Behat\Testwork\Tester\Result\TestResult;
+
+/**
+ * Represents an AfterStep hook scope.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class AfterStepScope implements StepScope, AfterTestScope
+{
+    /**
+     * @var Environment
+     */
+    private $environment;
+    /**
+     * @var FeatureNode
+     */
+    private $feature;
+    /**
+     * @var StepNode
+     */
+    private $step;
+    /**
+     * @var StepResult
+     */
+    private $result;
+
+    /**
+     * Initializes scope.
+     *
+     * @param Environment $env
+     * @param FeatureNode $feature
+     * @param StepNode    $step
+     * @param StepResult  $result
+     */
+    public function __construct(Environment $env, FeatureNode $feature, StepNode $step, StepResult $result)
+    {
+        $this->environment = $env;
+        $this->feature = $feature;
+        $this->step = $step;
+        $this->result = $result;
+    }
+
+    /**
+     * Returns hook scope name.
+     *
+     * @return string
+     */
+    public function getName()
+    {
+        return self::AFTER;
+    }
+
+    /**
+     * Returns hook suite.
+     *
+     * @return Suite
+     */
+    public function getSuite()
+    {
+        return $this->environment->getSuite();
+    }
+
+    /**
+     * Returns hook environment.
+     *
+     * @return Environment
+     */
+    public function getEnvironment()
+    {
+        return $this->environment;
+    }
+
+    /**
+     * Returns scope feature.
+     *
+     * @return FeatureNode
+     */
+    public function getFeature()
+    {
+        return $this->feature;
+    }
+
+    /**
+     * Returns scope step.
+     *
+     * @return StepNode
+     */
+    public function getStep()
+    {
+        return $this->step;
+    }
+
+    /**
+     * Returns test result.
+     *
+     * @return TestResult
+     */
+    public function getTestResult()
+    {
+        return $this->result;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Hook/Scope/BeforeFeatureScope.php b/vendor/behat/behat/src/Behat/Behat/Hook/Scope/BeforeFeatureScope.php
new file mode 100644 (file)
index 0000000..73254de
--- /dev/null
@@ -0,0 +1,84 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Hook\Scope;
+
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\Suite\Suite;
+
+/**
+ * Represents a BeforeFeature hook scope.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class BeforeFeatureScope implements FeatureScope
+{
+    /**
+     * @var Environment
+     */
+    private $environment;
+    /**
+     * @var FeatureNode
+     */
+    private $feature;
+
+    /**
+     * Initializes scope.
+     *
+     * @param Environment $env
+     * @param FeatureNode $feature
+     */
+    public function __construct(Environment $env, FeatureNode $feature)
+    {
+        $this->environment = $env;
+        $this->feature = $feature;
+    }
+
+    /**
+     * Returns hook scope name.
+     *
+     * @return string
+     */
+    public function getName()
+    {
+        return self::BEFORE;
+    }
+
+    /**
+     * Returns hook suite.
+     *
+     * @return Suite
+     */
+    public function getSuite()
+    {
+        return $this->environment->getSuite();
+    }
+
+    /**
+     * Returns hook environment.
+     *
+     * @return Environment
+     */
+    public function getEnvironment()
+    {
+        return $this->environment;
+    }
+
+    /**
+     * Returns scope feature.
+     *
+     * @return FeatureNode
+     */
+    public function getFeature()
+    {
+        return $this->feature;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Hook/Scope/BeforeScenarioScope.php b/vendor/behat/behat/src/Behat/Behat/Hook/Scope/BeforeScenarioScope.php
new file mode 100644 (file)
index 0000000..af4178e
--- /dev/null
@@ -0,0 +1,101 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Hook\Scope;
+
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\ScenarioInterface as Scenario;
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\Suite\Suite;
+
+/**
+ * Represents a BeforeScenario hook scope.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class BeforeScenarioScope implements ScenarioScope
+{
+    /**
+     * @var Environment
+     */
+    private $environment;
+    /**
+     * @var FeatureNode
+     */
+    private $feature;
+    /**
+     * @var Scenario
+     */
+    private $scenario;
+
+    /**
+     * Initializes scope.
+     *
+     * @param Environment $env
+     * @param FeatureNode $feature
+     * @param Scenario    $scenario
+     */
+    public function __construct(Environment $env, FeatureNode $feature, Scenario $scenario)
+    {
+        $this->environment = $env;
+        $this->feature = $feature;
+        $this->scenario = $scenario;
+    }
+
+    /**
+     * Returns hook scope name.
+     *
+     * @return string
+     */
+    public function getName()
+    {
+        return self::BEFORE;
+    }
+
+    /**
+     * Returns hook suite.
+     *
+     * @return Suite
+     */
+    public function getSuite()
+    {
+        return $this->environment->getSuite();
+    }
+
+    /**
+     * Returns hook environment.
+     *
+     * @return Environment
+     */
+    public function getEnvironment()
+    {
+        return $this->environment;
+    }
+
+    /**
+     * Returns scope feature.
+     *
+     * @return FeatureNode
+     */
+    public function getFeature()
+    {
+        return $this->feature;
+    }
+
+    /**
+     * Returns scenario.
+     *
+     * @return Scenario
+     */
+    public function getScenario()
+    {
+        return $this->scenario;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Hook/Scope/BeforeStepScope.php b/vendor/behat/behat/src/Behat/Behat/Hook/Scope/BeforeStepScope.php
new file mode 100644 (file)
index 0000000..72e1cad
--- /dev/null
@@ -0,0 +1,101 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Hook\Scope;
+
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\StepNode;
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\Suite\Suite;
+
+/**
+ * Represents a BeforeStep hook scope.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class BeforeStepScope implements StepScope
+{
+    /**
+     * @var Environment
+     */
+    private $environment;
+    /**
+     * @var FeatureNode
+     */
+    private $feature;
+    /**
+     * @var StepNode
+     */
+    private $step;
+
+    /**
+     * Initializes scope.
+     *
+     * @param Environment $env
+     * @param FeatureNode $feature
+     * @param StepNode    $step
+     */
+    public function __construct(Environment $env, FeatureNode $feature, StepNode $step)
+    {
+        $this->environment = $env;
+        $this->feature = $feature;
+        $this->step = $step;
+    }
+
+    /**
+     * Returns hook scope name.
+     *
+     * @return string
+     */
+    public function getName()
+    {
+        return self::BEFORE;
+    }
+
+    /**
+     * Returns hook suite.
+     *
+     * @return Suite
+     */
+    public function getSuite()
+    {
+        return $this->environment->getSuite();
+    }
+
+    /**
+     * Returns hook environment.
+     *
+     * @return Environment
+     */
+    public function getEnvironment()
+    {
+        return $this->environment;
+    }
+
+    /**
+     * Returns scope feature.
+     *
+     * @return FeatureNode
+     */
+    public function getFeature()
+    {
+        return $this->feature;
+    }
+
+    /**
+     * Returns scope step.
+     *
+     * @return StepNode
+     */
+    public function getStep()
+    {
+        return $this->step;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Hook/Scope/FeatureScope.php b/vendor/behat/behat/src/Behat/Behat/Hook/Scope/FeatureScope.php
new file mode 100644 (file)
index 0000000..fe87469
--- /dev/null
@@ -0,0 +1,32 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Hook\Scope;
+
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Testwork\Hook\Scope\HookScope;
+
+/**
+ * Represents a feature hook scope.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface FeatureScope extends HookScope
+{
+    const BEFORE = 'feature.before';
+    const AFTER = 'feature.after';
+
+    /**
+     * Returns scope feature.
+     *
+     * @return FeatureNode
+     */
+    public function getFeature();
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Hook/Scope/ScenarioScope.php b/vendor/behat/behat/src/Behat/Behat/Hook/Scope/ScenarioScope.php
new file mode 100644 (file)
index 0000000..c5238bc
--- /dev/null
@@ -0,0 +1,40 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Hook\Scope;
+
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\ScenarioInterface as Scenario;
+use Behat\Testwork\Hook\Scope\HookScope;
+
+/**
+ * Represents a scenario hook scope.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface ScenarioScope extends HookScope
+{
+    const BEFORE = 'scenario.before';
+    const AFTER = 'scenario.after';
+
+    /**
+     * Returns scope feature.
+     *
+     * @return FeatureNode
+     */
+    public function getFeature();
+
+    /**
+     * Returns scenario.
+     *
+     * @return Scenario
+     */
+    public function getScenario();
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Hook/Scope/StepScope.php b/vendor/behat/behat/src/Behat/Behat/Hook/Scope/StepScope.php
new file mode 100644 (file)
index 0000000..c07a79b
--- /dev/null
@@ -0,0 +1,40 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Hook\Scope;
+
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\StepNode;
+use Behat\Testwork\Hook\Scope\HookScope;
+
+/**
+ * Represents a step hook scope.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface StepScope extends HookScope
+{
+    const BEFORE = 'step.before';
+    const AFTER = 'step.after';
+
+    /**
+     * Returns scope feature.
+     *
+     * @return FeatureNode
+     */
+    public function getFeature();
+
+    /**
+     * Returns scope step.
+     *
+     * @return StepNode
+     */
+    public function getStep();
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Hook/ServiceContainer/HookExtension.php b/vendor/behat/behat/src/Behat/Behat/Hook/ServiceContainer/HookExtension.php
new file mode 100644 (file)
index 0000000..76d4be9
--- /dev/null
@@ -0,0 +1,88 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Hook\ServiceContainer;
+
+use Behat\Behat\Context\ServiceContainer\ContextExtension;
+use Behat\Behat\Tester\ServiceContainer\TesterExtension;
+use Behat\Testwork\Hook\ServiceContainer\HookExtension as BaseExtension;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Definition;
+use Symfony\Component\DependencyInjection\Reference;
+
+/**
+ * Extends Testwork HookExtension with additional behat services.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class HookExtension extends BaseExtension
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function load(ContainerBuilder $container, array $config)
+    {
+        parent::load($container, $config);
+
+        $this->loadAnnotationReader($container);
+    }
+
+    /**
+     * Loads hookable testers.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function loadHookableTesters(ContainerBuilder $container)
+    {
+        parent::loadHookableTesters($container);
+
+        $definition = new Definition('Behat\Behat\Hook\Tester\HookableFeatureTester', array(
+            new Reference(TesterExtension::SPECIFICATION_TESTER_ID),
+            new Reference(self::DISPATCHER_ID)
+        ));
+        $definition->addTag(TesterExtension::SPECIFICATION_TESTER_WRAPPER_TAG, array('priority' => 9999));
+        $container->setDefinition(TesterExtension::SPECIFICATION_TESTER_WRAPPER_TAG . '.hookable', $definition);
+
+        $definition = new Definition('Behat\Behat\Hook\Tester\HookableScenarioTester', array(
+                new Reference(TesterExtension::SCENARIO_TESTER_ID),
+                new Reference(self::DISPATCHER_ID)
+            )
+        );
+        $definition->addTag(TesterExtension::SCENARIO_TESTER_WRAPPER_TAG, array('priority' => 9999));
+        $container->setDefinition(TesterExtension::SCENARIO_TESTER_WRAPPER_TAG . '.hookable', $definition);
+
+        $definition = new Definition('Behat\Behat\Hook\Tester\HookableScenarioTester', array(
+                new Reference(TesterExtension::EXAMPLE_TESTER_ID),
+                new Reference(self::DISPATCHER_ID)
+            )
+        );
+        $definition->addTag(TesterExtension::EXAMPLE_TESTER_WRAPPER_TAG, array('priority' => 9999));
+        $container->setDefinition(TesterExtension::EXAMPLE_TESTER_WRAPPER_TAG . '.hookable', $definition);
+
+        $definition = new Definition('Behat\Behat\Hook\Tester\HookableStepTester', array(
+            new Reference(TesterExtension::STEP_TESTER_ID),
+            new Reference(self::DISPATCHER_ID)
+        ));
+        $definition->addTag(TesterExtension::STEP_TESTER_WRAPPER_TAG, array('priority' => 9999));
+        $container->setDefinition(TesterExtension::STEP_TESTER_WRAPPER_TAG . '.hookable', $definition);
+    }
+
+    /**
+     * Loads hook annotation reader.
+     *
+     * @param ContainerBuilder $container
+     */
+    private function loadAnnotationReader(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Behat\Hook\Context\Annotation\HookAnnotationReader');
+        $definition->addTag(ContextExtension::ANNOTATION_READER_TAG, array('priority' => 50));
+        $container->setDefinition(ContextExtension::ANNOTATION_READER_TAG . '.hook', $definition);
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Hook/Tester/HookableFeatureTester.php b/vendor/behat/behat/src/Behat/Behat/Hook/Tester/HookableFeatureTester.php
new file mode 100644 (file)
index 0000000..288c6c0
--- /dev/null
@@ -0,0 +1,91 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Hook\Tester;
+
+use Behat\Behat\Hook\Scope\AfterFeatureScope;
+use Behat\Behat\Hook\Scope\BeforeFeatureScope;
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\Hook\HookDispatcher;
+use Behat\Testwork\Hook\Tester\Setup\HookedSetup;
+use Behat\Testwork\Hook\Tester\Setup\HookedTeardown;
+use Behat\Testwork\Tester\Result\TestResult;
+use Behat\Testwork\Tester\SpecificationTester;
+
+/**
+ * Feature tester which dispatches hooks during its execution.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class HookableFeatureTester implements SpecificationTester
+{
+    /**
+     * @var SpecificationTester
+     */
+    private $baseTester;
+    /**
+     * @var HookDispatcher
+     */
+    private $hookDispatcher;
+
+    /**
+     * Initializes tester.
+     *
+     * @param SpecificationTester $baseTester
+     * @param HookDispatcher      $hookDispatcher
+     */
+    public function __construct(SpecificationTester $baseTester, HookDispatcher $hookDispatcher)
+    {
+        $this->baseTester = $baseTester;
+        $this->hookDispatcher = $hookDispatcher;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setUp(Environment $env, $spec, $skip)
+    {
+        $setup = $this->baseTester->setUp($env, $spec, $skip);
+
+        if ($skip) {
+            return $setup;
+        }
+
+        $scope = new BeforeFeatureScope($env, $spec);
+        $hookCallResults = $this->hookDispatcher->dispatchScopeHooks($scope);
+
+        return new HookedSetup($setup, $hookCallResults);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function test(Environment $env, $spec, $skip)
+    {
+        return $this->baseTester->test($env, $spec, $skip);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function tearDown(Environment $env, $spec, $skip, TestResult $result)
+    {
+        $teardown = $this->baseTester->tearDown($env, $spec, $skip, $result);
+
+        if ($skip) {
+            return $teardown;
+        }
+
+        $scope = new AfterFeatureScope($env, $spec, $result);
+        $hookCallResults = $this->hookDispatcher->dispatchScopeHooks($scope);
+
+        return new HookedTeardown($teardown, $hookCallResults);
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Hook/Tester/HookableScenarioTester.php b/vendor/behat/behat/src/Behat/Behat/Hook/Tester/HookableScenarioTester.php
new file mode 100644 (file)
index 0000000..2ec0c06
--- /dev/null
@@ -0,0 +1,93 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Hook\Tester;
+
+use Behat\Behat\Hook\Scope\AfterScenarioScope;
+use Behat\Behat\Hook\Scope\BeforeScenarioScope;
+use Behat\Behat\Tester\ScenarioTester;
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\ScenarioInterface as Scenario;
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\Hook\HookDispatcher;
+use Behat\Testwork\Hook\Tester\Setup\HookedSetup;
+use Behat\Testwork\Hook\Tester\Setup\HookedTeardown;
+use Behat\Testwork\Tester\Result\TestResult;
+
+/**
+ * Scenario tester which dispatches hooks during its execution.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class HookableScenarioTester implements ScenarioTester
+{
+    /**
+     * @var ScenarioTester
+     */
+    private $baseTester;
+    /**
+     * @var HookDispatcher
+     */
+    private $hookDispatcher;
+
+    /**
+     * Initializes tester.
+     *
+     * @param ScenarioTester $baseTester
+     * @param HookDispatcher $hookDispatcher
+     */
+    public function __construct(ScenarioTester $baseTester, HookDispatcher $hookDispatcher)
+    {
+        $this->baseTester = $baseTester;
+        $this->hookDispatcher = $hookDispatcher;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setUp(Environment $env, FeatureNode $feature, Scenario $scenario, $skip)
+    {
+        $setup = $this->baseTester->setUp($env, $feature, $scenario, $skip);
+
+        if ($skip) {
+            return $setup;
+        }
+
+        $scope = new BeforeScenarioScope($env, $feature, $scenario);
+        $hookCallResults = $this->hookDispatcher->dispatchScopeHooks($scope);
+
+        return new HookedSetup($setup, $hookCallResults);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function test(Environment $env, FeatureNode $feature, Scenario $scenario, $skip)
+    {
+        return $this->baseTester->test($env, $feature, $scenario, $skip);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function tearDown(Environment $env, FeatureNode $feature, Scenario $scenario, $skip, TestResult $result)
+    {
+        $teardown = $this->baseTester->tearDown($env, $feature, $scenario, $skip, $result);
+
+        if ($skip) {
+            return $teardown;
+        }
+
+        $scope = new AfterScenarioScope($env, $feature, $scenario, $result);
+        $hookCallResults = $this->hookDispatcher->dispatchScopeHooks($scope);
+
+        return new HookedTeardown($teardown, $hookCallResults);
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Hook/Tester/HookableStepTester.php b/vendor/behat/behat/src/Behat/Behat/Hook/Tester/HookableStepTester.php
new file mode 100644 (file)
index 0000000..590d1f5
--- /dev/null
@@ -0,0 +1,93 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Hook\Tester;
+
+use Behat\Behat\Hook\Scope\AfterStepScope;
+use Behat\Behat\Hook\Scope\BeforeStepScope;
+use Behat\Behat\Tester\Result\StepResult;
+use Behat\Behat\Tester\StepTester;
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\StepNode;
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\Hook\HookDispatcher;
+use Behat\Testwork\Hook\Tester\Setup\HookedSetup;
+use Behat\Testwork\Hook\Tester\Setup\HookedTeardown;
+
+/**
+ * Step tester which dispatches hooks during its execution.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class HookableStepTester implements StepTester
+{
+    /**
+     * @var StepTester
+     */
+    private $baseTester;
+    /**
+     * @var HookDispatcher
+     */
+    private $hookDispatcher;
+
+    /**
+     * Initializes tester.
+     *
+     * @param StepTester     $baseTester
+     * @param HookDispatcher $hookDispatcher
+     */
+    public function __construct(StepTester $baseTester, HookDispatcher $hookDispatcher)
+    {
+        $this->baseTester = $baseTester;
+        $this->hookDispatcher = $hookDispatcher;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setUp(Environment $env, FeatureNode $feature, StepNode $step, $skip)
+    {
+        $setup = $this->baseTester->setUp($env, $feature, $step, $skip);
+
+        if ($skip) {
+            return $setup;
+        }
+
+        $scope = new BeforeStepScope($env, $feature, $step);
+        $hookCallResults = $this->hookDispatcher->dispatchScopeHooks($scope);
+
+        return new HookedSetup($setup, $hookCallResults);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function test(Environment $env, FeatureNode $feature, StepNode $step, $skip)
+    {
+        return $this->baseTester->test($env, $feature, $step, $skip);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function tearDown(Environment $env, FeatureNode $feature, StepNode $step, $skip, StepResult $result)
+    {
+        $teardown = $this->baseTester->tearDown($env, $feature, $step, $skip, $result);
+
+        if ($skip) {
+            return $teardown;
+        }
+
+        $scope = new AfterStepScope($env, $feature, $step, $result);
+        $hookCallResults = $this->hookDispatcher->dispatchScopeHooks($scope);
+
+        return new HookedTeardown($teardown, $hookCallResults);
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Output/Exception/NodeVisitorNotFoundException.php b/vendor/behat/behat/src/Behat/Behat/Output/Exception/NodeVisitorNotFoundException.php
new file mode 100644 (file)
index 0000000..5493bd6
--- /dev/null
@@ -0,0 +1,23 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Output\Exception;
+
+use Behat\Testwork\Output\Exception\OutputException;
+use InvalidArgumentException;
+
+/**
+ * Represents an exception caused by a request for non-existent node visitor.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class NodeVisitorNotFoundException extends InvalidArgumentException implements OutputException
+{
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Output/Node/EventListener/AST/FeatureListener.php b/vendor/behat/behat/src/Behat/Behat/Output/Node/EventListener/AST/FeatureListener.php
new file mode 100644 (file)
index 0000000..13bc0a4
--- /dev/null
@@ -0,0 +1,94 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Output\Node\EventListener\AST;
+
+use Behat\Behat\EventDispatcher\Event\AfterFeatureSetup;
+use Behat\Behat\EventDispatcher\Event\AfterFeatureTested;
+use Behat\Behat\EventDispatcher\Event\FeatureTested;
+use Behat\Behat\Output\Node\Printer\FeaturePrinter;
+use Behat\Behat\Output\Node\Printer\SetupPrinter;
+use Behat\Testwork\Output\Formatter;
+use Behat\Testwork\Output\Node\EventListener\EventListener;
+use Symfony\Component\EventDispatcher\Event;
+
+/**
+ * Listens to feature events and calls appropriate printers.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class FeatureListener implements EventListener
+{
+    /**
+     * @var FeaturePrinter
+     */
+    private $featurePrinter;
+    /**
+     * @var SetupPrinter
+     */
+    private $setupPrinter;
+
+    /**
+     * Initializes listener.
+     *
+     * @param FeaturePrinter $featurePrinter
+     * @param SetupPrinter   $setupPrinter
+     */
+    public function __construct(FeaturePrinter $featurePrinter, SetupPrinter $setupPrinter)
+    {
+        $this->featurePrinter = $featurePrinter;
+        $this->setupPrinter = $setupPrinter;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function listenEvent(Formatter $formatter, Event $event, $eventName)
+    {
+        if (!$event instanceof FeatureTested) {
+            return;
+        }
+
+        $this->printHeaderOnBeforeEvent($formatter, $event);
+        $this->printFooterOnAfterEvent($formatter, $event);
+    }
+
+    /**
+     * Prints feature header on BEFORE event.
+     *
+     * @param Formatter $formatter
+     * @param Event     $event
+     */
+    private function printHeaderOnBeforeEvent(Formatter $formatter, Event $event)
+    {
+        if (!$event instanceof AfterFeatureSetup) {
+            return;
+        }
+
+        $this->setupPrinter->printSetup($formatter, $event->getSetup());
+        $this->featurePrinter->printHeader($formatter, $event->getFeature());
+    }
+
+    /**
+     * Prints feature footer on AFTER event.
+     *
+     * @param Formatter $formatter
+     * @param Event     $event
+     */
+    private function printFooterOnAfterEvent(Formatter $formatter, Event $event)
+    {
+        if (!$event instanceof AfterFeatureTested) {
+            return;
+        }
+
+        $this->setupPrinter->printTeardown($formatter, $event->getTeardown());
+        $this->featurePrinter->printFooter($formatter, $event->getTestResult());
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Output/Node/EventListener/AST/OutlineListener.php b/vendor/behat/behat/src/Behat/Behat/Output/Node/EventListener/AST/OutlineListener.php
new file mode 100644 (file)
index 0000000..bacb12f
--- /dev/null
@@ -0,0 +1,194 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Output\Node\EventListener\AST;
+
+use Behat\Behat\EventDispatcher\Event\AfterOutlineTested;
+use Behat\Behat\EventDispatcher\Event\AfterScenarioSetup;
+use Behat\Behat\EventDispatcher\Event\AfterScenarioTested;
+use Behat\Behat\EventDispatcher\Event\AfterStepSetup;
+use Behat\Behat\EventDispatcher\Event\AfterStepTested;
+use Behat\Behat\EventDispatcher\Event\BeforeOutlineTested;
+use Behat\Behat\EventDispatcher\Event\ExampleTested;
+use Behat\Behat\Output\Node\Printer\ExamplePrinter;
+use Behat\Behat\Output\Node\Printer\OutlinePrinter;
+use Behat\Behat\Output\Node\Printer\SetupPrinter;
+use Behat\Behat\Output\Node\Printer\StepPrinter;
+use Behat\Gherkin\Node\ExampleNode;
+use Behat\Testwork\Output\Formatter;
+use Behat\Testwork\Output\Node\EventListener\EventListener;
+use Symfony\Component\EventDispatcher\Event;
+
+/**
+ * Listens to expanded outline events and calls appropriate printers.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class OutlineListener implements EventListener
+{
+    /**
+     * @var OutlinePrinter
+     */
+    private $outlinePrinter;
+    /**
+     * @var ExamplePrinter
+     */
+    private $examplePrinter;
+    /**
+     * @var StepPrinter
+     */
+    private $stepPrinter;
+    /**
+     * @var SetupPrinter
+     */
+    private $stepSetupPrinter;
+    /**
+     * @var SetupPrinter
+     */
+    private $exampleSetupPrinter;
+    /**
+     * @var ExampleNode
+     */
+    private $example;
+
+    /**
+     * Initializes listener.
+     *
+     * @param OutlinePrinter $outlinePrinter
+     * @param ExamplePrinter $examplePrinter
+     * @param StepPrinter    $stepPrinter
+     * @param SetupPrinter   $exampleSetupPrinter
+     * @param SetupPrinter   $stepSetupPrinter
+     */
+    public function __construct(
+        OutlinePrinter $outlinePrinter,
+        ExamplePrinter $examplePrinter,
+        StepPrinter $stepPrinter,
+        SetupPrinter $exampleSetupPrinter,
+        SetupPrinter $stepSetupPrinter
+    ) {
+        $this->outlinePrinter = $outlinePrinter;
+        $this->examplePrinter = $examplePrinter;
+        $this->stepPrinter = $stepPrinter;
+        $this->exampleSetupPrinter = $exampleSetupPrinter;
+        $this->stepSetupPrinter = $stepSetupPrinter;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function listenEvent(Formatter $formatter, Event $event, $eventName)
+    {
+        $this->printAndCaptureOutlineHeaderOnBeforeEvent($formatter, $event);
+        $this->printAndForgetOutlineFooterOnAfterEvent($formatter, $event);
+        $this->printExampleHeaderOnBeforeExampleEvent($formatter, $event);
+        $this->printExampleFooterOnAfterExampleEvent($formatter, $event, $eventName);
+        $this->printStepSetupOnBeforeStepEvent($formatter, $event);
+        $this->printStepOnAfterStepEvent($formatter, $event);
+    }
+
+    /**
+     * Prints outline header and captures outline into ivar on BEFORE event.
+     *
+     * @param Formatter $formatter
+     * @param Event     $event
+     */
+    private function printAndCaptureOutlineHeaderOnBeforeEvent(Formatter $formatter, Event $event)
+    {
+        if (!$event instanceof BeforeOutlineTested) {
+            return;
+        }
+
+        $this->outlinePrinter->printHeader($formatter, $event->getFeature(), $event->getOutline());
+    }
+
+    /**
+     * Prints outline footer and removes outline from ivar on AFTER event.
+     *
+     * @param Formatter $formatter
+     * @param Event     $event
+     */
+    private function printAndForgetOutlineFooterOnAfterEvent(Formatter $formatter, Event $event)
+    {
+        if (!$event instanceof AfterOutlineTested) {
+            return;
+        }
+
+        $this->outlinePrinter->printFooter($formatter, $event->getTestResult());
+    }
+
+    /**
+     * Prints example header on example BEFORE event.
+     *
+     * @param Formatter $formatter
+     * @param Event     $event
+     */
+    private function printExampleHeaderOnBeforeExampleEvent(Formatter $formatter, Event $event)
+    {
+        if (!$event instanceof AfterScenarioSetup) {
+            return;
+        }
+
+        $this->example = $event->getScenario();
+
+        $this->exampleSetupPrinter->printSetup($formatter, $event->getSetup());
+        $this->examplePrinter->printHeader($formatter, $event->getFeature(), $this->example);
+    }
+
+    /**
+     * Prints example footer on example AFTER event.
+     *
+     * @param Formatter $formatter
+     * @param Event     $event
+     * @param string    $eventName
+     */
+    private function printExampleFooterOnAfterExampleEvent(Formatter $formatter, Event $event, $eventName)
+    {
+        if (!$event instanceof AfterScenarioTested || ExampleTested::AFTER !== $eventName) {
+            return;
+        }
+
+        $this->examplePrinter->printFooter($formatter, $event->getTestResult());
+        $this->exampleSetupPrinter->printTeardown($formatter, $event->getTeardown());
+
+        $this->example = null;
+    }
+
+    /**
+     * Prints step setup on step BEFORE event.
+     *
+     * @param Formatter $formatter
+     * @param Event     $event
+     */
+    private function printStepSetupOnBeforeStepEvent(Formatter $formatter, Event $event)
+    {
+        if (!$event instanceof AfterStepSetup) {
+            return;
+        }
+
+        $this->stepSetupPrinter->printSetup($formatter, $event->getSetup());
+    }
+
+    /**
+     * Prints example step on step AFTER event.
+     *
+     * @param Formatter $formatter
+     * @param Event     $event
+     */
+    private function printStepOnAfterStepEvent(Formatter $formatter, Event $event)
+    {
+        if (!$event instanceof AfterStepTested) {
+            return;
+        }
+
+        $this->stepPrinter->printStep($formatter, $this->example, $event->getStep(), $event->getTestResult());
+        $this->stepSetupPrinter->printTeardown($formatter, $event->getTeardown());
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Output/Node/EventListener/AST/OutlineTableListener.php b/vendor/behat/behat/src/Behat/Behat/Output/Node/EventListener/AST/OutlineTableListener.php
new file mode 100644 (file)
index 0000000..fa77da4
--- /dev/null
@@ -0,0 +1,260 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Output\Node\EventListener\AST;
+
+use Behat\Behat\EventDispatcher\Event\AfterOutlineTested;
+use Behat\Behat\EventDispatcher\Event\AfterScenarioSetup;
+use Behat\Behat\EventDispatcher\Event\AfterScenarioTested;
+use Behat\Behat\EventDispatcher\Event\AfterStepSetup;
+use Behat\Behat\EventDispatcher\Event\AfterStepTested;
+use Behat\Behat\EventDispatcher\Event\BeforeOutlineTested;
+use Behat\Behat\EventDispatcher\Event\ExampleTested;
+use Behat\Behat\EventDispatcher\Event\OutlineTested;
+use Behat\Behat\EventDispatcher\Event\StepTested;
+use Behat\Behat\Output\Node\Printer\ExampleRowPrinter;
+use Behat\Behat\Output\Node\Printer\OutlineTablePrinter;
+use Behat\Behat\Output\Node\Printer\SetupPrinter;
+use Behat\Behat\Tester\Result\StepResult;
+use Behat\Gherkin\Node\OutlineNode;
+use Behat\Testwork\Output\Formatter;
+use Behat\Testwork\Output\Node\EventListener\EventListener;
+use Behat\Testwork\Tester\Setup\Setup;
+use Symfony\Component\EventDispatcher\Event;
+
+/**
+ * Listens to outline table events and calls appropriate printers.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class OutlineTableListener implements EventListener
+{
+    /**
+     * @var OutlineTablePrinter
+     */
+    private $tablePrinter;
+    /**
+     * @var ExampleRowPrinter
+     */
+    private $exampleRowPrinter;
+    /**
+     * @var SetupPrinter
+     */
+    private $stepSetupPrinter;
+    /**
+     * @var SetupPrinter
+     */
+    private $exampleSetupPrinter;
+    /**
+     * @var OutlineNode
+     */
+    private $outline;
+    /**
+     * @var Setup
+     */
+    private $exampleSetup;
+    /**
+     * @var Boolean
+     */
+    private $headerPrinted = false;
+    /**
+     * @var AfterStepSetup[]
+     */
+    private $stepBeforeTestedEvents = array();
+    /**
+     * @var AfterStepTested[]
+     */
+    private $stepAfterTestedEvents = array();
+
+    /**
+     * Initializes listener.
+     *
+     * @param OutlineTablePrinter $tablePrinter
+     * @param ExampleRowPrinter   $exampleRowPrinter
+     * @param SetupPrinter        $exampleSetupPrinter
+     * @param SetupPrinter        $stepSetupPrinter
+     */
+    public function __construct(
+        OutlineTablePrinter $tablePrinter,
+        ExampleRowPrinter $exampleRowPrinter,
+        SetupPrinter $exampleSetupPrinter,
+        SetupPrinter $stepSetupPrinter
+    ) {
+        $this->tablePrinter = $tablePrinter;
+        $this->exampleRowPrinter = $exampleRowPrinter;
+        $this->exampleSetupPrinter = $exampleSetupPrinter;
+        $this->stepSetupPrinter = $stepSetupPrinter;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function listenEvent(Formatter $formatter, Event $event, $eventName)
+    {
+        if ($event instanceof StepTested) {
+            $this->captureStepEvent($event);
+
+            return;
+        }
+
+        $this->captureOutlineOnBeforeOutlineEvent($event);
+        $this->forgetOutlineOnAfterOutlineEvent($eventName);
+        $this->captureExampleSetupOnBeforeEvent($event);
+
+        $this->printHeaderOnAfterExampleEvent($formatter, $event, $eventName);
+        $this->printExampleRowOnAfterExampleEvent($formatter, $event, $eventName);
+        $this->printFooterOnAfterEvent($formatter, $event);
+    }
+
+    /**
+     * Captures step tested event.
+     *
+     * @param StepTested $event
+     */
+    private function captureStepEvent(StepTested $event)
+    {
+        if ($event instanceof AfterStepSetup) {
+            $this->stepBeforeTestedEvents[$event->getStep()->getLine()] = $event;
+        } else {
+            $this->stepAfterTestedEvents[$event->getStep()->getLine()] = $event;
+        }
+    }
+
+    /**
+     * Captures outline into the ivar on outline BEFORE event.
+     *
+     * @param Event $event
+     */
+    private function captureOutlineOnBeforeOutlineEvent(Event $event)
+    {
+        if (!$event instanceof BeforeOutlineTested) {
+            return;
+        }
+
+        $this->outline = $event->getOutline();
+        $this->headerPrinted = false;
+    }
+
+    /**
+     * Captures example setup on example BEFORE event.
+     *
+     * @param Event $event
+     */
+    private function captureExampleSetupOnBeforeEvent(Event $event)
+    {
+        if (!$event instanceof AfterScenarioSetup) {
+            return;
+        }
+
+        $this->exampleSetup = $event->getSetup();
+    }
+
+    /**
+     * Removes outline from the ivar on outline AFTER event.
+     *
+     * @param string $eventName
+     */
+    private function forgetOutlineOnAfterOutlineEvent($eventName)
+    {
+        if (OutlineTested::AFTER !== $eventName) {
+            return;
+        }
+
+        $this->outline = null;
+    }
+
+    /**
+     * Prints outline header (if has not been printed yet) on example AFTER event.
+     *
+     * @param Formatter $formatter
+     * @param Event     $event
+     * @param string    $eventName
+     */
+    private function printHeaderOnAfterExampleEvent(Formatter $formatter, Event $event, $eventName)
+    {
+        if (!$event instanceof AfterScenarioTested || ExampleTested::AFTER !== $eventName) {
+            return;
+        }
+
+        if ($this->headerPrinted) {
+            return;
+        }
+
+        $feature = $event->getFeature();
+        $stepTestResults = $this->getStepTestResults();
+
+        $this->tablePrinter->printHeader($formatter, $feature, $this->outline, $stepTestResults);
+        $this->headerPrinted = true;
+    }
+
+    /**
+     * Prints example row on example AFTER event.
+     *
+     * @param Formatter $formatter
+     * @param Event     $event
+     * @param string    $eventName
+     */
+    private function printExampleRowOnAfterExampleEvent(Formatter $formatter, Event $event, $eventName)
+    {
+        if (!$event instanceof AfterScenarioTested || ExampleTested::AFTER !== $eventName) {
+            return;
+        }
+
+        $example = $event->getScenario();
+
+        $this->exampleSetupPrinter->printSetup($formatter, $this->exampleSetup);
+
+        foreach ($this->stepBeforeTestedEvents as $beforeEvent) {
+            $this->stepSetupPrinter->printSetup($formatter, $beforeEvent->getSetup());
+        }
+
+        $this->exampleRowPrinter->printExampleRow($formatter, $this->outline, $example, $this->stepAfterTestedEvents);
+
+        foreach ($this->stepAfterTestedEvents as $afterEvent) {
+            $this->stepSetupPrinter->printTeardown($formatter, $afterEvent->getTeardown());
+        }
+
+        $this->exampleSetupPrinter->printTeardown($formatter, $event->getTeardown());
+
+        $this->exampleSetup = null;
+        $this->stepBeforeTestedEvents = array();
+        $this->stepAfterTestedEvents = array();
+    }
+
+    /**
+     * Prints outline footer on outline AFTER event.
+     *
+     * @param Formatter $formatter
+     * @param Event     $event
+     */
+    private function printFooterOnAfterEvent(Formatter $formatter, Event $event)
+    {
+        if (!$event instanceof AfterOutlineTested) {
+            return;
+        }
+
+        $this->tablePrinter->printFooter($formatter, $event->getTestResult());
+    }
+
+    /**
+     * Returns currently captured step events results.
+     *
+     * @return StepResult[]
+     */
+    private function getStepTestResults()
+    {
+        return array_map(
+            function (AfterStepTested $event) {
+                return $event->getTestResult();
+            },
+            $this->stepAfterTestedEvents
+        );
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Output/Node/EventListener/AST/ScenarioNodeListener.php b/vendor/behat/behat/src/Behat/Behat/Output/Node/EventListener/AST/ScenarioNodeListener.php
new file mode 100644 (file)
index 0000000..77ac28e
--- /dev/null
@@ -0,0 +1,118 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Output\Node\EventListener\AST;
+
+use Behat\Behat\EventDispatcher\Event\ScenarioLikeTested;
+use Behat\Behat\Output\Node\Printer\ScenarioPrinter;
+use Behat\Behat\Output\Node\Printer\SetupPrinter;
+use Behat\Testwork\EventDispatcher\Event\AfterSetup;
+use Behat\Testwork\EventDispatcher\Event\AfterTested;
+use Behat\Testwork\Output\Formatter;
+use Behat\Testwork\Output\Node\EventListener\EventListener;
+use Symfony\Component\EventDispatcher\Event;
+
+/**
+ * Listens to scenario events and calls appropriate printers (header/footer).
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class ScenarioNodeListener implements EventListener
+{
+    /**
+     * @var string
+     */
+    private $beforeEventName;
+    /**
+     * @var string
+     */
+    private $afterEventName;
+    /**
+     * @var ScenarioPrinter
+     */
+    private $scenarioPrinter;
+    /**
+     * @var SetupPrinter
+     */
+    private $setupPrinter;
+
+    /**
+     * Initializes listener.
+     *
+     * @param string            $beforeEventName
+     * @param string            $afterEventName
+     * @param ScenarioPrinter   $scenarioPrinter
+     * @param null|SetupPrinter $setupPrinter
+     */
+    public function __construct(
+        $beforeEventName,
+        $afterEventName,
+        ScenarioPrinter $scenarioPrinter,
+        SetupPrinter $setupPrinter = null
+    ) {
+        $this->beforeEventName = $beforeEventName;
+        $this->afterEventName = $afterEventName;
+        $this->scenarioPrinter = $scenarioPrinter;
+        $this->setupPrinter = $setupPrinter;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function listenEvent(Formatter $formatter, Event $event, $eventName)
+    {
+        if (!$event instanceof ScenarioLikeTested) {
+            return;
+        }
+
+        $this->printHeaderOnBeforeEvent($formatter, $event, $eventName);
+        $this->printFooterOnAfterEvent($formatter, $event, $eventName);
+    }
+
+    /**
+     * Prints scenario/background header on BEFORE event.
+     *
+     * @param Formatter                     $formatter
+     * @param ScenarioLikeTested|AfterSetup $event
+     * @param string                        $eventName
+     */
+    private function printHeaderOnBeforeEvent(Formatter $formatter, ScenarioLikeTested $event, $eventName)
+    {
+        if ($this->beforeEventName !== $eventName || !$event instanceof AfterSetup) {
+            return;
+        }
+
+        if ($this->setupPrinter) {
+            $this->setupPrinter->printSetup($formatter, $event->getSetup());
+        }
+
+        $this->scenarioPrinter->printHeader($formatter, $event->getFeature(), $event->getScenario());
+    }
+
+    /**
+     * Prints scenario/background footer on AFTER event.
+     *
+     * @param Formatter                      $formatter
+     * @param ScenarioLikeTested|AfterTested $event
+     * @param string                         $eventName
+     */
+    private function printFooterOnAfterEvent(Formatter $formatter, ScenarioLikeTested $event, $eventName)
+    {
+        if ($this->afterEventName !== $eventName || !$event instanceof AfterTested) {
+            return;
+        }
+
+        if ($this->setupPrinter) {
+            $this->setupPrinter->printTeardown($formatter, $event->getTeardown());
+        }
+
+        $this->scenarioPrinter->printFooter($formatter, $event->getTestResult());
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Output/Node/EventListener/AST/StepListener.php b/vendor/behat/behat/src/Behat/Behat/Output/Node/EventListener/AST/StepListener.php
new file mode 100644 (file)
index 0000000..0d62a56
--- /dev/null
@@ -0,0 +1,125 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Output\Node\EventListener\AST;
+
+use Behat\Behat\EventDispatcher\Event\AfterStepSetup;
+use Behat\Behat\EventDispatcher\Event\AfterStepTested;
+use Behat\Behat\EventDispatcher\Event\ExampleTested;
+use Behat\Behat\EventDispatcher\Event\ScenarioLikeTested;
+use Behat\Behat\EventDispatcher\Event\ScenarioTested;
+use Behat\Behat\Output\Node\Printer\SetupPrinter;
+use Behat\Behat\Output\Node\Printer\StepPrinter;
+use Behat\Gherkin\Node\ScenarioLikeInterface;
+use Behat\Testwork\Output\Formatter;
+use Behat\Testwork\Output\Node\EventListener\EventListener;
+use Symfony\Component\EventDispatcher\Event;
+
+/**
+ * Listens to step events and call appropriate printers.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class StepListener implements EventListener
+{
+    /**
+     * @var StepPrinter
+     */
+    private $stepPrinter;
+    /**
+     * @var ScenarioLikeInterface
+     */
+    private $scenario;
+    /**
+     * @var null|SetupPrinter
+     */
+    private $setupPrinter;
+
+    /**
+     * Initializes listener.
+     *
+     * @param StepPrinter       $stepPrinter
+     * @param null|SetupPrinter $setupPrinter
+     */
+    public function __construct(StepPrinter $stepPrinter, SetupPrinter $setupPrinter = null)
+    {
+        $this->stepPrinter = $stepPrinter;
+        $this->setupPrinter = $setupPrinter;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function listenEvent(Formatter $formatter, Event $event, $eventName)
+    {
+        $this->captureScenarioOnScenarioEvent($event);
+        $this->forgetScenarioOnAfterEvent($eventName);
+        $this->printStepSetupOnBeforeEvent($formatter, $event);
+        $this->printStepOnAfterEvent($formatter, $event);
+    }
+
+    /**
+     * Captures scenario into the ivar on scenario/background/example BEFORE event.
+     *
+     * @param Event $event
+     */
+    private function captureScenarioOnScenarioEvent(Event $event)
+    {
+        if (!$event instanceof ScenarioLikeTested) {
+            return;
+        }
+
+        $this->scenario = $event->getScenario();
+    }
+
+    /**
+     * Removes scenario from the ivar on scenario/background/example AFTER event.
+     *
+     * @param string $eventName
+     */
+    private function forgetScenarioOnAfterEvent($eventName)
+    {
+        if (!in_array($eventName, array(ScenarioTested::AFTER, ExampleTested::AFTER))) {
+            return;
+        }
+
+        $this->scenario = null;
+    }
+
+    private function printStepSetupOnBeforeEvent(Formatter $formatter, Event $event)
+    {
+        if (!$event instanceof AfterStepSetup) {
+            return;
+        }
+
+        if ($this->setupPrinter) {
+            $this->setupPrinter->printSetup($formatter, $event->getSetup());
+        }
+    }
+
+    /**
+     * Prints step on AFTER event.
+     *
+     * @param Formatter $formatter
+     * @param Event     $event
+     */
+    private function printStepOnAfterEvent(Formatter $formatter, Event $event)
+    {
+        if (!$event instanceof AfterStepTested) {
+            return;
+        }
+
+        $this->stepPrinter->printStep($formatter, $this->scenario, $event->getStep(), $event->getTestResult());
+
+        if ($this->setupPrinter) {
+            $this->setupPrinter->printTeardown($formatter, $event->getTeardown());
+        }
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Output/Node/EventListener/AST/SuiteListener.php b/vendor/behat/behat/src/Behat/Behat/Output/Node/EventListener/AST/SuiteListener.php
new file mode 100644 (file)
index 0000000..8e116e0
--- /dev/null
@@ -0,0 +1,55 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Output\Node\EventListener\AST;
+
+use Behat\Behat\Output\Node\Printer\SetupPrinter;
+use Behat\Testwork\EventDispatcher\Event\AfterSuiteSetup;
+use Behat\Testwork\EventDispatcher\Event\AfterSuiteTested;
+use Behat\Testwork\Output\Formatter;
+use Behat\Testwork\Output\Node\EventListener\EventListener;
+use Symfony\Component\EventDispatcher\Event;
+
+/**
+ * Behat suite listener.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class SuiteListener implements EventListener
+{
+    /**
+     * @var SetupPrinter
+     */
+    private $setupPrinter;
+
+    /**
+     * Initializes listener.
+     *
+     * @param SetupPrinter $setupPrinter
+     */
+    public function __construct(SetupPrinter $setupPrinter)
+    {
+        $this->setupPrinter = $setupPrinter;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function listenEvent(Formatter $formatter, Event $event, $eventName)
+    {
+        if ($event instanceof AfterSuiteSetup) {
+            $this->setupPrinter->printSetup($formatter, $event->getSetup());
+        }
+
+        if ($event instanceof AfterSuiteTested) {
+            $this->setupPrinter->printTeardown($formatter, $event->getTeardown());
+        }
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Output/Node/EventListener/Flow/FireOnlySiblingsListener.php b/vendor/behat/behat/src/Behat/Behat/Output/Node/EventListener/Flow/FireOnlySiblingsListener.php
new file mode 100644 (file)
index 0000000..7e57885
--- /dev/null
@@ -0,0 +1,75 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Output\Node\EventListener\Flow;
+
+use Behat\Testwork\Output\Formatter;
+use Behat\Testwork\Output\Node\EventListener\EventListener;
+use Symfony\Component\EventDispatcher\Event;
+
+/**
+ * Behat fire only siblings listener.
+ *
+ * This listener catches all events, but proxies them to further listeners only if they
+ * live inside specific event lifecycle (between BEFORE and AFTER events).
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class FireOnlySiblingsListener implements EventListener
+{
+    /**
+     * @var string
+     */
+    private $beforeEventName;
+    /**
+     * @var string
+     */
+    private $afterEventName;
+    /**
+     * @var EventListener
+     */
+    private $descendant;
+    /**
+     * @var Boolean
+     */
+    private $inContext = false;
+
+    /**
+     * Initializes listener.
+     *
+     * @param string        $beforeEventName
+     * @param string        $afterEventName
+     * @param EventListener $descendant
+     */
+    public function __construct($beforeEventName, $afterEventName, EventListener $descendant)
+    {
+        $this->beforeEventName = $beforeEventName;
+        $this->afterEventName = $afterEventName;
+        $this->descendant = $descendant;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function listenEvent(Formatter $formatter, Event $event, $eventName)
+    {
+        if ($this->beforeEventName === $eventName) {
+            $this->inContext = true;
+        }
+
+        if ($this->inContext) {
+            $this->descendant->listenEvent($formatter, $event, $eventName);
+        }
+
+        if ($this->afterEventName === $eventName) {
+            $this->inContext = false;
+        }
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Output/Node/EventListener/Flow/FirstBackgroundFiresFirstListener.php b/vendor/behat/behat/src/Behat/Behat/Output/Node/EventListener/Flow/FirstBackgroundFiresFirstListener.php
new file mode 100644 (file)
index 0000000..f9bb95f
--- /dev/null
@@ -0,0 +1,137 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Output\Node\EventListener\Flow;
+
+use Behat\Behat\EventDispatcher\Event\BackgroundTested;
+use Behat\Behat\EventDispatcher\Event\ExampleTested;
+use Behat\Behat\EventDispatcher\Event\FeatureTested;
+use Behat\Behat\EventDispatcher\Event\OutlineTested;
+use Behat\Behat\EventDispatcher\Event\ScenarioTested;
+use Behat\Testwork\Output\Formatter;
+use Behat\Testwork\Output\Node\EventListener\EventListener;
+use Symfony\Component\EventDispatcher\Event;
+
+/**
+ * Behat first background fires first listener.
+ *
+ * This listener catches first scenario and background events in the feature and makes sure
+ * that background event are always fired before scenario events, thus following Gherkin format.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class FirstBackgroundFiresFirstListener implements EventListener
+{
+    /**
+     * @var \Behat\Testwork\Output\Node\EventListener\EventListener
+     */
+    private $descendant;
+    /**
+     * @var Boolean
+     */
+    private $firstBackgroundEnded = false;
+    /**
+     * @var Event[]
+     */
+    private $delayedUntilBackgroundEnd = array();
+
+    /**
+     * Initializes listener.
+     *
+     * @param EventListener $descendant
+     */
+    public function __construct(EventListener $descendant)
+    {
+        $this->descendant = $descendant;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function listenEvent(Formatter $formatter, Event $event, $eventName)
+    {
+        $this->flushStatesIfBeginningOfTheFeature($eventName);
+        $this->markFirstBackgroundPrintedAfterBackground($eventName);
+
+        if ($this->isEventDelayedUntilFirstBackgroundPrinted($event)) {
+            $this->delayedUntilBackgroundEnd[] = array($event, $eventName);
+
+            return;
+        }
+
+        $this->descendant->listenEvent($formatter, $event, $eventName);
+        $this->fireDelayedEventsOnAfterBackground($formatter, $eventName);
+    }
+
+    /**
+     * Flushes state if the event is the BEFORE feature.
+     *
+     * @param string $eventName
+     */
+    private function flushStatesIfBeginningOfTheFeature($eventName)
+    {
+        if (FeatureTested::BEFORE !== $eventName) {
+            return;
+        }
+
+        $this->firstBackgroundEnded = false;
+    }
+
+    /**
+     * Marks first background printed.
+     *
+     * @param string $eventName
+     */
+    private function markFirstBackgroundPrintedAfterBackground($eventName)
+    {
+        if (BackgroundTested::AFTER !== $eventName) {
+            return;
+        }
+
+        $this->firstBackgroundEnded = true;
+    }
+
+    /**
+     * Checks if provided event should be postponed until background is printed.
+     *
+     * @param Event $event
+     *
+     * @return Boolean
+     */
+    private function isEventDelayedUntilFirstBackgroundPrinted(Event $event)
+    {
+        if (!$event instanceof ScenarioTested && !$event instanceof OutlineTested && !$event instanceof ExampleTested) {
+            return false;
+        }
+
+        return !$this->firstBackgroundEnded && $event->getFeature()->hasBackground();
+    }
+
+    /**
+     * Fires delayed events on AFTER background event.
+     *
+     * @param Formatter $formatter
+     * @param string    $eventName
+     */
+    private function fireDelayedEventsOnAfterBackground(Formatter $formatter, $eventName)
+    {
+        if (BackgroundTested::AFTER !== $eventName) {
+            return;
+        }
+
+        foreach ($this->delayedUntilBackgroundEnd as $eventInfo) {
+            list($event, $eventName) = $eventInfo;
+
+            $this->descendant->listenEvent($formatter, $event, $eventName);
+        }
+
+        $this->delayedUntilBackgroundEnd = array();
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Output/Node/EventListener/Flow/OnlyFirstBackgroundFiresListener.php b/vendor/behat/behat/src/Behat/Behat/Output/Node/EventListener/Flow/OnlyFirstBackgroundFiresListener.php
new file mode 100644 (file)
index 0000000..ad3679c
--- /dev/null
@@ -0,0 +1,202 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Output\Node\EventListener\Flow;
+
+use Behat\Behat\EventDispatcher\Event\AfterStepSetup;
+use Behat\Behat\EventDispatcher\Event\AfterStepTested;
+use Behat\Behat\EventDispatcher\Event\BackgroundTested;
+use Behat\Behat\EventDispatcher\Event\FeatureTested;
+use Behat\Testwork\Output\Formatter;
+use Behat\Testwork\Output\Node\EventListener\EventListener;
+use Symfony\Component\EventDispatcher\Event;
+
+/**
+ * Behat only first background fires listener.
+ *
+ * This listener catches all in-background events and then proxies them further
+ * only if they meet one of two conditions:
+ *
+ *   1. It is a first background
+ *   2. It is a failing step
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class OnlyFirstBackgroundFiresListener implements EventListener
+{
+    /**
+     * @var EventListener
+     */
+    private $descendant;
+    /**
+     * @var Boolean
+     */
+    private $firstBackgroundEnded = false;
+    /**
+     * @var Boolean
+     */
+    private $inBackground = false;
+    /**
+     * @var Boolean
+     */
+    private $stepSetupHadOutput = false;
+
+    /**
+     * Initializes listener.
+     *
+     * @param EventListener $descendant
+     */
+    public function __construct(EventListener $descendant)
+    {
+        $this->descendant = $descendant;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function listenEvent(Formatter $formatter, Event $event, $eventName)
+    {
+        $this->flushStatesIfBeginningOfTheFeature($eventName);
+        $this->markBeginningOrEndOfTheBackground($eventName);
+
+        if ($this->isSkippableEvent($event)) {
+            return;
+        }
+
+        $this->markFirstBackgroundPrintedAfterBackground($eventName);
+
+        $this->descendant->listenEvent($formatter, $event, $eventName);
+    }
+
+    /**
+     * Flushes state if the event is the BEFORE feature.
+     *
+     * @param string $eventName
+     */
+    private function flushStatesIfBeginningOfTheFeature($eventName)
+    {
+        if (FeatureTested::BEFORE !== $eventName) {
+            return;
+        }
+
+        $this->firstBackgroundEnded = false;
+        $this->inBackground = false;
+    }
+
+    /**
+     * Marks beginning or end of the background.
+     *
+     * @param string $eventName
+     */
+    private function markBeginningOrEndOfTheBackground($eventName)
+    {
+        if (BackgroundTested::BEFORE === $eventName) {
+            $this->inBackground = true;
+        }
+
+        if (BackgroundTested::AFTER === $eventName) {
+            $this->inBackground = false;
+        }
+    }
+
+    /**
+     * Marks first background printed.
+     *
+     * @param string $eventName
+     */
+    private function markFirstBackgroundPrintedAfterBackground($eventName)
+    {
+        if (BackgroundTested::AFTER !== $eventName) {
+            return;
+        }
+
+        $this->firstBackgroundEnded = true;
+    }
+
+    /**
+     * Checks if provided event is skippable.
+     *
+     * @param Event $event
+     *
+     * @return Boolean
+     */
+    private function isSkippableEvent(Event $event)
+    {
+        if (!$this->firstBackgroundEnded) {
+            return false;
+        }
+
+        return $event instanceof BackgroundTested || $this->isNonFailingConsequentBackgroundStep($event);
+    }
+
+    /**
+     * Checks if provided event is a non-failing step in consequent background.
+     *
+     * @param Event $event
+     *
+     * @return Boolean
+     */
+    private function isNonFailingConsequentBackgroundStep(Event $event)
+    {
+        if (!$this->inBackground) {
+            return false;
+        }
+
+        return !$this->isStepEventWithOutput($event);
+    }
+
+    /**
+     * Checks if provided event is a step event which setup or teardown produced any output.
+     *
+     * @param Event $event
+     *
+     * @return Boolean
+     */
+    private function isStepEventWithOutput(Event $event)
+    {
+        return $this->isBeforeStepEventWithOutput($event) || $this->isAfterStepWithOutput($event);
+    }
+
+    /**
+     * Checks if provided event is a BEFORE step with setup that produced output.
+     *
+     * @param Event $event
+     *
+     * @return Boolean
+     */
+    private function isBeforeStepEventWithOutput(Event $event)
+    {
+        if ($event instanceof AfterStepSetup && $event->hasOutput()) {
+            $this->stepSetupHadOutput = true;
+
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Checks if provided event is an AFTER step with teardown that produced output.
+     *
+     * @param Event $event
+     *
+     * @return Boolean
+     */
+    private function isAfterStepWithOutput(Event $event)
+    {
+        if ($event instanceof AfterStepTested && ($this->stepSetupHadOutput || $event->hasOutput())) {
+            $this->stepSetupHadOutput = false;
+
+            return true;
+        }
+
+        return false;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Output/Node/EventListener/JUnit/JUnitFeatureElementListener.php b/vendor/behat/behat/src/Behat/Behat/Output/Node/EventListener/JUnit/JUnitFeatureElementListener.php
new file mode 100644 (file)
index 0000000..465efb6
--- /dev/null
@@ -0,0 +1,187 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Output\Node\EventListener\JUnit;
+
+use Behat\Behat\EventDispatcher\Event\AfterFeatureTested;
+use Behat\Behat\EventDispatcher\Event\AfterScenarioTested;
+use Behat\Behat\EventDispatcher\Event\AfterStepSetup;
+use Behat\Behat\EventDispatcher\Event\AfterStepTested;
+use Behat\Behat\EventDispatcher\Event\BeforeFeatureTested;
+use Behat\Behat\EventDispatcher\Event\ScenarioTested;
+use Behat\Behat\EventDispatcher\Event\StepTested;
+use Behat\Behat\Output\Node\Printer\FeaturePrinter;
+use Behat\Behat\Output\Node\Printer\JUnit\JUnitScenarioPrinter;
+use Behat\Behat\Output\Node\Printer\SetupPrinter;
+use Behat\Behat\Output\Node\Printer\StepPrinter;
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Testwork\EventDispatcher\Event\AfterSetup;
+use Behat\Testwork\Output\Formatter;
+use Behat\Testwork\Output\Node\EventListener\EventListener;
+use Symfony\Component\EventDispatcher\Event;
+
+/**
+ * Listens to feature, scenario and step events and calls appropriate printers.
+ *
+ * @author Wouter J <wouter@wouterj.nl>
+ */
+final class JUnitFeatureElementListener implements EventListener
+{
+    /**
+     * @var FeaturePrinter
+     */
+    private $featurePrinter;
+    /**
+     * @var JUnitScenarioPrinter
+     */
+    private $scenarioPrinter;
+    /**
+     * @var StepPrinter
+     */
+    private $stepPrinter;
+    /**
+     * @var SetupPrinter
+     */
+    private $setupPrinter;
+    /**
+     * @var FeatureNode
+     */
+    private $beforeFeatureTestedEvent;
+    /**
+     * @var AfterScenarioTested[]
+     */
+    private $afterScenarioTestedEvents = array();
+    /**
+     * @var AfterStepTested[]
+     */
+    private $afterStepTestedEvents = array();
+    /**
+     * @var AfterSetup[]
+     */
+    private $afterStepSetupEvents = array();
+
+    /**
+     * Initializes listener.
+     *
+     * @param FeaturePrinter $featurePrinter
+     * @param JUnitScenarioPrinter $scenarioPrinter
+     * @param StepPrinter $stepPrinter
+     * @param SetupPrinter $setupPrinter
+     */
+    public function __construct(FeaturePrinter $featurePrinter,
+                                JUnitScenarioPrinter $scenarioPrinter,
+                                StepPrinter $stepPrinter,
+                                SetupPrinter $setupPrinter)
+    {
+        $this->featurePrinter = $featurePrinter;
+        $this->scenarioPrinter = $scenarioPrinter;
+        $this->stepPrinter = $stepPrinter;
+        $this->setupPrinter = $setupPrinter;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function listenEvent(Formatter $formatter, Event $event, $eventName)
+    {
+        if ($event instanceof ScenarioTested) {
+            $this->captureScenarioEvent($event);
+        }
+
+        if ($event instanceof StepTested
+            || $event instanceof AfterStepSetup
+        ) {
+            $this->captureStepEvent($event);
+        }
+
+        $this->captureFeatureOnBeforeEvent($event);
+        $this->printFeatureOnAfterEvent($formatter, $event);
+    }
+
+    /**
+     * Captures scenario tested event.
+     *
+     * @param ScenarioTested $event
+     */
+    private function captureScenarioEvent(ScenarioTested $event)
+    {
+        if ($event instanceof AfterScenarioTested) {
+            $this->afterScenarioTestedEvents[$event->getScenario()->getLine()] = array(
+                'event'             => $event,
+                'step_events'       => $this->afterStepTestedEvents,
+                'step_setup_events' => $this->afterStepSetupEvents,
+            );
+
+            $this->afterStepTestedEvents = array();
+            $this->afterStepSetupEvents = array();
+        }
+    }
+
+    /**
+     * Captures feature on BEFORE event.
+     *
+     * @param Event $event
+     */
+    private function captureFeatureOnBeforeEvent(Event $event)
+    {
+        if (!$event instanceof BeforeFeatureTested) {
+            return;
+        }
+
+        $this->beforeFeatureTestedEvent = $event->getFeature();
+    }
+
+    /**
+     * Captures step tested event.
+     *
+     * @param Event $event
+     */
+    private function captureStepEvent(Event $event)
+    {
+        if ($event instanceof AfterStepTested) {
+            $this->afterStepTestedEvents[$event->getStep()->getLine()] = $event;
+        }
+        if ($event instanceof AfterStepSetup) {
+            $this->afterStepSetupEvents[$event->getStep()->getLine()] = $event;
+        }
+    }
+
+    /**
+     * Prints the feature on AFTER event.
+     *
+     * @param Formatter $formatter
+     * @param Event     $event
+     */
+    public function printFeatureOnAfterEvent(Formatter $formatter, Event $event)
+    {
+        if (!$event instanceof AfterFeatureTested) {
+            return;
+        }
+
+        $this->featurePrinter->printHeader($formatter, $this->beforeFeatureTestedEvent);
+
+        foreach ($this->afterScenarioTestedEvents as $afterScenario) {
+            $afterScenarioTested = $afterScenario['event'];
+            $this->scenarioPrinter->printOpenTag($formatter, $afterScenarioTested->getFeature(), $afterScenarioTested->getScenario(), $afterScenarioTested->getTestResult());
+
+            /** @var AfterStepSetup $afterStepSetup */
+            foreach ($afterScenario['step_setup_events'] as $afterStepSetup) {
+                $this->setupPrinter->printSetup($formatter, $afterStepSetup->getSetup());
+            }
+            foreach ($afterScenario['step_events'] as $afterStepTested) {
+                $this->stepPrinter->printStep($formatter, $afterScenarioTested->getScenario(), $afterStepTested->getStep(), $afterStepTested->getTestResult());
+                $this->setupPrinter->printTeardown($formatter, $afterStepTested->getTeardown());
+            }
+        }
+
+        $this->featurePrinter->printFooter($formatter, $event->getTestResult());
+        $this->afterScenarioTestedEvents = array();
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Output/Node/EventListener/JUnit/JUnitOutlineStoreListener.php b/vendor/behat/behat/src/Behat/Behat/Output/Node/EventListener/JUnit/JUnitOutlineStoreListener.php
new file mode 100644 (file)
index 0000000..4458ebb
--- /dev/null
@@ -0,0 +1,111 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Output\Node\EventListener\JUnit;
+
+use Behat\Behat\EventDispatcher\Event\BeforeOutlineTested;
+use Behat\Behat\Output\Node\Printer\SuitePrinter;
+use Behat\Gherkin\Node\ExampleNode;
+use Behat\Gherkin\Node\OutlineNode;
+use Behat\Testwork\EventDispatcher\Event\AfterSuiteTested;
+use Behat\Testwork\EventDispatcher\Event\BeforeSuiteTested;
+use Behat\Testwork\Output\Formatter;
+use Behat\Testwork\Output\Node\EventListener\EventListener;
+use Symfony\Component\EventDispatcher\Event;
+
+/**
+ * Listens for Outline events store the current one
+ *
+ * @author James Watson <james@sitepulse.org>
+ */
+final class JUnitOutlineStoreListener implements EventListener
+{
+
+    /**
+     * @var SuitePrinter
+     */
+    private $suitePrinter;
+
+    /**
+     * @var array
+     */
+    private $lineScenarioMap = array();
+
+    /**
+     * Initializes listener.
+     *
+     * @param SuitePrinter $suitePrinter
+     */
+    public function __construct(SuitePrinter $suitePrinter)
+    {
+        $this->suitePrinter = $suitePrinter;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function listenEvent(Formatter $formatter, Event $event, $eventName)
+    {
+        $this->captureOutlineOnBeforeOutlineEvent($event);
+
+        $this->printHeaderOnBeforeSuiteTestedEvent($formatter, $event);
+        $this->printFooterOnAfterSuiteTestedEvent($formatter, $event);
+    }
+
+    /**
+     * Captures outline into the ivar on outline BEFORE event.
+     *
+     * @param Event $event
+     */
+    private function captureOutlineOnBeforeOutlineEvent(Event $event)
+    {
+        if (!$event instanceof BeforeOutlineTested) {
+            return;
+        }
+
+        $outline = $event->getOutline();
+        foreach ($outline->getExamples() as $example) {
+            $this->lineScenarioMap[$example->getLine()] = $outline;
+        }
+    }
+
+    /**
+     * @param Formatter $formatter
+     * @param Event     $event
+     */
+    private function printHeaderOnBeforeSuiteTestedEvent(Formatter $formatter, Event $event)
+    {
+        if (!$event instanceof BeforeSuiteTested) {
+            return;
+        }
+        $this->suitePrinter->printHeader($formatter, $event->getSuite());
+    }
+
+    /**
+     * @param Formatter $formatter
+     * @param Event     $event
+     */
+    private function printFooterOnAfterSuiteTestedEvent(Formatter $formatter, Event $event)
+    {
+        if (!$event instanceof AfterSuiteTested) {
+            return;
+        }
+        $this->suitePrinter->printFooter($formatter, $event->getSuite());
+    }
+
+    /**
+     * @param ExampleNode $scenario
+     * @return OutlineNode
+     */
+    public function getCurrentOutline(ExampleNode $scenario)
+    {
+        return $this->lineScenarioMap[$scenario->getLine()];
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Output/Node/EventListener/Statistics/HookStatsListener.php b/vendor/behat/behat/src/Behat/Behat/Output/Node/EventListener/Statistics/HookStatsListener.php
new file mode 100644 (file)
index 0000000..a8d6007
--- /dev/null
@@ -0,0 +1,123 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Output\Node\EventListener\Statistics;
+
+use Behat\Behat\Output\Statistics\HookStat;
+use Behat\Behat\Output\Statistics\Statistics;
+use Behat\Testwork\Call\CallResult;
+use Behat\Testwork\EventDispatcher\Event\AfterSetup;
+use Behat\Testwork\EventDispatcher\Event\AfterTested;
+use Behat\Testwork\Exception\ExceptionPresenter;
+use Behat\Testwork\Hook\Tester\Setup\HookedSetup;
+use Behat\Testwork\Hook\Tester\Setup\HookedTeardown;
+use Behat\Testwork\Output\Formatter;
+use Behat\Testwork\Output\Node\EventListener\EventListener;
+use Symfony\Component\EventDispatcher\Event;
+
+/**
+ * Listens and records hook stats.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class HookStatsListener implements EventListener
+{
+    /**
+     * @var Statistics
+     */
+    private $statistics;
+    /**
+     * @var ExceptionPresenter
+     */
+    private $exceptionPresenter;
+
+    /**
+     * Initializes listener.
+     *
+     * @param Statistics         $statistics
+     * @param ExceptionPresenter $exceptionPresenter
+     */
+    public function __construct(Statistics $statistics, ExceptionPresenter $exceptionPresenter)
+    {
+        $this->statistics = $statistics;
+        $this->exceptionPresenter = $exceptionPresenter;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function listenEvent(Formatter $formatter, Event $event, $eventName)
+    {
+        $this->captureHookStatsOnEvent($event);
+    }
+
+    /**
+     * Captures hook stats on hooked event.
+     *
+     * @param Event $event
+     */
+    private function captureHookStatsOnEvent(Event $event)
+    {
+        if ($event instanceof AfterSetup && $event->getSetup() instanceof HookedSetup) {
+            $this->captureBeforeHookStats($event->getSetup());
+        }
+
+        if ($event instanceof AfterTested && $event->getTeardown() instanceof HookedTeardown) {
+            $this->captureAfterHookStats($event->getTeardown());
+        }
+    }
+
+    /**
+     * Captures before hook stats.
+     *
+     * @param HookedSetup $setup
+     */
+    private function captureBeforeHookStats(HookedSetup $setup)
+    {
+        $hookCallResults = $setup->getHookCallResults();
+
+        foreach ($hookCallResults as $hookCallResult) {
+            $this->captureHookStat($hookCallResult);
+        }
+    }
+
+    /**
+     * Captures before hook stats.
+     *
+     * @param HookedTeardown $teardown
+     */
+    private function captureAfterHookStats(HookedTeardown $teardown)
+    {
+        $hookCallResults = $teardown->getHookCallResults();
+
+        foreach ($hookCallResults as $hookCallResult) {
+            $this->captureHookStat($hookCallResult);
+        }
+    }
+
+    /**
+     * Captures hook call result.
+     *
+     * @param CallResult $hookCallResult
+     */
+    private function captureHookStat(CallResult $hookCallResult)
+    {
+        $callee = $hookCallResult->getCall()->getCallee();
+        $hook = (string) $callee;
+        $path = $callee->getPath();
+        $stdOut = $hookCallResult->getStdOut();
+        $error = $hookCallResult->getException()
+            ? $this->exceptionPresenter->presentException($hookCallResult->getException())
+            : null;
+
+        $stat = new HookStat($hook, $path, $error, $stdOut);
+        $this->statistics->registerHookStat($stat);
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Output/Node/EventListener/Statistics/ScenarioStatsListener.php b/vendor/behat/behat/src/Behat/Behat/Output/Node/EventListener/Statistics/ScenarioStatsListener.php
new file mode 100644 (file)
index 0000000..f83a38f
--- /dev/null
@@ -0,0 +1,105 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Output\Node\EventListener\Statistics;
+
+use Behat\Behat\EventDispatcher\Event\AfterFeatureTested;
+use Behat\Behat\EventDispatcher\Event\AfterScenarioTested;
+use Behat\Behat\EventDispatcher\Event\BeforeFeatureTested;
+use Behat\Behat\Output\Statistics\ScenarioStat;
+use Behat\Behat\Output\Statistics\Statistics;
+use Behat\Testwork\Output\Formatter;
+use Behat\Testwork\Output\Node\EventListener\EventListener;
+use Symfony\Component\EventDispatcher\Event;
+
+/**
+ * Listens and records scenario events to the statistics.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class ScenarioStatsListener implements EventListener
+{
+    /**
+     * @var Statistics
+     */
+    private $statistics;
+    /**
+     * @var string
+     */
+    private $currentFeaturePath;
+
+    /**
+     * Initializes listener.
+     *
+     * @param Statistics $statistics
+     */
+    public function __construct(Statistics $statistics)
+    {
+        $this->statistics = $statistics;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function listenEvent(Formatter $formatter, Event $event, $eventName)
+    {
+        $this->captureCurrentFeaturePathOnBeforeFeatureEvent($event);
+        $this->forgetCurrentFeaturePathOnAfterFeatureEvent($event);
+        $this->captureScenarioOrExampleStatsOnAfterEvent($event);
+    }
+
+    /**
+     * Captures current feature file path to the ivar on feature BEFORE event.
+     *
+     * @param Event $event
+     */
+    private function captureCurrentFeaturePathOnBeforeFeatureEvent(Event $event)
+    {
+        if (!$event instanceof BeforeFeatureTested) {
+            return;
+        }
+
+        $this->currentFeaturePath = $event->getFeature()->getFile();
+    }
+
+    /**
+     * Removes current feature file path from the ivar on feature AFTER event.
+     *
+     * @param Event $event
+     */
+    private function forgetCurrentFeaturePathOnAfterFeatureEvent($event)
+    {
+        if (!$event instanceof AfterFeatureTested) {
+            return;
+        }
+
+        $this->currentFeaturePath = null;
+    }
+
+    /**
+     * Captures scenario or example stats on their AFTER event.
+     *
+     * @param Event $event
+     */
+    private function captureScenarioOrExampleStatsOnAfterEvent(Event $event)
+    {
+        if (!$event instanceof AfterScenarioTested) {
+            return;
+        }
+
+        $scenario = $event->getScenario();
+        $title = $scenario->getTitle();
+        $path = sprintf('%s:%d', $this->currentFeaturePath, $scenario->getLine());
+        $resultCode = $event->getTestResult()->getResultCode();
+
+        $stat = new ScenarioStat($title, $path, $resultCode);
+        $this->statistics->registerScenarioStat($stat);
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Output/Node/EventListener/Statistics/StatisticsListener.php b/vendor/behat/behat/src/Behat/Behat/Output/Node/EventListener/Statistics/StatisticsListener.php
new file mode 100644 (file)
index 0000000..1845e1b
--- /dev/null
@@ -0,0 +1,86 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Output\Node\EventListener\Statistics;
+
+use Behat\Behat\Output\Node\Printer\StatisticsPrinter;
+use Behat\Behat\Output\Statistics\Statistics;
+use Behat\Testwork\EventDispatcher\Event\ExerciseCompleted;
+use Behat\Testwork\Output\Formatter;
+use Behat\Testwork\Output\Node\EventListener\EventListener;
+use Symfony\Component\EventDispatcher\Event;
+
+/**
+ * Collects general suite stats such as time and memory during its execution and prints it afterwards.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class StatisticsListener implements EventListener
+{
+    /**
+     * @var Statistics
+     */
+    private $statistics;
+    /**
+     * @var StatisticsPrinter
+     */
+    private $printer;
+
+    /**
+     * Initializes listener.
+     *
+     * @param Statistics        $statistics
+     * @param StatisticsPrinter $statisticsPrinter
+     */
+    public function __construct(Statistics $statistics, StatisticsPrinter $statisticsPrinter)
+    {
+        $this->statistics = $statistics;
+        $this->printer = $statisticsPrinter;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function listenEvent(Formatter $formatter, Event $event, $eventName)
+    {
+        $this->startTimerOnBeforeExercise($eventName);
+        $this->printStatisticsOnAfterExerciseEvent($formatter, $eventName);
+    }
+
+    /**
+     * Starts timer on exercise BEFORE event.
+     *
+     * @param string $eventName
+     */
+    private function startTimerOnBeforeExercise($eventName)
+    {
+        if (ExerciseCompleted::BEFORE !== $eventName) {
+            return;
+        }
+
+        $this->statistics->startTimer();
+    }
+
+    /**
+     * Prints statistics on after exercise event.
+     *
+     * @param Formatter $formatter
+     * @param string    $eventName
+     */
+    private function printStatisticsOnAfterExerciseEvent(Formatter $formatter, $eventName)
+    {
+        if (ExerciseCompleted::AFTER !== $eventName) {
+            return;
+        }
+
+        $this->statistics->stopTimer();
+        $this->printer->printStatistics($formatter, $this->statistics);
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Output/Node/EventListener/Statistics/StepStatsListener.php b/vendor/behat/behat/src/Behat/Behat/Output/Node/EventListener/Statistics/StepStatsListener.php
new file mode 100644 (file)
index 0000000..2f84d05
--- /dev/null
@@ -0,0 +1,195 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Output\Node\EventListener\Statistics;
+
+use Behat\Behat\EventDispatcher\Event\AfterStepTested;
+use Behat\Behat\EventDispatcher\Event\BeforeFeatureTested;
+use Behat\Behat\EventDispatcher\Event\BeforeScenarioTested;
+use Behat\Behat\EventDispatcher\Event\FeatureTested;
+use Behat\Behat\EventDispatcher\Event\ScenarioTested;
+use Behat\Behat\Output\Statistics\StepStatV2;
+use Behat\Behat\Output\Statistics\Statistics;
+use Behat\Behat\Output\Statistics\StepStat;
+use Behat\Behat\Tester\Exception\PendingException;
+use Behat\Behat\Tester\Result\ExecutedStepResult;
+use Behat\Behat\Tester\Result\StepResult;
+use Behat\Testwork\Exception\ExceptionPresenter;
+use Behat\Testwork\Output\Formatter;
+use Behat\Testwork\Output\Node\EventListener\EventListener;
+use Behat\Testwork\Tester\Result\ExceptionResult;
+use Exception;
+use Symfony\Component\EventDispatcher\Event;
+
+/**
+ * Listens and records step events to statistics.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class StepStatsListener implements EventListener
+{
+    /**
+     * @var Statistics
+     */
+    private $statistics;
+    /**
+     * @var string
+     */
+    private $currentFeaturePath;
+    /**
+     * @var ExceptionPresenter
+     */
+    private $exceptionPresenter;
+    /**
+     * @var string
+     */
+    private $scenarioTitle;
+    /**
+     * @var string
+     */
+    private $scenarioPath;
+
+    /**
+     * Initializes listener.
+     *
+     * @param Statistics         $statistics
+     * @param ExceptionPresenter $exceptionPresenter
+     */
+    public function __construct(Statistics $statistics, ExceptionPresenter $exceptionPresenter)
+    {
+        $this->statistics = $statistics;
+        $this->exceptionPresenter = $exceptionPresenter;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function listenEvent(Formatter $formatter, Event $event, $eventName)
+    {
+        $this->captureCurrentFeaturePathOnBeforeFeatureEvent($event);
+        $this->forgetCurrentFeaturePathOnAfterFeatureEvent($eventName);
+        $this->captureScenarioOnBeforeFeatureEvent($event);
+        $this->forgetScenarioOnAfterFeatureEvent($eventName);
+        $this->captureStepStatsOnAfterEvent($event);
+    }
+
+    /**
+     * Captures current feature file path to the ivar on feature BEFORE event.
+     *
+     * @param Event $event
+     */
+    private function captureCurrentFeaturePathOnBeforeFeatureEvent(Event $event)
+    {
+        if (!$event instanceof BeforeFeatureTested) {
+            return;
+        }
+
+        $this->currentFeaturePath = $event->getFeature()->getFile();
+    }
+
+    /**
+     * Removes current feature file path from the ivar on feature AFTER event.
+     *
+     * @param string $eventName
+     */
+    private function forgetCurrentFeaturePathOnAfterFeatureEvent($eventName)
+    {
+        if (FeatureTested::AFTER !== $eventName) {
+            return;
+        }
+
+        $this->currentFeaturePath = null;
+    }
+
+    /**
+     * Captures current scenario title and path on scenario BEFORE event.
+     *
+     * @param Event $event
+     */
+    private function captureScenarioOnBeforeFeatureEvent(Event $event)
+    {
+        if (!$event instanceof BeforeScenarioTested) {
+            return;
+        }
+
+        $this->scenarioTitle = sprintf('%s: %s', $event->getScenario()->getKeyword(), $event->getScenario()->getTitle());
+        $this->scenarioPath = sprintf('%s:%s', $this->currentFeaturePath, $event->getScenario()->getLine());
+    }
+
+    private function forgetScenarioOnAfterFeatureEvent($eventName)
+    {
+        if (ScenarioTested::AFTER !== $eventName) {
+            return;
+        }
+
+        $this->scenarioTitle = $this->scenarioPath = null;
+    }
+
+    /**
+     * Captures step stats on step AFTER event.
+     *
+     * @param Event $event
+     */
+    private function captureStepStatsOnAfterEvent(Event $event)
+    {
+        if (!$event instanceof AfterStepTested) {
+            return;
+        }
+
+        $result = $event->getTestResult();
+        $step = $event->getStep();
+        $text = sprintf('%s %s', $step->getKeyword(), $step->getText());
+        $exception = $this->getStepException($result);
+
+        $path = $this->getStepPath($event, $exception);
+        $error = $exception ? $this->exceptionPresenter->presentException($exception) : null;
+        $stdOut = $result instanceof ExecutedStepResult ? $result->getCallResult()->getStdOut() : null;
+
+        $resultCode = $result->getResultCode();
+        $stat = new StepStatV2($this->scenarioTitle, $this->scenarioPath, $text, $path, $resultCode, $error, $stdOut);
+
+        $this->statistics->registerStepStat($stat);
+    }
+
+    /**
+     * Gets exception from the step test results.
+     *
+     * @param StepResult $result
+     *
+     * @return null|Exception
+     */
+    private function getStepException(StepResult $result)
+    {
+        if ($result instanceof ExceptionResult) {
+            return $result->getException();
+        }
+
+        return null;
+    }
+
+    /**
+     * Gets step path from the AFTER test event and exception.
+     *
+     * @param AfterStepTested $event
+     * @param null|Exception  $exception
+     *
+     * @return string
+     */
+    private function getStepPath(AfterStepTested $event, Exception $exception = null)
+    {
+        $path = sprintf('%s:%d', $this->currentFeaturePath, $event->getStep()->getLine());
+
+        if ($exception && $exception instanceof PendingException) {
+            $path = $event->getTestResult()->getStepDefinition()->getPath();
+        }
+
+        return $path;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/CounterPrinter.php b/vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/CounterPrinter.php
new file mode 100644 (file)
index 0000000..ff567db
--- /dev/null
@@ -0,0 +1,81 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Output\Node\Printer;
+
+use Behat\Behat\Output\Node\Printer\Helper\ResultToStringConverter;
+use Behat\Testwork\Output\Printer\OutputPrinter;
+use Symfony\Component\Translation\TranslatorInterface;
+
+/**
+ * Behat counter printer.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class CounterPrinter
+{
+    /**
+     * @var ResultToStringConverter
+     */
+    private $resultConverter;
+    /**
+     * @var TranslatorInterface
+     */
+    private $translator;
+
+    /**
+     * Initializes printer.
+     *
+     * @param ResultToStringConverter $resultConverter
+     * @param TranslatorInterface     $translator
+     */
+    public function __construct(ResultToStringConverter $resultConverter, TranslatorInterface $translator)
+    {
+        $this->resultConverter = $resultConverter;
+        $this->translator = $translator;
+    }
+
+    /**
+     * Prints scenario and step counters.
+     *
+     * @param OutputPrinter $printer
+     * @param string        $intro
+     * @param array         $stats
+     */
+    public function printCounters(OutputPrinter $printer, $intro, array $stats)
+    {
+        $stats = array_filter($stats, function ($count) { return 0 !== $count; });
+
+        if (0 === count($stats)) {
+            $totalCount = 0;
+        } else {
+            $totalCount = array_sum($stats);
+        }
+
+        $detailedStats = array();
+        foreach ($stats as $resultCode => $count) {
+            $style = $this->resultConverter->convertResultCodeToString($resultCode);
+
+            $transId = $style . '_count';
+            $message = $this->translator->transChoice($transId, $count, array('%1%' => $count), 'output');
+
+            $detailedStats[] = sprintf('{+%s}%s{-%s}', $style, $message, $style);
+        }
+
+        $message = $this->translator->transChoice($intro, $totalCount, array('%1%' => $totalCount), 'output');
+        $printer->write($message);
+
+        if (count($detailedStats)) {
+            $printer->write(sprintf(' (%s)', implode(', ', $detailedStats)));
+        }
+
+        $printer->writeln();
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/ExamplePrinter.php b/vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/ExamplePrinter.php
new file mode 100644 (file)
index 0000000..048f547
--- /dev/null
@@ -0,0 +1,41 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Output\Node\Printer;
+
+use Behat\Gherkin\Node\ExampleNode;
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Testwork\Output\Formatter;
+use Behat\Testwork\Tester\Result\TestResult;
+
+/**
+ * Prints example headers and footers.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface ExamplePrinter
+{
+    /**
+     * Prints example header using provided printer.
+     *
+     * @param Formatter   $formatter
+     * @param FeatureNode $feature
+     * @param ExampleNode $example
+     */
+    public function printHeader(Formatter $formatter, FeatureNode $feature, ExampleNode $example);
+
+    /**
+     * Prints example footer using provided printer.
+     *
+     * @param Formatter  $formatter
+     * @param TestResult $result
+     */
+    public function printFooter(Formatter $formatter, TestResult $result);
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/ExampleRowPrinter.php b/vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/ExampleRowPrinter.php
new file mode 100644 (file)
index 0000000..1b52997
--- /dev/null
@@ -0,0 +1,34 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Output\Node\Printer;
+
+use Behat\Behat\EventDispatcher\Event\AfterStepTested;
+use Behat\Gherkin\Node\ExampleNode;
+use Behat\Gherkin\Node\OutlineNode;
+use Behat\Testwork\Output\Formatter;
+
+/**
+ * Prints outline example row results.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface ExampleRowPrinter
+{
+    /**
+     * Prints example row result using provided printer.
+     *
+     * @param Formatter         $formatter
+     * @param OutlineNode       $outline
+     * @param ExampleNode       $example
+     * @param AfterStepTested[] $events
+     */
+    public function printExampleRow(Formatter $formatter, OutlineNode $outline, ExampleNode $example, array $events);
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/FeaturePrinter.php b/vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/FeaturePrinter.php
new file mode 100644 (file)
index 0000000..699615f
--- /dev/null
@@ -0,0 +1,39 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Output\Node\Printer;
+
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Testwork\Output\Formatter;
+use Behat\Testwork\Tester\Result\TestResult;
+
+/**
+ * Prints feature headers and footers.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface FeaturePrinter
+{
+    /**
+     * Prints feature header using provided formatter.
+     *
+     * @param Formatter   $formatter
+     * @param FeatureNode $feature
+     */
+    public function printHeader(Formatter $formatter, FeatureNode $feature);
+
+    /**
+     * Prints feature footer using provided printer.
+     *
+     * @param Formatter  $formatter
+     * @param TestResult $result
+     */
+    public function printFooter(Formatter $formatter, TestResult $result);
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/Helper/ResultToStringConverter.php b/vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/Helper/ResultToStringConverter.php
new file mode 100644 (file)
index 0000000..dabddfd
--- /dev/null
@@ -0,0 +1,57 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Output\Node\Printer\Helper;
+
+use Behat\Behat\Tester\Result\StepResult;
+use Behat\Testwork\Tester\Result\TestResult;
+
+/**
+ * Converts result objects into a string representation.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class ResultToStringConverter
+{
+    /**
+     * Converts provided test result to a string.
+     *
+     * @param TestResult $result
+     *
+     * @return string
+     */
+    public function convertResultToString(TestResult $result)
+    {
+        return $this->convertResultCodeToString($result->getResultCode());
+    }
+
+    /**
+     * Converts provided result code to a string.
+     *
+     * @param integer $resultCode
+     *
+     * @return string
+     */
+    public function convertResultCodeToString($resultCode)
+    {
+        switch ($resultCode) {
+            case TestResult::SKIPPED:
+                return 'skipped';
+            case TestResult::PENDING:
+                return 'pending';
+            case TestResult::FAILED:
+                return 'failed';
+            case StepResult::UNDEFINED:
+                return 'undefined';
+        }
+
+        return 'passed';
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/Helper/StepTextPainter.php b/vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/Helper/StepTextPainter.php
new file mode 100644 (file)
index 0000000..d2becc5
--- /dev/null
@@ -0,0 +1,106 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Output\Node\Printer\Helper;
+
+use Behat\Behat\Definition\Definition;
+use Behat\Behat\Definition\Pattern\PatternTransformer;
+use Behat\Testwork\Tester\Result\TestResult;
+
+/**
+ * Paints step text (with tokens) according to found definition.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class StepTextPainter
+{
+    /**
+     * @var PatternTransformer
+     */
+    private $patternTransformer;
+    /**
+     * @var ResultToStringConverter
+     */
+    private $resultConverter;
+
+    /**
+     * Initializes painter.
+     *
+     * @param PatternTransformer      $patternTransformer
+     * @param ResultToStringConverter $resultConverter
+     */
+    public function __construct(PatternTransformer $patternTransformer, ResultToStringConverter $resultConverter)
+    {
+        $this->patternTransformer = $patternTransformer;
+        $this->resultConverter = $resultConverter;
+    }
+
+    /**
+     * Colorizes step text arguments according to definition.
+     *
+     * @param string     $text
+     * @param Definition $definition
+     * @param TestResult $result
+     *
+     * @return string
+     */
+    public function paintText($text, Definition $definition, TestResult $result)
+    {
+        $regex = $this->patternTransformer->transformPatternToRegex($definition->getPattern());
+        $style = $this->resultConverter->convertResultToString($result);
+        $paramStyle = $style . '_param';
+
+        // If it's just a string - skip
+        if ('/' !== substr($regex, 0, 1)) {
+            return $text;
+        }
+
+        // Find arguments with offsets
+        $matches = array();
+        preg_match($regex, $text, $matches, PREG_OFFSET_CAPTURE);
+        array_shift($matches);
+
+        // Replace arguments with colorized ones
+        $shift = 0;
+        $lastReplacementPosition = 0;
+        foreach ($matches as $key => $match) {
+            if (!is_numeric($key) || -1 === $match[1] || false !== strpos($match[0], '<')) {
+                continue;
+            }
+
+            $offset = $match[1] + $shift;
+            $value = $match[0];
+
+            // Skip inner matches
+            if ($lastReplacementPosition > $offset) {
+                continue;
+            }
+            $lastReplacementPosition = $offset + strlen($value);
+
+            $begin = substr($text, 0, $offset);
+            $end = substr($text, $lastReplacementPosition);
+            $format = "{-$style}{+$paramStyle}%s{-$paramStyle}{+$style}";
+            $text = sprintf("%s{$format}%s", $begin, $value, $end);
+
+            // Keep track of how many extra characters are added
+            $shift += strlen($format) - 2;
+            $lastReplacementPosition += strlen($format) - 2;
+        }
+
+        // Replace "<", ">" with colorized ones
+        $text = preg_replace(
+            '/(<[^>]+>)/',
+            "{-$style}{+$paramStyle}\$1{-$paramStyle}{+$style}",
+            $text
+        );
+
+        return $text;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/Helper/WidthCalculator.php b/vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/Helper/WidthCalculator.php
new file mode 100644 (file)
index 0000000..bef1881
--- /dev/null
@@ -0,0 +1,105 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Output\Node\Printer\Helper;
+
+use Behat\Gherkin\Node\ExampleNode;
+use Behat\Gherkin\Node\ScenarioLikeInterface as Scenario;
+use Behat\Gherkin\Node\StepNode;
+
+/**
+ * Calculates width of scenario. Width of scenario = max width of scenario title and scenario step texts.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class WidthCalculator
+{
+    /**
+     * Calculates scenario width.
+     *
+     * @param Scenario $scenario
+     * @param integer  $indentation
+     * @param integer  $subIndentation
+     *
+     * @return integer
+     */
+    public function calculateScenarioWidth(Scenario $scenario, $indentation, $subIndentation)
+    {
+        $length = $this->calculateScenarioHeaderWidth($scenario, $indentation);
+
+        foreach ($scenario->getSteps() as $step) {
+            $stepLength = $this->calculateStepWidth($step, $indentation + $subIndentation);
+            $length = max($length, $stepLength);
+        }
+
+        return $length;
+    }
+
+    /**
+     * Calculates outline examples width.
+     *
+     * @param ExampleNode $example
+     * @param integer     $indentation
+     * @param integer     $subIndentation
+     *
+     * @return integer
+     */
+    public function calculateExampleWidth(ExampleNode $example, $indentation, $subIndentation)
+    {
+        $length = $this->calculateScenarioHeaderWidth($example, $indentation);
+
+        foreach ($example->getSteps() as $step) {
+            $stepLength = $this->calculateStepWidth($step, $indentation + $subIndentation);
+            $length = max($length, $stepLength);
+        }
+
+        return $length;
+    }
+
+    /**
+     * Calculates scenario header width.
+     *
+     * @param Scenario $scenario
+     * @param integer  $indentation
+     *
+     * @return integer
+     */
+    public function calculateScenarioHeaderWidth(Scenario $scenario, $indentation)
+    {
+        $indentText = str_repeat(' ', intval($indentation));
+
+        if ($scenario instanceof ExampleNode) {
+            $header = sprintf('%s%s', $indentText, $scenario->getTitle());
+        } else {
+            $title = $scenario->getTitle();
+            $lines = explode("\n", $title);
+            $header = sprintf('%s%s: %s', $indentText, $scenario->getKeyword(), array_shift($lines));
+        }
+
+        return mb_strlen(rtrim($header), 'utf8');
+    }
+
+    /**
+     * Calculates step width.
+     *
+     * @param StepNode $step
+     * @param integer  $indentation
+     *
+     * @return integer
+     */
+    public function calculateStepWidth(StepNode $step, $indentation)
+    {
+        $indentText = str_repeat(' ', intval($indentation));
+
+        $text = sprintf('%s%s %s', $indentText, $step->getKeyword(), $step->getText());
+
+        return mb_strlen($text, 'utf8');
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/JUnit/JUnitFeaturePrinter.php b/vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/JUnit/JUnitFeaturePrinter.php
new file mode 100644 (file)
index 0000000..6b6e871
--- /dev/null
@@ -0,0 +1,70 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Output\Node\Printer\JUnit;
+
+use Behat\Behat\Output\Node\Printer\FeaturePrinter;
+use Behat\Behat\Output\Statistics\PhaseStatistics;
+use Behat\Behat\Tester\Result\StepResult;
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Testwork\Output\Formatter;
+use Behat\Testwork\Output\Printer\JUnitOutputPrinter;
+use Behat\Testwork\Tester\Result\TestResult;
+
+/**
+ * Prints the <testsuite> element.
+ *
+ * @author Wouter J <wouter@wouterj.nl>
+ */
+final class JUnitFeaturePrinter implements FeaturePrinter
+{
+    /**
+     * @var PhaseStatistics
+     */
+    private $statistics;
+
+    public function __construct(PhaseStatistics $statistics)
+    {
+        $this->statistics = $statistics;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function printHeader(Formatter $formatter, FeatureNode $feature)
+    {
+        $stats = $this->statistics->getScenarioStatCounts();
+
+        if (0 === count($stats)) {
+            $totalCount = 0;
+        } else {
+            $totalCount = array_sum($stats);
+        }
+
+        /** @var JUnitOutputPrinter $outputPrinter */
+        $outputPrinter = $formatter->getOutputPrinter();
+
+        $outputPrinter->addTestsuite(array(
+            'name' => $feature->getTitle(),
+            'tests' => $totalCount,
+            'skipped' => $stats[TestResult::SKIPPED],
+            'failures' => $stats[TestResult::FAILED],
+            'errors' => $stats[TestResult::PENDING] + $stats[StepResult::UNDEFINED],
+        ));
+        $this->statistics->reset();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function printFooter(Formatter $formatter, TestResult $result)
+    {
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/JUnit/JUnitScenarioPrinter.php b/vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/JUnit/JUnitScenarioPrinter.php
new file mode 100644 (file)
index 0000000..cf61eaa
--- /dev/null
@@ -0,0 +1,95 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Output\Node\Printer\JUnit;
+
+use Behat\Behat\Output\Node\EventListener\JUnit\JUnitOutlineStoreListener;
+use Behat\Behat\Output\Node\Printer\Helper\ResultToStringConverter;
+use Behat\Gherkin\Node\ExampleNode;
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\OutlineNode;
+use Behat\Gherkin\Node\ScenarioLikeInterface;
+use Behat\Testwork\Output\Formatter;
+use Behat\Testwork\Output\Printer\JUnitOutputPrinter;
+use Behat\Testwork\Tester\Result\TestResult;
+
+/**
+ * Prints the <testcase> element.
+ *
+ * @author Wouter J <wouter@wouterj.nl>
+ */
+final class JUnitScenarioPrinter
+{
+    /**
+     * @var ResultToStringConverter
+     */
+    private $resultConverter;
+
+    /**
+     * @var JUnitOutlineStoreListener
+     */
+    private $outlineStoreListener;
+
+    /**
+     * @var OutlineNode
+     */
+    private $lastOutline;
+
+    /**
+     * @var int
+     */
+    private $outlineStepCount;
+
+    public function __construct(ResultToStringConverter $resultConverter, JUnitOutlineStoreListener $outlineListener)
+    {
+        $this->resultConverter = $resultConverter;
+        $this->outlineStoreListener = $outlineListener;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function printOpenTag(Formatter $formatter, FeatureNode $feature, ScenarioLikeInterface $scenario, TestResult $result)
+    {
+        $name = implode(' ', array_map(function ($l) {
+            return trim($l);
+        }, explode("\n", $scenario->getTitle())));
+
+        if ($scenario instanceof ExampleNode) {
+            $name = $this->buildExampleName($scenario);
+        }
+
+        /** @var JUnitOutputPrinter $outputPrinter */
+        $outputPrinter = $formatter->getOutputPrinter();
+
+        $outputPrinter->addTestcase(array(
+            'name' => $name,
+            'status' => $this->resultConverter->convertResultToString($result)
+        ));
+    }
+
+    /**
+     * @param ExampleNode $scenario
+     * @return string
+     */
+    private function buildExampleName(ExampleNode $scenario)
+    {
+        $currentOutline = $this->outlineStoreListener->getCurrentOutline($scenario);
+        if ($currentOutline === $this->lastOutline) {
+            $this->outlineStepCount++;
+        } else {
+            $this->lastOutline = $currentOutline;
+            $this->outlineStepCount = 1;
+        }
+
+        $name = $currentOutline->getTitle() . ' #' . $this->outlineStepCount;
+        return $name;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/JUnit/JUnitSetupPrinter.php b/vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/JUnit/JUnitSetupPrinter.php
new file mode 100644 (file)
index 0000000..401c7e9
--- /dev/null
@@ -0,0 +1,87 @@
+<?php
+namespace Behat\Behat\Output\Node\Printer\JUnit;
+
+use Behat\Behat\Hook\Scope\StepScope;
+use Behat\Behat\Output\Node\Printer\SetupPrinter;
+use Behat\Testwork\Call\CallResult;
+use Behat\Testwork\Call\CallResults;
+use Behat\Testwork\Exception\ExceptionPresenter;
+use Behat\Testwork\Hook\Call\HookCall;
+use Behat\Testwork\Hook\Tester\Setup\HookedSetup;
+use Behat\Testwork\Hook\Tester\Setup\HookedTeardown;
+use Behat\Testwork\Output\Formatter;
+use Behat\Testwork\Output\Printer\JUnitOutputPrinter;
+use Behat\Testwork\Tester\Setup\Setup;
+use Behat\Testwork\Tester\Setup\Teardown;
+
+/**
+ * @author: Jakob Erdmann <jakob.erdmann@rocket-internet.com>
+ */
+class JUnitSetupPrinter implements SetupPrinter
+{
+
+    /** @var ExceptionPresenter */
+    private $exceptionPresenter;
+
+    public function __construct(ExceptionPresenter $exceptionPresenter)
+    {
+        $this->exceptionPresenter = $exceptionPresenter;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function printSetup(Formatter $formatter, Setup $setup)
+    {
+        if (!$setup->isSuccessful()) {
+            if ($setup instanceof HookedSetup) {
+                $this->handleHookCalls($formatter, $setup->getHookCallResults(), 'setup');
+            }
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function printTeardown(Formatter $formatter, Teardown $teardown)
+    {
+        if (!$teardown->isSuccessful()) {
+            if ($teardown instanceof HookedTeardown) {
+                $this->handleHookCalls($formatter, $teardown->getHookCallResults(), 'teardown');
+            }
+        }
+    }
+
+    /**
+     * @param Formatter $formatter
+     * @param CallResults $results
+     * @param string $messageType
+     */
+    private function handleHookCalls(Formatter $formatter, CallResults $results, $messageType)
+    {
+        /** @var CallResult $hookCallResult */
+        foreach ($results as $hookCallResult) {
+            if ($hookCallResult->hasException()) {
+                /** @var HookCall $call */
+                $call = $hookCallResult->getCall();
+                $scope = $call->getScope();
+                /** @var JUnitOutputPrinter $outputPrinter */
+                $outputPrinter = $formatter->getOutputPrinter();
+
+                $message = '';
+                if ($scope instanceof StepScope) {
+                    $message .= $scope->getStep()->getKeyword() . ' ' . $scope->getStep()->getText() . ': ';
+                }
+                $message .= $this->exceptionPresenter->presentException($hookCallResult->getException());
+
+                $attributes = array(
+                    'message' => $message,
+                    'type'    => $messageType,
+                );
+
+                $outputPrinter->addTestcaseChild('failure', $attributes);
+
+            }
+        }
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/JUnit/JUnitStepPrinter.php b/vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/JUnit/JUnitStepPrinter.php
new file mode 100644 (file)
index 0000000..dcca50d
--- /dev/null
@@ -0,0 +1,78 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Output\Node\Printer\JUnit;
+
+use Behat\Behat\Tester\Result\StepResult;
+use Behat\Behat\Output\Node\Printer\StepPrinter;
+use Behat\Gherkin\Node\ScenarioLikeInterface as Scenario;
+use Behat\Gherkin\Node\StepNode;
+use Behat\Testwork\Exception\ExceptionPresenter;
+use Behat\Testwork\Output\Formatter;
+use Behat\Testwork\Output\Printer\JUnitOutputPrinter;
+use Behat\Testwork\Tester\Result\TestResult;
+use Behat\Testwork\Tester\Result\ExceptionResult;
+
+/**
+ * Prints step with optional results.
+ *
+ * @author Wouter J <wouter@wouterj.nl>
+ * @author James Watson <james@sitepulse.org>
+ */
+class JUnitStepPrinter implements StepPrinter
+{
+    /**
+     * @var ExceptionPresenter
+     */
+    private $exceptionPresenter;
+
+    public function __construct(ExceptionPresenter $exceptionPresenter)
+    {
+        $this->exceptionPresenter = $exceptionPresenter;
+    }
+
+    /**
+     * Prints step using provided printer.
+     *
+     * @param Formatter  $formatter
+     * @param Scenario   $scenario
+     * @param StepNode   $step
+     * @param StepResult $result
+     */
+    public function printStep(Formatter $formatter, Scenario $scenario, StepNode $step, StepResult $result)
+    {
+        /** @var JUnitOutputPrinter $outputPrinter */
+        $outputPrinter = $formatter->getOutputPrinter();
+
+        $message = $step->getKeyword() . ' ' . $step->getText();
+
+        if ($result instanceof ExceptionResult && $result->hasException()) {
+            $message .= ': ' . $this->exceptionPresenter->presentException($result->getException());
+        }
+
+        $attributes = array('message' => $message);
+
+        switch ($result->getResultCode()) {
+            case TestResult::FAILED:
+                $outputPrinter->addTestcaseChild('failure', $attributes);
+                break;
+
+            case TestResult::PENDING:
+                $attributes['type'] = 'pending';
+                $outputPrinter->addTestcaseChild('error', $attributes);
+                break;
+
+            case StepResult::UNDEFINED:
+                $attributes['type'] = 'undefined';
+                $outputPrinter->addTestcaseChild('error', $attributes);
+                break;
+        }
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/JUnit/JUnitSuitePrinter.php b/vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/JUnit/JUnitSuitePrinter.php
new file mode 100644 (file)
index 0000000..7e5efad
--- /dev/null
@@ -0,0 +1,57 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Output\Node\Printer\JUnit;
+
+use Behat\Behat\Output\Node\Printer\SuitePrinter;
+use Behat\Behat\Output\Statistics\PhaseStatistics;
+use Behat\Testwork\Output\Formatter;
+use Behat\Testwork\Output\Printer\JUnitOutputPrinter;
+use Behat\Testwork\Suite\Suite;
+
+/**
+ * Creates new JUnit report file.
+ *
+ * @author Wouter J <wouter@wouterj.nl>
+ */
+final class JUnitSuitePrinter implements SuitePrinter
+{
+    /**
+     * @var PhaseStatistics
+     */
+    private $statistics;
+
+    public function __construct(PhaseStatistics $statistics = null)
+    {
+        $this->statistics = $statistics;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function printHeader(Formatter $formatter, Suite $suite)
+    {
+        if ($this->statistics) {
+            $this->statistics->reset();
+        }
+
+        /** @var JUnitOutputPrinter $outputPrinter */
+        $outputPrinter = $formatter->getOutputPrinter();
+        $outputPrinter->createNewFile($suite->getName());
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function printFooter(Formatter $formatter, Suite $suite)
+    {
+        $formatter->getOutputPrinter()->flush();
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/ListPrinter.php b/vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/ListPrinter.php
new file mode 100644 (file)
index 0000000..31e8388
--- /dev/null
@@ -0,0 +1,271 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Output\Node\Printer;
+
+use Behat\Behat\Output\Node\Printer\Helper\ResultToStringConverter;
+use Behat\Behat\Output\Statistics\HookStat;
+use Behat\Behat\Output\Statistics\ScenarioStat;
+use Behat\Behat\Output\Statistics\StepStatV2;
+use Behat\Behat\Output\Statistics\StepStat;
+use Behat\Testwork\Exception\ExceptionPresenter;
+use Behat\Testwork\Output\Printer\OutputPrinter;
+use Behat\Testwork\Tester\Result\TestResult;
+use Symfony\Component\Translation\TranslatorInterface;
+
+/**
+ * Behat list printer.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class ListPrinter
+{
+    /**
+     * @var ResultToStringConverter
+     */
+    private $resultConverter;
+    /**
+     * @var ExceptionPresenter
+     */
+    private $exceptionPresenter;
+    /**
+     * @var TranslatorInterface
+     */
+    private $translator;
+    /**
+     * @var string
+     */
+    private $basePath;
+
+    /**
+     * Initializes printer.
+     *
+     * @param ResultToStringConverter $resultConverter
+     * @param ExceptionPresenter      $exceptionPresenter
+     * @param TranslatorInterface     $translator
+     * @param string                  $basePath
+     */
+    public function __construct(
+        ResultToStringConverter $resultConverter,
+        ExceptionPresenter $exceptionPresenter,
+        TranslatorInterface $translator,
+        $basePath
+    ) {
+        $this->resultConverter = $resultConverter;
+        $this->exceptionPresenter = $exceptionPresenter;
+        $this->translator = $translator;
+        $this->basePath = $basePath;
+    }
+
+    /**
+     * Prints scenarios list.
+     *
+     * @param OutputPrinter  $printer
+     * @param string         $intro
+     * @param integer        $resultCode
+     * @param ScenarioStat[] $scenarioStats
+     */
+    public function printScenariosList(OutputPrinter $printer, $intro, $resultCode, array $scenarioStats)
+    {
+        if (!count($scenarioStats)) {
+            return;
+        }
+
+        $style = $this->resultConverter->convertResultCodeToString($resultCode);
+        $intro = $this->translator->trans($intro, array(), 'output');
+
+        $printer->writeln(sprintf('--- {+%s}%s{-%s}' . PHP_EOL, $style, $intro, $style));
+        foreach ($scenarioStats as $stat) {
+            $path = $this->relativizePaths((string) $stat);
+            $printer->writeln(sprintf('    {+%s}%s{-%s}', $style, $path, $style));
+        }
+
+        $printer->writeln();
+    }
+
+    /**
+     * Prints step list.
+     *
+     * @param OutputPrinter $printer
+     * @param string        $intro
+     * @param integer       $resultCode
+     * @param StepStat[]    $stepStats
+     */
+    public function printStepList(OutputPrinter $printer, $intro, $resultCode, array $stepStats)
+    {
+        if (!count($stepStats)) {
+            return;
+        }
+
+        $style = $this->resultConverter->convertResultCodeToString($resultCode);
+        $intro = $this->translator->trans($intro, array(), 'output');
+
+        $printer->writeln(sprintf('--- {+%s}%s{-%s}' . PHP_EOL, $style, $intro, $style));
+
+        foreach ($stepStats as $num => $stepStat) {
+            if ($stepStat instanceof StepStatV2) {
+                $this->printStepStat($printer, $num + 1, $stepStat, $style);
+            } elseif ($stepStat instanceof StepStat) {
+                $this->printStat($printer, $stepStat->getText(), $stepStat->getPath(), $style, $stepStat->getStdOut(), $stepStat->getError());
+            }
+        }
+    }
+
+    /**
+     * Prints failed hooks list.
+     *
+     * @param OutputPrinter $printer
+     * @param string        $intro
+     * @param HookStat[]    $failedHookStats
+     */
+    public function printFailedHooksList(OutputPrinter $printer, $intro, array $failedHookStats)
+    {
+        if (!count($failedHookStats)) {
+            return;
+        }
+
+        $style = $this->resultConverter->convertResultCodeToString(TestResult::FAILED);
+        $intro = $this->translator->trans($intro, array(), 'output');
+
+        $printer->writeln(sprintf('--- {+%s}%s{-%s}' . PHP_EOL, $style, $intro, $style));
+        foreach ($failedHookStats as $hookStat) {
+            $this->printHookStat($printer, $hookStat, $style);
+        }
+    }
+
+    /**
+     * Prints hook stat.
+     *
+     * @param OutputPrinter $printer
+     * @param string        $name
+     * @param string        $path
+     * @param string        $style
+     * @param null|string   $stdOut
+     * @param null|string   $error
+     *
+     * @deprecated Remove in 4.0
+     */
+    private function printStat(OutputPrinter $printer, $name, $path, $style, $stdOut, $error)
+    {
+        $path = $this->relativizePaths($path);
+        $printer->writeln(sprintf('    {+%s}%s{-%s} {+comment}# %s{-comment}', $style, $name, $style, $path));
+
+        $pad = function ($line) { return '      ' . $line; };
+
+        if (null !== $stdOut) {
+            $padText = function ($line) { return '      │ ' . $line; };
+            $stdOutString = array_map($padText, explode("\n", $stdOut));
+            $printer->writeln(implode("\n", $stdOutString));
+        }
+
+        if ($error) {
+            $exceptionString = implode("\n", array_map($pad, explode("\n", $error)));
+            $printer->writeln(sprintf('{+%s}%s{-%s}', $style, $exceptionString, $style));
+        }
+
+        $printer->writeln();
+    }
+
+    /**
+     * Prints hook stat.
+     *
+     * @param OutputPrinter $printer
+     * @param HookStat      $hookStat
+     * @param string        $style
+     */
+    private function printHookStat(OutputPrinter $printer, HookStat $hookStat, $style)
+    {
+        $printer->writeln(
+            sprintf('    {+%s}%s{-%s} {+comment}# %s{-comment}',
+                $style, $hookStat->getName(), $style, $this->relativizePaths($hookStat->getPath())
+            )
+        );
+
+        $pad = function ($line) { return '      ' . $line; };
+
+        if (null !== $hookStat->getStdOut()) {
+            $padText = function ($line) { return '      │ ' . $line; };
+            $stdOutString = array_map($padText, explode("\n", $hookStat->getStdOut()));
+            $printer->writeln(implode("\n", $stdOutString));
+        }
+
+        if ($hookStat->getError()) {
+            $exceptionString = implode("\n", array_map($pad, explode("\n", $hookStat->getError())));
+            $printer->writeln(sprintf('{+%s}%s{-%s}', $style, $exceptionString, $style));
+        }
+
+        $printer->writeln();
+    }
+
+    /**
+     * Prints hook stat.
+     *
+     * @param OutputPrinter $printer
+     * @param integer       $number
+     * @param StepStatV2    $stat
+     * @param string        $style
+     */
+    private function printStepStat(OutputPrinter $printer, $number, StepStatV2 $stat, $style)
+    {
+        $maxLength = max(mb_strlen($stat->getScenarioText(), 'utf8'), mb_strlen($stat->getStepText(), 'utf8') + 2) + 1;
+
+        $printer->writeln(
+            sprintf('%03d {+%s}%s{-%s}%s{+comment}# %s{-comment}',
+                $number,
+                $style,
+                $stat->getScenarioText(),
+                $style,
+                str_pad(' ', $maxLength - mb_strlen($stat->getScenarioText(), 'utf8')),
+                $this->relativizePaths($stat->getScenarioPath())
+            )
+        );
+
+        $printer->writeln(
+            sprintf('      {+%s}%s{-%s}%s{+comment}# %s{-comment}',
+                $style,
+                $stat->getStepText(),
+                $style,
+                str_pad(' ', $maxLength - mb_strlen($stat->getStepText(), 'utf8') - 2),
+                $this->relativizePaths($stat->getStepPath())
+            )
+        );
+
+        $pad = function ($line) { return '        ' . $line; };
+
+        if (null !== $stat->getStdOut()) {
+            $padText = function ($line) { return '        │ ' . $line; };
+            $stdOutString = array_map($padText, explode("\n", $stat->getStdOut()));
+            $printer->writeln(implode("\n", $stdOutString));
+        }
+
+        if ($stat->getError()) {
+            $exceptionString = implode("\n", array_map($pad, explode("\n", $stat->getError())));
+            $printer->writeln(sprintf('{+%s}%s{-%s}', $style, $exceptionString, $style));
+        }
+
+        $printer->writeln();
+    }
+
+    /**
+     * Transforms path to relative.
+     *
+     * @param string $path
+     *
+     * @return string
+     */
+    private function relativizePaths($path)
+    {
+        if (!$this->basePath) {
+            return $path;
+        }
+
+        return str_replace($this->basePath . DIRECTORY_SEPARATOR, '', $path);
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/OutlinePrinter.php b/vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/OutlinePrinter.php
new file mode 100644 (file)
index 0000000..eb460ad
--- /dev/null
@@ -0,0 +1,41 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Output\Node\Printer;
+
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\OutlineNode;
+use Behat\Testwork\Output\Formatter;
+use Behat\Testwork\Tester\Result\TestResult;
+
+/**
+ * Prints outline headers and footers.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface OutlinePrinter
+{
+    /**
+     * Prints outline header using provided printer.
+     *
+     * @param Formatter   $formatter
+     * @param FeatureNode $feature
+     * @param OutlineNode $outline
+     */
+    public function printHeader(Formatter $formatter, FeatureNode $feature, OutlineNode $outline);
+
+    /**
+     * Prints outline footer using provided printer.
+     *
+     * @param Formatter  $formatter
+     * @param TestResult $result
+     */
+    public function printFooter(Formatter $formatter, TestResult $result);
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/OutlineTablePrinter.php b/vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/OutlineTablePrinter.php
new file mode 100644 (file)
index 0000000..488fae6
--- /dev/null
@@ -0,0 +1,43 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Output\Node\Printer;
+
+use Behat\Behat\Tester\Result\StepResult;
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\OutlineNode;
+use Behat\Testwork\Output\Formatter;
+use Behat\Testwork\Tester\Result\TestResult;
+
+/**
+ * Prints outline table representation headers and footers.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface OutlineTablePrinter
+{
+    /**
+     * Prints outline header using provided printer and first row example step results.
+     *
+     * @param Formatter    $formatter
+     * @param FeatureNode  $feature
+     * @param OutlineNode  $outline
+     * @param StepResult[] $results
+     */
+    public function printHeader(Formatter $formatter, FeatureNode $feature, OutlineNode $outline, array $results);
+
+    /**
+     * Prints outline footer using provided printer.
+     *
+     * @param Formatter  $formatter
+     * @param TestResult $result
+     */
+    public function printFooter(Formatter $formatter, TestResult $result);
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/Pretty/PrettyExamplePrinter.php b/vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/Pretty/PrettyExamplePrinter.php
new file mode 100644 (file)
index 0000000..2d5babf
--- /dev/null
@@ -0,0 +1,74 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Output\Node\Printer\Pretty;
+
+use Behat\Behat\Output\Node\Printer\ExamplePrinter;
+use Behat\Gherkin\Node\ExampleNode;
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Testwork\Output\Formatter;
+use Behat\Testwork\Output\Printer\OutputPrinter;
+use Behat\Testwork\Tester\Result\TestResult;
+
+/**
+ * Prints example header (usually simply an example row) and footer.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class PrettyExamplePrinter implements ExamplePrinter
+{
+    /**
+     * @var PrettyPathPrinter
+     */
+    private $pathPrinter;
+    /**
+     * @var string
+     */
+    private $indentText;
+
+    /**
+     * Initializes printer.
+     *
+     * @param PrettyPathPrinter $pathPrinter
+     * @param integer           $indentation
+     */
+    public function __construct(PrettyPathPrinter $pathPrinter, $indentation = 6)
+    {
+        $this->pathPrinter = $pathPrinter;
+        $this->indentText = str_repeat(' ', intval($indentation));
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function printHeader(Formatter $formatter, FeatureNode $feature, ExampleNode $example)
+    {
+        $this->printTitle($formatter->getOutputPrinter(), $example);
+        $this->pathPrinter->printScenarioPath($formatter, $feature, $example, mb_strlen($this->indentText, 'utf8'));
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function printFooter(Formatter $formatter, TestResult $result)
+    {
+    }
+
+    /**
+     * Prints example title.
+     *
+     * @param OutputPrinter $printer
+     * @param ExampleNode   $example
+     */
+    private function printTitle(OutputPrinter $printer, ExampleNode $example)
+    {
+        $printer->write(sprintf('%s%s', $this->indentText, $example->getTitle()));
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/Pretty/PrettyExampleRowPrinter.php b/vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/Pretty/PrettyExampleRowPrinter.php
new file mode 100644 (file)
index 0000000..109dd25
--- /dev/null
@@ -0,0 +1,185 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Output\Node\Printer\Pretty;
+
+use Behat\Behat\EventDispatcher\Event\AfterStepTested;
+use Behat\Behat\Output\Node\Printer\ExampleRowPrinter;
+use Behat\Behat\Output\Node\Printer\Helper\ResultToStringConverter;
+use Behat\Behat\Tester\Result\ExecutedStepResult;
+use Behat\Behat\Tester\Result\StepResult;
+use Behat\Gherkin\Node\ExampleNode;
+use Behat\Gherkin\Node\OutlineNode;
+use Behat\Testwork\EventDispatcher\Event\AfterTested;
+use Behat\Testwork\Exception\ExceptionPresenter;
+use Behat\Testwork\Output\Formatter;
+use Behat\Testwork\Output\Printer\OutputPrinter;
+use Behat\Testwork\Tester\Result\ExceptionResult;
+use Behat\Testwork\Tester\Result\TestResults;
+
+/**
+ * Prints example results in form of a table row.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class PrettyExampleRowPrinter implements ExampleRowPrinter
+{
+    /**
+     * @var ResultToStringConverter
+     */
+    private $resultConverter;
+    /**
+     * @var ExceptionPresenter
+     */
+    private $exceptionPresenter;
+    /**
+     * @var string
+     */
+    private $indentText;
+    /**
+     * @var string
+     */
+    private $subIndentText;
+
+    /**
+     * Initializes printer.
+     *
+     * @param ResultToStringConverter $resultConverter
+     * @param ExceptionPresenter      $exceptionPresenter
+     * @param integer                 $indentation
+     * @param integer                 $subIndentation
+     */
+    public function __construct(
+        ResultToStringConverter $resultConverter,
+        ExceptionPresenter $exceptionPresenter,
+        $indentation = 6,
+        $subIndentation = 2
+    ) {
+        $this->resultConverter = $resultConverter;
+        $this->exceptionPresenter = $exceptionPresenter;
+        $this->indentText = str_repeat(' ', intval($indentation));
+        $this->subIndentText = $this->indentText . str_repeat(' ', intval($subIndentation));
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function printExampleRow(Formatter $formatter, OutlineNode $outline, ExampleNode $example, array $events)
+    {
+        $rowNum = array_search($example, $outline->getExamples()) + 1;
+        $wrapper = $this->getWrapperClosure($outline, $example, $events);
+        $row = $outline->getExampleTable()->getRowAsStringWithWrappedValues($rowNum, $wrapper);
+
+        $formatter->getOutputPrinter()->writeln(sprintf('%s%s', $this->indentText, $row));
+        $this->printStepExceptionsAndStdOut($formatter->getOutputPrinter(), $events);
+    }
+
+    /**
+     * Creates wrapper-closure for the example table.
+     *
+     * @param OutlineNode   $outline
+     * @param ExampleNode   $example
+     * @param AfterStepTested[] $stepEvents
+     *
+     * @return callable
+     */
+    private function getWrapperClosure(OutlineNode $outline, ExampleNode $example, array $stepEvents)
+    {
+        $resultConverter = $this->resultConverter;
+
+        return function ($value, $column) use ($outline, $example, $stepEvents, $resultConverter) {
+            $results = array();
+            foreach ($stepEvents as $event) {
+                $index = array_search($event->getStep(), $example->getSteps());
+                $header = $outline->getExampleTable()->getRow(0);
+                $steps = $outline->getSteps();
+                $outlineStepText = $steps[$index]->getText();
+
+                if (false !== strpos($outlineStepText, '<' . $header[$column] . '>')) {
+                    $results[] = $event->getTestResult();
+                }
+            }
+
+            $result = new TestResults($results);
+            $style = $resultConverter->convertResultToString($result);
+
+            return sprintf('{+%s}%s{-%s}', $style, $value, $style);
+        };
+    }
+
+    /**
+     * Prints step events exceptions (if has some).
+     *
+     * @param OutputPrinter $printer
+     * @param AfterTested[] $events
+     */
+    private function printStepExceptionsAndStdOut(OutputPrinter $printer, array $events)
+    {
+        foreach ($events as $event) {
+            $this->printStepStdOut($printer, $event->getTestResult());
+            $this->printStepException($printer, $event->getTestResult());
+        }
+    }
+
+    /**
+     * Prints step exception (if has one).
+     *
+     * @param OutputPrinter $printer
+     * @param StepResult    $result
+     */
+    private function printStepException(OutputPrinter $printer, StepResult $result)
+    {
+        $style = $this->resultConverter->convertResultToString($result);
+
+        if (!$result instanceof ExceptionResult || !$result->hasException()) {
+            return;
+        }
+
+        $text = $this->exceptionPresenter->presentException($result->getException());
+        $indentedText = implode("\n", array_map(array($this, 'subIndent'), explode("\n", $text)));
+        $printer->writeln(sprintf('{+%s}%s{-%s}', $style, $indentedText, $style));
+    }
+
+    /**
+     * Prints step output (if has one).
+     *
+     * @param OutputPrinter $printer
+     * @param StepResult    $result
+     */
+    private function printStepStdOut(OutputPrinter $printer, StepResult $result)
+    {
+        if (!$result instanceof ExecutedStepResult || null === $result->getCallResult()->getStdOut()) {
+            return;
+        }
+
+        $callResult = $result->getCallResult();
+        $indentedText = $this->subIndentText;
+
+        $pad = function ($line) use ($indentedText) {
+            return sprintf(
+                '%s│ {+stdout}%s{-stdout}', $indentedText, $line
+            );
+        };
+
+        $printer->writeln(implode("\n", array_map($pad, explode("\n", $callResult->getStdOut()))));
+    }
+
+    /**
+     * Indents text to the subIndentation level.
+     *
+     * @param string $text
+     *
+     * @return string
+     */
+    private function subIndent($text)
+    {
+        return $this->subIndentText . $text;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/Pretty/PrettyFeaturePrinter.php b/vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/Pretty/PrettyFeaturePrinter.php
new file mode 100644 (file)
index 0000000..1a352c7
--- /dev/null
@@ -0,0 +1,133 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Output\Node\Printer\Pretty;
+
+use Behat\Behat\Output\Node\Printer\FeaturePrinter;
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\TaggedNodeInterface;
+use Behat\Testwork\Output\Formatter;
+use Behat\Testwork\Output\Printer\OutputPrinter;
+use Behat\Testwork\Tester\Result\TestResult;
+
+/**
+ * Prints feature header and footer.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class PrettyFeaturePrinter implements FeaturePrinter
+{
+    /**
+     * @var string
+     */
+    private $indentText;
+    /**
+     * @var string
+     */
+    private $subIndentText;
+
+    /**
+     * Initializes printer.
+     *
+     * @param integer $indentation
+     * @param integer $subIndentation
+     */
+    public function __construct($indentation = 0, $subIndentation = 2)
+    {
+        $this->indentText = str_repeat(' ', intval($indentation));
+        $this->subIndentText = $this->indentText . str_repeat(' ', intval($subIndentation));
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function printHeader(Formatter $formatter, FeatureNode $feature)
+    {
+        if ($feature instanceof TaggedNodeInterface) {
+            $this->printTags($formatter->getOutputPrinter(), $feature->getTags());
+        }
+
+        $this->printTitle($formatter->getOutputPrinter(), $feature);
+        $this->printDescription($formatter->getOutputPrinter(), $feature);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function printFooter(Formatter $formatter, TestResult $result)
+    {
+    }
+
+    /**
+     * Prints feature tags.
+     *
+     * @param OutputPrinter $printer
+     * @param string[]      $tags
+     */
+    private function printTags(OutputPrinter $printer, array $tags)
+    {
+        if (!count($tags)) {
+            return;
+        }
+
+        $tags = array_map(array($this, 'prependTagWithTagSign'), $tags);
+        $printer->writeln(sprintf('%s{+tag}%s{-tag}', $this->indentText, implode(' ', $tags)));
+    }
+
+    /**
+     * Prints feature title using provided printer.
+     *
+     * @param OutputPrinter $printer
+     * @param FeatureNode   $feature
+     */
+    private function printTitle(OutputPrinter $printer, FeatureNode $feature)
+    {
+        $printer->write(sprintf('%s{+keyword}%s:{-keyword}', $this->indentText, $feature->getKeyword()));
+
+        if ($title = $feature->getTitle()) {
+            $printer->write(sprintf(' %s', $title));
+        }
+
+        $printer->writeln();
+    }
+
+    /**
+     * Prints feature description using provided printer.
+     *
+     * @param OutputPrinter $printer
+     * @param FeatureNode   $feature
+     */
+    private function printDescription(OutputPrinter $printer, FeatureNode $feature)
+    {
+        if (!$feature->getDescription()) {
+            $printer->writeln();
+
+            return;
+        }
+
+        foreach (explode("\n", $feature->getDescription()) as $descriptionLine) {
+            $printer->writeln(sprintf('%s%s', $this->subIndentText, $descriptionLine));
+        }
+
+        $printer->writeln();
+    }
+
+    /**
+     * Prepends tags string with tag-sign.
+     *
+     * @param string $tag
+     *
+     * @return string
+     */
+    private function prependTagWithTagSign($tag)
+    {
+        return '@' . $tag;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/Pretty/PrettyOutlinePrinter.php b/vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/Pretty/PrettyOutlinePrinter.php
new file mode 100644 (file)
index 0000000..8fbc033
--- /dev/null
@@ -0,0 +1,140 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Output\Node\Printer\Pretty;
+
+use Behat\Behat\Output\Node\Printer\Helper\ResultToStringConverter;
+use Behat\Behat\Output\Node\Printer\OutlinePrinter;
+use Behat\Behat\Output\Node\Printer\ScenarioPrinter;
+use Behat\Behat\Output\Node\Printer\StepPrinter;
+use Behat\Behat\Tester\Result\UndefinedStepResult;
+use Behat\Gherkin\Node\ExampleTableNode;
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\OutlineNode;
+use Behat\Gherkin\Node\StepNode;
+use Behat\Testwork\Output\Formatter;
+use Behat\Testwork\Output\Printer\OutputPrinter;
+use Behat\Testwork\Tester\Result\TestResult;
+
+/**
+ * Prints outline header with outline steps and table header.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class PrettyOutlinePrinter implements OutlinePrinter
+{
+    /**
+     * @var ScenarioPrinter
+     */
+    private $scenarioPrinter;
+    /**
+     * @var StepPrinter
+     */
+    private $stepPrinter;
+    /**
+     * @var ResultToStringConverter
+     */
+    private $resultConverter;
+    /**
+     * @var string
+     */
+    private $indentText;
+    /**
+     * @var string
+     */
+    private $subIndentText;
+
+    /**
+     * @param ScenarioPrinter         $scenarioPrinter
+     * @param StepPrinter             $stepPrinter
+     * @param ResultToStringConverter $resultConverter
+     * @param integer                 $indentation
+     * @param integer                 $subIndentation
+     */
+    public function __construct(
+        ScenarioPrinter $scenarioPrinter,
+        StepPrinter $stepPrinter,
+        ResultToStringConverter $resultConverter,
+        $indentation = 4,
+        $subIndentation = 2
+    ) {
+        $this->scenarioPrinter = $scenarioPrinter;
+        $this->stepPrinter = $stepPrinter;
+        $this->resultConverter = $resultConverter;
+        $this->indentText = str_repeat(' ', intval($indentation));
+        $this->subIndentText = $this->indentText . str_repeat(' ', intval($subIndentation));
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function printHeader(Formatter $formatter, FeatureNode $feature, OutlineNode $outline)
+    {
+        $this->scenarioPrinter->printHeader($formatter, $feature, $outline);
+
+        $this->printExamplesSteps($formatter, $outline, $outline->getSteps());
+        $this->printExamplesTableHeader($formatter->getOutputPrinter(), $outline->getExampleTable());
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function printFooter(Formatter $formatter, TestResult $result)
+    {
+        $formatter->getOutputPrinter()->writeln();
+    }
+
+    /**
+     * Prints outline steps.
+     *
+     * @param Formatter   $formatter
+     * @param OutlineNode $outline
+     * @param StepNode[]  $steps
+     */
+    private function printExamplesSteps(Formatter $formatter, OutlineNode $outline, array $steps)
+    {
+        foreach ($steps as $step) {
+            $this->stepPrinter->printStep($formatter, $outline, $step, new UndefinedStepResult());
+        }
+
+        $formatter->getOutputPrinter()->writeln();
+    }
+
+    /**
+     * Prints examples table header.
+     *
+     * @param OutputPrinter    $printer
+     * @param ExampleTableNode $table
+     */
+    private function printExamplesTableHeader(OutputPrinter $printer, ExampleTableNode $table)
+    {
+        $printer->writeln(sprintf('%s{+keyword}%s:{-keyword}', $this->indentText, $table->getKeyword()));
+
+        $rowNum = 0;
+        $wrapper = $this->getWrapperClosure();
+        $row = $table->getRowAsStringWithWrappedValues($rowNum, $wrapper);
+
+        $printer->writeln(sprintf('%s%s', $this->subIndentText, $row));
+    }
+
+    /**
+     * Creates wrapper-closure for the example header.
+     *
+     * @return callable
+     */
+    private function getWrapperClosure()
+    {
+        $style = $this->resultConverter->convertResultCodeToString(TestResult::SKIPPED);
+
+        return function ($col) use ($style) {
+            return sprintf('{+%s_param}%s{-%s_param}', $style, $col, $style);
+        };
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/Pretty/PrettyOutlineTablePrinter.php b/vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/Pretty/PrettyOutlineTablePrinter.php
new file mode 100644 (file)
index 0000000..ea0298e
--- /dev/null
@@ -0,0 +1,145 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Output\Node\Printer\Pretty;
+
+use Behat\Behat\Output\Node\Printer\Helper\ResultToStringConverter;
+use Behat\Behat\Output\Node\Printer\OutlineTablePrinter;
+use Behat\Behat\Output\Node\Printer\ScenarioPrinter;
+use Behat\Behat\Output\Node\Printer\StepPrinter;
+use Behat\Behat\Tester\Result\StepResult;
+use Behat\Gherkin\Node\ExampleTableNode;
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\OutlineNode;
+use Behat\Gherkin\Node\StepNode;
+use Behat\Testwork\Output\Formatter;
+use Behat\Testwork\Output\Printer\OutputPrinter;
+use Behat\Testwork\Tester\Result\TestResult;
+
+/**
+ * Prints outline table header and footer.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class PrettyOutlineTablePrinter implements OutlineTablePrinter
+{
+    /**
+     * @var ScenarioPrinter
+     */
+    private $scenarioPrinter;
+    /**
+     * @var StepPrinter
+     */
+    private $stepPrinter;
+    /**
+     * @var ResultToStringConverter
+     */
+    private $resultConverter;
+    /**
+     * @var string
+     */
+    private $indentText;
+    /**
+     * @var string
+     */
+    private $subIndentText;
+
+    /**
+     * Initializes printer.
+     *
+     * @param ScenarioPrinter         $scenarioPrinter
+     * @param StepPrinter             $stepPrinter
+     * @param ResultToStringConverter $resultConverter
+     * @param integer                 $indentation
+     * @param integer                 $subIndentation
+     */
+    public function __construct(
+        ScenarioPrinter $scenarioPrinter,
+        StepPrinter $stepPrinter,
+        ResultToStringConverter $resultConverter,
+        $indentation = 4,
+        $subIndentation = 2
+    ) {
+        $this->scenarioPrinter = $scenarioPrinter;
+        $this->stepPrinter = $stepPrinter;
+        $this->resultConverter = $resultConverter;
+        $this->indentText = str_repeat(' ', intval($indentation));
+        $this->subIndentText = $this->indentText . str_repeat(' ', intval($subIndentation));
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function printHeader(Formatter $formatter, FeatureNode $feature, OutlineNode $outline, array $results)
+    {
+        $this->scenarioPrinter->printHeader($formatter, $feature, $outline);
+
+        $this->printExamplesSteps($formatter, $outline, $outline->getSteps(), $results);
+        $this->printExamplesTableHeader($formatter->getOutputPrinter(), $outline->getExampleTable());
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function printFooter(Formatter $formatter, TestResult $result)
+    {
+        $formatter->getOutputPrinter()->writeln();
+    }
+
+    /**
+     * Prints example steps with definition paths (if has some), but without exceptions or state (skipped).
+     *
+     * @param Formatter    $formatter
+     * @param OutlineNode  $outline
+     * @param StepNode[]   $steps
+     * @param StepResult[] $results
+     */
+    private function printExamplesSteps(Formatter $formatter, OutlineNode $outline, array $steps, array $results)
+    {
+        foreach ($steps as $step) {
+            $result = $results[$step->getLine()];
+
+            $this->stepPrinter->printStep($formatter, $outline, $step, $result);
+        }
+
+        $formatter->getOutputPrinter()->writeln();
+    }
+
+    /**
+     * Prints examples table header.
+     *
+     * @param OutputPrinter    $printer
+     * @param ExampleTableNode $table
+     */
+    private function printExamplesTableHeader(OutputPrinter $printer, ExampleTableNode $table)
+    {
+        $printer->writeln(sprintf('%s{+keyword}%s:{-keyword}', $this->indentText, $table->getKeyword()));
+
+        $rowNum = 0;
+        $wrapper = $this->getWrapperClosure();
+        $row = $table->getRowAsStringWithWrappedValues($rowNum, $wrapper);
+
+        $printer->writeln(sprintf('%s%s', $this->subIndentText, $row));
+    }
+
+    /**
+     * Creates wrapper-closure for the example header.
+     *
+     * @return callable
+     */
+    private function getWrapperClosure()
+    {
+        $style = $this->resultConverter->convertResultCodeToString(TestResult::SKIPPED);
+
+        return function ($col) use ($style) {
+            return sprintf('{+%s_param}%s{-%s_param}', $style, $col, $style);
+        };
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/Pretty/PrettyPathPrinter.php b/vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/Pretty/PrettyPathPrinter.php
new file mode 100644 (file)
index 0000000..9ea0b68
--- /dev/null
@@ -0,0 +1,137 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Output\Node\Printer\Pretty;
+
+use Behat\Behat\Output\Node\Printer\Helper\WidthCalculator;
+use Behat\Behat\Tester\Result\DefinedStepResult;
+use Behat\Behat\Tester\Result\StepResult;
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\ScenarioLikeInterface as Scenario;
+use Behat\Gherkin\Node\StepNode;
+use Behat\Testwork\Output\Formatter;
+use Behat\Testwork\Output\Printer\OutputPrinter;
+
+/**
+ * Prints paths for scenarios, examples, backgrounds and steps.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class PrettyPathPrinter
+{
+    /**
+     * @var WidthCalculator
+     */
+    private $widthCalculator;
+    /**
+     * @var string
+     */
+    private $basePath;
+
+    /**
+     * Initializes printer.
+     *
+     * @param WidthCalculator $widthCalculator
+     * @param string          $basePath
+     */
+    public function __construct(WidthCalculator $widthCalculator, $basePath)
+    {
+        $this->widthCalculator = $widthCalculator;
+        $this->basePath = $basePath;
+    }
+
+    /**
+     * Prints scenario path comment.
+     *
+     * @param Formatter   $formatter
+     * @param FeatureNode $feature
+     * @param Scenario    $scenario
+     * @param integer     $indentation
+     */
+    public function printScenarioPath(Formatter $formatter, FeatureNode $feature, Scenario $scenario, $indentation)
+    {
+        $printer = $formatter->getOutputPrinter();
+
+        if (!$formatter->getParameter('paths')) {
+            $printer->writeln();
+
+            return;
+        }
+
+        $fileAndLine = sprintf('%s:%s', $this->relativizePaths($feature->getFile()), $scenario->getLine());
+        $headerWidth = $this->widthCalculator->calculateScenarioHeaderWidth($scenario, $indentation);
+        $scenarioWidth = $this->widthCalculator->calculateScenarioWidth($scenario, $indentation, 2);
+        $spacing = str_repeat(' ', max(0, $scenarioWidth - $headerWidth));
+
+        $printer->writeln(sprintf('%s {+comment}# %s{-comment}', $spacing, $fileAndLine));
+    }
+
+    /**
+     * Prints step path comment.
+     *
+     * @param Formatter  $formatter
+     * @param Scenario   $scenario
+     * @param StepNode   $step
+     * @param StepResult $result
+     * @param integer    $indentation
+     */
+    public function printStepPath(
+        Formatter $formatter,
+        Scenario $scenario,
+        StepNode $step,
+        StepResult $result,
+        $indentation
+    ) {
+        $printer = $formatter->getOutputPrinter();
+
+        if (!$result instanceof DefinedStepResult || !$result->getStepDefinition() || !$formatter->getParameter('paths')) {
+            $printer->writeln();
+
+            return;
+        }
+
+        $textWidth = $this->widthCalculator->calculateStepWidth($step, $indentation);
+        $scenarioWidth = $this->widthCalculator->calculateScenarioWidth($scenario, $indentation - 2, 2);
+
+        $this->printDefinedStepPath($printer, $result, $scenarioWidth, $textWidth);
+    }
+
+    /**
+     * Prints defined step path.
+     *
+     * @param OutputPrinter     $printer
+     * @param DefinedStepResult $result
+     * @param integer           $scenarioWidth
+     * @param integer           $stepWidth
+     */
+    private function printDefinedStepPath(OutputPrinter $printer, DefinedStepResult $result, $scenarioWidth, $stepWidth)
+    {
+        $path = $result->getStepDefinition()->getPath();
+        $spacing = str_repeat(' ', max(0, $scenarioWidth - $stepWidth));
+
+        $printer->writeln(sprintf('%s {+comment}# %s{-comment}', $spacing, $path));
+    }
+
+    /**
+     * Transforms path to relative.
+     *
+     * @param string $path
+     *
+     * @return string
+     */
+    private function relativizePaths($path)
+    {
+        if (!$this->basePath) {
+            return $path;
+        }
+
+        return str_replace($this->basePath . DIRECTORY_SEPARATOR, '', $path);
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/Pretty/PrettyScenarioPrinter.php b/vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/Pretty/PrettyScenarioPrinter.php
new file mode 100644 (file)
index 0000000..378a991
--- /dev/null
@@ -0,0 +1,148 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Output\Node\Printer\Pretty;
+
+use Behat\Behat\Output\Node\Printer\ScenarioPrinter;
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\ScenarioLikeInterface as Scenario;
+use Behat\Gherkin\Node\TaggedNodeInterface;
+use Behat\Testwork\Output\Formatter;
+use Behat\Testwork\Output\Printer\OutputPrinter;
+use Behat\Testwork\Tester\Result\TestResult;
+
+/**
+ * Prints scenario headers (with tags, keyword and long title) and footers.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class PrettyScenarioPrinter implements ScenarioPrinter
+{
+    /**
+     * @var PrettyPathPrinter
+     */
+    private $pathPrinter;
+    /**
+     * @var string
+     */
+    private $indentText;
+    /**
+     * @var string
+     */
+    private $subIndentText;
+
+    /**
+     * Initializes printer.
+     *
+     * @param PrettyPathPrinter $pathPrinter
+     * @param integer           $indentation
+     * @param integer           $subIndentation
+     */
+    public function __construct(PrettyPathPrinter $pathPrinter, $indentation = 2, $subIndentation = 2)
+    {
+        $this->pathPrinter = $pathPrinter;
+        $this->indentText = str_repeat(' ', intval($indentation));
+        $this->subIndentText = $this->indentText . str_repeat(' ', intval($subIndentation));
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function printHeader(Formatter $formatter, FeatureNode $feature, Scenario $scenario)
+    {
+        if ($scenario instanceof TaggedNodeInterface) {
+            $this->printTags($formatter->getOutputPrinter(), $scenario->getTags());
+        }
+
+        $this->printKeyword($formatter->getOutputPrinter(), $scenario->getKeyword());
+        $this->printTitle($formatter->getOutputPrinter(), $scenario->getTitle());
+        $this->pathPrinter->printScenarioPath($formatter, $feature, $scenario, mb_strlen($this->indentText, 'utf8'));
+        $this->printDescription($formatter->getOutputPrinter(), $scenario->getTitle());
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function printFooter(Formatter $formatter, TestResult $result)
+    {
+        $formatter->getOutputPrinter()->writeln();
+    }
+
+    /**
+     * Prints scenario tags.
+     *
+     * @param OutputPrinter $printer
+     * @param string[]      $tags
+     */
+    private function printTags(OutputPrinter $printer, array $tags)
+    {
+        if (!count($tags)) {
+            return;
+        }
+
+        $tags = array_map(array($this, 'prependTagWithTagSign'), $tags);
+        $printer->writeln(sprintf('%s{+tag}%s{-tag}', $this->indentText, implode(' ', $tags)));
+    }
+
+    /**
+     * Prints scenario keyword.
+     *
+     * @param OutputPrinter $printer
+     * @param string        $keyword
+     */
+    private function printKeyword(OutputPrinter $printer, $keyword)
+    {
+        $printer->write(sprintf('%s{+keyword}%s:{-keyword}', $this->indentText, $keyword));
+    }
+
+    /**
+     * Prints scenario title (first line of long title).
+     *
+     * @param OutputPrinter $printer
+     * @param string        $longTitle
+     */
+    private function printTitle(OutputPrinter $printer, $longTitle)
+    {
+        $description = explode("\n", $longTitle);
+        $title = array_shift($description);
+
+        if ('' !== $title) {
+            $printer->write(sprintf(' %s', $title));
+        }
+    }
+
+    /**
+     * Prints scenario description (other lines of long title).
+     *
+     * @param OutputPrinter $printer
+     * @param string        $longTitle
+     */
+    private function printDescription(OutputPrinter $printer, $longTitle)
+    {
+        $lines = explode("\n", $longTitle);
+        array_shift($lines);
+
+        foreach ($lines as $line) {
+            $printer->writeln(sprintf('%s%s', $this->subIndentText, $line));
+        }
+    }
+
+    /**
+     * Prepends tags string with tag-sign.
+     *
+     * @param string $tag
+     *
+     * @return string
+     */
+    private function prependTagWithTagSign($tag)
+    {
+        return '@' . $tag;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/Pretty/PrettySetupPrinter.php b/vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/Pretty/PrettySetupPrinter.php
new file mode 100644 (file)
index 0000000..46bcba3
--- /dev/null
@@ -0,0 +1,212 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Output\Node\Printer\Pretty;
+
+use Behat\Behat\Output\Node\Printer\Helper\ResultToStringConverter;
+use Behat\Behat\Output\Node\Printer\SetupPrinter;
+use Behat\Testwork\Call\CallResult;
+use Behat\Testwork\Exception\ExceptionPresenter;
+use Behat\Testwork\Hook\Tester\Setup\HookedSetup;
+use Behat\Testwork\Hook\Tester\Setup\HookedTeardown;
+use Behat\Testwork\Output\Formatter;
+use Behat\Testwork\Output\Printer\OutputPrinter;
+use Behat\Testwork\Tester\Result\TestResult;
+use Behat\Testwork\Tester\Setup\Setup;
+use Behat\Testwork\Tester\Setup\Teardown;
+
+/**
+ * Prints hooks in a pretty fashion.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class PrettySetupPrinter implements SetupPrinter
+{
+    /**
+     * @var ResultToStringConverter
+     */
+    private $resultConverter;
+    /**
+     * @var ExceptionPresenter
+     */
+    private $exceptionPresenter;
+    /**
+     * @var string
+     */
+    private $indentText;
+    /**
+     * @var bool
+     */
+    private $newlineBefore;
+    /**
+     * @var bool
+     */
+    private $newlineAfter;
+
+    /**
+     * Initializes printer.
+     *
+     * @param ResultToStringConverter $resultConverter
+     * @param ExceptionPresenter      $exceptionPresenter
+     * @param integer                 $indentation
+     * @param Boolean                 $newlineBefore
+     * @param Boolean                 $newlineAfter
+     */
+    public function __construct(
+        ResultToStringConverter $resultConverter,
+        ExceptionPresenter $exceptionPresenter,
+        $indentation = 0,
+        $newlineBefore = false,
+        $newlineAfter = false
+    ) {
+        $this->resultConverter = $resultConverter;
+        $this->exceptionPresenter = $exceptionPresenter;
+        $this->indentText = str_repeat(' ', intval($indentation));
+        $this->newlineBefore = $newlineBefore;
+        $this->newlineAfter = $newlineAfter;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function printSetup(Formatter $formatter, Setup $setup)
+    {
+        if (!$setup instanceof HookedSetup) {
+            return;
+        }
+
+        foreach ($setup->getHookCallResults() as $callResult) {
+            $this->printSetupHookCallResult($formatter->getOutputPrinter(), $callResult);
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function printTeardown(Formatter $formatter, Teardown $teardown)
+    {
+        if (!$teardown instanceof HookedTeardown) {
+            return;
+        }
+
+        foreach ($teardown->getHookCallResults() as $callResult) {
+            $this->printTeardownHookCallResult($formatter->getOutputPrinter(), $callResult);
+        }
+    }
+
+    /**
+     * Prints setup hook call result.
+     *
+     * @param OutputPrinter $printer
+     * @param CallResult    $callResult
+     */
+    private function printSetupHookCallResult(OutputPrinter $printer, CallResult $callResult)
+    {
+        if (!$callResult->hasStdOut() && !$callResult->hasException()) {
+            return;
+        }
+
+        $resultCode = $callResult->hasException() ? TestResult::FAILED : TestResult::PASSED;
+        $style = $this->resultConverter->convertResultCodeToString($resultCode);
+        $hook = $callResult->getCall()->getCallee();
+        $path = $hook->getPath();
+
+        $printer->writeln(
+            sprintf('%s┌─ {+%s}@%s{-%s} {+comment}# %s{-comment}', $this->indentText, $style, $hook, $style, $path)
+        );
+
+        $printer->writeln(sprintf('%s│', $this->indentText));
+
+        $this->printHookCallStdOut($printer, $callResult, $this->indentText);
+        $this->printHookCallException($printer, $callResult, $this->indentText);
+
+        if ($this->newlineBefore) {
+            $printer->writeln();
+        }
+    }
+
+    /**
+     * Prints teardown hook call result.
+     *
+     * @param OutputPrinter $printer
+     * @param CallResult    $callResult
+     */
+    private function printTeardownHookCallResult(OutputPrinter $printer, CallResult $callResult)
+    {
+        if (!$callResult->hasStdOut() && !$callResult->hasException()) {
+            return;
+        }
+
+        $resultCode = $callResult->hasException() ? TestResult::FAILED : TestResult::PASSED;
+        $style = $this->resultConverter->convertResultCodeToString($resultCode);
+        $hook = $callResult->getCall()->getCallee();
+        $path = $hook->getPath();
+
+        $printer->writeln(sprintf('%s│', $this->indentText));
+
+        $this->printHookCallStdOut($printer, $callResult, $this->indentText);
+        $this->printHookCallException($printer, $callResult, $this->indentText);
+
+        $printer->writeln(
+            sprintf('%s└─ {+%s}@%s{-%s} {+comment}# %s{-comment}', $this->indentText, $style, $hook, $style, $path)
+        );
+
+        if ($this->newlineAfter) {
+            $printer->writeln();
+        }
+    }
+
+    /**
+     * Prints hook call output (if has some).
+     *
+     * @param OutputPrinter $printer
+     * @param CallResult    $callResult
+     * @param string        $indentText
+     */
+    private function printHookCallStdOut(OutputPrinter $printer, CallResult $callResult, $indentText)
+    {
+        if (!$callResult->hasStdOut()) {
+            return;
+        }
+
+        $pad = function ($line) use ($indentText) {
+            return sprintf(
+                '%s│  {+stdout}%s{-stdout}', $indentText, $line
+            );
+        };
+
+        $printer->writeln(implode("\n", array_map($pad, explode("\n", $callResult->getStdOut()))));
+        $printer->writeln(sprintf('%s│', $indentText));
+    }
+
+    /**
+     * Prints hook call exception (if has some).
+     *
+     * @param OutputPrinter $printer
+     * @param CallResult    $callResult
+     * @param string        $indentText
+     */
+    private function printHookCallException(OutputPrinter $printer, CallResult $callResult, $indentText)
+    {
+        if (!$callResult->hasException()) {
+            return;
+        }
+
+        $pad = function ($l) use ($indentText) {
+            return sprintf(
+                '%s╳  {+exception}%s{-exception}', $indentText, $l
+            );
+        };
+
+        $exception = $this->exceptionPresenter->presentException($callResult->getException());
+        $printer->writeln(implode("\n", array_map($pad, explode("\n", $exception))));
+        $printer->writeln(sprintf('%s│', $indentText));
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/Pretty/PrettySkippedStepPrinter.php b/vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/Pretty/PrettySkippedStepPrinter.php
new file mode 100644 (file)
index 0000000..718afd3
--- /dev/null
@@ -0,0 +1,162 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Output\Node\Printer\Pretty;
+
+use Behat\Behat\Output\Node\Printer\Helper\ResultToStringConverter;
+use Behat\Behat\Output\Node\Printer\Helper\StepTextPainter;
+use Behat\Behat\Output\Node\Printer\StepPrinter;
+use Behat\Behat\Tester\Result\DefinedStepResult;
+use Behat\Behat\Tester\Result\StepResult;
+use Behat\Gherkin\Node\ArgumentInterface;
+use Behat\Gherkin\Node\PyStringNode;
+use Behat\Gherkin\Node\ScenarioLikeInterface as Scenario;
+use Behat\Gherkin\Node\StepNode;
+use Behat\Testwork\Output\Formatter;
+use Behat\Testwork\Output\Printer\OutputPrinter;
+use Behat\Testwork\Tester\Result\IntegerTestResult;
+use Behat\Testwork\Tester\Result\TestResult;
+
+/**
+ * Prints steps as skipped.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class PrettySkippedStepPrinter implements StepPrinter
+{
+    /**
+     * @var StepTextPainter
+     */
+    private $textPainter;
+    /**
+     * @var ResultToStringConverter
+     */
+    private $resultConverter;
+    /**
+     * @var PrettyPathPrinter
+     */
+    private $pathPrinter;
+    /**
+     * @var string
+     */
+    private $indentText;
+    /**
+     * @var string
+     */
+    private $subIndentText;
+
+    /**
+     * Initializes printer.
+     *
+     * @param StepTextPainter         $textPainter
+     * @param ResultToStringConverter $resultConverter
+     * @param PrettyPathPrinter       $pathPrinter
+     * @param integer                 $indentation
+     * @param integer                 $subIndentation
+     */
+    public function __construct(
+        StepTextPainter $textPainter,
+        ResultToStringConverter $resultConverter,
+        PrettyPathPrinter $pathPrinter,
+        $indentation = 4,
+        $subIndentation = 2
+    ) {
+        $this->textPainter = $textPainter;
+        $this->resultConverter = $resultConverter;
+        $this->pathPrinter = $pathPrinter;
+        $this->indentText = str_repeat(' ', intval($indentation));
+        $this->subIndentText = $this->indentText . str_repeat(' ', intval($subIndentation));
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function printStep(Formatter $formatter, Scenario $scenario, StepNode $step, StepResult $result)
+    {
+        $this->printText($formatter->getOutputPrinter(), $step->getKeyword(), $step->getText(), $result);
+        $this->pathPrinter->printStepPath($formatter, $scenario, $step, $result, mb_strlen($this->indentText, 'utf8'));
+        $this->printArguments($formatter, $step->getArguments());
+    }
+
+    /**
+     * Prints step text.
+     *
+     * @param OutputPrinter $printer
+     * @param string        $stepType
+     * @param string        $stepText
+     * @param StepResult    $result
+     */
+    private function printText(OutputPrinter $printer, $stepType, $stepText, StepResult $result)
+    {
+        $style = $this->resultConverter->convertResultCodeToString(TestResult::SKIPPED);
+
+        if ($result instanceof DefinedStepResult && $result->getStepDefinition()) {
+            $definition = $result->getStepDefinition();
+            $stepText = $this->textPainter->paintText(
+                $stepText, $definition, new IntegerTestResult(TestResult::SKIPPED)
+            );
+        }
+
+        $printer->write(sprintf('%s{+%s}%s %s{-%s}', $this->indentText, $style, $stepType, $stepText, $style));
+    }
+
+    /**
+     * Prints step multiline arguments.
+     *
+     * @param Formatter           $formatter
+     * @param ArgumentInterface[] $arguments
+     */
+    private function printArguments(Formatter $formatter, array $arguments)
+    {
+        $style = $this->resultConverter->convertResultCodeToString(TestResult::SKIPPED);
+
+        foreach ($arguments as $argument) {
+            $text = $this->getArgumentString($argument, !$formatter->getParameter('multiline'));
+
+            $indentedText = implode("\n", array_map(array($this, 'subIndent'), explode("\n", $text)));
+            $formatter->getOutputPrinter()->writeln(sprintf('{+%s}%s{-%s}', $style, $indentedText, $style));
+        }
+    }
+
+    /**
+     * Returns argument string for provided argument.
+     *
+     * @param ArgumentInterface $argument
+     * @param Boolean           $collapse
+     *
+     * @return string
+     */
+    private function getArgumentString(ArgumentInterface $argument, $collapse = false)
+    {
+        if ($collapse) {
+            return '...';
+        }
+
+        if ($argument instanceof PyStringNode) {
+            $text = '"""' . "\n" . $argument . "\n" . '"""';
+
+            return $text;
+        }
+
+        return (string) $argument;
+    }
+
+    /**
+     * Indents text to the subIndentation level.
+     *
+     * @param string $text
+     *
+     * @return string
+     */
+    private function subIndent($text)
+    {
+        return $this->subIndentText . $text;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/Pretty/PrettyStatisticsPrinter.php b/vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/Pretty/PrettyStatisticsPrinter.php
new file mode 100644 (file)
index 0000000..23702c7
--- /dev/null
@@ -0,0 +1,71 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Output\Node\Printer\Pretty;
+
+use Behat\Behat\Output\Node\Printer\CounterPrinter;
+use Behat\Behat\Output\Node\Printer\ListPrinter;
+use Behat\Behat\Output\Node\Printer\StatisticsPrinter;
+use Behat\Behat\Output\Statistics\Statistics;
+use Behat\Testwork\Output\Formatter;
+use Behat\Testwork\Tester\Result\TestResult;
+
+/**
+ * Prints exercise statistics.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class PrettyStatisticsPrinter implements StatisticsPrinter
+{
+    /**
+     * @var CounterPrinter
+     */
+    private $counterPrinter;
+    /**
+     * @var ListPrinter
+     */
+    private $listPrinter;
+
+    /**
+     * Initializes printer.
+     *
+     * @param CounterPrinter $counterPrinter
+     * @param ListPrinter    $listPrinter
+     */
+    public function __construct(CounterPrinter $counterPrinter, ListPrinter $listPrinter)
+    {
+        $this->counterPrinter = $counterPrinter;
+        $this->listPrinter = $listPrinter;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function printStatistics(Formatter $formatter, Statistics $statistics)
+    {
+        $printer = $formatter->getOutputPrinter();
+
+        $scenarioStats = $statistics->getSkippedScenarios();
+        $this->listPrinter->printScenariosList($printer, 'skipped_scenarios_title', TestResult::SKIPPED, $scenarioStats);
+
+        $scenarioStats = $statistics->getFailedScenarios();
+        $this->listPrinter->printScenariosList($printer, 'failed_scenarios_title', TestResult::FAILED, $scenarioStats);
+
+        $this->counterPrinter->printCounters($printer, 'scenarios_count', $statistics->getScenarioStatCounts());
+        $this->counterPrinter->printCounters($printer, 'steps_count', $statistics->getStepStatCounts());
+
+        if ($formatter->getParameter('timer')) {
+            $timer = $statistics->getTimer();
+            $memory = $statistics->getMemory();
+
+            $formatter->getOutputPrinter()->writeln(sprintf('%s (%s)', $timer, $memory));
+        }
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/Pretty/PrettyStepPrinter.php b/vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/Pretty/PrettyStepPrinter.php
new file mode 100644 (file)
index 0000000..8d47da1
--- /dev/null
@@ -0,0 +1,213 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Output\Node\Printer\Pretty;
+
+use Behat\Behat\Output\Node\Printer\Helper\ResultToStringConverter;
+use Behat\Behat\Output\Node\Printer\Helper\StepTextPainter;
+use Behat\Behat\Output\Node\Printer\StepPrinter;
+use Behat\Behat\Tester\Result\DefinedStepResult;
+use Behat\Behat\Tester\Result\ExecutedStepResult;
+use Behat\Behat\Tester\Result\StepResult;
+use Behat\Gherkin\Node\ArgumentInterface;
+use Behat\Gherkin\Node\PyStringNode;
+use Behat\Gherkin\Node\ScenarioLikeInterface as Scenario;
+use Behat\Gherkin\Node\StepNode;
+use Behat\Testwork\Exception\ExceptionPresenter;
+use Behat\Testwork\Output\Formatter;
+use Behat\Testwork\Output\Printer\OutputPrinter;
+use Behat\Testwork\Tester\Result\ExceptionResult;
+
+/**
+ * Prints step.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class PrettyStepPrinter implements StepPrinter
+{
+    /**
+     * @var StepTextPainter
+     */
+    private $textPainter;
+    /**
+     * @var ResultToStringConverter
+     */
+    private $resultConverter;
+    /**
+     * @var PrettyPathPrinter
+     */
+    private $pathPrinter;
+    /**
+     * @var ExceptionPresenter
+     */
+    private $exceptionPresenter;
+    /**
+     * @var string
+     */
+    private $indentText;
+    /**
+     * @var string
+     */
+    private $subIndentText;
+
+    /**
+     * Initializes printer.
+     *
+     * @param StepTextPainter         $textPainter
+     * @param ResultToStringConverter $resultConverter
+     * @param PrettyPathPrinter       $pathPrinter
+     * @param ExceptionPresenter      $exceptionPresenter
+     * @param integer                 $indentation
+     * @param integer                 $subIndentation
+     */
+    public function __construct(
+        StepTextPainter $textPainter,
+        ResultToStringConverter $resultConverter,
+        PrettyPathPrinter $pathPrinter,
+        ExceptionPresenter $exceptionPresenter,
+        $indentation = 4,
+        $subIndentation = 2
+    ) {
+        $this->textPainter = $textPainter;
+        $this->resultConverter = $resultConverter;
+        $this->pathPrinter = $pathPrinter;
+        $this->exceptionPresenter = $exceptionPresenter;
+        $this->indentText = str_repeat(' ', intval($indentation));
+        $this->subIndentText = $this->indentText . str_repeat(' ', intval($subIndentation));
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function printStep(Formatter $formatter, Scenario $scenario, StepNode $step, StepResult $result)
+    {
+        $this->printText($formatter->getOutputPrinter(), $step->getKeyword(), $step->getText(), $result);
+        $this->pathPrinter->printStepPath($formatter, $scenario, $step, $result, mb_strlen($this->indentText, 'utf8'));
+        $this->printArguments($formatter, $step->getArguments(), $result);
+        $this->printStdOut($formatter->getOutputPrinter(), $result);
+        $this->printException($formatter->getOutputPrinter(), $result);
+    }
+
+    /**
+     * Prints step text.
+     *
+     * @param OutputPrinter $printer
+     * @param string        $stepType
+     * @param string        $stepText
+     * @param StepResult    $result
+     */
+    private function printText(OutputPrinter $printer, $stepType, $stepText, StepResult $result)
+    {
+        if ($result && $result instanceof DefinedStepResult && $result->getStepDefinition()) {
+            $definition = $result->getStepDefinition();
+            $stepText = $this->textPainter->paintText($stepText, $definition, $result);
+        }
+
+        $style = $this->resultConverter->convertResultToString($result);
+        $printer->write(sprintf('%s{+%s}%s %s{-%s}', $this->indentText, $style, $stepType, $stepText, $style));
+    }
+
+    /**
+     * Prints step multiline arguments.
+     *
+     * @param Formatter           $formatter
+     * @param ArgumentInterface[] $arguments
+     * @param StepResult          $result
+     */
+    private function printArguments(Formatter $formatter, array $arguments, StepResult $result)
+    {
+        $style = $this->resultConverter->convertResultToString($result);
+
+        foreach ($arguments as $argument) {
+            $text = $this->getArgumentString($argument, !$formatter->getParameter('multiline'));
+
+            $indentedText = implode("\n", array_map(array($this, 'subIndent'), explode("\n", $text)));
+            $formatter->getOutputPrinter()->writeln(sprintf('{+%s}%s{-%s}', $style, $indentedText, $style));
+        }
+    }
+
+    /**
+     * Prints step output (if has one).
+     *
+     * @param OutputPrinter $printer
+     * @param StepResult    $result
+     */
+    private function printStdOut(OutputPrinter $printer, StepResult $result)
+    {
+        if (!$result instanceof ExecutedStepResult || null === $result->getCallResult()->getStdOut()) {
+            return;
+        }
+
+        $callResult = $result->getCallResult();
+        $indentedText = $this->subIndentText;
+
+        $pad = function ($line) use ($indentedText) {
+            return sprintf(
+                '%s│ {+stdout}%s{-stdout}', $indentedText, $line
+            );
+        };
+
+        $printer->writeln(implode("\n", array_map($pad, explode("\n", $callResult->getStdOut()))));
+    }
+
+    /**
+     * Prints step exception (if has one).
+     *
+     * @param OutputPrinter $printer
+     * @param StepResult    $result
+     */
+    private function printException(OutputPrinter $printer, StepResult $result)
+    {
+        $style = $this->resultConverter->convertResultToString($result);
+
+        if (!$result instanceof ExceptionResult || !$result->hasException()) {
+            return;
+        }
+
+        $text = $this->exceptionPresenter->presentException($result->getException());
+        $indentedText = implode("\n", array_map(array($this, 'subIndent'), explode("\n", $text)));
+        $printer->writeln(sprintf('{+%s}%s{-%s}', $style, $indentedText, $style));
+    }
+
+    /**
+     * Returns argument string for provided argument.
+     *
+     * @param ArgumentInterface $argument
+     * @param Boolean           $collapse
+     *
+     * @return string
+     */
+    private function getArgumentString(ArgumentInterface $argument, $collapse = false)
+    {
+        if ($collapse) {
+            return '...';
+        }
+
+        if ($argument instanceof PyStringNode) {
+            $text = '"""' . "\n" . $argument . "\n" . '"""';
+
+            return $text;
+        }
+
+        return (string) $argument;
+    }
+
+    /**
+     * Indents text to the subIndentation level.
+     *
+     * @param string $text
+     *
+     * @return string
+     */
+    private function subIndent($text)
+    {
+        return $this->subIndentText . $text;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/Progress/ProgressStatisticsPrinter.php b/vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/Progress/ProgressStatisticsPrinter.php
new file mode 100644 (file)
index 0000000..a104178
--- /dev/null
@@ -0,0 +1,77 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Output\Node\Printer\Progress;
+
+use Behat\Behat\Output\Node\Printer\CounterPrinter;
+use Behat\Behat\Output\Node\Printer\ListPrinter;
+use Behat\Behat\Output\Node\Printer\StatisticsPrinter;
+use Behat\Behat\Output\Statistics\Statistics;
+use Behat\Testwork\Output\Formatter;
+use Behat\Testwork\Tester\Result\TestResult;
+
+/**
+ * Behat progress statistics printer.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class ProgressStatisticsPrinter implements StatisticsPrinter
+{
+    /**
+     * @var CounterPrinter
+     */
+    private $counterPrinter;
+    /**
+     * @var ListPrinter
+     */
+    private $listPrinter;
+
+    /**
+     * Initializes printer.
+     *
+     * @param CounterPrinter $counterPrinter
+     * @param ListPrinter    $listPrinter
+     */
+    public function __construct(CounterPrinter $counterPrinter, ListPrinter $listPrinter)
+    {
+        $this->counterPrinter = $counterPrinter;
+        $this->listPrinter = $listPrinter;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function printStatistics(Formatter $formatter, Statistics $statistics)
+    {
+        $printer = $formatter->getOutputPrinter();
+
+        $printer->writeln();
+        $printer->writeln();
+
+        $hookStats = $statistics->getFailedHookStats();
+        $this->listPrinter->printFailedHooksList($printer, 'failed_hooks_title', $hookStats);
+
+        $stepStats = $statistics->getFailedSteps();
+        $this->listPrinter->printStepList($printer, 'failed_steps_title', TestResult::FAILED, $stepStats);
+
+        $stepStats = $statistics->getPendingSteps();
+        $this->listPrinter->printStepList($printer, 'pending_steps_title', TestResult::PENDING, $stepStats);
+
+        $this->counterPrinter->printCounters($printer, 'scenarios_count', $statistics->getScenarioStatCounts());
+        $this->counterPrinter->printCounters($printer, 'steps_count', $statistics->getStepStatCounts());
+
+        if ($formatter->getParameter('timer')) {
+            $timer = $statistics->getTimer();
+            $memory = $statistics->getMemory();
+
+            $formatter->getOutputPrinter()->writeln(sprintf('%s (%s)', $timer, $memory));
+        }
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/Progress/ProgressStepPrinter.php b/vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/Progress/ProgressStepPrinter.php
new file mode 100644 (file)
index 0000000..ca1656f
--- /dev/null
@@ -0,0 +1,77 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Output\Node\Printer\Progress;
+
+use Behat\Behat\Output\Node\Printer\Helper\ResultToStringConverter;
+use Behat\Behat\Output\Node\Printer\StepPrinter;
+use Behat\Behat\Tester\Result\StepResult;
+use Behat\Gherkin\Node\ScenarioLikeInterface as Scenario;
+use Behat\Gherkin\Node\StepNode;
+use Behat\Testwork\Output\Formatter;
+use Behat\Testwork\Tester\Result\TestResult;
+
+/**
+ * Behat progress step printer.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class ProgressStepPrinter implements StepPrinter
+{
+    /**
+     * @var ResultToStringConverter
+     */
+    private $resultConverter;
+    /**
+     * @var integer
+     */
+    private $stepsPrinted = 0;
+
+    /**
+     * Initializes printer.
+     *
+     * @param ResultToStringConverter $resultConverter
+     */
+    public function __construct(ResultToStringConverter $resultConverter)
+    {
+        $this->resultConverter = $resultConverter;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function printStep(Formatter $formatter, Scenario $scenario, StepNode $step, StepResult $result)
+    {
+        $printer = $formatter->getOutputPrinter();
+        $style = $this->resultConverter->convertResultToString($result);
+
+        switch ($result->getResultCode()) {
+            case TestResult::PASSED:
+                $printer->write("{+$style}.{-$style}");
+                break;
+            case TestResult::SKIPPED:
+                $printer->write("{+$style}-{-$style}");
+                break;
+            case TestResult::PENDING:
+                $printer->write("{+$style}P{-$style}");
+                break;
+            case StepResult::UNDEFINED:
+                $printer->write("{+$style}U{-$style}");
+                break;
+            case TestResult::FAILED:
+                $printer->write("{+$style}F{-$style}");
+                break;
+        }
+
+        if (++$this->stepsPrinted % 70 == 0) {
+            $printer->writeln(' ' . $this->stepsPrinted);
+        }
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/ScenarioPrinter.php b/vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/ScenarioPrinter.php
new file mode 100644 (file)
index 0000000..0260c41
--- /dev/null
@@ -0,0 +1,41 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Output\Node\Printer;
+
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\ScenarioLikeInterface as Scenario;
+use Behat\Testwork\Output\Formatter;
+use Behat\Testwork\Tester\Result\TestResult;
+
+/**
+ * Prints scenario headers and footers.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface ScenarioPrinter
+{
+    /**
+     * Prints scenario header using provided printer.
+     *
+     * @param Formatter   $formatter
+     * @param FeatureNode $feature
+     * @param Scenario    $scenario
+     */
+    public function printHeader(Formatter $formatter, FeatureNode $feature, Scenario $scenario);
+
+    /**
+     * Prints scenario footer using provided printer.
+     *
+     * @param Formatter  $formatter
+     * @param TestResult $result
+     */
+    public function printFooter(Formatter $formatter, TestResult $result);
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/SetupPrinter.php b/vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/SetupPrinter.php
new file mode 100644 (file)
index 0000000..5a06527
--- /dev/null
@@ -0,0 +1,39 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Output\Node\Printer;
+
+use Behat\Testwork\Output\Formatter;
+use Behat\Testwork\Tester\Setup\Setup;
+use Behat\Testwork\Tester\Setup\Teardown;
+
+/**
+ * Behat setup printer interface.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface SetupPrinter
+{
+    /**
+     * Prints setup state.
+     *
+     * @param Formatter $formatter
+     * @param Setup     $setup
+     */
+    public function printSetup(Formatter $formatter, Setup $setup);
+
+    /**
+     * Prints teardown state.
+     *
+     * @param Formatter $formatter
+     * @param Teardown  $teardown
+     */
+    public function printTeardown(Formatter $formatter, Teardown $teardown);
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/StatisticsPrinter.php b/vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/StatisticsPrinter.php
new file mode 100644 (file)
index 0000000..7999a20
--- /dev/null
@@ -0,0 +1,30 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Output\Node\Printer;
+
+use Behat\Behat\Output\Statistics\Statistics;
+use Behat\Testwork\Output\Formatter;
+
+/**
+ * Prints exercise statistics.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface StatisticsPrinter
+{
+    /**
+     * Prints test suite statistics after run.
+     *
+     * @param Formatter  $formatter
+     * @param Statistics $statistics
+     */
+    public function printStatistics(Formatter $formatter, Statistics $statistics);
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/StepPrinter.php b/vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/StepPrinter.php
new file mode 100644 (file)
index 0000000..7b03c4b
--- /dev/null
@@ -0,0 +1,34 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Output\Node\Printer;
+
+use Behat\Behat\Tester\Result\StepResult;
+use Behat\Gherkin\Node\ScenarioLikeInterface as Scenario;
+use Behat\Gherkin\Node\StepNode;
+use Behat\Testwork\Output\Formatter;
+
+/**
+ * Prints step with optional results.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface StepPrinter
+{
+    /**
+     * Prints step using provided printer.
+     *
+     * @param Formatter  $formatter
+     * @param Scenario   $scenario
+     * @param StepNode   $step
+     * @param StepResult $result
+     */
+    public function printStep(Formatter $formatter, Scenario $scenario, StepNode $step, StepResult $result);
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/SuitePrinter.php b/vendor/behat/behat/src/Behat/Behat/Output/Node/Printer/SuitePrinter.php
new file mode 100644 (file)
index 0000000..58b8ef9
--- /dev/null
@@ -0,0 +1,38 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Output\Node\Printer;
+
+use Behat\Testwork\Output\Formatter;
+use Behat\Testwork\Suite\Suite;
+
+/**
+ * Prints suite headers and footers.
+ *
+ * @author Wouter J <wouter@wouterj.nl>
+ */
+interface SuitePrinter
+{
+    /**
+     * Prints suite header using provided formatter.
+     *
+     * @param Formatter $formatter
+     * @param Suite     $suite
+     */
+    public function printHeader(Formatter $formatter, Suite $suite);
+
+    /**
+     * Prints suite footer using provided printer.
+     *
+     * @param Formatter $formatter
+     * @param Suite     $suite
+     */
+    public function printFooter(Formatter $formatter, Suite $suite);
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Output/Printer/ConsoleOutputFactory.php b/vendor/behat/behat/src/Behat/Behat/Output/Printer/ConsoleOutputFactory.php
new file mode 100644 (file)
index 0000000..4764e17
--- /dev/null
@@ -0,0 +1,62 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Output\Printer;
+
+use Behat\Behat\Output\Printer\Formatter\ConsoleFormatter;
+use Behat\Testwork\Output\Printer\Factory\ConsoleOutputFactory as BaseFactory;
+use Symfony\Component\Console\Formatter\OutputFormatterStyle;
+
+/**
+ * Extends default printer with default styles.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class ConsoleOutputFactory extends BaseFactory
+{
+    /**
+     * {@inheritDoc}
+     */
+    protected function createOutputFormatter()
+    {
+        $formatter = new ConsoleFormatter($this->isOutputDecorated());
+
+        foreach ($this->getDefaultStyles() as $name => $style) {
+            $formatter->setStyle($name, $style);
+        }
+
+        return $formatter;
+    }
+
+    /**
+     * Returns default styles.
+     *
+     * @return OutputFormatterStyle[string]
+     */
+    private function getDefaultStyles()
+    {
+        return array(
+            'keyword'       => new OutputFormatterStyle(null, null, array('bold')),
+            'stdout'        => new OutputFormatterStyle(null, null, array()),
+            'exception'     => new OutputFormatterStyle('red'),
+            'undefined'     => new OutputFormatterStyle('yellow'),
+            'pending'       => new OutputFormatterStyle('yellow'),
+            'pending_param' => new OutputFormatterStyle('yellow', null, array('bold')),
+            'failed'        => new OutputFormatterStyle('red'),
+            'failed_param'  => new OutputFormatterStyle('red', null, array('bold')),
+            'passed'        => new OutputFormatterStyle('green'),
+            'passed_param'  => new OutputFormatterStyle('green', null, array('bold')),
+            'skipped'       => new OutputFormatterStyle('cyan'),
+            'skipped_param' => new OutputFormatterStyle('cyan', null, array('bold')),
+            'comment'       => new OutputFormatterStyle('black'),
+            'tag'           => new OutputFormatterStyle('cyan')
+        );
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Output/Printer/Formatter/ConsoleFormatter.php b/vendor/behat/behat/src/Behat/Behat/Output/Printer/Formatter/ConsoleFormatter.php
new file mode 100644 (file)
index 0000000..9b403a6
--- /dev/null
@@ -0,0 +1,57 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Output\Printer\Formatter;
+
+use Symfony\Component\Console\Formatter\OutputFormatter as BaseOutputFormatter;
+
+/**
+ * Symfony2 Console output formatter extended with custom highlighting tokens support.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class ConsoleFormatter extends BaseOutputFormatter
+{
+    const CUSTOM_PATTERN = '/{\+([a-z-_]+)}(.*?){\-\\1}/si';
+
+    /**
+     * Formats a message according to the given styles.
+     *
+     * @param string $message The message to style
+     *
+     * @return string The styled message
+     */
+    public function format($message)
+    {
+        return preg_replace_callback(self::CUSTOM_PATTERN, array($this, 'replaceStyle'), $message);
+    }
+
+    /**
+     * Replaces style of the output.
+     *
+     * @param array $match
+     *
+     * @return string The replaced style
+     */
+    private function replaceStyle($match)
+    {
+        if (!$this->isDecorated()) {
+            return $match[2];
+        }
+
+        if ($this->hasStyle($match[1])) {
+            $style = $this->getStyle($match[1]);
+        } else {
+            return $match[0];
+        }
+
+        return $style->apply($match[2]);
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Output/ServiceContainer/Formatter/JUnitFormatterFactory.php b/vendor/behat/behat/src/Behat/Behat/Output/ServiceContainer/Formatter/JUnitFormatterFactory.php
new file mode 100644 (file)
index 0000000..a9d2895
--- /dev/null
@@ -0,0 +1,176 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Output\ServiceContainer\Formatter;
+
+use Behat\Testwork\Exception\ServiceContainer\ExceptionExtension;
+use Behat\Testwork\Output\ServiceContainer\Formatter\FormatterFactory;
+use Behat\Testwork\Output\ServiceContainer\OutputExtension;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Definition;
+use Symfony\Component\DependencyInjection\Reference;
+
+/**
+ * Behat junit formatter factory.
+ *
+ * @author Wouter J <wouter@wouterj.nl>
+ */
+final class JUnitFormatterFactory implements FormatterFactory
+{
+    /*
+     * Available services
+     */
+    const ROOT_LISTENER_ID = 'output.node.listener.junit';
+    const RESULT_TO_STRING_CONVERTER_ID = 'output.node.printer.result_to_string';
+
+    /**
+     * {@inheritdoc}
+     */
+    public function buildFormatter(ContainerBuilder $container)
+    {
+        $this->loadRootNodeListener($container);
+        $this->loadPrinterHelpers($container);
+        $this->loadCorePrinters($container);
+        $this->loadFormatter($container);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function processFormatter(ContainerBuilder $container)
+    {
+    }
+
+    /**
+     * Loads printer helpers.
+     *
+     * @param ContainerBuilder $container
+     */
+    private function loadPrinterHelpers(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Behat\Output\Node\Printer\Helper\ResultToStringConverter');
+        $container->setDefinition(self::RESULT_TO_STRING_CONVERTER_ID, $definition);
+    }
+
+    /**
+     * Loads the printers used to print the basic JUnit report.
+     *
+     * @param ContainerBuilder $container
+     */
+    private function loadCorePrinters(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Behat\Output\Node\Printer\JUnit\JUnitSuitePrinter', array(
+            new Reference('output.junit.statistics'),
+        ));
+        $container->setDefinition('output.node.printer.junit.suite', $definition);
+
+        $definition = new Definition('Behat\Behat\Output\Node\Printer\JUnit\JUnitFeaturePrinter', array(
+            new Reference('output.junit.statistics'),
+        ));
+        $container->setDefinition('output.node.printer.junit.feature', $definition);
+
+        $definition = new Definition('Behat\Behat\Output\Node\Printer\JUnit\JUnitScenarioPrinter', array(
+            new Reference(self::RESULT_TO_STRING_CONVERTER_ID),
+            new Reference('output.node.listener.junit.outline'),
+        ));
+        $container->setDefinition('output.node.printer.junit.scenario', $definition);
+
+        $definition = new Definition('Behat\Behat\Output\Node\Printer\JUnit\JUnitStepPrinter', array(
+            new Reference(ExceptionExtension::PRESENTER_ID),
+        ));
+        $container->setDefinition('output.node.printer.junit.step', $definition);
+
+        $definition = new Definition(
+            'Behat\Behat\Output\Node\Printer\JUnit\JUnitSetupPrinter', array(
+            new Reference(ExceptionExtension::PRESENTER_ID),
+        )
+        );
+        $container->setDefinition('output.node.printer.junit.setup', $definition);
+    }
+
+    /**
+     * Loads the node listeners required for JUnit printers to work.
+     *
+     * @param ContainerBuilder $container
+     */
+    private function loadRootNodeListener(ContainerBuilder $container)
+    {
+
+        $definition = new Definition('Behat\Behat\Output\Node\EventListener\JUnit\JUnitOutlineStoreListener', array(
+                new Reference('output.node.printer.junit.suite')
+            )
+        );
+        $container->setDefinition('output.node.listener.junit.outline', $definition);
+
+
+        $definition = new Definition('Behat\Testwork\Output\Node\EventListener\ChainEventListener', array(
+            array(
+                new Reference('output.node.listener.junit.outline'),
+                new Definition('Behat\Behat\Output\Node\EventListener\JUnit\JUnitFeatureElementListener', array(
+                    new Reference('output.node.printer.junit.feature'),
+                    new Reference('output.node.printer.junit.scenario'),
+                    new Reference('output.node.printer.junit.step'),
+                    new Reference('output.node.printer.junit.setup'),
+                )),
+            ),
+        ));
+        $container->setDefinition(self::ROOT_LISTENER_ID, $definition);
+    }
+
+    /**
+     * Loads formatter itself.
+     *
+     * @param ContainerBuilder $container
+     */
+    private function loadFormatter(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Behat\Output\Statistics\PhaseStatistics');
+        $container->setDefinition('output.junit.statistics', $definition);
+
+        $definition = new Definition('Behat\Testwork\Output\NodeEventListeningFormatter', array(
+            'junit',
+            'Outputs the failures in JUnit compatible files.',
+            array(
+                'timer' => true,
+            ),
+            $this->createOutputPrinterDefinition(),
+            new Definition('Behat\Testwork\Output\Node\EventListener\ChainEventListener', array(
+                array(
+                    new Reference(self::ROOT_LISTENER_ID),
+                    new Definition('Behat\Behat\Output\Node\EventListener\Statistics\ScenarioStatsListener', array(
+                        new Reference('output.junit.statistics')
+                    )),
+                    new Definition('Behat\Behat\Output\Node\EventListener\Statistics\StepStatsListener', array(
+                        new Reference('output.junit.statistics'),
+                        new Reference(ExceptionExtension::PRESENTER_ID)
+                    )),
+                    new Definition('Behat\Behat\Output\Node\EventListener\Statistics\HookStatsListener', array(
+                        new Reference('output.junit.statistics'),
+                        new Reference(ExceptionExtension::PRESENTER_ID)
+                    )),
+                ),
+            )),
+        ));
+        $definition->addTag(OutputExtension::FORMATTER_TAG, array('priority' => 100));
+        $container->setDefinition(OutputExtension::FORMATTER_TAG . '.junit', $definition);
+    }
+
+    /**
+     * Creates output printer definition.
+     *
+     * @return Definition
+     */
+    private function createOutputPrinterDefinition()
+    {
+        return new Definition('Behat\Testwork\Output\Printer\JUnitOutputPrinter', array(
+            new Definition('Behat\Testwork\Output\Printer\Factory\FilesystemOutputFactory'),
+        ));
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Output/ServiceContainer/Formatter/PrettyFormatterFactory.php b/vendor/behat/behat/src/Behat/Behat/Output/ServiceContainer/Formatter/PrettyFormatterFactory.php
new file mode 100644 (file)
index 0000000..261b509
--- /dev/null
@@ -0,0 +1,469 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Output\ServiceContainer\Formatter;
+
+use Behat\Behat\Definition\ServiceContainer\DefinitionExtension;
+use Behat\Behat\EventDispatcher\Event\BackgroundTested;
+use Behat\Behat\EventDispatcher\Event\OutlineTested;
+use Behat\Behat\EventDispatcher\Event\ScenarioTested;
+use Behat\Testwork\Exception\ServiceContainer\ExceptionExtension;
+use Behat\Testwork\Output\ServiceContainer\Formatter\FormatterFactory;
+use Behat\Testwork\Output\ServiceContainer\OutputExtension;
+use Behat\Testwork\ServiceContainer\ServiceProcessor;
+use Behat\Testwork\Translator\ServiceContainer\TranslatorExtension;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Definition;
+use Symfony\Component\DependencyInjection\Reference;
+
+/**
+ * Behat pretty formatter factory.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class PrettyFormatterFactory implements FormatterFactory
+{
+    /**
+     * @var ServiceProcessor
+     */
+    private $processor;
+
+    /*
+     * Available services
+     */
+    const ROOT_LISTENER_ID = 'output.node.listener.pretty';
+    const RESULT_TO_STRING_CONVERTER_ID = 'output.node.printer.result_to_string';
+
+    /*
+     * Available extension points
+     */
+    const ROOT_LISTENER_WRAPPER_TAG = 'output.node.listener.pretty.wrapper';
+
+    /**
+     * Initializes extension.
+     *
+     * @param null|ServiceProcessor $processor
+     */
+    public function __construct(ServiceProcessor $processor = null)
+    {
+        $this->processor = $processor ? : new ServiceProcessor();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function buildFormatter(ContainerBuilder $container)
+    {
+        $this->loadRootNodeListener($container);
+
+        $this->loadCorePrinters($container);
+        $this->loadTableOutlinePrinter($container);
+        $this->loadExpandedOutlinePrinter($container);
+        $this->loadHookPrinters($container);
+        $this->loadStatisticsPrinter($container);
+        $this->loadPrinterHelpers($container);
+
+        $this->loadFormatter($container);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function processFormatter(ContainerBuilder $container)
+    {
+        $this->processListenerWrappers($container);
+    }
+
+    /**
+     * Loads pretty formatter node event listener.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function loadRootNodeListener(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Testwork\Output\Node\EventListener\ChainEventListener', array(
+            array(
+                new Definition('Behat\Behat\Output\Node\EventListener\AST\SuiteListener', array(
+                    new Reference('output.node.printer.pretty.suite_setup')
+                )),
+                new Definition('Behat\Behat\Output\Node\EventListener\AST\FeatureListener', array(
+                    new Reference('output.node.printer.pretty.feature'),
+                    new Reference('output.node.printer.pretty.feature_setup')
+                )),
+                $this->proxySiblingEvents(
+                    BackgroundTested::BEFORE,
+                    BackgroundTested::AFTER,
+                    array(
+                        new Definition('Behat\Behat\Output\Node\EventListener\AST\ScenarioNodeListener', array(
+                            BackgroundTested::AFTER_SETUP,
+                            BackgroundTested::AFTER,
+                            new Reference('output.node.printer.pretty.scenario')
+                        )),
+                        new Definition('Behat\Behat\Output\Node\EventListener\AST\StepListener', array(
+                            new Reference('output.node.printer.pretty.step'),
+                            new Reference('output.node.printer.pretty.step_setup')
+                        )),
+                    )
+                ),
+                $this->proxySiblingEvents(
+                    ScenarioTested::BEFORE,
+                    ScenarioTested::AFTER,
+                    array(
+                        new Definition('Behat\Behat\Output\Node\EventListener\AST\ScenarioNodeListener', array(
+                            ScenarioTested::AFTER_SETUP,
+                            ScenarioTested::AFTER,
+                            new Reference('output.node.printer.pretty.scenario'),
+                            new Reference('output.node.printer.pretty.scenario_setup')
+                        )),
+                        new Definition('Behat\Behat\Output\Node\EventListener\AST\StepListener', array(
+                            new Reference('output.node.printer.pretty.step'),
+                            new Reference('output.node.printer.pretty.step_setup')
+                        )),
+                    )
+                ),
+                $this->proxySiblingEvents(
+                    OutlineTested::BEFORE,
+                    OutlineTested::AFTER,
+                    array(
+                        $this->proxyEventsIfParameterIsSet(
+                            'expand',
+                            false,
+                            new Definition('Behat\Behat\Output\Node\EventListener\AST\OutlineTableListener', array(
+                                new Reference('output.node.printer.pretty.outline_table'),
+                                new Reference('output.node.printer.pretty.example_row'),
+                                new Reference('output.node.printer.pretty.example_setup'),
+                                new Reference('output.node.printer.pretty.example_step_setup')
+                            ))
+                        ),
+                        $this->proxyEventsIfParameterIsSet(
+                            'expand',
+                            true,
+                            new Definition('Behat\Behat\Output\Node\EventListener\AST\OutlineListener', array(
+                                new Reference('output.node.printer.pretty.outline'),
+                                new Reference('output.node.printer.pretty.example'),
+                                new Reference('output.node.printer.pretty.example_step'),
+                                new Reference('output.node.printer.pretty.example_setup'),
+                                new Reference('output.node.printer.pretty.example_step_setup')
+                            ))
+                        )
+                    )
+                ),
+            )
+        ));
+        $container->setDefinition(self::ROOT_LISTENER_ID, $definition);
+    }
+
+    /**
+     * Loads formatter itself.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function loadFormatter(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Behat\Output\Statistics\TotalStatistics');
+        $container->setDefinition('output.pretty.statistics', $definition);
+
+        $definition = new Definition('Behat\Testwork\Output\NodeEventListeningFormatter', array(
+            'pretty',
+            'Prints the feature as is.',
+            array(
+                'timer'     => true,
+                'expand'    => false,
+                'paths'     => true,
+                'multiline' => true,
+            ),
+            $this->createOutputPrinterDefinition(),
+            new Definition('Behat\Testwork\Output\Node\EventListener\ChainEventListener', array(
+                    array(
+                        $this->rearrangeBackgroundEvents(
+                            new Reference(self::ROOT_LISTENER_ID)
+                        ),
+                        new Definition('Behat\Behat\Output\Node\EventListener\Statistics\StatisticsListener', array(
+                            new Reference('output.pretty.statistics'),
+                            new Reference('output.node.printer.pretty.statistics')
+                        )),
+                        new Definition('Behat\Behat\Output\Node\EventListener\Statistics\ScenarioStatsListener', array(
+                            new Reference('output.pretty.statistics')
+                        )),
+                        new Definition('Behat\Behat\Output\Node\EventListener\Statistics\StepStatsListener', array(
+                            new Reference('output.pretty.statistics'),
+                            new Reference(ExceptionExtension::PRESENTER_ID)
+                        )),
+                    )
+                )
+            )
+        ));
+        $definition->addTag(OutputExtension::FORMATTER_TAG, array('priority' => 100));
+        $container->setDefinition(OutputExtension::FORMATTER_TAG . '.pretty', $definition);
+    }
+
+    /**
+     * Loads feature, scenario and step printers.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function loadCorePrinters(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Behat\Output\Node\Printer\Pretty\PrettyFeaturePrinter');
+        $container->setDefinition('output.node.printer.pretty.feature', $definition);
+
+        $definition = new Definition('Behat\Behat\Output\Node\Printer\Pretty\PrettyPathPrinter', array(
+            new Reference('output.node.printer.pretty.width_calculator'),
+            '%paths.base%'
+        ));
+        $container->setDefinition('output.node.printer.pretty.path', $definition);
+
+        $definition = new Definition('Behat\Behat\Output\Node\Printer\Pretty\PrettyScenarioPrinter', array(
+            new Reference('output.node.printer.pretty.path'),
+        ));
+        $container->setDefinition('output.node.printer.pretty.scenario', $definition);
+
+        $definition = new Definition('Behat\Behat\Output\Node\Printer\Pretty\PrettyStepPrinter', array(
+            new Reference('output.node.printer.pretty.step_text_painter'),
+            new Reference(self::RESULT_TO_STRING_CONVERTER_ID),
+            new Reference('output.node.printer.pretty.path'),
+            new Reference(ExceptionExtension::PRESENTER_ID)
+        ));
+        $container->setDefinition('output.node.printer.pretty.step', $definition);
+
+        $definition = new Definition('Behat\Behat\Output\Node\Printer\Pretty\PrettySkippedStepPrinter', array(
+            new Reference('output.node.printer.pretty.step_text_painter'),
+            new Reference(self::RESULT_TO_STRING_CONVERTER_ID),
+            new Reference('output.node.printer.pretty.path'),
+        ));
+        $container->setDefinition('output.node.printer.pretty.skipped_step', $definition);
+    }
+
+    /**
+     * Loads table outline printer.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function loadTableOutlinePrinter(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Behat\Output\Node\Printer\Pretty\PrettyOutlineTablePrinter', array(
+            new Reference('output.node.printer.pretty.scenario'),
+            new Reference('output.node.printer.pretty.skipped_step'),
+            new Reference(self::RESULT_TO_STRING_CONVERTER_ID)
+        ));
+        $container->setDefinition('output.node.printer.pretty.outline_table', $definition);
+
+        $definition = new Definition('Behat\Behat\Output\Node\Printer\Pretty\PrettyExampleRowPrinter', array(
+            new Reference(self::RESULT_TO_STRING_CONVERTER_ID),
+            new Reference(ExceptionExtension::PRESENTER_ID)
+        ));
+        $container->setDefinition('output.node.printer.pretty.example_row', $definition);
+    }
+
+    /**
+     * Loads expanded outline printer.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function loadExpandedOutlinePrinter(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Behat\Output\Node\Printer\Pretty\PrettyOutlinePrinter', array(
+            new Reference('output.node.printer.pretty.scenario'),
+            new Reference('output.node.printer.pretty.skipped_step'),
+            new Reference(self::RESULT_TO_STRING_CONVERTER_ID)
+        ));
+        $container->setDefinition('output.node.printer.pretty.outline', $definition);
+
+        $definition = new Definition('Behat\Behat\Output\Node\Printer\Pretty\PrettyExamplePrinter', array(
+            new Reference('output.node.printer.pretty.path'),
+        ));
+        $container->setDefinition('output.node.printer.pretty.example', $definition);
+
+        $definition = new Definition('Behat\Behat\Output\Node\Printer\Pretty\PrettyStepPrinter', array(
+            new Reference('output.node.printer.pretty.step_text_painter'),
+            new Reference(self::RESULT_TO_STRING_CONVERTER_ID),
+            new Reference('output.node.printer.pretty.path'),
+            new Reference(ExceptionExtension::PRESENTER_ID),
+            8
+        ));
+        $container->setDefinition('output.node.printer.pretty.example_step', $definition);
+    }
+
+    /**
+     * Loads hook printers.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function loadHookPrinters(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Behat\Output\Node\Printer\Pretty\PrettySetupPrinter', array(
+            new Reference(self::RESULT_TO_STRING_CONVERTER_ID),
+            new Reference(ExceptionExtension::PRESENTER_ID),
+            0,
+            true,
+            true
+        ));
+        $container->setDefinition('output.node.printer.pretty.suite_setup', $definition);
+
+        $definition = new Definition('Behat\Behat\Output\Node\Printer\Pretty\PrettySetupPrinter', array(
+            new Reference(self::RESULT_TO_STRING_CONVERTER_ID),
+            new Reference(ExceptionExtension::PRESENTER_ID),
+            0,
+            false,
+            true
+        ));
+        $container->setDefinition('output.node.printer.pretty.feature_setup', $definition);
+
+        $definition = new Definition('Behat\Behat\Output\Node\Printer\Pretty\PrettySetupPrinter', array(
+            new Reference(self::RESULT_TO_STRING_CONVERTER_ID),
+            new Reference(ExceptionExtension::PRESENTER_ID),
+            2
+        ));
+        $container->setDefinition('output.node.printer.pretty.scenario_setup', $definition);
+
+        $definition = new Definition('Behat\Behat\Output\Node\Printer\Pretty\PrettySetupPrinter', array(
+            new Reference(self::RESULT_TO_STRING_CONVERTER_ID),
+            new Reference(ExceptionExtension::PRESENTER_ID),
+            4
+        ));
+        $container->setDefinition('output.node.printer.pretty.step_setup', $definition);
+
+        $definition = new Definition('Behat\Behat\Output\Node\Printer\Pretty\PrettySetupPrinter', array(
+            new Reference(self::RESULT_TO_STRING_CONVERTER_ID),
+            new Reference(ExceptionExtension::PRESENTER_ID),
+            8
+        ));
+        $container->setDefinition('output.node.printer.pretty.example_step_setup', $definition);
+
+        $definition = new Definition('Behat\Behat\Output\Node\Printer\Pretty\PrettySetupPrinter', array(
+            new Reference(self::RESULT_TO_STRING_CONVERTER_ID),
+            new Reference(ExceptionExtension::PRESENTER_ID),
+            6
+        ));
+        $container->setDefinition('output.node.printer.pretty.example_setup', $definition);
+    }
+
+    /**
+     * Loads statistics printer.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function loadStatisticsPrinter(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Behat\Output\Node\Printer\CounterPrinter', array(
+            new Reference(self::RESULT_TO_STRING_CONVERTER_ID),
+            new Reference(TranslatorExtension::TRANSLATOR_ID),
+        ));
+        $container->setDefinition('output.node.printer.counter', $definition);
+
+        $definition = new Definition('Behat\Behat\Output\Node\Printer\ListPrinter', array(
+            new Reference(self::RESULT_TO_STRING_CONVERTER_ID),
+            new Reference(ExceptionExtension::PRESENTER_ID),
+            new Reference(TranslatorExtension::TRANSLATOR_ID),
+            '%paths.base%'
+        ));
+        $container->setDefinition('output.node.printer.list', $definition);
+
+        $definition = new Definition('Behat\Behat\Output\Node\Printer\Pretty\PrettyStatisticsPrinter', array(
+            new Reference('output.node.printer.counter'),
+            new Reference('output.node.printer.list')
+        ));
+        $container->setDefinition('output.node.printer.pretty.statistics', $definition);
+    }
+
+    /**
+     * Loads printer helpers.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function loadPrinterHelpers(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Behat\Output\Node\Printer\Helper\WidthCalculator');
+        $container->setDefinition('output.node.printer.pretty.width_calculator', $definition);
+
+        $definition = new Definition('Behat\Behat\Output\Node\Printer\Helper\StepTextPainter', array(
+            new Reference(DefinitionExtension::PATTERN_TRANSFORMER_ID),
+            new Reference(self::RESULT_TO_STRING_CONVERTER_ID)
+        ));
+        $container->setDefinition('output.node.printer.pretty.step_text_painter', $definition);
+
+        $definition = new Definition('Behat\Behat\Output\Node\Printer\Helper\ResultToStringConverter');
+        $container->setDefinition(self::RESULT_TO_STRING_CONVERTER_ID, $definition);
+    }
+
+    /**
+     * Creates output printer definition.
+     *
+     * @return Definition
+     */
+    protected function createOutputPrinterDefinition()
+    {
+        return new Definition('Behat\Testwork\Output\Printer\StreamOutputPrinter', array(
+            new Definition('Behat\Behat\Output\Printer\ConsoleOutputFactory'),
+        ));
+    }
+
+    /**
+     * Creates root listener definition.
+     *
+     * @param mixed $listener
+     *
+     * @return Definition
+     */
+    protected function rearrangeBackgroundEvents($listener)
+    {
+        return new Definition('Behat\Behat\Output\Node\EventListener\Flow\FirstBackgroundFiresFirstListener', array(
+            new Definition('Behat\Behat\Output\Node\EventListener\Flow\OnlyFirstBackgroundFiresListener', array(
+                $listener
+            ))
+        ));
+    }
+
+    /**
+     * Creates contextual proxy listener.
+     *
+     * @param string       $beforeEventName
+     * @param string       $afterEventName
+     * @param Definition[] $listeners
+     *
+     * @return Definition
+     */
+    protected function proxySiblingEvents($beforeEventName, $afterEventName, array $listeners)
+    {
+        return new Definition('Behat\Behat\Output\Node\EventListener\Flow\FireOnlySiblingsListener',
+            array(
+                $beforeEventName,
+                $afterEventName,
+                new Definition('Behat\Testwork\Output\Node\EventListener\ChainEventListener', array($listeners))
+            )
+        );
+    }
+
+    /**
+     * Creates contextual proxy listener.
+     *
+     * @param string $name
+     * @param mixed  $value
+     * @param mixed  $listener
+     *
+     * @return Definition
+     */
+    protected function proxyEventsIfParameterIsSet($name, $value, Definition $listener)
+    {
+        return new Definition('Behat\Testwork\Output\Node\EventListener\Flow\FireOnlyIfFormatterParameterListener',
+            array($name, $value, $listener)
+        );
+    }
+
+    /**
+     * Processes all registered pretty formatter node listener wrappers.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function processListenerWrappers(ContainerBuilder $container)
+    {
+        $this->processor->processWrapperServices($container, self::ROOT_LISTENER_ID, self::ROOT_LISTENER_WRAPPER_TAG);
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Output/ServiceContainer/Formatter/ProgressFormatterFactory.php b/vendor/behat/behat/src/Behat/Behat/Output/ServiceContainer/Formatter/ProgressFormatterFactory.php
new file mode 100644 (file)
index 0000000..e19acdc
--- /dev/null
@@ -0,0 +1,195 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Output\ServiceContainer\Formatter;
+
+use Behat\Testwork\Exception\ServiceContainer\ExceptionExtension;
+use Behat\Testwork\Output\ServiceContainer\Formatter\FormatterFactory;
+use Behat\Testwork\Output\ServiceContainer\OutputExtension;
+use Behat\Testwork\ServiceContainer\ServiceProcessor;
+use Behat\Testwork\Translator\ServiceContainer\TranslatorExtension;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Definition;
+use Symfony\Component\DependencyInjection\Reference;
+
+/**
+ * Behat progress formatter factory.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class ProgressFormatterFactory implements FormatterFactory
+{
+    /**
+     * @var ServiceProcessor
+     */
+    private $processor;
+
+    /*
+     * Available services
+     */
+    const ROOT_LISTENER_ID = 'output.node.listener.progress';
+    const RESULT_TO_STRING_CONVERTER_ID = 'output.node.printer.result_to_string';
+
+    /*
+     * Available extension points
+     */
+    const ROOT_LISTENER_WRAPPER_TAG = 'output.node.listener.progress.wrapper';
+
+    /**
+     * Initializes extension.
+     *
+     * @param null|ServiceProcessor $processor
+     */
+    public function __construct(ServiceProcessor $processor = null)
+    {
+        $this->processor = $processor ? : new ServiceProcessor();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function buildFormatter(ContainerBuilder $container)
+    {
+        $this->loadRootNodeListener($container);
+        $this->loadCorePrinters($container);
+        $this->loadPrinterHelpers($container);
+        $this->loadFormatter($container);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function processFormatter(ContainerBuilder $container)
+    {
+        $this->processListenerWrappers($container);
+    }
+
+    /**
+     * Loads progress formatter node event listener.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function loadRootNodeListener(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Behat\Output\Node\EventListener\AST\StepListener', array(
+            new Reference('output.node.printer.progress.step')
+        ));
+        $container->setDefinition(self::ROOT_LISTENER_ID, $definition);
+    }
+
+    /**
+     * Loads feature, scenario and step printers.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function loadCorePrinters(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Behat\Output\Node\Printer\CounterPrinter', array(
+            new Reference(self::RESULT_TO_STRING_CONVERTER_ID),
+            new Reference(TranslatorExtension::TRANSLATOR_ID),
+        ));
+        $container->setDefinition('output.node.printer.counter', $definition);
+
+        $definition = new Definition('Behat\Behat\Output\Node\Printer\ListPrinter', array(
+            new Reference(self::RESULT_TO_STRING_CONVERTER_ID),
+            new Reference(ExceptionExtension::PRESENTER_ID),
+            new Reference(TranslatorExtension::TRANSLATOR_ID),
+            '%paths.base%'
+        ));
+        $container->setDefinition('output.node.printer.list', $definition);
+
+        $definition = new Definition('Behat\Behat\Output\Node\Printer\Progress\ProgressStepPrinter', array(
+            new Reference(self::RESULT_TO_STRING_CONVERTER_ID)
+        ));
+        $container->setDefinition('output.node.printer.progress.step', $definition);
+
+        $definition = new Definition('Behat\Behat\Output\Node\Printer\Progress\ProgressStatisticsPrinter', array(
+            new Reference('output.node.printer.counter'),
+            new Reference('output.node.printer.list')
+        ));
+        $container->setDefinition('output.node.printer.progress.statistics', $definition);
+    }
+
+    /**
+     * Loads printer helpers.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function loadPrinterHelpers(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Behat\Output\Node\Printer\Helper\ResultToStringConverter');
+        $container->setDefinition(self::RESULT_TO_STRING_CONVERTER_ID, $definition);
+    }
+
+    /**
+     * Loads formatter itself.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function loadFormatter(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Behat\Output\Statistics\TotalStatistics');
+        $container->setDefinition('output.progress.statistics', $definition);
+
+        $definition = new Definition('Behat\Testwork\Output\NodeEventListeningFormatter', array(
+            'progress',
+            'Prints one character per step.',
+            array(
+                'timer' => true
+            ),
+            $this->createOutputPrinterDefinition(),
+            new Definition('Behat\Testwork\Output\Node\EventListener\ChainEventListener', array(
+                    array(
+                        new Reference(self::ROOT_LISTENER_ID),
+                        new Definition('Behat\Behat\Output\Node\EventListener\Statistics\StatisticsListener', array(
+                            new Reference('output.progress.statistics'),
+                            new Reference('output.node.printer.progress.statistics')
+                        )),
+                        new Definition('Behat\Behat\Output\Node\EventListener\Statistics\ScenarioStatsListener', array(
+                            new Reference('output.progress.statistics')
+                        )),
+                        new Definition('Behat\Behat\Output\Node\EventListener\Statistics\StepStatsListener', array(
+                            new Reference('output.progress.statistics'),
+                            new Reference(ExceptionExtension::PRESENTER_ID)
+                        )),
+                        new Definition('Behat\Behat\Output\Node\EventListener\Statistics\HookStatsListener', array(
+                            new Reference('output.progress.statistics'),
+                            new Reference(ExceptionExtension::PRESENTER_ID)
+                        )),
+                    )
+                )
+            )
+        ));
+        $definition->addTag(OutputExtension::FORMATTER_TAG, array('priority' => 100));
+        $container->setDefinition(OutputExtension::FORMATTER_TAG . '.progress', $definition);
+    }
+
+    /**
+     * Creates output printer definition.
+     *
+     * @return Definition
+     */
+    protected function createOutputPrinterDefinition()
+    {
+        return new Definition('Behat\Testwork\Output\Printer\StreamOutputPrinter', array(
+            new Definition('Behat\Behat\Output\Printer\ConsoleOutputFactory'),
+        ));
+    }
+
+    /**
+     * Processes all registered pretty formatter node listener wrappers.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function processListenerWrappers(ContainerBuilder $container)
+    {
+        $this->processor->processWrapperServices($container, self::ROOT_LISTENER_ID, self::ROOT_LISTENER_WRAPPER_TAG);
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Output/Statistics/HookStat.php b/vendor/behat/behat/src/Behat/Behat/Output/Statistics/HookStat.php
new file mode 100644 (file)
index 0000000..e8afc31
--- /dev/null
@@ -0,0 +1,98 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Output\Statistics;
+
+/**
+ * Represents hook stat.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class HookStat
+{
+    /**
+     * @var string
+     */
+    private $name;
+    /**
+     * @var string
+     */
+    private $path;
+    /**
+     * @var string|null
+     */
+    private $error;
+    /**
+     * @var string|null
+     */
+    private $stdOut;
+
+    /**
+     * Initializes hook stat.
+     *
+     * @param string      $name
+     * @param string      $path
+     * @param null|string $error
+     * @param null|string $stdOut
+     */
+    public function __construct($name, $path, $error = null, $stdOut = null)
+    {
+        $this->name = $name;
+        $this->path = $path;
+        $this->error = $error;
+        $this->stdOut = $stdOut;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getName()
+    {
+        return $this->name;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function isSuccessful()
+    {
+        return null === $this->error;
+    }
+
+    /**
+     * Returns hook standard output (if has some).
+     *
+     * @return null|string
+     */
+    public function getStdOut()
+    {
+        return $this->stdOut;
+    }
+
+    /**
+     * Returns hook exception.
+     *
+     * @return string
+     */
+    public function getError()
+    {
+        return $this->error;
+    }
+
+    /**
+     * Returns hook path.
+     *
+     * @return string
+     */
+    public function getPath()
+    {
+        return $this->path;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Output/Statistics/PhaseStatistics.php b/vendor/behat/behat/src/Behat/Behat/Output/Statistics/PhaseStatistics.php
new file mode 100644 (file)
index 0000000..c21e942
--- /dev/null
@@ -0,0 +1,179 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Output\Statistics;
+
+use Behat\Testwork\Counter\Timer;
+use Behat\Testwork\Counter\Memory;
+
+/**
+ * A TotalStatistics decorator to get statistics per phase.
+ *
+ * This is useful to show the amount of failures
+ * in a single suite for instance.
+ *
+ * @author Wouter J <wouter@wouterj.nl>
+ */
+final class PhaseStatistics implements Statistics
+{
+    /**
+     * @var TotalStatistics
+     */
+    private $statistics;
+
+    public function __construct()
+    {
+        $this->statistics = new TotalStatistics();
+    }
+
+    /**
+     * Resets the statistics.
+     */
+    public function reset()
+    {
+        $this->statistics = new TotalStatistics();
+    }
+
+    /**
+     * Starts timer.
+     */
+    public function startTimer()
+    {
+        $this->statistics->startTimer();
+    }
+
+    /**
+     * Stops timer.
+     */
+    public function stopTimer()
+    {
+        $this->statistics->stopTimer();
+    }
+
+    /**
+     * Returns timer object.
+     *
+     * @return Timer
+     */
+    public function getTimer()
+    {
+        return $this->statistics->getTimer();
+    }
+
+    /**
+     * Returns memory usage object.
+     *
+     * @return Memory
+     */
+    public function getMemory()
+    {
+        return $this->statistics->getMemory();
+    }
+
+    /**
+     * Registers scenario stat.
+     *
+     * @param ScenarioStat $stat
+     */
+    public function registerScenarioStat(ScenarioStat $stat)
+    {
+        $this->statistics->registerScenarioStat($stat);
+    }
+
+    /**
+     * Registers step stat.
+     *
+     * @param StepStat $stat
+     */
+    public function registerStepStat(StepStat $stat)
+    {
+        $this->statistics->registerStepStat($stat);
+    }
+
+    /**
+     * Registers hook stat.
+     *
+     * @param HookStat $stat
+     */
+    public function registerHookStat(HookStat $stat)
+    {
+        $this->statistics->registerHookStat($stat);
+    }
+
+    /**
+     * Returns counters for different scenario result codes.
+     *
+     * @return array[]
+     */
+    public function getScenarioStatCounts()
+    {
+        return $this->statistics->getScenarioStatCounts();
+    }
+
+    /**
+     * Returns skipped scenario stats.
+     *
+     * @return ScenarioStat[]
+     */
+    public function getSkippedScenarios()
+    {
+        return $this->statistics->getSkippedScenarios();
+    }
+
+    /**
+     * Returns failed scenario stats.
+     *
+     * @return ScenarioStat[]
+     */
+    public function getFailedScenarios()
+    {
+        return $this->statistics->getFailedScenarios();
+    }
+
+    /**
+     * Returns counters for different step result codes.
+     *
+     * @return array[]
+     */
+    public function getStepStatCounts()
+    {
+        return $this->statistics->getStepStatCounts();
+    }
+
+    /**
+     * Returns failed step stats.
+     *
+     * @return StepStat[]
+     */
+    public function getFailedSteps()
+    {
+        return $this->statistics->getFailedSteps();
+    }
+
+    /**
+     * Returns pending step stats.
+     *
+     * @return StepStat[]
+     */
+    public function getPendingSteps()
+    {
+        return $this->statistics->getPendingSteps();
+    }
+
+    /**
+     * Returns failed hook stats.
+     *
+     * @return HookStat[]
+     */
+    public function getFailedHookStats()
+    {
+        return $this->statistics->getFailedHookStats();
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Output/Statistics/ScenarioStat.php b/vendor/behat/behat/src/Behat/Behat/Output/Statistics/ScenarioStat.php
new file mode 100644 (file)
index 0000000..0af5005
--- /dev/null
@@ -0,0 +1,86 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Output\Statistics;
+
+/**
+ * Behat scenario stat.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class ScenarioStat
+{
+    /**
+     * @var string
+     */
+    private $title;
+    /**
+     * @var string
+     */
+    private $path;
+    /**
+     * @var integer
+     */
+    private $resultCode;
+
+    /**
+     * Initializes scenario stat.
+     *
+     * @param string  $title
+     * @param string  $path
+     * @param integer $resultCode
+     */
+    public function __construct($title, $path, $resultCode)
+    {
+        $this->title = $title;
+        $this->path = $path;
+        $this->resultCode = $resultCode;
+    }
+
+    /**
+     * Returns scenario title.
+     *
+     * @return string
+     */
+    public function getTitle()
+    {
+        return $this->title;
+    }
+
+    /**
+     * Returns scenario path.
+     *
+     * @return string
+     */
+    public function getPath()
+    {
+        return $this->path;
+    }
+
+    /**
+     * Returns scenario result code.
+     *
+     * @return integer
+     */
+    public function getResultCode()
+    {
+        return $this->resultCode;
+    }
+
+    /**
+     * Returns string representation for a stat.
+     *
+     * @return string
+     */
+    public function __toString()
+    {
+        return $this->getPath();
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Output/Statistics/Statistics.php b/vendor/behat/behat/src/Behat/Behat/Output/Statistics/Statistics.php
new file mode 100644 (file)
index 0000000..4d20de9
--- /dev/null
@@ -0,0 +1,117 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Output\Statistics;
+
+use Behat\Testwork\Counter\Memory;
+use Behat\Testwork\Counter\Timer;
+
+
+/**
+ * Collects and provided exercise statistics.
+ *
+ * @author Wouter J <wouter@wouterj.nl>
+ */
+interface Statistics
+{
+    /**
+     * Starts timer.
+     */
+    public function startTimer();
+
+    /**
+     * Stops timer.
+     */
+    public function stopTimer();
+
+    /**
+     * Returns timer object.
+     *
+     * @return Timer
+     */
+    public function getTimer();
+
+    /**
+     * Returns memory usage object.
+     *
+     * @return Memory
+     */
+    public function getMemory();
+
+    /**
+     * Registers scenario stat.
+     *
+     * @param ScenarioStat $stat
+     */
+    public function registerScenarioStat(ScenarioStat $stat);
+
+    /**
+     * Registers step stat.
+     *
+     * @param StepStat $stat
+     */
+    public function registerStepStat(StepStat $stat);
+
+    /**
+     * Registers hook stat.
+     *
+     * @param HookStat $stat
+     */
+    public function registerHookStat(HookStat $stat);
+
+    /**
+     * Returns counters for different scenario result codes.
+     *
+     * @return array[]
+     */
+    public function getScenarioStatCounts();
+
+    /**
+     * Returns skipped scenario stats.
+     *
+     * @return ScenarioStat[]
+     */
+    public function getSkippedScenarios();
+
+    /**
+     * Returns failed scenario stats.
+     *
+     * @return ScenarioStat[]
+     */
+    public function getFailedScenarios();
+
+    /**
+     * Returns counters for different step result codes.
+     *
+     * @return array[]
+     */
+    public function getStepStatCounts();
+
+    /**
+     * Returns failed step stats.
+     *
+     * @return StepStat[]
+     */
+    public function getFailedSteps();
+
+    /**
+     * Returns pending step stats.
+     *
+     * @return StepStat[]
+     */
+    public function getPendingSteps();
+
+    /**
+     * Returns failed hook stats.
+     *
+     * @return HookStat[]
+     */
+    public function getFailedHookStats();
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Output/Statistics/StepStat.php b/vendor/behat/behat/src/Behat/Behat/Output/Statistics/StepStat.php
new file mode 100644 (file)
index 0000000..320d287
--- /dev/null
@@ -0,0 +1,120 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Output\Statistics;
+
+/**
+ * Behat step stat.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * @deprecated in favour of StepStatV2 and to be removed in 4.0
+ */
+class StepStat
+{
+    /**
+     * @var string
+     */
+    private $text;
+    /**
+     * @var string
+     */
+    private $path;
+    /**
+     * @var integer
+     */
+    private $resultCode;
+    /**
+     * @var null|string
+     */
+    private $error;
+    /**
+     * @var null|string
+     */
+    private $stdOut;
+
+    /**
+     * Initializes step stat.
+     *
+     * @param string      $text
+     * @param string      $path
+     * @param integer     $resultCode
+     * @param null|string $error
+     * @param null|string $stdOut
+     */
+    public function __construct($text, $path, $resultCode, $error = null, $stdOut = null)
+    {
+        $this->text = $text;
+        $this->path = $path;
+        $this->resultCode = $resultCode;
+        $this->error = $error;
+        $this->stdOut = $stdOut;
+    }
+
+    /**
+     * Returns step text.
+     *
+     * @return string
+     */
+    public function getText()
+    {
+        return $this->text;
+    }
+
+    /**
+     * Returns step path.
+     *
+     * @return string
+     */
+    public function getPath()
+    {
+        return $this->path;
+    }
+
+    /**
+     * Returns step result code.
+     *
+     * @return integer
+     */
+    public function getResultCode()
+    {
+        return $this->resultCode;
+    }
+
+    /**
+     * Returns step error (if has one).
+     *
+     * @return null|string
+     */
+    public function getError()
+    {
+        return $this->error;
+    }
+
+    /**
+     * Returns step output (if has one).
+     *
+     * @return null|string
+     */
+    public function getStdOut()
+    {
+        return $this->stdOut;
+    }
+
+    /**
+     * Returns string representation for a stat.
+     *
+     * @return string
+     */
+    public function __toString()
+    {
+        return $this->getPath();
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Output/Statistics/StepStatV2.php b/vendor/behat/behat/src/Behat/Behat/Output/Statistics/StepStatV2.php
new file mode 100644 (file)
index 0000000..ae13fc6
--- /dev/null
@@ -0,0 +1,152 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Output\Statistics;
+
+/**
+ * Second iteration of Behat step stat, with a scenario information.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class StepStatV2 extends StepStat
+{
+    /**
+     * @var string
+     */
+    private $scenarioTitle;
+    /**
+     * @var string
+     */
+    private $scenarioPath;
+    /**
+     * @var string
+     */
+    private $stepText;
+    /**
+     * @var string
+     */
+    private $stepPath;
+    /**
+     * @var integer
+     */
+    private $resultCode;
+    /**
+     * @var null|string
+     */
+    private $error;
+    /**
+     * @var null|string
+     */
+    private $stdOut;
+
+    /**
+     * Initializes step stat.
+     *
+     * @param string      $scenarioTitle
+     * @param string      $scenarioPath
+     * @param string      $stepText
+     * @param string      $stepPath
+     * @param integer     $resultCode
+     * @param null|string $error
+     * @param null|string $stdOut
+     */
+    public function __construct($scenarioTitle, $scenarioPath, $stepText, $stepPath, $resultCode, $error = null, $stdOut = null)
+    {
+        parent::__construct($stepText, $stepPath, $resultCode, $error, $stdOut);
+
+        $this->scenarioTitle = $scenarioTitle;
+        $this->scenarioPath = $scenarioPath;
+        $this->stepText = $stepText;
+        $this->stepPath = $stepPath;
+        $this->resultCode = $resultCode;
+        $this->error = $error;
+        $this->stdOut = $stdOut;
+    }
+
+    /**
+     * Returns associated scenario text.
+     *
+     * @return string
+     */
+    public function getScenarioText()
+    {
+        return $this->scenarioTitle;
+    }
+
+    /**
+     * Returns associated scenario path.
+     *
+     * @return string
+     */
+    public function getScenarioPath()
+    {
+        return $this->scenarioPath;
+    }
+
+    /**
+     * Returns step text.
+     *
+     * @return string
+     */
+    public function getStepText()
+    {
+        return $this->stepText;
+    }
+
+    /**
+     * Returns step path.
+     *
+     * @return string
+     */
+    public function getStepPath()
+    {
+        return $this->stepPath;
+    }
+
+    /**
+     * Returns step result code.
+     *
+     * @return integer
+     */
+    public function getResultCode()
+    {
+        return $this->resultCode;
+    }
+
+    /**
+     * Returns step error (if has one).
+     *
+     * @return null|string
+     */
+    public function getError()
+    {
+        return $this->error;
+    }
+
+    /**
+     * Returns step output (if has one).
+     *
+     * @return null|string
+     */
+    public function getStdOut()
+    {
+        return $this->stdOut;
+    }
+
+    /**
+     * Returns string representation for a stat.
+     *
+     * @return string
+     */
+    public function __toString()
+    {
+        return $this->getPath();
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Output/Statistics/TotalStatistics.php b/vendor/behat/behat/src/Behat/Behat/Output/Statistics/TotalStatistics.php
new file mode 100644 (file)
index 0000000..1b89e87
--- /dev/null
@@ -0,0 +1,244 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Output\Statistics;
+
+use Behat\Behat\Tester\Result\StepResult;
+use Behat\Testwork\Counter\Memory;
+use Behat\Testwork\Counter\Timer;
+use Behat\Testwork\Tester\Result\TestResult;
+use Behat\Testwork\Tester\Result\TestResults;
+
+/**
+ * Collects and provided exercise statistics.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class TotalStatistics implements Statistics
+{
+    /**
+     * @var Timer
+     */
+    private $timer;
+    /**
+     * @var Memory
+     */
+    private $memory;
+    /**
+     * @var array
+     */
+    private $scenarioCounters = array();
+    /**
+     * @var array
+     */
+    private $stepCounters = array();
+    /**
+     * @var ScenarioStat[]
+     */
+    private $failedScenarioStats = array();
+    /**
+     * @var ScenarioStat[]
+     */
+    private $skippedScenarioStats = array();
+    /**
+     * @var StepStat[]
+     */
+    private $failedStepStats = array();
+    /**
+     * @var StepStat[]
+     */
+    private $pendingStepStats = array();
+    /**
+     * @var HookStat[]
+     */
+    private $failedHookStats = array();
+
+    /**
+     * Initializes statistics.
+     */
+    public function __construct()
+    {
+        $this->resetAllCounters();
+
+        $this->timer = new Timer();
+        $this->memory = new Memory();
+    }
+
+    public function resetAllCounters()
+    {
+        $this->scenarioCounters = $this->stepCounters = array(
+            TestResult::PASSED    => 0,
+            TestResult::FAILED    => 0,
+            StepResult::UNDEFINED => 0,
+            TestResult::PENDING   => 0,
+            TestResult::SKIPPED   => 0
+        );
+    }
+
+    /**
+     * Starts timer.
+     */
+    public function startTimer()
+    {
+        $this->timer->start();
+    }
+
+    /**
+     * Stops timer.
+     */
+    public function stopTimer()
+    {
+        $this->timer->stop();
+    }
+
+    /**
+     * Returns timer object.
+     *
+     * @return Timer
+     */
+    public function getTimer()
+    {
+        return $this->timer;
+    }
+
+    /**
+     * Returns memory usage object.
+     *
+     * @return Memory
+     */
+    public function getMemory()
+    {
+        return $this->memory;
+    }
+
+    /**
+     * Registers scenario stat.
+     *
+     * @param ScenarioStat $stat
+     */
+    public function registerScenarioStat(ScenarioStat $stat)
+    {
+        if (TestResults::NO_TESTS === $stat->getResultCode()) {
+            return;
+        }
+
+        $this->scenarioCounters[$stat->getResultCode()]++;
+
+        if (TestResult::FAILED === $stat->getResultCode()) {
+            $this->failedScenarioStats[] = $stat;
+        }
+
+        if (TestResult::SKIPPED === $stat->getResultCode()) {
+            $this->skippedScenarioStats[] = $stat;
+        }
+    }
+
+    /**
+     * Registers step stat.
+     *
+     * @param StepStat $stat
+     */
+    public function registerStepStat(StepStat $stat)
+    {
+        $this->stepCounters[$stat->getResultCode()]++;
+
+        if (TestResult::FAILED === $stat->getResultCode()) {
+            $this->failedStepStats[] = $stat;
+        }
+
+        if (TestResult::PENDING === $stat->getResultCode()) {
+            $this->pendingStepStats[] = $stat;
+        }
+    }
+
+    /**
+     * Registers hook stat.
+     *
+     * @param HookStat $stat
+     */
+    public function registerHookStat(HookStat $stat)
+    {
+        if ($stat->isSuccessful()) {
+            return;
+        }
+
+        $this->failedHookStats[] = $stat;
+    }
+
+    /**
+     * Returns counters for different scenario result codes.
+     *
+     * @return array[]
+     */
+    public function getScenarioStatCounts()
+    {
+        return $this->scenarioCounters;
+    }
+
+    /**
+     * Returns skipped scenario stats.
+     *
+     * @return ScenarioStat[]
+     */
+    public function getSkippedScenarios()
+    {
+        return $this->skippedScenarioStats;
+    }
+
+    /**
+     * Returns failed scenario stats.
+     *
+     * @return ScenarioStat[]
+     */
+    public function getFailedScenarios()
+    {
+        return $this->failedScenarioStats;
+    }
+
+    /**
+     * Returns counters for different step result codes.
+     *
+     * @return array[]
+     */
+    public function getStepStatCounts()
+    {
+        return $this->stepCounters;
+    }
+
+    /**
+     * Returns failed step stats.
+     *
+     * @return StepStat[]
+     */
+    public function getFailedSteps()
+    {
+        return $this->failedStepStats;
+    }
+
+    /**
+     * Returns pending step stats.
+     *
+     * @return StepStat[]
+     */
+    public function getPendingSteps()
+    {
+        return $this->pendingStepStats;
+    }
+
+    /**
+     * Returns failed hook stats.
+     *
+     * @return HookStat[]
+     */
+    public function getFailedHookStats()
+    {
+        return $this->failedHookStats;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Snippet/AggregateSnippet.php b/vendor/behat/behat/src/Behat/Behat/Snippet/AggregateSnippet.php
new file mode 100644 (file)
index 0000000..cbadc05
--- /dev/null
@@ -0,0 +1,130 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Snippet;
+
+use Behat\Behat\Context\Snippet\ContextSnippet;
+use Behat\Gherkin\Node\StepNode;
+
+/**
+ * Aggregates multiple similar snippets with different targets and steps.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class AggregateSnippet
+{
+    /**
+     * @var Snippet[]
+     */
+    private $snippets;
+
+    /**
+     * Initializes snippet.
+     *
+     * @param Snippet[] $snippets
+     */
+    public function __construct(array $snippets)
+    {
+        $this->snippets = $snippets;
+    }
+
+    /**
+     * Returns snippet type.
+     *
+     * @return string
+     */
+    public function getType()
+    {
+        return current($this->snippets)->getType();
+    }
+
+    /**
+     * Returns snippet unique ID (step type independent).
+     *
+     * @return string
+     */
+    public function getHash()
+    {
+        return current($this->snippets)->getHash();
+    }
+
+    /**
+     * Returns definition snippet text.
+     *
+     * @return string
+     */
+    public function getSnippet()
+    {
+        return current($this->snippets)->getSnippet();
+    }
+
+    /**
+     * Returns all steps interested in this snippet.
+     *
+     * @return StepNode[]
+     */
+    public function getSteps()
+    {
+        return array_unique(
+            array_map(
+                function (Snippet $snippet) {
+                    return $snippet->getStep();
+                },
+                $this->snippets
+            ),
+            SORT_REGULAR
+        );
+    }
+
+    /**
+     * Returns all snippet targets.
+     *
+     * @return string[]
+     */
+    public function getTargets()
+    {
+        return array_unique(
+            array_map(
+                function (Snippet $snippet) {
+                    return $snippet->getTarget();
+                },
+                $this->snippets
+            )
+        );
+    }
+
+    /**
+     * Returns the classes used in the snippet which should be imported.
+     *
+     * @return string[]
+     */
+    public function getUsedClasses()
+    {
+        if (empty($this->snippets)) {
+            return array();
+        }
+
+        return array_unique(
+            call_user_func_array(
+                'array_merge',
+                array_map(
+                    function (Snippet $snippet) {
+                        if (!$snippet instanceof ContextSnippet) {
+                            return array();
+                        }
+
+                        return $snippet->getUsedClasses();
+                    },
+                    $this->snippets
+                )
+            )
+        );
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Snippet/Appender/SnippetAppender.php b/vendor/behat/behat/src/Behat/Behat/Snippet/Appender/SnippetAppender.php
new file mode 100644 (file)
index 0000000..041b8e6
--- /dev/null
@@ -0,0 +1,40 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Snippet\Appender;
+
+use Behat\Behat\Snippet\AggregateSnippet;
+use Behat\Behat\Snippet\SnippetWriter;
+
+/**
+ * Appends snippets to its targets. Used by SnippetWriter.
+ *
+ * @see SnippetWriter
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface SnippetAppender
+{
+    /**
+     * Checks if appender supports snippet.
+     *
+     * @param AggregateSnippet $snippet
+     *
+     * @return Boolean
+     */
+    public function supportsSnippet(AggregateSnippet $snippet);
+
+    /**
+     * Appends snippet to the source.
+     *
+     * @param AggregateSnippet $snippet
+     */
+    public function appendSnippet(AggregateSnippet $snippet);
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Snippet/Cli/SnippetsController.php b/vendor/behat/behat/src/Behat/Behat/Snippet/Cli/SnippetsController.php
new file mode 100644 (file)
index 0000000..8ecdac5
--- /dev/null
@@ -0,0 +1,163 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Snippet\Cli;
+
+use Behat\Behat\EventDispatcher\Event\AfterStepTested;
+use Behat\Behat\EventDispatcher\Event\StepTested;
+use Behat\Behat\Snippet\Printer\ConsoleSnippetPrinter;
+use Behat\Behat\Snippet\SnippetRegistry;
+use Behat\Behat\Snippet\SnippetWriter;
+use Behat\Behat\Tester\Result\StepResult;
+use Behat\Testwork\Cli\Controller;
+use Behat\Testwork\EventDispatcher\Event\ExerciseCompleted;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\EventDispatcher\EventDispatcherInterface;
+
+/**
+ * Appends and prints snippets.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class SnippetsController implements Controller
+{
+    /**
+     * @var SnippetRegistry
+     */
+    private $registry;
+    /**
+     * @var SnippetWriter
+     */
+    private $writer;
+    /**
+     * @var ConsoleSnippetPrinter
+     */
+    private $printer;
+    /**
+     * @var EventDispatcherInterface
+     */
+    private $eventDispatcher;
+    /**
+     * @var OutputInterface
+     */
+    private $output;
+
+    /**
+     * Initializes controller.
+     *
+     * @param SnippetRegistry          $registry
+     * @param SnippetWriter            $writer
+     * @param ConsoleSnippetPrinter    $printer
+     * @param EventDispatcherInterface $eventDispatcher
+     */
+    public function __construct(
+        SnippetRegistry $registry,
+        SnippetWriter $writer,
+        ConsoleSnippetPrinter $printer,
+        EventDispatcherInterface $eventDispatcher
+    ) {
+        $this->registry = $registry;
+        $this->writer = $writer;
+        $this->printer = $printer;
+        $this->eventDispatcher = $eventDispatcher;
+    }
+
+    /**
+     * Configures command to be executable by the controller.
+     *
+     * @param Command $command
+     */
+    public function configure(Command $command)
+    {
+        $command
+            ->addOption(
+                '--append-snippets', null, InputOption::VALUE_NONE,
+                "Appends snippets for undefined steps into main context."
+            )
+            ->addOption(
+                '--no-snippets', null, InputOption::VALUE_NONE,
+                "Do not print snippets for undefined steps after stats."
+            );
+    }
+
+    /**
+     * Executes controller.
+     *
+     * @param InputInterface  $input
+     * @param OutputInterface $output
+     *
+     * @return null|integer
+     */
+    public function execute(InputInterface $input, OutputInterface $output)
+    {
+        $this->eventDispatcher->addListener(StepTested::AFTER, array($this, 'registerUndefinedStep'), -999);
+        $this->output = $output;
+
+        if ($input->getOption('append-snippets')) {
+            $this->eventDispatcher->addListener(ExerciseCompleted::AFTER, array($this, 'appendAllSnippets'), -999);
+        }
+
+        if (!$input->getOption('no-snippets') && !$input->getOption('append-snippets')) {
+            $this->eventDispatcher->addListener(ExerciseCompleted::AFTER, array($this, 'printAllSnippets'), -999);
+        }
+
+        if (!$input->getOption('no-snippets')) {
+            $this->eventDispatcher->addListener(ExerciseCompleted::AFTER, array($this, 'printUndefinedSteps'), -995);
+        }
+    }
+
+    /**
+     * Registers undefined step.
+     *
+     * @param AfterStepTested $event
+     */
+    public function registerUndefinedStep(AfterStepTested $event)
+    {
+        if (StepResult::UNDEFINED === $event->getTestResult()->getResultCode()) {
+            $this->registry->registerUndefinedStep($event->getEnvironment(), $event->getStep());
+        }
+    }
+
+    /**
+     * Appends all snippets to corresponding targets.
+     */
+    public function appendAllSnippets()
+    {
+        $snippets = $this->registry->getSnippets();
+        count($snippets) && $this->output->writeln('');
+
+        $this->writer->appendSnippets($snippets);
+    }
+
+    /**
+     * Prints all snippets.
+     */
+    public function printAllSnippets()
+    {
+        $snippets = $this->registry->getSnippets();
+        count($snippets) && $this->output->writeln('');
+
+        $this->writer->printSnippets($this->printer, $snippets);
+    }
+
+    /**
+     * Prints all undefined steps.
+     */
+    public function printUndefinedSteps()
+    {
+        $undefined = $this->registry->getUndefinedSteps();
+        count($undefined) && $this->output->writeln('');
+
+        $this->writer->printUndefinedSteps($this->printer, $undefined);
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Snippet/Exception/EnvironmentSnippetGenerationException.php b/vendor/behat/behat/src/Behat/Behat/Snippet/Exception/EnvironmentSnippetGenerationException.php
new file mode 100644 (file)
index 0000000..5b01e2f
--- /dev/null
@@ -0,0 +1,50 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Snippet\Exception;
+
+use Behat\Testwork\Environment\Environment;
+use RuntimeException;
+
+/**
+ * Represents exception caused by an attempt to generate snippet for unsupported environment.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class EnvironmentSnippetGenerationException extends RuntimeException implements SnippetException
+{
+    /**
+     * @var Environment
+     */
+    private $environment;
+
+    /**
+     * Initializes exception.
+     *
+     * @param string      $message
+     * @param Environment $environment
+     */
+    public function __construct($message, Environment $environment)
+    {
+        $this->environment = $environment;
+
+        parent::__construct($message);
+    }
+
+    /**
+     * Returns environment that caused exception.
+     *
+     * @return Environment
+     */
+    public function getEnvironment()
+    {
+        return $this->environment;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Snippet/Exception/SnippetException.php b/vendor/behat/behat/src/Behat/Behat/Snippet/Exception/SnippetException.php
new file mode 100644 (file)
index 0000000..f3b23ae
--- /dev/null
@@ -0,0 +1,22 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Snippet\Exception;
+
+use Behat\Testwork\Exception\TestworkException;
+
+/**
+ * All snippet exceptions should implement this interface.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface SnippetException extends TestworkException
+{
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Snippet/Generator/SnippetGenerator.php b/vendor/behat/behat/src/Behat/Behat/Snippet/Generator/SnippetGenerator.php
new file mode 100644 (file)
index 0000000..ca7d739
--- /dev/null
@@ -0,0 +1,46 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Snippet\Generator;
+
+use Behat\Behat\Snippet\Snippet;
+use Behat\Behat\Snippet\SnippetRegistry;
+use Behat\Gherkin\Node\StepNode;
+use Behat\Testwork\Environment\Environment;
+
+/**
+ * Generates snippet for a specific step in a specific environment.
+ *
+ * @see SnippetRegistry
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface SnippetGenerator
+{
+    /**
+     * Checks if generator supports search query.
+     *
+     * @param Environment $environment
+     * @param StepNode    $step
+     *
+     * @return Boolean
+     */
+    public function supportsEnvironmentAndStep(Environment $environment, StepNode $step);
+
+    /**
+     * Generates snippet from search.
+     *
+     * @param Environment $environment
+     * @param StepNode    $step
+     *
+     * @return Snippet
+     */
+    public function generateSnippet(Environment $environment, StepNode $step);
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Snippet/Printer/ConsoleSnippetPrinter.php b/vendor/behat/behat/src/Behat/Behat/Snippet/Printer/ConsoleSnippetPrinter.php
new file mode 100644 (file)
index 0000000..7a5b36e
--- /dev/null
@@ -0,0 +1,87 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Snippet\Printer;
+
+use Behat\Behat\Snippet\AggregateSnippet;
+use Behat\Gherkin\Node\StepNode;
+use Symfony\Component\Console\Formatter\OutputFormatterStyle;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Translation\TranslatorInterface;
+
+/**
+ * Behat console-based snippet printer.
+ *
+ * Extends default printer with default styles.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class ConsoleSnippetPrinter implements SnippetPrinter
+{
+    /**
+     * @var OutputInterface
+     */
+    private $output;
+    /**
+     * @var TranslatorInterface
+     */
+    private $translator;
+
+    /**
+     * Initializes printer.
+     *
+     * @param OutputInterface     $output
+     * @param TranslatorInterface $translator
+     */
+    public function __construct(OutputInterface $output, TranslatorInterface $translator)
+    {
+        $this->output = $output;
+        $this->translator = $translator;
+
+        $output->getFormatter()->setStyle('snippet_keyword', new OutputFormatterStyle(null, null, array('bold')));
+        $output->getFormatter()->setStyle('snippet_undefined', new OutputFormatterStyle('yellow'));
+    }
+
+    /**
+     * Prints snippets of specific target.
+     *
+     * @param string             $targetName
+     * @param AggregateSnippet[] $snippets
+     */
+    public function printSnippets($targetName, array $snippets)
+    {
+        $message = $this->translator->trans('snippet_proposal_title', array('%1%' => $targetName), 'output');
+
+        $this->output->writeln('--- ' . $message . PHP_EOL);
+
+        foreach ($snippets as $snippet) {
+            $this->output->writeln(sprintf('<snippet_undefined>%s</snippet_undefined>', $snippet->getSnippet()) . PHP_EOL);
+        }
+    }
+
+    /**
+     * Prints undefined steps of specific suite.
+     *
+     * @param string     $suiteName
+     * @param StepNode[] $steps
+     */
+    public function printUndefinedSteps($suiteName, array $steps)
+    {
+        $message = $this->translator->trans('snippet_missing_title', array('%1%' => $suiteName), 'output');
+
+        $this->output->writeln('--- ' . $message . PHP_EOL);
+
+        foreach ($steps as $step) {
+            $this->output->writeln(sprintf('    <snippet_undefined>%s %s</snippet_undefined>', $step->getKeyword(), $step->getText()));
+        }
+
+        $this->output->writeln('');
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Snippet/Printer/SnippetPrinter.php b/vendor/behat/behat/src/Behat/Behat/Snippet/Printer/SnippetPrinter.php
new file mode 100644 (file)
index 0000000..a0050af
--- /dev/null
@@ -0,0 +1,38 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Snippet\Printer;
+
+use Behat\Behat\Snippet\AggregateSnippet;
+use Behat\Gherkin\Node\StepNode;
+
+/**
+ * Prints all snippets for a target.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface SnippetPrinter
+{
+    /**
+     * Prints snippets of the specific target.
+     *
+     * @param string             $targetName
+     * @param AggregateSnippet[] $snippets
+     */
+    public function printSnippets($targetName, array $snippets);
+
+    /**
+     * Prints undefined steps of the specific suite.
+     *
+     * @param string     $suiteName
+     * @param StepNode[] $steps
+     */
+    public function printUndefinedSteps($suiteName, array $steps);
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Snippet/ServiceContainer/SnippetExtension.php b/vendor/behat/behat/src/Behat/Behat/Snippet/ServiceContainer/SnippetExtension.php
new file mode 100644 (file)
index 0000000..992c371
--- /dev/null
@@ -0,0 +1,163 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Snippet\ServiceContainer;
+
+use Behat\Testwork\Cli\ServiceContainer\CliExtension;
+use Behat\Testwork\EventDispatcher\ServiceContainer\EventDispatcherExtension;
+use Behat\Testwork\ServiceContainer\Extension;
+use Behat\Testwork\ServiceContainer\ExtensionManager;
+use Behat\Testwork\ServiceContainer\ServiceProcessor;
+use Behat\Testwork\Translator\ServiceContainer\TranslatorExtension;
+use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Definition;
+use Symfony\Component\DependencyInjection\Reference;
+
+/**
+ * Provides snippet generation, printing and appending functionality.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class SnippetExtension implements Extension
+{
+    /*
+     * Available services
+     */
+    const REGISTRY_ID = 'snippet.registry';
+    const WRITER_ID = 'snippet.writer';
+
+    /*
+     * Available extension points
+     */
+    const GENERATOR_TAG = 'snippet.generator';
+    const APPENDER_TAG = 'snippet.appender';
+
+    /**
+     * @var ServiceProcessor
+     */
+    private $processor;
+
+    /**
+     * Initializes extension.
+     *
+     * @param null|ServiceProcessor $processor
+     */
+    public function __construct(ServiceProcessor $processor = null)
+    {
+        $this->processor = $processor ? : new ServiceProcessor();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getConfigKey()
+    {
+        return 'snippets';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function initialize(ExtensionManager $extensionManager)
+    {
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function configure(ArrayNodeDefinition $builder)
+    {
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function load(ContainerBuilder $container, array $config)
+    {
+        $this->loadController($container);
+        $this->loadRegistry($container);
+        $this->loadWriter($container);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function process(ContainerBuilder $container)
+    {
+        $this->processGenerators($container);
+        $this->processAppenders($container);
+    }
+
+    /**
+     * @param ContainerBuilder $container
+     */
+    protected function loadController(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Behat\Snippet\Printer\ConsoleSnippetPrinter', array(
+            new Reference(CliExtension::OUTPUT_ID),
+            new Reference(TranslatorExtension::TRANSLATOR_ID)
+        ));
+        $container->setDefinition('snippet.printer', $definition);
+
+        $definition = new Definition('Behat\Behat\Snippet\Cli\SnippetsController', array(
+            new Reference(self::REGISTRY_ID),
+            new Reference(self::WRITER_ID),
+            new Reference('snippet.printer'),
+            new Reference(EventDispatcherExtension::DISPATCHER_ID)
+        ));
+        $definition->addTag(CliExtension::CONTROLLER_TAG, array('priority' => 400));
+        $container->setDefinition(CliExtension::CONTROLLER_TAG . '.snippet', $definition);
+    }
+
+    /**
+     * @param ContainerBuilder $container
+     */
+    protected function loadRegistry(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Behat\Snippet\SnippetRegistry');
+        $container->setDefinition(self::REGISTRY_ID, $definition);
+    }
+
+    /**
+     * @param ContainerBuilder $container
+     */
+    protected function loadWriter(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Behat\Snippet\SnippetWriter');
+        $container->setDefinition(self::WRITER_ID, $definition);
+    }
+
+    /**
+     * @param ContainerBuilder $container
+     */
+    protected function processGenerators(ContainerBuilder $container)
+    {
+        $references = $this->processor->findAndSortTaggedServices($container, self::GENERATOR_TAG);
+        $definition = $container->getDefinition(self::REGISTRY_ID);
+
+        foreach ($references as $reference) {
+            $definition->addMethodCall('registerSnippetGenerator', array($reference));
+        }
+    }
+
+    /**
+     * @param ContainerBuilder $container
+     */
+    protected function processAppenders(ContainerBuilder $container)
+    {
+        $references = $this->processor->findAndSortTaggedServices($container, self::APPENDER_TAG);
+        $definition = $container->getDefinition(self::WRITER_ID);
+
+        foreach ($references as $reference) {
+            $definition->addMethodCall('registerSnippetAppender', array($reference));
+        }
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Snippet/Snippet.php b/vendor/behat/behat/src/Behat/Behat/Snippet/Snippet.php
new file mode 100644 (file)
index 0000000..b96e445
--- /dev/null
@@ -0,0 +1,56 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Snippet;
+
+use Behat\Gherkin\Node\StepNode;
+
+/**
+ * Step definition snippet.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface Snippet
+{
+    /**
+     * Returns snippet type.
+     *
+     * @return string
+     */
+    public function getType();
+
+    /**
+     * Returns snippet unique ID (step type independent).
+     *
+     * @return string
+     */
+    public function getHash();
+
+    /**
+     * Returns definition snippet text.
+     *
+     * @return string
+     */
+    public function getSnippet();
+
+    /**
+     * Returns step which asked for this snippet.
+     *
+     * @return StepNode
+     */
+    public function getStep();
+
+    /**
+     * Returns snippet target.
+     *
+     * @return string
+     */
+    public function getTarget();
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Snippet/SnippetRegistry.php b/vendor/behat/behat/src/Behat/Behat/Snippet/SnippetRegistry.php
new file mode 100644 (file)
index 0000000..0724c3e
--- /dev/null
@@ -0,0 +1,143 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Snippet;
+
+use Behat\Behat\Snippet\Generator\SnippetGenerator;
+use Behat\Gherkin\Node\StepNode;
+use Behat\Testwork\Environment\Environment;
+
+/**
+ * Acts like a snippet repository by producing snippets from registered undefined steps using snippet generators.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class SnippetRegistry implements SnippetRepository
+{
+    /**
+     * @var SnippetGenerator[]
+     */
+    private $generators = array();
+    /**
+     * @var UndefinedStep[]
+     */
+    private $undefinedSteps = array();
+    /**
+     * @var AggregateSnippet[]
+     */
+    private $snippets = array();
+    /**
+     * @var Boolean
+     */
+    private $snippetsGenerated = false;
+
+    /**
+     * Registers snippet generator.
+     *
+     * @param SnippetGenerator $generator
+     */
+    public function registerSnippetGenerator(SnippetGenerator $generator)
+    {
+        $this->generators[] = $generator;
+        $this->snippetsGenerated = false;
+    }
+
+    /**
+     * Generates and registers snippet.
+     *
+     * @param Environment $environment
+     * @param StepNode    $step
+     *
+     * @return null|Snippet
+     */
+    public function registerUndefinedStep(Environment $environment, StepNode $step)
+    {
+        $this->undefinedSteps[] = new UndefinedStep($environment, $step);
+        $this->snippetsGenerated = false;
+    }
+
+    /**
+     * Returns all generated snippets.
+     *
+     * @return AggregateSnippet[]
+     */
+    public function getSnippets()
+    {
+        $this->generateSnippets();
+
+        return $this->snippets;
+    }
+
+    /**
+     * Returns steps for which there was no snippet generated.
+     *
+     * @return UndefinedStep[]
+     */
+    public function getUndefinedSteps()
+    {
+        $this->generateSnippets();
+
+        return $this->undefinedSteps;
+    }
+
+    /**
+     * Generates snippets for undefined steps.
+     */
+    private function generateSnippets()
+    {
+        if ($this->snippetsGenerated) {
+            return null;
+        }
+
+        $snippetsSet = array();
+        foreach ($this->undefinedSteps as $i => $undefinedStep) {
+            $snippet = $this->generateSnippet($undefinedStep->getEnvironment(), $undefinedStep->getStep());
+
+            if (!$snippet) {
+                continue;
+            }
+
+            if (!isset($snippetsSet[$snippet->getHash()])) {
+                $snippetsSet[$snippet->getHash()] = array();
+            }
+
+            $snippetsSet[$snippet->getHash()][] = $snippet;
+            unset($this->undefinedSteps[$i]);
+        }
+
+        $this->snippets = array_values(
+            array_map(
+                function (array $snippets) {
+                    return new AggregateSnippet($snippets);
+                },
+                $snippetsSet
+            )
+        );
+        $this->undefinedSteps = array_values($this->undefinedSteps);
+        $this->snippetsGenerated = true;
+    }
+
+    /**
+     * @param Environment $environment
+     * @param StepNode    $step
+     *
+     * @return null|Snippet
+     */
+    private function generateSnippet(Environment $environment, StepNode $step)
+    {
+        foreach ($this->generators as $generator) {
+            if ($generator->supportsEnvironmentAndStep($environment, $step)) {
+                return $generator->generateSnippet($environment, $step);
+            }
+        }
+
+        return null;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Snippet/SnippetRepository.php b/vendor/behat/behat/src/Behat/Behat/Snippet/SnippetRepository.php
new file mode 100644 (file)
index 0000000..0305c4c
--- /dev/null
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Snippet;
+
+/**
+ * Provides snippets.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface SnippetRepository
+{
+    /**
+     * Returns all generated snippets.
+     *
+     * @return AggregateSnippet[]
+     */
+    public function getSnippets();
+
+    /**
+     * Returns steps for which there was no snippet generated.
+     *
+     * @return UndefinedStep[]
+     */
+    public function getUndefinedSteps();
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Snippet/SnippetWriter.php b/vendor/behat/behat/src/Behat/Behat/Snippet/SnippetWriter.php
new file mode 100644 (file)
index 0000000..62d6e96
--- /dev/null
@@ -0,0 +1,117 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Snippet;
+
+use Behat\Behat\Snippet\Appender\SnippetAppender;
+use Behat\Behat\Snippet\Printer\SnippetPrinter;
+
+/**
+ * Prints or appends snippets to a specific environment using registered appenders and printers.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class SnippetWriter
+{
+    /**
+     * @var SnippetAppender[]
+     */
+    private $appenders = array();
+
+    /**
+     * Registers snippet appender.
+     *
+     * @param SnippetAppender $appender
+     */
+    public function registerSnippetAppender(SnippetAppender $appender)
+    {
+        $this->appenders[] = $appender;
+    }
+
+    /**
+     * Appends snippets to appropriate targets.
+     *
+     * @param AggregateSnippet[] $snippets
+     */
+    public function appendSnippets(array $snippets)
+    {
+        foreach ($snippets as $snippet) {
+            $this->appendSnippet($snippet);
+        }
+    }
+
+    /**
+     * Prints snippets using provided printer.
+     *
+     * @param SnippetPrinter     $printer
+     * @param AggregateSnippet[] $snippets
+     */
+    public function printSnippets(SnippetPrinter $printer, array $snippets)
+    {
+        $printableSnippets = array();
+        foreach ($snippets as $snippet) {
+            foreach ($snippet->getTargets() as $target) {
+                $targetSnippets = array();
+
+                if (isset($printableSnippets[$target])) {
+                    $targetSnippets = $printableSnippets[$target];
+                }
+
+                $targetSnippets[] = $snippet;
+                $printableSnippets[$target] = $targetSnippets;
+            }
+        }
+
+        foreach ($printableSnippets as $target => $targetSnippets) {
+            $printer->printSnippets($target, $targetSnippets);
+        }
+    }
+
+    /**
+     * Prints undefined steps using provided printer.
+     *
+     * @param SnippetPrinter  $printer
+     * @param UndefinedStep[] $undefinedSteps
+     */
+    public function printUndefinedSteps(SnippetPrinter $printer, array $undefinedSteps)
+    {
+        $printableSteps = array();
+        foreach ($undefinedSteps as $undefinedStep) {
+            $suiteName = $undefinedStep->getEnvironment()->getSuite()->getName();
+            $step = $undefinedStep->getStep();
+
+            if (!isset($printableSteps[$suiteName])) {
+                $printableSteps[$suiteName] = array();
+            }
+
+            $printableSteps[$suiteName][$step->getText()] = $step;
+        }
+
+        foreach ($printableSteps as $suiteName => $steps) {
+            $printer->printUndefinedSteps($suiteName, array_values($steps));
+        }
+    }
+
+    /**
+     * Appends snippet to appropriate targets.
+     *
+     * @param AggregateSnippet $snippet
+     */
+    private function appendSnippet(AggregateSnippet $snippet)
+    {
+        foreach ($this->appenders as $appender) {
+            if (!$appender->supportsSnippet($snippet)) {
+                continue;
+            }
+
+            $appender->appendSnippet($snippet);
+        }
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Snippet/UndefinedStep.php b/vendor/behat/behat/src/Behat/Behat/Snippet/UndefinedStep.php
new file mode 100644 (file)
index 0000000..58e3ddd
--- /dev/null
@@ -0,0 +1,63 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Snippet;
+
+use Behat\Gherkin\Node\StepNode;
+use Behat\Testwork\Environment\Environment;
+
+/**
+ * Represents an undefined step in a specific environment.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class UndefinedStep
+{
+    /**
+     * @var Environment
+     */
+    private $environment;
+    /**
+     * @var StepNode
+     */
+    private $step;
+
+    /**
+     * Initializes undefined step.
+     *
+     * @param Environment $environment
+     * @param StepNode    $step
+     */
+    public function __construct(Environment $environment, StepNode $step)
+    {
+        $this->environment = $environment;
+        $this->step = $step;
+    }
+
+    /**
+     * Returns environment that needs this step.
+     *
+     * @return Environment
+     */
+    public function getEnvironment()
+    {
+        return $this->environment;
+    }
+
+    /**
+     * Returns undefined step node.
+     *
+     * @return StepNode
+     */
+    public function getStep()
+    {
+        return $this->step;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Tester/BackgroundTester.php b/vendor/behat/behat/src/Behat/Behat/Tester/BackgroundTester.php
new file mode 100644 (file)
index 0000000..8d70b57
--- /dev/null
@@ -0,0 +1,59 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Tester;
+
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\Tester\Result\TestResult;
+use Behat\Testwork\Tester\Setup\Setup;
+use Behat\Testwork\Tester\Setup\Teardown;
+
+/**
+ * Prepares and tests background from a provided feature object against provided environment.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface BackgroundTester
+{
+    /**
+     * Sets up background for a test.
+     *
+     * @param Environment $env
+     * @param FeatureNode $feature
+     * @param Boolean     $skip
+     *
+     * @return Setup
+     */
+    public function setUp(Environment $env, FeatureNode $feature, $skip);
+
+    /**
+     * Tests background.
+     *
+     * @param Environment $env
+     * @param FeatureNode $feature
+     * @param Boolean     $skip
+     *
+     * @return TestResult
+     */
+    public function test(Environment $env, FeatureNode $feature, $skip);
+
+    /**
+     * Tears down background after a test.
+     *
+     * @param Environment $env
+     * @param FeatureNode $feature
+     * @param Boolean     $skip
+     * @param TestResult  $result
+     *
+     * @return Teardown
+     */
+    public function tearDown(Environment $env, FeatureNode $feature, $skip, TestResult $result);
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Tester/Cli/RerunController.php b/vendor/behat/behat/src/Behat/Behat/Tester/Cli/RerunController.php
new file mode 100644 (file)
index 0000000..93bd84f
--- /dev/null
@@ -0,0 +1,185 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Tester\Cli;
+
+use Behat\Behat\EventDispatcher\Event\AfterScenarioTested;
+use Behat\Behat\EventDispatcher\Event\ExampleTested;
+use Behat\Behat\EventDispatcher\Event\ScenarioTested;
+use Behat\Testwork\Cli\Controller;
+use Behat\Testwork\EventDispatcher\Event\ExerciseCompleted;
+use Behat\Testwork\Tester\Result\TestResult;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\EventDispatcher\EventDispatcherInterface;
+
+/**
+ * Caches failed scenarios and reruns only them if `--rerun` option provided.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class RerunController implements Controller
+{
+    /**
+     * @var EventDispatcherInterface
+     */
+    private $eventDispatcher;
+    /**
+     * @var null|string
+     */
+    private $cachePath;
+    /**
+     * @var string
+     */
+    private $key;
+    /**
+     * @var string[]
+     */
+    private $lines = array();
+    /**
+     * @var string
+     */
+    private $basepath;
+
+    /**
+     * Initializes controller.
+     *
+     * @param EventDispatcherInterface $eventDispatcher
+     * @param null|string              $cachePath
+     * @param string                   $basepath
+     */
+    public function __construct(EventDispatcherInterface $eventDispatcher, $cachePath, $basepath)
+    {
+        $this->eventDispatcher = $eventDispatcher;
+        $this->cachePath = null !== $cachePath ? rtrim($cachePath, DIRECTORY_SEPARATOR) : null;
+        $this->basepath = $basepath;
+    }
+
+    /**
+     * Configures command to be executable by the controller.
+     *
+     * @param Command $command
+     */
+    public function configure(Command $command)
+    {
+        $command->addOption('--rerun', null, InputOption::VALUE_NONE,
+            'Re-run scenarios that failed during last execution.'
+        );
+    }
+
+    /**
+     * Executes controller.
+     *
+     * @param InputInterface  $input
+     * @param OutputInterface $output
+     *
+     * @return null|integer
+     */
+    public function execute(InputInterface $input, OutputInterface $output)
+    {
+        $this->eventDispatcher->addListener(ScenarioTested::AFTER, array($this, 'collectFailedScenario'), -50);
+        $this->eventDispatcher->addListener(ExampleTested::AFTER, array($this, 'collectFailedScenario'), -50);
+        $this->eventDispatcher->addListener(ExerciseCompleted::AFTER, array($this, 'writeCache'), -50);
+
+        $this->key = $this->generateKey($input);
+
+        if (!$input->getOption('rerun')) {
+            return;
+        }
+
+        if (!$this->getFileName() || !file_exists($this->getFileName())) {
+            return;
+        }
+
+        $input->setArgument('paths', $this->getFileName());
+    }
+
+    /**
+     * Records scenario if it is failed.
+     *
+     * @param AfterScenarioTested $event
+     */
+    public function collectFailedScenario(AfterScenarioTested $event)
+    {
+        if (!$this->getFileName()) {
+            return;
+        }
+
+        if ($event->getTestResult()->getResultCode() !== TestResult::FAILED) {
+            return;
+        }
+
+        $feature = $event->getFeature();
+        $scenario = $event->getScenario();
+        $suitename = $event->getSuite()->getName();
+
+        $this->lines[$suitename][] = $feature->getFile() . ':' . $scenario->getLine();
+    }
+
+    /**
+     * Writes failed scenarios cache.
+     */
+    public function writeCache()
+    {
+        if (!$this->getFileName()) {
+            return;
+        }
+
+        if (file_exists($this->getFileName())) {
+            unlink($this->getFileName());
+        }
+
+        if (0 === count($this->lines)) {
+            return;
+        }
+
+        file_put_contents($this->getFileName(), json_encode($this->lines));
+    }
+
+    /**
+     * Generates cache key.
+     *
+     * @param InputInterface $input
+     *
+     * @return string
+     */
+    private function generateKey(InputInterface $input)
+    {
+        return md5(
+            $input->getParameterOption(array('--profile', '-p')) .
+            $input->getOption('suite') .
+            implode(' ', $input->getOption('name')) .
+            implode(' ', $input->getOption('tags')) .
+            $input->getOption('role') .
+            $input->getArgument('paths') .
+            $this->basepath
+        );
+    }
+
+    /**
+     * Returns cache filename (if exists).
+     *
+     * @return null|string
+     */
+    private function getFileName()
+    {
+        if (null === $this->cachePath || null === $this->key) {
+            return null;
+        }
+
+        if (!is_dir($this->cachePath)) {
+            mkdir($this->cachePath, 0777);
+        }
+
+        return $this->cachePath . DIRECTORY_SEPARATOR . $this->key . '.rerun';
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Tester/Exception/FeatureHasNoBackgroundException.php b/vendor/behat/behat/src/Behat/Behat/Tester/Exception/FeatureHasNoBackgroundException.php
new file mode 100644 (file)
index 0000000..6d31eb1
--- /dev/null
@@ -0,0 +1,51 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Tester\Exception;
+
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Testwork\Exception\TestworkException;
+use RuntimeException;
+
+/**
+ * Represents exception throw during attempt to test non-existent feature background.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class FeatureHasNoBackgroundException extends RuntimeException implements TestworkException
+{
+    /**
+     * @var FeatureNode
+     */
+    private $feature;
+
+    /**
+     * Initializes exception.
+     *
+     * @param string      $message
+     * @param FeatureNode $feature
+     */
+    public function __construct($message, FeatureNode $feature)
+    {
+        $this->feature = $feature;
+
+        parent::__construct($message);
+    }
+
+    /**
+     * Returns feature that caused exception.
+     *
+     * @return FeatureNode
+     */
+    public function getFeature()
+    {
+        return $this->feature;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Tester/Exception/PendingException.php b/vendor/behat/behat/src/Behat/Behat/Tester/Exception/PendingException.php
new file mode 100644 (file)
index 0000000..c328bd1
--- /dev/null
@@ -0,0 +1,32 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Tester\Exception;
+
+use Behat\Testwork\Tester\Exception\TesterException;
+use RuntimeException;
+
+/**
+ * Represents a pending exception.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class PendingException extends RuntimeException implements TesterException
+{
+    /**
+     * Initializes pending exception.
+     *
+     * @param string $text
+     */
+    public function __construct($text = 'TODO: write pending definition')
+    {
+        parent::__construct($text);
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Tester/Exception/Stringer/PendingExceptionStringer.php b/vendor/behat/behat/src/Behat/Behat/Tester/Exception/Stringer/PendingExceptionStringer.php
new file mode 100644 (file)
index 0000000..ef299ce
--- /dev/null
@@ -0,0 +1,39 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Tester\Exception\Stringer;
+
+use Behat\Behat\Tester\Exception\PendingException;
+use Behat\Testwork\Exception\Stringer\ExceptionStringer;
+use Exception;
+
+/**
+ * Strings pending exceptions.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class PendingExceptionStringer implements ExceptionStringer
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function supportsException(Exception $exception)
+    {
+        return $exception instanceof PendingException;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function stringException(Exception $exception, $verbosity)
+    {
+        return trim($exception->getMessage());
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Tester/OutlineTester.php b/vendor/behat/behat/src/Behat/Behat/Tester/OutlineTester.php
new file mode 100644 (file)
index 0000000..863aba3
--- /dev/null
@@ -0,0 +1,63 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Tester;
+
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\OutlineNode;
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\Tester\Result\TestResult;
+use Behat\Testwork\Tester\Setup\Setup;
+use Behat\Testwork\Tester\Setup\Teardown;
+
+/**
+ * Prepares and tests provided outline object against provided environment.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface OutlineTester
+{
+    /**
+     * Sets up background for a test.
+     *
+     * @param Environment $env
+     * @param FeatureNode $feature
+     * @param OutlineNode $outline
+     * @param Boolean     $skip
+     *
+     * @return Setup
+     */
+    public function setUp(Environment $env, FeatureNode $feature, OutlineNode $outline, $skip);
+
+    /**
+     * Tests outline.
+     *
+     * @param Environment $env
+     * @param FeatureNode $feature
+     * @param OutlineNode $outline
+     * @param Boolean     $skip
+     *
+     * @return TestResult
+     */
+    public function test(Environment $env, FeatureNode $feature, OutlineNode $outline, $skip);
+
+    /**
+     * Sets up background for a test.
+     *
+     * @param Environment $env
+     * @param FeatureNode $feature
+     * @param OutlineNode $outline
+     * @param Boolean     $skip
+     * @param TestResult  $result
+     *
+     * @return Teardown
+     */
+    public function tearDown(Environment $env, FeatureNode $feature, OutlineNode $outline, $skip, TestResult $result);
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Tester/Result/DefinedStepResult.php b/vendor/behat/behat/src/Behat/Behat/Tester/Result/DefinedStepResult.php
new file mode 100644 (file)
index 0000000..ba0c935
--- /dev/null
@@ -0,0 +1,28 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Tester\Result;
+
+use Behat\Behat\Definition\Definition;
+
+/**
+ * Represents a step result that contains step definition.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface DefinedStepResult extends StepResult
+{
+    /**
+     * Returns found step definition.
+     *
+     * @return null|Definition
+     */
+    public function getStepDefinition();
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Tester/Result/ExecutedStepResult.php b/vendor/behat/behat/src/Behat/Behat/Tester/Result/ExecutedStepResult.php
new file mode 100644 (file)
index 0000000..40633ec
--- /dev/null
@@ -0,0 +1,113 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Tester\Result;
+
+use Behat\Behat\Definition\SearchResult;
+use Behat\Behat\Tester\Exception\PendingException;
+use Behat\Testwork\Call\CallResult;
+use Behat\Testwork\Tester\Result\ExceptionResult;
+
+/**
+ * Represents an executed (successfully or not) step result.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class ExecutedStepResult implements StepResult, DefinedStepResult, ExceptionResult
+{
+    /**
+     * @var SearchResult
+     */
+    private $searchResult;
+    /**
+     * @var null|CallResult
+     */
+    private $callResult;
+
+    /**
+     * Initialize test result.
+     *
+     * @param SearchResult $searchResult
+     * @param CallResult   $callResult
+     */
+    public function __construct(SearchResult $searchResult, CallResult $callResult)
+    {
+        $this->searchResult = $searchResult;
+        $this->callResult = $callResult;
+    }
+
+    /**
+     * Returns definition search result.
+     *
+     * @return SearchResult
+     */
+    public function getSearchResult()
+    {
+        return $this->searchResult;
+    }
+
+    /**
+     * Returns definition call result or null if no call were made.
+     *
+     * @return CallResult
+     */
+    public function getCallResult()
+    {
+        return $this->callResult;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getStepDefinition()
+    {
+        return $this->searchResult->getMatchedDefinition();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function hasException()
+    {
+        return null !== $this->getException();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getException()
+    {
+        return $this->callResult->getException();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getResultCode()
+    {
+        if ($this->callResult->hasException() && $this->callResult->getException() instanceof PendingException) {
+            return self::PENDING;
+        }
+
+        if ($this->callResult->hasException()) {
+            return self::FAILED;
+        }
+
+        return self::PASSED;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function isPassed()
+    {
+        return self::PASSED == $this->getResultCode();
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Tester/Result/FailedStepSearchResult.php b/vendor/behat/behat/src/Behat/Behat/Tester/Result/FailedStepSearchResult.php
new file mode 100644 (file)
index 0000000..94fe072
--- /dev/null
@@ -0,0 +1,69 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Tester\Result;
+
+use Behat\Behat\Definition\Exception\SearchException;
+use Behat\Testwork\Tester\Result\ExceptionResult;
+
+/**
+ * Represents a step test result with a failed definition search.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class FailedStepSearchResult implements StepResult, ExceptionResult
+{
+    /**
+     * @var SearchException
+     */
+    private $searchException;
+
+    /**
+     * Initializes result.
+     *
+     * @param SearchException $searchException
+     */
+    public function __construct(SearchException $searchException)
+    {
+        $this->searchException = $searchException;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function hasException()
+    {
+        return true;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getException()
+    {
+        return $this->searchException;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function isPassed()
+    {
+        return false;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getResultCode()
+    {
+        return self::FAILED;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Tester/Result/SkippedStepResult.php b/vendor/behat/behat/src/Behat/Behat/Tester/Result/SkippedStepResult.php
new file mode 100644 (file)
index 0000000..4788d24
--- /dev/null
@@ -0,0 +1,70 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Tester\Result;
+
+use Behat\Behat\Definition\SearchResult;
+
+/**
+ * Represents a skipped step result.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class SkippedStepResult implements StepResult, DefinedStepResult
+{
+    /**
+     * @var SearchResult
+     */
+    private $searchResult;
+
+    /**
+     * Initializes step result.
+     *
+     * @param SearchResult $searchResult
+     */
+    public function __construct(SearchResult $searchResult)
+    {
+        $this->searchResult = $searchResult;
+    }
+    
+    /**
+     * Returns definition search result.
+     *
+     * @return SearchResult
+     */
+    public function getSearchResult()
+    {
+        return $this->searchResult;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getStepDefinition()
+    {
+        return $this->searchResult->getMatchedDefinition();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function isPassed()
+    {
+        return false;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getResultCode()
+    {
+        return self::SKIPPED;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Tester/Result/StepResult.php b/vendor/behat/behat/src/Behat/Behat/Tester/Result/StepResult.php
new file mode 100644 (file)
index 0000000..0a898c9
--- /dev/null
@@ -0,0 +1,23 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Tester\Result;
+
+use Behat\Testwork\Tester\Result\TestResult;
+
+/**
+ * Extends Testwork test result with support for undefined status.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface StepResult extends TestResult
+{
+    const UNDEFINED = 30;
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Tester/Result/UndefinedStepResult.php b/vendor/behat/behat/src/Behat/Behat/Tester/Result/UndefinedStepResult.php
new file mode 100644 (file)
index 0000000..1268cb7
--- /dev/null
@@ -0,0 +1,35 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Tester\Result;
+
+/**
+ * Represents an undefined step result.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class UndefinedStepResult implements StepResult
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function isPassed()
+    {
+        return false;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getResultCode()
+    {
+        return self::UNDEFINED;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Tester/Runtime/IsolatingScenarioTester.php b/vendor/behat/behat/src/Behat/Behat/Tester/Runtime/IsolatingScenarioTester.php
new file mode 100644 (file)
index 0000000..f526b70
--- /dev/null
@@ -0,0 +1,84 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Tester\Runtime;
+
+use Behat\Behat\Tester\ScenarioTester;
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\ScenarioInterface as Scenario;
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\Environment\EnvironmentManager;
+use Behat\Testwork\Tester\Result\IntegerTestResult;
+use Behat\Testwork\Tester\Result\TestResult;
+use Behat\Testwork\Tester\Result\TestWithSetupResult;
+use Behat\Testwork\Tester\Setup\SuccessfulSetup;
+use Behat\Testwork\Tester\Setup\SuccessfulTeardown;
+
+/**
+ * Scenario tester that isolates the environment for each scenario.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class IsolatingScenarioTester implements ScenarioTester
+{
+    /**
+     * @var ScenarioTester
+     */
+    private $decoratedTester;
+    /**
+     * @var EnvironmentManager
+     */
+    private $envManager;
+
+    /**
+     * Initialises tester.
+     *
+     * @param ScenarioTester     $decoratedTester
+     * @param EnvironmentManager $envManager
+     */
+    public function __construct(ScenarioTester $decoratedTester, EnvironmentManager $envManager)
+    {
+        $this->decoratedTester = $decoratedTester;
+        $this->envManager = $envManager;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setUp(Environment $env, FeatureNode $feature, Scenario $scenario, $skip)
+    {
+        return new SuccessfulSetup();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function test(Environment $env, FeatureNode $feature, Scenario $scenario, $skip)
+    {
+        $isolatedEnvironment = $this->envManager->isolateEnvironment($env, $scenario);
+
+        $setup = $this->decoratedTester->setUp($isolatedEnvironment, $feature, $scenario, $skip);
+        $localSkip = !$setup->isSuccessful() || $skip;
+        $testResult = $this->decoratedTester->test($isolatedEnvironment, $feature, $scenario, $localSkip);
+        $teardown = $this->decoratedTester->tearDown($isolatedEnvironment, $feature, $scenario, $localSkip, $testResult);
+
+        $integerResult = new IntegerTestResult($testResult->getResultCode());
+
+        return new TestWithSetupResult($setup, $integerResult, $teardown);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function tearDown(Environment $env, FeatureNode $feature, Scenario $scenario, $skip, TestResult $result)
+    {
+        return new SuccessfulTeardown();
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Tester/Runtime/RuntimeBackgroundTester.php b/vendor/behat/behat/src/Behat/Behat/Tester/Runtime/RuntimeBackgroundTester.php
new file mode 100644 (file)
index 0000000..72d5c9d
--- /dev/null
@@ -0,0 +1,84 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Tester\Runtime;
+
+use Behat\Behat\Tester\BackgroundTester;
+use Behat\Behat\Tester\Exception\FeatureHasNoBackgroundException;
+use Behat\Behat\Tester\StepContainerTester;
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\Tester\Result\IntegerTestResult;
+use Behat\Testwork\Tester\Result\TestResult;
+use Behat\Testwork\Tester\Result\TestResults;
+use Behat\Testwork\Tester\Setup\SuccessfulSetup;
+use Behat\Testwork\Tester\Setup\SuccessfulTeardown;
+
+/**
+ * Tester executing background tests in the runtime.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class RuntimeBackgroundTester implements BackgroundTester
+{
+    /**
+     * @var StepContainerTester
+     */
+    private $containerTester;
+
+    /**
+     * Initializes tester.
+     *
+     * @param StepContainerTester $containerTester
+     */
+    public function __construct(StepContainerTester $containerTester)
+    {
+        $this->containerTester = $containerTester;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setUp(Environment $env, FeatureNode $feature, $skip)
+    {
+        return new SuccessfulSetup();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function test(Environment $env, FeatureNode $feature, $skip)
+    {
+        $background = $feature->getBackground();
+
+        if (null === $background) {
+            throw new FeatureHasNoBackgroundException(sprintf(
+                'Feature `%s` has no background that could be tested.',
+                $feature->getFile()
+            ), $feature);
+        }
+
+        if (!$background->hasSteps()) {
+            return new IntegerTestResult(TestResult::PASSED);
+        }
+
+        $results = $this->containerTester->test($env, $feature, $background, $skip);
+
+        return new TestResults($results);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function tearDown(Environment $env, FeatureNode $feature, $skip, TestResult $result)
+    {
+        return new SuccessfulTeardown();
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Tester/Runtime/RuntimeFeatureTester.php b/vendor/behat/behat/src/Behat/Behat/Tester/Runtime/RuntimeFeatureTester.php
new file mode 100644 (file)
index 0000000..dcafc7e
--- /dev/null
@@ -0,0 +1,101 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Tester\Runtime;
+
+use Behat\Behat\Tester\OutlineTester;
+use Behat\Behat\Tester\ScenarioTester;
+use Behat\Gherkin\Node\OutlineNode;
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\Environment\EnvironmentManager;
+use Behat\Testwork\Tester\Result\IntegerTestResult;
+use Behat\Testwork\Tester\Result\TestResult;
+use Behat\Testwork\Tester\Result\TestResults;
+use Behat\Testwork\Tester\Result\TestWithSetupResult;
+use Behat\Testwork\Tester\Setup\SuccessfulSetup;
+use Behat\Testwork\Tester\Setup\SuccessfulTeardown;
+use Behat\Testwork\Tester\SpecificationTester;
+
+/**
+ * Tester executing feature tests in the runtime.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class RuntimeFeatureTester implements SpecificationTester
+{
+    /**
+     * @var ScenarioTester
+     */
+    private $scenarioTester;
+    /**
+     * @var OutlineTester
+     */
+    private $outlineTester;
+    /**
+     * @var EnvironmentManager
+     */
+    private $envManager;
+
+    /**
+     * Initializes tester.
+     *
+     * @param ScenarioTester     $scenarioTester
+     * @param OutlineTester      $outlineTester
+     * @param EnvironmentManager $envManager
+     *
+     * TODO: Remove EnvironmentManager parameter in next major
+     */
+    public function __construct(
+        ScenarioTester $scenarioTester,
+        OutlineTester $outlineTester,
+        EnvironmentManager $envManager
+    ) {
+        $this->scenarioTester = $scenarioTester;
+        $this->outlineTester = $outlineTester;
+        $this->envManager = $envManager;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setUp(Environment $env, $spec, $skip)
+    {
+        return new SuccessfulSetup();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function test(Environment $env, $feature, $skip = false)
+    {
+        $results = array();
+        foreach ($feature->getScenarios() as $scenario) {
+            $tester = $scenario instanceof OutlineNode ? $this->outlineTester : $this->scenarioTester;
+
+            $setup = $tester->setUp($env, $feature, $scenario, $skip);
+            $localSkip = !$setup->isSuccessful() || $skip;
+            $testResult = $tester->test($env, $feature, $scenario, $localSkip);
+            $teardown = $tester->tearDown($env, $feature, $scenario, $localSkip, $testResult);
+
+            $integerResult = new IntegerTestResult($testResult->getResultCode());
+            $results[] = new TestWithSetupResult($setup, $integerResult, $teardown);
+        }
+
+        return new TestResults($results);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function tearDown(Environment $env, $spec, $skip, TestResult $result)
+    {
+        return new SuccessfulTeardown();
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Tester/Runtime/RuntimeOutlineTester.php b/vendor/behat/behat/src/Behat/Behat/Tester/Runtime/RuntimeOutlineTester.php
new file mode 100644 (file)
index 0000000..1c1c38b
--- /dev/null
@@ -0,0 +1,81 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Tester\Runtime;
+
+use Behat\Behat\Tester\OutlineTester;
+use Behat\Behat\Tester\ScenarioTester;
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\OutlineNode;
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\Tester\Result\IntegerTestResult;
+use Behat\Testwork\Tester\Result\TestResult;
+use Behat\Testwork\Tester\Result\TestResults;
+use Behat\Testwork\Tester\Result\TestWithSetupResult;
+use Behat\Testwork\Tester\Setup\SuccessfulSetup;
+use Behat\Testwork\Tester\Setup\SuccessfulTeardown;
+
+/**
+ * Tester executing outline tests in the runtime.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class RuntimeOutlineTester implements OutlineTester
+{
+    /**
+     * @var ScenarioTester
+     */
+    private $scenarioTester;
+
+    /**
+     * Initializes tester.
+     *
+     * @param ScenarioTester $scenarioTester
+     */
+    public function __construct(ScenarioTester $scenarioTester)
+    {
+        $this->scenarioTester = $scenarioTester;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setUp(Environment $env, FeatureNode $feature, OutlineNode $outline, $skip)
+    {
+        return new SuccessfulSetup();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function test(Environment $env, FeatureNode $feature, OutlineNode $outline, $skip = false)
+    {
+        $results = array();
+        foreach ($outline->getExamples() as $example) {
+            $setup = $this->scenarioTester->setUp($env, $feature, $example, $skip);
+            $localSkip = !$setup->isSuccessful() || $skip;
+            $testResult = $this->scenarioTester->test($env, $feature, $example, $localSkip);
+            $teardown = $this->scenarioTester->tearDown($env, $feature, $example, $localSkip, $testResult);
+
+            $integerResult = new IntegerTestResult($testResult->getResultCode());
+            $results[] = new TestWithSetupResult($setup, $integerResult, $teardown);
+        }
+
+        return new TestResults($results);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function tearDown(Environment $env, FeatureNode $feature, OutlineNode $outline, $skip, TestResult $result)
+    {
+        return new SuccessfulTeardown();
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Tester/Runtime/RuntimeScenarioTester.php b/vendor/behat/behat/src/Behat/Behat/Tester/Runtime/RuntimeScenarioTester.php
new file mode 100644 (file)
index 0000000..7ab11a0
--- /dev/null
@@ -0,0 +1,109 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Tester\Runtime;
+
+use Behat\Behat\Tester\BackgroundTester;
+use Behat\Behat\Tester\StepContainerTester;
+use Behat\Behat\Tester\ScenarioTester;
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\ScenarioInterface as Scenario;
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\Tester\Result\IntegerTestResult;
+use Behat\Testwork\Tester\Result\TestResult;
+use Behat\Testwork\Tester\Result\TestResults;
+use Behat\Testwork\Tester\Result\TestWithSetupResult;
+use Behat\Testwork\Tester\Setup\SuccessfulSetup;
+use Behat\Testwork\Tester\Setup\SuccessfulTeardown;
+
+/**
+ * Tester executing scenario or example tests in the runtime.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class RuntimeScenarioTester implements ScenarioTester
+{
+    /**
+     * @var StepContainerTester
+     */
+    private $containerTester;
+    /**
+     * @var BackgroundTester
+     */
+    private $backgroundTester;
+
+    /**
+     * Initializes tester.
+     *
+     * @param StepContainerTester $containerTester
+     * @param BackgroundTester    $backgroundTester
+     */
+    public function __construct(StepContainerTester $containerTester, BackgroundTester $backgroundTester)
+    {
+        $this->containerTester = $containerTester;
+        $this->backgroundTester = $backgroundTester;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setUp(Environment $env, FeatureNode $feature, Scenario $example, $skip)
+    {
+        return new SuccessfulSetup();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function test(Environment $env, FeatureNode $feature, Scenario $scenario, $skip = false)
+    {
+        $results = array();
+
+        if ($feature->hasBackground()) {
+            $backgroundResult = $this->testBackground($env, $feature, $skip);
+            $skip = !$backgroundResult->isPassed() || $skip;
+
+            $results[] = $backgroundResult;
+        }
+
+        $results = array_merge($results, $this->containerTester->test($env, $feature, $scenario, $skip));
+
+        return new TestResults($results);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function tearDown(Environment $env, FeatureNode $feature, Scenario $scenario, $skip, TestResult $result)
+    {
+        return new SuccessfulTeardown();
+    }
+
+    /**
+     * Tests background of the provided feature against provided environment.
+     *
+     * @param Environment $env
+     * @param FeatureNode $feature
+     * @param Boolean     $skip
+     *
+     * @return TestResult
+     */
+    private function testBackground(Environment $env, FeatureNode $feature, $skip)
+    {
+        $setup = $this->backgroundTester->setUp($env, $feature, $skip);
+        $skipSetup = !$setup->isSuccessful() || $skip;
+        $testResult = $this->backgroundTester->test($env, $feature, $skipSetup);
+        $teardown = $this->backgroundTester->tearDown($env, $feature, $skipSetup, $testResult);
+
+        $integerResult = new IntegerTestResult($testResult->getResultCode());
+
+        return new TestWithSetupResult($setup, $integerResult, $teardown);
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Tester/Runtime/RuntimeStepTester.php b/vendor/behat/behat/src/Behat/Behat/Tester/Runtime/RuntimeStepTester.php
new file mode 100644 (file)
index 0000000..7031eec
--- /dev/null
@@ -0,0 +1,147 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Tester\Runtime;
+
+use Behat\Behat\Definition\Call\DefinitionCall;
+use Behat\Behat\Definition\DefinitionFinder;
+use Behat\Behat\Definition\Exception\SearchException;
+use Behat\Behat\Definition\SearchResult;
+use Behat\Behat\Tester\Result\ExecutedStepResult;
+use Behat\Behat\Tester\Result\FailedStepSearchResult;
+use Behat\Behat\Tester\Result\SkippedStepResult;
+use Behat\Behat\Tester\Result\StepResult;
+use Behat\Behat\Tester\Result\UndefinedStepResult;
+use Behat\Behat\Tester\StepTester;
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\StepNode;
+use Behat\Testwork\Call\CallCenter;
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\Tester\Setup\SuccessfulSetup;
+use Behat\Testwork\Tester\Setup\SuccessfulTeardown;
+
+/**
+ * Tester executing step tests in the runtime.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class RuntimeStepTester implements StepTester
+{
+    /**
+     * @var DefinitionFinder
+     */
+    private $definitionFinder;
+    /**
+     * @var CallCenter
+     */
+    private $callCenter;
+
+    /**
+     * Initialize tester.
+     *
+     * @param DefinitionFinder $definitionFinder
+     * @param CallCenter       $callCenter
+     */
+    public function __construct(DefinitionFinder $definitionFinder, CallCenter $callCenter)
+    {
+        $this->definitionFinder = $definitionFinder;
+        $this->callCenter = $callCenter;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setUp(Environment $env, FeatureNode $feature, StepNode $step, $skip)
+    {
+        return new SuccessfulSetup();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function test(Environment $env, FeatureNode $feature, StepNode $step, $skip = false)
+    {
+        try {
+            $search = $this->searchDefinition($env, $feature, $step);
+            $result = $this->testDefinition($env, $feature, $step, $search, $skip);
+        } catch (SearchException $exception) {
+            $result = new FailedStepSearchResult($exception);
+        }
+
+        return $result;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function tearDown(Environment $env, FeatureNode $feature, StepNode $step, $skip, StepResult $result)
+    {
+        return new SuccessfulTeardown();
+    }
+
+    /**
+     * Searches for a definition.
+     *
+     * @param Environment $env
+     * @param FeatureNode $feature
+     * @param StepNode    $step
+     *
+     * @return SearchResult
+     */
+    private function searchDefinition(Environment $env, FeatureNode $feature, StepNode $step)
+    {
+        return $this->definitionFinder->findDefinition($env, $feature, $step);
+    }
+
+    /**
+     * Tests found definition.
+     *
+     * @param Environment  $env
+     * @param FeatureNode  $feature
+     * @param StepNode     $step
+     * @param SearchResult $search
+     * @param Boolean      $skip
+     *
+     * @return StepResult
+     */
+    private function testDefinition(Environment $env, FeatureNode $feature, StepNode $step, SearchResult $search, $skip)
+    {
+        if (!$search->hasMatch()) {
+            return new UndefinedStepResult();
+        }
+
+        if ($skip) {
+            return new SkippedStepResult($search);
+        }
+
+        $call = $this->createDefinitionCall($env, $feature, $search, $step);
+        $result = $this->callCenter->makeCall($call);
+
+        return new ExecutedStepResult($search, $result);
+    }
+
+    /**
+     * Creates definition call.
+     *
+     * @param Environment  $env
+     * @param FeatureNode  $feature
+     * @param SearchResult $search
+     * @param StepNode     $step
+     *
+     * @return DefinitionCall
+     */
+    private function createDefinitionCall(Environment $env, FeatureNode $feature, SearchResult $search, StepNode $step)
+    {
+        $definition = $search->getMatchedDefinition();
+        $arguments = $search->getMatchedArguments();
+
+        return new DefinitionCall($env, $feature, $step, $definition, $arguments);
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Tester/ScenarioTester.php b/vendor/behat/behat/src/Behat/Behat/Tester/ScenarioTester.php
new file mode 100644 (file)
index 0000000..2fd2494
--- /dev/null
@@ -0,0 +1,63 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Tester;
+
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\ScenarioInterface as Scenario;
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\Tester\Result\TestResult;
+use Behat\Testwork\Tester\Setup\Setup;
+use Behat\Testwork\Tester\Setup\Teardown;
+
+/**
+ * Prepares and tests provided scenario object against provided environment.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface ScenarioTester
+{
+    /**
+     * Sets up example for a test.
+     *
+     * @param Environment $env
+     * @param FeatureNode $feature
+     * @param Scenario    $scenario
+     * @param Boolean     $skip
+     *
+     * @return Setup
+     */
+    public function setUp(Environment $env, FeatureNode $feature, Scenario $scenario, $skip);
+
+    /**
+     * Tests example.
+     *
+     * @param Environment $env
+     * @param FeatureNode $feature
+     * @param Scenario    $scenario
+     * @param Boolean     $skip
+     *
+     * @return TestResult
+     */
+    public function test(Environment $env, FeatureNode $feature, Scenario $scenario, $skip);
+
+    /**
+     * Tears down example after a test.
+     *
+     * @param Environment $env
+     * @param FeatureNode $feature
+     * @param Scenario    $scenario
+     * @param Boolean     $skip
+     * @param TestResult  $result
+     *
+     * @return Teardown
+     */
+    public function tearDown(Environment $env, FeatureNode $feature, Scenario $scenario, $skip, TestResult $result);
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Tester/ServiceContainer/TesterExtension.php b/vendor/behat/behat/src/Behat/Behat/Tester/ServiceContainer/TesterExtension.php
new file mode 100644 (file)
index 0000000..394ee93
--- /dev/null
@@ -0,0 +1,315 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Tester\ServiceContainer;
+
+use Behat\Behat\Definition\ServiceContainer\DefinitionExtension;
+use Behat\Testwork\Call\ServiceContainer\CallExtension;
+use Behat\Testwork\Cli\ServiceContainer\CliExtension;
+use Behat\Testwork\Environment\ServiceContainer\EnvironmentExtension;
+use Behat\Testwork\EventDispatcher\ServiceContainer\EventDispatcherExtension;
+use Behat\Testwork\Exception\ServiceContainer\ExceptionExtension;
+use Behat\Testwork\ServiceContainer\ServiceProcessor;
+use Behat\Testwork\Tester\ServiceContainer\TesterExtension as BaseExtension;
+use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Definition;
+use Symfony\Component\DependencyInjection\Reference;
+
+/**
+ * Provides gherkin testers.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class TesterExtension extends BaseExtension
+{
+    /*
+     * Available services
+     */
+    const SCENARIO_TESTER_ID = 'tester.scenario';
+    const OUTLINE_TESTER_ID = 'tester.outline';
+    const EXAMPLE_TESTER_ID = 'tester.example';
+    const BACKGROUND_TESTER_ID = 'tester.background';
+    const STEP_TESTER_ID = 'tester.step';
+
+    /**
+     * Available extension points
+     */
+    const SCENARIO_TESTER_WRAPPER_TAG = 'tester.scenario.wrapper';
+    const OUTLINE_TESTER_WRAPPER_TAG = 'tester.outline.wrapper';
+    const EXAMPLE_TESTER_WRAPPER_TAG = 'tester.example.wrapper';
+    const BACKGROUND_TESTER_WRAPPER_TAG = 'tester.background.wrapper';
+    const STEP_TESTER_WRAPPER_TAG = 'tester.step.wrapper';
+
+    /**
+     * @var ServiceProcessor
+     */
+    private $processor;
+
+    /**
+     * Initializes extension.
+     *
+     * @param null|ServiceProcessor $processor
+     */
+    public function __construct(ServiceProcessor $processor = null)
+    {
+        $this->processor = $processor ? : new ServiceProcessor();
+
+        parent::__construct($this->processor);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function configure(ArrayNodeDefinition $builder)
+    {
+        parent::configure($builder);
+
+        $builder
+            ->children()
+                ->scalarNode('rerun_cache')
+                    ->info('Sets the rerun cache path')
+                    ->defaultValue(
+                        is_writable(sys_get_temp_dir())
+                            ? sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'behat_rerun_cache'
+                            : null
+                    )
+                ->end()
+            ->end()
+        ;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function load(ContainerBuilder $container, array $config)
+    {
+        parent::load($container, $config);
+
+        $this->loadRerunController($container, $config['rerun_cache']);
+        $this->loadPendingExceptionStringer($container);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function process(ContainerBuilder $container)
+    {
+        parent::process($container);
+
+        $this->processScenarioTesterWrappers($container);
+        $this->processOutlineTesterWrappers($container);
+        $this->processExampleTesterWrappers($container);
+        $this->processBackgroundTesterWrappers($container);
+        $this->processStepTesterWrappers($container);
+    }
+
+    /**
+     * Loads specification tester.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function loadSpecificationTester(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Behat\Tester\Runtime\RuntimeFeatureTester', array(
+            new Reference(self::SCENARIO_TESTER_ID),
+            new Reference(self::OUTLINE_TESTER_ID),
+            new Reference(EnvironmentExtension::MANAGER_ID)
+        ));
+        $container->setDefinition(self::SPECIFICATION_TESTER_ID, $definition);
+
+        $this->loadScenarioTester($container);
+        $this->loadOutlineTester($container);
+        $this->loadBackgroundTester($container);
+        $this->loadStepTester($container);
+    }
+
+    /**
+     * Loads scenario tester.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function loadScenarioTester(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Behat\Tester\StepContainerTester', array(
+            new Reference(self::STEP_TESTER_ID)
+        ));
+        $container->setDefinition('tester.step_container', $definition);
+
+        $definition = new Definition('Behat\Behat\Tester\Runtime\RuntimeScenarioTester', array(
+            new Reference('tester.step_container'),
+            new Reference(self::BACKGROUND_TESTER_ID)
+        ));
+        $container->setDefinition(self::SCENARIO_TESTER_ID, $definition);
+
+        // Proper isolation for scenarios
+        $definition = new Definition('Behat\Behat\Tester\Runtime\IsolatingScenarioTester', array(
+                new Reference(self::SCENARIO_TESTER_ID),
+                new Reference(EnvironmentExtension::MANAGER_ID)
+            )
+        );
+        $definition->addTag(self::SCENARIO_TESTER_WRAPPER_TAG, array('priority' => -999999));
+        $container->setDefinition(self::SCENARIO_TESTER_WRAPPER_TAG . '.isolating', $definition);
+    }
+
+    /**
+     * Loads outline tester.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function loadOutlineTester(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Behat\Tester\Runtime\RuntimeOutlineTester', array(
+            new Reference(self::EXAMPLE_TESTER_ID)
+        ));
+        $container->setDefinition(self::OUTLINE_TESTER_ID, $definition);
+
+        $this->loadExampleTester($container);
+    }
+
+    /**
+     * Loads example tester.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function loadExampleTester(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Behat\Tester\StepContainerTester', array(
+            new Reference(self::STEP_TESTER_ID)
+        ));
+        $container->setDefinition('tester.step_container', $definition);
+
+        $definition = new Definition('Behat\Behat\Tester\Runtime\RuntimeScenarioTester', array(
+            new Reference('tester.step_container'),
+            new Reference(self::BACKGROUND_TESTER_ID)
+        ));
+        $container->setDefinition(self::EXAMPLE_TESTER_ID, $definition);
+
+        // Proper isolation for examples
+        $definition = new Definition('Behat\Behat\Tester\Runtime\IsolatingScenarioTester', array(
+                new Reference(self::EXAMPLE_TESTER_ID),
+                new Reference(EnvironmentExtension::MANAGER_ID)
+            )
+        );
+        $definition->addTag(self::EXAMPLE_TESTER_WRAPPER_TAG, array('priority' => -999999));
+        $container->setDefinition(self::EXAMPLE_TESTER_WRAPPER_TAG . '.isolating', $definition);
+    }
+
+    /**
+     * Loads background tester.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function loadBackgroundTester(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Behat\Tester\StepContainerTester', array(
+            new Reference(self::STEP_TESTER_ID)
+        ));
+        $container->setDefinition('tester.step_container', $definition);
+
+        $definition = new Definition('Behat\Behat\Tester\Runtime\RuntimeBackgroundTester', array(
+            new Reference('tester.step_container')
+        ));
+        $container->setDefinition(self::BACKGROUND_TESTER_ID, $definition);
+    }
+
+    /**
+     * Loads step tester.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function loadStepTester(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Behat\Tester\Runtime\RuntimeStepTester', array(
+            new Reference(DefinitionExtension::FINDER_ID),
+            new Reference(CallExtension::CALL_CENTER_ID)
+        ));
+        $container->setDefinition(self::STEP_TESTER_ID, $definition);
+    }
+
+    /**
+     * Loads rerun controller.
+     *
+     * @param ContainerBuilder $container
+     * @param null|string      $cachePath
+     */
+    protected function loadRerunController(ContainerBuilder $container, $cachePath)
+    {
+        $definition = new Definition('Behat\Behat\Tester\Cli\RerunController', array(
+            new Reference(EventDispatcherExtension::DISPATCHER_ID),
+            $cachePath,
+            $container->getParameter('paths.base')
+        ));
+        $definition->addTag(CliExtension::CONTROLLER_TAG, array('priority' => 200));
+        $container->setDefinition(CliExtension::CONTROLLER_TAG . '.rerun', $definition);
+    }
+
+    /**
+     * Loads pending exception stringer.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function loadPendingExceptionStringer(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Behat\Tester\Exception\Stringer\PendingExceptionStringer');
+        $definition->addTag(ExceptionExtension::STRINGER_TAG);
+        $container->setDefinition(ExceptionExtension::STRINGER_TAG . '.pending', $definition);
+    }
+
+    /**
+     * Processes all registered scenario tester wrappers.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function processScenarioTesterWrappers(ContainerBuilder $container)
+    {
+        $this->processor->processWrapperServices($container, self::SCENARIO_TESTER_ID, self::SCENARIO_TESTER_WRAPPER_TAG);
+    }
+
+    /**
+     * Processes all registered outline tester wrappers.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function processOutlineTesterWrappers(ContainerBuilder $container)
+    {
+        $this->processor->processWrapperServices($container, self::OUTLINE_TESTER_ID, self::OUTLINE_TESTER_WRAPPER_TAG);
+    }
+
+    /**
+     * Processes all registered example tester wrappers.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function processExampleTesterWrappers(ContainerBuilder $container)
+    {
+        $this->processor->processWrapperServices($container, self::EXAMPLE_TESTER_ID, self::EXAMPLE_TESTER_WRAPPER_TAG);
+    }
+
+    /**
+     * Processes all registered background tester wrappers.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function processBackgroundTesterWrappers(ContainerBuilder $container)
+    {
+        $this->processor->processWrapperServices($container, self::BACKGROUND_TESTER_ID, self::BACKGROUND_TESTER_WRAPPER_TAG);
+    }
+
+    /**
+     * Processes all registered step tester wrappers.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function processStepTesterWrappers(ContainerBuilder $container)
+    {
+        $this->processor->processWrapperServices($container, self::STEP_TESTER_ID, self::STEP_TESTER_WRAPPER_TAG);
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Tester/StepContainerTester.php b/vendor/behat/behat/src/Behat/Behat/Tester/StepContainerTester.php
new file mode 100644 (file)
index 0000000..543e133
--- /dev/null
@@ -0,0 +1,71 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Tester;
+
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\StepContainerInterface;
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\Tester\Result\IntegerTestResult;
+use Behat\Testwork\Tester\Result\TestResult;
+use Behat\Testwork\Tester\Result\TestWithSetupResult;
+
+/**
+ * Tests provided collection of steps against provided environment.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class StepContainerTester
+{
+    /**
+     * @var StepTester
+     */
+    private $stepTester;
+
+    /**
+     * Initializes tester.
+     *
+     * @param StepTester $stepTester
+     */
+    public function __construct(StepTester $stepTester)
+    {
+        $this->stepTester = $stepTester;
+    }
+
+    /**
+     * Tests container.
+     *
+     * @param Environment            $env
+     * @param FeatureNode            $feature
+     * @param StepContainerInterface $container
+     * @param Boolean                $skip
+     *
+     * @return TestResult[]
+     */
+    public function test(Environment $env, FeatureNode $feature, StepContainerInterface $container, $skip)
+    {
+        $results = array();
+        foreach ($container->getSteps() as $step) {
+            $setup = $this->stepTester->setUp($env, $feature, $step, $skip);
+            $skipSetup = !$setup->isSuccessful() || $skip;
+
+            $testResult = $this->stepTester->test($env, $feature, $step, $skipSetup);
+            $skip = !$testResult->isPassed() || $skip;
+
+            $teardown = $this->stepTester->tearDown($env, $feature, $step, $skipSetup, $testResult);
+            $skip = $skip || $skipSetup || !$teardown->isSuccessful();
+
+            $integerResult = new IntegerTestResult($testResult->getResultCode());
+            $results[] = new TestWithSetupResult($setup, $integerResult, $teardown);
+        }
+
+        return $results;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Tester/StepTester.php b/vendor/behat/behat/src/Behat/Behat/Tester/StepTester.php
new file mode 100644 (file)
index 0000000..d5c995c
--- /dev/null
@@ -0,0 +1,63 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Tester;
+
+use Behat\Behat\Tester\Result\StepResult;
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\StepNode;
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\Tester\Setup\Setup;
+use Behat\Testwork\Tester\Setup\Teardown;
+
+/**
+ * Prepares and tests provided step object against provided environment.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface StepTester
+{
+    /**
+     * Sets up step for a test.
+     *
+     * @param Environment $env
+     * @param FeatureNode $feature
+     * @param StepNode    $step
+     * @param Boolean     $skip
+     *
+     * @return Setup
+     */
+    public function setUp(Environment $env, FeatureNode $feature, StepNode $step, $skip);
+
+    /**
+     * Tests step.
+     *
+     * @param Environment $env
+     * @param FeatureNode $feature
+     * @param StepNode    $step
+     * @param Boolean     $skip
+     *
+     * @return StepResult
+     */
+    public function test(Environment $env, FeatureNode $feature, StepNode $step, $skip);
+
+    /**
+     * Tears down step after a test.
+     *
+     * @param Environment $env
+     * @param FeatureNode $feature
+     * @param StepNode    $step
+     * @param Boolean     $skip
+     * @param StepResult  $result
+     *
+     * @return Teardown
+     */
+    public function tearDown(Environment $env, FeatureNode $feature, StepNode $step, $skip, StepResult $result);
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Transformation/Call/Filter/DefinitionArgumentsTransformer.php b/vendor/behat/behat/src/Behat/Behat/Transformation/Call/Filter/DefinitionArgumentsTransformer.php
new file mode 100644 (file)
index 0000000..d6cde91
--- /dev/null
@@ -0,0 +1,108 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Transformation\Call\Filter;
+
+use Behat\Behat\Definition\Call\DefinitionCall;
+use Behat\Behat\Transformation\Exception\UnsupportedCallException;
+use Behat\Behat\Transformation\Transformer\ArgumentTransformer;
+use Behat\Testwork\Call\Call;
+use Behat\Testwork\Call\Filter\CallFilter;
+
+/**
+ * Handles definition calls by intercepting them and transforming their arguments using transformations.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class DefinitionArgumentsTransformer implements CallFilter
+{
+    /**
+     * @var ArgumentTransformer[]
+     */
+    private $argumentTransformers = array();
+
+    /**
+     * Registers new argument transformer.
+     *
+     * @param ArgumentTransformer $transformer
+     */
+    public function registerArgumentTransformer(ArgumentTransformer $transformer)
+    {
+        $this->argumentTransformers[] = $transformer;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function supportsCall(Call $call)
+    {
+        return $call instanceof DefinitionCall;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function filterCall(Call $definitionCall)
+    {
+        if (!$definitionCall instanceof DefinitionCall) {
+            throw new UnsupportedCallException(sprintf(
+                'DefinitionArgumentTransformer can not filter `%s` call.',
+                get_class($definitionCall)
+            ), $definitionCall);
+        }
+
+        $newArguments = array();
+        $transformed = false;
+        foreach ($definitionCall->getArguments() as $index => $value) {
+            $newValue = $this->transformArgument($definitionCall, $index, $value);
+
+            if ($newValue !== $value) {
+                $transformed = true;
+            }
+
+            $newArguments[$index] = $newValue;
+        }
+
+        if (!$transformed) {
+            return $definitionCall;
+        }
+
+        return new DefinitionCall(
+            $definitionCall->getEnvironment(),
+            $definitionCall->getFeature(),
+            $definitionCall->getStep(),
+            $definitionCall->getCallee(),
+            $newArguments,
+            $definitionCall->getErrorReportingLevel()
+        );
+    }
+
+    /**
+     * Transforms call argument using registered transformers.
+     *
+     * @param DefinitionCall $definitionCall
+     * @param integer|string $index
+     * @param mixed          $value
+     *
+     * @return mixed
+     */
+    private function transformArgument(DefinitionCall $definitionCall, $index, $value)
+    {
+        foreach ($this->argumentTransformers as $transformer) {
+            if (!$transformer->supportsDefinitionAndArgument($definitionCall, $index, $value)) {
+                continue;
+            }
+
+            return $transformer->transformArgument($definitionCall, $index, $value);
+        }
+
+        return $value;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Transformation/Call/RuntimeTransformation.php b/vendor/behat/behat/src/Behat/Behat/Transformation/Call/RuntimeTransformation.php
new file mode 100644 (file)
index 0000000..5a51955
--- /dev/null
@@ -0,0 +1,59 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Transformation\Call;
+
+use Behat\Behat\Transformation\Transformation;
+use Behat\Testwork\Call\RuntimeCallee;
+
+/**
+ * Transformation that is created and executed in the runtime.
+ *
+ * @deprecated Will be removed in 4.0. Use specific transformations instead
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class RuntimeTransformation extends RuntimeCallee implements Transformation
+{
+    /**
+     * @var string
+     */
+    private $pattern;
+
+    /**
+     * Initializes transformation.
+     *
+     * @param string      $pattern
+     * @param callable    $callable
+     * @param null|string $description
+     */
+    public function __construct($pattern, $callable, $description = null)
+    {
+        $this->pattern = $pattern;
+
+        parent::__construct($callable, $description);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getPattern()
+    {
+        return $this->pattern;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function __toString()
+    {
+        return 'Transform ' . $this->getPattern();
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Transformation/Call/TransformationCall.php b/vendor/behat/behat/src/Behat/Behat/Transformation/Call/TransformationCall.php
new file mode 100644 (file)
index 0000000..8b57d0b
--- /dev/null
@@ -0,0 +1,58 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Transformation\Call;
+
+use Behat\Behat\Definition\Definition;
+use Behat\Behat\Transformation\Transformation;
+use Behat\Testwork\Environment\Call\EnvironmentCall;
+use Behat\Testwork\Environment\Environment;
+
+/**
+ * Call extended with transformation information.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class TransformationCall extends EnvironmentCall
+{
+    /**
+     * @var Definition
+     */
+    private $definition;
+
+    /**
+     * Initializes call.
+     *
+     * @param Environment    $environment
+     * @param Definition     $definition
+     * @param Transformation $transformation
+     * @param array          $arguments
+     */
+    public function __construct(
+        Environment $environment,
+        Definition $definition,
+        Transformation $transformation,
+        array $arguments
+    ) {
+        parent::__construct($environment, $transformation, $arguments);
+
+        $this->definition = $definition;
+    }
+
+    /**
+     * Returns transformed definition.
+     *
+     * @return Definition
+     */
+    public function getDefinition()
+    {
+        return $this->definition;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Transformation/Context/Annotation/TransformationAnnotationReader.php b/vendor/behat/behat/src/Behat/Behat/Transformation/Context/Annotation/TransformationAnnotationReader.php
new file mode 100644 (file)
index 0000000..a32ac5c
--- /dev/null
@@ -0,0 +1,81 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Transformation\Context\Annotation;
+
+use Behat\Behat\Context\Annotation\AnnotationReader;
+use Behat\Behat\Transformation\Transformation\PatternTransformation;
+use Behat\Behat\Transformation\Transformation;
+use ReflectionMethod;
+
+/**
+ * Step transformation annotation reader.
+ *
+ * Reads step transformations from a context method annotation.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class TransformationAnnotationReader implements AnnotationReader
+{
+    /**
+     * @var string
+     */
+    private static $regex = '/^\@transform\s*+(.*+)$/i';
+
+    /**
+     * Loads step callees (if exist) associated with specific method.
+     *
+     * @param string           $contextClass
+     * @param ReflectionMethod $method
+     * @param string           $docLine
+     * @param string           $description
+     *
+     * @return null|Transformation
+     */
+    public function readCallee($contextClass, ReflectionMethod $method, $docLine, $description)
+    {
+        if (!preg_match(self::$regex, $docLine, $match)) {
+            return null;
+        }
+
+        $pattern = $match[1];
+        $callable = array($contextClass, $method->getName());
+
+        foreach ($this->simpleTransformations() as $transformation) {
+            if ($transformation::supportsPatternAndMethod($pattern, $method)) {
+                return new $transformation($pattern, $callable, $description);
+            }
+        }
+
+        return new PatternTransformation($pattern, $callable, $description);
+    }
+
+    /**
+     * Returns list of default transformations.
+     *
+     * @return array
+     */
+    private function simpleTransformations()
+    {
+        $transformations = array();
+        $transformations[] = 'Behat\Behat\Transformation\Transformation\RowBasedTableTransformation';
+        $transformations[] = 'Behat\Behat\Transformation\Transformation\ColumnBasedTableTransformation';
+        $transformations[] = 'Behat\Behat\Transformation\Transformation\TableRowTransformation';
+
+        if (PHP_VERSION_ID >= 70000) {
+            $transformations[] = 'Behat\Behat\Transformation\Transformation\TokenNameAndReturnTypeTransformation';
+            $transformations[] = 'Behat\Behat\Transformation\Transformation\ReturnTypeTransformation';
+        }
+
+        $transformations[] = 'Behat\Behat\Transformation\Transformation\TokenNameTransformation';
+
+        return $transformations;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Transformation/Exception/TransformationException.php b/vendor/behat/behat/src/Behat/Behat/Transformation/Exception/TransformationException.php
new file mode 100644 (file)
index 0000000..f5aef3e
--- /dev/null
@@ -0,0 +1,22 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Transformation\Exception;
+
+use Behat\Testwork\Exception\TestworkException;
+
+/**
+ * Represents an exception caused by a transformation.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface TransformationException extends TestworkException
+{
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Transformation/Exception/UnsupportedCallException.php b/vendor/behat/behat/src/Behat/Behat/Transformation/Exception/UnsupportedCallException.php
new file mode 100644 (file)
index 0000000..40d0ab2
--- /dev/null
@@ -0,0 +1,50 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Transformation\Exception;
+
+use Behat\Testwork\Call\Call;
+use InvalidArgumentException;
+
+/**
+ * Represents an exception caused by an attempt to filter an unsupported call.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class UnsupportedCallException extends InvalidArgumentException implements TransformationException
+{
+    /**
+     * @var Call
+     */
+    private $call;
+
+    /**
+     * Initializes exception.
+     *
+     * @param string $message
+     * @param Call   $call
+     */
+    public function __construct($message, Call $call)
+    {
+        parent::__construct($message);
+
+        $this->call = $call;
+    }
+
+    /**
+     * Returns a call that caused exception.
+     *
+     * @return Call
+     */
+    public function getCall()
+    {
+        return $this->call;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Transformation/RegexGenerator.php b/vendor/behat/behat/src/Behat/Behat/Transformation/RegexGenerator.php
new file mode 100644 (file)
index 0000000..4a7000e
--- /dev/null
@@ -0,0 +1,30 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Transformation;
+
+/**
+ * Regular expression generator.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface RegexGenerator
+{
+    /**
+     * Generates regular expression using provided parameters.
+     *
+     * @param string $suiteName
+     * @param string $pattern
+     * @param string $language
+     *
+     * @return string
+     */
+    public function generateRegex($suiteName, $pattern, $language);
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Transformation/ServiceContainer/TransformationExtension.php b/vendor/behat/behat/src/Behat/Behat/Transformation/ServiceContainer/TransformationExtension.php
new file mode 100644 (file)
index 0000000..f322ee9
--- /dev/null
@@ -0,0 +1,177 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Transformation\ServiceContainer;
+
+use Behat\Behat\Context\ServiceContainer\ContextExtension;
+use Behat\Behat\Definition\ServiceContainer\DefinitionExtension;
+use Behat\Testwork\Call\ServiceContainer\CallExtension;
+use Behat\Testwork\Environment\ServiceContainer\EnvironmentExtension;
+use Behat\Testwork\ServiceContainer\Extension;
+use Behat\Testwork\ServiceContainer\ExtensionManager;
+use Behat\Testwork\ServiceContainer\ServiceProcessor;
+use Behat\Testwork\Translator\ServiceContainer\TranslatorExtension;
+use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Definition;
+use Symfony\Component\DependencyInjection\Reference;
+
+/**
+ * Provides definition arguments transformation functionality.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class TransformationExtension implements Extension
+{
+    /*
+     * Available services
+     */
+    const REPOSITORY_ID = 'transformation.repository';
+
+    /*
+     * Available extension points
+     */
+    const ARGUMENT_TRANSFORMER_TAG = 'transformation.argument_transformer';
+
+    /**
+     * @var ServiceProcessor
+     */
+    private $processor;
+
+    /**
+     * Initializes extension.
+     *
+     * @param null|ServiceProcessor $processor
+     */
+    public function __construct(ServiceProcessor $processor = null)
+    {
+        $this->processor = $processor ?: new ServiceProcessor();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getConfigKey()
+    {
+        return 'transformations';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function initialize(ExtensionManager $extensionManager)
+    {
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function configure(ArrayNodeDefinition $builder)
+    {
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function load(ContainerBuilder $container, array $config)
+    {
+        $this->loadDefinitionArgumentsTransformer($container);
+        $this->loadDefaultTransformers($container);
+        $this->loadAnnotationReader($container);
+        $this->loadRepository($container);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function process(ContainerBuilder $container)
+    {
+        $this->processArgumentsTransformers($container);
+    }
+
+    /**
+     * Loads definition arguments transformer.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function loadDefinitionArgumentsTransformer(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Behat\Transformation\Call\Filter\DefinitionArgumentsTransformer');
+        $definition->addTag(CallExtension::CALL_FILTER_TAG, array('priority' => 200));
+        $container->setDefinition($this->getDefinitionArgumentTransformerId(), $definition);
+    }
+
+    /**
+     * Loads default transformers.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function loadDefaultTransformers(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Behat\Transformation\Transformer\RepositoryArgumentTransformer', array(
+            new Reference(self::REPOSITORY_ID),
+            new Reference(CallExtension::CALL_CENTER_ID),
+            new Reference(DefinitionExtension::PATTERN_TRANSFORMER_ID),
+            new Reference(TranslatorExtension::TRANSLATOR_ID)
+        ));
+        $definition->addTag(self::ARGUMENT_TRANSFORMER_TAG, array('priority' => 50));
+        $container->setDefinition(self::ARGUMENT_TRANSFORMER_TAG . '.repository', $definition);
+    }
+
+    /**
+     * Loads transformation context annotation reader.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function loadAnnotationReader(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Behat\Transformation\Context\Annotation\TransformationAnnotationReader');
+        $definition->addTag(ContextExtension::ANNOTATION_READER_TAG, array('priority' => 50));
+        $container->setDefinition(ContextExtension::ANNOTATION_READER_TAG . '.transformation', $definition);
+    }
+
+    /**
+     * Loads transformations repository.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function loadRepository(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Behat\Transformation\TransformationRepository', array(
+            new Reference(EnvironmentExtension::MANAGER_ID)
+        ));
+        $container->setDefinition(self::REPOSITORY_ID, $definition);
+    }
+
+    /**
+     * Processes all available argument transformers.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function processArgumentsTransformers(ContainerBuilder $container)
+    {
+        $references = $this->processor->findAndSortTaggedServices($container, self::ARGUMENT_TRANSFORMER_TAG);
+        $definition = $container->getDefinition($this->getDefinitionArgumentTransformerId());
+
+        foreach ($references as $reference) {
+            $definition->addMethodCall('registerArgumentTransformer', array($reference));
+        }
+    }
+
+    /**
+     * Returns definition argument transformer service id.
+     *
+     * @return string
+     */
+    protected function getDefinitionArgumentTransformerId()
+    {
+        return CallExtension::CALL_FILTER_TAG . '.definition_argument_transformer';
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Transformation/SimpleArgumentTransformation.php b/vendor/behat/behat/src/Behat/Behat/Transformation/SimpleArgumentTransformation.php
new file mode 100644 (file)
index 0000000..77cdeef
--- /dev/null
@@ -0,0 +1,63 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Transformation;
+
+use Behat\Behat\Definition\Call\DefinitionCall;
+use Behat\Testwork\Call\CallCenter;
+use ReflectionMethod;
+
+/**
+ * Represents a simple self-contained transformation capable of changing a single argument.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface SimpleArgumentTransformation extends Transformation
+{
+    /**
+     * Checks if transformation supports given pattern.
+     *
+     * @param string           $pattern
+     * @param ReflectionMethod $method
+     *
+     * @return bool
+     */
+    static public function supportsPatternAndMethod($pattern, ReflectionMethod $method);
+
+    /**
+     * Returns transformation priority.
+     *
+     * @return integer
+     */
+    public function getPriority();
+
+    /**
+     * Checks if transformation supports argument.
+     *
+     * @param DefinitionCall $definitionCall
+     * @param integer|string $argumentIndex
+     * @param mixed          $argumentValue
+     *
+     * @return Boolean
+     */
+    public function supportsDefinitionAndArgument(DefinitionCall $definitionCall, $argumentIndex, $argumentValue);
+
+    /**
+     * Transforms argument value using transformation and returns a new one.
+     *
+     * @param CallCenter     $callCenter
+     * @param DefinitionCall $definitionCall
+     * @param integer|string $argumentIndex
+     * @param mixed          $argumentValue
+     *
+     * @return mixed
+     */
+    public function transformArgument(CallCenter $callCenter, DefinitionCall $definitionCall, $argumentIndex, $argumentValue);
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Transformation/Transformation.php b/vendor/behat/behat/src/Behat/Behat/Transformation/Transformation.php
new file mode 100644 (file)
index 0000000..e82190c
--- /dev/null
@@ -0,0 +1,37 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Transformation;
+
+use Behat\Testwork\Call\Callee;
+
+/**
+ * Step transformation interface.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface Transformation extends Callee
+{
+    /**
+     * Returns transformation pattern exactly as it was defined.
+     *
+     * @deprecated Will be removed in 4.0.
+     *
+     * @return string
+     */
+    public function getPattern();
+
+    /**
+     * Represents transformation as a string.
+     *
+     * @return string
+     */
+    public function __toString();
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Transformation/Transformation/ColumnBasedTableTransformation.php b/vendor/behat/behat/src/Behat/Behat/Transformation/Transformation/ColumnBasedTableTransformation.php
new file mode 100644 (file)
index 0000000..1c8cc0e
--- /dev/null
@@ -0,0 +1,114 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Transformation\Transformation;
+
+use Behat\Behat\Definition\Call\DefinitionCall;
+use Behat\Behat\Transformation\Call\TransformationCall;
+use Behat\Behat\Transformation\SimpleArgumentTransformation;
+use Behat\Gherkin\Node\TableNode;
+use Behat\Testwork\Call\CallCenter;
+use Behat\Testwork\Call\RuntimeCallee;
+use ReflectionMethod;
+
+/**
+ * Column-based table transformation.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class ColumnBasedTableTransformation extends RuntimeCallee implements SimpleArgumentTransformation
+{
+    const PATTERN_REGEX = '/^table\:(?:\*|[[:print:]]+)$/';
+
+    /**
+     * @var string
+     */
+    private $pattern;
+
+    /**
+     * {@inheritdoc}
+     */
+    static public function supportsPatternAndMethod($pattern, ReflectionMethod $method)
+    {
+        return 1 === preg_match(self::PATTERN_REGEX, $pattern);
+    }
+
+    /**
+     * Initializes transformation.
+     *
+     * @param string      $pattern
+     * @param callable    $callable
+     * @param null|string $description
+     */
+    public function __construct($pattern, $callable, $description = null)
+    {
+        $this->pattern = $pattern;
+
+        parent::__construct($callable, $description);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function supportsDefinitionAndArgument(DefinitionCall $definitionCall, $argumentIndex, $argumentValue)
+    {
+        if (!$argumentValue instanceof TableNode) {
+            return false;
+        };
+
+        return $this->pattern === 'table:' . implode(',', $argumentValue->getRow(0))
+            || $this->pattern === 'table:*';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function transformArgument(CallCenter $callCenter, DefinitionCall $definitionCall, $argumentIndex, $argumentValue)
+    {
+        $call = new TransformationCall(
+            $definitionCall->getEnvironment(),
+            $definitionCall->getCallee(),
+            $this,
+            array($argumentValue)
+        );
+
+        $result = $callCenter->makeCall($call);
+
+        if ($result->hasException()) {
+            throw $result->getException();
+        }
+
+        return $result->getReturn();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getPriority()
+    {
+        return 50;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getPattern()
+    {
+        return $this->pattern;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function __toString()
+    {
+        return 'ColumnTableTransform ' . $this->pattern;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Transformation/Transformation/PatternTransformation.php b/vendor/behat/behat/src/Behat/Behat/Transformation/Transformation/PatternTransformation.php
new file mode 100644 (file)
index 0000000..5054901
--- /dev/null
@@ -0,0 +1,148 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Transformation\Transformation;
+
+use Behat\Behat\Definition\Call\DefinitionCall;
+use Behat\Behat\Transformation\Call\TransformationCall;
+use Behat\Behat\Transformation\RegexGenerator;
+use Behat\Behat\Transformation\Transformation;
+use Behat\Testwork\Call\CallCenter;
+use Behat\Testwork\Call\RuntimeCallee;
+use Exception;
+
+/**
+ * Pattern-based transformation.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class PatternTransformation extends RuntimeCallee implements Transformation
+{
+    /**
+     * @var string
+     */
+    private $pattern;
+
+    /**
+     * Initializes transformation.
+     *
+     * @param string      $pattern
+     * @param callable    $callable
+     * @param null|string $description
+     */
+    public function __construct($pattern, $callable, $description = null)
+    {
+        $this->pattern = $pattern;
+
+        parent::__construct($callable, $description);
+    }
+
+    /**
+     * Checks if transformer supports argument.
+     *
+     * @param RegexGenerator $regexGenerator
+     * @param DefinitionCall $definitionCall
+     * @param mixed          $argumentValue
+     *
+     * @return bool
+     */
+    public function supportsDefinitionAndArgument(
+        RegexGenerator $regexGenerator,
+        DefinitionCall $definitionCall,
+        $argumentValue
+    ) {
+        $regex = $regexGenerator->generateRegex(
+            $definitionCall->getEnvironment()->getSuite()->getName(),
+            $this->pattern,
+            $definitionCall->getFeature()->getLanguage()
+        );
+
+        return $this->match($regex, $argumentValue, $match);
+    }
+
+    /**
+     * Transforms argument value using transformation and returns a new one.
+     *
+     * @param RegexGenerator $regexGenerator
+     * @param CallCenter     $callCenter
+     * @param DefinitionCall $definitionCall
+     * @param mixed          $argumentValue
+     *
+     * @return mixed
+     *
+     * @throws Exception If transformation throws exception
+     */
+    public function transformArgument(
+        RegexGenerator $regexGenerator,
+        CallCenter $callCenter,
+        DefinitionCall $definitionCall,
+        $argumentValue
+    ) {
+        $regex = $regexGenerator->generateRegex(
+            $definitionCall->getEnvironment()->getSuite()->getName(),
+            $this->pattern,
+            $definitionCall->getFeature()->getLanguage()
+        );
+
+        $this->match($regex, $argumentValue, $arguments);
+
+        $call = new TransformationCall(
+            $definitionCall->getEnvironment(),
+            $definitionCall->getCallee(),
+            $this,
+            $arguments
+        );
+
+        $result = $callCenter->makeCall($call);
+
+        if ($result->hasException()) {
+            throw $result->getException();
+        }
+
+        return $result->getReturn();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getPattern()
+    {
+        return $this->pattern;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function __toString()
+    {
+        return 'PatternTransform ' . $this->pattern;
+    }
+
+    /**
+     * @param $regexPattern
+     * @param $argumentValue
+     * @param $match
+     *
+     * @return bool
+     */
+    private function match($regexPattern, $argumentValue, &$match)
+    {
+        if (is_string($argumentValue) && preg_match($regexPattern, $argumentValue, $match)) {
+            // take arguments from capture groups if there are some
+            if (count($match) > 1) {
+                $match = array_slice($match, 1);
+            }
+
+            return true;
+        }
+
+        return false;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Transformation/Transformation/ReturnTypeTransformation.php b/vendor/behat/behat/src/Behat/Behat/Transformation/Transformation/ReturnTypeTransformation.php
new file mode 100644 (file)
index 0000000..ecdc613
--- /dev/null
@@ -0,0 +1,218 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Transformation\Transformation;
+
+use Behat\Behat\Definition\Call\DefinitionCall;
+use Behat\Behat\Transformation\Call\TransformationCall;
+use Behat\Behat\Transformation\SimpleArgumentTransformation;
+use Behat\Testwork\Call\CallCenter;
+use Behat\Testwork\Call\RuntimeCallee;
+use Closure;
+use ReflectionFunctionAbstract;
+use ReflectionMethod;
+use ReflectionParameter;
+
+/**
+ * By-type object transformation.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class ReturnTypeTransformation extends RuntimeCallee implements SimpleArgumentTransformation
+{
+
+    /**
+     * {@inheritdoc}
+     */
+    static public function supportsPatternAndMethod($pattern, ReflectionMethod $method)
+    {
+        $returnClass = self::getReturnClass($method);
+
+        if (null === $returnClass) {
+            return false;
+        }
+
+        return '' === $pattern;
+    }
+
+    /**
+     * Initializes transformation.
+     *
+     * @param string      $pattern
+     * @param callable    $callable
+     * @param null|string $description
+     */
+    public function __construct($pattern, $callable, $description = null)
+    {
+        parent::__construct($callable, $description);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function supportsDefinitionAndArgument(DefinitionCall $definitionCall, $argumentIndex, $argumentValue)
+    {
+        $returnClass = self::getReturnClass($this->getReflection());
+
+        if (null === $returnClass) {
+            return false;
+        }
+
+        $parameterClass = $this->getParameterClassNameByIndex($definitionCall, $argumentIndex);
+
+        return $parameterClass === $returnClass;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function transformArgument(CallCenter $callCenter, DefinitionCall $definitionCall, $argumentIndex, $argumentValue)
+    {
+        $call = new TransformationCall(
+            $definitionCall->getEnvironment(),
+            $definitionCall->getCallee(),
+            $this,
+            array($argumentValue)
+        );
+
+        $result = $callCenter->makeCall($call);
+
+        if ($result->hasException()) {
+            throw $result->getException();
+        }
+
+        return $result->getReturn();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getPriority()
+    {
+        return 80;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getPattern()
+    {
+        return null;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function __toString()
+    {
+        return 'ReturnTypeTransform';
+    }
+
+    /**
+     * Extracts parameters from provided definition call.
+     *
+     * @param ReflectionFunctionAbstract $reflection
+     *
+     * @return null|string
+     */
+    static private function getReturnClass(ReflectionFunctionAbstract $reflection)
+    {
+        $type = $reflection->getReturnType();
+
+        if (null === $type || $type->isBuiltin()) {
+            return null;
+        }
+
+        return (string) $type;
+    }
+
+    /**
+     * Attempts to get definition parameter using its index (parameter position or name).
+     *
+     * @param DefinitionCall $definitionCall
+     * @param string|integer $argumentIndex
+     *
+     * @return null|string
+     */
+    private function getParameterClassNameByIndex(DefinitionCall $definitionCall, $argumentIndex)
+    {
+        $parameters = array_filter(
+            array_filter($this->getCallParameters($definitionCall),
+                $this->hasIndex($argumentIndex)
+            ),
+            $this->isClass()
+        );
+        return count($parameters) ? current($parameters)->getClass()->getName() : null;
+    }
+
+    /**
+     * Extracts parameters from provided definition call.
+     *
+     * @param DefinitionCall $definitionCall
+     *
+     * @return ReflectionParameter[]
+     */
+    private function getCallParameters(DefinitionCall $definitionCall)
+    {
+        return $definitionCall->getCallee()->getReflection()->getParameters();
+    }
+
+    /**
+     * Returns appropriate closure for filtering parameter by index.
+     *
+     * @param string|integer $index
+     *
+     * @return Closure
+     */
+    private function hasIndex($index)
+    {
+        return is_string($index) ? $this->hasName($index) : $this->hasPosition($index);
+    }
+
+    /**
+     * Returns closure to filter parameter by name.
+     *
+     * @param string $index
+     *
+     * @return Closure
+     */
+    private function hasName($index)
+    {
+        return function (ReflectionParameter $parameter) use ($index) {
+            return $index === $parameter->getName();
+        };
+    }
+
+    /**
+     * Returns closure to filter parameter by position.
+     *
+     * @param integer $index
+     *
+     * @return Closure
+     */
+    private function hasPosition($index)
+    {
+        return function (ReflectionParameter $parameter) use ($index) {
+            return $index === $parameter->getPosition();
+        };
+    }
+
+    /**
+     * Returns closure to filter parameter by typehinted class.
+     *
+     * @return Closure
+     */
+    private function isClass()
+    {
+        return function (ReflectionParameter $parameter) {
+            return $parameter->getClass();
+        };
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Transformation/Transformation/RowBasedTableTransformation.php b/vendor/behat/behat/src/Behat/Behat/Transformation/Transformation/RowBasedTableTransformation.php
new file mode 100644 (file)
index 0000000..6138983
--- /dev/null
@@ -0,0 +1,130 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Transformation\Transformation;
+
+use Behat\Behat\Definition\Call\DefinitionCall;
+use Behat\Behat\Transformation\Call\TransformationCall;
+use Behat\Behat\Transformation\SimpleArgumentTransformation;
+use Behat\Gherkin\Exception\NodeException;
+use Behat\Gherkin\Node\TableNode;
+use Behat\Testwork\Call\CallCenter;
+use Behat\Testwork\Call\RuntimeCallee;
+use ReflectionMethod;
+
+/**
+ * Row-based table transformation.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class RowBasedTableTransformation extends RuntimeCallee implements SimpleArgumentTransformation
+{
+    const PATTERN_REGEX = '/^rowtable\:[[:print:]]+$/';
+
+    /**
+     * @var string
+     */
+    private $pattern;
+
+    /**
+     * {@inheritdoc}
+     */
+    static public function supportsPatternAndMethod($pattern, ReflectionMethod $method)
+    {
+        return 1 === preg_match(self::PATTERN_REGEX, $pattern);
+    }
+
+    /**
+     * Initializes transformation.
+     *
+     * @param string      $pattern
+     * @param callable    $callable
+     * @param null|string $description
+     */
+    public function __construct($pattern, $callable, $description = null)
+    {
+        $this->pattern = $pattern;
+
+        parent::__construct($callable, $description);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function supportsDefinitionAndArgument(DefinitionCall $definitionCall, $argumentIndex, $value)
+    {
+        if (!$value instanceof TableNode) {
+            return false;
+        };
+
+        // What we're doing here is checking that we have a 2 column table.
+        // This bit checks we have two columns
+        try {
+            $value->getColumn(1);
+        } catch (NodeException $e) {
+            return false;
+        }
+
+        // And here we check we don't have a 3rd column
+        try {
+            $value->getColumn(2);
+        } catch (NodeException $e) {
+            // Once we know the table could be a row table, we check against the pattern.
+            return $this->pattern === 'rowtable:' . implode(',', $value->getColumn(0));
+        }
+
+        return false;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function transformArgument(CallCenter $callCenter, DefinitionCall $definitionCall, $argumentIndex, $argumentValue)
+    {
+        $call = new TransformationCall(
+            $definitionCall->getEnvironment(),
+            $definitionCall->getCallee(),
+            $this,
+            array($argumentValue)
+        );
+
+        $result = $callCenter->makeCall($call);
+
+        if ($result->hasException()) {
+            throw $result->getException();
+        }
+
+        return $result->getReturn();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getPriority()
+    {
+        return 50;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getPattern()
+    {
+        return $this->pattern;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function __toString()
+    {
+        return 'RowTableTransform ' . $this->pattern;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Transformation/Transformation/TableRowTransformation.php b/vendor/behat/behat/src/Behat/Behat/Transformation/Transformation/TableRowTransformation.php
new file mode 100644 (file)
index 0000000..571f1f0
--- /dev/null
@@ -0,0 +1,118 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Transformation\Transformation;
+
+use Behat\Behat\Definition\Call\DefinitionCall;
+use Behat\Behat\Transformation\Call\TransformationCall;
+use Behat\Behat\Transformation\SimpleArgumentTransformation;
+use Behat\Gherkin\Node\TableNode;
+use Behat\Testwork\Call\CallCenter;
+use Behat\Testwork\Call\RuntimeCallee;
+use ReflectionMethod;
+
+/**
+ * Table row transformation.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class TableRowTransformation extends RuntimeCallee implements SimpleArgumentTransformation
+{
+    const PATTERN_REGEX = '/^row\:[[:print:]]+$/';
+
+    /**
+     * @var string
+     */
+    private $pattern;
+
+    /**
+     * {@inheritdoc}
+     */
+    static public function supportsPatternAndMethod($pattern, ReflectionMethod $method)
+    {
+        return 1 === preg_match(self::PATTERN_REGEX, $pattern);
+    }
+
+    /**
+     * Initializes transformation.
+     *
+     * @param string      $pattern
+     * @param callable    $callable
+     * @param null|string $description
+     */
+    public function __construct($pattern, $callable, $description = null)
+    {
+        $this->pattern = $pattern;
+
+        parent::__construct($callable, $description);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function supportsDefinitionAndArgument(DefinitionCall $definitionCall, $argumentIndex, $argumentValue)
+    {
+        if (!$argumentValue instanceof TableNode) {
+            return false;
+        };
+
+        return $this->pattern === 'row:' . implode(',', $argumentValue->getRow(0));
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function transformArgument(CallCenter $callCenter, DefinitionCall $definitionCall, $argumentIndex, $argumentValue)
+    {
+        $rows = array();
+        foreach ($argumentValue as $row) {
+            $call = new TransformationCall(
+                $definitionCall->getEnvironment(),
+                $definitionCall->getCallee(),
+                $this,
+                array($row)
+            );
+
+            $result = $callCenter->makeCall($call);
+
+            if ($result->hasException()) {
+                throw $result->getException();
+            }
+
+            $rows[] = $result->getReturn();
+        }
+
+        return $rows;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getPriority()
+    {
+        return 50;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getPattern()
+    {
+        return $this->pattern;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function __toString()
+    {
+        return 'TableRowTransform ' . $this->pattern;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Transformation/Transformation/TokenNameAndReturnTypeTransformation.php b/vendor/behat/behat/src/Behat/Behat/Transformation/Transformation/TokenNameAndReturnTypeTransformation.php
new file mode 100644 (file)
index 0000000..32f954d
--- /dev/null
@@ -0,0 +1,113 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Transformation\Transformation;
+
+use Behat\Behat\Definition\Call\DefinitionCall;
+use Behat\Behat\Transformation\Call\TransformationCall;
+use Behat\Behat\Transformation\SimpleArgumentTransformation;
+use Behat\Testwork\Call\CallCenter;
+use Behat\Testwork\Call\RuntimeCallee;
+use ReflectionMethod;
+
+/**
+ * Name and return type object transformation.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class TokenNameAndReturnTypeTransformation extends RuntimeCallee implements SimpleArgumentTransformation
+{
+    /**
+     * @var TokenNameTransformation
+     */
+    private $tokenTransformation;
+    /**
+     * @var ReturnTypeTransformation
+     */
+    private $returnTransformation;
+
+    /**
+     * {@inheritdoc}
+     */
+    static public function supportsPatternAndMethod($pattern, ReflectionMethod $method)
+    {
+        return TokenNameTransformation::supportsPatternAndMethod($pattern, $method)
+            && ReturnTypeTransformation::supportsPatternAndMethod('', $method);
+    }
+
+    /**
+     * Initializes transformation.
+     *
+     * @param string      $pattern
+     * @param callable    $callable
+     * @param null|string $description
+     */
+    public function __construct($pattern, $callable, $description = null)
+    {
+        $this->tokenTransformation = new TokenNameTransformation($pattern, $callable, $description);
+        $this->returnTransformation = new ReturnTypeTransformation('', $callable, $description);
+
+        parent::__construct($callable, $description);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function supportsDefinitionAndArgument(DefinitionCall $definitionCall, $argumentIndex, $argumentValue)
+    {
+        return $this->tokenTransformation->supportsDefinitionAndArgument($definitionCall, $argumentIndex, $argumentValue)
+            && $this->returnTransformation->supportsDefinitionAndArgument($definitionCall, $argumentIndex, $argumentValue);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function transformArgument(CallCenter $callCenter, DefinitionCall $definitionCall, $argumentIndex, $argumentValue)
+    {
+        $call = new TransformationCall(
+            $definitionCall->getEnvironment(),
+            $definitionCall->getCallee(),
+            $this,
+            array($argumentValue)
+        );
+
+        $result = $callCenter->makeCall($call);
+
+        if ($result->hasException()) {
+            throw $result->getException();
+        }
+
+        return $result->getReturn();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getPriority()
+    {
+        return 100;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getPattern()
+    {
+        return $this->tokenTransformation->getPattern();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function __toString()
+    {
+        return 'NamedReturnTypeTransform ' . $this->getPattern();
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Transformation/Transformation/TokenNameTransformation.php b/vendor/behat/behat/src/Behat/Behat/Transformation/Transformation/TokenNameTransformation.php
new file mode 100644 (file)
index 0000000..cd4f4ab
--- /dev/null
@@ -0,0 +1,109 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Transformation\Transformation;
+
+use Behat\Behat\Definition\Call\DefinitionCall;
+use Behat\Behat\Transformation\Call\TransformationCall;
+use Behat\Behat\Transformation\SimpleArgumentTransformation;
+use Behat\Testwork\Call\CallCenter;
+use Behat\Testwork\Call\RuntimeCallee;
+use ReflectionMethod;
+
+/**
+ * Token name based transformation.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class TokenNameTransformation extends RuntimeCallee implements SimpleArgumentTransformation
+{
+    const PATTERN_REGEX = '/^\:\w+$/';
+
+    /**
+     * @var string
+     */
+    private $pattern;
+
+
+    /**
+     * {@inheritdoc}
+     */
+    static public function supportsPatternAndMethod($pattern, ReflectionMethod $method)
+    {
+        return 1 === preg_match(self::PATTERN_REGEX, $pattern);
+    }
+
+    /**
+     * Initializes transformation.
+     *
+     * @param string      $pattern
+     * @param callable    $callable
+     * @param null|string $description
+     */
+    public function __construct($pattern, $callable, $description = null)
+    {
+        $this->pattern = $pattern;
+
+        parent::__construct($callable, $description);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function supportsDefinitionAndArgument(DefinitionCall $definitionCall, $argumentIndex, $argumentValue)
+    {
+        return ':' . $argumentIndex === $this->pattern;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function transformArgument(CallCenter $callCenter, DefinitionCall $definitionCall, $argumentIndex, $argumentValue)
+    {
+        $call = new TransformationCall(
+            $definitionCall->getEnvironment(),
+            $definitionCall->getCallee(),
+            $this,
+            array($argumentValue)
+        );
+
+        $result = $callCenter->makeCall($call);
+
+        if ($result->hasException()) {
+            throw $result->getException();
+        }
+
+        return $result->getReturn();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getPriority()
+    {
+        return 50;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getPattern()
+    {
+        return $this->pattern;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function __toString()
+    {
+        return 'TokenNameTransform ' . $this->pattern;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Transformation/TransformationRepository.php b/vendor/behat/behat/src/Behat/Behat/Transformation/TransformationRepository.php
new file mode 100644 (file)
index 0000000..2fb0ff5
--- /dev/null
@@ -0,0 +1,55 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Transformation;
+
+use Behat\Testwork\Call\Callee;
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\Environment\EnvironmentManager;
+
+/**
+ * Provides transformations using environment manager.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class TransformationRepository
+{
+    /**
+     * @var EnvironmentManager
+     */
+    private $environmentManager;
+
+    /**
+     * Initializes repository.
+     *
+     * @param EnvironmentManager $environmentManager
+     */
+    public function __construct(EnvironmentManager $environmentManager)
+    {
+        $this->environmentManager = $environmentManager;
+    }
+
+    /**
+     * Returns all available definitions for a specific environment.
+     *
+     * @param Environment $environment
+     *
+     * @return Transformation[]
+     */
+    public function getEnvironmentTransformations(Environment $environment)
+    {
+        return array_filter(
+            $this->environmentManager->readEnvironmentCallees($environment),
+            function (Callee $callee) {
+                return $callee instanceof Transformation;
+            }
+        );
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Transformation/Transformer/ArgumentTransformer.php b/vendor/behat/behat/src/Behat/Behat/Transformation/Transformer/ArgumentTransformer.php
new file mode 100644 (file)
index 0000000..4773960
--- /dev/null
@@ -0,0 +1,43 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Transformation\Transformer;
+
+use Behat\Behat\Definition\Call\DefinitionCall;
+
+/**
+ * Transforms a single argument value.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface ArgumentTransformer
+{
+    /**
+     * Checks if transformer supports argument.
+     *
+     * @param DefinitionCall $definitionCall
+     * @param integer|string $argumentIndex
+     * @param mixed          $argumentValue
+     *
+     * @return Boolean
+     */
+    public function supportsDefinitionAndArgument(DefinitionCall $definitionCall, $argumentIndex, $argumentValue);
+
+    /**
+     * Transforms argument value using transformation and returns a new one.
+     *
+     * @param DefinitionCall $definitionCall
+     * @param integer|string $argumentIndex
+     * @param mixed          $argumentValue
+     *
+     * @return mixed
+     */
+    public function transformArgument(DefinitionCall $definitionCall, $argumentIndex, $argumentValue);
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Transformation/Transformer/RepositoryArgumentTransformer.php b/vendor/behat/behat/src/Behat/Behat/Transformation/Transformer/RepositoryArgumentTransformer.php
new file mode 100644 (file)
index 0000000..795f42f
--- /dev/null
@@ -0,0 +1,198 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Transformation\Transformer;
+
+use Behat\Behat\Definition\Call\DefinitionCall;
+use Behat\Behat\Definition\Pattern\PatternTransformer;
+use Behat\Behat\Transformation\SimpleArgumentTransformation;
+use Behat\Behat\Transformation\Transformation\PatternTransformation;
+use Behat\Behat\Transformation\RegexGenerator;
+use Behat\Behat\Transformation\Transformation;
+use Behat\Behat\Transformation\TransformationRepository;
+use Behat\Gherkin\Node\ArgumentInterface;
+use Behat\Testwork\Call\CallCenter;
+use Symfony\Component\Translation\TranslatorInterface;
+
+/**
+ * Argument transformer based on transformations repository.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class RepositoryArgumentTransformer implements ArgumentTransformer, RegexGenerator
+{
+    /**
+     * @var TransformationRepository
+     */
+    private $repository;
+    /**
+     * @var CallCenter
+     */
+    private $callCenter;
+    /**
+     * @var PatternTransformer
+     */
+    private $patternTransformer;
+    /**
+     * @var TranslatorInterface
+     */
+    private $translator;
+
+    /**
+     * Initializes transformer.
+     *
+     * @param TransformationRepository $repository
+     * @param CallCenter               $callCenter
+     * @param PatternTransformer       $patternTransformer
+     * @param TranslatorInterface      $translator
+     */
+    public function __construct(
+        TransformationRepository $repository,
+        CallCenter $callCenter,
+        PatternTransformer $patternTransformer,
+        TranslatorInterface $translator
+    ) {
+        $this->repository = $repository;
+        $this->callCenter = $callCenter;
+        $this->patternTransformer = $patternTransformer;
+        $this->translator = $translator;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function supportsDefinitionAndArgument(DefinitionCall $definitionCall, $argumentIndex, $argumentValue)
+    {
+        return count($this->repository->getEnvironmentTransformations($definitionCall->getEnvironment())) > 0;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function transformArgument(DefinitionCall $definitionCall, $argumentIndex, $argumentValue)
+    {
+        $environment = $definitionCall->getEnvironment();
+        list($simpleTransformations, $normalTransformations) = $this->splitSimpleAndNormalTransformations(
+            $this->repository->getEnvironmentTransformations($environment)
+        );
+
+        $newValue = $this->applySimpleTransformations($simpleTransformations, $definitionCall, $argumentIndex, $argumentValue);
+        $newValue = $this->applyNormalTransformations($normalTransformations, $definitionCall, $argumentIndex, $newValue);
+
+        return $newValue;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function generateRegex($suiteName, $pattern, $language)
+    {
+        $translatedPattern = $this->translator->trans($pattern, array(), $suiteName, $language);
+        if ($pattern == $translatedPattern) {
+            return $this->patternTransformer->transformPatternToRegex($pattern);
+        }
+
+        return $this->patternTransformer->transformPatternToRegex($translatedPattern);
+    }
+
+    /**
+     * Apply simple argument transformations in priority order.
+     *
+     * @param SimpleArgumentTransformation[] $transformations
+     * @param DefinitionCall                 $definitionCall
+     * @param integer|string                 $index
+     * @param mixed                          $value
+     *
+     * @return mixed
+     */
+    private function applySimpleTransformations(array $transformations, DefinitionCall $definitionCall, $index, $value)
+    {
+        usort($transformations, function (SimpleArgumentTransformation $t1, SimpleArgumentTransformation $t2) {
+            if ($t1->getPriority() == $t2->getPriority()) {
+                return 0;
+            }
+
+            return ($t1->getPriority() > $t2->getPriority()) ? -1 : 1;
+        });
+
+        $newValue = $value;
+        foreach ($transformations as $transformation) {
+            $newValue = $this->transform($definitionCall, $transformation, $index, $newValue);
+        }
+
+        return $newValue;
+    }
+
+    /**
+     * Apply normal (non-simple) argument transformations.
+     *
+     * @param Transformation[] $transformations
+     * @param DefinitionCall   $definitionCall
+     * @param integer|string   $index
+     * @param mixed            $value
+     *
+     * @return mixed
+     */
+    private function applyNormalTransformations(array $transformations, DefinitionCall $definitionCall, $index, $value)
+    {
+        $newValue = $value;
+        foreach ($transformations as $transformation) {
+            $newValue = $this->transform($definitionCall, $transformation, $index, $newValue);
+        }
+
+        return $newValue;
+    }
+
+    /**
+     * Transforms argument value using registered transformers.
+     *
+     * @param Transformation $transformation
+     * @param DefinitionCall $definitionCall
+     * @param integer|string $index
+     * @param mixed          $value
+     *
+     * @return mixed
+     */
+    private function transform(DefinitionCall $definitionCall, Transformation $transformation, $index, $value)
+    {
+        if (is_object($value) && !$value instanceof ArgumentInterface) {
+            return $value;
+        }
+
+        if ($transformation instanceof SimpleArgumentTransformation &&
+            $transformation->supportsDefinitionAndArgument($definitionCall, $index, $value)) {
+            return $transformation->transformArgument($this->callCenter, $definitionCall, $index, $value);
+        }
+
+        if ($transformation instanceof PatternTransformation &&
+            $transformation->supportsDefinitionAndArgument($this, $definitionCall, $value)) {
+            return $transformation->transformArgument($this, $this->callCenter, $definitionCall, $value);
+        }
+
+        return $value;
+    }
+
+    /**
+     * Splits transformations into simple and normal ones.
+     *
+     * @param Transformation[] $transformations
+     *
+     * @return array
+     */
+    private function splitSimpleAndNormalTransformations(array $transformations)
+    {
+        return array_reduce($transformations, function ($acc, $t) {
+            return array(
+                $t instanceof SimpleArgumentTransformation ? array_merge($acc[0], array($t)) : $acc[0],
+                !$t instanceof SimpleArgumentTransformation ? array_merge($acc[1], array($t)) : $acc[1],
+            );
+        }, array(array(), array()));
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Translator/Cli/GherkinTranslationsController.php b/vendor/behat/behat/src/Behat/Behat/Translator/Cli/GherkinTranslationsController.php
new file mode 100644 (file)
index 0000000..439ad09
--- /dev/null
@@ -0,0 +1,59 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Translator\Cli;
+
+use Behat\Testwork\Cli\Controller;
+use Symfony\Component\Console\Command\Command as SymfonyCommand;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Translation\Translator;
+
+/**
+ * Configures translator service and loads default translations.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class GherkinTranslationsController implements Controller
+{
+    /**
+     * @var Translator
+     */
+    private $translator;
+
+    /**
+     * Initializes controller.
+     *
+     * @param Translator $translator
+     */
+    public function __construct(Translator $translator)
+    {
+        $this->translator = $translator;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function configure(SymfonyCommand $command)
+    {
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function execute(InputInterface $input, OutputInterface $output)
+    {
+        $i18nPath = dirname(dirname(dirname(dirname(dirname(__DIR__))))) . DIRECTORY_SEPARATOR . 'i18n.php';
+
+        foreach (require($i18nPath) as $lang => $messages) {
+            $this->translator->addResource('array', $messages, $lang, 'output');
+        }
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Behat/Translator/ServiceContainer/GherkinTranslationsExtension.php b/vendor/behat/behat/src/Behat/Behat/Translator/ServiceContainer/GherkinTranslationsExtension.php
new file mode 100644 (file)
index 0000000..f4af2a5
--- /dev/null
@@ -0,0 +1,79 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Translator\ServiceContainer;
+
+use Behat\Testwork\Cli\ServiceContainer\CliExtension;
+use Behat\Testwork\ServiceContainer\Extension;
+use Behat\Testwork\ServiceContainer\ExtensionManager;
+use Behat\Testwork\Translator\ServiceContainer\TranslatorExtension;
+use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Definition;
+use Symfony\Component\DependencyInjection\Reference;
+
+/**
+ * Extends translator service with knowledge about gherkin translations.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class GherkinTranslationsExtension implements Extension
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function getConfigKey()
+    {
+        return 'gherkin_translations';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function initialize(ExtensionManager $extensionManager)
+    {
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function configure(ArrayNodeDefinition $builder)
+    {
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function load(ContainerBuilder $container, array $config)
+    {
+        $this->loadController($container);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function process(ContainerBuilder $container)
+    {
+    }
+
+    /**
+     * Loads translator controller.
+     *
+     * @param ContainerBuilder $container
+     */
+    private function loadController(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Behat\Translator\Cli\GherkinTranslationsController', array(
+            new Reference(TranslatorExtension::TRANSLATOR_ID)
+        ));
+        $definition->addTag(CliExtension::CONTROLLER_TAG, array('priority' => 9999));
+        $container->setDefinition(CliExtension::CONTROLLER_TAG . '.gherkin_translations', $definition);
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/ApplicationFactory.php b/vendor/behat/behat/src/Behat/Testwork/ApplicationFactory.php
new file mode 100644 (file)
index 0000000..ff60404
--- /dev/null
@@ -0,0 +1,94 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork;
+
+use Behat\Testwork\Cli\Application;
+use Behat\Testwork\ServiceContainer\Configuration\ConfigurationLoader;
+use Behat\Testwork\ServiceContainer\Extension;
+use Behat\Testwork\ServiceContainer\ExtensionManager;
+
+/**
+ * Defines the way application is created.
+ *
+ * Extend and implement this class to create an entry point for your framework.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+abstract class ApplicationFactory
+{
+    /**
+     * Returns application name.
+     *
+     * @return string
+     */
+    abstract protected function getName();
+
+    /**
+     * Returns current application version.
+     *
+     * @return string
+     */
+    abstract protected function getVersion();
+
+    /**
+     * Returns list of extensions enabled by default.
+     *
+     * @return Extension[]
+     */
+    abstract protected function getDefaultExtensions();
+
+    /**
+     * Returns the name of configuration environment variable.
+     *
+     * @return string
+     */
+    abstract protected function getEnvironmentVariableName();
+
+    /**
+     * Returns user config path.
+     *
+     * @return null|string
+     */
+    abstract protected function getConfigPath();
+
+    /**
+     * Creates application instance.
+     *
+     * @return Application
+     */
+    public function createApplication()
+    {
+        $configurationLoader = $this->createConfigurationLoader();
+        $extensionManager = $this->createExtensionManager();
+
+        return new Application($this->getName(), $this->getVersion(), $configurationLoader, $extensionManager);
+    }
+
+    /**
+     * Creates configuration loader.
+     *
+     * @return ConfigurationLoader
+     */
+    protected function createConfigurationLoader()
+    {
+        return new ConfigurationLoader($this->getEnvironmentVariableName(), $this->getConfigPath());
+    }
+
+    /**
+     * Creates extension manager.
+     *
+     * @return ExtensionManager
+     */
+    protected function createExtensionManager()
+    {
+        return new ExtensionManager($this->getDefaultExtensions());
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Argument/ArgumentOrganiser.php b/vendor/behat/behat/src/Behat/Testwork/Argument/ArgumentOrganiser.php
new file mode 100644 (file)
index 0000000..8659631
--- /dev/null
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Argument;
+
+use ReflectionFunctionAbstract;
+
+/**
+ * Organises function arguments using its reflection.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface ArgumentOrganiser
+{
+    /**
+     * Organises arguments using function reflection.
+     *
+     * @param ReflectionFunctionAbstract $function
+     * @param mixed[]                    $arguments
+     *
+     * @return mixed[]
+     */
+    public function organiseArguments(ReflectionFunctionAbstract $function, array $arguments);
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Argument/ConstructorArgumentOrganiser.php b/vendor/behat/behat/src/Behat/Testwork/Argument/ConstructorArgumentOrganiser.php
new file mode 100644 (file)
index 0000000..5ab6127
--- /dev/null
@@ -0,0 +1,90 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Argument;
+
+use Behat\Testwork\Argument\Exception\UnknownParameterValueException;
+use Behat\Testwork\Argument\Exception\UnsupportedFunctionException;
+use ReflectionFunctionAbstract;
+use ReflectionMethod;
+
+/**
+ * Organises constructor arguments.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class ConstructorArgumentOrganiser implements ArgumentOrganiser
+{
+    /**
+     * @var ArgumentOrganiser
+     */
+    private $baseOrganiser;
+
+    /**
+     * Initializes organiser.
+     *
+     * @param ArgumentOrganiser $organiser
+     */
+    public function __construct(ArgumentOrganiser $organiser)
+    {
+        $this->baseOrganiser = $organiser;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function organiseArguments(ReflectionFunctionAbstract $constructor, array $arguments)
+    {
+        if (!$constructor instanceof ReflectionMethod) {
+            throw new UnsupportedFunctionException(sprintf(
+                'ConstructorArgumentOrganiser can only work with ReflectionMethod, but `%s` given.',
+                get_class($constructor)
+            ));
+        }
+
+        $organisedArguments = $this->baseOrganiser->organiseArguments(
+            $constructor,
+            $arguments
+        );
+
+        $this->validateArguments($constructor, $arguments, $organisedArguments);
+
+        return $organisedArguments;
+    }
+
+    /**
+     * Checks that all provided constructor arguments are present in the constructor.
+     *
+     * @param ReflectionMethod $constructor
+     * @param mixed[]          $passedArguments
+     * @param mixed[]          $organisedArguments
+     *
+     * @throws UnknownParameterValueException
+     */
+    private function validateArguments(
+        ReflectionMethod $constructor,
+        array $passedArguments,
+        array $organisedArguments
+    ) {
+        foreach ($passedArguments as $key => $val) {
+            if (array_key_exists($key, $organisedArguments)) {
+                continue;
+            }
+
+            throw new UnknownParameterValueException(
+                sprintf(
+                    '`%s::__construct()` does not expect argument `$%s`.',
+                    $constructor->getDeclaringClass()->getName(),
+                    $key
+                )
+            );
+        }
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Argument/Exception/ArgumentException.php b/vendor/behat/behat/src/Behat/Testwork/Argument/Exception/ArgumentException.php
new file mode 100644 (file)
index 0000000..fdcf310
--- /dev/null
@@ -0,0 +1,22 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Argument\Exception;
+
+use Behat\Testwork\Exception\TestworkException;
+
+/**
+ * All argument exceptions extend this interface.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface ArgumentException extends TestworkException
+{
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Argument/Exception/UnknownParameterValueException.php b/vendor/behat/behat/src/Behat/Testwork/Argument/Exception/UnknownParameterValueException.php
new file mode 100644 (file)
index 0000000..b83958b
--- /dev/null
@@ -0,0 +1,24 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Argument\Exception;
+
+use BadMethodCallException;
+
+/**
+ * Represents an exception caused by an unknown function parameter value.
+ *
+ * Exception is thrown if provided function parameter value is unknown or missing.
+ *
+ * @author Wouter J <wouter@wouterj.nl>
+ */
+final class UnknownParameterValueException extends BadMethodCallException implements ArgumentException
+{
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Argument/Exception/UnsupportedFunctionException.php b/vendor/behat/behat/src/Behat/Testwork/Argument/Exception/UnsupportedFunctionException.php
new file mode 100644 (file)
index 0000000..688c939
--- /dev/null
@@ -0,0 +1,22 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Argument\Exception;
+
+use InvalidArgumentException;
+
+/**
+ * Represents an attempt to organise unsupported function arguments.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class UnsupportedFunctionException extends InvalidArgumentException implements ArgumentException
+{
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Argument/MixedArgumentOrganiser.php b/vendor/behat/behat/src/Behat/Testwork/Argument/MixedArgumentOrganiser.php
new file mode 100644 (file)
index 0000000..bc116dd
--- /dev/null
@@ -0,0 +1,429 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Argument;
+
+use ReflectionFunctionAbstract;
+use ReflectionClass;
+use ReflectionParameter;
+
+/**
+ * Organises function arguments using its reflection.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class MixedArgumentOrganiser implements ArgumentOrganiser
+{
+    private $definedArguments = array();
+
+    /**
+     * Organises arguments using function reflection.
+     *
+     * @param ReflectionFunctionAbstract $function
+     * @param mixed[]                    $arguments
+     *
+     * @return mixed[]
+     */
+    public function organiseArguments(ReflectionFunctionAbstract $function, array $arguments)
+    {
+        return $this->prepareArguments($function->getParameters(), $arguments);
+    }
+
+    /**
+     * Prepares arguments based on provided parameters.
+     *
+     * @param ReflectionParameter[] $parameters
+     * @param mixed[]               $arguments
+     *
+     * @return mixed[]
+     */
+    private function prepareArguments(array $parameters, array $arguments)
+    {
+        $this->markAllArgumentsUndefined();
+
+        list($named, $typehinted, $numbered) = $this->splitArguments($parameters, $arguments);
+
+        $arguments =
+            $this->prepareNamedArguments($parameters, $named) +
+            $this->prepareTypehintedArguments($parameters, $typehinted) +
+            $this->prepareNumberedArguments($parameters, $numbered) +
+            $this->prepareDefaultArguments($parameters);
+
+        return $this->reorderArguments($parameters, $arguments);
+    }
+
+    /**
+     * Splits arguments into three separate arrays - named, numbered and typehinted.
+     *
+     * @param ReflectionParameter[] $parameters
+     * @param mixed[]               $arguments
+     *
+     * @return array
+     */
+    private function splitArguments(array $parameters, array $arguments)
+    {
+        $parameterNames = array_map(
+            function (ReflectionParameter $parameter) {
+                return $parameter->getName();
+            },
+            $parameters
+        );
+
+        $namedArguments = array();
+        $numberedArguments = array();
+        $typehintedArguments = array();
+        foreach ($arguments as $key => $val) {
+            if ($this->isStringKeyAndExistsInParameters($key, $parameterNames)) {
+                $namedArguments[$key] = $val;
+            } elseif ($this->isParameterTypehintedInArgumentList($parameters, $val)) {
+                $typehintedArguments[] = $val;
+            } else {
+                $numberedArguments[] = $val;
+            }
+        }
+
+        return array($namedArguments, $typehintedArguments, $numberedArguments);
+    }
+
+    /**
+     * Checks that provided argument key is a string and it matches some parameter name.
+     *
+     * @param mixed    $argumentKey
+     * @param string[] $parameterNames
+     *
+     * @return Boolean
+     */
+    private function isStringKeyAndExistsInParameters($argumentKey, $parameterNames)
+    {
+        return is_string($argumentKey) && in_array($argumentKey, $parameterNames);
+    }
+
+    /**
+     * Check if a given value is typehinted in the argument list.
+     *
+     * @param  ReflectionParameter[] $parameters
+     * @param  mixed                 $value
+     *
+     * @return Boolean
+     */
+    private function isParameterTypehintedInArgumentList(array $parameters, $value)
+    {
+        if (!is_object($value)) {
+            return false;
+        }
+
+        foreach ($parameters as $parameter) {
+            if ($this->isValueMatchesTypehintedParameter($value, $parameter)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Checks if value matches typehint of provided parameter.
+     *
+     * @param object              $value
+     * @param ReflectionParameter $parameter
+     *
+     * @return Boolean
+     */
+    private function isValueMatchesTypehintedParameter($value, ReflectionParameter $parameter)
+    {
+        $typehintRefl = $parameter->getClass();
+
+        return $typehintRefl && $typehintRefl->isInstance($value);
+    }
+
+    /**
+     * Captures argument values based on their respective names.
+     *
+     * @param ReflectionParameter[] $parameters
+     * @param mixed[]               $namedArguments
+     *
+     * @return mixed[]
+     */
+    private function prepareNamedArguments(array $parameters, array $namedArguments)
+    {
+        $arguments = array();
+
+        foreach ($parameters as $num => $parameter) {
+            $name = $parameter->getName();
+
+            if (array_key_exists($name, $namedArguments)) {
+                $arguments[$name] = $namedArguments[$name];
+                $this->markArgumentDefined($num);
+            }
+        }
+
+        return $arguments;
+    }
+
+    /**
+     * Captures argument values for typehinted arguments based on the given candidates.
+     *
+     * This method attempts to match up the best fitting arguments to each constructor argument.
+     *
+     * This case specifically fixes the issue where a constructor asks for a parent and child class,
+     * as separate arguments, but both arguments could satisfy the first argument,
+     * so they would both be passed in (overwriting each other).
+     *
+     * This will ensure that the children (exact class matches) are mapped first, and then other dependencies
+     * are mapped sequentially (to arguments which they are an `instanceof`).
+     *
+     * As such, this requires two passes of the $parameters array to ensure it is mapped as accurately as possible.
+     *
+     * @param ReflectionParameter[] $parameters          Reflection Parameters (constructor argument requirements)
+     * @param mixed[]               $typehintedArguments Resolved arguments
+     *
+     * @return mixed[] Ordered list of arguments, index is the constructor argument position, value is what will be injected
+     */
+    private function prepareTypehintedArguments(array $parameters, array $typehintedArguments)
+    {
+        $arguments = array();
+
+        $candidates = $typehintedArguments;
+
+        $this->applyPredicateToTypehintedArguments(
+            $parameters,
+            $candidates,
+            $arguments,
+            array($this, 'classMatchingPredicateForTypehintedArguments')
+        );
+
+        // This iteration maps up everything else, providing the argument is an instanceof the parameter.
+        $this->applyPredicateToTypehintedArguments(
+            $parameters,
+            $candidates,
+            $arguments,
+            array($this, 'isInstancePredicateForTypehintedArguments')
+        );
+
+        return $arguments;
+    }
+
+    /**
+     * Filtered out superfluous parameters for matching up typehinted arguments.
+     *
+     * @param  ReflectionParameter[] $parameters Constructor Arguments
+     * @return ReflectionParameter[]             Filtered $parameters
+     */
+    private function filterApplicableTypehintedParameters(array $parameters)
+    {
+        $filtered = array();
+
+        foreach ($parameters as $num => $parameter) {
+            if ($this->isArgumentDefined($num)) {
+                continue;
+            }
+
+            $reflectionClass = $parameter->getClass();
+
+            if (!$reflectionClass) {
+                continue;
+            }
+
+            $filtered[$num] = $parameter;
+        }
+
+        return $filtered;
+    }
+
+    /**
+     * Applies a predicate for each candidate when matching up typehinted arguments.
+     * This passes through to another loop of the candidates in @matchParameterToCandidateUsingPredicate,
+     * because this method is "too complex" with two loops...
+     *
+     * @param  ReflectionParameter[] $parameters Reflection Parameters (constructor argument requirements)
+     * @param  mixed[]               &$candidates Resolved arguments
+     * @param  mixed[]               &$arguments  Argument mapping
+     * @param  callable              $predicate   Callable predicate to apply to each candidate
+     * @return void
+     */
+    private function applyPredicateToTypehintedArguments(
+        array $parameters,
+        array &$candidates,
+        array &$arguments,
+        callable $predicate
+    ) {
+        $filtered = $this->filterApplicableTypehintedParameters($parameters);
+
+        foreach ($filtered as $num => $parameter) {
+            $this->matchParameterToCandidateUsingPredicate($parameter, $candidates, $arguments, $predicate);
+        }
+    }
+
+    /**
+     * Applies a predicate for each candidate when matching up typehinted arguments.
+     * This helps to avoid repetition when looping them, as multiple passes are needed over the parameters / candidates.
+     *
+     * @param  ReflectionParameter $parameter   Reflection Parameter (constructor argument requirements)
+     * @param  mixed[]             &$candidates Resolved arguments
+     * @param  mixed[]             &$arguments  Argument mapping
+     * @param  callable            $predicate   Callable predicate to apply to each candidate
+     * @return boolean Returns true if a candidate has been matched to the given parameter, otherwise false
+     */
+    public function matchParameterToCandidateUsingPredicate(
+        ReflectionParameter $parameter,
+        array &$candidates,
+        array &$arguments,
+        callable $predicate
+    ) {
+        foreach ($candidates as $candidateIndex => $candidate) {
+            if (call_user_func_array($predicate, array($parameter->getClass(), $candidate))) {
+                $num = $parameter->getPosition();
+
+                $arguments[$num] = $candidate;
+
+                $this->markArgumentDefined($num);
+
+                unset($candidates[$candidateIndex]);
+
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Typehinted argument predicate to check if the argument and parameter classes match equally.
+     *
+     * @param  ReflectionClass $reflectionClass Typehinted argument
+     * @param  mixed           $candidate       Resolved argument
+     * @return boolean
+     */
+    private function classMatchingPredicateForTypehintedArguments(ReflectionClass $reflectionClass, $candidate)
+    {
+        return $reflectionClass->getName() === get_class($candidate);
+    }
+
+    /**
+     * Typehinted argument predicate to check if the argument is an instance of the parameter.
+     *
+     * @param  ReflectionClass $reflectionClass Typehinted argument
+     * @param  mixed           $candidate       Resolved argument
+     * @return boolean
+     */
+    private function isInstancePredicateForTypehintedArguments(ReflectionClass $reflectionClass, $candidate)
+    {
+        return $reflectionClass->isInstance($candidate);
+    }
+
+    /**
+     * Captures argument values for undefined arguments based on their respective numbers.
+     *
+     * @param ReflectionParameter[] $parameters
+     * @param mixed[]               $numberedArguments
+     *
+     * @return mixed[]
+     */
+    private function prepareNumberedArguments(array $parameters, array $numberedArguments)
+    {
+        $arguments = array();
+
+        $increment = 0;
+        foreach ($parameters as $num => $parameter) {
+            if ($this->isArgumentDefined($num)) {
+                continue;
+            }
+
+            if (array_key_exists($increment, $numberedArguments)) {
+                $arguments[$num] = $numberedArguments[$increment++];
+                $this->markArgumentDefined($num);
+            }
+        }
+
+        return $arguments;
+    }
+
+    /**
+     * Captures argument values for undefined arguments based on parameters defaults.
+     *
+     * @param ReflectionParameter[] $parameters
+     *
+     * @return mixed[]
+     */
+    private function prepareDefaultArguments(array $parameters)
+    {
+        $arguments = array();
+
+        foreach ($parameters as $num => $parameter) {
+            if ($this->isArgumentDefined($num)) {
+                continue;
+            }
+
+            if ($parameter->isDefaultValueAvailable()) {
+                $arguments[$num] = $parameter->getDefaultValue();
+                $this->markArgumentDefined($num);
+            }
+        }
+
+        return $arguments;
+    }
+
+    /**
+     * Reorders arguments based on their respective parameters order.
+     *
+     * @param ReflectionParameter[] $parameters
+     * @param array                 $arguments
+     *
+     * @return mixed[]
+     */
+    private function reorderArguments(array $parameters, array $arguments)
+    {
+        $orderedArguments = array();
+
+        foreach ($parameters as $num => $parameter) {
+            $name = $parameter->getName();
+
+            if (array_key_exists($num, $arguments)) {
+                $orderedArguments[$num] = $arguments[$num];
+            } elseif (array_key_exists($name, $arguments)) {
+                $orderedArguments[$name] = $arguments[$name];
+            }
+        }
+
+        return $orderedArguments;
+    }
+
+    /**
+     * Marks arguments at all positions as undefined.
+     *
+     * This is used to share state between get*Arguments() methods.
+     */
+    private function markAllArgumentsUndefined()
+    {
+        $this->definedArguments = array();
+    }
+
+    /**
+     * Marks an argument at provided position as defined.
+     *
+     * @param integer $position
+     */
+    private function markArgumentDefined($position)
+    {
+        $this->definedArguments[$position] = true;
+    }
+
+    /**
+     * Checks if an argument at provided position is defined.
+     *
+     * @param integer $position
+     *
+     * @return Boolean
+     */
+    private function isArgumentDefined($position)
+    {
+        return isset($this->definedArguments[$position]);
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Argument/PregMatchArgumentOrganiser.php b/vendor/behat/behat/src/Behat/Testwork/Argument/PregMatchArgumentOrganiser.php
new file mode 100644 (file)
index 0000000..2fb0535
--- /dev/null
@@ -0,0 +1,93 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Argument;
+
+use ReflectionFunctionAbstract;
+
+/**
+ * Organises arguments coming from preg_match results.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class PregMatchArgumentOrganiser implements ArgumentOrganiser
+{
+    /**
+     * @var ArgumentOrganiser
+     */
+    private $baseOrganiser;
+
+    /**
+     * Initialises organiser.
+     *
+     * @param ArgumentOrganiser $organiser
+     */
+    public function __construct(ArgumentOrganiser $organiser)
+    {
+        $this->baseOrganiser = $organiser;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function organiseArguments(ReflectionFunctionAbstract $function, array $match)
+    {
+        $arguments = $this->cleanupMatchDuplicates($match);
+
+        return $this->baseOrganiser->organiseArguments($function, $arguments);
+    }
+
+    /**
+     * Cleans up provided preg_match match into a list of arguments.
+     *
+     * `preg_match` matches named arguments with named indexes and also
+     * represents all arguments with numbered indexes. This method removes
+     * duplication and also drops the first full match element from the
+     * array.
+     *
+     * @param array $match
+     *
+     * @return mixed[]
+     */
+    private function cleanupMatchDuplicates(array $match)
+    {
+        $cleanMatch = array_slice($match, 1);
+        $arguments = array();
+
+        $keys = array_keys($cleanMatch);
+        for ($keyIndex = 0; $keyIndex < count($keys); $keyIndex++) {
+            $key = $keys[$keyIndex];
+
+            $arguments[$key] = $cleanMatch[$key];
+
+            if ($this->isKeyAStringAndNexOneIsAnInteger($keyIndex, $keys)) {
+                $keyIndex += 1;
+            }
+        }
+
+        return $arguments;
+    }
+
+    /**
+     * Checks if key at provided index is a string and next key in the array is an integer.
+     *
+     * @param integer $keyIndex
+     * @param mixed[] $keys
+     *
+     * @return Boolean
+     */
+    private function isKeyAStringAndNexOneIsAnInteger($keyIndex, array $keys)
+    {
+        $keyIsAString = is_string($keys[$keyIndex]);
+        $nextKeyIsAnInteger = isset($keys[$keyIndex + 1]) && is_integer($keys[$keyIndex + 1]);
+
+        return $keyIsAString && $nextKeyIsAnInteger;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Argument/ServiceContainer/ArgumentExtension.php b/vendor/behat/behat/src/Behat/Testwork/Argument/ServiceContainer/ArgumentExtension.php
new file mode 100644 (file)
index 0000000..9aa5afe
--- /dev/null
@@ -0,0 +1,81 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Argument\ServiceContainer;
+
+use Behat\Testwork\ServiceContainer\Extension;
+use Behat\Testwork\ServiceContainer\ExtensionManager;
+use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Definition;
+use Symfony\Component\DependencyInjection\Reference;
+
+/**
+ * Enables argument organisers for Testwork.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class ArgumentExtension implements Extension
+{
+    /*
+     * Available services
+     */
+    const MIXED_ARGUMENT_ORGANISER_ID = 'argument.mixed_organiser';
+    const PREG_MATCH_ARGUMENT_ORGANISER_ID = 'argument.preg_match_organiser';
+    const CONSTRUCTOR_ARGUMENT_ORGANISER_ID = 'argument.constructor_organiser';
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getConfigKey()
+    {
+        return 'argument';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function initialize(ExtensionManager $extensionManager)
+    {
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function configure(ArrayNodeDefinition $builder)
+    {
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function load(ContainerBuilder $container, array $config)
+    {
+        $definition = new Definition('Behat\Testwork\Argument\MixedArgumentOrganiser');
+        $container->setDefinition(self::MIXED_ARGUMENT_ORGANISER_ID, $definition);
+
+        $definition = new Definition('Behat\Testwork\Argument\PregMatchArgumentOrganiser', array(
+            new Reference(self::MIXED_ARGUMENT_ORGANISER_ID)
+        ));
+        $container->setDefinition(self::PREG_MATCH_ARGUMENT_ORGANISER_ID, $definition);
+
+        $definition = new Definition('Behat\Testwork\Argument\ConstructorArgumentOrganiser', array(
+            new Reference(self::MIXED_ARGUMENT_ORGANISER_ID)
+        ));
+        $container->setDefinition(self::CONSTRUCTOR_ARGUMENT_ORGANISER_ID, $definition);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function process(ContainerBuilder $container)
+    {
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Argument/Validator.php b/vendor/behat/behat/src/Behat/Testwork/Argument/Validator.php
new file mode 100644 (file)
index 0000000..3d47e7e
--- /dev/null
@@ -0,0 +1,87 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Argument;
+
+use Behat\Testwork\Argument\Exception\UnknownParameterValueException;
+use ReflectionFunctionAbstract;
+use ReflectionMethod;
+use ReflectionParameter;
+
+/**
+ * Validates function arguments.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class Validator
+{
+    /**
+     * Validates that all arguments are in place, throws exception otherwise.
+     *
+     * @param ReflectionFunctionAbstract $function
+     * @param mixed[]                    $arguments
+     *
+     * @throws UnknownParameterValueException
+     */
+    public function validateArguments(ReflectionFunctionAbstract $function, array $arguments)
+    {
+        foreach ($function->getParameters() as $num => $parameter) {
+            $this->validateArgument($parameter, $num, $arguments);
+        }
+    }
+
+    /**
+     * Validates given argument.
+     *
+     * @param ReflectionParameter $parameter
+     * @param integer             $parameterIndex
+     * @param array               $givenArguments
+     */
+    private function validateArgument(ReflectionParameter $parameter, $parameterIndex, array $givenArguments)
+    {
+        if ($parameter->isDefaultValueAvailable()) {
+            return;
+        }
+
+        if (array_key_exists($parameterIndex, $givenArguments)) {
+            return;
+        }
+
+        if (array_key_exists($parameter->getName(), $givenArguments)) {
+            return;
+        }
+
+        throw new UnknownParameterValueException(sprintf(
+            'Can not find a matching value for an argument `$%s` of the method `%s`.',
+            $parameter->getName(),
+            $this->getFunctionPath($parameter->getDeclaringFunction())
+        ));
+    }
+
+    /**
+     * Returns function path for a provided reflection.
+     *
+     * @param ReflectionFunctionAbstract $function
+     *
+     * @return string
+     */
+    private function getFunctionPath(ReflectionFunctionAbstract $function)
+    {
+        if ($function instanceof ReflectionMethod) {
+            return sprintf(
+                '%s::%s()',
+                $function->getDeclaringClass()->getName(),
+                $function->getName()
+            );
+        }
+
+        return sprintf('%s()', $function->getName());
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Autoloader/Cli/AutoloaderController.php b/vendor/behat/behat/src/Behat/Testwork/Autoloader/Cli/AutoloaderController.php
new file mode 100644 (file)
index 0000000..991eb41
--- /dev/null
@@ -0,0 +1,55 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Autoloader\Cli;
+
+use Behat\Testwork\Cli\Controller;
+use Symfony\Component\ClassLoader\ClassLoader;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * Registers Testwork autoloader.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class AutoloaderController implements Controller
+{
+    /**
+     * @var ClassLoader
+     */
+    private $loader;
+
+    /**
+     * Initializes controller
+     *
+     * @param ClassLoader $loader
+     */
+    public function __construct(ClassLoader $loader)
+    {
+        $this->loader = $loader;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function configure(Command $command)
+    {
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function execute(InputInterface $input, OutputInterface $output)
+    {
+        $this->loader->register();
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Autoloader/ServiceContainer/AutoloaderExtension.php b/vendor/behat/behat/src/Behat/Testwork/Autoloader/ServiceContainer/AutoloaderExtension.php
new file mode 100644 (file)
index 0000000..2c5f021
--- /dev/null
@@ -0,0 +1,151 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Autoloader\ServiceContainer;
+
+use Behat\Testwork\Cli\ServiceContainer\CliExtension;
+use Behat\Testwork\ServiceContainer\Extension;
+use Behat\Testwork\ServiceContainer\ExtensionManager;
+use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Definition;
+use Symfony\Component\DependencyInjection\Reference;
+
+/**
+ * Extends Testwork with class-loading services.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class AutoloaderExtension implements Extension
+{
+    /*
+     * Available services
+     */
+    const CLASS_LOADER_ID = 'class_loader';
+
+    /**
+     * @var array
+     */
+    private $defaultPaths = array();
+
+    /**
+     * Initializes extension.
+     *
+     * @param array $defaultPaths
+     */
+    public function __construct(array $defaultPaths = array())
+    {
+        $this->defaultPaths = $defaultPaths;
+    }
+
+    /**
+     * Returns the extension config key.
+     *
+     * @return string
+     */
+    public function getConfigKey()
+    {
+        return 'autoload';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function initialize(ExtensionManager $extensionManager)
+    {
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function configure(ArrayNodeDefinition $builder)
+    {
+        $builder
+            ->beforeNormalization()
+                ->ifString()->then(function ($path) {
+                    return array('' => $path);
+                })
+            ->end()
+
+            ->defaultValue($this->defaultPaths)
+            ->treatTrueLike($this->defaultPaths)
+            ->treatNullLike(array())
+            ->treatFalseLike(array())
+
+            ->prototype('scalar')->end()
+        ;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function load(ContainerBuilder $container, array $config)
+    {
+        $this->loadAutoloader($container);
+        $this->loadController($container);
+        $this->setLoaderPrefixes($container, $config);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function process(ContainerBuilder $container)
+    {
+        $this->processLoaderPrefixes($container);
+    }
+
+    /**
+     * Loads Symfony2 autoloader.
+     *
+     * @param ContainerBuilder $container
+     */
+    private function loadAutoloader(ContainerBuilder $container)
+    {
+        $definition = new Definition('Symfony\Component\ClassLoader\ClassLoader');
+        $container->setDefinition(self::CLASS_LOADER_ID, $definition);
+    }
+
+    /**
+     * Loads controller.
+     *
+     * @param ContainerBuilder $container
+     */
+    private function loadController(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Testwork\Autoloader\Cli\AutoloaderController', array(
+            new Reference(self::CLASS_LOADER_ID)
+        ));
+        $definition->addTag(CliExtension::CONTROLLER_TAG, array('priority' => 9999));
+
+        $container->setDefinition(CliExtension::CONTROLLER_TAG . '.autoloader', $definition);
+    }
+
+    /**
+     * Sets provided prefixes to container.
+     *
+     * @param ContainerBuilder $container
+     * @param array            $prefixes
+     */
+    private function setLoaderPrefixes(ContainerBuilder $container, array $prefixes)
+    {
+        $container->setParameter('class_loader.prefixes', $prefixes);
+    }
+
+    /**
+     * Processes container loader prefixes.
+     *
+     * @param ContainerBuilder $container
+     */
+    private function processLoaderPrefixes(ContainerBuilder $container)
+    {
+        $loaderDefinition = $container->getDefinition(self::CLASS_LOADER_ID);
+        $loaderDefinition->addMethodCall('addPrefixes', array($container->getParameter('class_loader.prefixes')));
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Call/Call.php b/vendor/behat/behat/src/Behat/Testwork/Call/Call.php
new file mode 100644 (file)
index 0000000..efa04de
--- /dev/null
@@ -0,0 +1,47 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Call;
+
+/**
+ * Represents any call made inside testwork.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface Call
+{
+    /**
+     * Returns callee.
+     *
+     * @return Callee
+     */
+    public function getCallee();
+
+    /**
+     * Returns bound callable.
+     *
+     * @return callable
+     */
+    public function getBoundCallable();
+
+    /**
+     * Returns call arguments.
+     *
+     * @return array
+     */
+    public function getArguments();
+
+    /**
+     * Returns call error reporting level.
+     *
+     * @return null|integer
+     */
+    public function getErrorReportingLevel();
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Call/CallCenter.php b/vendor/behat/behat/src/Behat/Testwork/Call/CallCenter.php
new file mode 100644 (file)
index 0000000..448367b
--- /dev/null
@@ -0,0 +1,192 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Call;
+
+use Behat\Testwork\Call\Exception\CallHandlingException;
+use Behat\Testwork\Call\Exception\FatalThrowableError;
+use Behat\Testwork\Call\Filter\CallFilter;
+use Behat\Testwork\Call\Filter\ResultFilter;
+use Behat\Testwork\Call\Handler\CallHandler;
+use Behat\Testwork\Call\Handler\ExceptionHandler;
+use Exception;
+use Throwable;
+
+/**
+ * Makes calls and handles results using registered handlers.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class CallCenter
+{
+    /**
+     * @var CallFilter[]
+     */
+    private $callFilters = array();
+    /**
+     * @var CallHandler[]
+     */
+    private $callHandlers = array();
+    /**
+     * @var ResultFilter[]
+     */
+    private $resultFilters = array();
+    /**
+     * @var ExceptionHandler[]
+     */
+    private $exceptionHandlers = array();
+
+    /**
+     * Registers call filter.
+     *
+     * @param CallFilter $filter
+     */
+    public function registerCallFilter(CallFilter $filter)
+    {
+        $this->callFilters[] = $filter;
+    }
+
+    /**
+     * Registers call handler.
+     *
+     * @param CallHandler $handler
+     */
+    public function registerCallHandler(CallHandler $handler)
+    {
+        $this->callHandlers[] = $handler;
+    }
+
+    /**
+     * Registers call result filter.
+     *
+     * @param ResultFilter $filter
+     */
+    public function registerResultFilter(ResultFilter $filter)
+    {
+        $this->resultFilters[] = $filter;
+    }
+
+    /**
+     * Registers result exception handler.
+     *
+     * @param ExceptionHandler $handler
+     */
+    public function registerExceptionHandler(ExceptionHandler $handler)
+    {
+        $this->exceptionHandlers[] = $handler;
+    }
+
+    /**
+     * Handles call and its result using registered filters and handlers.
+     *
+     * @param Call $call
+     *
+     * @return CallResult
+     */
+    public function makeCall(Call $call)
+    {
+        try {
+            return $this->filterResult($this->handleCall($this->filterCall($call)));
+        } catch (Exception $exception) {
+            return new CallResult($call, null, $this->handleException($exception), null);
+        } catch (Throwable $exception) {
+            return new CallResult($call, null, $this->handleException($exception), null);
+        }
+    }
+
+    /**
+     * Filters call using registered filters and returns a filtered one.
+     *
+     * @param Call $call
+     *
+     * @return Call
+     */
+    private function filterCall(Call $call)
+    {
+        foreach ($this->callFilters as $filter) {
+            if (!$filter->supportsCall($call)) {
+                continue;
+            }
+
+            $call = $filter->filterCall($call);
+        }
+
+        return $call;
+    }
+
+    /**
+     * Handles call using registered call handlers.
+     *
+     * @param Call $call
+     *
+     * @return CallResult
+     *
+     * @throws CallHandlingException If call handlers didn't produce call result
+     */
+    private function handleCall(Call $call)
+    {
+        foreach ($this->callHandlers as $handler) {
+            if (!$handler->supportsCall($call)) {
+                continue;
+            }
+
+            return $handler->handleCall($call);
+        }
+
+        throw new CallHandlingException(sprintf(
+            'None of the registered call handlers could handle a `%s` call.',
+            $call->getCallee()->getPath()
+        ), $call);
+    }
+
+    /**
+     * Filters call result using registered filters and returns a filtered one.
+     *
+     * @param CallResult $result
+     *
+     * @return CallResult
+     */
+    private function filterResult(CallResult $result)
+    {
+        foreach ($this->resultFilters as $filter) {
+            if (!$filter->supportsResult($result)) {
+                continue;
+            }
+
+            $result = $filter->filterResult($result);
+        }
+
+        return $result;
+    }
+
+    /**
+     * Handles exception using registered handlers and returns a handled one.
+     *
+     * @param Throwable $exception
+     *
+     * @return Throwable
+     */
+    private function handleException($exception)
+    {
+        foreach ($this->exceptionHandlers as $handler) {
+            if (!$handler->supportsException($exception)) {
+                continue;
+            }
+
+            $exception = $handler->handleException($exception);
+        }
+
+        if ($exception instanceof Throwable) {
+            return new FatalThrowableError($exception);
+        }
+
+        return $exception;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Call/CallResult.php b/vendor/behat/behat/src/Behat/Testwork/Call/CallResult.php
new file mode 100644 (file)
index 0000000..ca3c528
--- /dev/null
@@ -0,0 +1,114 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Call;
+
+use Exception;
+
+/**
+ * Represents result of the call.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class CallResult
+{
+    /**
+     * @var Call
+     */
+    private $call;
+    /**
+     * @var mixed
+     */
+    private $return;
+    /**
+     * @var null|Exception
+     */
+    private $exception;
+    /**
+     * @var null|string
+     */
+    private $stdOut;
+
+    /**
+     * Initializes call result.
+     *
+     * @param Call           $call
+     * @param mixed          $return
+     * @param null|Exception $exception
+     * @param null|string    $stdOut
+     */
+    public function __construct(Call $call, $return, Exception $exception = null, $stdOut = null)
+    {
+        $this->call = $call;
+        $this->return = $return;
+        $this->exception = $exception;
+        $this->stdOut = $stdOut;
+    }
+
+    /**
+     * Returns call.
+     *
+     * @return Call
+     */
+    public function getCall()
+    {
+        return $this->call;
+    }
+
+    /**
+     * Returns call return value.
+     *
+     * @return mixed
+     */
+    public function getReturn()
+    {
+        return $this->return;
+    }
+
+    /**
+     * Check if call thrown exception.
+     *
+     * @return Boolean
+     */
+    public function hasException()
+    {
+        return null !== $this->exception;
+    }
+
+    /**
+     * Returns exception thrown by call (if any).
+     *
+     * @return null|Exception
+     */
+    public function getException()
+    {
+        return $this->exception;
+    }
+
+    /**
+     * Checks if call produced stdOut.
+     *
+     * @return Boolean
+     */
+    public function hasStdOut()
+    {
+        return null !== $this->stdOut;
+    }
+
+    /**
+     * Returns stdOut produced by call (if any).
+     *
+     * @return null|string
+     */
+    public function getStdOut()
+    {
+        return $this->stdOut;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Call/CallResults.php b/vendor/behat/behat/src/Behat/Testwork/Call/CallResults.php
new file mode 100644 (file)
index 0000000..f79ea0c
--- /dev/null
@@ -0,0 +1,114 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Call;
+
+use ArrayIterator;
+use Countable;
+use Iterator;
+use IteratorAggregate;
+
+/**
+ * Aggregates multiple call results into a collection and provides an informational API on top of that.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class CallResults implements Countable, IteratorAggregate
+{
+    /**
+     * @var CallResult[]
+     */
+    private $results;
+
+    /**
+     * Initializes call results collection.
+     *
+     * @param CallResult[] $results
+     */
+    public function __construct(array $results = array())
+    {
+        $this->results = $results;
+    }
+
+    /**
+     * Merges results from provided collection into the current one.
+     *
+     * @param CallResults $first
+     * @param CallResults $second
+     *
+     * @return CallResults
+     */
+    public static function merge(CallResults $first, CallResults $second)
+    {
+        return new static(array_merge($first->toArray(), $second->toArray()));
+    }
+
+    /**
+     * Checks if any call in collection throws an exception.
+     *
+     * @return Boolean
+     */
+    public function hasExceptions()
+    {
+        foreach ($this->results as $result) {
+            if ($result->hasException()) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Checks if any call in collection produces an output.
+     *
+     * @return Boolean
+     */
+    public function hasStdOuts()
+    {
+        foreach ($this->results as $result) {
+            if ($result->hasStdOut()) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Returns amount of results.
+     *
+     * @return integer
+     */
+    public function count()
+    {
+        return count($this->results);
+    }
+
+    /**
+     * Returns collection iterator.
+     *
+     * @return Iterator
+     */
+    public function getIterator()
+    {
+        return new ArrayIterator($this->results);
+    }
+
+    /**
+     * Returns call results array.
+     *
+     * @return CallResult[]
+     */
+    public function toArray()
+    {
+        return $this->results;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Call/Callee.php b/vendor/behat/behat/src/Behat/Testwork/Call/Callee.php
new file mode 100644 (file)
index 0000000..c03e776
--- /dev/null
@@ -0,0 +1,63 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Call;
+
+use ReflectionFunctionAbstract;
+
+/**
+ * Represents callable object.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface Callee
+{
+    /**
+     * Returns callee definition path.
+     *
+     * @return string
+     */
+    public function getPath();
+
+    /**
+     * Returns callee description.
+     *
+     * @return string
+     */
+    public function getDescription();
+
+    /**
+     * Returns true if callee is a method, false otherwise.
+     *
+     * @return Boolean
+     */
+    public function isAMethod();
+
+    /**
+     * Returns true if callee is an instance (non-static) method, false otherwise.
+     *
+     * @return Boolean
+     */
+    public function isAnInstanceMethod();
+
+    /**
+     * Returns callable.
+     *
+     * @return callable
+     */
+    public function getCallable();
+
+    /**
+     * Returns callable reflection.
+     *
+     * @return ReflectionFunctionAbstract
+     */
+    public function getReflection();
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Call/Exception/BadCallbackException.php b/vendor/behat/behat/src/Behat/Testwork/Call/Exception/BadCallbackException.php
new file mode 100644 (file)
index 0000000..de56b4e
--- /dev/null
@@ -0,0 +1,49 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Call\Exception;
+
+use InvalidArgumentException;
+
+/**
+ * Represents exception caused by a bad callback.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class BadCallbackException extends InvalidArgumentException implements CallException
+{
+    /**
+     * @var callable
+     */
+    private $callable;
+
+    /**
+     * Initializes exception.
+     *
+     * @param string   $message
+     * @param callable $callable
+     */
+    public function __construct($message, $callable)
+    {
+        $this->callable = $callable;
+
+        parent::__construct($message);
+    }
+
+    /**
+     * Returns callback that caused exception.
+     *
+     * @return callable
+     */
+    public function getCallable()
+    {
+        return $this->callable;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Call/Exception/CallErrorException.php b/vendor/behat/behat/src/Behat/Testwork/Call/Exception/CallErrorException.php
new file mode 100644 (file)
index 0000000..423abf3
--- /dev/null
@@ -0,0 +1,52 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Call\Exception;
+
+use ErrorException;
+
+/**
+ * Represents catchable errors raised during call execution.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class CallErrorException extends ErrorException
+{
+    private $levels = array(
+        E_WARNING           => 'Warning',
+        E_NOTICE            => 'Notice',
+        E_USER_ERROR        => 'User Error',
+        E_USER_WARNING      => 'User Warning',
+        E_USER_NOTICE       => 'User Notice',
+        E_STRICT            => 'Runtime Notice',
+        E_RECOVERABLE_ERROR => 'Catchable Fatal Error',
+    );
+
+    /**
+     * Initializes error handler exception.
+     *
+     * @param integer $level   error level
+     * @param string  $message error message
+     * @param string  $file    error file
+     * @param integer $line    error line
+     */
+    public function __construct($level, $message, $file, $line)
+    {
+        parent::__construct(
+            sprintf(
+                '%s: %s in %s line %d',
+                isset($this->levels[$level]) ? $this->levels[$level] : $level,
+                $message,
+                $file,
+                $line
+            )
+        );
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Call/Exception/CallException.php b/vendor/behat/behat/src/Behat/Testwork/Call/Exception/CallException.php
new file mode 100644 (file)
index 0000000..1e3db97
--- /dev/null
@@ -0,0 +1,22 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Call\Exception;
+
+use Behat\Testwork\Exception\TestworkException;
+
+/**
+ * All call exceptions should implement this interface.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface CallException extends TestworkException
+{
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Call/Exception/CallHandlingException.php b/vendor/behat/behat/src/Behat/Testwork/Call/Exception/CallHandlingException.php
new file mode 100644 (file)
index 0000000..f8e670e
--- /dev/null
@@ -0,0 +1,50 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Call\Exception;
+
+use Behat\Testwork\Call\Call;
+use RuntimeException;
+
+/**
+ * Represents exceptions thrown during call handling phase.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class CallHandlingException extends RuntimeException implements CallException
+{
+    /**
+     * @var Call
+     */
+    private $call;
+
+    /**
+     * Initializes exception.
+     *
+     * @param string $message
+     * @param Call   $callable
+     */
+    public function __construct($message, Call $callable)
+    {
+        $this->call = $callable;
+
+        parent::__construct($message);
+    }
+
+    /**
+     * Returns call that caused exception.
+     *
+     * @return Call
+     */
+    public function getCall()
+    {
+        return $this->call;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Call/Exception/FatalThrowableError.php b/vendor/behat/behat/src/Behat/Testwork/Call/Exception/FatalThrowableError.php
new file mode 100644 (file)
index 0000000..52958b9
--- /dev/null
@@ -0,0 +1,55 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Call\Exception;
+
+use ErrorException;
+use ParseError;
+use Throwable;
+use TypeError;
+
+/**
+ * Fatal Throwable Error.
+ *
+ * @author Nicolas Grekas <p@tchwork.com>
+ */
+class FatalThrowableError extends ErrorException
+{
+    public function __construct(Throwable $e)
+    {
+        if ($e instanceof ParseError) {
+            $message = 'Parse error: '.$e->getMessage();
+            $severity = E_PARSE;
+        } elseif ($e instanceof TypeError) {
+            $message = 'Type error: '.$e->getMessage();
+            $severity = E_RECOVERABLE_ERROR;
+        } else {
+            $message = 'Fatal error: '.$e->getMessage();
+            $severity = E_ERROR;
+        }
+
+        parent::__construct(
+            $message,
+            $e->getCode(),
+            $severity,
+            $e->getFile(),
+            $e->getLine()
+        );
+
+        $this->setTrace($e->getTrace());
+    }
+
+    private function setTrace($trace)
+    {
+        $traceReflector = new \ReflectionProperty('Exception', 'trace');
+        $traceReflector->setAccessible(true);
+        $traceReflector->setValue($this, $trace);
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Call/Filter/CallFilter.php b/vendor/behat/behat/src/Behat/Testwork/Call/Filter/CallFilter.php
new file mode 100644 (file)
index 0000000..5426c16
--- /dev/null
@@ -0,0 +1,42 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Call\Filter;
+
+use Behat\Testwork\Call\Call;
+use Behat\Testwork\Call\CallCenter;
+
+/**
+ * Filters call before its being made and returns a new call.
+ *
+ * @see CallCenter
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface CallFilter
+{
+    /**
+     * Checks if filter supports a call.
+     *
+     * @param Call $call
+     *
+     * @return Boolean
+     */
+    public function supportsCall(Call $call);
+
+    /**
+     * Filters a call and returns a new one.
+     *
+     * @param Call $call
+     *
+     * @return Call
+     */
+    public function filterCall(Call $call);
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Call/Filter/ResultFilter.php b/vendor/behat/behat/src/Behat/Testwork/Call/Filter/ResultFilter.php
new file mode 100644 (file)
index 0000000..ac3ebe0
--- /dev/null
@@ -0,0 +1,42 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Call\Filter;
+
+use Behat\Testwork\Call\CallCenter;
+use Behat\Testwork\Call\CallResult;
+
+/**
+ * Filters call results and produces new ones.
+ *
+ * @see CallCenter
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface ResultFilter
+{
+    /**
+     * Checks if filter supports call result.
+     *
+     * @param CallResult $result
+     *
+     * @return Boolean
+     */
+    public function supportsResult(CallResult $result);
+
+    /**
+     * Filters call result and returns a new result.
+     *
+     * @param CallResult $result
+     *
+     * @return CallResult
+     */
+    public function filterResult(CallResult $result);
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Call/Handler/CallHandler.php b/vendor/behat/behat/src/Behat/Testwork/Call/Handler/CallHandler.php
new file mode 100644 (file)
index 0000000..e553d2a
--- /dev/null
@@ -0,0 +1,43 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Call\Handler;
+
+use Behat\Testwork\Call\Call;
+use Behat\Testwork\Call\CallCenter;
+use Behat\Testwork\Call\CallResult;
+
+/**
+ * Handles calls and produces call results.
+ *
+ * @see CallCenter
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface CallHandler
+{
+    /**
+     * Checks if handler supports call.
+     *
+     * @param Call $call
+     *
+     * @return Boolean
+     */
+    public function supportsCall(Call $call);
+
+    /**
+     * Handles call and returns call result.
+     *
+     * @param Call $call
+     *
+     * @return CallResult
+     */
+    public function handleCall(Call $call);
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Call/Handler/Exception/ClassNotFoundHandler.php b/vendor/behat/behat/src/Behat/Testwork/Call/Handler/Exception/ClassNotFoundHandler.php
new file mode 100644 (file)
index 0000000..8d0f488
--- /dev/null
@@ -0,0 +1,71 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Call\Handler\Exception;
+
+use Behat\Testwork\Call\Handler\ExceptionHandler;
+use Error;
+
+/**
+ * Handles class not found exceptions.
+ *
+ * @see ExceptionHandler
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+abstract class ClassNotFoundHandler implements ExceptionHandler
+{
+    const PATTERN = "/^Class '([^']+)' not found$/";
+
+    /**
+     * {@inheritdoc}
+     */
+    final public function supportsException($exception)
+    {
+        if (!$exception instanceof Error) {
+            return false;
+        }
+
+        return null !== $this->extractNonExistentClass($exception);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    final public function handleException($exception)
+    {
+        $this->handleNonExistentClass($this->extractNonExistentClass($exception));
+
+        return $exception;
+    }
+
+    /**
+     * Override to handle non-existent class name.
+     *
+     * @param string $class
+     */
+    abstract public function handleNonExistentClass($class);
+
+    /**
+     * Extracts missing class name from the exception.
+     *
+     * @param Error $exception
+     *
+     * @return null|string
+     */
+    private function extractNonExistentClass(Error $exception)
+    {
+        if (1 === preg_match(self::PATTERN, $exception->getMessage(), $matches)) {
+            return $matches[1];
+        }
+
+        return null;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Call/Handler/Exception/MethodNotFoundHandler.php b/vendor/behat/behat/src/Behat/Testwork/Call/Handler/Exception/MethodNotFoundHandler.php
new file mode 100644 (file)
index 0000000..3ca680d
--- /dev/null
@@ -0,0 +1,71 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Call\Handler\Exception;
+
+use Behat\Testwork\Call\Handler\ExceptionHandler;
+use Error;
+
+/**
+ * Handles method not found exceptions.
+ *
+ * @see ExceptionHandler
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+abstract class MethodNotFoundHandler implements ExceptionHandler
+{
+    const PATTERN = '/^Call to undefined method ([^:]+)::([^\)]+)\(\)$/';
+
+    /**
+     * {@inheritdoc}
+     */
+    final public function supportsException($exception)
+    {
+        if (!$exception instanceof Error) {
+            return false;
+        }
+
+        return null !== $this->extractNonExistentCallable($exception);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    final public function handleException($exception)
+    {
+        $this->handleNonExistentMethod($this->extractNonExistentCallable($exception));
+
+        return $exception;
+    }
+
+    /**
+     * Override to handle non-existent method.
+     *
+     * @param array $callable
+     */
+    abstract public function handleNonExistentMethod(array $callable);
+
+    /**
+     * Extract callable from exception.
+     *
+     * @param Error $exception
+     *
+     * @return null|array
+     */
+    private function extractNonExistentCallable(Error $exception)
+    {
+        if (1 === preg_match(self::PATTERN, $exception->getMessage(), $matches)) {
+            return array($matches[1], $matches[2]);
+        }
+
+        return null;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Call/Handler/ExceptionHandler.php b/vendor/behat/behat/src/Behat/Testwork/Call/Handler/ExceptionHandler.php
new file mode 100644 (file)
index 0000000..53a35f7
--- /dev/null
@@ -0,0 +1,39 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Call\Handler;
+
+/**
+ * Handles exceptions.
+ *
+ * @see CallCenter
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface ExceptionHandler
+{
+    /**
+     * Checks if handler supports exception.
+     *
+     * @param \Throwable $exception
+     *
+     * @return bool
+     */
+    public function supportsException($exception);
+
+    /**
+     * Handles exception and returns new one if necessary.
+     *
+     * @param \Throwable $exception
+     *
+     * @return \Throwable
+     */
+    public function handleException($exception);
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Call/Handler/RuntimeCallHandler.php b/vendor/behat/behat/src/Behat/Testwork/Call/Handler/RuntimeCallHandler.php
new file mode 100644 (file)
index 0000000..62b3d1d
--- /dev/null
@@ -0,0 +1,163 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Call\Handler;
+
+use Behat\Testwork\Argument\Validator;
+use Behat\Testwork\Call\Call;
+use Behat\Testwork\Call\CallResult;
+use Behat\Testwork\Call\Exception\CallErrorException;
+use Exception;
+
+/**
+ * Handles calls in the current runtime.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class RuntimeCallHandler implements CallHandler
+{
+    /**
+     * @var integer
+     */
+    private $errorReportingLevel;
+    /**
+     * @var bool
+     */
+    private $obStarted = false;
+    /**
+     * @var Validator
+     */
+    private $validator;
+
+    /**
+     * Initializes executor.
+     *
+     * @param integer $errorReportingLevel
+     */
+    public function __construct($errorReportingLevel = E_ALL)
+    {
+        $this->errorReportingLevel = $errorReportingLevel;
+        $this->validator = new Validator();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function supportsCall(Call $call)
+    {
+        return true;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function handleCall(Call $call)
+    {
+        $this->startErrorAndOutputBuffering($call);
+        $result = $this->executeCall($call);
+        $this->stopErrorAndOutputBuffering();
+
+        return $result;
+    }
+
+    /**
+     * Used as a custom error handler when step is running.
+     *
+     * @see set_error_handler()
+     *
+     * @param integer $level
+     * @param string  $message
+     * @param string  $file
+     * @param integer $line
+     *
+     * @return Boolean
+     *
+     * @throws CallErrorException
+     */
+    public function handleError($level, $message, $file, $line)
+    {
+        if ($this->errorLevelIsNotReportable($level)) {
+            return false;
+        }
+
+        throw new CallErrorException($level, $message, $file, $line);
+    }
+
+    /**
+     * Executes single call.
+     *
+     * @param Call $call
+     *
+     * @return CallResult
+     */
+    private function executeCall(Call $call)
+    {
+        $reflection = $call->getCallee()->getReflection();
+        $callable = $call->getBoundCallable();
+        $arguments = $call->getArguments();
+        $return = $exception = null;
+
+        try {
+            $this->validator->validateArguments($reflection, $arguments);
+            $return = call_user_func_array($callable, $arguments);
+        } catch (Exception $caught) {
+            $exception = $caught;
+        }
+
+        $stdOut = $this->getBufferedStdOut();
+
+        return new CallResult($call, $return, $exception, $stdOut);
+    }
+
+    /**
+     * Returns buffered stdout.
+     *
+     * @return null|string
+     */
+    private function getBufferedStdOut()
+    {
+        return ob_get_length() ? ob_get_contents() : null;
+    }
+
+    /**
+     * Starts error handler and stdout buffering.
+     *
+     * @param Call $call
+     */
+    private function startErrorAndOutputBuffering(Call $call)
+    {
+        $errorReporting = $call->getErrorReportingLevel() ? : $this->errorReportingLevel;
+        set_error_handler(array($this, 'handleError'), $errorReporting);
+        $this->obStarted = ob_start();
+    }
+
+    /**
+     * Stops error handler and stdout buffering.
+     */
+    private function stopErrorAndOutputBuffering()
+    {
+        if ($this->obStarted) {
+            ob_end_clean();
+        }
+        restore_error_handler();
+    }
+
+    /**
+     * Checks if provided error level is not reportable.
+     *
+     * @param integer $level
+     *
+     * @return Boolean
+     */
+    private function errorLevelIsNotReportable($level)
+    {
+        return !(error_reporting() & $level);
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Call/RuntimeCallee.php b/vendor/behat/behat/src/Behat/Testwork/Call/RuntimeCallee.php
new file mode 100644 (file)
index 0000000..c764629
--- /dev/null
@@ -0,0 +1,132 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Call;
+
+use Behat\Testwork\Call\Exception\BadCallbackException;
+use ReflectionFunction;
+use ReflectionFunctionAbstract;
+use ReflectionMethod;
+
+/**
+ * Represents callee created and executed in the runtime.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class RuntimeCallee implements Callee
+{
+    /**
+     * @var callable
+     */
+    private $callable;
+    /**
+     * @var null|string
+     */
+    private $description;
+    /**
+     * @var ReflectionFunctionAbstract
+     */
+    private $reflection;
+    /**
+     * @var string
+     */
+    private $path;
+
+    /**
+     * Initializes callee.
+     *
+     * @param callable    $callable
+     * @param null|string $description
+     *
+     * @throws BadCallbackException If invalid callback provided
+     */
+    public function __construct($callable, $description = null)
+    {
+        if (!is_array($callable) && !is_callable($callable)) {
+            throw new BadCallbackException(sprintf(
+                '%s expects a valid callable, but `%s` given',
+                get_class($this),
+                gettype($callable)
+            ), $callable);
+        }
+
+        if (is_array($callable)) {
+            $this->reflection = new ReflectionMethod($callable[0], $callable[1]);
+            $this->path = $callable[0] . '::' . $callable[1] . '()';
+        } else {
+            $this->reflection = new ReflectionFunction($callable);
+            $this->path = $this->reflection->getFileName() . ':' . $this->reflection->getStartLine();
+        }
+
+        $this->callable = $callable;
+        $this->description = $description;
+    }
+
+    /**
+     * Returns callee description.
+     *
+     * @return string
+     */
+    public function getDescription()
+    {
+        return $this->description;
+    }
+
+    /**
+     * Returns callee definition path.
+     *
+     * @return string
+     */
+    public function getPath()
+    {
+        return $this->path;
+    }
+
+    /**
+     * Returns callable.
+     *
+     * @return callable
+     */
+    public function getCallable()
+    {
+        return $this->callable;
+    }
+
+    /**
+     * Returns callable reflection.
+     *
+     * @return ReflectionFunctionAbstract
+     */
+    public function getReflection()
+    {
+        return $this->reflection;
+    }
+
+    /**
+     * Returns true if callee is a method, false otherwise.
+     *
+     * @return Boolean
+     */
+    public function isAMethod()
+    {
+        return $this->reflection instanceof ReflectionMethod;
+    }
+
+    /**
+     * Returns true if callee is an instance (non-static) method, false otherwise.
+     *
+     * @return Boolean
+     */
+    public function isAnInstanceMethod()
+    {
+        return $this->reflection instanceof ReflectionMethod
+            && !$this->reflection->isStatic();
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Call/ServiceContainer/CallExtension.php b/vendor/behat/behat/src/Behat/Testwork/Call/ServiceContainer/CallExtension.php
new file mode 100644 (file)
index 0000000..b9df7ea
--- /dev/null
@@ -0,0 +1,189 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Call\ServiceContainer;
+
+use Behat\Testwork\ServiceContainer\Extension;
+use Behat\Testwork\ServiceContainer\ExtensionManager;
+use Behat\Testwork\ServiceContainer\ServiceProcessor;
+use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Definition;
+
+/**
+ * Provides call services for testwork.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class CallExtension implements Extension
+{
+    /*
+     * Available services
+     */
+    const CALL_CENTER_ID = 'call.center';
+
+    /*
+     * Available extension points
+     */
+    const CALL_FILTER_TAG = 'call.call_filter';
+    const CALL_HANDLER_TAG = 'call.call_handler';
+    const RESULT_FILTER_TAG = 'call.result_filter';
+    const EXCEPTION_HANDLER_TAG = 'call.exception_handler';
+
+    /**
+     * @var ServiceProcessor
+     */
+    private $processor;
+
+    /**
+     * Initializes extension.
+     *
+     * @param null|ServiceProcessor $processor
+     */
+    public function __construct(ServiceProcessor $processor = null)
+    {
+        $this->processor = $processor ? : new ServiceProcessor();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getConfigKey()
+    {
+        return 'calls';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function initialize(ExtensionManager $extensionManager)
+    {
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function configure(ArrayNodeDefinition $builder)
+    {
+        $builder
+            ->addDefaultsIfNotSet()
+            ->children()
+                ->scalarNode('error_reporting')
+                    ->info('Call executor will catch exceptions matching this level')
+                    ->defaultValue(E_ALL | E_STRICT)
+                ->end()
+            ->end()
+        ;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function load(ContainerBuilder $container, array $config)
+    {
+        $this->loadCallCenter($container);
+        $this->loadCallHandlers($container, $config['error_reporting']);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function process(ContainerBuilder $container)
+    {
+        $this->processCallFilters($container);
+        $this->processCallHandlers($container);
+        $this->processResultFilters($container);
+        $this->processExceptionHandlers($container);
+    }
+
+    /**
+     * Loads call center service.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function loadCallCenter(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Testwork\Call\CallCenter');
+        $container->setDefinition(self::CALL_CENTER_ID, $definition);
+    }
+
+    /**
+     * Loads prebuilt call handlers.
+     *
+     * @param ContainerBuilder $container
+     * @param integer          $errorReporting
+     */
+    protected function loadCallHandlers(ContainerBuilder $container, $errorReporting)
+    {
+        $definition = new Definition('Behat\Testwork\Call\Handler\RuntimeCallHandler', array($errorReporting));
+        $definition->addTag(self::CALL_HANDLER_TAG, array('priority' => 50));
+        $container->setDefinition(self::CALL_HANDLER_TAG . '.runtime', $definition);
+    }
+
+    /**
+     * Registers all call filters to the CallCenter.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function processCallFilters(ContainerBuilder $container)
+    {
+        $references = $this->processor->findAndSortTaggedServices($container, CallExtension::CALL_FILTER_TAG);
+        $definition = $container->getDefinition(CallExtension::CALL_CENTER_ID);
+
+        foreach ($references as $reference) {
+            $definition->addMethodCall('registerCallFilter', array($reference));
+        }
+    }
+
+    /**
+     * Registers all call handlers to the CallCenter.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function processCallHandlers(ContainerBuilder $container)
+    {
+        $references = $this->processor->findAndSortTaggedServices($container, CallExtension::CALL_HANDLER_TAG);
+        $definition = $container->getDefinition(CallExtension::CALL_CENTER_ID);
+
+        foreach ($references as $reference) {
+            $definition->addMethodCall('registerCallHandler', array($reference));
+        }
+    }
+
+    /**
+     * Registers all call result filters to the CallCenter.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function processResultFilters(ContainerBuilder $container)
+    {
+        $references = $this->processor->findAndSortTaggedServices($container, CallExtension::RESULT_FILTER_TAG);
+        $definition = $container->getDefinition(CallExtension::CALL_CENTER_ID);
+
+        foreach ($references as $reference) {
+            $definition->addMethodCall('registerResultFilter', array($reference));
+        }
+    }
+
+    /**
+     * Registers all exception handlers to the CallCenter.
+     *
+     * @param ContainerBuilder $container
+     */
+    private function processExceptionHandlers(ContainerBuilder $container)
+    {
+        $references = $this->processor->findAndSortTaggedServices($container, CallExtension::EXCEPTION_HANDLER_TAG);
+        $definition = $container->getDefinition(CallExtension::CALL_CENTER_ID);
+
+        foreach ($references as $reference) {
+            $definition->addMethodCall('registerExceptionHandler', array($reference));
+        }
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Cli/Application.php b/vendor/behat/behat/src/Behat/Testwork/Cli/Application.php
new file mode 100644 (file)
index 0000000..4189224
--- /dev/null
@@ -0,0 +1,236 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Cli;
+
+use Behat\Testwork\ServiceContainer\Configuration\ConfigurationLoader;
+use Behat\Testwork\ServiceContainer\ContainerLoader;
+use Behat\Testwork\ServiceContainer\Exception\ConfigurationLoadingException;
+use Behat\Testwork\ServiceContainer\ExtensionManager;
+use Symfony\Component\Console\Application as BaseApplication;
+use Symfony\Component\Console\Command\Command as SymfonyCommand;
+use Symfony\Component\Console\Input\ArrayInput;
+use Symfony\Component\Console\Input\InputDefinition;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Extends Symfony console application with testwork functionality.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class Application extends BaseApplication
+{
+    /**
+     * @var ConfigurationLoader
+     */
+    private $configurationLoader;
+    /**
+     * @var ExtensionManager
+     */
+    private $extensionManager;
+
+    /**
+     * Initializes application.
+     *
+     * @param string              $name
+     * @param string              $version
+     * @param ConfigurationLoader $configLoader
+     * @param ExtensionManager    $extensionManager
+     */
+    public function __construct($name, $version, ConfigurationLoader $configLoader, ExtensionManager $extensionManager)
+    {
+        putenv('COLUMNS=9999');
+
+        $this->configurationLoader = $configLoader;
+        $this->extensionManager = $extensionManager;
+
+        parent::__construct($name, $version);
+    }
+
+    /**
+     * Gets the default input definition.
+     *
+     * @return InputDefinition An InputDefinition instance
+     */
+    public function getDefaultInputDefinition()
+    {
+        return new InputDefinition(array(
+            new InputOption('--profile', '-p', InputOption::VALUE_REQUIRED, 'Specify config profile to use.'),
+            new InputOption('--config', '-c', InputOption::VALUE_REQUIRED, 'Specify config file to use.'),
+            new InputOption(
+                '--verbose', '-v', InputOption::VALUE_OPTIONAL,
+                'Increase verbosity of exceptions.' . PHP_EOL .
+                'Use -vv or --verbose=2 to display backtraces in addition to exceptions.'
+            ),
+            new InputOption('--help', '-h', InputOption::VALUE_NONE, 'Display this help message.'),
+            new InputOption('--config-reference', null, InputOption::VALUE_NONE, 'Display the configuration reference.'),
+            new InputOption('--debug', null, InputOption::VALUE_NONE, 'Provide debugging information about current environment.'),
+            new InputOption('--version', '-V', InputOption::VALUE_NONE, 'Display version.'),
+            new InputOption('--no-interaction', '-n', InputOption::VALUE_NONE, 'Do not ask any interactive question.'),
+            new InputOption(
+                '--colors', null, InputOption::VALUE_NONE,
+                'Force ANSI color in the output. By default color support is' . PHP_EOL .
+                'guessed based on your platform and the output if not specified.'
+            ),
+            new InputOption('--no-colors', null, InputOption::VALUE_NONE, 'Force no ANSI color in the output.'),
+        ));
+    }
+
+    /**
+     * Runs the current application.
+     *
+     * @param InputInterface  $input  An Input instance
+     * @param OutputInterface $output An Output instance
+     *
+     * @return integer 0 if everything went fine, or an error code
+     */
+    public function doRun(InputInterface $input, OutputInterface $output)
+    {
+        // xdebug's default nesting level of 100 is not enough
+        if (extension_loaded('xdebug')
+            && false === strpos(ini_get('disable_functions'), 'ini_set')
+        ) {
+            $oldValue = ini_get('xdebug.max_nesting_level');
+            if ($oldValue === false || $oldValue < 256) {
+                ini_set('xdebug.max_nesting_level', 256);
+            }
+        }
+
+        if ($input->hasParameterOption(array('--config-reference'))) {
+            $input = new ArrayInput(array('--config-reference' => true));
+        }
+
+        if ($path = $input->getParameterOption(array('--config', '-c'))) {
+            if (!is_file($path)) {
+                throw new ConfigurationLoadingException("The requested config file does not exist");
+            }
+
+            $this->configurationLoader->setConfigurationFilePath($path);
+        }
+
+        $this->add($this->createCommand($input, $output));
+
+        return parent::doRun($input, $output);
+    }
+
+    protected function getDefaultCommands()
+    {
+        $commands = parent::getDefaultCommands();
+
+        $commands[] = new DumpReferenceCommand($this->extensionManager);
+        $commands[] = new DebugCommand($this, $this->configurationLoader, $this->extensionManager);
+
+        return $commands;
+    }
+
+    /**
+     * Configures container based on provided config file and profile.
+     *
+     * @param InputInterface $input
+     *
+     * @return array
+     */
+    private function loadConfiguration(InputInterface $input)
+    {
+        $profile = $input->getParameterOption(array('--profile', '-p')) ? : 'default';
+
+        return $this->configurationLoader->loadConfiguration($profile);
+    }
+
+    /**
+     * Creates main command for application.
+     *
+     * @param InputInterface  $input
+     * @param OutputInterface $output
+     *
+     * @return SymfonyCommand
+     */
+    private function createCommand(InputInterface $input, OutputInterface $output)
+    {
+        return $this->createContainer($input, $output)->get('cli.command');
+    }
+
+    /**
+     * Creates container instance, loads extensions and freezes it.
+     *
+     * @param InputInterface  $input
+     * @param OutputInterface $output
+     *
+     * @return ContainerInterface
+     */
+    private function createContainer(InputInterface $input, OutputInterface $output)
+    {
+        $basePath = rtrim($this->getBasePath(), DIRECTORY_SEPARATOR);
+
+        $container = new ContainerBuilder();
+
+        $container->setParameter('cli.command.name', $this->getName());
+        $container->setParameter('paths.base', $basePath);
+
+        $container->set('cli.input', $input);
+        $container->set('cli.output', $output);
+
+        $extension = new ContainerLoader($this->extensionManager);
+        $extension->load($container, $this->loadConfiguration($input));
+        $container->addObjectResource($extension);
+        $container->compile(true);
+
+        return $container;
+    }
+
+    /**
+     * Returns base path.
+     *
+     * @return string
+     */
+    private function getBasePath()
+    {
+        if ($configPath = $this->configurationLoader->getConfigurationFilePath()) {
+            return realpath(dirname($configPath));
+        }
+
+        return realpath(getcwd());
+    }
+
+    /**
+     * Gets the name of the command based on input.
+     *
+     * @param InputInterface $input The input interface
+     *
+     * @return string The command name
+     */
+    protected function getCommandName(InputInterface $input)
+    {
+        if ($input->hasParameterOption(array('--config-reference'))) {
+            return 'dump-reference';
+        }
+
+        if ($input->hasParameterOption(array('--debug'))) {
+            return 'debug';
+        }
+
+        return $this->getName();
+    }
+
+    protected function configureIO(InputInterface $input, OutputInterface $output)
+    {
+        if (true === $input->hasParameterOption(array('--colors'))) {
+            $output->setDecorated(true);
+        } elseif (true === $input->hasParameterOption(array('--no-colors'))) {
+            $output->setDecorated(false);
+        }
+
+        parent::configureIO($input, $output);
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Cli/Command.php b/vendor/behat/behat/src/Behat/Testwork/Cli/Command.php
new file mode 100644 (file)
index 0000000..ae53dfa
--- /dev/null
@@ -0,0 +1,70 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Cli;
+
+use Symfony\Component\Console\Command\Command as BaseCommand;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * Extends Symfony console command with a controller-based delegation.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class Command extends BaseCommand
+{
+    /**
+     * @var Controller[]
+     */
+    private $controllers = array();
+
+    /**
+     * Initializes command.
+     *
+     * @param string       $commandName
+     * @param Controller[] $controllers
+     */
+    public function __construct($commandName, array $controllers)
+    {
+        $this->controllers = $controllers;
+
+        parent::__construct($commandName);
+    }
+
+    /**
+     * Configures the command by running controllers prepare().
+     */
+    protected function configure()
+    {
+        foreach ($this->controllers as $controller) {
+            $controller->configure($this);
+        }
+    }
+
+    /**
+     * Executes the current command by executing all controllers action().
+     *
+     * @param InputInterface  $input  An InputInterface instance
+     * @param OutputInterface $output An OutputInterface instance
+     *
+     * @return integer Return code of one of the processors or 0 if none of them returned integer
+     */
+    protected function execute(InputInterface $input, OutputInterface $output)
+    {
+        foreach ($this->controllers as $controller) {
+            if (is_int($return = $controller->execute($input, $output))) {
+                return $return;
+            }
+        }
+
+        return 0;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Cli/Controller.php b/vendor/behat/behat/src/Behat/Testwork/Cli/Controller.php
new file mode 100644 (file)
index 0000000..e604d67
--- /dev/null
@@ -0,0 +1,42 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Cli;
+
+use Symfony\Component\Console\Command\Command as SymfonyCommand;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * Represents Testwork Console Controller.
+ *
+ * All testwork console controllers should implement this interface.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface Controller
+{
+    /**
+     * Configures command to be executable by the controller.
+     *
+     * @param SymfonyCommand $command
+     */
+    public function configure(SymfonyCommand $command);
+
+    /**
+     * Executes controller.
+     *
+     * @param InputInterface  $input
+     * @param OutputInterface $output
+     *
+     * @return null|integer
+     */
+    public function execute(InputInterface $input, OutputInterface $output);
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Cli/DebugCommand.php b/vendor/behat/behat/src/Behat/Testwork/Cli/DebugCommand.php
new file mode 100644 (file)
index 0000000..d888cb9
--- /dev/null
@@ -0,0 +1,80 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Cli;
+
+use Behat\Testwork\ServiceContainer\Configuration\ConfigurationLoader;
+use Behat\Testwork\ServiceContainer\ExtensionManager;
+use Symfony\Component\Console\Command\Command as BaseCommand;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * Provides debug information about the current environment.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class DebugCommand extends BaseCommand
+{
+    /**
+     * @var Application
+     */
+    private $application;
+    /**
+     * @var ConfigurationLoader
+     */
+    private $configurationLoader;
+    /**
+     * @var ExtensionManager
+     */
+    private $extensionManager;
+
+    /**
+     * Initialises command.
+     *
+     * @param Application         $application
+     * @param ConfigurationLoader $configurationLoader
+     * @param ExtensionManager    $extensionManager
+     */
+    public function __construct(
+        Application $application,
+        ConfigurationLoader $configurationLoader,
+        ExtensionManager $extensionManager
+    ) {
+        $this->application = $application;
+        $this->configurationLoader = $configurationLoader;
+        $this->extensionManager = $extensionManager;
+
+        parent::__construct('debug');
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function execute(InputInterface $input, OutputInterface $output)
+    {
+        $output->writeln(sprintf('%s version %s', $this->application->getName(), $this->application->getVersion()));
+
+        $output->writeln('');
+
+        $debug = $this->configurationLoader->debugInformation();
+        $output->writeln('--- configuration');
+        $output->writeln(sprintf('    environment variable (%s): %s', $debug['environment_variable_name'], $debug['environment_variable_content']));
+        $output->writeln(sprintf('    configuration file: %s', $debug['configuration_file_path']));
+
+        $output->writeln('');
+
+        $debug = $this->extensionManager->debugInformation();
+        $output->writeln('--- extensions');
+        $output->writeln(sprintf('    extensions loaded: %s', count($debug['extensions_list']) ? implode(', ', $debug['extensions_list']) : 'none'));
+
+        $output->writeln('');
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Cli/DumpReferenceCommand.php b/vendor/behat/behat/src/Behat/Testwork/Cli/DumpReferenceCommand.php
new file mode 100644 (file)
index 0000000..d6b57d4
--- /dev/null
@@ -0,0 +1,61 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Cli;
+
+use Behat\Testwork\ServiceContainer\Configuration\ConfigurationTree;
+use Behat\Testwork\ServiceContainer\ExtensionManager;
+use Symfony\Component\Config\Definition\Dumper\YamlReferenceDumper;
+use Symfony\Component\Config\Definition\ReferenceDumper;
+use Symfony\Component\Console\Command\Command as BaseCommand;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * Extends Symfony console application with testwork functionality.
+ *
+ * @author Christophe Coevoet <stof>
+ */
+final class DumpReferenceCommand extends BaseCommand
+{
+    /**
+     * @var ExtensionManager
+     */
+    private $extensionManager;
+
+    /**
+     * Initializes dumper.
+     *
+     * @param ExtensionManager $extensionManager
+     */
+    public function __construct(ExtensionManager $extensionManager)
+    {
+        $this->extensionManager = $extensionManager;
+
+        parent::__construct('dump-reference');
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function execute(InputInterface $input, OutputInterface $output)
+    {
+        if (class_exists('Symfony\Component\Config\Definition\Dumper\YamlReferenceDumper')) {
+            $dumper = new YamlReferenceDumper();
+        } else {
+            // Support Symfony Config 2.3
+            $dumper = new ReferenceDumper();
+        }
+
+        $configTree = new ConfigurationTree();
+
+        $output->writeln($dumper->dumpNode($configTree->getConfigTree($this->extensionManager->getExtensions())));
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Cli/ServiceContainer/CliExtension.php b/vendor/behat/behat/src/Behat/Testwork/Cli/ServiceContainer/CliExtension.php
new file mode 100644 (file)
index 0000000..4b9fba8
--- /dev/null
@@ -0,0 +1,115 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Cli\ServiceContainer;
+
+use Behat\Testwork\ServiceContainer\Extension;
+use Behat\Testwork\ServiceContainer\ExtensionManager;
+use Behat\Testwork\ServiceContainer\ServiceProcessor;
+use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Definition;
+
+/**
+ * Provides console services for testwork.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class CliExtension implements Extension
+{
+    /*
+     * Available services
+     */
+    const COMMAND_ID = 'cli.command';
+    const INPUT_ID = 'cli.input';
+    const OUTPUT_ID = 'cli.output';
+
+    /*
+     * Available extension points
+     */
+    const CONTROLLER_TAG = 'cli.controller';
+
+    /**
+     * @var ServiceProcessor
+     */
+    private $processor;
+
+    /**
+     * Initializes extension.
+     *
+     * @param null|ServiceProcessor $processor
+     */
+    public function __construct(ServiceProcessor $processor = null)
+    {
+        $this->processor = $processor ?: new ServiceProcessor();
+    }
+
+    /**
+     * Returns the extension config key.
+     *
+     * @return string
+     */
+    public function getConfigKey()
+    {
+        return 'cli';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function initialize(ExtensionManager $extensionManager)
+    {
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function configure(ArrayNodeDefinition $builder)
+    {
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function load(ContainerBuilder $container, array $config)
+    {
+        $this->loadCommand($container);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function process(ContainerBuilder $container)
+    {
+        $this->processControllers($container);
+    }
+
+    /**
+     * Loads application command.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function loadCommand(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Testwork\Cli\Command', array('%cli.command.name%', array()));
+        $container->setDefinition(self::COMMAND_ID, $definition);
+    }
+
+    /**
+     * Processes all controllers in container.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function processControllers(ContainerBuilder $container)
+    {
+        $references = $this->processor->findAndSortTaggedServices($container, self::CONTROLLER_TAG);
+        $container->getDefinition(self::COMMAND_ID)->replaceArgument(1, $references);
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Counter/Exception/TimerException.php b/vendor/behat/behat/src/Behat/Testwork/Counter/Exception/TimerException.php
new file mode 100644 (file)
index 0000000..72238fd
--- /dev/null
@@ -0,0 +1,23 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Counter\Exception;
+
+use Behat\Testwork\Exception\TestworkException;
+use LogicException;
+
+/**
+ * Represents exception caused by timer handling.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class TimerException extends LogicException implements TestworkException
+{
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Counter/Memory.php b/vendor/behat/behat/src/Behat/Testwork/Counter/Memory.php
new file mode 100644 (file)
index 0000000..f7d8605
--- /dev/null
@@ -0,0 +1,62 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Counter;
+
+/**
+ * Counts amount of system memory being used.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class Memory
+{
+    /**
+     * @var string[]
+     */
+    private $units = array('B', 'Kb', 'Mb', 'Gb', 'Tb');
+
+    /**
+     * Returns current memory usage.
+     *
+     * @return integer
+     */
+    public function getMemoryUsage()
+    {
+        return memory_get_usage();
+    }
+
+    /**
+     * Presents memory usage in human-readable form.
+     *
+     * @return string
+     */
+    public function __toString()
+    {
+        return $this->humanize($this->getMemoryUsage());
+    }
+
+    /**
+     * Humanizes usage information.
+     *
+     * @param integer $bytes
+     *
+     * @return string
+     */
+    private function humanize($bytes)
+    {
+        $e = intval(floor(log($bytes) / log(1024)));
+
+        if (!isset($this->units[$e])) {
+            return 'Can not calculate memory usage';
+        }
+
+        return sprintf('%.2f%s', ($bytes / pow(1024, floor($e))), $this->units[$e]);
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Counter/Timer.php b/vendor/behat/behat/src/Behat/Testwork/Counter/Timer.php
new file mode 100644 (file)
index 0000000..65025a3
--- /dev/null
@@ -0,0 +1,105 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Counter;
+
+use Behat\Testwork\Counter\Exception\TimerException;
+
+/**
+ * Provides time counting functionality.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class Timer
+{
+    /**
+     * @var null|float
+     */
+    private $starTime;
+    /**
+     * @var null|float
+     */
+    private $stopTime;
+
+    /**
+     * Starts timer.
+     */
+    public function start()
+    {
+        $this->starTime = microtime(true);
+    }
+
+    /**
+     * Stops timer.
+     *
+     * @throws TimerException If timer has not been started
+     */
+    public function stop()
+    {
+        if (!$this->starTime) {
+            throw new TimerException('You can not stop timer that has not been started.');
+        }
+
+        $this->stopTime = microtime(true);
+    }
+
+    /**
+     * @return null|float
+     *
+     * @throws TimerException If timer has not been started
+     */
+    public function getTime()
+    {
+        if (!$this->starTime) {
+            throw new TimerException('You can not get time from timer that never been started.');
+        }
+
+        $stopTime = $this->stopTime;
+        if (!$this->stopTime) {
+            $stopTime = microtime(true);
+        }
+
+        return $stopTime - $this->starTime;
+    }
+
+    /**
+     * Returns number of minutes passed.
+     *
+     * @return integer
+     */
+    public function getMinutes()
+    {
+        return intval(floor($this->getTime() / 60));
+    }
+
+    /**
+     * Returns number of seconds passed.
+     *
+     * @return float
+     */
+    public function getSeconds()
+    {
+        return round($this->getTime() - ($this->getMinutes() * 60), 3);
+    }
+
+    /**
+     * Returns string representation of time passed.
+     *
+     * @return string
+     */
+    public function __toString()
+    {
+        if (!$this->starTime || !$this->stopTime) {
+            return '0m0s';
+        }
+
+        return sprintf('%dm%.2fs', $this->getMinutes(), $this->getSeconds());
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Environment/Call/EnvironmentCall.php b/vendor/behat/behat/src/Behat/Testwork/Environment/Call/EnvironmentCall.php
new file mode 100644 (file)
index 0000000..39d34f7
--- /dev/null
@@ -0,0 +1,102 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Environment\Call;
+
+use Behat\Testwork\Call\Call;
+use Behat\Testwork\Call\Callee;
+use Behat\Testwork\Environment\Environment;
+
+/**
+ * Represents environment-based call.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class EnvironmentCall implements Call
+{
+    /**
+     * @var Environment
+     */
+    private $environment;
+    /**
+     * @var Callee
+     */
+    private $callee;
+    /**
+     * @var array
+     */
+    private $arguments;
+    /**
+     * @var null|integer
+     */
+    private $errorReportingLevel;
+
+    /**
+     * Initializes call.
+     *
+     * @param Environment  $environment
+     * @param Callee       $callee
+     * @param array        $arguments
+     * @param null|integer $errorReportingLevel
+     */
+    public function __construct(
+        Environment $environment,
+        Callee $callee,
+        array $arguments,
+        $errorReportingLevel = null
+    ) {
+        $this->environment = $environment;
+        $this->callee = $callee;
+        $this->arguments = $arguments;
+        $this->errorReportingLevel = $errorReportingLevel;
+    }
+
+    /**
+     * Returns environment this call is executed from.
+     *
+     * @return Environment
+     */
+    final public function getEnvironment()
+    {
+        return $this->environment;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    final public function getCallee()
+    {
+        return $this->callee;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    final public function getBoundCallable()
+    {
+        return $this->environment->bindCallee($this->callee);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    final public function getArguments()
+    {
+        return $this->arguments;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    final public function getErrorReportingLevel()
+    {
+        return $this->errorReportingLevel;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Environment/Environment.php b/vendor/behat/behat/src/Behat/Testwork/Environment/Environment.php
new file mode 100644 (file)
index 0000000..0850015
--- /dev/null
@@ -0,0 +1,38 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Environment;
+
+use Behat\Testwork\Call\Callee;
+use Behat\Testwork\Suite\Suite;
+
+/**
+ * Represents Testwork test environment.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface Environment
+{
+    /**
+     * Returns environment suite.
+     *
+     * @return Suite
+     */
+    public function getSuite();
+
+    /**
+     * Creates callable using provided Callee.
+     *
+     * @param Callee $callee
+     *
+     * @return callable
+     */
+    public function bindCallee(Callee $callee);
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Environment/EnvironmentManager.php b/vendor/behat/behat/src/Behat/Testwork/Environment/EnvironmentManager.php
new file mode 100644 (file)
index 0000000..b1dda50
--- /dev/null
@@ -0,0 +1,121 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Environment;
+
+use Behat\Testwork\Call\Callee;
+use Behat\Testwork\Environment\Exception\EnvironmentBuildException;
+use Behat\Testwork\Environment\Exception\EnvironmentIsolationException;
+use Behat\Testwork\Environment\Handler\EnvironmentHandler;
+use Behat\Testwork\Environment\Reader\EnvironmentReader;
+use Behat\Testwork\Suite\Suite;
+
+/**
+ * Builds, isolates and reads environments using registered handlers and readers.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class EnvironmentManager
+{
+    /**
+     * @var EnvironmentHandler[]
+     */
+    private $handlers = array();
+    /**
+     * @var EnvironmentReader[]
+     */
+    private $readers = array();
+
+    /**
+     * Registers environment handler.
+     *
+     * @param EnvironmentHandler $handler
+     */
+    public function registerEnvironmentHandler(EnvironmentHandler $handler)
+    {
+        $this->handlers[] = $handler;
+    }
+
+    /**
+     * Registers environment reader.
+     *
+     * @param EnvironmentReader $reader
+     */
+    public function registerEnvironmentReader(EnvironmentReader $reader)
+    {
+        $this->readers[] = $reader;
+    }
+
+    /**
+     * Builds new environment for provided test suite.
+     *
+     * @param Suite $suite
+     *
+     * @return Environment
+     *
+     * @throws EnvironmentBuildException
+     */
+    public function buildEnvironment(Suite $suite)
+    {
+        foreach ($this->handlers as $handler) {
+            if ($handler->supportsSuite($suite)) {
+                return $handler->buildEnvironment($suite);
+            }
+        }
+
+        throw new EnvironmentBuildException(sprintf(
+            'None of the registered environment handlers seem to support `%s` suite.',
+            $suite->getName()
+        ), $suite);
+    }
+
+    /**
+     * Creates new isolated test environment using built one.
+     *
+     * @param Environment $environment
+     * @param mixed       $testSubject
+     *
+     * @return Environment
+     *
+     * @throws EnvironmentIsolationException If appropriate environment handler is not found
+     */
+    public function isolateEnvironment(Environment $environment, $testSubject = null)
+    {
+        foreach ($this->handlers as $handler) {
+            if ($handler->supportsEnvironmentAndSubject($environment, $testSubject)) {
+                return $handler->isolateEnvironment($environment, $testSubject);
+            }
+        }
+
+        throw new EnvironmentIsolationException(sprintf(
+            'None of the registered environment handlers seem to support `%s` environment.',
+            get_class($environment)
+        ), $environment, $testSubject);
+    }
+
+    /**
+     * Reads all callees from environment using registered environment readers.
+     *
+     * @param Environment $environment
+     *
+     * @return Callee[]
+     */
+    public function readEnvironmentCallees(Environment $environment)
+    {
+        $callees = array();
+        foreach ($this->readers as $reader) {
+            if ($reader->supportsEnvironment($environment)) {
+                $callees = array_merge($callees, $reader->readEnvironmentCallees($environment));
+            }
+        }
+
+        return $callees;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Environment/Exception/EnvironmentBuildException.php b/vendor/behat/behat/src/Behat/Testwork/Environment/Exception/EnvironmentBuildException.php
new file mode 100644 (file)
index 0000000..4c3bb92
--- /dev/null
@@ -0,0 +1,50 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Environment\Exception;
+
+use Behat\Testwork\Suite\Suite;
+use RuntimeException;
+
+/**
+ * Represents exception thrown during an environment build process.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class EnvironmentBuildException extends RuntimeException implements EnvironmentException
+{
+    /**
+     * @var Suite
+     */
+    private $suite;
+
+    /**
+     * Initializes exception.
+     *
+     * @param string $message
+     * @param Suite  $suite
+     */
+    public function __construct($message, Suite $suite)
+    {
+        $this->suite = $suite;
+
+        parent::__construct($message);
+    }
+
+    /**
+     * Returns suite that caused exception.
+     *
+     * @return Suite
+     */
+    public function getSuite()
+    {
+        return $this->suite;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Environment/Exception/EnvironmentException.php b/vendor/behat/behat/src/Behat/Testwork/Environment/Exception/EnvironmentException.php
new file mode 100644 (file)
index 0000000..4b8579f
--- /dev/null
@@ -0,0 +1,22 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Environment\Exception;
+
+use Behat\Testwork\Exception\TestworkException;
+
+/**
+ * All environment exceptions should implement this interface.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface EnvironmentException extends TestworkException
+{
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Environment/Exception/EnvironmentIsolationException.php b/vendor/behat/behat/src/Behat/Testwork/Environment/Exception/EnvironmentIsolationException.php
new file mode 100644 (file)
index 0000000..6f517ae
--- /dev/null
@@ -0,0 +1,66 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Environment\Exception;
+
+use Behat\Testwork\Environment\Environment;
+use RuntimeException;
+
+/**
+ * Represents exception thrown during environment isolation process.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class EnvironmentIsolationException extends RuntimeException implements EnvironmentException
+{
+    /**
+     * @var Environment
+     */
+    private $environment;
+    /**
+     * @var mixed
+     */
+    private $subject;
+
+    /**
+     * Initializes exception.
+     *
+     * @param string      $message
+     * @param Environment $environment
+     * @param mixed       $testSubject
+     */
+    public function __construct($message, Environment $environment, $testSubject = null)
+    {
+        $this->environment = $environment;
+        $this->subject = $testSubject;
+
+        parent::__construct($message);
+    }
+
+    /**
+     * Returns environment that caused exception.
+     *
+     * @return Environment
+     */
+    public function getEnvironment()
+    {
+        return $this->environment;
+    }
+
+    /**
+     * Returns test subject that caused exception.
+     *
+     * @return mixed
+     */
+    public function getSubject()
+    {
+        return $this->subject;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Environment/Exception/EnvironmentReadException.php b/vendor/behat/behat/src/Behat/Testwork/Environment/Exception/EnvironmentReadException.php
new file mode 100644 (file)
index 0000000..07ed513
--- /dev/null
@@ -0,0 +1,50 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Environment\Exception;
+
+use Behat\Testwork\Environment\Environment;
+use RuntimeException;
+
+/**
+ * Represents exception thrown during an environment read.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class EnvironmentReadException extends RuntimeException implements EnvironmentException
+{
+    /**
+     * @var Environment
+     */
+    private $environment;
+
+    /**
+     * Initializes exception.
+     *
+     * @param string      $message
+     * @param Environment $environment
+     */
+    public function __construct($message, Environment $environment)
+    {
+        $this->environment = $environment;
+
+        parent::__construct($message);
+    }
+
+    /**
+     * Returns environment that caused exception.
+     *
+     * @return Environment
+     */
+    public function getEnvironment()
+    {
+        return $this->environment;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Environment/Handler/EnvironmentHandler.php b/vendor/behat/behat/src/Behat/Testwork/Environment/Handler/EnvironmentHandler.php
new file mode 100644 (file)
index 0000000..f2b6b98
--- /dev/null
@@ -0,0 +1,63 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Environment\Handler;
+
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\Environment\EnvironmentManager;
+use Behat\Testwork\Suite\Suite;
+
+/**
+ * Handles test environment building and isolation.
+ *
+ * @see EnvironmentManager
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface EnvironmentHandler
+{
+    /**
+     * Checks if handler supports provided suite.
+     *
+     * @param Suite $suite
+     *
+     * @return Boolean
+     */
+    public function supportsSuite(Suite $suite);
+
+    /**
+     * Builds environment object based on provided suite.
+     *
+     * @param Suite $suite
+     *
+     * @return Environment
+     */
+    public function buildEnvironment(Suite $suite);
+
+    /**
+     * Checks if handler supports provided environment.
+     *
+     * @param Environment $environment
+     * @param mixed       $testSubject
+     *
+     * @return Boolean
+     */
+    public function supportsEnvironmentAndSubject(Environment $environment, $testSubject = null);
+
+    /**
+     * Isolates provided environment.
+     *
+     * @param Environment $environment
+     * @param mixed       $testSubject
+     *
+     * @return Environment
+     */
+    public function isolateEnvironment(Environment $environment, $testSubject = null);
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Environment/Handler/StaticEnvironmentHandler.php b/vendor/behat/behat/src/Behat/Testwork/Environment/Handler/StaticEnvironmentHandler.php
new file mode 100644 (file)
index 0000000..6b399cc
--- /dev/null
@@ -0,0 +1,55 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Environment\Handler;
+
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\Environment\StaticEnvironment;
+use Behat\Testwork\Suite\Suite;
+
+/**
+ * Represents environment handler based on static calls (without any isolation).
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class StaticEnvironmentHandler implements EnvironmentHandler
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function supportsSuite(Suite $suite)
+    {
+        return true;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function buildEnvironment(Suite $suite)
+    {
+        return new StaticEnvironment($suite);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function supportsEnvironmentAndSubject(Environment $environment, $testSubject = null)
+    {
+        return $environment instanceof StaticEnvironment;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function isolateEnvironment(Environment $environment, $testSubject = null)
+    {
+        return $environment;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Environment/Reader/EnvironmentReader.php b/vendor/behat/behat/src/Behat/Testwork/Environment/Reader/EnvironmentReader.php
new file mode 100644 (file)
index 0000000..dcf66fd
--- /dev/null
@@ -0,0 +1,43 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Environment\Reader;
+
+use Behat\Testwork\Call\Callee;
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\Environment\EnvironmentManager;
+
+/**
+ * Reads callees from a provided environment.
+ *
+ * @see EnvironmentManager
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface EnvironmentReader
+{
+    /**
+     * Checks if reader supports an environment.
+     *
+     * @param Environment $environment
+     *
+     * @return Boolean
+     */
+    public function supportsEnvironment(Environment $environment);
+
+    /**
+     * Reads callees from an environment.
+     *
+     * @param Environment $environment
+     *
+     * @return Callee[]
+     */
+    public function readEnvironmentCallees(Environment $environment);
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Environment/ServiceContainer/EnvironmentExtension.php b/vendor/behat/behat/src/Behat/Testwork/Environment/ServiceContainer/EnvironmentExtension.php
new file mode 100644 (file)
index 0000000..e06f058
--- /dev/null
@@ -0,0 +1,147 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Environment\ServiceContainer;
+
+use Behat\Testwork\ServiceContainer\Extension;
+use Behat\Testwork\ServiceContainer\ExtensionManager;
+use Behat\Testwork\ServiceContainer\ServiceProcessor;
+use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Definition;
+
+/**
+ * Testwork test environment extension.
+ *
+ * Extends testwork with environment services.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class EnvironmentExtension implements Extension
+{
+    /*
+     * Available services
+     */
+    const MANAGER_ID = 'environment.manager';
+
+    /*
+     * Available extension points
+     */
+    const HANDLER_TAG = 'environment.handler';
+    const READER_TAG = 'environment.reader';
+
+    /**
+     * @var ServiceProcessor
+     */
+    private $processor;
+
+    /**
+     * Initializes extension.
+     *
+     * @param null|ServiceProcessor $processor
+     */
+    public function __construct(ServiceProcessor $processor = null)
+    {
+        $this->processor = $processor ? : new ServiceProcessor();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getConfigKey()
+    {
+        return 'environments';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function initialize(ExtensionManager $extensionManager)
+    {
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function configure(ArrayNodeDefinition $builder)
+    {
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function load(ContainerBuilder $container, array $config)
+    {
+        $this->loadManager($container);
+        $this->loadStaticEnvironmentHandler($container);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function process(ContainerBuilder $container)
+    {
+        $this->processHandlers($container);
+        $this->processReaders($container);
+    }
+
+    /**
+     * Loads environment manager.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function loadManager(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Testwork\Environment\EnvironmentManager');
+        $container->setDefinition(self::MANAGER_ID, $definition);
+    }
+
+    /**
+     * Loads static environments handler.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function loadStaticEnvironmentHandler(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Testwork\Environment\Handler\StaticEnvironmentHandler');
+        $definition->addTag(self::HANDLER_TAG, array('priority' => 0));
+        $container->setDefinition(self::HANDLER_TAG . '.static', $definition);
+    }
+
+    /**
+     * Processes all environment handlers.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function processHandlers(ContainerBuilder $container)
+    {
+        $references = $this->processor->findAndSortTaggedServices($container, self::HANDLER_TAG);
+        $definition = $container->getDefinition(self::MANAGER_ID);
+
+        foreach ($references as $reference) {
+            $definition->addMethodCall('registerEnvironmentHandler', array($reference));
+        }
+    }
+
+    /**
+     * Processes all environment readers.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function processReaders(ContainerBuilder $container)
+    {
+        $references = $this->processor->findAndSortTaggedServices($container, self::READER_TAG);
+        $definition = $container->getDefinition(self::MANAGER_ID);
+
+        foreach ($references as $reference) {
+            $definition->addMethodCall('registerEnvironmentReader', array($reference));
+        }
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Environment/StaticEnvironment.php b/vendor/behat/behat/src/Behat/Testwork/Environment/StaticEnvironment.php
new file mode 100644 (file)
index 0000000..3396b63
--- /dev/null
@@ -0,0 +1,53 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Environment;
+
+use Behat\Testwork\Call\Callee;
+use Behat\Testwork\Suite\Suite;
+
+/**
+ * Represents static calls environment.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class StaticEnvironment implements Environment
+{
+    /**
+     * @var Suite
+     */
+    private $suite;
+
+    /**
+     * Initializes environment.
+     *
+     * @param Suite $suite
+     */
+    public function __construct(Suite $suite)
+    {
+        $this->suite = $suite;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    final public function getSuite()
+    {
+        return $this->suite;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    final public function bindCallee(Callee $callee)
+    {
+        return $callee->getCallable();
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/EventDispatcher/Cli/SigintController.php b/vendor/behat/behat/src/Behat/Testwork/EventDispatcher/Cli/SigintController.php
new file mode 100644 (file)
index 0000000..24a639c
--- /dev/null
@@ -0,0 +1,70 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\EventDispatcher\Cli;
+
+use Behat\Testwork\Cli\Controller;
+use Behat\Testwork\EventDispatcher\Event\AfterExerciseAborted;
+use Behat\Testwork\EventDispatcher\Event\ExerciseCompleted;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\EventDispatcher\EventDispatcherInterface;
+
+/**
+ * Aborts exercise on SIGINT signal.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class SigintController implements Controller
+{
+    /**
+     * @var EventDispatcherInterface
+     */
+    private $eventDispatcher;
+
+    /**
+     * Initializes controller.
+     *
+     * @param EventDispatcherInterface $eventDispatcher
+     */
+    public function __construct(EventDispatcherInterface $eventDispatcher)
+    {
+        $this->eventDispatcher = $eventDispatcher;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function configure(Command $command)
+    {
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function execute(InputInterface $input, OutputInterface $output)
+    {
+        if (function_exists('pcntl_signal')) {
+            declare(ticks = 1);
+            pcntl_signal(SIGINT, array($this, 'abortExercise'));
+        }
+    }
+
+    /**
+     * Dispatches AFTER exercise event and exits program.
+     */
+    public function abortExercise()
+    {
+        $this->eventDispatcher->dispatch(ExerciseCompleted::AFTER, new AfterExerciseAborted());
+
+        exit(1);
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/EventDispatcher/Event/AfterExerciseAborted.php b/vendor/behat/behat/src/Behat/Testwork/EventDispatcher/Event/AfterExerciseAborted.php
new file mode 100644 (file)
index 0000000..18c9aae
--- /dev/null
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\EventDispatcher\Event;
+
+/**
+ * Represents an event in which exercise was aborted.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class AfterExerciseAborted extends ExerciseCompleted
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function getSpecificationIterators()
+    {
+        return array();
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/EventDispatcher/Event/AfterExerciseCompleted.php b/vendor/behat/behat/src/Behat/Testwork/EventDispatcher/Event/AfterExerciseCompleted.php
new file mode 100644 (file)
index 0000000..b2eec9f
--- /dev/null
@@ -0,0 +1,80 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\EventDispatcher\Event;
+
+use Behat\Testwork\Specification\SpecificationIterator;
+use Behat\Testwork\Tester\Result\TestResult;
+use Behat\Testwork\Tester\Setup\Teardown;
+
+/**
+ * Represents an event in which exercise was completed.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class AfterExerciseCompleted extends ExerciseCompleted implements AfterTested
+{
+    /**
+     * @var SpecificationIterator[]
+     */
+    private $specificationIterators;
+    /**
+     * @var TestResult
+     */
+    private $result;
+    /**
+     * @var Teardown
+     */
+    private $teardown;
+
+    /**
+     * Initializes event.
+     *
+     * @param SpecificationIterator[] $specificationIterators
+     * @param TestResult              $result
+     * @param Teardown                $teardown
+     */
+    public function __construct(array $specificationIterators, TestResult $result, Teardown $teardown)
+    {
+        $this->specificationIterators = $specificationIterators;
+        $this->result = $result;
+        $this->teardown = $teardown;
+    }
+
+    /**
+     * Returns specification iterators.
+     *
+     * @return SpecificationIterator[]
+     */
+    public function getSpecificationIterators()
+    {
+        return $this->specificationIterators;
+    }
+
+    /**
+     * Returns exercise test result.
+     *
+     * @return TestResult
+     */
+    public function getTestResult()
+    {
+        return $this->result;
+    }
+
+    /**
+     * Returns exercise teardown result.
+     *
+     * @return Teardown
+     */
+    public function getTeardown()
+    {
+        return $this->teardown;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/EventDispatcher/Event/AfterExerciseSetup.php b/vendor/behat/behat/src/Behat/Testwork/EventDispatcher/Event/AfterExerciseSetup.php
new file mode 100644 (file)
index 0000000..b77de06
--- /dev/null
@@ -0,0 +1,63 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\EventDispatcher\Event;
+
+use Behat\Testwork\Specification\SpecificationIterator;
+use Behat\Testwork\Tester\Setup\Setup;
+
+/**
+ * Represents an event in which exercise is prepared to be executed.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class AfterExerciseSetup extends ExerciseCompleted implements AfterSetup
+{
+    /**
+     * @var SpecificationIterator[]
+     */
+    private $specificationIterators;
+    /**
+     * @var Setup
+     */
+    private $setup;
+
+    /**
+     * Initializes event.
+     *
+     * @param SpecificationIterator[] $specificationIterators
+     * @param Setup                   $setup
+     */
+    public function __construct(array $specificationIterators, Setup $setup)
+    {
+        $this->specificationIterators = $specificationIterators;
+        $this->setup = $setup;
+    }
+
+    /**
+     * Returns specification iterators.
+     *
+     * @return SpecificationIterator[]
+     */
+    public function getSpecificationIterators()
+    {
+        return $this->specificationIterators;
+    }
+
+    /**
+     * Returns exercise setup result.
+     *
+     * @return Setup
+     */
+    public function getSetup()
+    {
+        return $this->setup;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/EventDispatcher/Event/AfterSetup.php b/vendor/behat/behat/src/Behat/Testwork/EventDispatcher/Event/AfterSetup.php
new file mode 100644 (file)
index 0000000..f820caf
--- /dev/null
@@ -0,0 +1,28 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\EventDispatcher\Event;
+
+use Behat\Testwork\Tester\Setup\Setup;
+
+/**
+ * Represents an event right after a test setup.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface AfterSetup
+{
+    /**
+     * Returns current test setup.
+     *
+     * @return Setup
+     */
+    public function getSetup();
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/EventDispatcher/Event/AfterSuiteAborted.php b/vendor/behat/behat/src/Behat/Testwork/EventDispatcher/Event/AfterSuiteAborted.php
new file mode 100644 (file)
index 0000000..97c8a7a
--- /dev/null
@@ -0,0 +1,29 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\EventDispatcher\Event;
+
+use Behat\Testwork\Specification\NoSpecificationsIterator;
+
+/**
+ * Represents an event in which suite was aborted.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class AfterSuiteAborted extends SuiteTested
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function getSpecificationIterator()
+    {
+        return new NoSpecificationsIterator($this->getSuite());
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/EventDispatcher/Event/AfterSuiteSetup.php b/vendor/behat/behat/src/Behat/Testwork/EventDispatcher/Event/AfterSuiteSetup.php
new file mode 100644 (file)
index 0000000..591e54b
--- /dev/null
@@ -0,0 +1,67 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\EventDispatcher\Event;
+
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\Specification\SpecificationIterator;
+use Behat\Testwork\Tester\Setup\Setup;
+
+/**
+ * Represents an event right after a suite setup.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class AfterSuiteSetup extends SuiteTested implements AfterSetup
+{
+    /**
+     * @var SpecificationIterator
+     */
+    private $iterator;
+    /**
+     * @var Setup
+     */
+    private $setup;
+
+    /**
+     * Initializes event.
+     *
+     * @param Environment           $env
+     * @param SpecificationIterator $iterator
+     * @param Setup                 $setup
+     */
+    public function __construct(Environment $env, SpecificationIterator $iterator, Setup $setup)
+    {
+        parent::__construct($env);
+
+        $this->iterator = $iterator;
+        $this->setup = $setup;
+    }
+
+    /**
+     * Returns specification iterator.
+     *
+     * @return SpecificationIterator
+     */
+    public function getSpecificationIterator()
+    {
+        return $this->iterator;
+    }
+
+    /**
+     * Returns current test setup.
+     *
+     * @return Setup
+     */
+    public function getSetup()
+    {
+        return $this->setup;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/EventDispatcher/Event/AfterSuiteTested.php b/vendor/behat/behat/src/Behat/Testwork/EventDispatcher/Event/AfterSuiteTested.php
new file mode 100644 (file)
index 0000000..b68a4ec
--- /dev/null
@@ -0,0 +1,88 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\EventDispatcher\Event;
+
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\Specification\SpecificationIterator;
+use Behat\Testwork\Tester\Result\TestResult;
+use Behat\Testwork\Tester\Setup\Teardown;
+
+/**
+ * Represents an event in which suite was tested.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class AfterSuiteTested extends SuiteTested implements AfterTested
+{
+    /**
+     * @var SpecificationIterator
+     */
+    private $iterator;
+    /**
+     * @var TestResult
+     */
+    private $result;
+    /**
+     * @var Teardown
+     */
+    private $teardown;
+
+    /**
+     * Initializes event.
+     *
+     * @param Environment           $env
+     * @param SpecificationIterator $iterator
+     * @param TestResult            $result
+     * @param Teardown              $teardown
+     */
+    public function __construct(
+        Environment $env,
+        SpecificationIterator $iterator,
+        TestResult $result,
+        Teardown $teardown
+    ) {
+        parent::__construct($env);
+
+        $this->iterator = $iterator;
+        $this->result = $result;
+        $this->teardown = $teardown;
+    }
+
+    /**
+     * Returns specification iterator.
+     *
+     * @return SpecificationIterator
+     */
+    public function getSpecificationIterator()
+    {
+        return $this->iterator;
+    }
+
+    /**
+     * Returns current test result.
+     *
+     * @return TestResult
+     */
+    public function getTestResult()
+    {
+        return $this->result;
+    }
+
+    /**
+     * Returns current test teardown.
+     *
+     * @return Teardown
+     */
+    public function getTeardown()
+    {
+        return $this->teardown;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/EventDispatcher/Event/AfterTested.php b/vendor/behat/behat/src/Behat/Testwork/EventDispatcher/Event/AfterTested.php
new file mode 100644 (file)
index 0000000..1bec416
--- /dev/null
@@ -0,0 +1,36 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\EventDispatcher\Event;
+
+use Behat\Testwork\Tester\Result\TestResult;
+use Behat\Testwork\Tester\Setup\Teardown;
+
+/**
+ * Represents an event right after a test was completed.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface AfterTested
+{
+    /**
+     * Returns current test result.
+     *
+     * @return TestResult
+     */
+    public function getTestResult();
+
+    /**
+     * Returns current test teardown.
+     *
+     * @return Teardown
+     */
+    public function getTeardown();
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/EventDispatcher/Event/BeforeExerciseCompleted.php b/vendor/behat/behat/src/Behat/Testwork/EventDispatcher/Event/BeforeExerciseCompleted.php
new file mode 100644 (file)
index 0000000..dc0a22c
--- /dev/null
@@ -0,0 +1,46 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\EventDispatcher\Event;
+
+use Behat\Testwork\Specification\SpecificationIterator;
+
+/**
+ * Represents an event in which exercise is prepared to be executed.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class BeforeExerciseCompleted extends ExerciseCompleted implements BeforeTested
+{
+    /**
+     * @var SpecificationIterator[]
+     */
+    private $specificationIterators;
+
+    /**
+     * Initializes event.
+     *
+     * @param SpecificationIterator[] $specificationIterators
+     */
+    public function __construct(array $specificationIterators)
+    {
+        $this->specificationIterators = $specificationIterators;
+    }
+
+    /**
+     * Returns specification iterators.
+     *
+     * @return SpecificationIterator[]
+     */
+    public function getSpecificationIterators()
+    {
+        return $this->specificationIterators;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/EventDispatcher/Event/BeforeExerciseTeardown.php b/vendor/behat/behat/src/Behat/Testwork/EventDispatcher/Event/BeforeExerciseTeardown.php
new file mode 100644 (file)
index 0000000..5892a08
--- /dev/null
@@ -0,0 +1,63 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\EventDispatcher\Event;
+
+use Behat\Testwork\Specification\SpecificationIterator;
+use Behat\Testwork\Tester\Result\TestResult;
+
+/**
+ * Represents an event right before exercise teardown.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class BeforeExerciseTeardown extends ExerciseCompleted implements BeforeTeardown
+{
+    /**
+     * @var SpecificationIterator[]
+     */
+    private $specificationIterators;
+    /**
+     * @var TestResult
+     */
+    private $result;
+
+    /**
+     * Initializes event.
+     *
+     * @param SpecificationIterator[] $specificationIterators
+     * @param TestResult              $result
+     */
+    public function __construct(array $specificationIterators, TestResult $result)
+    {
+        $this->specificationIterators = $specificationIterators;
+        $this->result = $result;
+    }
+
+    /**
+     * Returns specification iterators.
+     *
+     * @return SpecificationIterator[]
+     */
+    public function getSpecificationIterators()
+    {
+        return $this->specificationIterators;
+    }
+
+    /**
+     * Returns exercise test result.
+     *
+     * @return TestResult
+     */
+    public function getTestResult()
+    {
+        return $this->result;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/EventDispatcher/Event/BeforeSuiteTeardown.php b/vendor/behat/behat/src/Behat/Testwork/EventDispatcher/Event/BeforeSuiteTeardown.php
new file mode 100644 (file)
index 0000000..3138217
--- /dev/null
@@ -0,0 +1,67 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\EventDispatcher\Event;
+
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\Specification\SpecificationIterator;
+use Behat\Testwork\Tester\Result\TestResult;
+
+/**
+ * Represents an event right before suite teardown.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class BeforeSuiteTeardown extends SuiteTested implements BeforeTeardown
+{
+    /**
+     * @var SpecificationIterator
+     */
+    private $iterator;
+    /**
+     * @var TestResult
+     */
+    private $result;
+
+    /**
+     * Initializes event.
+     *
+     * @param Environment           $env
+     * @param SpecificationIterator $iterator
+     * @param TestResult            $result
+     */
+    public function __construct(Environment $env, SpecificationIterator $iterator, TestResult $result)
+    {
+        parent::__construct($env);
+
+        $this->iterator = $iterator;
+        $this->result = $result;
+    }
+
+    /**
+     * Returns specification iterator.
+     *
+     * @return SpecificationIterator
+     */
+    public function getSpecificationIterator()
+    {
+        return $this->iterator;
+    }
+
+    /**
+     * Returns current test result.
+     *
+     * @return TestResult
+     */
+    public function getTestResult()
+    {
+        return $this->result;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/EventDispatcher/Event/BeforeSuiteTested.php b/vendor/behat/behat/src/Behat/Testwork/EventDispatcher/Event/BeforeSuiteTested.php
new file mode 100644 (file)
index 0000000..819be30
--- /dev/null
@@ -0,0 +1,50 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\EventDispatcher\Event;
+
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\Specification\SpecificationIterator;
+
+/**
+ * Represents an event in which suite is prepared to be tested.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class BeforeSuiteTested extends SuiteTested implements BeforeTested
+{
+    /**
+     * @var SpecificationIterator
+     */
+    private $iterator;
+
+    /**
+     * Initializes event.
+     *
+     * @param Environment           $env
+     * @param SpecificationIterator $iterator
+     */
+    public function __construct(Environment $env, SpecificationIterator $iterator)
+    {
+        parent::__construct($env);
+
+        $this->iterator = $iterator;
+    }
+
+    /**
+     * Returns specification iterator.
+     *
+     * @return SpecificationIterator
+     */
+    public function getSpecificationIterator()
+    {
+        return $this->iterator;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/EventDispatcher/Event/BeforeTeardown.php b/vendor/behat/behat/src/Behat/Testwork/EventDispatcher/Event/BeforeTeardown.php
new file mode 100644 (file)
index 0000000..66a82c6
--- /dev/null
@@ -0,0 +1,28 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\EventDispatcher\Event;
+
+use Behat\Testwork\Tester\Result\TestResult;
+
+/**
+ * Represents an event right before a teardown.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface BeforeTeardown
+{
+    /**
+     * Returns current test result.
+     *
+     * @return TestResult
+     */
+    public function getTestResult();
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/EventDispatcher/Event/BeforeTested.php b/vendor/behat/behat/src/Behat/Testwork/EventDispatcher/Event/BeforeTested.php
new file mode 100644 (file)
index 0000000..27e9728
--- /dev/null
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\EventDispatcher\Event;
+
+/**
+ * Represents an event just before test setup is started.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface BeforeTested
+{
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/EventDispatcher/Event/ExerciseCompleted.php b/vendor/behat/behat/src/Behat/Testwork/EventDispatcher/Event/ExerciseCompleted.php
new file mode 100644 (file)
index 0000000..026592b
--- /dev/null
@@ -0,0 +1,34 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\EventDispatcher\Event;
+
+use Behat\Testwork\Specification\SpecificationIterator;
+use Symfony\Component\EventDispatcher\Event;
+
+/**
+ * Represents an exercise event.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+abstract class ExerciseCompleted extends Event
+{
+    const BEFORE = 'tester.exercise_completed.before';
+    const AFTER_SETUP = 'tester.exercise_completed.after_setup';
+    const BEFORE_TEARDOWN = 'tester.exercise_completed.before_teardown';
+    const AFTER = 'tester.exercise_completed.after';
+
+    /**
+     * Returns specification iterators.
+     *
+     * @return SpecificationIterator[]
+     */
+    abstract public function getSpecificationIterators();
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/EventDispatcher/Event/LifecycleEvent.php b/vendor/behat/behat/src/Behat/Testwork/EventDispatcher/Event/LifecycleEvent.php
new file mode 100644 (file)
index 0000000..50191b4
--- /dev/null
@@ -0,0 +1,58 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\EventDispatcher\Event;
+
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\Suite\Suite;
+use Symfony\Component\EventDispatcher\Event;
+
+/**
+ * Represents an event which holds references to current suite and environment.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+abstract class LifecycleEvent extends Event
+{
+    /**
+     * @var Environment
+     */
+    private $environment;
+
+    /**
+     * Initializes scenario event.
+     *
+     * @param Environment $env
+     */
+    public function __construct(Environment $env)
+    {
+        $this->environment = $env;
+    }
+
+    /**
+     * Returns suite in which this event was fired.
+     *
+     * @return Suite
+     */
+    public function getSuite()
+    {
+        return $this->environment->getSuite();
+    }
+
+    /**
+     * Returns environment in which this event was fired.
+     *
+     * @return Environment
+     */
+    public function getEnvironment()
+    {
+        return $this->environment;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/EventDispatcher/Event/SuiteTested.php b/vendor/behat/behat/src/Behat/Testwork/EventDispatcher/Event/SuiteTested.php
new file mode 100644 (file)
index 0000000..2ded66a
--- /dev/null
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\EventDispatcher\Event;
+
+use Behat\Testwork\Specification\SpecificationIterator;
+
+/**
+ * Represents a suite event.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+abstract class SuiteTested extends LifecycleEvent
+{
+    const BEFORE = 'tester.suite_tested.before';
+    const AFTER_SETUP = 'tester.suite_tested.after_setup';
+    const BEFORE_TEARDOWN = 'tester.suite_tested.before_teardown';
+    const AFTER = 'tester.suite_tested.after';
+
+    /**
+     * Returns specification iterator.
+     *
+     * @return SpecificationIterator
+     */
+    abstract public function getSpecificationIterator();
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/EventDispatcher/ServiceContainer/EventDispatcherExtension.php b/vendor/behat/behat/src/Behat/Testwork/EventDispatcher/ServiceContainer/EventDispatcherExtension.php
new file mode 100644 (file)
index 0000000..72376da
--- /dev/null
@@ -0,0 +1,165 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\EventDispatcher\ServiceContainer;
+
+use Behat\Testwork\Cli\ServiceContainer\CliExtension;
+use Behat\Testwork\ServiceContainer\Extension;
+use Behat\Testwork\ServiceContainer\ExtensionManager;
+use Behat\Testwork\ServiceContainer\ServiceProcessor;
+use Behat\Testwork\Tester\ServiceContainer\TesterExtension;
+use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Definition;
+use Symfony\Component\DependencyInjection\Reference;
+
+/**
+ * Provides event dispatching service.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class EventDispatcherExtension implements Extension
+{
+    /*
+     * Available services
+     */
+    const DISPATCHER_ID = 'event_dispatcher';
+
+    /*
+     * Available extension points
+     */
+    const SUBSCRIBER_TAG = 'event_dispatcher.subscriber';
+
+    /**
+     * @var ServiceProcessor
+     */
+    protected $processor;
+
+    /**
+     * Initializes extension.
+     *
+     * @param null|ServiceProcessor $processor
+     */
+    public function __construct(ServiceProcessor $processor = null)
+    {
+        $this->processor = $processor ? : new ServiceProcessor();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getConfigKey()
+    {
+        return 'events';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function initialize(ExtensionManager $extensionManager)
+    {
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function configure(ArrayNodeDefinition $builder)
+    {
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function load(ContainerBuilder $container, array $config)
+    {
+        $this->loadSigintController($container);
+        $this->loadEventDispatcher($container);
+        $this->loadEventDispatchingExercise($container);
+        $this->loadEventDispatchingSuiteTester($container);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function process(ContainerBuilder $container)
+    {
+        $this->processSubscribers($container);
+    }
+
+    /**
+     * Loads sigint controller
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function loadSigintController(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Testwork\EventDispatcher\Cli\SigintController', array(
+            new Reference(EventDispatcherExtension::DISPATCHER_ID)
+        ));
+        $definition->addTag(CliExtension::CONTROLLER_TAG, array('priority' => 9999));
+        $container->setDefinition(CliExtension::CONTROLLER_TAG . '.sigint', $definition);
+    }
+
+    /**
+     * Loads event dispatcher.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function loadEventDispatcher(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Testwork\EventDispatcher\TestworkEventDispatcher');
+        $container->setDefinition(self::DISPATCHER_ID, $definition);
+    }
+
+    /**
+     * Loads event-dispatching exercise.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function loadEventDispatchingExercise(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Testwork\EventDispatcher\Tester\EventDispatchingExercise', array(
+            new Reference(TesterExtension::EXERCISE_ID),
+            new Reference(self::DISPATCHER_ID)
+        ));
+        $definition->addTag(TesterExtension::EXERCISE_WRAPPER_TAG);
+        $container->setDefinition(TesterExtension::EXERCISE_WRAPPER_TAG . '.event_dispatching', $definition);
+    }
+
+    /**
+     * Loads event-dispatching suite tester.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function loadEventDispatchingSuiteTester(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Testwork\EventDispatcher\Tester\EventDispatchingSuiteTester', array(
+            new Reference(TesterExtension::SUITE_TESTER_ID),
+            new Reference(self::DISPATCHER_ID)
+        ));
+        $definition->addTag(TesterExtension::SUITE_TESTER_WRAPPER_TAG, array('priority' => -9999));
+        $container->setDefinition(TesterExtension::SUITE_TESTER_WRAPPER_TAG . '.event_dispatching', $definition);
+    }
+
+    /**
+     * Registers all available event subscribers.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function processSubscribers(ContainerBuilder $container)
+    {
+        $references = $this->processor->findAndSortTaggedServices($container, self::SUBSCRIBER_TAG);
+        $definition = $container->getDefinition(self::DISPATCHER_ID);
+
+        foreach ($references as $reference) {
+            $definition->addMethodCall('addSubscriber', array($reference));
+        }
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/EventDispatcher/Tester/EventDispatchingExercise.php b/vendor/behat/behat/src/Behat/Testwork/EventDispatcher/Tester/EventDispatchingExercise.php
new file mode 100644 (file)
index 0000000..10f3419
--- /dev/null
@@ -0,0 +1,88 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\EventDispatcher\Tester;
+
+use Behat\Testwork\EventDispatcher\Event\AfterExerciseCompleted;
+use Behat\Testwork\EventDispatcher\Event\AfterExerciseSetup;
+use Behat\Testwork\EventDispatcher\Event\BeforeExerciseCompleted;
+use Behat\Testwork\EventDispatcher\Event\BeforeExerciseTeardown;
+use Behat\Testwork\Tester\Exercise;
+use Behat\Testwork\Tester\Result\TestResult;
+use Symfony\Component\EventDispatcher\EventDispatcherInterface;
+
+/**
+ * Exercise dispatching BEFORE/AFTER events during its execution.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class EventDispatchingExercise implements Exercise
+{
+    /**
+     * @var Exercise
+     */
+    private $baseExercise;
+    /**
+     * @var EventDispatcherInterface
+     */
+    private $eventDispatcher;
+
+    /**
+     * Initializes exercise.
+     *
+     * @param Exercise                 $baseExercise
+     * @param EventDispatcherInterface $eventDispatcher
+     */
+    public function __construct(Exercise $baseExercise, EventDispatcherInterface $eventDispatcher)
+    {
+        $this->baseExercise = $baseExercise;
+        $this->eventDispatcher = $eventDispatcher;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setUp(array $iterators, $skip)
+    {
+        $event = new BeforeExerciseCompleted($iterators);
+        $this->eventDispatcher->dispatch($event::BEFORE, $event);
+
+        $setup = $this->baseExercise->setUp($iterators, $skip);
+
+        $event = new AfterExerciseSetup($iterators, $setup);
+        $this->eventDispatcher->dispatch($event::AFTER_SETUP, $event);
+
+        return $setup;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function test(array $iterators, $skip = false)
+    {
+        return $this->baseExercise->test($iterators, $skip);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function tearDown(array $iterators, $skip, TestResult $result)
+    {
+        $event = new BeforeExerciseTeardown($iterators, $result);
+        $this->eventDispatcher->dispatch($event::BEFORE_TEARDOWN, $event);
+
+        $teardown = $this->baseExercise->tearDown($iterators, $skip, $result);
+
+        $event = new AfterExerciseCompleted($iterators, $result, $teardown);
+        $this->eventDispatcher->dispatch($event::AFTER, $event);
+
+        return $teardown;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/EventDispatcher/Tester/EventDispatchingSuiteTester.php b/vendor/behat/behat/src/Behat/Testwork/EventDispatcher/Tester/EventDispatchingSuiteTester.php
new file mode 100644 (file)
index 0000000..84b2d07
--- /dev/null
@@ -0,0 +1,90 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\EventDispatcher\Tester;
+
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\EventDispatcher\Event\AfterSuiteSetup;
+use Behat\Testwork\EventDispatcher\Event\AfterSuiteTested;
+use Behat\Testwork\EventDispatcher\Event\BeforeSuiteTeardown;
+use Behat\Testwork\EventDispatcher\Event\BeforeSuiteTested;
+use Behat\Testwork\Specification\SpecificationIterator;
+use Behat\Testwork\Tester\Result\TestResult;
+use Behat\Testwork\Tester\SuiteTester;
+use Symfony\Component\EventDispatcher\EventDispatcherInterface;
+
+/**
+ * Suite tester dispatching BEFORE/AFTER events during testing.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class EventDispatchingSuiteTester implements SuiteTester
+{
+    /**
+     * @var SuiteTester
+     */
+    private $baseTester;
+    /**
+     * @var EventDispatcherInterface
+     */
+    private $eventDispatcher;
+
+    /**
+     * Initializes tester.
+     *
+     * @param SuiteTester              $baseTester
+     * @param EventDispatcherInterface $eventDispatcher
+     */
+    public function __construct(SuiteTester $baseTester, EventDispatcherInterface $eventDispatcher)
+    {
+        $this->baseTester = $baseTester;
+        $this->eventDispatcher = $eventDispatcher;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setUp(Environment $env, SpecificationIterator $iterator, $skip)
+    {
+        $event = new BeforeSuiteTested($env, $iterator);
+        $this->eventDispatcher->dispatch($event::BEFORE, $event);
+
+        $setup = $this->baseTester->setUp($env, $iterator, $skip);
+
+        $event = new AfterSuiteSetup($env, $iterator, $setup);
+        $this->eventDispatcher->dispatch($event::AFTER_SETUP, $event);
+
+        return $setup;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function test(Environment $env, SpecificationIterator $iterator, $skip = false)
+    {
+        return $this->baseTester->test($env, $iterator, $skip);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function tearDown(Environment $env, SpecificationIterator $iterator, $skip, TestResult $result)
+    {
+        $event = new BeforeSuiteTeardown($env, $iterator, $result);
+        $this->eventDispatcher->dispatch($event::BEFORE_TEARDOWN, $event);
+
+        $teardown = $this->baseTester->tearDown($env, $iterator, $skip, $result);
+
+        $event = new AfterSuiteTested($env, $iterator, $result, $teardown);
+        $this->eventDispatcher->dispatch($event::AFTER, $event);
+
+        return $teardown;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/EventDispatcher/TestworkEventDispatcher.php b/vendor/behat/behat/src/Behat/Testwork/EventDispatcher/TestworkEventDispatcher.php
new file mode 100644 (file)
index 0000000..c1200f3
--- /dev/null
@@ -0,0 +1,59 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\EventDispatcher;
+
+use Symfony\Component\EventDispatcher\Event;
+use Symfony\Component\EventDispatcher\EventDispatcher;
+
+/**
+ * Extends Symfony2 event dispatcher with catch-all listeners.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class TestworkEventDispatcher extends EventDispatcher
+{
+    const BEFORE_ALL_EVENTS = '*~';
+    const AFTER_ALL_EVENTS = '~*';
+
+    /**
+     * {@inheritdoc}
+     */
+    public function dispatch($eventName, Event $event = null)
+    {
+        if (null === $event) {
+            $event = new Event();
+        }
+
+        if (method_exists($event, 'setName')) {
+            $event->setName($eventName);
+        }
+
+        $this->doDispatch($this->getListeners($eventName), $eventName, $event);
+
+        return $event;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getListeners($eventName = null)
+    {
+        if (null == $eventName || self::BEFORE_ALL_EVENTS === $eventName) {
+            return parent::getListeners($eventName);
+        }
+
+        return array_merge(
+            parent::getListeners(self::BEFORE_ALL_EVENTS),
+            parent::getListeners($eventName),
+            parent::getListeners(self::AFTER_ALL_EVENTS)
+        );
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Exception/Cli/VerbosityController.php b/vendor/behat/behat/src/Behat/Testwork/Exception/Cli/VerbosityController.php
new file mode 100644 (file)
index 0000000..bc86fb5
--- /dev/null
@@ -0,0 +1,64 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Exception\Cli;
+
+use Behat\Testwork\Cli\Controller;
+use Behat\Testwork\Exception\ExceptionPresenter;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * Controls exception default verbosity level.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class VerbosityController implements Controller
+{
+    /**
+     * @var ExceptionPresenter
+     */
+    private $exceptionPresenter;
+
+    /**
+     * Initializes controller.
+     *
+     * @param ExceptionPresenter $exceptionPresenter
+     */
+    public function __construct(ExceptionPresenter $exceptionPresenter)
+    {
+        $this->exceptionPresenter = $exceptionPresenter;
+    }
+
+    /**
+     * Configures command to be executable by the controller.
+     *
+     * @param Command $command
+     */
+    public function configure(Command $command)
+    {
+    }
+
+    /**
+     * Executes controller.
+     *
+     * @param InputInterface  $input
+     * @param OutputInterface $output
+     *
+     * @return null|integer
+     */
+    public function execute(InputInterface $input, OutputInterface $output)
+    {
+        if ($output->getVerbosity() !== OutputInterface::VERBOSITY_NORMAL) {
+            $this->exceptionPresenter->setDefaultVerbosity($output->getVerbosity());
+        }
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Exception/ExceptionPresenter.php b/vendor/behat/behat/src/Behat/Testwork/Exception/ExceptionPresenter.php
new file mode 100644 (file)
index 0000000..fce59bb
--- /dev/null
@@ -0,0 +1,118 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Exception;
+
+use Behat\Testwork\Exception\Stringer\ExceptionStringer;
+use Behat\Testwork\Output\Printer\OutputPrinter;
+use Exception;
+
+/**
+ * Presents exceptions as strings using registered stringers.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class ExceptionPresenter
+{
+    /**
+     * @var string
+     */
+    private $basePath;
+
+    /**
+     * @var ExceptionStringer[]
+     */
+    private $stringers = array();
+    /**
+     * @var integer
+     */
+    private $defaultVerbosity = OutputPrinter::VERBOSITY_NORMAL;
+
+    /**
+     * Initializes presenter.
+     *
+     * @param string  $basePath
+     * @param integer $defaultVerbosity
+     */
+    public function __construct($basePath = null, $defaultVerbosity = OutputPrinter::VERBOSITY_NORMAL)
+    {
+        if (null !== $basePath) {
+            $realBasePath = realpath($basePath);
+
+            if ($realBasePath) {
+                $basePath = $realBasePath;
+            }
+        }
+
+        $this->basePath = $basePath;
+        $this->defaultVerbosity = $defaultVerbosity;
+    }
+
+    /**
+     * Registers exception stringer.
+     *
+     * @param ExceptionStringer $stringer
+     */
+    public function registerExceptionStringer(ExceptionStringer $stringer)
+    {
+        $this->stringers[] = $stringer;
+    }
+
+    /**
+     * Sets default verbosity to a specified level.
+     *
+     * @param integer $defaultVerbosity
+     */
+    public function setDefaultVerbosity($defaultVerbosity)
+    {
+        $this->defaultVerbosity = $defaultVerbosity;
+    }
+
+    /**
+     * Presents exception as a string.
+     *
+     * @param Exception $exception
+     * @param integer   $verbosity
+     *
+     * @return string
+     */
+    public function presentException(Exception $exception, $verbosity = null)
+    {
+        $verbosity = $verbosity ?: $this->defaultVerbosity;
+
+        foreach ($this->stringers as $stringer) {
+            if ($stringer->supportsException($exception)) {
+                return $this->relativizePaths($stringer->stringException($exception, $verbosity));
+            }
+        }
+
+        if (OutputPrinter::VERBOSITY_VERY_VERBOSE <= $verbosity) {
+            return $this->relativizePaths(trim($exception));
+        }
+
+        return trim($this->relativizePaths($exception->getMessage()) . ' (' . get_class($exception) . ')');
+    }
+
+    /**
+     * Relativizes absolute paths in the text.
+     *
+     * @param string $text
+     *
+     * @return string
+     */
+    private function relativizePaths($text)
+    {
+        if (!$this->basePath) {
+            return $text;
+        }
+
+        return str_replace($this->basePath . DIRECTORY_SEPARATOR, '', $text);
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Exception/ServiceContainer/ExceptionExtension.php b/vendor/behat/behat/src/Behat/Testwork/Exception/ServiceContainer/ExceptionExtension.php
new file mode 100644 (file)
index 0000000..ac89715
--- /dev/null
@@ -0,0 +1,169 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Exception\ServiceContainer;
+
+use Behat\Testwork\Cli\ServiceContainer\CliExtension;
+use Behat\Testwork\Output\Printer\OutputPrinter;
+use Behat\Testwork\ServiceContainer\Extension;
+use Behat\Testwork\ServiceContainer\ExtensionManager;
+use Behat\Testwork\ServiceContainer\ServiceProcessor;
+use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Definition;
+use Symfony\Component\DependencyInjection\Reference;
+
+/**
+ * Provides exception handling services.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class ExceptionExtension implements Extension
+{
+    /*
+     * Available services
+     */
+    const PRESENTER_ID = 'exception.presenter';
+
+    /*
+     * Available extension points
+     */
+    const STRINGER_TAG = 'exception.stringer';
+
+    /**
+     * @var ServiceProcessor
+     */
+    private $processor;
+
+    /**
+     * Initializes extension.
+     *
+     * @param null|ServiceProcessor $processor
+     */
+    public function __construct(ServiceProcessor $processor = null)
+    {
+        $this->processor = $processor ? : new ServiceProcessor();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getConfigKey()
+    {
+        return 'exceptions';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function initialize(ExtensionManager $extensionManager)
+    {
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function configure(ArrayNodeDefinition $builder)
+    {
+        $builder
+            ->addDefaultsIfNotSet()
+            ->children()
+                ->scalarNode('verbosity')
+                    ->info('Output verbosity')
+                    ->example(sprintf('%d, %d, %d, %d',
+                        OutputPrinter::VERBOSITY_NORMAL,
+                        OutputPrinter::VERBOSITY_VERBOSE,
+                        OutputPrinter::VERBOSITY_VERY_VERBOSE,
+                        OutputPrinter::VERBOSITY_DEBUG
+                    ))
+                    ->defaultValue(OutputPrinter::VERBOSITY_NORMAL)
+                ->end()
+            ->end()
+        ;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function load(ContainerBuilder $container, array $config)
+    {
+        $this->loadPresenter($container, $config['verbosity']);
+        $this->loadDefaultStringers($container);
+        $this->loadVerbosityController($container);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function process(ContainerBuilder $container)
+    {
+        $this->processStringers($container);
+    }
+
+    /**
+     * Loads exception presenter.
+     *
+     * @param ContainerBuilder $container
+     * @param integer          $verbosity
+     */
+    protected function loadPresenter(ContainerBuilder $container, $verbosity)
+    {
+        $definition = new Definition('Behat\Testwork\Exception\ExceptionPresenter', array(
+            '%paths.base%',
+            $verbosity
+        ));
+        $container->setDefinition(self::PRESENTER_ID, $definition);
+    }
+
+    /**
+     * Loads default stringer.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function loadDefaultStringers(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Testwork\Exception\Stringer\PHPUnitExceptionStringer');
+        $definition->addTag(self::STRINGER_TAG, array('priority' => 50));
+        $container->setDefinition(self::STRINGER_TAG . '.phpunit', $definition);
+
+        $definition = new Definition('Behat\Testwork\Exception\Stringer\TestworkExceptionStringer');
+        $definition->addTag(self::STRINGER_TAG, array('priority' => 50));
+        $container->setDefinition(self::STRINGER_TAG . '.testwork', $definition);
+    }
+
+    /**
+     * Processes all available exception stringers.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function processStringers(ContainerBuilder $container)
+    {
+        $references = $this->processor->findAndSortTaggedServices($container, self::STRINGER_TAG);
+        $definition = $container->getDefinition(self::PRESENTER_ID);
+
+        foreach ($references as $reference) {
+            $definition->addMethodCall('registerExceptionStringer', array($reference));
+        }
+    }
+
+    /**
+     * Loads verbosity controller.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function loadVerbosityController($container)
+    {
+        $definition = new Definition('Behat\Testwork\Exception\Cli\VerbosityController', array(
+            new Reference(self::PRESENTER_ID)
+        ));
+        $definition->addTag(CliExtension::CONTROLLER_TAG, array('priority' => 9999));
+        $container->setDefinition(CliExtension::CONTROLLER_TAG . '.exception_verbosity', $definition);
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Exception/Stringer/ExceptionStringer.php b/vendor/behat/behat/src/Behat/Testwork/Exception/Stringer/ExceptionStringer.php
new file mode 100644 (file)
index 0000000..eab7061
--- /dev/null
@@ -0,0 +1,43 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Exception\Stringer;
+
+use Behat\Testwork\Exception\ExceptionPresenter;
+use Exception;
+
+/**
+ * Finds a best way to present as a string particular.
+ *
+ * @see ExceptionPresenter
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface ExceptionStringer
+{
+    /**
+     * Checks if stringer supports provided exception.
+     *
+     * @param Exception $exception
+     *
+     * @return Boolean
+     */
+    public function supportsException(Exception $exception);
+
+    /**
+     * Strings provided exception.
+     *
+     * @param Exception $exception
+     * @param integer   $verbosity
+     *
+     * @return string
+     */
+    public function stringException(Exception $exception, $verbosity);
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Exception/Stringer/PHPUnitExceptionStringer.php b/vendor/behat/behat/src/Behat/Testwork/Exception/Stringer/PHPUnitExceptionStringer.php
new file mode 100644 (file)
index 0000000..0b06299
--- /dev/null
@@ -0,0 +1,47 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Exception\Stringer;
+
+use Exception;
+
+/**
+ * Strings PHPUnit assertion exceptions.
+ *
+ * @see ExceptionPresenter
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class PHPUnitExceptionStringer implements ExceptionStringer
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function supportsException(Exception $exception)
+    {
+        return $exception instanceof \PHPUnit_Framework_Exception
+            || $exception instanceof \PHPUnit\Framework\Exception;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function stringException(Exception $exception, $verbosity)
+    {
+        if (!class_exists('PHPUnit\\Framework\\TestFailure')) {
+            return trim(\PHPUnit_Framework_TestFailure::exceptionToString($exception));
+        }
+
+        // PHPUnit assertion exceptions do not include expected / observed info in their
+        // messages, but expect the test listeners to format that info like the following
+        // (see e.g. PHPUnit_TextUI_ResultPrinter::printDefectTrace)
+        return trim(\PHPUnit\Framework\TestFailure::exceptionToString($exception));
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Exception/Stringer/TestworkExceptionStringer.php b/vendor/behat/behat/src/Behat/Testwork/Exception/Stringer/TestworkExceptionStringer.php
new file mode 100644 (file)
index 0000000..5a5e599
--- /dev/null
@@ -0,0 +1,39 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Exception\Stringer;
+
+use Behat\Testwork\Call\Exception\CallErrorException;
+use Behat\Testwork\Exception\TestworkException;
+use Exception;
+
+/**
+ * Strings Testwork exceptions.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class TestworkExceptionStringer implements ExceptionStringer
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function supportsException(Exception $exception)
+    {
+        return $exception instanceof TestworkException || $exception instanceof CallErrorException;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function stringException(Exception $exception, $verbosity)
+    {
+        return trim($exception->getMessage());
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Exception/TestworkException.php b/vendor/behat/behat/src/Behat/Testwork/Exception/TestworkException.php
new file mode 100644 (file)
index 0000000..a140b00
--- /dev/null
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Exception;
+
+/**
+ * All testwork exceptions implement this interface.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface TestworkException
+{
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Filesystem/ConsoleFilesystemLogger.php b/vendor/behat/behat/src/Behat/Testwork/Filesystem/ConsoleFilesystemLogger.php
new file mode 100644 (file)
index 0000000..d08c498
--- /dev/null
@@ -0,0 +1,84 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Filesystem;
+
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * Logs filesystem operations to the console.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class ConsoleFilesystemLogger implements FilesystemLogger
+{
+    /**
+     * @var string
+     */
+    private $basePath;
+    /**
+     * @var OutputInterface
+     */
+    private $output;
+
+    /**
+     * Initializes logger.
+     *
+     * @param string          $basePath
+     * @param OutputInterface $output
+     */
+    public function __construct($basePath, OutputInterface $output)
+    {
+        $this->basePath = $basePath;
+        $this->output = $output;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function directoryCreated($path, $reason)
+    {
+        $this->output->writeln(
+            sprintf(
+                '<info>+d</info> %s - %s',
+                str_replace($this->basePath . DIRECTORY_SEPARATOR, '', realpath($path)),
+                $reason
+            )
+        );
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function fileCreated($path, $reason)
+    {
+        $this->output->writeln(
+            sprintf(
+                '<info>+f</info> %s - %s',
+                str_replace($this->basePath . DIRECTORY_SEPARATOR, '', realpath($path)),
+                $reason
+            )
+        );
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function fileUpdated($path, $reason)
+    {
+        $this->output->writeln(
+            sprintf(
+                '<info>u</info> %s - %s',
+                str_replace($this->basePath . DIRECTORY_SEPARATOR, '', realpath($path)),
+                $reason
+            )
+        );
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Filesystem/FilesystemLogger.php b/vendor/behat/behat/src/Behat/Testwork/Filesystem/FilesystemLogger.php
new file mode 100644 (file)
index 0000000..77f0a75
--- /dev/null
@@ -0,0 +1,43 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Filesystem;
+
+/**
+ * Logs filesystem operations.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface FilesystemLogger
+{
+    /**
+     * Logs directory creation.
+     *
+     * @param string $path
+     * @param string $reason
+     */
+    public function directoryCreated($path, $reason);
+
+    /**
+     * Logs file creation.
+     *
+     * @param string $path
+     * @param string $reason
+     */
+    public function fileCreated($path, $reason);
+
+    /**
+     * Logs file update.
+     *
+     * @param string $path
+     * @param string $reason
+     */
+    public function fileUpdated($path, $reason);
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Filesystem/ServiceContainer/FilesystemExtension.php b/vendor/behat/behat/src/Behat/Testwork/Filesystem/ServiceContainer/FilesystemExtension.php
new file mode 100644 (file)
index 0000000..4fdc537
--- /dev/null
@@ -0,0 +1,83 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Filesystem\ServiceContainer;
+
+use Behat\Testwork\Cli\ServiceContainer\CliExtension;
+use Behat\Testwork\ServiceContainer\Extension;
+use Behat\Testwork\ServiceContainer\ExtensionManager;
+use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Definition;
+use Symfony\Component\DependencyInjection\Reference;
+
+/**
+ * Provides filesystem services for testwork.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class FilesystemExtension implements Extension
+{
+    /*
+     * Available services
+     */
+    const LOGGER_ID = 'filesystem.logger';
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getConfigKey()
+    {
+        return 'filesystem';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function initialize(ExtensionManager $extensionManager)
+    {
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function configure(ArrayNodeDefinition $builder)
+    {
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function load(ContainerBuilder $container, array $config)
+    {
+        $this->loadFilesystemLogger($container);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function process(ContainerBuilder $container)
+    {
+    }
+
+    /**
+     * Loads filesystem logger.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function loadFilesystemLogger(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Testwork\Filesystem\ConsoleFilesystemLogger', array(
+            '%paths.base%',
+            new Reference(CliExtension::OUTPUT_ID)
+        ));
+        $container->setDefinition(self::LOGGER_ID, $definition);
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Hook/Call/AfterSuite.php b/vendor/behat/behat/src/Behat/Testwork/Hook/Call/AfterSuite.php
new file mode 100644 (file)
index 0000000..0154d59
--- /dev/null
@@ -0,0 +1,43 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Hook\Call;
+
+use Behat\Testwork\Hook\Scope\SuiteScope;
+
+/**
+ * Represents AfterSuite hook.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class AfterSuite extends RuntimeSuiteHook
+{
+    /**
+     * Initializes hook.
+     *
+     * @param null|string $filterString
+     * @param callable    $callable
+     * @param null|string $description
+     */
+    public function __construct($filterString, $callable, $description = null)
+    {
+        parent::__construct(SuiteScope::AFTER, $filterString, $callable, $description);
+    }
+
+    /**
+     * Returns hook name.
+     *
+     * @return string
+     */
+    public function getName()
+    {
+        return 'AfterSuite';
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Hook/Call/BeforeSuite.php b/vendor/behat/behat/src/Behat/Testwork/Hook/Call/BeforeSuite.php
new file mode 100644 (file)
index 0000000..e06fb44
--- /dev/null
@@ -0,0 +1,43 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Hook\Call;
+
+use Behat\Testwork\Hook\Scope\SuiteScope;
+
+/**
+ * Represents BeforeSuite hook.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class BeforeSuite extends RuntimeSuiteHook
+{
+    /**
+     * Initializes hook.
+     *
+     * @param null|string $filterString
+     * @param callable    $callable
+     * @param null|string $description
+     */
+    public function __construct($filterString, $callable, $description = null)
+    {
+        parent::__construct(SuiteScope::BEFORE, $filterString, $callable, $description);
+    }
+
+    /**
+     * Returns hook name.
+     *
+     * @return string
+     */
+    public function getName()
+    {
+        return 'BeforeSuite';
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Hook/Call/HookCall.php b/vendor/behat/behat/src/Behat/Testwork/Hook/Call/HookCall.php
new file mode 100644 (file)
index 0000000..38b7a0d
--- /dev/null
@@ -0,0 +1,52 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Hook\Call;
+
+use Behat\Testwork\Environment\Call\EnvironmentCall;
+use Behat\Testwork\Hook\Hook;
+use Behat\Testwork\Hook\Scope\HookScope;
+
+/**
+ * Represents a hook call.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class HookCall extends EnvironmentCall
+{
+    /**
+     * @var HookScope
+     */
+    private $scope;
+
+    /**
+     * Initializes hook call.
+     *
+     * @param HookScope    $scope
+     * @param Hook         $hook
+     * @param null|integer $errorReportingLevel
+     */
+    public function __construct(HookScope $scope, Hook $hook, $errorReportingLevel = null)
+    {
+        parent::__construct($scope->getEnvironment(), $hook, array($scope), $errorReportingLevel);
+
+        $this->scope = $scope;
+    }
+
+    /**
+     * Returns hook scope.
+     *
+     * @return HookScope
+     */
+    public function getScope()
+    {
+        return $this->scope;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Hook/Call/RuntimeFilterableHook.php b/vendor/behat/behat/src/Behat/Testwork/Hook/Call/RuntimeFilterableHook.php
new file mode 100644 (file)
index 0000000..a8d392c
--- /dev/null
@@ -0,0 +1,59 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Hook\Call;
+
+use Behat\Testwork\Hook\FilterableHook;
+
+/**
+ * Represents runtime hook, filterable by filter string.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+abstract class RuntimeFilterableHook extends RuntimeHook implements FilterableHook
+{
+    /**
+     * @var null|string
+     */
+    private $filterString;
+
+    /**
+     * Initializes hook.
+     *
+     * @param string      $scopeName
+     * @param null|string $filterString
+     * @param callable    $callable
+     * @param null|string $description
+     */
+    public function __construct($scopeName, $filterString, $callable, $description = null)
+    {
+        $this->filterString = $filterString;
+
+        parent::__construct($scopeName, $callable, $description);
+    }
+
+    /**
+     * Returns hook filter string (if has one).
+     *
+     * @return null|string
+     */
+    public function getFilterString()
+    {
+        return $this->filterString;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function __toString()
+    {
+        return trim($this->getName() . ' ' . $this->getFilterString());
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Hook/Call/RuntimeHook.php b/vendor/behat/behat/src/Behat/Testwork/Hook/Call/RuntimeHook.php
new file mode 100644 (file)
index 0000000..5242fa8
--- /dev/null
@@ -0,0 +1,57 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Hook\Call;
+
+use Behat\Testwork\Call\RuntimeCallee;
+use Behat\Testwork\Hook\Hook;
+
+/**
+ * Represents a hook executed during the execution runtime.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+abstract class RuntimeHook extends RuntimeCallee implements Hook
+{
+    /**
+     * @var string
+     */
+    private $scopeName;
+
+    /**
+     * Initializes hook.
+     *
+     * @param string      $scopeName
+     * @param callable    $callable
+     * @param null|string $description
+     */
+    public function __construct($scopeName, $callable, $description = null)
+    {
+        $this->scopeName = $scopeName;
+
+        parent::__construct($callable, $description);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getScopeName()
+    {
+        return $this->scopeName;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function __toString()
+    {
+        return $this->getName();
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Hook/Call/RuntimeSuiteHook.php b/vendor/behat/behat/src/Behat/Testwork/Hook/Call/RuntimeSuiteHook.php
new file mode 100644 (file)
index 0000000..237bc76
--- /dev/null
@@ -0,0 +1,83 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Hook\Call;
+
+use Behat\Testwork\Call\Exception\BadCallbackException;
+use Behat\Testwork\Hook\Scope\HookScope;
+use Behat\Testwork\Hook\Scope\SuiteScope;
+use Behat\Testwork\Suite\Suite;
+
+/**
+ * Represents suite hook executed in the runtime.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+abstract class RuntimeSuiteHook extends RuntimeFilterableHook
+{
+    /**
+     * Initializes hook.
+     *
+     * @param string      $scopeName
+     * @param null|string $filterString
+     * @param callable    $callable
+     * @param null|string $description
+     *
+     * @throws BadCallbackException If callback is method, but not a static one
+     */
+    public function __construct($scopeName, $filterString, $callable, $description = null)
+    {
+        parent::__construct($scopeName, $filterString, $callable, $description);
+
+        if ($this->isAnInstanceMethod()) {
+            throw new BadCallbackException(sprintf(
+                'Suite hook callback: %s::%s() must be a static method',
+                $callable[0],
+                $callable[1]
+            ), $callable);
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function filterMatches(HookScope $scope)
+    {
+        if (!$scope instanceof SuiteScope) {
+            return false;
+        }
+        if (null === ($filterString = $this->getFilterString())) {
+            return true;
+        }
+
+        if (!empty($filterString)) {
+            return $this->isSuiteMatch($scope->getSuite(), $filterString);
+        }
+
+        return false;
+    }
+
+    /**
+     * Checks if Feature matches specified filter.
+     *
+     * @param Suite  $suite
+     * @param string $filterString
+     *
+     * @return Boolean
+     */
+    private function isSuiteMatch(Suite $suite, $filterString)
+    {
+        if ('/' === $filterString[0]) {
+            return 1 === preg_match($filterString, $suite->getName());
+        }
+
+        return false !== mb_strpos($suite->getName(), $filterString, 0, 'utf8');
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Hook/FilterableHook.php b/vendor/behat/behat/src/Behat/Testwork/Hook/FilterableHook.php
new file mode 100644 (file)
index 0000000..48ece6a
--- /dev/null
@@ -0,0 +1,30 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Hook;
+
+use Behat\Testwork\Hook\Scope\HookScope;
+
+/**
+ * Represents hook that is filterable by the provided scope.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface FilterableHook extends Hook
+{
+    /**
+     * Checks that current hook matches provided hook scope.
+     *
+     * @param HookScope $scope
+     *
+     * @return Boolean
+     */
+    public function filterMatches(HookScope $scope);
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Hook/Hook.php b/vendor/behat/behat/src/Behat/Testwork/Hook/Hook.php
new file mode 100644 (file)
index 0000000..19719ec
--- /dev/null
@@ -0,0 +1,42 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Hook;
+
+use Behat\Testwork\Call\Callee;
+
+/**
+ * Represents a Testwork hook.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface Hook extends Callee
+{
+    /**
+     * Returns hook name.
+     *
+     * @return string
+     */
+    public function getName();
+
+    /**
+     * Returns hook scope name.
+     *
+     * @return string
+     */
+    public function getScopeName();
+
+    /**
+     * Represents hook as a string.
+     *
+     * @return string
+     */
+    public function __toString();
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Hook/HookDispatcher.php b/vendor/behat/behat/src/Behat/Testwork/Hook/HookDispatcher.php
new file mode 100644 (file)
index 0000000..0dd7508
--- /dev/null
@@ -0,0 +1,76 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Hook;
+
+use Behat\Testwork\Call\CallCenter;
+use Behat\Testwork\Call\CallResult;
+use Behat\Testwork\Call\CallResults;
+use Behat\Testwork\Hook\Call\HookCall;
+use Behat\Testwork\Hook\Scope\HookScope;
+
+/**
+ * Dispatches registered hooks for provided events.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class HookDispatcher
+{
+    /**
+     * @var HookRepository
+     */
+    private $repository;
+    /**
+     * @var CallCenter
+     */
+    private $callCenter;
+
+    /**
+     * Initializes hook dispatcher.
+     *
+     * @param HookRepository $repository
+     * @param CallCenter     $callCenter
+     */
+    public function __construct(HookRepository $repository, CallCenter $callCenter)
+    {
+        $this->repository = $repository;
+        $this->callCenter = $callCenter;
+    }
+
+    /**
+     * Dispatches hooks for a specified event.
+     *
+     * @param HookScope $scope
+     *
+     * @return CallResults
+     */
+    public function dispatchScopeHooks(HookScope $scope)
+    {
+        $results = array();
+        foreach ($this->repository->getScopeHooks($scope) as $hook) {
+            $results[] = $this->dispatchHook($scope, $hook);
+        }
+
+        return new CallResults($results);
+    }
+
+    /**
+     * Dispatches single event hook.
+     *
+     * @param HookScope $scope
+     * @param Hook      $hook
+     *
+     * @return CallResult
+     */
+    private function dispatchHook(HookScope $scope, Hook $hook)
+    {
+        return $this->callCenter->makeCall(new HookCall($scope, $hook));
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Hook/HookRepository.php b/vendor/behat/behat/src/Behat/Testwork/Hook/HookRepository.php
new file mode 100644 (file)
index 0000000..527a11a
--- /dev/null
@@ -0,0 +1,77 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Hook;
+
+use Behat\Testwork\Call\Callee;
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\Environment\EnvironmentManager;
+use Behat\Testwork\Hook\Scope\HookScope;
+
+/**
+ * Finds hooks using provided environments or scopes.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class HookRepository
+{
+    /**
+     * @var EnvironmentManager
+     */
+    private $environmentManager;
+
+    /**
+     * Initializes repository.
+     *
+     * @param EnvironmentManager $environmentManager
+     */
+    public function __construct(EnvironmentManager $environmentManager)
+    {
+        $this->environmentManager = $environmentManager;
+    }
+
+    /**
+     * Returns all available hooks for a specific environment.
+     *
+     * @param Environment $environment
+     *
+     * @return Hook[]
+     */
+    public function getEnvironmentHooks(Environment $environment)
+    {
+        return array_filter(
+            $this->environmentManager->readEnvironmentCallees($environment),
+            function (Callee $callee) {
+                return $callee instanceof Hook;
+            }
+        );
+    }
+
+    /**
+     * Returns hooks for a specific event.
+     *
+     * @param HookScope $scope
+     *
+     * @return Hook[]
+     */
+    public function getScopeHooks(HookScope $scope)
+    {
+        return array_filter(
+            $this->getEnvironmentHooks($scope->getEnvironment()),
+            function (Hook $hook) use ($scope) {
+                if ($scope->getName() !== $hook->getScopeName()) {
+                    return false;
+                }
+
+                return !($hook instanceof FilterableHook && !$hook->filterMatches($scope));
+            }
+        );
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Hook/Scope/AfterSuiteScope.php b/vendor/behat/behat/src/Behat/Testwork/Hook/Scope/AfterSuiteScope.php
new file mode 100644 (file)
index 0000000..59b07c7
--- /dev/null
@@ -0,0 +1,90 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Hook\Scope;
+
+use Behat\Testwork\Specification\SpecificationIterator;
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\Tester\Result\TestResult;
+
+/**
+ * Represents a scope for AfterSuite hook.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class AfterSuiteScope implements SuiteScope, AfterTestScope
+{
+    /**
+     * @var Environment
+     */
+    private $environment;
+    /**
+     * @var SpecificationIterator
+     */
+    private $iterator;
+    /**
+     * @var TestResult
+     */
+    private $result;
+
+    /**
+     * Initializes scope.
+     *
+     * @param Environment           $environment
+     * @param SpecificationIterator $iterator
+     * @param TestResult            $result
+     */
+    public function __construct(Environment $environment, SpecificationIterator $iterator, TestResult $result)
+    {
+        $this->environment = $environment;
+        $this->iterator = $iterator;
+        $this->result = $result;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getName()
+    {
+        return self::AFTER;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getSuite()
+    {
+        return $this->environment->getSuite();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getEnvironment()
+    {
+        return $this->environment;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getSpecificationIterator()
+    {
+        return $this->iterator;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getTestResult()
+    {
+        return $this->result;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Hook/Scope/AfterTestScope.php b/vendor/behat/behat/src/Behat/Testwork/Hook/Scope/AfterTestScope.php
new file mode 100644 (file)
index 0000000..30c5fd5
--- /dev/null
@@ -0,0 +1,28 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Hook\Scope;
+
+use Behat\Testwork\Tester\Result\TestResult;
+
+/**
+ * Represents a hook scope for After* hooks.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface AfterTestScope extends HookScope
+{
+    /**
+     * Returns test result.
+     *
+     * @return TestResult
+     */
+    public function getTestResult();
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Hook/Scope/BeforeSuiteScope.php b/vendor/behat/behat/src/Behat/Testwork/Hook/Scope/BeforeSuiteScope.php
new file mode 100644 (file)
index 0000000..5c982cb
--- /dev/null
@@ -0,0 +1,75 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Hook\Scope;
+
+use Behat\Testwork\Specification\SpecificationIterator;
+use Behat\Testwork\Environment\Environment;
+
+/**
+ * Represents a scope for BeforeSuite hook.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class BeforeSuiteScope implements SuiteScope
+{
+    /**
+     * @var Environment
+     */
+    private $environment;
+    /**
+     * @var SpecificationIterator
+     */
+    private $iterator;
+
+    /**
+     * Initializes scope.
+     *
+     * @param Environment           $env
+     * @param SpecificationIterator $iterator
+     */
+    public function __construct(Environment $env, SpecificationIterator $iterator)
+    {
+        $this->environment = $env;
+        $this->iterator = $iterator;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getName()
+    {
+        return self::BEFORE;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getSuite()
+    {
+        return $this->environment->getSuite();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getEnvironment()
+    {
+        return $this->environment;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getSpecificationIterator()
+    {
+        return $this->iterator;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Hook/Scope/HookScope.php b/vendor/behat/behat/src/Behat/Testwork/Hook/Scope/HookScope.php
new file mode 100644 (file)
index 0000000..d7014fd
--- /dev/null
@@ -0,0 +1,48 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Hook\Scope;
+
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\Hook\HookDispatcher;
+use Behat\Testwork\Hook\HookRepository;
+use Behat\Testwork\Suite\Suite;
+
+/**
+ * Represents an object used to find appropriate hooks.
+ *
+ * @see HookDispatcher
+ * @see HookRepository
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface HookScope
+{
+    /**
+     * Returns hook scope name.
+     *
+     * @return string
+     */
+    public function getName();
+
+    /**
+     * Returns hook suite.
+     *
+     * @return Suite
+     */
+    public function getSuite();
+
+    /**
+     * Returns hook environment.
+     *
+     * @return Environment
+     */
+    public function getEnvironment();
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Hook/Scope/SuiteScope.php b/vendor/behat/behat/src/Behat/Testwork/Hook/Scope/SuiteScope.php
new file mode 100644 (file)
index 0000000..6cc308f
--- /dev/null
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Hook\Scope;
+
+use Behat\Testwork\Specification\SpecificationIterator;
+
+/**
+ * Represents a suite hook.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface SuiteScope extends HookScope
+{
+    const BEFORE = 'suite.before';
+    const AFTER = 'suite.after';
+
+    /**
+     * Returns specification iterator.
+     *
+     * @return SpecificationIterator
+     */
+    public function getSpecificationIterator();
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Hook/ServiceContainer/HookExtension.php b/vendor/behat/behat/src/Behat/Testwork/Hook/ServiceContainer/HookExtension.php
new file mode 100644 (file)
index 0000000..fee6de4
--- /dev/null
@@ -0,0 +1,116 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Hook\ServiceContainer;
+
+use Behat\Behat\Tester\ServiceContainer\TesterExtension;
+use Behat\Testwork\Call\ServiceContainer\CallExtension;
+use Behat\Testwork\Environment\ServiceContainer\EnvironmentExtension;
+use Behat\Testwork\ServiceContainer\Extension;
+use Behat\Testwork\ServiceContainer\ExtensionManager;
+use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Definition;
+use Symfony\Component\DependencyInjection\Reference;
+
+/**
+ * Provides test hooking services for testwork.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class HookExtension implements Extension
+{
+    /*
+     * Available services
+     */
+    const DISPATCHER_ID = 'hook.dispatcher';
+    const REPOSITORY_ID = 'hook.repository';
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getConfigKey()
+    {
+        return 'hooks';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function initialize(ExtensionManager $extensionManager)
+    {
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function configure(ArrayNodeDefinition $builder)
+    {
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function load(ContainerBuilder $container, array $config)
+    {
+        $this->loadDispatcher($container);
+        $this->loadRepository($container);
+        $this->loadHookableTesters($container);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function process(ContainerBuilder $container)
+    {
+    }
+
+    /**
+     * Loads hook dispatcher.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function loadDispatcher(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Testwork\Hook\HookDispatcher', array(
+            new Reference(self::REPOSITORY_ID),
+            new Reference(CallExtension::CALL_CENTER_ID)
+        ));
+        $container->setDefinition(self::DISPATCHER_ID, $definition);
+    }
+
+    /**
+     * Loads hook repository.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function loadRepository(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Testwork\Hook\HookRepository', array(
+            new Reference(EnvironmentExtension::MANAGER_ID)
+        ));
+        $container->setDefinition(self::REPOSITORY_ID, $definition);
+    }
+
+    /**
+     * Loads hookable testers.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function loadHookableTesters(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Testwork\Hook\Tester\HookableSuiteTester', array(
+            new Reference(TesterExtension::SUITE_TESTER_ID),
+            new Reference(self::DISPATCHER_ID)
+        ));
+        $definition->addTag(TesterExtension::SUITE_TESTER_WRAPPER_TAG, array('priority' => 9999));
+        $container->setDefinition(TesterExtension::SUITE_TESTER_WRAPPER_TAG . '.hookable', $definition);
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Hook/Tester/HookableSuiteTester.php b/vendor/behat/behat/src/Behat/Testwork/Hook/Tester/HookableSuiteTester.php
new file mode 100644 (file)
index 0000000..1277e82
--- /dev/null
@@ -0,0 +1,92 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Hook\Tester;
+
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\Hook\HookDispatcher;
+use Behat\Testwork\Hook\Scope\AfterSuiteScope;
+use Behat\Testwork\Hook\Scope\BeforeSuiteScope;
+use Behat\Testwork\Hook\Tester\Setup\HookedSetup;
+use Behat\Testwork\Hook\Tester\Setup\HookedTeardown;
+use Behat\Testwork\Specification\SpecificationIterator;
+use Behat\Testwork\Tester\Result\TestResult;
+use Behat\Testwork\Tester\SuiteTester;
+
+/**
+ * Suite tester which dispatches hooks during its execution.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class HookableSuiteTester implements SuiteTester
+{
+    /**
+     * @var SuiteTester
+     */
+    private $baseTester;
+    /**
+     * @var HookDispatcher
+     */
+    private $hookDispatcher;
+
+    /**
+     * Initializes tester.
+     *
+     * @param SuiteTester    $baseTester
+     * @param HookDispatcher $hookDispatcher
+     */
+    public function __construct(SuiteTester $baseTester, HookDispatcher $hookDispatcher)
+    {
+        $this->baseTester = $baseTester;
+        $this->hookDispatcher = $hookDispatcher;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setUp(Environment $env, SpecificationIterator $iterator, $skip)
+    {
+        $setup = $this->baseTester->setUp($env, $iterator, $skip);
+
+        if ($skip) {
+            return $setup;
+        }
+
+        $scope = new BeforeSuiteScope($env, $iterator);
+        $hookCallResults = $this->hookDispatcher->dispatchScopeHooks($scope);
+
+        return new HookedSetup($setup, $hookCallResults);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function test(Environment $env, SpecificationIterator $iterator, $skip)
+    {
+        return $this->baseTester->test($env, $iterator, $skip);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function tearDown(Environment $env, SpecificationIterator $iterator, $skip, TestResult $result)
+    {
+        $teardown = $this->baseTester->tearDown($env, $iterator, $skip, $result);
+
+        if ($skip) {
+            return $teardown;
+        }
+
+        $scope = new AfterSuiteScope($env, $iterator, $result);
+        $hookCallResults = $this->hookDispatcher->dispatchScopeHooks($scope);
+
+        return new HookedTeardown($teardown, $hookCallResults);
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Hook/Tester/Setup/HookedSetup.php b/vendor/behat/behat/src/Behat/Testwork/Hook/Tester/Setup/HookedSetup.php
new file mode 100644 (file)
index 0000000..3ba4478
--- /dev/null
@@ -0,0 +1,73 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Hook\Tester\Setup;
+
+use Behat\Testwork\Call\CallResults;
+use Behat\Testwork\Tester\Setup\Setup;
+
+/**
+ * Represents hooked test setup.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class HookedSetup implements Setup
+{
+    /**
+     * @var Setup
+     */
+    private $setup;
+    /**
+     * @var CallResults
+     */
+    private $hookCallResults;
+
+    /**
+     * Initializes setup.
+     *
+     * @param Setup       $setup
+     * @param CallResults $hookCallResults
+     */
+    public function __construct(Setup $setup, CallResults $hookCallResults)
+    {
+        $this->setup = $setup;
+        $this->hookCallResults = $hookCallResults;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function isSuccessful()
+    {
+        if ($this->hookCallResults->hasExceptions()) {
+            return false;
+        }
+
+        return $this->setup->isSuccessful();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function hasOutput()
+    {
+        return $this->hookCallResults->hasStdOuts() || $this->hookCallResults->hasExceptions();
+    }
+
+    /**
+     * Returns hook call results.
+     *
+     * @return CallResults
+     */
+    public function getHookCallResults()
+    {
+        return $this->hookCallResults;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Hook/Tester/Setup/HookedTeardown.php b/vendor/behat/behat/src/Behat/Testwork/Hook/Tester/Setup/HookedTeardown.php
new file mode 100644 (file)
index 0000000..5400be9
--- /dev/null
@@ -0,0 +1,73 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Hook\Tester\Setup;
+
+use Behat\Testwork\Call\CallResults;
+use Behat\Testwork\Tester\Setup\Teardown;
+
+/**
+ * Represents hooked test teardown.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class HookedTeardown implements Teardown
+{
+    /**
+     * @var Teardown
+     */
+    private $teardown;
+    /**
+     * @var CallResults
+     */
+    private $hookCallResults;
+
+    /**
+     * Initializes setup.
+     *
+     * @param Teardown    $teardown
+     * @param CallResults $hookCallResults
+     */
+    public function __construct(Teardown $teardown, CallResults $hookCallResults)
+    {
+        $this->teardown = $teardown;
+        $this->hookCallResults = $hookCallResults;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function isSuccessful()
+    {
+        if ($this->hookCallResults->hasExceptions()) {
+            return false;
+        }
+
+        return $this->teardown->isSuccessful();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function hasOutput()
+    {
+        return $this->hookCallResults->hasStdOuts() || $this->hookCallResults->hasExceptions();
+    }
+
+    /**
+     * Returns hook call results.
+     *
+     * @return CallResults
+     */
+    public function getHookCallResults()
+    {
+        return $this->hookCallResults;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Ordering/Cli/OrderController.php b/vendor/behat/behat/src/Behat/Testwork/Ordering/Cli/OrderController.php
new file mode 100644 (file)
index 0000000..12edd91
--- /dev/null
@@ -0,0 +1,99 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Ordering\Cli;
+
+use Behat\Testwork\Ordering\Exception\InvalidOrderException;
+use Behat\Testwork\Ordering\OrderedExercise;
+use Behat\Testwork\Ordering\Orderer\Orderer;
+use Behat\Testwork\Cli\Controller;
+use Symfony\Component\Console\Command\Command as SymfonyCommand;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\EventDispatcher\EventDispatcherInterface;
+
+/**
+ * Preloads scenarios and then modifies the order when --order is passed
+ *
+ * @author Ciaran McNulty <mail@ciaranmcnulty.com>
+ */
+final class OrderController implements Controller
+{
+    /**
+     * @var EventDispatcherInterface
+     */
+    private $eventDispatcher;
+    /**
+     * @var OrderedExercise
+     */
+    private $exercise;
+    /**
+     * @var array
+     */
+    private $orderers = array();
+
+    /**
+     * Initializes controller.
+     *
+     * @param EventDispatcherInterface $eventDispatcher
+     * @param OrderedExercise $exercise
+     */
+    public function __construct(EventDispatcherInterface $eventDispatcher, OrderedExercise $exercise)
+    {
+        $this->eventDispatcher = $eventDispatcher;
+        $this->exercise = $exercise;
+    }
+
+    /**
+     * Configures command to be executable by the controller.
+     *
+     * @param SymfonyCommand $command
+     */
+    public function configure(SymfonyCommand $command)
+    {
+        $command->addOption('--order', null, InputOption::VALUE_REQUIRED,
+            'Set an order in which to execute the specifications (this will result in slower feedback).'
+        );
+    }
+
+    /**
+     * Executes controller.
+     *
+     * @param InputInterface $input
+     * @param OutputInterface $output
+     *
+     * @return null|integer
+     */
+    public function execute(InputInterface $input, OutputInterface $output)
+    {
+        $orderer = $input->getOption('order');
+
+        if (!$orderer) {
+            return;
+        }
+
+        if (!array_key_exists($orderer, $this->orderers)) {
+           throw new InvalidOrderException(sprintf("Order option '%s' was not recognised", $orderer));
+        }
+
+        $this->exercise->setOrderer($this->orderers[$orderer]);
+    }
+
+    /**
+     * Register a new available controller
+     *
+     * @param Orderer $orderer
+     */
+    public function registerOrderer(Orderer $orderer)
+    {
+        $this->orderers[$orderer->getName()] = $orderer;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Ordering/Exception/InvalidOrderException.php b/vendor/behat/behat/src/Behat/Testwork/Ordering/Exception/InvalidOrderException.php
new file mode 100644 (file)
index 0000000..8d9cd32
--- /dev/null
@@ -0,0 +1,22 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Ordering\Exception;
+
+use Behat\Testwork\Exception\TestworkException;
+use RuntimeException;
+
+/**
+ * Represents exception throw during attempt to prioritise execution with a non-existent algorithm
+ *
+ * @author Ciaran McNulty <mail@ciaranmcnulty.com>
+ */
+final class InvalidOrderException extends RuntimeException implements TestworkException
+{}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Ordering/OrderedExercise.php b/vendor/behat/behat/src/Behat/Testwork/Ordering/OrderedExercise.php
new file mode 100644 (file)
index 0000000..1cc3055
--- /dev/null
@@ -0,0 +1,120 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Ordering;
+
+use Behat\Testwork\Ordering\Orderer\NoopOrderer;
+use Behat\Testwork\Ordering\Orderer\Orderer;
+use Behat\Testwork\Specification\SpecificationIterator;
+use Behat\Testwork\Tester\Exercise;
+use Behat\Testwork\Tester\Result\TestResult;
+use Behat\Testwork\Tester\Setup\Setup;
+use Behat\Testwork\Tester\Setup\Teardown;
+
+/**
+ * Exercise that is ordered according to a specified algorithm
+ *
+ * @author Ciaran McNulty <mail@ciaranmcnulty.com>
+ */
+final class OrderedExercise implements Exercise
+{
+    /**
+     * @var Orderer
+     */
+    private $orderer;
+
+    /**
+     * @var SpecificationIterator[]
+     */
+    private $unordered;
+
+    /**
+     * @var SpecificationIterator[]
+     */
+    private $ordered;
+
+    /**
+     * @var Exercise
+     */
+    private $decoratedExercise;
+
+    /**
+     * @param Exercise $decoratedExercise
+     */
+    public function __construct(Exercise $decoratedExercise)
+    {
+        $this->orderer = new NoopOrderer();
+        $this->decoratedExercise = $decoratedExercise;
+    }
+
+    /**
+     * Sets up exercise for a test.
+     *
+     * @param SpecificationIterator[] $iterators
+     * @param Boolean $skip
+     *
+     * @return Setup
+     */
+    public function setUp(array $iterators, $skip)
+    {
+        return $this->decoratedExercise->setUp($this->order($iterators), $skip);
+    }
+
+    /**
+     * Tests suites specifications.
+     *
+     * @param SpecificationIterator[] $iterators
+     * @param Boolean $skip
+     *
+     * @return TestResult
+     */
+    public function test(array $iterators, $skip)
+    {
+        return $this->decoratedExercise->test($this->order($iterators), $skip);
+    }
+
+    /**
+     * Tears down exercise after a test.
+     *
+     * @param SpecificationIterator[] $iterators
+     * @param Boolean $skip
+     * @param TestResult $result
+     *
+     * @return Teardown
+     */
+    public function tearDown(array $iterators, $skip, TestResult $result)
+    {
+        return $this->decoratedExercise->tearDown($this->order($iterators), $skip, $result);
+    }
+
+    /**
+     * Replace the algorithm being used for prioritisation
+     *
+     * @param Orderer $orderer
+     */
+    public function setOrderer(Orderer $orderer)
+    {
+        $this->orderer = $orderer;
+    }
+
+    /**
+     * @param SpecificationIterator[] $iterators
+     * @return SpecificationIterator[]
+     */
+    private function order(array $iterators)
+    {
+        if (!$this->ordered || $this->unordered != $iterators) {
+            $this->unordered = $iterators;
+            $this->ordered = $this->orderer->order($iterators);
+        }
+
+        return $this->ordered;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Ordering/Orderer/NoopOrderer.php b/vendor/behat/behat/src/Behat/Testwork/Ordering/Orderer/NoopOrderer.php
new file mode 100644 (file)
index 0000000..a2257f9
--- /dev/null
@@ -0,0 +1,39 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Ordering\Orderer;
+
+use Behat\Testwork\Specification\SpecificationIterator;
+
+/**
+ * Null implementation of Orderer that does no ordering
+ *
+ * @author Ciaran McNulty <mail@ciaranmcnulty.com>
+ */
+final class NoopOrderer implements Orderer
+{
+
+    /**
+     * @param SpecificationIterator[] $scenarioIterators
+     * @return SpecificationIterator[]
+     */
+    public function order(array $scenarioIterators)
+    {
+        return $scenarioIterators;
+    }
+
+    /**
+     * @return string
+     */
+    public function getName()
+    {
+        return 'null';
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Ordering/Orderer/Orderer.php b/vendor/behat/behat/src/Behat/Testwork/Ordering/Orderer/Orderer.php
new file mode 100644 (file)
index 0000000..1f29c52
--- /dev/null
@@ -0,0 +1,32 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Ordering\Orderer;
+
+use Behat\Testwork\Specification\SpecificationIterator;
+
+/**
+ * Algorithm for prioritising Specification execution
+ *
+ * @author Ciaran McNulty <mail@ciaranmcnulty.com>
+ */
+interface Orderer
+{
+    /**
+     * @param SpecificationIterator[] $scenarioIterators
+     * @return SpecificationIterator[]
+     */
+    public function order(array $scenarioIterators);
+
+    /**
+     * @return string
+     */
+    public function getName();
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Ordering/Orderer/RandomOrderer.php b/vendor/behat/behat/src/Behat/Testwork/Ordering/Orderer/RandomOrderer.php
new file mode 100644 (file)
index 0000000..551e447
--- /dev/null
@@ -0,0 +1,61 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Ordering\Orderer;
+
+use Behat\Testwork\Specification\SpecificationArrayIterator;
+
+/**
+ * Prioritises Suites and Features into random order
+ *
+ * @author Ciaran McNulty <mail@ciaranmcnulty.com>
+ */
+final class RandomOrderer implements Orderer
+{
+    /**
+     * @param SpecificationIterator[] $scenarioIterators
+     * @return SpecificationIterator[]
+     */
+    public function order(array $scenarioIterators)
+    {
+        $orderedFeatures = $this->orderFeatures($scenarioIterators);
+        shuffle($orderedFeatures);
+
+        return $orderedFeatures;
+    }
+
+    /**
+     * @param array $scenarioIterators
+     * @return array
+     */
+    private function orderFeatures(array $scenarioIterators)
+    {
+        $orderedSuites = array();
+
+        foreach ($scenarioIterators as $scenarioIterator) {
+            $orderedSpecifications = iterator_to_array($scenarioIterator);
+            shuffle($orderedSpecifications);
+            $orderedSuites[] = new SpecificationArrayIterator(
+                $scenarioIterator->getSuite(),
+                $orderedSpecifications
+            );
+        }
+
+        return $orderedSuites;
+    }
+
+    /**
+     * @return string
+     */
+    public function getName()
+    {
+        return 'random';
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Ordering/Orderer/ReverseOrderer.php b/vendor/behat/behat/src/Behat/Testwork/Ordering/Orderer/ReverseOrderer.php
new file mode 100644 (file)
index 0000000..9a23a4d
--- /dev/null
@@ -0,0 +1,70 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Ordering\Orderer;
+
+use Behat\Testwork\Specification\SpecificationArrayIterator;
+use Behat\Testwork\Specification\SpecificationIterator;
+
+/**
+ * Prioritises Suites and Features into reverse order
+ *
+ * @author Ciaran McNulty <mail@ciaranmcnulty.com>
+ */
+final class ReverseOrderer implements Orderer
+{
+    /**
+     * @param SpecificationIterator[] $scenarioIterators
+     * @return SpecificationIterator[]
+     */
+    public function order(array $scenarioIterators)
+    {
+        $orderedFeatures = $this->orderFeatures($scenarioIterators);
+        $orderedSuites = $this->orderSuites($orderedFeatures);
+
+        return $orderedSuites;
+    }
+
+    /**
+     * @param array $scenarioIterators
+     * @return array
+     */
+    private function orderFeatures(array $scenarioIterators)
+    {
+        $orderedSuites = array();
+
+        foreach ($scenarioIterators as $scenarioIterator) {
+            $orderedSpecifications = array_reverse(iterator_to_array($scenarioIterator));
+            $orderedSuites[] = new SpecificationArrayIterator(
+                $scenarioIterator->getSuite(),
+                $orderedSpecifications
+            );
+        }
+
+        return $orderedSuites;
+    }
+
+    /**
+     * @param $orderedSuites
+     * @return array
+     */
+    private function orderSuites($orderedSuites)
+    {
+        return array_reverse($orderedSuites);
+    }
+
+    /**
+     * @return string
+     */
+    public function getName()
+    {
+        return 'reverse';
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Ordering/ServiceContainer/OrderingExtension.php b/vendor/behat/behat/src/Behat/Testwork/Ordering/ServiceContainer/OrderingExtension.php
new file mode 100644 (file)
index 0000000..2a9d5a7
--- /dev/null
@@ -0,0 +1,156 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Ordering\ServiceContainer;
+
+use Behat\Testwork\Cli\ServiceContainer\CliExtension;
+use Behat\Testwork\EventDispatcher\ServiceContainer\EventDispatcherExtension;
+use Behat\Testwork\ServiceContainer\Extension;
+use Behat\Testwork\ServiceContainer\ExtensionManager;
+use Behat\Testwork\ServiceContainer\ServiceProcessor;
+use Behat\Testwork\Tester\ServiceContainer\TesterExtension;
+use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Definition;
+use Symfony\Component\DependencyInjection\Reference;
+
+/**
+ * Provides specification execution ordering.
+ *
+ * @author Ciaran McNulty <mail@ciaranmcnulty.com>
+ */
+final class OrderingExtension implements Extension
+{
+    const ORDERER_TAG = 'tester.orderer';
+
+    /**
+     * @var ServiceProcessor
+     */
+    private $processor;
+
+    /**
+     * Initializes extension.
+     *
+     * @param null|ServiceProcessor $processor
+     */
+    public function __construct(ServiceProcessor $processor = null)
+    {
+        $this->processor = $processor ?: new ServiceProcessor();
+    }
+
+    /**
+     * You can modify the container here before it is dumped to PHP code.
+     *
+     * @param ContainerBuilder $container
+     *
+     * @api
+     */
+    public function process(ContainerBuilder $container)
+    {
+        $definition = $container->getDefinition(CliExtension::CONTROLLER_TAG . '.order');
+        $references = $this->processor->findAndSortTaggedServices($container, self::ORDERER_TAG);
+
+        foreach ($references as $reference) {
+            $definition->addMethodCall('registerOrderer', array($reference));
+        }
+    }
+
+    /**
+     * Returns the extension config key.
+     *
+     * @return string
+     */
+    public function getConfigKey()
+    {
+        return 'ordering';
+    }
+
+    /**
+     * Initializes other extensions.
+     *
+     * This method is called immediately after all extensions are activated but
+     * before any extension `configure()` method is called. This allows extensions
+     * to hook into the configuration of other extensions providing such an
+     * extension point.
+     *
+     * @param ExtensionManager $extensionManager
+     */
+    public function initialize(ExtensionManager $extensionManager)
+    {
+    }
+
+    /**
+     * Setups configuration for the extension.
+     *
+     * @param ArrayNodeDefinition $builder
+     */
+    public function configure(ArrayNodeDefinition $builder)
+    {
+    }
+
+    /**
+     * Loads extension services into temporary container.
+     *
+     * @param ContainerBuilder $container
+     * @param array $config
+     */
+    public function load(ContainerBuilder $container, array $config)
+    {
+        $this->loadOrderController($container);
+        $this->loadOrderedExercise($container);
+        $this->loadDefaultOrderers($container);
+    }
+
+    /**
+     * Loads order controller.
+     *
+     * @param ContainerBuilder $container
+     */
+    private function loadOrderController(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Testwork\Ordering\Cli\OrderController', array(
+            new Reference(EventDispatcherExtension::DISPATCHER_ID),
+            new Reference(TesterExtension::EXERCISE_WRAPPER_TAG . '.ordering')
+        ));
+        $definition->addTag(CliExtension::CONTROLLER_TAG, array('priority' => 250));
+        $container->setDefinition(CliExtension::CONTROLLER_TAG . '.order', $definition);
+    }
+
+    /**
+     * Loads exercise wrapper that enables ordering
+     *
+     * @param ContainerBuilder $container
+     */
+    private function loadOrderedExercise(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Testwork\Ordering\OrderedExercise', array(
+            new Reference(TesterExtension::EXERCISE_ID)
+        ));
+        $definition->addTag(TesterExtension::EXERCISE_WRAPPER_TAG, array('priority' => -9999));
+        $container->setDefinition(TesterExtension::EXERCISE_WRAPPER_TAG . '.ordering', $definition);
+    }
+
+    /**
+     * Defines default orderers
+     *
+     * @param ContainerBuilder $container
+     */
+    private function loadDefaultOrderers(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Testwork\Ordering\Orderer\ReverseOrderer');
+        $definition->addTag(self::ORDERER_TAG, array('priority' => -9999));
+        $container->setDefinition(TesterExtension::EXERCISE_WRAPPER_TAG . '.ordering.reverse', $definition);
+
+
+        $definition = new Definition('Behat\Testwork\Ordering\Orderer\RandomOrderer');
+        $definition->addTag(self::ORDERER_TAG, array('priority' => -9999));
+        $container->setDefinition(TesterExtension::EXERCISE_WRAPPER_TAG . '.ordering.random', $definition);
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Output/Cli/OutputController.php b/vendor/behat/behat/src/Behat/Testwork/Output/Cli/OutputController.php
new file mode 100644 (file)
index 0000000..ae88651
--- /dev/null
@@ -0,0 +1,253 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Output\Cli;
+
+use Behat\Testwork\Cli\Controller;
+use Behat\Testwork\Output\Formatter;
+use Behat\Testwork\Output\OutputManager;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * Configures formatters based on user input.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class OutputController implements Controller
+{
+    /**
+     * @var OutputManager
+     */
+    private $manager;
+
+    /**
+     * Initializes controller.
+     *
+     * @param OutputManager $manager
+     */
+    public function __construct(OutputManager $manager)
+    {
+        $this->manager = $manager;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function configure(Command $command)
+    {
+        $command
+            ->addOption(
+                '--format', '-f', InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
+                'How to format tests output. <comment>pretty</comment> is default.' . PHP_EOL .
+                'Available formats are:' . PHP_EOL . $this->getFormatterDescriptions() .
+                'You can use multiple formats at the same time.'
+            )
+            ->addOption(
+                '--out', '-o', InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
+                'Write format output to a file/directory instead of' . PHP_EOL .
+                'STDOUT <comment>(output_path)</comment>. You can also provide different' . PHP_EOL .
+                'outputs to multiple formats.'
+            )
+            ->addOption(
+                '--format-settings', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
+                'Set formatters parameters using json object.' . PHP_EOL .
+                'Keys are parameter names, values are values.'
+            );
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function execute(InputInterface $input, OutputInterface $output)
+    {
+        $formats = $input->getOption('format');
+        $outputs = $input->getOption('out');
+
+        $this->configureFormatters($formats, $input, $output);
+        $this->configureOutputs($formats, $outputs, $output->isDecorated());
+    }
+
+    /**
+     * Configures formatters based on container, input and output configurations.
+     *
+     * @param array           $formats
+     * @param InputInterface  $input
+     * @param OutputInterface $output
+     */
+    protected function configureFormatters(array $formats, InputInterface $input, OutputInterface $output)
+    {
+        $this->enableFormatters($formats);
+        $this->setFormattersParameters($input, $output);
+    }
+
+    /**
+     * Enables formatters.
+     *
+     * @param array $formats
+     */
+    protected function enableFormatters(array $formats)
+    {
+        if (count($formats)) {
+            $this->manager->disableAllFormatters();
+            foreach ($formats as $format) {
+                $this->manager->enableFormatter($format);
+            }
+        }
+    }
+
+    /**
+     * Sets formatters parameters based on input & output.
+     *
+     * @param InputInterface  $input
+     * @param OutputInterface $output
+     */
+    protected function setFormattersParameters(InputInterface $input, OutputInterface $output)
+    {
+        $this->manager->setFormattersParameter('output_decorate', $output->isDecorated());
+
+        if ($input->getOption('format-settings')) {
+            foreach ($input->getOption('format-settings') as $jsonSettings) {
+                $this->loadJsonSettings($jsonSettings);
+            }
+        }
+    }
+
+    /**
+     * Locates output path from relative one.
+     *
+     * @param string $path
+     *
+     * @return string
+     */
+    protected function locateOutputPath($path)
+    {
+        if ($this->isAbsolutePath($path)) {
+            return $path;
+        }
+
+        $path = getcwd() . DIRECTORY_SEPARATOR . $path;
+
+        if (!file_exists($path)) {
+            touch($path);
+            $path = realpath($path);
+            unlink($path);
+        } else {
+            $path = realpath($path);
+        }
+
+        return $path;
+    }
+
+    /**
+     * Initializes multiple formatters with different outputs.
+     *
+     * @param array   $formats
+     * @param array   $outputs
+     * @param Boolean $decorated
+     */
+    private function configureOutputs(array $formats, array $outputs, $decorated = false)
+    {
+        if (1 == count($outputs) && !$this->isStandardOutput($outputs[0])) {
+            $outputPath = $this->locateOutputPath($outputs[0]);
+
+            $this->manager->setFormattersParameter('output_path', $outputPath);
+            $this->manager->setFormattersParameter('output_decorate', $decorated);
+
+            return;
+        }
+
+        foreach ($outputs as $i => $out) {
+            if ($this->isStandardOutput($out)) {
+                continue;
+            }
+
+            $outputPath = $this->locateOutputPath($out);
+            if (isset($formats[$i])) {
+                $this->manager->setFormatterParameter($formats[$i], 'output_path', $outputPath);
+                $this->manager->setFormatterParameter($formats[$i], 'output_decorate', $decorated);
+            }
+        }
+    }
+
+    /**
+     * Checks if provided output identifier represents standard output.
+     *
+     * @param string $outputId
+     *
+     * @return Boolean
+     */
+    private function isStandardOutput($outputId)
+    {
+        return 'std' === $outputId || 'null' === $outputId || 'false' === $outputId;
+    }
+
+    /**
+     * Returns whether the file path is an absolute path.
+     *
+     * @param string $file A file path
+     *
+     * @return Boolean
+     */
+    private function isAbsolutePath($file)
+    {
+        if ($file[0] == '/' || $file[0] == '\\'
+            || (strlen($file) > 3 && ctype_alpha($file[0])
+                && $file[1] == ':'
+                && ($file[2] == '\\' || $file[2] == '/')
+            )
+            || null !== parse_url($file, PHP_URL_SCHEME)
+        ) {
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Returns formatters description.
+     *
+     * @return string
+     */
+    private function getFormatterDescriptions()
+    {
+        return implode(
+            PHP_EOL,
+            array_map(
+                function (Formatter $formatter) {
+                    $comment = '- <comment>' . $formatter->getName() . '</comment>: ';
+                    $comment .= $formatter->getDescription();
+
+                    return $comment;
+                }, $this->manager->getFormatters()
+            )
+        ) . PHP_EOL;
+    }
+
+    /**
+     * Loads JSON settings as formatter parameters.
+     *
+     * @param string $jsonSettings
+     */
+    private function loadJsonSettings($jsonSettings)
+    {
+        $settings = @json_decode($jsonSettings, true);
+
+        if (!is_array($settings)) {
+            return;
+        }
+
+        foreach ($settings as $name => $value) {
+            $this->manager->setFormattersParameter($name, $value);
+        }
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Output/Exception/BadOutputPathException.php b/vendor/behat/behat/src/Behat/Testwork/Output/Exception/BadOutputPathException.php
new file mode 100644 (file)
index 0000000..edd773c
--- /dev/null
@@ -0,0 +1,49 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Output\Exception;
+
+use InvalidArgumentException;
+
+/**
+ * Represents an exception thrown because user provided bad output path.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class BadOutputPathException extends InvalidArgumentException implements PrinterException
+{
+    /**
+     * @var string
+     */
+    private $path;
+
+    /**
+     * Initializes exception.
+     *
+     * @param string $message
+     * @param string $path
+     */
+    public function __construct($message, $path)
+    {
+        $this->path = $path;
+
+        parent::__construct($message);
+    }
+
+    /**
+     * Returns exception causing path.
+     *
+     * @return string
+     */
+    public function getPath()
+    {
+        return $this->path;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Output/Exception/FormatterNotFoundException.php b/vendor/behat/behat/src/Behat/Testwork/Output/Exception/FormatterNotFoundException.php
new file mode 100644 (file)
index 0000000..43b3371
--- /dev/null
@@ -0,0 +1,47 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Output\Exception;
+
+use InvalidArgumentException;
+
+/**
+ * Represents an exception thrown because requested formatter is not found.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class FormatterNotFoundException extends InvalidArgumentException implements OutputException
+{
+    /**
+     * @var string
+     */
+    private $name;
+
+    /**
+     * Initializes exception.
+     *
+     * @param string $message
+     * @param string $name
+     */
+    public function __construct($message, $name)
+    {
+        parent::__construct($message);
+    }
+
+    /**
+     * Returns formatter name.
+     *
+     * @return string
+     */
+    public function getName()
+    {
+        return $this->name;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Output/Exception/OutputException.php b/vendor/behat/behat/src/Behat/Testwork/Output/Exception/OutputException.php
new file mode 100644 (file)
index 0000000..cba1a7d
--- /dev/null
@@ -0,0 +1,22 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Output\Exception;
+
+use Behat\Testwork\Exception\TestworkException;
+
+/**
+ * Represents an output exception.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface OutputException extends TestworkException
+{
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Output/Exception/PrinterException.php b/vendor/behat/behat/src/Behat/Testwork/Output/Exception/PrinterException.php
new file mode 100644 (file)
index 0000000..283ed14
--- /dev/null
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Output\Exception;
+
+/**
+ * Represents a printer exception.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface PrinterException extends OutputException
+{
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Output/Formatter.php b/vendor/behat/behat/src/Behat/Testwork/Output/Formatter.php
new file mode 100644 (file)
index 0000000..23a87c6
--- /dev/null
@@ -0,0 +1,62 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Output;
+
+use Behat\Testwork\Output\Printer\OutputPrinter;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+
+/**
+ * Represents Testwork output formatter.
+ *
+ * @see OutputManager
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface Formatter extends EventSubscriberInterface
+{
+    /**
+     * Returns formatter name.
+     *
+     * @return string
+     */
+    public function getName();
+
+    /**
+     * Returns formatter description.
+     *
+     * @return string
+     */
+    public function getDescription();
+
+    /**
+     * Returns formatter output printer.
+     *
+     * @return OutputPrinter
+     */
+    public function getOutputPrinter();
+
+    /**
+     * Sets formatter parameter.
+     *
+     * @param string $name
+     * @param mixed  $value
+     */
+    public function setParameter($name, $value);
+
+    /**
+     * Returns parameter name.
+     *
+     * @param string $name
+     *
+     * @return mixed
+     */
+    public function getParameter($name);
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Output/Node/EventListener/ChainEventListener.php b/vendor/behat/behat/src/Behat/Testwork/Output/Node/EventListener/ChainEventListener.php
new file mode 100644 (file)
index 0000000..0c76bac
--- /dev/null
@@ -0,0 +1,66 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Output\Node\EventListener;
+
+use ArrayIterator;
+use Behat\Testwork\Output\Formatter;
+use Countable;
+use IteratorAggregate;
+use Symfony\Component\EventDispatcher\Event;
+
+/**
+ * Used to compose formatter event listeners.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class ChainEventListener implements EventListener, Countable, IteratorAggregate
+{
+    /**
+     * @var EventListener[]
+     */
+    private $listeners;
+
+    /**
+     * Initializes collection.
+     *
+     * @param EventListener[] $listeners
+     */
+    public function __construct(array $listeners)
+    {
+        $this->listeners = $listeners;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function listenEvent(Formatter $formatter, Event $event, $eventName)
+    {
+        foreach ($this->listeners as $listener) {
+            $listener->listenEvent($formatter, $event, $eventName);
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function count()
+    {
+        return count($this->listeners);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getIterator()
+    {
+        return new ArrayIterator($this->listeners);
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Output/Node/EventListener/EventListener.php b/vendor/behat/behat/src/Behat/Testwork/Output/Node/EventListener/EventListener.php
new file mode 100644 (file)
index 0000000..6fbc078
--- /dev/null
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Output\Node\EventListener;
+
+use Behat\Testwork\Output\Formatter;
+use Symfony\Component\EventDispatcher\Event;
+
+/**
+ * Used to define formatter event listeners.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface EventListener
+{
+    /**
+     * Notifies listener about an event.
+     *
+     * @param Formatter $formatter
+     * @param Event     $event
+     * @param string    $eventName
+     */
+    public function listenEvent(Formatter $formatter, Event $event, $eventName);
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Output/Node/EventListener/Flow/FireOnlyIfFormatterParameterListener.php b/vendor/behat/behat/src/Behat/Testwork/Output/Node/EventListener/Flow/FireOnlyIfFormatterParameterListener.php
new file mode 100644 (file)
index 0000000..0df21eb
--- /dev/null
@@ -0,0 +1,62 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Output\Node\EventListener\Flow;
+
+use Behat\Testwork\Output\Formatter;
+use Behat\Testwork\Output\Node\EventListener\EventListener;
+use Symfony\Component\EventDispatcher\Event;
+
+/**
+ * Catches all events, but proxies them only if formatter has specific parameter set to a specific value.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class FireOnlyIfFormatterParameterListener implements EventListener
+{
+    /**
+     * @var string
+     */
+    private $name;
+    /**
+     * @var mixed
+     */
+    private $value;
+    /**
+     * @var EventListener
+     */
+    private $descendant;
+
+    /**
+     * Initializes listener.
+     *
+     * @param string        $name
+     * @param mixed         $value
+     * @param EventListener $descendant
+     */
+    public function __construct($name, $value, EventListener $descendant)
+    {
+        $this->name = $name;
+        $this->value = $value;
+        $this->descendant = $descendant;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function listenEvent(Formatter $formatter, Event $event, $eventName)
+    {
+        if ($this->value !== $formatter->getParameter($this->name)) {
+            return;
+        }
+
+        $this->descendant->listenEvent($formatter, $event, $eventName);
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Output/NodeEventListeningFormatter.php b/vendor/behat/behat/src/Behat/Testwork/Output/NodeEventListeningFormatter.php
new file mode 100644 (file)
index 0000000..3894d49
--- /dev/null
@@ -0,0 +1,126 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Output;
+
+use Behat\Testwork\EventDispatcher\TestworkEventDispatcher;
+use Behat\Testwork\Output\Node\EventListener\EventListener;
+use Behat\Testwork\Output\Printer\OutputPrinter;
+use Symfony\Component\EventDispatcher\Event;
+
+/**
+ * Formatter built around the idea of event delegation and composition.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class NodeEventListeningFormatter implements Formatter
+{
+    /**
+     * @var OutputPrinter
+     */
+    private $printer;
+    /**
+     * @var array
+     */
+    private $parameters;
+    /**
+     * @var EventListener
+     */
+    private $listener;
+    /**
+     * @var string
+     */
+    private $name;
+    /**
+     * @var string
+     */
+    private $description;
+
+    /**
+     * Initializes formatter.
+     *
+     * @param string        $name
+     * @param string        $description
+     * @param array         $parameters
+     * @param OutputPrinter $printer
+     * @param EventListener $listener
+     */
+    public function __construct($name, $description, array $parameters, OutputPrinter $printer, EventListener $listener)
+    {
+        $this->name = $name;
+        $this->description = $description;
+        $this->parameters = $parameters;
+        $this->printer = $printer;
+        $this->listener = $listener;
+    }
+
+    /**
+     * Returns an array of event names this subscriber wants to listen to.
+     *
+     * @return array The event names to listen to
+     */
+    public static function getSubscribedEvents()
+    {
+        return array(TestworkEventDispatcher::BEFORE_ALL_EVENTS => 'listenEvent');
+    }
+
+    /**
+     * Proxies event to the listener.
+     *
+     * @param Event       $event
+     * @param null|string $eventName
+     */
+    public function listenEvent(Event $event, $eventName = null)
+    {
+        $eventName = $eventName ?: $event->getName();
+
+        $this->listener->listenEvent($this, $event, $eventName);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getName()
+    {
+        return $this->name;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getDescription()
+    {
+        return $this->description;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getOutputPrinter()
+    {
+        return $this->printer;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setParameter($name, $value)
+    {
+        $this->parameters[$name] = $value;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getParameter($name)
+    {
+        return isset($this->parameters[$name]) ? $this->parameters[$name] : null;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Output/OutputManager.php b/vendor/behat/behat/src/Behat/Testwork/Output/OutputManager.php
new file mode 100644 (file)
index 0000000..cdf7760
--- /dev/null
@@ -0,0 +1,208 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Output;
+
+use Behat\Testwork\Output\Exception\FormatterNotFoundException;
+use Symfony\Component\EventDispatcher\EventDispatcherInterface;
+
+/**
+ * Manages formatters and their configuration.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class OutputManager
+{
+    /**
+     * @var EventDispatcherInterface
+     */
+    private $eventDispatcher;
+    /**
+     * @var Formatter[]
+     */
+    private $formatters = array();
+
+    /**
+     * Initializes manager.
+     *
+     * @param EventDispatcherInterface $eventDispatcher
+     */
+    public function __construct(EventDispatcherInterface $eventDispatcher)
+    {
+        $this->eventDispatcher = $eventDispatcher;
+    }
+
+    /**
+     * Registers formatter.
+     *
+     * @param Formatter $formatter
+     */
+    public function registerFormatter(Formatter $formatter)
+    {
+        if (isset($this->formatters[$formatter->getName()])) {
+            $this->disableFormatter($formatter->getName());
+        }
+
+        $this->formatters[$formatter->getName()] = $formatter;
+    }
+
+    /**
+     * Checks if formatter is registered.
+     *
+     * @param string $name
+     *
+     * @return Boolean
+     */
+    public function isFormatterRegistered($name)
+    {
+        return isset($this->formatters[$name]);
+    }
+
+    /**
+     * Returns formatter by name provided.
+     *
+     * @param string $name
+     *
+     * @return Formatter
+     *
+     * @throws FormatterNotFoundException
+     */
+    public function getFormatter($name)
+    {
+        if (!$this->isFormatterRegistered($name)) {
+            throw new FormatterNotFoundException(sprintf(
+                '`%s` formatter is not found or has not been properly registered. Registered formatters: `%s`.',
+                $name,
+                implode('`, `', array_keys($this->formatters))
+            ), $name);
+        }
+
+        return $this->formatters[$name];
+    }
+
+    /**
+     * Returns all registered formatters.
+     *
+     * @return Formatter[]
+     */
+    public function getFormatters()
+    {
+        return $this->formatters;
+    }
+
+    /**
+     * Enable formatter by name provided.
+     *
+     * @param string $formatter
+     */
+    public function enableFormatter($formatter)
+    {
+        if (!$this->isFormatterRegistered($formatter) && class_exists($formatter)) {
+            $formatterInstance = new $formatter();
+            $formatter = $formatterInstance->getName();
+
+            if (!$this->isFormatterRegistered($formatter)) {
+                $this->registerFormatter($formatterInstance);
+            }
+        }
+
+        $this->eventDispatcher->addSubscriber($this->getFormatter($formatter));
+    }
+
+    /**
+     * Disable formatter by name provided.
+     *
+     * @param string $formatter
+     */
+    public function disableFormatter($formatter)
+    {
+        $this->eventDispatcher->removeSubscriber($this->getFormatter($formatter));
+    }
+
+    /**
+     * Disable all registered formatters.
+     */
+    public function disableAllFormatters()
+    {
+        array_map(array($this, 'disableFormatter'), array_keys($this->formatters));
+    }
+
+    /**
+     * Sets provided parameter to said formatter.
+     *
+     * @param string $formatter
+     * @param string $parameterName
+     * @param mixed  $parameterValue
+     */
+    public function setFormatterParameter($formatter, $parameterName, $parameterValue)
+    {
+        $formatter = $this->getFormatter($formatter);
+        $printer = $formatter->getOutputPrinter();
+
+        switch ($parameterName) {
+            case 'output_verbosity':
+                $printer->setOutputVerbosity($parameterValue);
+
+                return;
+            case 'output_path':
+                $printer->setOutputPath($parameterValue);
+
+                return;
+            case 'output_decorate':
+                $printer->setOutputDecorated($parameterValue);
+
+                return;
+            case 'output_styles':
+                $printer->setOutputStyles($parameterValue);
+
+                return;
+        }
+
+        $formatter->setParameter($parameterName, $parameterValue);
+    }
+
+    /**
+     * Sets provided formatter parameters.
+     *
+     * @param string $formatter
+     * @param array  $parameters
+     */
+    public function setFormatterParameters($formatter, array $parameters)
+    {
+        foreach ($parameters as $key => $val) {
+            $this->setFormatterParameter($formatter, $key, $val);
+        }
+    }
+
+    /**
+     * Sets provided parameter to all registered formatters.
+     *
+     * @param string $parameterName
+     * @param mixed  $parameterValue
+     */
+    public function setFormattersParameter($parameterName, $parameterValue)
+    {
+        foreach (array_keys($this->formatters) as $formatter) {
+            $this->setFormatterParameter($formatter, $parameterName, $parameterValue);
+        }
+    }
+
+    /**
+     * Sets provided parameters to all registered formatters.
+     *
+     * @param array $parameters
+     */
+    public function setFormattersParameters(array $parameters)
+    {
+        foreach ($parameters as $key => $val) {
+            $this->setFormattersParameter($key, $val);
+        }
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Output/Printer/Factory/ConsoleOutputFactory.php b/vendor/behat/behat/src/Behat/Testwork/Output/Printer/Factory/ConsoleOutputFactory.php
new file mode 100644 (file)
index 0000000..e1d22ee
--- /dev/null
@@ -0,0 +1,112 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Output\Printer\Factory;
+
+use Behat\Testwork\Output\Exception\BadOutputPathException;
+use Symfony\Component\Console\Formatter\OutputFormatter;
+use Symfony\Component\Console\Formatter\OutputFormatterStyle;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Output\StreamOutput;
+
+/**
+ * Creates an output stream for the console.
+ *
+ * @author Wouter J <wouter@wouterj.nl>
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class ConsoleOutputFactory extends OutputFactory
+{
+    /**
+     * Creates output formatter that is used to create a stream.
+     *
+     * @return OutputFormatter
+     */
+    protected function createOutputFormatter()
+    {
+        return new OutputFormatter();
+    }
+
+    /**
+     * Configure output stream parameters.
+     *
+     * @param OutputInterface $output
+     */
+    protected function configureOutputStream(OutputInterface $output)
+    {
+        $verbosity = $this->getOutputVerbosity() ? OutputInterface::VERBOSITY_VERBOSE : OutputInterface::VERBOSITY_NORMAL;
+        $output->setVerbosity($verbosity);
+
+        if (null !== $this->isOutputDecorated()) {
+            $output->getFormatter()->setDecorated($this->isOutputDecorated());
+        }
+    }
+
+    /**
+     * Returns new output stream.
+     *
+     * Override this method & call flush() to write output in another stream
+     *
+     * @return resource
+     *
+     * @throws BadOutputPathException
+     */
+    protected function createOutputStream()
+    {
+        if (null === $this->getOutputPath()) {
+            $stream = fopen('php://stdout', 'w');
+        } elseif (!is_dir($this->getOutputPath())) {
+            $stream = fopen($this->getOutputPath(), 'w');
+        } else {
+            throw new BadOutputPathException(sprintf(
+                'Filename expected as `output_path` parameter, but got `%s`.',
+                $this->getOutputPath()
+            ), $this->getOutputPath());
+        }
+
+        return $stream;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function createOutput($stream = null)
+    {
+        $stream = $stream ? : $this->createOutputStream();
+        $format = $this->createOutputFormatter();
+
+        // set user-defined styles
+        foreach ($this->getOutputStyles() as $name => $options) {
+            $style = new OutputFormatterStyle();
+
+            if (isset($options[0])) {
+                $style->setForeground($options[0]);
+            }
+            if (isset($options[1])) {
+                $style->setBackground($options[1]);
+            }
+            if (isset($options[2])) {
+                $style->setOptions($options[2]);
+            }
+
+            $format->setStyle($name, $style);
+        }
+
+        $output = new StreamOutput(
+            $stream,
+            StreamOutput::VERBOSITY_NORMAL,
+            $this->isOutputDecorated(),
+            $format
+        );
+        $this->configureOutputStream($output);
+
+        return $output;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Output/Printer/Factory/FilesystemOutputFactory.php b/vendor/behat/behat/src/Behat/Testwork/Output/Printer/Factory/FilesystemOutputFactory.php
new file mode 100644 (file)
index 0000000..af98202
--- /dev/null
@@ -0,0 +1,71 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Output\Printer\Factory;
+
+use Behat\Testwork\Output\Exception\BadOutputPathException;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Output\StreamOutput;
+
+/**
+ * Creates an output stream for the filesystem.
+ *
+ * @author Wouter J <wouter@wouterj.nl>
+ */
+class FilesystemOutputFactory extends OutputFactory
+{
+    private $fileName;
+
+    public function setFileName($fileName)
+    {
+        $this->fileName = $fileName;
+    }
+
+    /**
+     * Configure output stream parameters.
+     *
+     * @param OutputInterface $output
+     */
+    protected function configureOutputStream(OutputInterface $output)
+    {
+        $verbosity = $this->getOutputVerbosity() ? OutputInterface::VERBOSITY_VERBOSE : OutputInterface::VERBOSITY_NORMAL;
+        $output->setVerbosity($verbosity);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function createOutput($stream = null)
+    {
+        if (is_file($this->getOutputPath())) {
+            throw new BadOutputPathException(
+                'Directory expected for the `output_path` option, but a filename was given.',
+                $this->getOutputPath()
+            );
+        } elseif (!is_dir($this->getOutputPath())) {
+            mkdir($this->getOutputPath(), 0777, true);
+        }
+
+        if (null === $this->fileName) {
+            throw new \LogicException('Unable to create file, no file name specified');
+        }
+
+        $filePath = $this->getOutputPath().'/'.$this->fileName;
+
+        $stream = new StreamOutput(
+            fopen($filePath, 'w'),
+            StreamOutput::VERBOSITY_NORMAL,
+            false // a file is never decorated
+        );
+        $this->configureOutputStream($stream);
+
+        return $stream;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Output/Printer/Factory/OutputFactory.php b/vendor/behat/behat/src/Behat/Testwork/Output/Printer/Factory/OutputFactory.php
new file mode 100644 (file)
index 0000000..20f47d3
--- /dev/null
@@ -0,0 +1,129 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Output\Printer\Factory;
+
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * @author Wouter J <wouter@wouterj.nl>
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+abstract class OutputFactory
+{
+    const VERBOSITY_NORMAL       = 1;
+    const VERBOSITY_VERBOSE      = 2;
+    const VERBOSITY_VERY_VERBOSE = 3;
+    const VERBOSITY_DEBUG        = 4;
+
+    /**
+     * @var null|string
+     */
+    private $outputPath;
+    /**
+     * @var array
+     */
+    private $outputStyles = array();
+    /**
+     * @var null|Boolean
+     */
+    private $outputDecorated = null;
+    /**
+     * @var integer
+     */
+    private $verbosityLevel = 0;
+
+    /**
+     * Sets output path.
+     *
+     * @param string $path
+     */
+    public function setOutputPath($path)
+    {
+        $this->outputPath = $path;
+    }
+
+    /**
+     * Returns output path.
+     *
+     * @return null|string
+     */
+    public function getOutputPath()
+    {
+        return $this->outputPath;
+    }
+
+    /**
+     * Sets output styles.
+     *
+     * @param array $styles
+     */
+    public function setOutputStyles(array $styles)
+    {
+        $this->outputStyles = $styles;
+    }
+
+    /**
+     * Returns output styles.
+     *
+     * @return array
+     */
+    public function getOutputStyles()
+    {
+        return $this->outputStyles;
+    }
+
+    /**
+     * Forces output to be decorated.
+     *
+     * @param Boolean $decorated
+     */
+    public function setOutputDecorated($decorated)
+    {
+        $this->outputDecorated = $decorated;
+    }
+
+    /**
+     * Returns output decoration status.
+     *
+     * @return null|Boolean
+     */
+    public function isOutputDecorated()
+    {
+        return $this->outputDecorated;
+    }
+
+    /**
+     * Sets output verbosity level.
+     *
+     * @param integer $level
+     */
+    public function setOutputVerbosity($level)
+    {
+        $this->verbosityLevel = intval($level);
+    }
+
+    /**
+     * Returns output verbosity level.
+     *
+     * @return integer
+     */
+    public function getOutputVerbosity()
+    {
+        return $this->verbosityLevel;
+    }
+
+    /**
+     * Returns a new output stream.
+     *
+     * @return OutputInterface
+     */
+    abstract public function createOutput();
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Output/Printer/JUnitOutputPrinter.php b/vendor/behat/behat/src/Behat/Testwork/Output/Printer/JUnitOutputPrinter.php
new file mode 100644 (file)
index 0000000..7577e11
--- /dev/null
@@ -0,0 +1,148 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Output\Printer;
+
+use Behat\Testwork\Output\Printer\Factory\FilesystemOutputFactory;
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * A convenient wrapper around the ConsoleOutputPrinter to write valid JUnit
+ * reports.
+ *
+ * @author Wouter J <wouter@wouterj.nl>
+ * @author James Watson <james@sitepulse.org>
+ */
+final class JUnitOutputPrinter extends StreamOutputPrinter
+{
+    const XML_VERSION  = '1.0';
+    const XML_ENCODING = 'UTF-8';
+
+    /**
+     * @var \DOMDocument
+     */
+    private $domDocument;
+    /**
+     * @var \DOMElement
+     */
+    private $currentTestsuite;
+    /**
+     * @var \DOMElement
+     */
+    private $currentTestcase;
+    /**
+     * @var \DOMElement
+     */
+    private $testSuites;
+
+    public function __construct(FilesystemOutputFactory $outputFactory)
+    {
+        parent::__construct($outputFactory);
+    }
+
+    /**
+     * Creates a new JUnit file.
+     *
+     * The file will be initialized with an XML definition and the root element.
+     *
+     * @param string $name                 The filename (without extension) and default value of the name attribute
+     * @param array  $testsuitesAttributes Attributes for the root element
+     */
+    public function createNewFile($name, array $testsuitesAttributes = array())
+    {
+        $this->setFileName(strtolower(trim(preg_replace('/[^[:alnum:]_]+/', '_', $name), '_')));
+
+        $this->domDocument = new \DOMDocument(self::XML_VERSION, self::XML_ENCODING);
+        $this->domDocument->formatOutput = true;
+
+        $this->testSuites = $this->domDocument->createElement('testsuites');
+        $this->domDocument->appendChild($this->testSuites);
+        $this->addAttributesToNode($this->testSuites, array_merge(array('name' => $name), $testsuitesAttributes));
+        $this->flush();
+    }
+
+    /**
+     * Adds a new <testsuite> node.
+     *
+     * @param array $testsuiteAttributes
+     */
+    public function addTestsuite(array $testsuiteAttributes = array())
+    {
+        $this->currentTestsuite = $this->domDocument->createElement('testsuite');
+        $this->testSuites->appendChild($this->currentTestsuite);
+        $this->addAttributesToNode($this->currentTestsuite, $testsuiteAttributes);
+    }
+
+
+    /**
+     * Adds a new <testcase> node.
+     *
+     * @param array $testcaseAttributes
+     */
+    public function addTestcase(array $testcaseAttributes = array())
+    {
+        $this->currentTestcase = $this->domDocument->createElement('testcase');
+        $this->currentTestsuite->appendChild($this->currentTestcase);
+        $this->addAttributesToNode($this->currentTestcase, $testcaseAttributes);
+    }
+
+    /**
+     * Add a testcase child element.
+     *
+     * @param string $nodeName
+     * @param array  $nodeAttributes
+     * @param string $nodeValue
+     */
+    public function addTestcaseChild($nodeName, array $nodeAttributes = array(), $nodeValue = null)
+    {
+        $childNode = $this->domDocument->createElement($nodeName, $nodeValue);
+        $this->currentTestcase->appendChild($childNode);
+        $this->addAttributesToNode($childNode, $nodeAttributes);
+    }
+
+    private function addAttributesToNode(\DOMElement $node, array $attributes)
+    {
+        foreach ($attributes as $name => $value){
+            $node->setAttribute($name, $value);
+        }
+    }
+
+    /**
+     * Sets file name.
+     *
+     * @param string $fileName
+     * @param string $extension The file extension, defaults to "xml"
+     */
+    public function setFileName($fileName, $extension = 'xml')
+    {
+        if ('.'.$extension !== substr($fileName, strlen($extension) + 1)) {
+            $fileName .= '.'.$extension;
+        }
+
+        $this->getOutputFactory()->setFileName($fileName);
+        $this->flush();
+    }
+
+    /**
+     * Generate XML from the DOMDocument and parse to the the writing stream
+     */
+    public function flush()
+    {
+        if($this->domDocument instanceof \DOMDocument){
+            $this->getWritingStream()->write(
+                $this->domDocument->saveXML(null, LIBXML_NOEMPTYTAG),
+                false,
+                OutputInterface::OUTPUT_RAW
+            );
+        }
+
+        parent::flush();
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Output/Printer/OutputPrinter.php b/vendor/behat/behat/src/Behat/Testwork/Output/Printer/OutputPrinter.php
new file mode 100644 (file)
index 0000000..91292d3
--- /dev/null
@@ -0,0 +1,119 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Output\Printer;
+
+/**
+ * Isolates all console/filesystem writing.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface OutputPrinter
+{
+    /**
+     * @deprecated since 3.1, to be removed in 4.0
+     */
+    const VERBOSITY_NORMAL       = 1;
+    /**
+     * @deprecated since 3.1, to be removed in 4.0
+     */
+    const VERBOSITY_VERBOSE      = 2;
+    /**
+     * @deprecated since 3.1, to be removed in 4.0
+     */
+    const VERBOSITY_VERY_VERBOSE = 3;
+    /**
+     * @deprecated since 3.1, to be removed in 4.0
+     */
+    const VERBOSITY_DEBUG        = 4;
+
+    /**
+     * Sets output path.
+     *
+     * @param string $path
+     */
+    public function setOutputPath($path);
+
+    /**
+     * Returns output path.
+     *
+     * @return null|string
+     *
+     * @deprecated since 3.1, to be removed in 4.0
+     */
+    public function getOutputPath();
+
+    /**
+     * Sets output styles.
+     *
+     * @param array $styles
+     */
+    public function setOutputStyles(array $styles);
+
+    /**
+     * Returns output styles.
+     *
+     * @return array
+     *
+     * @deprecated since 3.1, to be removed in 4.0
+     */
+    public function getOutputStyles();
+
+    /**
+     * Forces output to be decorated.
+     *
+     * @param Boolean $decorated
+     */
+    public function setOutputDecorated($decorated);
+
+    /**
+     * Returns output decoration status.
+     *
+     * @return null|Boolean
+     *
+     * @deprecated since 3.1, to be removed in 4.0
+     */
+    public function isOutputDecorated();
+
+    /**
+     * Sets output verbosity level.
+     *
+     * @param integer $level
+     */
+    public function setOutputVerbosity($level);
+
+    /**
+     * Returns output verbosity level.
+     *
+     * @return integer
+     *
+     * @deprecated since 3.1, to be removed in 4.0
+     */
+    public function getOutputVerbosity();
+
+    /**
+     * Writes message(s) to output stream.
+     *
+     * @param string|array $messages message or array of messages
+     */
+    public function write($messages);
+
+    /**
+     * Writes newlined message(s) to output stream.
+     *
+     * @param string|array $messages message or array of messages
+     */
+    public function writeln($messages = '');
+
+    /**
+     * Clear output stream, so on next write formatter will need to init (create) it again.
+     */
+    public function flush();
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Output/Printer/StreamOutputPrinter.php b/vendor/behat/behat/src/Behat/Testwork/Output/Printer/StreamOutputPrinter.php
new file mode 100644 (file)
index 0000000..6b3fb4e
--- /dev/null
@@ -0,0 +1,149 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Output\Printer;
+
+use Behat\Testwork\Output\Printer\Factory\OutputFactory;
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * @author Wouter J <wouter@wouterj.nl>
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class StreamOutputPrinter implements OutputPrinter
+{
+    /**
+     * @var OutputInterface
+     */
+    private $output;
+    /**
+     * @var OutputFactory
+     */
+    private $outputFactory;
+
+    public function __construct(OutputFactory $outputFactory)
+    {
+        $this->outputFactory = $outputFactory;
+    }
+
+    /**
+     * @return OutputFactory
+     */
+    protected function getOutputFactory()
+    {
+        return $this->outputFactory;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setOutputPath($path)
+    {
+        $this->outputFactory->setOutputPath($path);
+        $this->flush();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getOutputPath()
+    {
+        return $this->outputFactory->getOutputPath();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setOutputStyles(array $styles)
+    {
+        $this->outputFactory->setOutputStyles($styles);
+        $this->flush();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getOutputStyles()
+    {
+        return $this->outputFactory->getOutputStyles();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setOutputDecorated($decorated)
+    {
+        $this->outputFactory->setOutputDecorated($decorated);
+        $this->flush();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function isOutputDecorated()
+    {
+        return $this->outputFactory->isOutputDecorated();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setOutputVerbosity($level)
+    {
+        $this->outputFactory->setOutputVerbosity($level);
+        $this->flush();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getOutputVerbosity()
+    {
+        return $this->outputFactory->getOutputVerbosity();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function write($messages)
+    {
+        $this->getWritingStream()->write($messages, false);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function writeln($messages = '')
+    {
+        $this->getWritingStream()->write($messages, true);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function flush()
+    {
+        $this->output = null;
+    }
+
+    /**
+     * Returns output instance, prepared to write.
+     *
+     * @return OutputInterface
+     */
+    final protected function getWritingStream()
+    {
+        if (null === $this->output) {
+            $this->output = $this->outputFactory->createOutput();
+        }
+
+        return $this->output;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Output/ServiceContainer/Formatter/FormatterFactory.php b/vendor/behat/behat/src/Behat/Testwork/Output/ServiceContainer/Formatter/FormatterFactory.php
new file mode 100644 (file)
index 0000000..c80b552
--- /dev/null
@@ -0,0 +1,35 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Output\ServiceContainer\Formatter;
+
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+
+/**
+ * Provides a way to easily define custom formatters.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface FormatterFactory
+{
+    /**
+     * Builds formatter configuration.
+     *
+     * @param ContainerBuilder $container
+     */
+    public function buildFormatter(ContainerBuilder $container);
+
+    /**
+     * Processes formatter configuration.
+     *
+     * @param ContainerBuilder $container
+     */
+    public function processFormatter(ContainerBuilder $container);
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Output/ServiceContainer/OutputExtension.php b/vendor/behat/behat/src/Behat/Testwork/Output/ServiceContainer/OutputExtension.php
new file mode 100644 (file)
index 0000000..f49babe
--- /dev/null
@@ -0,0 +1,223 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Output\ServiceContainer;
+
+use Behat\Testwork\Cli\ServiceContainer\CliExtension;
+use Behat\Testwork\EventDispatcher\ServiceContainer\EventDispatcherExtension;
+use Behat\Testwork\Output\ServiceContainer\Formatter\FormatterFactory;
+use Behat\Testwork\ServiceContainer\Extension;
+use Behat\Testwork\ServiceContainer\ExtensionManager;
+use Behat\Testwork\ServiceContainer\ServiceProcessor;
+use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Definition;
+use Symfony\Component\DependencyInjection\Reference;
+
+/**
+ * Provides output management services for testwork.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class OutputExtension implements Extension
+{
+    /*
+     * Available services
+     */
+    const MANAGER_ID = 'output.manager';
+
+    /*
+     * Available extension points
+     */
+    const FORMATTER_TAG = 'output.formatter';
+
+    /**
+     * @var string
+     */
+    private $defaultFormatter;
+    /**
+     * @var FormatterFactory[]
+     */
+    private $factories;
+    /**
+     * @var ServiceProcessor
+     */
+    private $processor;
+
+    /**
+     * Initializes extension.
+     *
+     * @param string                $defaultFormatter
+     * @param FormatterFactory[]    $formatterFactories
+     * @param null|ServiceProcessor $processor
+     */
+    public function __construct($defaultFormatter, array $formatterFactories, ServiceProcessor $processor = null)
+    {
+        $this->defaultFormatter = $defaultFormatter;
+        $this->factories = $formatterFactories;
+        $this->processor = $processor ? : new ServiceProcessor();
+    }
+
+    /**
+     * Registers formatter factory.
+     *
+     * @param FormatterFactory $factory
+     */
+    public function registerFormatterFactory(FormatterFactory $factory)
+    {
+        $this->factories[] = $factory;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getConfigKey()
+    {
+        return 'formatters';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function initialize(ExtensionManager $extensionManager)
+    {
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function configure(ArrayNodeDefinition $builder)
+    {
+        $builder
+            ->defaultValue(array($this->defaultFormatter => array('enabled' => true)))
+            ->useAttributeAsKey('name')
+            ->prototype('array')
+                ->beforeNormalization()
+                    ->ifTrue(function ($a) {
+                        return is_array($a) && !isset($a['enabled']);
+                    })
+                    ->then(function ($a) {
+                        return array_merge($a, array('enabled' => true));
+                    })
+                ->end()
+                ->useAttributeAsKey('name')
+                ->treatTrueLike(array('enabled' => true))
+                ->treatNullLike(array('enabled' => true))
+                ->treatFalseLike(array('enabled' => false))
+                ->prototype('variable')->end()
+            ->end()
+        ;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function load(ContainerBuilder $container, array $config)
+    {
+        $this->loadOutputController($container);
+        $this->loadFormatters($container);
+        $this->loadManager($container, $config);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function process(ContainerBuilder $container)
+    {
+        $this->processFormatters($container);
+        $this->processDynamicallyRegisteredFormatters($container);
+    }
+
+    /**
+     * Loads output controller.
+     *
+     * @param ContainerBuilder $container
+     */
+    private function loadOutputController(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Testwork\Output\Cli\OutputController', array(
+            new Reference(self::MANAGER_ID)
+        ));
+        $definition->addTag(CliExtension::CONTROLLER_TAG, array('priority' => 1000));
+        $container->setDefinition(CliExtension::CONTROLLER_TAG . '.output', $definition);
+    }
+
+    /**
+     * Loads output manager.
+     *
+     * @param ContainerBuilder $container
+     * @param array            $formatters
+     */
+    private function loadManager(ContainerBuilder $container, array $formatters)
+    {
+        $definition = new Definition('Behat\Testwork\Output\OutputManager', array(
+            new Reference(EventDispatcherExtension::DISPATCHER_ID)
+        ));
+
+        foreach ($formatters as $name => $parameters) {
+            if ($parameters['enabled']) {
+                $definition->addMethodCall('enableFormatter', array($name));
+            } else {
+                $definition->addMethodCall('disableFormatter', array($name));
+            }
+
+            unset($parameters['enabled']);
+            $definition->addMethodCall('setFormatterParameters', array($name, $parameters));
+        }
+
+        $container->setDefinition(self::MANAGER_ID, $definition);
+    }
+
+    /**
+     * Loads default formatters using registered factories.
+     *
+     * @param ContainerBuilder $container
+     */
+    private function loadFormatters(ContainerBuilder $container)
+    {
+        foreach ($this->factories as $factory) {
+            $factory->buildFormatter($container);
+        }
+    }
+
+    /**
+     * Processes formatters using registered factories.
+     *
+     * @param ContainerBuilder $container
+     */
+    private function processFormatters(ContainerBuilder $container)
+    {
+        foreach ($this->factories as $factory) {
+            $factory->processFormatter($container);
+        }
+    }
+
+    /**
+     * Processes all available output formatters.
+     *
+     * @param ContainerBuilder $container
+     */
+    private function processDynamicallyRegisteredFormatters(ContainerBuilder $container)
+    {
+        $references = $this->processor->findAndSortTaggedServices($container, self::FORMATTER_TAG);
+        $definition = $container->getDefinition(self::MANAGER_ID);
+
+        $previousCalls = $definition->getMethodCalls();
+        $definition->setMethodCalls();
+
+        foreach ($references as $reference) {
+            $definition->addMethodCall('registerFormatter', array($reference));
+        }
+
+        foreach ($previousCalls as $call) {
+            $definition->addMethodCall($call[0], $call[1]);
+        }
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/ServiceContainer/Configuration/ConfigurationLoader.php b/vendor/behat/behat/src/Behat/Testwork/ServiceContainer/Configuration/ConfigurationLoader.php
new file mode 100644 (file)
index 0000000..33521c1
--- /dev/null
@@ -0,0 +1,282 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\ServiceContainer\Configuration;
+
+use Behat\Testwork\ServiceContainer\Exception\ConfigurationLoadingException;
+use Symfony\Component\Yaml\Yaml;
+
+/**
+ * Loads configuration from different sources.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class ConfigurationLoader
+{
+    /**
+     * @var null|string
+     */
+    private $configurationPath;
+    /**
+     * @var null|string
+     */
+    private $environmentVariable;
+    /**
+     * @var Boolean
+     */
+    private $profileFound;
+    /**
+     * @var array
+     */
+    private $debugInformation = array(
+        'environment_variable_name' => 'none',
+        'environment_variable_content' => 'none',
+        'configuration_file_path' => 'none'
+    );
+
+    /**
+     * Constructs reader.
+     *
+     * @param string $environmentVariableName Environment variable name
+     * @param string $configurationPath       Configuration file path
+     */
+    public function __construct($environmentVariableName = null, $configurationPath = null)
+    {
+        $this->environmentVariable = $environmentVariableName;
+        $this->configurationPath = $configurationPath;
+    }
+
+    /**
+     * Sets environment variable name.
+     *
+     * @param null|string $variable
+     */
+    public function setEnvironmentVariableName($variable)
+    {
+        $this->environmentVariable = $variable;
+    }
+
+    /**
+     * Returns environment variable name.
+     *
+     * @return null|string
+     */
+    public function getEnvironmentVariableName()
+    {
+        return $this->environmentVariable;
+    }
+
+    /**
+     * Sets configuration file path.
+     *
+     * @param null|string $path
+     */
+    public function setConfigurationFilePath($path)
+    {
+        $this->configurationPath = $path;
+    }
+
+    /**
+     * Returns configuration file path.
+     *
+     * @return null|string
+     */
+    public function getConfigurationFilePath()
+    {
+        return $this->configurationPath;
+    }
+
+    /**
+     * Reads configuration sequence for specific profile.
+     *
+     * @param string $profile Profile name
+     *
+     * @return array
+     *
+     * @throws ConfigurationLoadingException
+     */
+    public function loadConfiguration($profile = 'default')
+    {
+        $configs = array();
+        $this->profileFound = false;
+
+        // first is ENV config
+        foreach ($this->loadEnvironmentConfiguration() as $config) {
+            $configs[] = $config;
+        }
+
+        // second is file configuration (if there is some)
+        if ($this->configurationPath) {
+            $this->debugInformation['configuration_file_path'] = $this->configurationPath;
+
+            foreach ($this->loadFileConfiguration($this->configurationPath, $profile) as $config) {
+                $configs[] = $config;
+            }
+        }
+
+        // if specific profile has not been found
+        if ('default' !== $profile && !$this->profileFound) {
+            throw new ConfigurationLoadingException(sprintf(
+                'Can not find configuration for `%s` profile.',
+                $profile
+            ));
+        }
+
+        return $configs;
+    }
+
+    /**
+     * Returns array with configuration debug information.
+     *
+     * @return array
+     */
+    public function debugInformation()
+    {
+        return $this->debugInformation;
+    }
+
+    /**
+     * Loads information from environment variable.
+     *
+     * @return array
+     *
+     * @throws ConfigurationLoadingException If environment variable environment var is set to invalid JSON
+     */
+    protected function loadEnvironmentConfiguration()
+    {
+        $configs = array();
+
+        if (!$this->environmentVariable) {
+            return $configs;
+        }
+
+        $this->debugInformation['environment_variable_name'] = $this->environmentVariable;
+
+        if ($envConfig = getenv($this->environmentVariable)) {
+            $config = @json_decode($envConfig, true);
+
+            $this->debugInformation['environment_variable_content'] = $envConfig;
+
+            if (!$config) {
+                throw new ConfigurationLoadingException(sprintf(
+                    'Environment variable `%s` should contain a valid JSON, but it is set to `%s`.',
+                    $this->environmentVariable,
+                    $envConfig
+                ));
+            }
+
+            $configs[] = $config;
+        }
+
+        return $configs;
+    }
+
+    /**
+     * Loads information from YAML configuration file.
+     *
+     * @param string $configPath Config file path
+     * @param string $profile    Profile name
+     *
+     * @return array
+     *
+     * @throws ConfigurationLoadingException If config file is not found
+     */
+    protected function loadFileConfiguration($configPath, $profile)
+    {
+        if (!is_file($configPath) || !is_readable($configPath)) {
+            throw new ConfigurationLoadingException(sprintf('Configuration file `%s` not found.', $configPath));
+        }
+
+        $basePath = rtrim(dirname($configPath), DIRECTORY_SEPARATOR);
+        $config = (array) Yaml::parse(file_get_contents($configPath));
+
+        return $this->loadConfigs($basePath, $config, $profile);
+    }
+
+    /**
+     * Loads configs for provided config and profile.
+     *
+     * @param string $basePath
+     * @param array  $config
+     * @param string $profile
+     *
+     * @return array
+     */
+    private function loadConfigs($basePath, array $config, $profile)
+    {
+        $configs = array();
+
+        // first load default profile from current config, but only if custom profile requested
+        if ('default' !== $profile && isset($config['default'])) {
+            $configs[] = $config['default'];
+        }
+
+        // then recursively load profiles from imports
+        if (isset($config['imports']) && is_array($config['imports'])) {
+            $configs = array_merge($configs, $this->loadImports($basePath, $config['imports'], $profile));
+        }
+
+        // then load specific profile from current config
+        if (isset($config[$profile])) {
+            $configs[] = $config[$profile];
+            $this->profileFound = true;
+        }
+
+        return $configs;
+    }
+
+    /**
+     * Loads all provided imports.
+     *
+     * @param string $basePath
+     * @param array  $paths
+     * @param string $profile
+     *
+     * @return array
+     */
+    private function loadImports($basePath, array $paths, $profile)
+    {
+        $configs = array();
+        foreach ($paths as $path) {
+            foreach ($this->parseImport($basePath, $path, $profile) as $importConfig) {
+                $configs[] = $importConfig;
+            }
+        }
+
+        return $configs;
+    }
+
+    /**
+     * Parses import.
+     *
+     * @param string $basePath
+     * @param string $path
+     * @param string $profile
+     *
+     * @return array
+     *
+     * @throws ConfigurationLoadingException If import file not found
+     */
+    private function parseImport($basePath, $path, $profile)
+    {
+        if (!file_exists($path) && file_exists($basePath . DIRECTORY_SEPARATOR . $path)) {
+            $path = $basePath . DIRECTORY_SEPARATOR . $path;
+        }
+
+        if (!file_exists($path)) {
+            throw new ConfigurationLoadingException(sprintf(
+                'Can not import `%s` configuration file. File not found.',
+                $path
+            ));
+        }
+
+        return $this->loadFileConfiguration($path, $profile);
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/ServiceContainer/Configuration/ConfigurationTree.php b/vendor/behat/behat/src/Behat/Testwork/ServiceContainer/Configuration/ConfigurationTree.php
new file mode 100644 (file)
index 0000000..d713cbc
--- /dev/null
@@ -0,0 +1,42 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\ServiceContainer\Configuration;
+
+use Behat\Testwork\ServiceContainer\Extension;
+use Symfony\Component\Config\Definition\Builder\TreeBuilder;
+use Symfony\Component\Config\Definition\NodeInterface;
+
+/**
+ * Builds configuration tree using provided lists of core and custom extensions.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class ConfigurationTree
+{
+    /**
+     * Generates the configuration tree.
+     *
+     * @param Extension[] $extensions
+     *
+     * @return NodeInterface
+     */
+    public function getConfigTree(array $extensions)
+    {
+        $tree = new TreeBuilder();
+        $root = $tree->root('testwork');
+
+        foreach ($extensions as $extension) {
+            $extension->configure($root->children()->arrayNode($extension->getConfigKey()));
+        }
+
+        return $tree->buildTree();
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/ServiceContainer/ContainerLoader.php b/vendor/behat/behat/src/Behat/Testwork/ServiceContainer/ContainerLoader.php
new file mode 100644 (file)
index 0000000..a723777
--- /dev/null
@@ -0,0 +1,163 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\ServiceContainer;
+
+use Behat\Testwork\ServiceContainer\Configuration\ConfigurationTree;
+use Behat\Testwork\ServiceContainer\Exception\ExtensionException;
+use Symfony\Component\Config\Definition\Processor;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
+
+/**
+ * Loads Symfony DI container with testwork extension services.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class ContainerLoader
+{
+    /**
+     * @var ExtensionManager
+     */
+    private $extensionManager;
+    /**
+     * @var ConfigurationTree
+     */
+    private $configuration;
+    /**
+     * @var Processor
+     */
+    private $processor;
+
+    /**
+     * Initialize extension.
+     *
+     * @param ExtensionManager       $extensionManager
+     * @param null|ConfigurationTree $configuration
+     * @param null|Processor         $processor
+     */
+    public function __construct(
+        ExtensionManager $extensionManager,
+        ConfigurationTree $configuration = null,
+        Processor $processor = null
+    ) {
+        $this->extensionManager = $extensionManager;
+        $this->configuration = $configuration ? : new ConfigurationTree();
+        $this->processor = $processor ? : new Processor();
+    }
+
+    /**
+     * Loads container extension.
+     *
+     * @param ContainerBuilder $container
+     * @param array            $configs
+     */
+    public function load(ContainerBuilder $container, array $configs)
+    {
+        $configs = $this->initializeExtensions($container, $configs);
+        $config = $this->processConfig($configs);
+
+        $this->loadExtensions($container, $config);
+    }
+
+    /**
+     * Processes config against extensions.
+     *
+     * @param array $configs
+     *
+     * @return array
+     */
+    private function processConfig(array $configs)
+    {
+        $tree = $this->configuration->getConfigTree($this->extensionManager->getExtensions());
+
+        return $this->processor->process($tree, $configs);
+    }
+
+    /**
+     * Initializes extensions using provided config.
+     *
+     * @param ContainerBuilder $container
+     * @param array            $configs
+     *
+     * @return array
+     */
+    private function initializeExtensions(ContainerBuilder $container, array $configs)
+    {
+        foreach ($configs as $i => $config) {
+            if (isset($config['extensions'])) {
+                foreach ($config['extensions'] as $extensionLocator => $extensionConfig) {
+                    $extension = $this->extensionManager->activateExtension($extensionLocator);
+                    $configs[$i][$extension->getConfigKey()] = $extensionConfig;
+                }
+
+                unset($configs[$i]['extensions']);
+            }
+        }
+
+        $this->extensionManager->initializeExtensions();
+
+        $container->setParameter('extensions', $this->extensionManager->getExtensionClasses());
+
+        return $configs;
+    }
+
+    /**
+     * Loads all extensions into container using provided config.
+     *
+     * @param ContainerBuilder $container
+     * @param array            $config
+     *
+     * @throws ExtensionException
+     */
+    private function loadExtensions(ContainerBuilder $container, array $config)
+    {
+        // Load default extensions first
+        foreach ($this->extensionManager->getExtensions() as $extension) {
+            $extensionConfig = array();
+            if (isset($config[$extension->getConfigKey()])) {
+                $extensionConfig = $config[$extension->getConfigKey()];
+                unset($config[$extension->getConfigKey()]);
+            }
+
+            $this->loadExtension($container, $extension, $extensionConfig);
+        }
+
+        // Load activated extensions
+        foreach ($config as $extensionConfigKey => $extensionConfig) {
+            if (null === $extension = $this->extensionManager->getExtension($extensionConfigKey)) {
+                throw new ExtensionException(
+                    sprintf('None of the activated extensions use `%s` config section.', $extensionConfigKey), $extensionConfigKey
+                );
+            }
+
+            $this->loadExtension($container, $extension, $extensionConfig);
+        }
+    }
+
+    /**
+     * Loads extension configuration.
+     *
+     * @param ContainerBuilder $container
+     * @param Extension        $extension
+     * @param array            $config
+     */
+    private function loadExtension(ContainerBuilder $container, Extension $extension, array $config)
+    {
+        $tempContainer = new ContainerBuilder(new ParameterBag(array(
+            'paths.base' => $container->getParameter('paths.base'),
+            'extensions' => $container->getParameter('extensions'),
+        )));
+        $tempContainer->addObjectResource($extension);
+        $extension->load($container, $config);
+        $container->merge($tempContainer);
+        $container->addCompilerPass($extension);
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/ServiceContainer/Exception/ConfigurationLoadingException.php b/vendor/behat/behat/src/Behat/Testwork/ServiceContainer/Exception/ConfigurationLoadingException.php
new file mode 100644 (file)
index 0000000..be18620
--- /dev/null
@@ -0,0 +1,22 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\ServiceContainer\Exception;
+
+use InvalidArgumentException;
+
+/**
+ * Represents exception thrown during configuration load.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class ConfigurationLoadingException extends InvalidArgumentException implements ServiceContainerException
+{
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/ServiceContainer/Exception/ExtensionException.php b/vendor/behat/behat/src/Behat/Testwork/ServiceContainer/Exception/ExtensionException.php
new file mode 100644 (file)
index 0000000..eb4e16d
--- /dev/null
@@ -0,0 +1,49 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\ServiceContainer\Exception;
+
+use RuntimeException;
+
+/**
+ * Extension exception.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class ExtensionException extends RuntimeException implements ServiceContainerException
+{
+    /**
+     * @var string
+     */
+    private $extensionName;
+
+    /**
+     * Initializes exception.
+     *
+     * @param string $message
+     * @param string $extensionName
+     */
+    public function __construct($message, $extensionName)
+    {
+        $this->extensionName = $extensionName;
+
+        parent::__construct($message);
+    }
+
+    /**
+     * Returns name of the extension that caused exception.
+     *
+     * @return string
+     */
+    public function getExtensionName()
+    {
+        return $this->extensionName;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/ServiceContainer/Exception/ExtensionInitializationException.php b/vendor/behat/behat/src/Behat/Testwork/ServiceContainer/Exception/ExtensionInitializationException.php
new file mode 100644 (file)
index 0000000..b57aa66
--- /dev/null
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\ServiceContainer\Exception;
+
+/**
+ * Represents exception thrown during extension initialization phase.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class ExtensionInitializationException extends ExtensionException
+{
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/ServiceContainer/Exception/ProcessingException.php b/vendor/behat/behat/src/Behat/Testwork/ServiceContainer/Exception/ProcessingException.php
new file mode 100644 (file)
index 0000000..b5da8b4
--- /dev/null
@@ -0,0 +1,22 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\ServiceContainer\Exception;
+
+use RuntimeException;
+
+/**
+ * Represents an exception thrown during processing phase.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class ProcessingException extends RuntimeException implements ServiceContainerException
+{
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/ServiceContainer/Exception/ServiceContainerException.php b/vendor/behat/behat/src/Behat/Testwork/ServiceContainer/Exception/ServiceContainerException.php
new file mode 100644 (file)
index 0000000..a7035c5
--- /dev/null
@@ -0,0 +1,22 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\ServiceContainer\Exception;
+
+use Behat\Testwork\Exception\TestworkException;
+
+/**
+ * Represents service container exception.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface ServiceContainerException extends TestworkException
+{
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/ServiceContainer/Extension.php b/vendor/behat/behat/src/Behat/Testwork/ServiceContainer/Extension.php
new file mode 100644 (file)
index 0000000..9533dca
--- /dev/null
@@ -0,0 +1,60 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\ServiceContainer;
+
+use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
+use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+
+/**
+ * Represents Testwork extension mechanism.
+ *
+ * Extensions are the core entities in Testwork. Almost all framework functionality in Testwork and its different
+ * implementations is provided through extensions.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface Extension extends CompilerPassInterface
+{
+    /**
+     * Returns the extension config key.
+     *
+     * @return string
+     */
+    public function getConfigKey();
+
+    /**
+     * Initializes other extensions.
+     *
+     * This method is called immediately after all extensions are activated but
+     * before any extension `configure()` method is called. This allows extensions
+     * to hook into the configuration of other extensions providing such an
+     * extension point.
+     *
+     * @param ExtensionManager $extensionManager
+     */
+    public function initialize(ExtensionManager $extensionManager);
+
+    /**
+     * Setups configuration for the extension.
+     *
+     * @param ArrayNodeDefinition $builder
+     */
+    public function configure(ArrayNodeDefinition $builder);
+
+    /**
+     * Loads extension services into temporary container.
+     *
+     * @param ContainerBuilder $container
+     * @param array            $config
+     */
+    public function load(ContainerBuilder $container, array $config);
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/ServiceContainer/ExtensionManager.php b/vendor/behat/behat/src/Behat/Testwork/ServiceContainer/ExtensionManager.php
new file mode 100644 (file)
index 0000000..7e2d955
--- /dev/null
@@ -0,0 +1,231 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\ServiceContainer;
+
+use Behat\Testwork\ServiceContainer\Exception\ExtensionInitializationException;
+
+/**
+ * Manages both default and 3rd-party extensions.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class ExtensionManager
+{
+    /**
+     * @var string
+     */
+    private $extensionsPath;
+    /**
+     * @var Extension[]
+     */
+    private $extensions = array();
+    /**
+     * @var Extension[string]
+     */
+    private $locatedExtensions = array();
+    private $debugInformation = array(
+        'extensions_list' => array()
+    );
+
+    /**
+     * Initializes manager.
+     *
+     * @param Extension[] $extensions     List of default extensions
+     * @param null|string $extensionsPath Base path where to search custom extension files
+     */
+    public function __construct(array $extensions, $extensionsPath = null)
+    {
+        foreach ($extensions as $extension) {
+            $this->extensions[$extension->getConfigKey()] = $extension;
+        }
+
+        $this->extensionsPath = $extensionsPath;
+    }
+
+    /**
+     * Sets path to directory in which manager will try to find extension files.
+     *
+     * @param null|string $path
+     */
+    public function setExtensionsPath($path)
+    {
+        $this->extensionsPath = $path;
+    }
+
+    /**
+     * Activate extension by its locator.
+     *
+     * @param string $locator phar file name, php file name, class name
+     *
+     * @return Extension
+     */
+    public function activateExtension($locator)
+    {
+        $extension = $this->initialize($locator);
+
+        $this->debugInformation['extensions_list'][] = $extension->getConfigKey();
+
+        return $this->extensions[$extension->getConfigKey()] = $extension;
+    }
+
+    /**
+     * Returns specific extension by its name.
+     *
+     * @param string $key
+     *
+     * @return Extension
+     */
+    public function getExtension($key)
+    {
+        return isset($this->extensions[$key]) ? $this->extensions[$key] : null;
+    }
+
+    /**
+     * Returns all available extensions.
+     *
+     * @return Extension[]
+     */
+    public function getExtensions()
+    {
+        return $this->extensions;
+    }
+
+    /**
+     * Returns activated extension names.
+     *
+     * @return array
+     */
+    public function getExtensionClasses()
+    {
+        return array_map('get_class', array_values($this->extensions));
+    }
+
+    /**
+     * Initializes all activated and predefined extensions.
+     */
+    public function initializeExtensions()
+    {
+        foreach ($this->extensions as $extension) {
+            $extension->initialize($this);
+        }
+    }
+
+    /**
+     * Returns array with extensions debug information.
+     *
+     * @return array
+     */
+    public function debugInformation()
+    {
+        return $this->debugInformation;
+    }
+
+    /**
+     * Attempts to guess full extension class from relative.
+     *
+     * @param string $locator
+     *
+     * @return string
+     */
+    private function getFullExtensionClass($locator)
+    {
+        $parts = explode('\\', $locator);
+        $name = preg_replace('/Extension$/', '', end($parts)) . 'Extension';
+
+        return $locator . '\\ServiceContainer\\' . $name;
+    }
+
+    /**
+     * Initializes extension by id.
+     *
+     * @param string $locator
+     *
+     * @return Extension
+     *
+     * @throws ExtensionInitializationException
+     */
+    private function initialize($locator)
+    {
+        if (isset($this->locatedExtensions[$locator])) {
+            return $this->locatedExtensions[$locator];
+        }
+
+        $extension = $this->instantiateExtension($locator);
+        $this->validateExtensionInstance($extension, $locator);
+
+        return $this->locatedExtensions[$locator] = $extension;
+    }
+
+    /**
+     * Instantiates extension from its locator.
+     *
+     * @param string $locator
+     *
+     * @return Extension
+     *
+     * @throws ExtensionInitializationException
+     */
+    private function instantiateExtension($locator)
+    {
+        if (class_exists($class = $locator)) {
+            return new $class;
+        }
+
+        if (class_exists($class = $this->getFullExtensionClass($locator))) {
+            return new $class;
+        }
+
+        if (file_exists($locator)) {
+            return require($locator);
+        }
+
+        if (file_exists($path = $this->extensionsPath . DIRECTORY_SEPARATOR . $locator)) {
+            return require($path);
+        }
+
+        throw new ExtensionInitializationException(sprintf(
+            '`%s` extension file or class could not be located.',
+            $locator
+        ), $locator);
+    }
+
+    /**
+     * Validates extension instance.
+     *
+     * @param Extension $extension
+     * @param string    $locator
+     *
+     * @throws ExtensionInitializationException
+     */
+    private function validateExtensionInstance($extension, $locator)
+    {
+        if (null === $extension) {
+            throw new ExtensionInitializationException(sprintf(
+                '`%s` extension could not be found.',
+                $locator
+            ), $locator);
+        }
+
+        if (!is_object($extension)) {
+            throw new ExtensionInitializationException(sprintf(
+                '`%s` extension could not be initialized.',
+                $locator
+            ), $locator);
+        }
+
+        if (!$extension instanceof Extension) {
+            throw new ExtensionInitializationException(sprintf(
+                '`%s` extension class should implement Testwork Extension interface.',
+                get_class($extension)
+            ), $locator);
+        }
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/ServiceContainer/ServiceProcessor.php b/vendor/behat/behat/src/Behat/Testwork/ServiceContainer/ServiceProcessor.php
new file mode 100644 (file)
index 0000000..a57810e
--- /dev/null
@@ -0,0 +1,87 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\ServiceContainer;
+
+use Symfony\Component\DependencyInjection\Alias;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Reference;
+
+/**
+ * Provides additional service finding functionality.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ * @author Christophe Coevoet <stof@notk.org>
+ */
+final class ServiceProcessor
+{
+    /**
+     * Finds and sorts (by priority) service references by provided tag.
+     *
+     * @param ContainerBuilder $container
+     * @param string           $tag
+     *
+     * @return Reference[]
+     */
+    public function findAndSortTaggedServices(ContainerBuilder $container, $tag)
+    {
+        $serviceTags = array();
+        foreach ($container->findTaggedServiceIds($tag) as $id => $tags) {
+            $firstTags = current($tags);
+
+            $serviceTags[] = array_merge(array('priority' => 0), $firstTags, array('id' => $id));
+        }
+
+        usort($serviceTags, function ($tag1, $tag2) { return $tag2['priority'] - $tag1['priority']; });
+        $serviceReferences = array_map(function ($tag) { return new Reference($tag['id']); }, $serviceTags);
+
+        return $serviceReferences;
+    }
+
+    /**
+     * Processes wrappers of a service, found by provided tag.
+     *
+     * The wrappers are applied by descending priority.
+     * The first argument of the wrapper service receives the inner service.
+     *
+     * @param ContainerBuilder $container
+     * @param string           $target     The id of the service being decorated
+     * @param string           $wrapperTag The tag used by wrappers
+     */
+    public function processWrapperServices(ContainerBuilder $container, $target, $wrapperTag)
+    {
+        $references = $this->findAndSortTaggedServices($container, $wrapperTag);
+
+        foreach ($references as $reference) {
+            $id = (string) $reference;
+            $renamedId = $id . '.inner';
+
+            // This logic is based on Symfony\Component\DependencyInjection\Compiler\DecoratorServicePass
+
+            // we create a new alias/service for the service we are replacing
+            // to be able to reference it in the new one
+            if ($container->hasAlias($target)) {
+                $alias = $container->getAlias($target);
+                $public = $alias->isPublic();
+                $container->setAlias($renamedId, new Alias((string) $alias, false));
+            } else {
+                $definition = $container->getDefinition($target);
+                $public = $definition->isPublic();
+                $definition->setPublic(false);
+                $container->setDefinition($renamedId, $definition);
+            }
+
+            $container->setAlias($target, new Alias($id, $public));
+            // Replace the reference so that users don't need to bother about the way the inner service is referenced
+            $wrappingService = $container->getDefinition($id);
+            $wrappingService->replaceArgument(0, new Reference($renamedId));
+        }
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Specification/GroupedSpecificationIterator.php b/vendor/behat/behat/src/Behat/Testwork/Specification/GroupedSpecificationIterator.php
new file mode 100644 (file)
index 0000000..bac556d
--- /dev/null
@@ -0,0 +1,137 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Specification;
+
+use Behat\Testwork\Suite\Suite;
+
+/**
+ * Iterates over specification iterators grouped by their suite.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class GroupedSpecificationIterator implements SpecificationIterator
+{
+    /**
+     * @var Suite
+     */
+    private $suite;
+    /**
+     * @var SpecificationIterator[]
+     */
+    private $iterators;
+    /**
+     * @var integer
+     */
+    private $position = 0;
+
+    /**
+     * Initializes iterator.
+     *
+     * @param Suite                   $suite
+     * @param SpecificationIterator[] $specificationIterators
+     */
+    public function __construct(Suite $suite, array $specificationIterators)
+    {
+        $this->suite = $suite;
+        $this->iterators = $specificationIterators;
+    }
+
+    /**
+     * Groups specifications by their suite.
+     *
+     * @param SpecificationIterator[] $specificationIterators
+     *
+     * @return GroupedSpecificationIterator[]
+     */
+    public static function group(array $specificationIterators)
+    {
+        $groupedSpecifications = array();
+        foreach ($specificationIterators as $specificationIterator) {
+            $groupedSpecifications[$specificationIterator->getSuite()->getName()][] = $specificationIterator;
+        }
+
+        return array_map(
+            function ($iterator) {
+                return new GroupedSpecificationIterator($iterator[0]->getSuite(), $iterator);
+            },
+            $groupedSpecifications
+        );
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getSuite()
+    {
+        return $this->suite;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function rewind()
+    {
+        $this->position = 0;
+        while (isset($this->iterators[$this->position])) {
+            $this->iterators[$this->position]->rewind();
+
+            if ($this->iterators[$this->position]->valid()) {
+                break;
+            }
+            $this->position++;
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function next()
+    {
+        if (!isset($this->iterators[$this->position])) {
+            return;
+        }
+
+        $this->iterators[$this->position]->next();
+        while (!$this->iterators[$this->position]->valid()) {
+            $this->position++;
+
+            if (!isset($this->iterators[$this->position])) {
+                break;
+            }
+
+            $this->iterators[$this->position]->rewind();
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function valid()
+    {
+        return isset($this->iterators[$this->position]) && $this->iterators[$this->position]->valid();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function current()
+    {
+        return $this->iterators[$this->position]->current();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function key()
+    {
+        return $this->position + $this->iterators[$this->position]->key();
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Specification/Locator/SpecificationLocator.php b/vendor/behat/behat/src/Behat/Testwork/Specification/Locator/SpecificationLocator.php
new file mode 100644 (file)
index 0000000..372fbea
--- /dev/null
@@ -0,0 +1,42 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Specification\Locator;
+
+use Behat\Testwork\Specification\SpecificationFinder;
+use Behat\Testwork\Specification\SpecificationIterator;
+use Behat\Testwork\Suite\Suite;
+
+/**
+ * Provides a custom way to locate specification by provided suite and locator string.
+ *
+ * @see SpecificationFinder
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface SpecificationLocator
+{
+    /**
+     * Returns array of strings representing examples of supported specification locators.
+     *
+     * @return string[]
+     */
+    public function getLocatorExamples();
+
+    /**
+     * Locates specifications and wraps them into iterator.
+     *
+     * @param Suite  $suite
+     * @param string $locator
+     *
+     * @return SpecificationIterator
+     */
+    public function locateSpecifications(Suite $suite, $locator);
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Specification/NoSpecificationsIterator.php b/vendor/behat/behat/src/Behat/Testwork/Specification/NoSpecificationsIterator.php
new file mode 100644 (file)
index 0000000..95cfc6a
--- /dev/null
@@ -0,0 +1,49 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Specification;
+
+use Behat\Testwork\Suite\Suite;
+use EmptyIterator;
+
+/**
+ * Represents empty specification iterator.
+ *
+ * Return an instance of this class from locator if no specifications are found.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class NoSpecificationsIterator extends EmptyIterator implements SpecificationIterator
+{
+    /**
+     * @var Suite
+     */
+    private $suite;
+
+    /**
+     * Initializes iterator.
+     *
+     * @param Suite $suite
+     */
+    public function __construct(Suite $suite)
+    {
+        $this->suite = $suite;
+    }
+
+    /**
+     * Returns suite that was used to load subjects.
+     *
+     * @return Suite
+     */
+    public function getSuite()
+    {
+        return $this->suite;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Specification/ServiceContainer/SpecificationExtension.php b/vendor/behat/behat/src/Behat/Testwork/Specification/ServiceContainer/SpecificationExtension.php
new file mode 100644 (file)
index 0000000..03ca52d
--- /dev/null
@@ -0,0 +1,115 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Specification\ServiceContainer;
+
+use Behat\Testwork\ServiceContainer\Extension;
+use Behat\Testwork\ServiceContainer\ExtensionManager;
+use Behat\Testwork\ServiceContainer\ServiceProcessor;
+use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Definition;
+
+/**
+ * Extends testwork with test specification services.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class SpecificationExtension implements Extension
+{
+    /*
+     * Available services
+     */
+    const FINDER_ID = 'specifications.finder';
+
+    /*
+     * Available extension points
+     */
+    const LOCATOR_TAG = 'specifications.locator';
+
+    /**
+     * @var ServiceProcessor
+     */
+    private $processor;
+
+    /**
+     * Initializes extension.
+     *
+     * @param null|ServiceProcessor $processor
+     */
+    public function __construct(ServiceProcessor $processor = null)
+    {
+        $this->processor = $processor ? : new ServiceProcessor();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getConfigKey()
+    {
+        return 'specifications';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function initialize(ExtensionManager $extensionManager)
+    {
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function configure(ArrayNodeDefinition $builder)
+    {
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function load(ContainerBuilder $container, array $config)
+    {
+        $this->loadFinder($container);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function process(ContainerBuilder $container)
+    {
+        $this->processLocators($container);
+    }
+
+    /**
+     * Loads specification finder.
+     *
+     * @param ContainerBuilder $container
+     */
+    private function loadFinder(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Testwork\Specification\SpecificationFinder');
+        $container->setDefinition(self::FINDER_ID, $definition);
+    }
+
+    /**
+     * Processes specification locators.
+     *
+     * @param ContainerBuilder $container
+     */
+    private function processLocators(ContainerBuilder $container)
+    {
+        $references = $this->processor->findAndSortTaggedServices($container, self::LOCATOR_TAG);
+        $definition = $container->getDefinition(self::FINDER_ID);
+
+        foreach ($references as $reference) {
+            $definition->addMethodCall('registerSpecificationLocator', array($reference));
+        }
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Specification/SpecificationArrayIterator.php b/vendor/behat/behat/src/Behat/Testwork/Specification/SpecificationArrayIterator.php
new file mode 100644 (file)
index 0000000..c48292d
--- /dev/null
@@ -0,0 +1,50 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Specification;
+
+use ArrayIterator;
+use Behat\Testwork\Suite\Suite;
+
+/**
+ * Iterates over specifications array.
+ *
+ * Return instance of this class from locator if specifications cannot be searched lazily.
+ *
+ * @author Christophe Coevoet <stof@notk.org>
+ */
+final class SpecificationArrayIterator extends ArrayIterator implements SpecificationIterator
+{
+    /**
+     * @var Suite
+     */
+    private $suite;
+
+    /**
+     * Initializes iterator.
+     *
+     * @param Suite   $suite
+     * @param mixed[] $specifications
+     */
+    public function __construct(Suite $suite, $specifications = array())
+    {
+        $this->suite = $suite;
+
+        parent::__construct($specifications);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getSuite()
+    {
+        return $this->suite;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Specification/SpecificationFinder.php b/vendor/behat/behat/src/Behat/Testwork/Specification/SpecificationFinder.php
new file mode 100644 (file)
index 0000000..5204bd5
--- /dev/null
@@ -0,0 +1,88 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Specification;
+
+use Behat\Testwork\Specification\Locator\SpecificationLocator;
+use Behat\Testwork\Suite\Suite;
+
+/**
+ * Finds test specifications for provided suites using registered locators.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class SpecificationFinder
+{
+    /**
+     * @var SpecificationLocator[]
+     */
+    private $specificationLocators = array();
+
+    /**
+     * Registers specification locator.
+     *
+     * @param SpecificationLocator $locator
+     */
+    public function registerSpecificationLocator(SpecificationLocator $locator)
+    {
+        $this->specificationLocators[] = $locator;
+    }
+
+    /**
+     * Returns array of strings representing examples of supported specification locators.
+     *
+     * @return string[]
+     */
+    public function getExampleLocators()
+    {
+        $examples = array();
+        foreach ($this->specificationLocators as $locator) {
+            $examples = array_merge($examples, $locator->getLocatorExamples());
+        }
+
+        return $examples;
+    }
+
+    /**
+     * Finds all specifications for all provided suites matching provided locator and wraps them into a spec iterator.
+     *
+     * @param Suite[]     $suites
+     * @param null|string $locator
+     *
+     * @return SpecificationIterator[]
+     */
+    public function findSuitesSpecifications(array $suites, $locator = null)
+    {
+        $iterators = array();
+        foreach ($suites as $suite) {
+            $iterators = array_merge($iterators, $this->findSuiteSpecifications($suite, $locator));
+        }
+
+        return $iterators;
+    }
+
+    /**
+     * Creates suite specification iterator for provided locator.
+     *
+     * @param Suite       $suite
+     * @param null|string $locator
+     *
+     * @return SpecificationIterator[]
+     */
+    private function findSuiteSpecifications(Suite $suite, $locator = null)
+    {
+        $iterators = array();
+        foreach ($this->specificationLocators as $specificationLocator) {
+            $iterators[] = $specificationLocator->locateSpecifications($suite, $locator);
+        }
+
+        return $iterators;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Specification/SpecificationIterator.php b/vendor/behat/behat/src/Behat/Testwork/Specification/SpecificationIterator.php
new file mode 100644 (file)
index 0000000..c96ad6c
--- /dev/null
@@ -0,0 +1,29 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Specification;
+
+use Behat\Testwork\Suite\Suite;
+use Iterator;
+
+/**
+ * Iterates over test specifications.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface SpecificationIterator extends Iterator
+{
+    /**
+     * Returns suite that was used to load specifications.
+     *
+     * @return Suite
+     */
+    public function getSuite();
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Suite/Cli/InitializationController.php b/vendor/behat/behat/src/Behat/Testwork/Suite/Cli/InitializationController.php
new file mode 100644 (file)
index 0000000..dc8ac0c
--- /dev/null
@@ -0,0 +1,75 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Suite\Cli;
+
+use Behat\Testwork\Cli\Controller;
+use Behat\Testwork\Suite\SuiteBootstrapper;
+use Behat\Testwork\Suite\SuiteRepository;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * Initializes registered test suites.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class InitializationController implements Controller
+{
+    /**
+     * @var SuiteRepository
+     */
+    private $repository;
+    /**
+     * @var SuiteBootstrapper
+     */
+    private $bootstrapper;
+
+    /**
+     * Initializes controller.
+     *
+     * @param SuiteRepository   $repository
+     * @param SuiteBootstrapper $bootstrapper
+     */
+    public function __construct(SuiteRepository $repository, SuiteBootstrapper $bootstrapper)
+    {
+        $this->repository = $repository;
+        $this->bootstrapper = $bootstrapper;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function configure(Command $command)
+    {
+        $command->addOption('--init', null, InputOption::VALUE_NONE,
+            'Initialize all registered test suites.'
+        );
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function execute(InputInterface $input, OutputInterface $output)
+    {
+        if (!$input->getOption('init')) {
+            return null;
+        }
+
+        $suites = $this->repository->getSuites();
+        $this->bootstrapper->bootstrapSuites($suites);
+
+        $output->write(PHP_EOL);
+
+        return 0;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Suite/Cli/SuiteController.php b/vendor/behat/behat/src/Behat/Testwork/Suite/Cli/SuiteController.php
new file mode 100644 (file)
index 0000000..ea1a23a
--- /dev/null
@@ -0,0 +1,83 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Suite\Cli;
+
+use Behat\Testwork\Cli\Controller;
+use Behat\Testwork\Suite\Exception\SuiteNotFoundException;
+use Behat\Testwork\Suite\SuiteRegistry;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * Sets up registered test suites.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class SuiteController implements Controller
+{
+    /**
+     * @var SuiteRegistry
+     */
+    private $registry;
+    /**
+     * @var array
+     */
+    private $suiteConfigurations = array();
+
+    /**
+     * Initializes controller.
+     *
+     * @param SuiteRegistry $registry
+     * @param array         $suiteConfigurations
+     */
+    public function __construct(SuiteRegistry $registry, array $suiteConfigurations)
+    {
+        $this->registry = $registry;
+        $this->suiteConfigurations = $suiteConfigurations;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function configure(Command $command)
+    {
+        $command->addOption('--suite', '-s', InputOption::VALUE_REQUIRED,
+            'Only execute a specific suite.'
+        );
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function execute(InputInterface $input, OutputInterface $output)
+    {
+        $exerciseSuiteName = $input->getOption('suite');
+
+        if (null !== $exerciseSuiteName && !isset($this->suiteConfigurations[$exerciseSuiteName])) {
+            throw new SuiteNotFoundException(sprintf(
+                '`%s` suite is not found or has not been properly registered.',
+                $exerciseSuiteName
+            ), $exerciseSuiteName);
+        }
+
+        foreach ($this->suiteConfigurations as $name => $config) {
+            if (null !== $exerciseSuiteName && $exerciseSuiteName !== $name) {
+                continue;
+            }
+
+            $this->registry->registerSuiteConfiguration(
+                $name, $config['type'], $config['settings']
+            );
+        }
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Suite/Exception/ParameterNotFoundException.php b/vendor/behat/behat/src/Behat/Testwork/Suite/Exception/ParameterNotFoundException.php
new file mode 100644 (file)
index 0000000..5005884
--- /dev/null
@@ -0,0 +1,48 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Suite\Exception;
+
+/**
+ * Represents an exception thrown when user tries to access non-existent suite parameter.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class ParameterNotFoundException extends SuiteException
+{
+    /**
+     * @var string
+     */
+    private $parameter;
+
+    /**
+     * Initializes exception.
+     *
+     * @param string $message
+     * @param string $name
+     * @param string $parameter
+     */
+    public function __construct($message, $name, $parameter)
+    {
+        $this->parameter = $parameter;
+
+        parent::__construct($message, $name);
+    }
+
+    /**
+     * Returns parameter that caused exception.
+     *
+     * @return string
+     */
+    public function getParameter()
+    {
+        return $this->parameter;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Suite/Exception/SuiteConfigurationException.php b/vendor/behat/behat/src/Behat/Testwork/Suite/Exception/SuiteConfigurationException.php
new file mode 100644 (file)
index 0000000..73f366c
--- /dev/null
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Suite\Exception;
+
+/**
+ * Represents an exception throw during suite configuration phase.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class SuiteConfigurationException extends SuiteException
+{
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Suite/Exception/SuiteException.php b/vendor/behat/behat/src/Behat/Testwork/Suite/Exception/SuiteException.php
new file mode 100644 (file)
index 0000000..2027089
--- /dev/null
@@ -0,0 +1,52 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Suite\Exception;
+
+use Behat\Testwork\Exception\TestworkException;
+use Exception;
+use InvalidArgumentException;
+
+/**
+ * Represents a suite exception.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class SuiteException extends InvalidArgumentException implements TestworkException
+{
+    /**
+     * @var string
+     */
+    private $name;
+
+    /**
+     * Initializes exception.
+     *
+     * @param string         $message
+     * @param string         $name
+     * @param Exception|null $previous
+     */
+    public function __construct($message, $name, Exception $previous = null)
+    {
+        $this->name = $name;
+
+        parent::__construct($message, 0, $previous);
+    }
+
+    /**
+     * Returns name of the suite that caused exception.
+     *
+     * @return string
+     */
+    public function getSuiteName()
+    {
+        return $this->name;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Suite/Exception/SuiteGenerationException.php b/vendor/behat/behat/src/Behat/Testwork/Suite/Exception/SuiteGenerationException.php
new file mode 100644 (file)
index 0000000..d6b418b
--- /dev/null
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Suite\Exception;
+
+/**
+ * Represents a suite exception thrown during suite generation phase.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class SuiteGenerationException extends SuiteException
+{
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Suite/Exception/SuiteNotFoundException.php b/vendor/behat/behat/src/Behat/Testwork/Suite/Exception/SuiteNotFoundException.php
new file mode 100644 (file)
index 0000000..95e0244
--- /dev/null
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Suite\Exception;
+
+/**
+ * Represents an exception thrown when trying to access non-registered suite.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class SuiteNotFoundException extends SuiteException
+{
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Suite/Exception/SuiteSetupException.php b/vendor/behat/behat/src/Behat/Testwork/Suite/Exception/SuiteSetupException.php
new file mode 100644 (file)
index 0000000..5ceeb7e
--- /dev/null
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Suite\Exception;
+
+/**
+ * Represents a suite exception thrown during a suite setup phase.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class SuiteSetupException extends SuiteException
+{
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Suite/Generator/GenericSuiteGenerator.php b/vendor/behat/behat/src/Behat/Testwork/Suite/Generator/GenericSuiteGenerator.php
new file mode 100644 (file)
index 0000000..36f6141
--- /dev/null
@@ -0,0 +1,64 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Suite\Generator;
+
+use Behat\Testwork\Suite\GenericSuite;
+
+/**
+ * Generates generic test suites.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class GenericSuiteGenerator implements SuiteGenerator
+{
+    /**
+     * @var array
+     */
+    private $defaultSettings = array();
+
+    /**
+     * Initializes suite generator.
+     *
+     * @param array $defaultSettings
+     */
+    public function __construct(array $defaultSettings = array())
+    {
+        $this->defaultSettings = $defaultSettings;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function supportsTypeAndSettings($type, array $settings)
+    {
+        return null === $type;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function generateSuite($suiteName, array $settings)
+    {
+        return new GenericSuite($suiteName, $this->mergeDefaultSettings($settings));
+    }
+
+    /**
+     * Merges provided settings into default ones.
+     *
+     * @param array $settings
+     *
+     * @return array
+     */
+    private function mergeDefaultSettings(array $settings)
+    {
+        return array_merge($this->defaultSettings, $settings);
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Suite/Generator/SuiteGenerator.php b/vendor/behat/behat/src/Behat/Testwork/Suite/Generator/SuiteGenerator.php
new file mode 100644 (file)
index 0000000..876d6b6
--- /dev/null
@@ -0,0 +1,44 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Suite\Generator;
+
+use Behat\Testwork\Suite\Suite;
+use Behat\Testwork\Suite\SuiteRegistry;
+
+/**
+ * Generates a suite using provided name, settings and parameters.
+ *
+ * @see SuiteRegistry
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface SuiteGenerator
+{
+    /**
+     * Checks if generator support provided suite type and settings.
+     *
+     * @param string $type
+     * @param array  $settings
+     *
+     * @return Boolean
+     */
+    public function supportsTypeAndSettings($type, array $settings);
+
+    /**
+     * Generate suite with provided name and settings.
+     *
+     * @param string $suiteName
+     * @param array  $settings
+     *
+     * @return Suite
+     */
+    public function generateSuite($suiteName, array $settings);
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Suite/GenericSuite.php b/vendor/behat/behat/src/Behat/Testwork/Suite/GenericSuite.php
new file mode 100644 (file)
index 0000000..766cffe
--- /dev/null
@@ -0,0 +1,96 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Suite;
+
+use Behat\Testwork\Suite\Exception\ParameterNotFoundException;
+
+/**
+ * Represents generic (no specific attributes) test suite.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class GenericSuite implements Suite
+{
+    /**
+     * @var string
+     */
+    private $name;
+    /**
+     * @var array
+     */
+    private $settings = array();
+
+    /**
+     * Initializes suite.
+     *
+     * @param string $name
+     * @param array  $settings
+     */
+    public function __construct($name, array $settings)
+    {
+        $this->name = $name;
+        $this->settings = $settings;
+    }
+
+    /**
+     * Returns unique suite name.
+     *
+     * @return string
+     */
+    public function getName()
+    {
+        return $this->name;
+    }
+
+    /**
+     * Returns suite settings.
+     *
+     * @return array
+     */
+    public function getSettings()
+    {
+        return $this->settings;
+    }
+
+    /**
+     * Checks if a setting with provided name exists.
+     *
+     * @param string $key
+     *
+     * @return Boolean
+     */
+    public function hasSetting($key)
+    {
+        return array_key_exists($key, $this->settings);
+    }
+
+    /**
+     * Returns setting value by its key.
+     *
+     * @param string $key
+     *
+     * @return mixed
+     *
+     * @throws ParameterNotFoundException If setting is not set
+     */
+    public function getSetting($key)
+    {
+        if (!$this->hasSetting($key)) {
+            throw new ParameterNotFoundException(sprintf(
+                '`%s` suite does not have a `%s` setting.',
+                $this->getName(),
+                $key
+            ), $this->getName(), $key);
+        }
+
+        return $this->settings[$key];
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Suite/ServiceContainer/SuiteExtension.php b/vendor/behat/behat/src/Behat/Testwork/Suite/ServiceContainer/SuiteExtension.php
new file mode 100644 (file)
index 0000000..79fbcda
--- /dev/null
@@ -0,0 +1,274 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Suite\ServiceContainer;
+
+use Behat\Testwork\Cli\ServiceContainer\CliExtension;
+use Behat\Testwork\ServiceContainer\Extension;
+use Behat\Testwork\ServiceContainer\ExtensionManager;
+use Behat\Testwork\ServiceContainer\ServiceProcessor;
+use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Definition;
+use Symfony\Component\DependencyInjection\Reference;
+
+/**
+ * Extends testwork with suite-related services.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class SuiteExtension implements Extension
+{
+    /*
+     * Available services
+     */
+    const REGISTRY_ID = 'suite.registry';
+    const BOOTSTRAPPER_ID = 'suite.bootstrapper';
+
+    /*
+     * Available extension points
+     */
+    const GENERATOR_TAG = 'suite.generator';
+    const SETUP_TAG = 'suite.setup';
+
+    /**
+     * @var ServiceProcessor
+     */
+    private $processor;
+
+    /**
+     * Initializes extension.
+     *
+     * @param null|ServiceProcessor $processor
+     */
+    public function __construct(ServiceProcessor $processor = null)
+    {
+        $this->processor = $processor ? : new ServiceProcessor();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getConfigKey()
+    {
+        return 'suites';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function initialize(ExtensionManager $extensionManager)
+    {
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function configure(ArrayNodeDefinition $builder)
+    {
+        $builder
+            ->defaultValue(array('default' => array(
+                'enabled'    => true,
+                'type'       => null,
+                'settings'   => array()
+            )))
+            ->treatNullLike(array())
+            ->treatFalseLike(array())
+            ->useAttributeAsKey('name')
+            ->normalizeKeys(false)
+            ->prototype('array')
+                ->beforeNormalization()
+                    ->ifTrue(function ($suite) {
+                        return is_array($suite) && count($suite);
+                    })
+                    ->then(function ($suite) {
+                        $suite['settings'] = isset($suite['settings'])
+                            ? $suite['settings']
+                            : array();
+
+                        foreach ($suite as $key => $val) {
+                            $suiteKeys = array('enabled', 'type', 'settings');
+                            if (!in_array($key, $suiteKeys)) {
+                                $suite['settings'][$key] = $val;
+                                unset($suite[$key]);
+                            }
+                        }
+
+                        return $suite;
+                    })
+                ->end()
+                ->normalizeKeys(false)
+                ->addDefaultsIfNotSet()
+                ->treatTrueLike(array('enabled' => true))
+                ->treatNullLike(array('enabled' => true))
+                ->treatFalseLike(array('enabled' => false))
+                ->children()
+                    ->booleanNode('enabled')
+                        ->info('Enables/disables suite')
+                        ->defaultTrue()
+                    ->end()
+                    ->scalarNode('type')
+                        ->info('Specifies suite type')
+                        ->defaultValue(null)
+                    ->end()
+                    ->arrayNode('settings')
+                        ->info('Specifies suite extra settings')
+                        ->defaultValue(array())
+                        ->useAttributeAsKey('name')
+                        ->prototype('variable')->end()
+                    ->end()
+                ->end()
+            ->end()
+        ;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function load(ContainerBuilder $container, array $config)
+    {
+        $this->setSuiteConfigurations($container, $config);
+        $this->loadRegistryController($container);
+        $this->loadBootstrapController($container);
+        $this->loadRegistry($container);
+        $this->loadBootstrapper($container);
+        $this->loadGenericSuiteGenerator($container);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function process(ContainerBuilder $container)
+    {
+        $this->processGenerators($container);
+        $this->processSetups($container);
+    }
+
+    /**
+     * Generates and sets suites parameter to container.
+     *
+     * @param ContainerBuilder $container
+     * @param array            $suites
+     */
+    private function setSuiteConfigurations(ContainerBuilder $container, array $suites)
+    {
+        $configuredSuites = array();
+        foreach ($suites as $name => $config) {
+            if (!$config['enabled']) {
+                continue;
+            }
+
+            $configuredSuites[$name] = array(
+                'type'     => $config['type'],
+                'settings' => $config['settings'],
+            );
+        }
+
+        $container->setParameter('suite.configurations', $configuredSuites);
+    }
+
+    /**
+     * Loads suite registry controller.
+     *
+     * @param ContainerBuilder $container
+     */
+    private function loadRegistryController(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Testwork\Suite\Cli\SuiteController', array(
+            new Reference(self::REGISTRY_ID),
+            '%suite.configurations%'
+        ));
+        $definition->addTag(CliExtension::CONTROLLER_TAG, array('priority' => 1100));
+        $container->setDefinition(CliExtension::CONTROLLER_TAG . '.suite', $definition);
+    }
+
+    /**
+     * Loads suite bootstrap controller.
+     *
+     * @param ContainerBuilder $container
+     */
+    private function loadBootstrapController(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Testwork\Suite\Cli\InitializationController', array(
+            new Reference(self::REGISTRY_ID),
+            new Reference(self::BOOTSTRAPPER_ID)
+        ));
+        $definition->addTag(CliExtension::CONTROLLER_TAG, array('priority' => 900));
+        $container->setDefinition(CliExtension::CONTROLLER_TAG . '.initialization', $definition);
+    }
+
+    /**
+     * Loads suite registry.
+     *
+     * @param ContainerBuilder $container
+     */
+    private function loadRegistry(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Testwork\Suite\SuiteRegistry');
+        $container->setDefinition(self::REGISTRY_ID, $definition);
+    }
+
+    /**
+     * Loads suite bootstrapper.
+     *
+     * @param ContainerBuilder $container
+     */
+    private function loadBootstrapper(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Testwork\Suite\SuiteBootstrapper');
+        $container->setDefinition(self::BOOTSTRAPPER_ID, $definition);
+    }
+
+    /**
+     * Loads generic suite generator.
+     *
+     * @param ContainerBuilder $container
+     */
+    private function loadGenericSuiteGenerator(ContainerBuilder $container)
+    {
+        $container->setParameter('suite.generic.default_settings', array());
+
+        $definition = new Definition('Behat\Testwork\Suite\Generator\GenericSuiteGenerator', array(
+            '%suite.generic.default_settings%'
+        ));
+        $definition->addTag(SuiteExtension::GENERATOR_TAG, array('priority' => 50));
+        $container->setDefinition(SuiteExtension::GENERATOR_TAG . '.generic', $definition);
+    }
+
+    /**
+     * Processes suite generators.
+     *
+     * @param ContainerBuilder $container
+     */
+    private function processGenerators(ContainerBuilder $container)
+    {
+        $references = $this->processor->findAndSortTaggedServices($container, self::GENERATOR_TAG);
+        $definition = $container->getDefinition(self::REGISTRY_ID);
+
+        foreach ($references as $reference) {
+            $definition->addMethodCall('registerSuiteGenerator', array($reference));
+        }
+    }
+
+    /**
+     * Processes suite setups.
+     *
+     * @param ContainerBuilder $container
+     */
+    private function processSetups(ContainerBuilder $container)
+    {
+        $references = $this->processor->findAndSortTaggedServices($container, self::SETUP_TAG);
+        $definition = $container->getDefinition(self::BOOTSTRAPPER_ID);
+
+        foreach ($references as $reference) {
+            $definition->addMethodCall('registerSuiteSetup', array($reference));
+        }
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Suite/Setup/SuiteSetup.php b/vendor/behat/behat/src/Behat/Testwork/Suite/Setup/SuiteSetup.php
new file mode 100644 (file)
index 0000000..6165624
--- /dev/null
@@ -0,0 +1,40 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Suite\Setup;
+
+use Behat\Testwork\Suite\Suite;
+use Behat\Testwork\Suite\SuiteBootstrapper;
+
+/**
+ * Sets up supported test suite.
+ *
+ * @see SuiteBootstrapper
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface SuiteSetup
+{
+    /**
+     * Checks if setup supports provided suite.
+     *
+     * @param Suite $suite
+     *
+     * @return Boolean
+     */
+    public function supportsSuite(Suite $suite);
+
+    /**
+     * Sets up provided suite.
+     *
+     * @param Suite $suite
+     */
+    public function setupSuite(Suite $suite);
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Suite/Suite.php b/vendor/behat/behat/src/Behat/Testwork/Suite/Suite.php
new file mode 100644 (file)
index 0000000..782f8fd
--- /dev/null
@@ -0,0 +1,51 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Suite;
+
+/**
+ * Represents a Testwork suite. Suite is a collection of tests.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface Suite
+{
+    /**
+     * Returns unique suite name.
+     *
+     * @return string
+     */
+    public function getName();
+
+    /**
+     * Returns suite settings.
+     *
+     * @return array
+     */
+    public function getSettings();
+
+    /**
+     * Checks if a setting with provided name exists.
+     *
+     * @param string $key
+     *
+     * @return Boolean
+     */
+    public function hasSetting($key);
+
+    /**
+     * Returns setting value by its key.
+     *
+     * @param string $key
+     *
+     * @return mixed
+     */
+    public function getSetting($key);
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Suite/SuiteBootstrapper.php b/vendor/behat/behat/src/Behat/Testwork/Suite/SuiteBootstrapper.php
new file mode 100644 (file)
index 0000000..28d0af1
--- /dev/null
@@ -0,0 +1,60 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Suite;
+
+use Behat\Testwork\Suite\Setup\SuiteSetup;
+
+/**
+ * Configures provided suites using registered suite setups.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class SuiteBootstrapper
+{
+    /**
+     * @var SuiteSetup[]
+     */
+    private $setups = array();
+
+    /**
+     * Registers suite setup.
+     *
+     * @param SuiteSetup $setup
+     */
+    public function registerSuiteSetup(SuiteSetup $setup)
+    {
+        $this->setups[] = $setup;
+    }
+
+    /**
+     * Bootstraps provided suites using registered setups.
+     *
+     * @param Suite[] $suites
+     */
+    public function bootstrapSuites(array $suites)
+    {
+        array_map(array($this, 'bootstrapSuite'), $suites);
+    }
+
+    /**
+     * Bootstraps provided suite using registered setup.
+     *
+     * @param Suite $suite
+     */
+    public function bootstrapSuite(Suite $suite)
+    {
+        foreach ($this->setups as $setup) {
+            if ($setup->supportsSuite($suite)) {
+                $setup->setupSuite($suite);
+            }
+        }
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Suite/SuiteRegistry.php b/vendor/behat/behat/src/Behat/Testwork/Suite/SuiteRegistry.php
new file mode 100644 (file)
index 0000000..5ad98fd
--- /dev/null
@@ -0,0 +1,125 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Suite;
+
+use Behat\Testwork\Suite\Exception\SuiteConfigurationException;
+use Behat\Testwork\Suite\Exception\SuiteGenerationException;
+use Behat\Testwork\Suite\Generator\SuiteGenerator;
+
+/**
+ * Acts like a suite repository by auto-generating suites for registered suite configurations using registered
+ * generators.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class SuiteRegistry implements SuiteRepository
+{
+    /**
+     * @var Boolean
+     */
+    private $suitesGenerated = false;
+    /**
+     * @var SuiteGenerator[]
+     */
+    private $generators = array();
+    /**
+     * @var array
+     */
+    private $suiteConfigurations = array();
+    /**
+     * @var Suite[]
+     */
+    private $suites = array();
+
+    /**
+     * Registers suite generator.
+     *
+     * @param SuiteGenerator $generator
+     */
+    public function registerSuiteGenerator(SuiteGenerator $generator)
+    {
+        $this->generators[] = $generator;
+        $this->suitesGenerated = false;
+    }
+
+    /**
+     * Registers suite using provided name, type & parameters.
+     *
+     * @param string $name
+     * @param string $type
+     * @param array  $settings
+     *
+     * @throws SuiteConfigurationException
+     */
+    public function registerSuiteConfiguration($name, $type, array $settings)
+    {
+        if (isset($this->suiteConfigurations[$name])) {
+            throw new SuiteConfigurationException(sprintf(
+                'Suite configuration for a suite "%s" is already registered.',
+                $name
+            ), $name);
+        }
+
+        $this->suiteConfigurations[$name] = array($type, $settings);
+        $this->suitesGenerated = false;
+    }
+
+    /**
+     * Returns all available suites.
+     *
+     * @return Suite[]
+     */
+    public function getSuites()
+    {
+        if ($this->suitesGenerated) {
+            return $this->suites;
+        }
+
+        $this->suites = array();
+        foreach ($this->suiteConfigurations as $name => $configuration) {
+            list($type, $settings) = $configuration;
+
+            $this->suites[] = $this->generateSuite($name, $type, $settings);
+        }
+
+        $this->suitesGenerated = true;
+
+        return $this->suites;
+    }
+
+    /**
+     * Generates suite using registered generators.
+     *
+     * @param string $name
+     * @param string $type
+     * @param array  $settings
+     *
+     * @return Suite
+     *
+     * @throws SuiteGenerationException If no appropriate generator found
+     */
+    private function generateSuite($name, $type, array $settings)
+    {
+        foreach ($this->generators as $generator) {
+            if (!$generator->supportsTypeAndSettings($type, $settings)) {
+                continue;
+            }
+
+            return $generator->generateSuite($name, $settings);
+        }
+
+        throw new SuiteGenerationException(sprintf(
+            'Can not find suite generator for a suite `%s` of type `%s`.',
+            $name,
+            $type
+        ), $name);
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Suite/SuiteRepository.php b/vendor/behat/behat/src/Behat/Testwork/Suite/SuiteRepository.php
new file mode 100644 (file)
index 0000000..7795cc9
--- /dev/null
@@ -0,0 +1,26 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Suite;
+
+/**
+ * Represents a way to retrieve suites.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface SuiteRepository
+{
+    /**
+     * Returns all available suites.
+     *
+     * @return Suite[]
+     */
+    public function getSuites();
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Tester/Cli/ExerciseController.php b/vendor/behat/behat/src/Behat/Testwork/Tester/Cli/ExerciseController.php
new file mode 100644 (file)
index 0000000..b3d2eac
--- /dev/null
@@ -0,0 +1,179 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Tester\Cli;
+
+use Behat\Testwork\Cli\Controller;
+use Behat\Testwork\Specification\SpecificationFinder;
+use Behat\Testwork\Specification\SpecificationIterator;
+use Behat\Testwork\Suite\Suite;
+use Behat\Testwork\Suite\SuiteRepository;
+use Behat\Testwork\Tester\Exception\WrongPathsException;
+use Behat\Testwork\Tester\Exercise;
+use Behat\Testwork\Tester\Result\IntegerTestResult;
+use Behat\Testwork\Tester\Result\ResultInterpreter;
+use Behat\Testwork\Tester\Result\TestResult;
+use Behat\Testwork\Tester\Result\TestResults;
+use Behat\Testwork\Tester\Result\TestWithSetupResult;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * Executes exercise.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class ExerciseController implements Controller
+{
+    /**
+     * @var SuiteRepository
+     */
+    private $suiteRepository;
+    /**
+     * @var SpecificationFinder
+     */
+    private $specificationFinder;
+    /**
+     * @var Exercise
+     */
+    private $exercise;
+    /**
+     * @var ResultInterpreter
+     */
+    private $resultInterpreter;
+    /**
+     * @var Boolean
+     */
+    private $skip;
+
+    /**
+     * Initializes controller.
+     *
+     * @param SuiteRepository     $suiteRepository
+     * @param SpecificationFinder $specificationFinder
+     * @param Exercise            $exercise
+     * @param ResultInterpreter   $resultInterpreter
+     * @param Boolean             $skip
+     */
+    public function __construct(
+        SuiteRepository $suiteRepository,
+        SpecificationFinder $specificationFinder,
+        Exercise $exercise,
+        ResultInterpreter $resultInterpreter,
+        $skip = false
+    ) {
+        $this->suiteRepository = $suiteRepository;
+        $this->specificationFinder = $specificationFinder;
+        $this->exercise = $exercise;
+        $this->resultInterpreter = $resultInterpreter;
+        $this->skip = $skip;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function configure(Command $command)
+    {
+        $locatorsExamples = implode(PHP_EOL, array_map(
+            function ($locator) {
+                return '- ' . $locator;
+            }, $this->specificationFinder->getExampleLocators()
+        ));
+
+        $command
+            ->addArgument('paths', InputArgument::OPTIONAL,
+                'Optional path(s) to execute. Could be:' . PHP_EOL . $locatorsExamples
+            )
+            ->addOption('--dry-run', null, InputOption::VALUE_NONE,
+                'Invokes formatters without executing the tests and hooks.'
+            );
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function execute(InputInterface $input, OutputInterface $output)
+    {
+        $specs = $this->findSpecifications($input);
+        $result = $this->testSpecifications($input, $specs);
+
+        if ($input->getArgument('paths') && TestResults::NO_TESTS === $result->getResultCode()) {
+            throw new WrongPathsException(
+                sprintf(
+                    'No specifications found at path(s) `%s`. This might be because of incorrect paths configuration in your `suites`.',
+                    $input->getArgument('paths')
+                ),
+                $input->getArgument('paths')
+            );
+        }
+
+        return $this->resultInterpreter->interpretResult($result);
+    }
+
+    /**
+     * Finds exercise specifications.
+     *
+     * @param InputInterface $input
+     *
+     * @return SpecificationIterator[]
+     */
+    private function findSpecifications(InputInterface $input)
+    {
+        return $this->findSuitesSpecifications($this->getAvailableSuites(), $input->getArgument('paths'));
+    }
+
+    /**
+     * Tests exercise specifications.
+     *
+     * @param InputInterface          $input
+     * @param SpecificationIterator[] $specifications
+     *
+     * @return TestResult
+     */
+    private function testSpecifications(InputInterface $input, array $specifications)
+    {
+        $skip = $input->getOption('dry-run') || $this->skip;
+
+        $setup = $this->exercise->setUp($specifications, $skip);
+        $skip = !$setup->isSuccessful() || $skip;
+        $testResult = $this->exercise->test($specifications, $skip);
+        $teardown = $this->exercise->tearDown($specifications, $skip, $testResult);
+
+        $result = new IntegerTestResult($testResult->getResultCode());
+
+        return new TestWithSetupResult($setup, $result, $teardown);
+    }
+
+    /**
+     * Returns all currently available suites.
+     *
+     * @return Suite[]
+     */
+    private function getAvailableSuites()
+    {
+        return $this->suiteRepository->getSuites();
+    }
+
+    /**
+     * Finds specification iterators for all provided suites using locator.
+     *
+     * @param Suite[]     $suites
+     * @param null|string $locator
+     *
+     * @return SpecificationIterator[]
+     */
+    private function findSuitesSpecifications($suites, $locator)
+    {
+        return $this->specificationFinder->findSuitesSpecifications($suites, $locator);
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Tester/Cli/StrictController.php b/vendor/behat/behat/src/Behat/Testwork/Tester/Cli/StrictController.php
new file mode 100644 (file)
index 0000000..1e610be
--- /dev/null
@@ -0,0 +1,70 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Tester\Cli;
+
+use Behat\Testwork\Cli\Controller;
+use Behat\Testwork\Tester\Result\Interpretation\StrictInterpretation;
+use Behat\Testwork\Tester\Result\ResultInterpreter;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * Configures Testwork to interpret test results strictly.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class StrictController implements Controller
+{
+    /**
+     * @var ResultInterpreter
+     */
+    private $resultInterpreter;
+    /**
+     * @var Boolean
+     */
+    private $strict;
+
+    /**
+     * Initializes controller.
+     *
+     * @param ResultInterpreter $resultInterpreter
+     * @param Boolean           $strict
+     */
+    public function __construct(ResultInterpreter $resultInterpreter, $strict = false)
+    {
+        $this->resultInterpreter = $resultInterpreter;
+        $this->strict = $strict;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function configure(Command $command)
+    {
+        $command->addOption('--strict', null, InputOption::VALUE_NONE,
+            'Passes only if all tests are explicitly passing.'
+        );
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function execute(InputInterface $input, OutputInterface $output)
+    {
+        if (!$this->strict && !$input->getOption('strict')) {
+            return;
+        }
+
+        $this->resultInterpreter->registerResultInterpretation(new StrictInterpretation());
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Tester/Exception/TesterException.php b/vendor/behat/behat/src/Behat/Testwork/Tester/Exception/TesterException.php
new file mode 100644 (file)
index 0000000..2bede7c
--- /dev/null
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Tester\Exception;
+
+/**
+ * Represents an exception caused by a tester.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface TesterException
+{
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Tester/Exception/WrongPathsException.php b/vendor/behat/behat/src/Behat/Testwork/Tester/Exception/WrongPathsException.php
new file mode 100644 (file)
index 0000000..c429957
--- /dev/null
@@ -0,0 +1,49 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Tester\Exception;
+
+use Symfony\Component\DependencyInjection\Exception\RuntimeException;
+
+/**
+ * Represents exception caused by a wrong paths argument.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class WrongPathsException extends RuntimeException implements TesterException
+{
+    /**
+     * @var string
+     */
+    private $path;
+
+    /**
+     * Initializes exception.
+     *
+     * @param string $message
+     * @param string $path
+     */
+    public function __construct($message, $path)
+    {
+        parent::__construct($message);
+
+        $this->path = $path;
+    }
+
+    /**
+     * Returns path that caused exception.
+     *
+     * @return string
+     */
+    public function getPath()
+    {
+        return $this->path;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Tester/Exercise.php b/vendor/behat/behat/src/Behat/Testwork/Tester/Exercise.php
new file mode 100644 (file)
index 0000000..6a19c1e
--- /dev/null
@@ -0,0 +1,55 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Tester;
+
+use Behat\Testwork\Specification\SpecificationIterator;
+use Behat\Testwork\Tester\Result\TestResult;
+use Behat\Testwork\Tester\Setup\Setup;
+use Behat\Testwork\Tester\Setup\Teardown;
+
+/**
+ * Prepares and tests provided exercise specifications.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface Exercise
+{
+    /**
+     * Sets up exercise for a test.
+     *
+     * @param SpecificationIterator[] $iterators
+     * @param Boolean                 $skip
+     *
+     * @return Setup
+     */
+    public function setUp(array $iterators, $skip);
+
+    /**
+     * Tests suites specifications.
+     *
+     * @param SpecificationIterator[] $iterators
+     * @param Boolean                 $skip
+     *
+     * @return TestResult
+     */
+    public function test(array $iterators, $skip);
+
+    /**
+     * Tears down exercise after a test.
+     *
+     * @param SpecificationIterator[] $iterators
+     * @param Boolean                 $skip
+     * @param TestResult              $result
+     *
+     * @return Teardown
+     */
+    public function tearDown(array $iterators, $skip, TestResult $result);
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Tester/Result/ExceptionResult.php b/vendor/behat/behat/src/Behat/Testwork/Tester/Result/ExceptionResult.php
new file mode 100644 (file)
index 0000000..f30edcf
--- /dev/null
@@ -0,0 +1,35 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Tester\Result;
+
+use Exception;
+
+/**
+ * Represents a result, that possibly produced an exception.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface ExceptionResult extends TestResult
+{
+    /**
+     * Checks that the test result has exception.
+     *
+     * @return Boolean
+     */
+    public function hasException();
+
+    /**
+     * Returns exception that test result has.
+     *
+     * @return null|Exception
+     */
+    public function getException();
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Tester/Result/IntegerTestResult.php b/vendor/behat/behat/src/Behat/Testwork/Tester/Result/IntegerTestResult.php
new file mode 100644 (file)
index 0000000..8dad2fc
--- /dev/null
@@ -0,0 +1,50 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Tester\Result;
+
+/**
+ * Represents an integer test result.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class IntegerTestResult implements TestResult
+{
+    /**
+     * @var integer
+     */
+    private $resultCode;
+
+    /**
+     * Initializes test result.
+     *
+     * @param integer $resultCode
+     */
+    public function __construct($resultCode)
+    {
+        $this->resultCode = $resultCode;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function isPassed()
+    {
+        return self::PASSED == $this->getResultCode();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getResultCode()
+    {
+        return $this->resultCode;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Tester/Result/Interpretation/ResultInterpretation.php b/vendor/behat/behat/src/Behat/Testwork/Tester/Result/Interpretation/ResultInterpretation.php
new file mode 100644 (file)
index 0000000..555e75f
--- /dev/null
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Tester\Result\Interpretation;
+
+use Behat\Testwork\Tester\Result\ResultInterpreter;
+use Behat\Testwork\Tester\Result\TestResult;
+
+/**
+ * Interprets particular test result by saying if it's failure or not.
+ *
+ * @see ResultInterpreter
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface ResultInterpretation
+{
+    /**
+     * Checks if provided test result should be considered as a failure.
+     *
+     * @param TestResult $result
+     *
+     * @return Boolean
+     */
+    public function isFailure(TestResult $result);
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Tester/Result/Interpretation/SoftInterpretation.php b/vendor/behat/behat/src/Behat/Testwork/Tester/Result/Interpretation/SoftInterpretation.php
new file mode 100644 (file)
index 0000000..fca891b
--- /dev/null
@@ -0,0 +1,29 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Tester\Result\Interpretation;
+
+use Behat\Testwork\Tester\Result\TestResult;
+
+/**
+ * Interprets test results softly - everything that is not an explicit failure is a pass.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class SoftInterpretation implements ResultInterpretation
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function isFailure(TestResult $result)
+    {
+        return TestResult::FAILED <= $result->getResultCode();
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Tester/Result/Interpretation/StrictInterpretation.php b/vendor/behat/behat/src/Behat/Testwork/Tester/Result/Interpretation/StrictInterpretation.php
new file mode 100644 (file)
index 0000000..0a43d8d
--- /dev/null
@@ -0,0 +1,29 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Tester\Result\Interpretation;
+
+use Behat\Testwork\Tester\Result\TestResult;
+
+/**
+ * Interprets test results strictly - everything that is not an explicit pass is a failure.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class StrictInterpretation implements ResultInterpretation
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function isFailure(TestResult $result)
+    {
+        return !$result->isPassed();
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Tester/Result/ResultInterpreter.php b/vendor/behat/behat/src/Behat/Testwork/Tester/Result/ResultInterpreter.php
new file mode 100644 (file)
index 0000000..5ea9ad1
--- /dev/null
@@ -0,0 +1,54 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Tester\Result;
+
+use Behat\Testwork\Tester\Result\Interpretation\ResultInterpretation;
+
+/**
+ * Interprets provided test result (as 1 or 0) using registered interpretations.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class ResultInterpreter
+{
+    /**
+     * @var ResultInterpretation[]
+     */
+    private $interpretations = array();
+
+    /**
+     * Registers result interpretation.
+     *
+     * @param ResultInterpretation $interpretation
+     */
+    public function registerResultInterpretation(ResultInterpretation $interpretation)
+    {
+        $this->interpretations[] = $interpretation;
+    }
+
+    /**
+     * Interprets result as a UNIX return code (0 for success, 1 for failure).
+     *
+     * @param TestResult $result
+     *
+     * @return integer
+     */
+    public function interpretResult(TestResult $result)
+    {
+        foreach ($this->interpretations as $interpretation) {
+            if ($interpretation->isFailure($result)) {
+                return 1;
+            }
+        }
+
+        return 0;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Tester/Result/TestResult.php b/vendor/behat/behat/src/Behat/Testwork/Tester/Result/TestResult.php
new file mode 100644 (file)
index 0000000..9d55796
--- /dev/null
@@ -0,0 +1,38 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Tester\Result;
+
+/**
+ * Represents a test result.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface TestResult
+{
+    const PASSED = 0;
+    const SKIPPED = 10;
+    const PENDING = 20;
+    const FAILED = 99;
+
+    /**
+     * Checks that test has passed.
+     *
+     * @return Boolean
+     */
+    public function isPassed();
+
+    /**
+     * Returns tester result code.
+     *
+     * @return integer
+     */
+    public function getResultCode();
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Tester/Result/TestResults.php b/vendor/behat/behat/src/Behat/Testwork/Tester/Result/TestResults.php
new file mode 100644 (file)
index 0000000..5102f37
--- /dev/null
@@ -0,0 +1,87 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Tester\Result;
+
+use ArrayIterator;
+use Countable;
+use IteratorAggregate;
+
+/**
+ * Aggregates multiple test results into a collection and provides informational API on top of that.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class TestResults implements TestResult, Countable, IteratorAggregate
+{
+    const NO_TESTS = -100;
+
+    /**
+     * @var TestResult[]
+     */
+    private $results;
+
+    /**
+     * Initializes test results collection.
+     *
+     * @param TestResult[] $results
+     */
+    public function __construct(array $results = array())
+    {
+        $this->results = $results;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function isPassed()
+    {
+        return self::PASSED == $this->getResultCode();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getResultCode()
+    {
+        $resultCode = static::NO_TESTS;
+        foreach ($this->results as $result) {
+            $resultCode = max($resultCode, $result->getResultCode());
+        }
+
+        return $resultCode;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function count()
+    {
+        return count($this->results);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getIterator()
+    {
+        return new ArrayIterator($this->results);
+    }
+
+    /**
+     * Returns test results array.
+     *
+     * @return TestResult[]
+     */
+    public function toArray()
+    {
+        return $this->results;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Tester/Result/TestWithSetupResult.php b/vendor/behat/behat/src/Behat/Testwork/Tester/Result/TestWithSetupResult.php
new file mode 100644 (file)
index 0000000..e9fa4f7
--- /dev/null
@@ -0,0 +1,73 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Tester\Result;
+
+use Behat\Testwork\Tester\Setup\Setup;
+use Behat\Testwork\Tester\Setup\Teardown;
+
+/**
+ * Represents a test result with both setup and teardown attached.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class TestWithSetupResult implements TestResult
+{
+    /**
+     * @var Setup
+     */
+    private $setup;
+    /**
+     * @var TestResult
+     */
+    private $result;
+    /**
+     * @var Teardown
+     */
+    private $teardown;
+
+    /**
+     * Initializes test result.
+     *
+     * @param Setup      $setup
+     * @param TestResult $result
+     * @param Teardown   $teardown
+     */
+    public function __construct(Setup $setup, TestResult $result, Teardown $teardown)
+    {
+        $this->setup = $setup;
+        $this->result = $result;
+        $this->teardown = $teardown;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function isPassed()
+    {
+        return self::PASSED == $this->getResultCode();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getResultCode()
+    {
+        if (!$this->setup->isSuccessful()) {
+            return self::FAILED;
+        }
+
+        if (!$this->teardown->isSuccessful()) {
+            return self::FAILED;
+        }
+
+        return $this->result->getResultCode();
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Tester/Runtime/RuntimeExercise.php b/vendor/behat/behat/src/Behat/Testwork/Tester/Runtime/RuntimeExercise.php
new file mode 100644 (file)
index 0000000..2f831dd
--- /dev/null
@@ -0,0 +1,88 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Tester\Runtime;
+
+use Behat\Testwork\Environment\EnvironmentManager;
+use Behat\Testwork\Specification\GroupedSpecificationIterator;
+use Behat\Testwork\Tester\Exercise;
+use Behat\Testwork\Tester\Result\IntegerTestResult;
+use Behat\Testwork\Tester\Result\TestResult;
+use Behat\Testwork\Tester\Result\TestResults;
+use Behat\Testwork\Tester\Result\TestWithSetupResult;
+use Behat\Testwork\Tester\Setup\SuccessfulSetup;
+use Behat\Testwork\Tester\Setup\SuccessfulTeardown;
+use Behat\Testwork\Tester\SuiteTester;
+
+/**
+ * Tester executing exercises in the runtime.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class RuntimeExercise implements Exercise
+{
+    /**
+     * @var EnvironmentManager
+     */
+    private $envManager;
+    /**
+     * @var SuiteTester
+     */
+    private $suiteTester;
+
+    /**
+     * Initializes tester.
+     *
+     * @param EnvironmentManager $envManager
+     * @param SuiteTester        $suiteTester
+     */
+    public function __construct(EnvironmentManager $envManager, SuiteTester $suiteTester)
+    {
+        $this->envManager = $envManager;
+        $this->suiteTester = $suiteTester;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setUp(array $iterators, $skip)
+    {
+        return new SuccessfulSetup();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function test(array $iterators, $skip = false)
+    {
+        $results = array();
+        foreach (GroupedSpecificationIterator::group($iterators) as $iterator) {
+            $environment = $this->envManager->buildEnvironment($iterator->getSuite());
+
+            $setup = $this->suiteTester->setUp($environment, $iterator, $skip);
+            $localSkip = !$setup->isSuccessful() || $skip;
+            $testResult = $this->suiteTester->test($environment, $iterator, $localSkip);
+            $teardown = $this->suiteTester->tearDown($environment, $iterator, $localSkip, $testResult);
+
+            $integerResult = new IntegerTestResult($testResult->getResultCode());
+            $results[] = new TestWithSetupResult($setup, $integerResult, $teardown);
+        }
+
+        return new TestResults($results);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function tearDown(array $iterators, $skip, TestResult $result)
+    {
+        return new SuccessfulTeardown();
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Tester/Runtime/RuntimeSuiteTester.php b/vendor/behat/behat/src/Behat/Testwork/Tester/Runtime/RuntimeSuiteTester.php
new file mode 100644 (file)
index 0000000..b67838d
--- /dev/null
@@ -0,0 +1,80 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Tester\Runtime;
+
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\Specification\SpecificationIterator;
+use Behat\Testwork\Tester\Result\IntegerTestResult;
+use Behat\Testwork\Tester\Result\TestResult;
+use Behat\Testwork\Tester\Result\TestResults;
+use Behat\Testwork\Tester\Result\TestWithSetupResult;
+use Behat\Testwork\Tester\Setup\SuccessfulSetup;
+use Behat\Testwork\Tester\Setup\SuccessfulTeardown;
+use Behat\Testwork\Tester\SpecificationTester;
+use Behat\Testwork\Tester\SuiteTester;
+
+/**
+ * Tester executing suite tests in the runtime.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class RuntimeSuiteTester implements SuiteTester
+{
+    /**
+     * @var SpecificationTester
+     */
+    private $specTester;
+
+    /**
+     * Initializes tester.
+     *
+     * @param SpecificationTester $specTester
+     */
+    public function __construct(SpecificationTester $specTester)
+    {
+        $this->specTester = $specTester;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setUp(Environment $env, SpecificationIterator $iterator, $skip)
+    {
+        return new SuccessfulSetup();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function test(Environment $env, SpecificationIterator $iterator, $skip = false)
+    {
+        $results = array();
+        foreach ($iterator as $specification) {
+            $setup = $this->specTester->setUp($env, $specification, $skip);
+            $localSkip = !$setup->isSuccessful() || $skip;
+            $testResult = $this->specTester->test($env, $specification, $localSkip);
+            $teardown = $this->specTester->tearDown($env, $specification, $localSkip, $testResult);
+
+            $integerResult = new IntegerTestResult($testResult->getResultCode());
+            $results[] = new TestWithSetupResult($setup, $integerResult, $teardown);
+        }
+
+        return new TestResults($results);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function tearDown(Environment $env, SpecificationIterator $iterator, $skip, TestResult $result)
+    {
+        return new SuccessfulTeardown();
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Tester/ServiceContainer/TesterExtension.php b/vendor/behat/behat/src/Behat/Testwork/Tester/ServiceContainer/TesterExtension.php
new file mode 100644 (file)
index 0000000..55bcfa9
--- /dev/null
@@ -0,0 +1,250 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Tester\ServiceContainer;
+
+use Behat\Testwork\Cli\ServiceContainer\CliExtension;
+use Behat\Testwork\Environment\ServiceContainer\EnvironmentExtension;
+use Behat\Testwork\ServiceContainer\Extension;
+use Behat\Testwork\ServiceContainer\ExtensionManager;
+use Behat\Testwork\ServiceContainer\ServiceProcessor;
+use Behat\Testwork\Specification\ServiceContainer\SpecificationExtension;
+use Behat\Testwork\Suite\ServiceContainer\SuiteExtension;
+use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Definition;
+use Symfony\Component\DependencyInjection\Reference;
+
+/**
+ * Provides tester services.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+abstract class TesterExtension implements Extension
+{
+    /*
+     * Available services
+     */
+    const EXERCISE_ID = 'tester.exercise';
+    const SUITE_TESTER_ID = 'tester.suite';
+    const SPECIFICATION_TESTER_ID = 'tester.specification';
+    const RESULT_INTERPRETER_ID = 'tester.result.interpreter';
+
+    /**
+     * Available extension points
+     */
+    const EXERCISE_WRAPPER_TAG = 'tester.exercise.wrapper';
+    const SUITE_TESTER_WRAPPER_TAG = 'tester.suite.wrapper';
+    const SPECIFICATION_TESTER_WRAPPER_TAG = 'tester.specification.wrapper';
+    const RESULT_INTERPRETATION_TAG = 'test.result.interpretation';
+
+    /**
+     * @var ServiceProcessor
+     */
+    private $processor;
+
+    /**
+     * Initializes extension.
+     *
+     * @param null|ServiceProcessor $processor
+     */
+    public function __construct(ServiceProcessor $processor = null)
+    {
+        $this->processor = $processor ? : new ServiceProcessor();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getConfigKey()
+    {
+        return 'testers';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function initialize(ExtensionManager $extensionManager)
+    {
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function configure(ArrayNodeDefinition $builder)
+    {
+        $builder
+            ->addDefaultsIfNotSet()
+            ->children()
+                ->booleanNode('strict')
+                    ->info('Sets the strict mode for result interpretation')
+                    ->defaultFalse()
+                ->end()
+                ->booleanNode('skip')
+                    ->info('Tells tester to skip all tests')
+                    ->defaultFalse()
+                ->end()
+            ->end()
+        ;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function load(ContainerBuilder $container, array $config)
+    {
+        $this->loadExerciseController($container, $config['skip']);
+        $this->loadStrictController($container, $config['strict']);
+        $this->loadResultInterpreter($container);
+        $this->loadExercise($container);
+        $this->loadSuiteTester($container);
+        $this->loadSpecificationTester($container);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function process(ContainerBuilder $container)
+    {
+        $this->processExerciseWrappers($container);
+        $this->processSuiteTesterWrappers($container);
+        $this->processSpecificationTesterWrappers($container);
+        $this->processResultInterpretations($container);
+    }
+
+    /**
+     * Loads exercise cli controllers.
+     *
+     * @param ContainerBuilder $container
+     * @param Boolean          $skip
+     */
+    protected function loadExerciseController(ContainerBuilder $container, $skip = false)
+    {
+        $definition = new Definition('Behat\Testwork\Tester\Cli\ExerciseController', array(
+            new Reference(SuiteExtension::REGISTRY_ID),
+            new Reference(SpecificationExtension::FINDER_ID),
+            new Reference(self::EXERCISE_ID),
+            new Reference(self::RESULT_INTERPRETER_ID),
+            $skip
+        ));
+        $definition->addTag(CliExtension::CONTROLLER_TAG, array('priority' => 0));
+        $container->setDefinition(CliExtension::CONTROLLER_TAG . '.exercise', $definition);
+    }
+
+    /**
+     * Loads exercise cli controllers.
+     *
+     * @param ContainerBuilder $container
+     * @param Boolean          $strict
+     */
+    protected function loadStrictController(ContainerBuilder $container, $strict = false)
+    {
+        $definition = new Definition('Behat\Testwork\Tester\Cli\StrictController', array(
+            new Reference(self::RESULT_INTERPRETER_ID),
+            $strict
+        ));
+        $definition->addTag(CliExtension::CONTROLLER_TAG, array('priority' => 300));
+        $container->setDefinition(CliExtension::CONTROLLER_TAG . '.strict', $definition);
+    }
+
+    /**
+     * Loads result interpreter controller
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function loadResultInterpreter(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Testwork\Tester\Result\ResultInterpreter');
+        $container->setDefinition(self::RESULT_INTERPRETER_ID, $definition);
+
+        $definition = new Definition('Behat\Testwork\Tester\Result\Interpretation\SoftInterpretation');
+        $definition->addTag(self::RESULT_INTERPRETATION_TAG);
+        $container->setDefinition(self::RESULT_INTERPRETATION_TAG . '.soft', $definition);
+    }
+
+    /**
+     * Loads exercise tester.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function loadExercise(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Testwork\Tester\Runtime\RuntimeExercise', array(
+            new Reference(EnvironmentExtension::MANAGER_ID),
+            new Reference(self::SUITE_TESTER_ID)
+        ));
+        $container->setDefinition(self::EXERCISE_ID, $definition);
+    }
+
+    /**
+     * Loads suite tester.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function loadSuiteTester(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Testwork\Tester\Runtime\RuntimeSuiteTester', array(
+            new Reference(self::SPECIFICATION_TESTER_ID)
+        ));
+        $container->setDefinition(self::SUITE_TESTER_ID, $definition);
+    }
+
+    /**
+     * Loads specification tester.
+     *
+     * @param ContainerBuilder $container
+     */
+    abstract protected function loadSpecificationTester(ContainerBuilder $container);
+
+    /**
+     * Processes all registered exercise wrappers.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function processExerciseWrappers(ContainerBuilder $container)
+    {
+        $this->processor->processWrapperServices($container, self::EXERCISE_ID, self::EXERCISE_WRAPPER_TAG);
+    }
+
+    /**
+     * Processes all registered suite tester wrappers.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function processSuiteTesterWrappers(ContainerBuilder $container)
+    {
+        $this->processor->processWrapperServices($container, self::SUITE_TESTER_ID, self::SUITE_TESTER_WRAPPER_TAG);
+    }
+
+    /**
+     * Processes all registered specification tester wrappers.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function processSpecificationTesterWrappers(ContainerBuilder $container)
+    {
+        $this->processor->processWrapperServices($container, self::SPECIFICATION_TESTER_ID, self::SPECIFICATION_TESTER_WRAPPER_TAG);
+    }
+
+    /**
+     * Processes all registered result interpretations.
+     *
+     * @param ContainerBuilder $container
+     */
+    protected function processResultInterpretations(ContainerBuilder $container)
+    {
+        $references = $this->processor->findAndSortTaggedServices($container, self::RESULT_INTERPRETATION_TAG);
+        $definition = $container->getDefinition(self::RESULT_INTERPRETER_ID);
+
+        foreach ($references as $reference) {
+            $definition->addMethodCall('registerResultInterpretation', array($reference));
+        }
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Tester/Setup/FailedSetup.php b/vendor/behat/behat/src/Behat/Testwork/Tester/Setup/FailedSetup.php
new file mode 100644 (file)
index 0000000..2130cd3
--- /dev/null
@@ -0,0 +1,35 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Tester\Setup;
+
+/**
+ * Represents a failed setup.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class FailedSetup implements Setup
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function isSuccessful()
+    {
+        return false;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function hasOutput()
+    {
+        return false;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Tester/Setup/FailedTeardown.php b/vendor/behat/behat/src/Behat/Testwork/Tester/Setup/FailedTeardown.php
new file mode 100644 (file)
index 0000000..7fdc74d
--- /dev/null
@@ -0,0 +1,35 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Tester\Setup;
+
+/**
+ * Represents a failed teardown.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class FailedTeardown implements Teardown
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function isSuccessful()
+    {
+        return false;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function hasOutput()
+    {
+        return false;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Tester/Setup/Setup.php b/vendor/behat/behat/src/Behat/Testwork/Tester/Setup/Setup.php
new file mode 100644 (file)
index 0000000..e904ebb
--- /dev/null
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Tester\Setup;
+
+/**
+ * Represents a result of test setUp action.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface Setup
+{
+    /**
+     * Returns true if fixtures have been handled successfully.
+     *
+     * @return Boolean
+     */
+    public function isSuccessful();
+
+    /**
+     * Checks if setup has produced any output.
+     *
+     * @return Boolean
+     */
+    public function hasOutput();
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Tester/Setup/SuccessfulSetup.php b/vendor/behat/behat/src/Behat/Testwork/Tester/Setup/SuccessfulSetup.php
new file mode 100644 (file)
index 0000000..56686d0
--- /dev/null
@@ -0,0 +1,35 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Tester\Setup;
+
+/**
+ * Represents successful setup.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class SuccessfulSetup implements Setup
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function isSuccessful()
+    {
+        return true;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function hasOutput()
+    {
+        return false;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Tester/Setup/SuccessfulTeardown.php b/vendor/behat/behat/src/Behat/Testwork/Tester/Setup/SuccessfulTeardown.php
new file mode 100644 (file)
index 0000000..8a94d15
--- /dev/null
@@ -0,0 +1,35 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Tester\Setup;
+
+/**
+ * Represents successful teardown.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class SuccessfulTeardown implements Teardown
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function isSuccessful()
+    {
+        return true;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function hasOutput()
+    {
+        return false;
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Tester/Setup/Teardown.php b/vendor/behat/behat/src/Behat/Testwork/Tester/Setup/Teardown.php
new file mode 100644 (file)
index 0000000..fbb445b
--- /dev/null
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Tester\Setup;
+
+/**
+ * Represents a result of test tearDown action.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface Teardown
+{
+    /**
+     * Returns true if fixtures have been handled successfully.
+     *
+     * @return Boolean
+     */
+    public function isSuccessful();
+
+    /**
+     * Checks if tear down has produced any output.
+     *
+     * @return Boolean
+     */
+    public function hasOutput();
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Tester/SpecificationTester.php b/vendor/behat/behat/src/Behat/Testwork/Tester/SpecificationTester.php
new file mode 100644 (file)
index 0000000..9dc106a
--- /dev/null
@@ -0,0 +1,58 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Tester;
+
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\Tester\Result\TestResult;
+use Behat\Testwork\Tester\Setup\Setup;
+use Behat\Testwork\Tester\Setup\Teardown;
+
+/**
+ * Prepares and tests provided specification against provided environment.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface SpecificationTester
+{
+    /**
+     * Sets up specification for a test.
+     *
+     * @param Environment $env
+     * @param mixed       $spec
+     * @param Boolean     $skip
+     *
+     * @return Setup
+     */
+    public function setUp(Environment $env, $spec, $skip);
+
+    /**
+     * Tests provided specification.
+     *
+     * @param Environment $env
+     * @param mixed       $spec
+     * @param Boolean     $skip
+     *
+     * @return TestResult
+     */
+    public function test(Environment $env, $spec, $skip);
+
+    /**
+     * Tears down specification after a test.
+     *
+     * @param Environment $env
+     * @param mixed       $spec
+     * @param Boolean     $skip
+     * @param TestResult  $result
+     *
+     * @return Teardown
+     */
+    public function tearDown(Environment $env, $spec, $skip, TestResult $result);
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Tester/SuiteTester.php b/vendor/behat/behat/src/Behat/Testwork/Tester/SuiteTester.php
new file mode 100644 (file)
index 0000000..f139f1a
--- /dev/null
@@ -0,0 +1,59 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Tester;
+
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\Specification\SpecificationIterator;
+use Behat\Testwork\Tester\Result\TestResult;
+use Behat\Testwork\Tester\Setup\Setup;
+use Behat\Testwork\Tester\Setup\Teardown;
+
+/**
+ * Prepares and tests provided suite specifications against provided environment.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface SuiteTester
+{
+    /**
+     * Sets up suite for a test.
+     *
+     * @param Environment           $env
+     * @param SpecificationIterator $iterator
+     * @param Boolean               $skip
+     *
+     * @return Setup
+     */
+    public function setUp(Environment $env, SpecificationIterator $iterator, $skip);
+
+    /**
+     * Tests provided suite specifications.
+     *
+     * @param Environment           $env
+     * @param SpecificationIterator $iterator
+     * @param Boolean               $skip
+     *
+     * @return TestResult
+     */
+    public function test(Environment $env, SpecificationIterator $iterator, $skip);
+
+    /**
+     * Tears down suite after a test.
+     *
+     * @param Environment           $env
+     * @param SpecificationIterator $iterator
+     * @param Boolean               $skip
+     * @param TestResult            $result
+     *
+     * @return Teardown
+     */
+    public function tearDown(Environment $env, SpecificationIterator $iterator, $skip, TestResult $result);
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Translator/Cli/LanguageController.php b/vendor/behat/behat/src/Behat/Testwork/Translator/Cli/LanguageController.php
new file mode 100644 (file)
index 0000000..676b891
--- /dev/null
@@ -0,0 +1,63 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Translator\Cli;
+
+use Behat\Testwork\Cli\Controller;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Translation\Translator;
+
+/**
+ * Configures translator service to use custom locale.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class LanguageController implements Controller
+{
+    /**
+     * @var Translator
+     */
+    private $translator;
+
+    /**
+     * Initializes controller.
+     *
+     * @param Translator $translator
+     */
+    public function __construct(Translator $translator)
+    {
+        $this->translator = $translator;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function configure(Command $command)
+    {
+        $command->addOption('--lang', null, InputOption::VALUE_REQUIRED,
+            'Print output in particular language.'
+        );
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function execute(InputInterface $input, OutputInterface $output)
+    {
+        if (!$input->getOption('lang')) {
+            return;
+        }
+
+        $this->translator->setLocale($input->getOption('lang'));
+    }
+}
diff --git a/vendor/behat/behat/src/Behat/Testwork/Translator/ServiceContainer/TranslatorExtension.php b/vendor/behat/behat/src/Behat/Testwork/Translator/ServiceContainer/TranslatorExtension.php
new file mode 100644 (file)
index 0000000..39de237
--- /dev/null
@@ -0,0 +1,155 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\Translator\ServiceContainer;
+
+use Behat\Testwork\Cli\ServiceContainer\CliExtension;
+use Behat\Testwork\ServiceContainer\Extension;
+use Behat\Testwork\ServiceContainer\ExtensionManager;
+use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Definition;
+use Symfony\Component\DependencyInjection\Reference;
+
+/**
+ * Provides translator service.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class TranslatorExtension implements Extension
+{
+    /*
+     * Available services
+     */
+    const TRANSLATOR_ID = 'translator';
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getConfigKey()
+    {
+        return 'translation';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function initialize(ExtensionManager $extensionManager)
+    {
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function configure(ArrayNodeDefinition $builder)
+    {
+        $defaultLanguage = $this->getDefaultLanguage() ?: 'en';
+
+        $builder
+            ->addDefaultsIfNotSet()
+            ->children()
+                ->scalarNode('locale')
+                    ->info('Sets output locale for the tester')
+                    ->defaultValue($defaultLanguage)
+                ->end()
+                ->scalarNode('fallback_locale')
+                    ->info('Sets fallback output locale for the tester')
+                    ->defaultValue('en')
+                ->end()
+            ->end();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function load(ContainerBuilder $container, array $config)
+    {
+        $this->loadTranslator($container, $config['locale'], $config['fallback_locale']);
+        $this->loadController($container);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function process(ContainerBuilder $container)
+    {
+    }
+
+    /**
+     * Loads translator service.
+     *
+     * @param ContainerBuilder $container
+     * @param string           $locale
+     * @param string           $fallbackLocale
+     */
+    private function loadTranslator(ContainerBuilder $container, $locale, $fallbackLocale)
+    {
+        $definition = new Definition('Symfony\Component\Translation\Translator', array($locale));
+        $container->setDefinition(self::TRANSLATOR_ID, $definition);
+
+        $definition->addMethodCall('setFallbackLocales', array(array($fallbackLocale)));
+        $definition->addMethodCall(
+            'addLoader', array(
+                'xliff',
+                new Definition('Symfony\Component\Translation\Loader\XliffFileLoader')
+            )
+        );
+        $definition->addMethodCall(
+            'addLoader', array(
+                'yaml',
+                new Definition('Symfony\Component\Translation\Loader\YamlFileLoader')
+            )
+        );
+        $definition->addMethodCall(
+            'addLoader', array(
+                'php',
+                new Definition('Symfony\Component\Translation\Loader\PhpFileLoader')
+            )
+        );
+        $definition->addMethodCall(
+            'addLoader', array(
+                'array',
+                new Definition('Symfony\Component\Translation\Loader\ArrayLoader')
+            )
+        );
+        $container->setDefinition(self::TRANSLATOR_ID, $definition);
+    }
+
+    /**
+     * Loads translator controller.
+     *
+     * @param ContainerBuilder $container
+     */
+    private function loadController(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\Testwork\Translator\Cli\LanguageController', array(
+            new Reference(self::TRANSLATOR_ID)
+        ));
+        $definition->addTag(CliExtension::CONTROLLER_TAG, array('priority' => 800));
+        $container->setDefinition(CliExtension::CONTROLLER_TAG . '.translator', $definition);
+    }
+
+    /**
+     * Tries to guess default user cli language.
+     *
+     * @return null|string
+     */
+    private function getDefaultLanguage()
+    {
+        $defaultLanguage = null;
+        if (($locale = getenv('LANG')) && preg_match('/^([a-z]{2})/', $locale, $matches)) {
+            $defaultLanguage = $matches[1];
+
+            return $defaultLanguage;
+        }
+
+        return $defaultLanguage;
+    }
+}
diff --git a/vendor/behat/gherkin/.gitignore b/vendor/behat/gherkin/.gitignore
new file mode 100644 (file)
index 0000000..33b7c65
--- /dev/null
@@ -0,0 +1,4 @@
+*.tgz
+vendor
+composer.phar
+composer.lock
diff --git a/vendor/behat/gherkin/.travis.yml b/vendor/behat/gherkin/.travis.yml
new file mode 100644 (file)
index 0000000..a348812
--- /dev/null
@@ -0,0 +1,33 @@
+language: php
+
+sudo: false
+
+cache:
+  directories:
+    - $HOME/.composer/cache/files
+
+php: [5.3, 5.6, 7.0, 7.1]
+
+matrix:
+  include:
+    - php: 5.6
+      env: SYMFONY_VERSION='2.3.*'
+    - php: 5.6
+      env: SYMFONY_VERSION='2.7.*'
+    - php: 5.6
+      env: SYMFONY_VERSION='2.8.*'
+    - php: 7.1
+      env: SYMFONY_VERSION='3.*'
+
+before_install:
+  - composer self-update
+  - if [ "$SYMFONY_VERSION" != "" ]; then composer require --no-update symfony/yaml=$SYMFONY_VERSION; fi;
+
+install:
+  - composer install
+
+script: vendor/bin/phpunit -v --coverage-clover=coverage.clover
+
+after_script:
+  # don't upload coverage on PHP 7 and HHVM as it cannot be generated. We don't want to tell Scrutinizer that the coverage generation failed.
+  - if [[ "7.0" != "$TRAVIS_PHP_VERSION" && "$TRAVIS_PHP_VERSION" != "hhvm" ]]; then wget https://scrutinizer-ci.com/ocular.phar && php ocular.phar code-coverage:upload --format=php-clover coverage.clover; fi
diff --git a/vendor/behat/gherkin/CHANGES.md b/vendor/behat/gherkin/CHANGES.md
new file mode 100644 (file)
index 0000000..ddbfbc1
--- /dev/null
@@ -0,0 +1,383 @@
+4.5.1 / 2017-08-30
+==================
+
+  * Fix regression in `PathsFilter`
+
+4.5.0 / 2017-08-30
+==================
+
+  * Sync i18n with Cucumber Gherkin
+  * Drop support for HHVM tests on Travis
+  * Add `TableNode::fromList()` method (thanks @TravisCarden)
+  * Add `ExampleNode::getOutlineTitle()` method (thanks @duxet)
+  * Use realpath, so the feature receives the cwd prefixed (thanks @glennunipro)
+  * Explicitly handle non-two-dimensional arrays in TableNode (thanks @TravisCarden)
+  * Fix to line/linefilter scenario runs which take relative paths to files (thanks @generalconsensus)
+
+4.4.5 / 2016-10-30
+==================
+
+  * Fix partial paths matching in `PathsFilter`
+
+4.4.4 / 2016-09-18
+==================
+
+  * Provide clearer exception for non-writeable cache directories
+
+4.4.3 / 2016-09-18
+==================
+
+  * Ensure we reset tags between features
+
+4.4.2 / 2016-09-03
+==================
+
+  * Sync 18n with gherkin 3
+
+4.4.1 / 2015-12-30
+==================
+
+  * Ensure keywords are trimmed when syncing translations
+  * Sync 18n with cucumber
+
+4.4.0 / 2015-09-19
+==================
+
+  * Added validation enforcing that all rows of a `TableNode` have the same number of columns
+  * Added `TableNode::getColumn` to get a column from the table
+  * Sync 18n with cucumber
+
+4.3.0 / 2014-06-06
+==================
+
+  * Added `setFilters(array)` method to `Gherkin` class
+  * Added `NarrativeFilter` for non-english `RoleFilter` lovers
+
+4.2.1 / 2014-06-06
+==================
+
+  * Fix parsing of features without line feed at the end
+
+4.2.0 / 2014-05-27
+==================
+
+  * Added `getKeyword()` and `getKeywordType()` methods to `StepNode`, deprecated `getType()`.
+    Thanks to @kibao
+
+4.1.3 / 2014-05-25
+==================
+
+  * Properly handle tables with rows terminating in whitespace
+
+4.1.2 / 2014-05-14
+==================
+
+  * Handle case where Gherkin cache is broken
+
+4.1.1 / 2014-05-05
+==================
+
+  * Fixed the compatibility with PHP 5.6-beta by avoiding to use the broken PHP array function
+  * The YamlFileLoader no longer extend from ArrayLoader but from AbstractFileLoader
+
+4.1.0 / 2014-04-20
+==================
+
+  * Fixed scenario tag filtering
+  * Do not allow multiple multiline step arguments
+  * Sync 18n with cucumber
+
+4.0.0 / 2014-01-05
+==================
+
+  * Changed the behavior when no loader can be found for the resource. Instead of throwing an exception, the
+    Gherkin class now returns an empty array.
+
+3.1.3 / 2014-01-04
+==================
+
+  * Dropped the dependency on the Symfony Finder by using SPL iterators directly
+  * Added testing on HHVM on Travis. HHVM is officially supported (previous release was actually already compatible)
+
+3.1.2 / 2014-01-01
+==================
+
+  * All paths passed to PathsFilter are converted using realpath
+
+3.1.1 / 2013-12-31
+==================
+
+  * Add `ComplexFilterInterace` that has complex behavior for scenarios and requires to pass
+    feature too
+  * `TagFilter` is an instance of a `ComplexFilterInterace` now
+
+3.1.0 / 2013-12-31
+==================
+
+  * Example node is a scenario
+  * Nodes do not have uprefs (memory usage fix)
+  * Scenario filters do not depend on feature nodes
+
+3.0.5 / 2014-01-01
+==================
+
+  * All paths passed to PathsFilter are converted using realpath
+
+3.0.4 / 2013-12-31
+==================
+
+  * TableNode is now traversable using foreach
+  * All possibly thrown exceptions implement Gherkin\Exception interface
+  * Sync i18n with cucumber
+
+3.0.3 / 2013-09-15
+==================
+
+  * Extend ExampleNode with additional methods
+
+3.0.2 / 2013-09-14
+==================
+
+  * Extract `KeywordNodeInterface` and `ScenarioLikeInterface`
+  * Add `getIndex()` methods to scenarios, outlines, steps and examples
+  * Throw proper exception for fractured node tree
+
+3.0.1 / 2013-09-14
+==================
+
+  * Use versioned subfolder in FileCache
+
+3.0.0 / 2013-09-14
+==================
+
+  * A lot of optimizations in Parser and Lexer
+  * Node tree is now immutable by nature (no setters)
+  * Example nodes are now part of the node tree. They are lazily generated by Outline node
+  * Sync with latest cucumber i18n
+
+2.3.4 / 2013-08-11
+==================
+
+  * Fix leaks in memory cache
+
+2.3.3 / 2013-08-11
+==================
+
+  * Fix encoding bug introduced with previous release
+  * Sync i18n with cucumber
+
+2.3.2 / 2013-08-11
+==================
+
+  * Explicitly use utf8 encoding
+
+2.3.1 / 2013-08-10
+==================
+
+  * Support `an` prefix with RoleFilter
+
+2.3.0 / 2013-08-04
+==================
+
+  * Add RoleFilter
+  * Add PathsFilter
+  * Add MemoryCache
+
+2.2.9 / 2013-03-02
+==================
+
+  * Fix dependency version requirement
+
+2.2.8 / 2013-03-02
+==================
+
+  * Features filtering behavior change. Now emptified (by filtering) features
+    that do not match filter themselves are removed from resultset.
+  * Small potential bug fix in TableNode
+
+2.2.7 / 2013-01-27
+==================
+
+  * Fixed bug in i18n syncing script
+  * Resynced Gherkin i18n
+
+2.2.6 / 2013-01-26
+==================
+
+  * Support long row hashes in tables ([see](https://github.com/Behat/Gherkin/issues/40))
+  * Synced Gherkin i18n
+
+2.2.5 / 2012-09-26
+==================
+
+  * Fixed issue with loading empty features
+  * Synced Gherkin i18n
+
+2.2.4 / 2012-08-03
+==================
+
+  * Fixed exception message for "no loader found"
+
+2.2.3 / 2012-08-03
+==================
+
+  * Fixed minor loader bug with empty base path
+  * Synced Gherkin i18n
+
+2.2.2 / 2012-07-01
+==================
+
+  * Added ability to filter outline scenarios by line and range filters
+  * Synced Gherkin i18n
+  * Refactored table parser to read row line numbers too
+
+2.2.1 / 2012-05-04
+==================
+
+  * Fixed StepNode `getLanguage()` and `getFile()`
+
+2.2.0 / 2012-05-03
+==================
+
+  * Features freeze after parsing
+  * Implemented GherkinDumper (@Halleck45)
+  * Synced i18n with Cucumber
+  * Updated inline documentation
+
+2.1.1 / 2012-03-09
+==================
+
+  * Fixed caching bug, where `isFresh()` always returned false
+
+2.1.0 / 2012-03-09
+==================
+
+  * Added parser caching layer
+  * Added support for table delimiter escaping (use `\|` for that)
+  * Added LineRangeFilter (thanks @headrevision)
+  * Synced i18n dictionary with cucumber/gherkin
+
+2.0.2 / 2012-02-04
+==================
+
+  * Synced i18n dictionary with cucumber/gherkin
+
+2.0.1 / 2012-01-26
+==================
+
+  * Fixed issue about parsing features without indentation
+
+2.0.0 / 2012-01-19
+==================
+
+  * Background titles support
+  * Correct parsing of titles/descriptions (hirarchy lexing)
+  * Migration to the cucumber/gherkin i18n dictionary
+  * Speed optimizations
+  * Refactored KeywordsDumper
+  * New loaders
+  * Bugfixes
+
+1.1.4 / 2012-01-08
+==================
+
+  * Read feature description even if it looks like a step
+
+1.1.3 / 2011-12-14
+==================
+
+  * Removed file loading routines from Parser (fixes `is_file()` issue on some systems - thanks
+    @flodocteurklein)
+
+1.1.2 / 2011-12-01
+==================
+
+  * Updated spanish trasnaltion (@anbotero)
+  * Integration with Composer and Travis CI
+
+1.1.1 / 2011-07-29
+==================
+
+  * Updated pt language step types (@danielcsgomes)
+  * Updated vendors
+
+1.1.0 / 2011-07-16
+==================
+
+  * Return all tags, including inherited in `Scenario::getTags()`
+  * New `Feature::getOwnTags()` and `Scenario::getOwnTags()` method added,
+    which returns only own tags
+
+1.0.8 / 2011-06-29
+==================
+
+  * Fixed comments parsing.
+    You can’t have comments at the end of a line # like this
+    # But you can still have comments at the beginning of a line
+
+1.0.7 / 2011-06-28
+==================
+
+  * Added `getRaw()` method to PyStringNode
+  * Updated vendors
+
+1.0.6 / 2011-06-17
+==================
+
+  * Updated vendors
+
+1.0.5 / 2011-06-10
+==================
+
+  * Fixed bug, introduced with 1.0.4 - hash in PyStrings
+
+1.0.4 / 2011-06-10
+==================
+
+  * Fixed inability to comment pystrings
+
+1.0.3 / 2011-04-21
+==================
+
+  * Fixed introduced with 1.0.2 pystring parsing bug
+
+1.0.2 / 2011-04-18
+==================
+
+  * Fixed bugs in text with comments parsing
+
+1.0.1 / 2011-04-01
+==================
+
+  * Updated vendors
+
+1.0.0 / 2011-03-08
+==================
+
+  * Updated vendors
+
+1.0.0RC2 / 2011-02-25
+=====================
+
+  * Windows support
+  * Missing phpunit config
+
+1.0.0RC1 / 2011-02-15
+=====================
+
+  * Huge optimizations to Lexer & Parser
+  * Additional loaders (Yaml, Array, Directory)
+  * Filters (Tag, Name, Line)
+  * Code refactoring
+  * Nodes optimizations
+  * Additional tests for exceptions and translations
+  * Keywords dumper
+
+0.2.0 / 2011-01-05
+==================
+
+  * New Parser & Lexer (based on AST)
+  * New verbose parsing exception handling
+  * New translation mechanics
+  * 47 brand new translations (see i18n)
+  * Full test suite for everything from AST nodes to translations
diff --git a/vendor/behat/gherkin/CONTRIBUTING.md b/vendor/behat/gherkin/CONTRIBUTING.md
new file mode 100644 (file)
index 0000000..6869f76
--- /dev/null
@@ -0,0 +1,33 @@
+Contributing
+------------
+
+Gherkin is an open source, community-driven project. If you'd like to contribute, feel free to do this, but remember to follow this few simple rules:
+
+- Make your feature addition or bug fix,
+- Always use the `master` branch as base for your changes (all new development happens in `master`),
+- Add tests for those changes (please look into `tests/` 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`,
+- __Remember__: when you create Pull Request, always select `master` branch as target (done by default), otherwise it will be closed.
+
+Running tests
+-------------
+
+Make sure that you don't break anything with your changes by running:
+
+```bash
+$> phpunit
+```
+
+Contributing to Gherkin Translations
+------------------------------------
+
+Gherkin supports &rarr;40 different languages and you could add more! You might notice
+`i18n.php` file in the root of the library. This file is downloaded and **autogenerated**
+from original [cucumber/gherkin translations](https://github.com/cucumber/cucumber/blob/master/gherkin/gherkin-languages.json).
+So, in order to fix/update/add some translation, you should send Pull Request to the
+`cucumber/gherkin` repository. `Behat\Gherkin` will redownload/regenerate translations
+from there before each release.
+
+It might sounds difficult, but this way of dictionary sharing gives you ability to
+migrate your `*.feature` files from language to language and library to library without
+the need to rewrite/modify them - same dictionary (Gherkin) used everywhere.
diff --git a/vendor/behat/gherkin/LICENSE b/vendor/behat/gherkin/LICENSE
new file mode 100644 (file)
index 0000000..14f15e8
--- /dev/null
@@ -0,0 +1,22 @@
+Copyright (c) 2011-2013 Konstantin Kudryashov <ever.zet@gmail.com>
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
diff --git a/vendor/behat/gherkin/README.md b/vendor/behat/gherkin/README.md
new file mode 100644 (file)
index 0000000..e7034df
--- /dev/null
@@ -0,0 +1,68 @@
+Behat Gherkin Parser
+====================
+
+This is the php Gherkin parser for Behat. It comes bundled with more than 40 native languages
+(see `i18n.php`) support & clean architecture.
+
+[![Build Status](https://travis-ci.org/Behat/Gherkin.svg?branch=master)](https://travis-ci.org/Behat/Gherkin)
+[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/Behat/Gherkin/badges/quality-score.png?s=04d9d0237c89f4c45a94ba5304234db861dfd036)](https://scrutinizer-ci.com/g/Behat/Gherkin/)
+[![Code Coverage](https://scrutinizer-ci.com/g/Behat/Gherkin/badges/coverage.png?s=204ca44800469d295b73d18c91011cb9d2dc99fc)](https://scrutinizer-ci.com/g/Behat/Gherkin/)
+
+Useful Links
+------------
+
+- Official Google Group is at [http://groups.google.com/group/behat](http://groups.google.com/group/behat)
+- IRC channel on [#freenode](http://freenode.net/) is `#behat`
+- [Note on Patches/Pull Requests](CONTRIBUTING.md)
+
+Usage Example
+-------------
+
+``` php
+<?php
+
+$keywords = new Behat\Gherkin\Keywords\ArrayKeywords(array(
+    'en' => array(
+        'feature'          => 'Feature',
+        'background'       => 'Background',
+        'scenario'         => 'Scenario',
+        'scenario_outline' => 'Scenario Outline|Scenario Template',
+        'examples'         => 'Examples|Scenarios',
+        'given'            => 'Given',
+        'when'             => 'When',
+        'then'             => 'Then',
+        'and'              => 'And',
+        'but'              => 'But'
+    ),
+    'en-pirate' => array(
+        'feature'          => 'Ahoy matey!',
+        'background'       => 'Yo-ho-ho',
+        'scenario'         => 'Heave to',
+        'scenario_outline' => 'Shiver me timbers',
+        'examples'         => 'Dead men tell no tales',
+        'given'            => 'Gangway!',
+        'when'             => 'Blimey!',
+        'then'             => 'Let go and haul',
+        'and'              => 'Aye',
+        'but'              => 'Avast!'
+    )
+));
+$lexer  = new Behat\Gherkin\Lexer($keywords);
+$parser = new Behat\Gherkin\Parser($lexer);
+
+$feature = $parser->parse(file_get_contents('some.feature'));
+```
+
+Installing Dependencies
+-----------------------
+
+``` bash
+$> curl http://getcomposer.org/installer | php
+$> php composer.phar update
+```
+
+Contributors
+------------
+
+* Konstantin Kudryashov [everzet](http://github.com/everzet) [lead developer]
+* Other [awesome developers](https://github.com/Behat/Gherkin/graphs/contributors)
diff --git a/vendor/behat/gherkin/bin/update_i18n b/vendor/behat/gherkin/bin/update_i18n
new file mode 100755 (executable)
index 0000000..3791956
--- /dev/null
@@ -0,0 +1,70 @@
+#!/usr/bin/env php
+<?php
+
+$gherkinUrl = 'https://raw.githubusercontent.com/cucumber/cucumber/master/gherkin/gherkin-languages.json';
+$json  = file_get_contents($gherkinUrl);
+$array = array();
+
+foreach (json_decode($json, true) as $lang => $keywords) {
+    $langMessages = array();
+
+    foreach ($keywords as $type => $words) {
+        if (!is_array($words)) {
+            $words = array($words);
+        }
+
+        if ('scenarioOutline' === $type) {
+            $type = 'scenario_outline';
+        }
+
+        if (in_array($type, array('given', 'when', 'then', 'and', 'but'))) {
+            $formattedKeywords = array();
+
+            foreach ($words as $word) {
+                $formattedWord = trim($word);
+
+                if ($formattedWord === $word) {
+                    $formattedWord = $formattedWord.'<'; // Convert the keywords to the syntax used by Gherkin 2, which is expected by our Lexer.
+                }
+
+                $formattedKeywords[] = $formattedWord;
+            }
+
+            $words = $formattedKeywords;
+        }
+
+        usort($words, function($type1, $type2) {
+            return mb_strlen($type2, 'utf8') - mb_strlen($type1, 'utf8');
+        });
+
+        $langMessages[$type] = implode('|', $words);
+    }
+
+    // ensure that the order of keys is consistent between updates
+    ksort($langMessages);
+
+    $array[$lang] = $langMessages;
+}
+
+// ensure that the languages are sorted to avoid useless diffs between updates. We keep the English first though as it is the reference.
+$enData = $array['en'];
+unset($array['en']);
+ksort($array);
+$array = array_merge(array('en' => $enData), $array);
+$arrayString = var_export($array, true);
+
+file_put_contents(__DIR__.'/../i18n.php', <<<EOD
+<?php
+
+/*
+ * DO NOT TOUCH THIS FILE!
+ *
+ * This file is automatically generated by `bin/update_i18n`.
+ * Actual Gherkin translations live in cucumber/gherkin repo:
+ * {$gherkinUrl}
+ * Please send your translation changes there.
+ */
+
+return $arrayString;
+EOD
+);
diff --git a/vendor/behat/gherkin/composer.json b/vendor/behat/gherkin/composer.json
new file mode 100644 (file)
index 0000000..d627882
--- /dev/null
@@ -0,0 +1,47 @@
+{
+    "name":         "behat/gherkin",
+    "description":  "Gherkin DSL parser for PHP 5.3",
+    "keywords":     ["BDD", "parser", "DSL", "Behat", "Gherkin", "Cucumber"],
+    "homepage":     "http://behat.org/",
+    "type":         "library",
+    "license":      "MIT",
+    "authors":      [
+        {
+            "name":      "Konstantin Kudryashov",
+            "email":     "ever.zet@gmail.com",
+            "homepage":  "http://everzet.com"
+        }
+    ],
+
+    "require": {
+        "php": ">=5.3.1"
+    },
+
+    "require-dev": {
+        "symfony/yaml": "~2.3|~3",
+        "symfony/phpunit-bridge": "~2.7|~3",
+        "phpunit/phpunit": "~4.5|~5"
+    },
+
+    "suggest": {
+        "symfony/yaml":   "If you want to parse features, represented in YAML files"
+    },
+
+    "autoload": {
+        "psr-0": {
+            "Behat\\Gherkin":   "src/"
+        }
+    },
+
+    "autoload-dev": {
+        "psr-4": {
+            "Tests\\Behat\\": "tests/Behat/"
+        }
+    },
+
+    "extra": {
+        "branch-alias": {
+            "dev-master": "4.4-dev"
+        }
+    }
+}
diff --git a/vendor/behat/gherkin/i18n.php b/vendor/behat/gherkin/i18n.php
new file mode 100644 (file)
index 0000000..f8e3740
--- /dev/null
@@ -0,0 +1,1108 @@
+<?php
+
+/*
+ * DO NOT TOUCH THIS FILE!
+ *
+ * This file is automatically generated by `bin/update_i18n`.
+ * Actual Gherkin translations live in cucumber/gherkin repo:
+ * https://raw.githubusercontent.com/cucumber/cucumber/master/gherkin/gherkin-languages.json
+ * Please send your translation changes there.
+ */
+
+return array (
+  'en' => 
+  array (
+    'and' => 'And|*',
+    'background' => 'Background',
+    'but' => 'But|*',
+    'examples' => 'Scenarios|Examples',
+    'feature' => 'Business Need|Feature|Ability',
+    'given' => 'Given|*',
+    'name' => 'English',
+    'native' => 'English',
+    'scenario' => 'Scenario',
+    'scenario_outline' => 'Scenario Template|Scenario Outline',
+    'then' => 'Then|*',
+    'when' => 'When|*',
+  ),
+  'af' => 
+  array (
+    'and' => 'En|*',
+    'background' => 'Agtergrond',
+    'but' => 'Maar|*',
+    'examples' => 'Voorbeelde',
+    'feature' => 'Besigheid Behoefte|Funksie|Vermoë',
+    'given' => 'Gegewe|*',
+    'name' => 'Afrikaans',
+    'native' => 'Afrikaans',
+    'scenario' => 'Situasie',
+    'scenario_outline' => 'Situasie Uiteensetting',
+    'then' => 'Dan|*',
+    'when' => 'Wanneer|*',
+  ),
+  'am' => 
+  array (
+    'and' => 'Եվ|*',
+    'background' => 'Կոնտեքստ',
+    'but' => 'Բայց|*',
+    'examples' => 'Օրինակներ',
+    'feature' => 'Ֆունկցիոնալություն|Հատկություն',
+    'given' => 'Դիցուք|*',
+    'name' => 'Armenian',
+    'native' => 'հայերեն',
+    'scenario' => 'Սցենար',
+    'scenario_outline' => 'Սցենարի կառուցվացքը',
+    'then' => 'Ապա|*',
+    'when' => 'Երբ|Եթե|*',
+  ),
+  'ar' => 
+  array (
+    'and' => '*|و',
+    'background' => 'الخلفية',
+    'but' => 'لكن|*',
+    'examples' => 'امثلة',
+    'feature' => 'خاصية',
+    'given' => 'بفرض|*',
+    'name' => 'Arabic',
+    'native' => 'العربية',
+    'scenario' => 'سيناريو',
+    'scenario_outline' => 'سيناريو مخطط',
+    'then' => 'اذاً|ثم|*',
+    'when' => 'عندما|متى|*',
+  ),
+  'ast' => 
+  array (
+    'and' => 'Ya|*|Y',
+    'background' => 'Antecedentes',
+    'but' => 'Peru|*',
+    'examples' => 'Exemplos',
+    'feature' => 'Carauterística',
+    'given' => 'Dada|Daos|Daes|Dáu|*',
+    'name' => 'Asturian',
+    'native' => 'asturianu',
+    'scenario' => 'Casu',
+    'scenario_outline' => 'Esbozu del casu',
+    'then' => 'Entós|*',
+    'when' => 'Cuando|*',
+  ),
+  'az' => 
+  array (
+    'and' => 'Həm|Və|*',
+    'background' => 'Kontekst|Keçmiş',
+    'but' => 'Ancaq|Amma|*',
+    'examples' => 'Nümunələr',
+    'feature' => 'Özəllik',
+    'given' => 'Tutaq ki|Verilir|*',
+    'name' => 'Azerbaijani',
+    'native' => 'Azərbaycanca',
+    'scenario' => 'Ssenari',
+    'scenario_outline' => 'Ssenarinin strukturu',
+    'then' => 'O halda|*',
+    'when' => 'Nə vaxt ki|Əgər|*',
+  ),
+  'bg' => 
+  array (
+    'and' => '*|И',
+    'background' => 'Предистория',
+    'but' => 'Но|*',
+    'examples' => 'Примери',
+    'feature' => 'Функционалност',
+    'given' => 'Дадено|*',
+    'name' => 'Bulgarian',
+    'native' => 'български',
+    'scenario' => 'Сценарий',
+    'scenario_outline' => 'Рамка на сценарий',
+    'then' => 'То|*',
+    'when' => 'Когато|*',
+  ),
+  'bm' => 
+  array (
+    'and' => 'Dan|*',
+    'background' => 'Latar Belakang',
+    'but' => 'Tetapi|Tapi|*',
+    'examples' => 'Contoh',
+    'feature' => 'Fungsi',
+    'given' => 'Diberi|Bagi|*',
+    'name' => 'Malay',
+    'native' => 'Bahasa Melayu',
+    'scenario' => 'Senario|Situasi|Keadaan',
+    'scenario_outline' => 'Garis Panduan Senario|Kerangka Senario|Kerangka Situasi|Kerangka Keadaan',
+    'then' => 'Kemudian|Maka|*',
+    'when' => 'Apabila|*',
+  ),
+  'bs' => 
+  array (
+    'and' => '*|I|A',
+    'background' => 'Pozadina',
+    'but' => 'Ali|*',
+    'examples' => 'Primjeri',
+    'feature' => 'Karakteristika',
+    'given' => 'Dato|*',
+    'name' => 'Bosnian',
+    'native' => 'Bosanski',
+    'scenario' => 'Scenariju|Scenario',
+    'scenario_outline' => 'Scenario-outline|Scenariju-obris',
+    'then' => 'Zatim|*',
+    'when' => 'Kada|*',
+  ),
+  'ca' => 
+  array (
+    'and' => '*|I',
+    'background' => 'Antecedents|Rerefons',
+    'but' => 'Però|*',
+    'examples' => 'Exemples',
+    'feature' => 'Característica|Funcionalitat',
+    'given' => 'Donada|Donat|Atesa|Atès|*',
+    'name' => 'Catalan',
+    'native' => 'català',
+    'scenario' => 'Escenari',
+    'scenario_outline' => 'Esquema de l\'escenari',
+    'then' => 'Aleshores|Cal|*',
+    'when' => 'Quan|*',
+  ),
+  'cs' => 
+  array (
+    'and' => 'A také|*|A',
+    'background' => 'Kontext|Pozadí',
+    'but' => 'Ale|*',
+    'examples' => 'Příklady',
+    'feature' => 'Požadavek',
+    'given' => 'Za předpokladu|Pokud|*',
+    'name' => 'Czech',
+    'native' => 'Česky',
+    'scenario' => 'Scénář',
+    'scenario_outline' => 'Osnova scénáře|Náčrt Scénáře',
+    'then' => 'Pak|*',
+    'when' => 'Když|*',
+  ),
+  'cy-GB' => 
+  array (
+    'and' => '*|A',
+    'background' => 'Cefndir',
+    'but' => 'Ond|*',
+    'examples' => 'Enghreifftiau',
+    'feature' => 'Arwedd',
+    'given' => 'Anrhegedig a|*',
+    'name' => 'Welsh',
+    'native' => 'Cymraeg',
+    'scenario' => 'Scenario',
+    'scenario_outline' => 'Scenario Amlinellol',
+    'then' => 'Yna|*',
+    'when' => 'Pryd|*',
+  ),
+  'da' => 
+  array (
+    'and' => 'Og|*',
+    'background' => 'Baggrund',
+    'but' => 'Men|*',
+    'examples' => 'Eksempler',
+    'feature' => 'Egenskab',
+    'given' => 'Givet|*',
+    'name' => 'Danish',
+    'native' => 'dansk',
+    'scenario' => 'Scenarie',
+    'scenario_outline' => 'Abstrakt Scenario',
+    'then' => 'Så|*',
+    'when' => 'Når|*',
+  ),
+  'de' => 
+  array (
+    'and' => 'Und|*',
+    'background' => 'Grundlage',
+    'but' => 'Aber|*',
+    'examples' => 'Beispiele',
+    'feature' => 'Funktionalität',
+    'given' => 'Gegeben seien|Gegeben sei|Angenommen|*',
+    'name' => 'German',
+    'native' => 'Deutsch',
+    'scenario' => 'Szenario',
+    'scenario_outline' => 'Szenariogrundriss',
+    'then' => 'Dann|*',
+    'when' => 'Wenn|*',
+  ),
+  'el' => 
+  array (
+    'and' => 'Και|*',
+    'background' => 'Υπόβαθρο',
+    'but' => 'Αλλά|*',
+    'examples' => 'Παραδείγματα|Σενάρια',
+    'feature' => 'Δυνατότητα|Λειτουργία',
+    'given' => 'Δεδομένου|*',
+    'name' => 'Greek',
+    'native' => 'Ελληνικά',
+    'scenario' => 'Σενάριο',
+    'scenario_outline' => 'Περιγραφή Σεναρίου',
+    'then' => 'Τότε|*',
+    'when' => 'Όταν|*',
+  ),
+  'em' => 
+  array (
+    'and' => '😂<|*',
+    'background' => '💤',
+    'but' => '😔<|*',
+    'examples' => '📓',
+    'feature' => '📚',
+    'given' => '😐<|*',
+    'name' => 'Emoji',
+    'native' => '😀',
+    'scenario' => '📕',
+    'scenario_outline' => '📖',
+    'then' => '🙏<|*',
+    'when' => '🎬<|*',
+  ),
+  'en-Scouse' => 
+  array (
+    'and' => 'An|*',
+    'background' => 'Dis is what went down',
+    'but' => 'Buh|*',
+    'examples' => 'Examples',
+    'feature' => 'Feature',
+    'given' => 'Youse know when youse got|Givun|*',
+    'name' => 'Scouse',
+    'native' => 'Scouse',
+    'scenario' => 'The thing of it is',
+    'scenario_outline' => 'Wharrimean is',
+    'then' => 'Den youse gotta|Dun|*',
+    'when' => 'Youse know like when|Wun|*',
+  ),
+  'en-au' => 
+  array (
+    'and' => 'Too right|*',
+    'background' => 'First off',
+    'but' => 'Yeah nah|*',
+    'examples' => 'You\'ll wanna',
+    'feature' => 'Pretty much',
+    'given' => 'Y\'know|*',
+    'name' => 'Australian',
+    'native' => 'Australian',
+    'scenario' => 'Awww, look mate',
+    'scenario_outline' => 'Reckon it\'s like',
+    'then' => 'But at the end of the day I reckon|*',
+    'when' => 'It\'s just unbelievable|*',
+  ),
+  'en-lol' => 
+  array (
+    'and' => 'AN|*',
+    'background' => 'B4',
+    'but' => 'BUT|*',
+    'examples' => 'EXAMPLZ',
+    'feature' => 'OH HAI',
+    'given' => 'I CAN HAZ|*',
+    'name' => 'LOLCAT',
+    'native' => 'LOLCAT',
+    'scenario' => 'MISHUN',
+    'scenario_outline' => 'MISHUN SRSLY',
+    'then' => 'DEN|*',
+    'when' => 'WEN|*',
+  ),
+  'en-old' => 
+  array (
+    'and' => 'Ond|*|7',
+    'background' => 'Aer|Ær',
+    'but' => 'Ac|*',
+    'examples' => 'Se the|Se þe|Se ðe',
+    'feature' => 'Hwaet|Hwæt',
+    'given' => 'Thurh|Þurh|Ðurh|*',
+    'name' => 'Old English',
+    'native' => 'Englisc',
+    'scenario' => 'Swa',
+    'scenario_outline' => 'Swa hwaer swa|Swa hwær swa',
+    'then' => 'Tha the|Þa þe|Ða ðe|Tha|Þa|Ða|*',
+    'when' => 'Tha|Þa|Ða|*',
+  ),
+  'en-pirate' => 
+  array (
+    'and' => 'Aye|*',
+    'background' => 'Yo-ho-ho',
+    'but' => 'Avast!|*',
+    'examples' => 'Dead men tell no tales',
+    'feature' => 'Ahoy matey!',
+    'given' => 'Gangway!|*',
+    'name' => 'Pirate',
+    'native' => 'Pirate',
+    'scenario' => 'Heave to',
+    'scenario_outline' => 'Shiver me timbers',
+    'then' => 'Let go and haul|*',
+    'when' => 'Blimey!|*',
+  ),
+  'eo' => 
+  array (
+    'and' => 'Kaj|*',
+    'background' => 'Fono',
+    'but' => 'Sed|*',
+    'examples' => 'Ekzemploj',
+    'feature' => 'Trajto',
+    'given' => 'Donitaĵo|Komence|*',
+    'name' => 'Esperanto',
+    'native' => 'Esperanto',
+    'scenario' => 'Scenaro|Kazo',
+    'scenario_outline' => 'Konturo de la scenaro|Kazo-skizo|Skizo',
+    'then' => 'Do|*',
+    'when' => 'Se|*',
+  ),
+  'es' => 
+  array (
+    'and' => '*|Y|E',
+    'background' => 'Antecedentes',
+    'but' => 'Pero|*',
+    'examples' => 'Ejemplos',
+    'feature' => 'Característica',
+    'given' => 'Dados|Dadas|Dada|Dado|*',
+    'name' => 'Spanish',
+    'native' => 'español',
+    'scenario' => 'Escenario',
+    'scenario_outline' => 'Esquema del escenario',
+    'then' => 'Entonces|*',
+    'when' => 'Cuando|*',
+  ),
+  'et' => 
+  array (
+    'and' => 'Ja|*',
+    'background' => 'Taust',
+    'but' => 'Kuid|*',
+    'examples' => 'Juhtumid',
+    'feature' => 'Omadus',
+    'given' => 'Eeldades|*',
+    'name' => 'Estonian',
+    'native' => 'eesti keel',
+    'scenario' => 'Stsenaarium',
+    'scenario_outline' => 'Raamstsenaarium',
+    'then' => 'Siis|*',
+    'when' => 'Kui|*',
+  ),
+  'fa' => 
+  array (
+    'and' => '*|و',
+    'background' => 'زمینه',
+    'but' => 'اما|*',
+    'examples' => 'نمونه ها',
+    'feature' => 'وِیژگی',
+    'given' => 'با فرض|*',
+    'name' => 'Persian',
+    'native' => 'فارسی',
+    'scenario' => 'سناریو',
+    'scenario_outline' => 'الگوی سناریو',
+    'then' => 'آنگاه|*',
+    'when' => 'هنگامی|*',
+  ),
+  'fi' => 
+  array (
+    'and' => 'Ja|*',
+    'background' => 'Tausta',
+    'but' => 'Mutta|*',
+    'examples' => 'Tapaukset',
+    'feature' => 'Ominaisuus',
+    'given' => 'Oletetaan|*',
+    'name' => 'Finnish',
+    'native' => 'suomi',
+    'scenario' => 'Tapaus',
+    'scenario_outline' => 'Tapausaihio',
+    'then' => 'Niin|*',
+    'when' => 'Kun|*',
+  ),
+  'fr' => 
+  array (
+    'and' => 'Et qu\'<|Et que|Et|*',
+    'background' => 'Contexte',
+    'but' => 'Mais qu\'<|Mais que|Mais|*',
+    'examples' => 'Exemples',
+    'feature' => 'Fonctionnalité',
+    'given' => 'Etant donné qu\'<|Étant donné qu\'<|Etant donné que|Étant donné que|Etant données|Étant données|Etant donnée|Etant donnés|Étant donnée|Étant donnés|Etant donné|Étant donné|Soit|*',
+    'name' => 'French',
+    'native' => 'français',
+    'scenario' => 'Scénario',
+    'scenario_outline' => 'Plan du scénario|Plan du Scénario',
+    'then' => 'Alors|*',
+    'when' => 'Lorsqu\'<|Lorsque|Quand|*',
+  ),
+  'ga' => 
+  array (
+    'and' => 'Agus<|*',
+    'background' => 'Cúlra',
+    'but' => 'Ach<|*',
+    'examples' => 'Samplaí',
+    'feature' => 'Gné',
+    'given' => 'Cuir i gcás nach<|Cuir i gcás gur<|Cuir i gcás nár<|Cuir i gcás go<|*',
+    'name' => 'Irish',
+    'native' => 'Gaeilge',
+    'scenario' => 'Cás',
+    'scenario_outline' => 'Cás Achomair',
+    'then' => 'Ansin<|*',
+    'when' => 'Nuair nach<|Nuair nár<|Nuair ba<|Nuair a<|*',
+  ),
+  'gj' => 
+  array (
+    'and' => 'અને|*',
+    'background' => 'બેકગ્રાઉન્ડ',
+    'but' => 'પણ|*',
+    'examples' => 'ઉદાહરણો',
+    'feature' => 'વ્યાપાર જરૂર|ક્ષમતા|લક્ષણ',
+    'given' => 'આપેલ છે|*',
+    'name' => 'Gujarati',
+    'native' => 'ગુજરાતી',
+    'scenario' => 'સ્થિતિ',
+    'scenario_outline' => 'પરિદ્દશ્ય રૂપરેખા|પરિદ્દશ્ય ઢાંચો',
+    'then' => 'પછી|*',
+    'when' => 'ક્યારે|*',
+  ),
+  'gl' => 
+  array (
+    'and' => '*|E',
+    'background' => 'Contexto',
+    'but' => 'Pero|Mais|*',
+    'examples' => 'Exemplos',
+    'feature' => 'Característica',
+    'given' => 'Dados|Dadas|Dada|Dado|*',
+    'name' => 'Galician',
+    'native' => 'galego',
+    'scenario' => 'Escenario',
+    'scenario_outline' => 'Esbozo do escenario',
+    'then' => 'Entón|Logo|*',
+    'when' => 'Cando|*',
+  ),
+  'he' => 
+  array (
+    'and' => 'וגם|*',
+    'background' => 'רקע',
+    'but' => 'אבל|*',
+    'examples' => 'דוגמאות',
+    'feature' => 'תכונה',
+    'given' => 'בהינתן|*',
+    'name' => 'Hebrew',
+    'native' => 'עברית',
+    'scenario' => 'תרחיש',
+    'scenario_outline' => 'תבנית תרחיש',
+    'then' => 'אזי|אז|*',
+    'when' => 'כאשר|*',
+  ),
+  'hi' => 
+  array (
+    'and' => 'तथा|और|*',
+    'background' => 'पृष्ठभूमि',
+    'but' => 'परन्तु|किन्तु|पर|*',
+    'examples' => 'उदाहरण',
+    'feature' => 'रूप लेख',
+    'given' => 'चूंकि|यदि|अगर|*',
+    'name' => 'Hindi',
+    'native' => 'हिंदी',
+    'scenario' => 'परिदृश्य',
+    'scenario_outline' => 'परिदृश्य रूपरेखा',
+    'then' => 'तदा|तब|*',
+    'when' => 'कदा|जब|*',
+  ),
+  'hr' => 
+  array (
+    'and' => '*|I',
+    'background' => 'Pozadina',
+    'but' => 'Ali|*',
+    'examples' => 'Scenariji|Primjeri',
+    'feature' => 'Mogucnost|Mogućnost|Osobina',
+    'given' => 'Zadani|Zadano|Zadan|*',
+    'name' => 'Croatian',
+    'native' => 'hrvatski',
+    'scenario' => 'Scenarij',
+    'scenario_outline' => 'Koncept|Skica',
+    'then' => 'Onda|*',
+    'when' => 'Kada|Kad|*',
+  ),
+  'ht' => 
+  array (
+    'and' => 'Epi|Ak|*|E',
+    'background' => 'Kontèks|Istorik',
+    'but' => 'Men|*',
+    'examples' => 'Egzanp',
+    'feature' => 'Karakteristik|Fonksyonalite|Mak',
+    'given' => 'Sipoze ke|Sipoze Ke|Sipoze|*',
+    'name' => 'Creole',
+    'native' => 'kreyòl',
+    'scenario' => 'Senaryo',
+    'scenario_outline' => 'Senaryo deskripsyon|Senaryo Deskripsyon|Dyagram senaryo|Dyagram Senaryo|Plan senaryo|Plan Senaryo',
+    'then' => 'Le sa a|Lè sa a|*',
+    'when' => 'Le|Lè|*',
+  ),
+  'hu' => 
+  array (
+    'and' => 'És|*',
+    'background' => 'Háttér',
+    'but' => 'De|*',
+    'examples' => 'Példák',
+    'feature' => 'Jellemző',
+    'given' => 'Amennyiben|Adott|*',
+    'name' => 'Hungarian',
+    'native' => 'magyar',
+    'scenario' => 'Forgatókönyv',
+    'scenario_outline' => 'Forgatókönyv vázlat',
+    'then' => 'Akkor|*',
+    'when' => 'Amikor|Majd|Ha|*',
+  ),
+  'id' => 
+  array (
+    'and' => 'Dan|*',
+    'background' => 'Dasar',
+    'but' => 'Tapi|*',
+    'examples' => 'Contoh',
+    'feature' => 'Fitur',
+    'given' => 'Dengan|*',
+    'name' => 'Indonesian',
+    'native' => 'Bahasa Indonesia',
+    'scenario' => 'Skenario',
+    'scenario_outline' => 'Skenario konsep',
+    'then' => 'Maka|*',
+    'when' => 'Ketika|*',
+  ),
+  'is' => 
+  array (
+    'and' => 'Og|*',
+    'background' => 'Bakgrunnur',
+    'but' => 'En|*',
+    'examples' => 'Atburðarásir|Dæmi',
+    'feature' => 'Eiginleiki',
+    'given' => 'Ef|*',
+    'name' => 'Icelandic',
+    'native' => 'Íslenska',
+    'scenario' => 'Atburðarás',
+    'scenario_outline' => 'Lýsing Atburðarásar|Lýsing Dæma',
+    'then' => 'Þá|*',
+    'when' => 'Þegar|*',
+  ),
+  'it' => 
+  array (
+    'and' => '*|E',
+    'background' => 'Contesto',
+    'but' => 'Ma|*',
+    'examples' => 'Esempi',
+    'feature' => 'Funzionalità',
+    'given' => 'Data|Dato|Dati|Date|*',
+    'name' => 'Italian',
+    'native' => 'italiano',
+    'scenario' => 'Scenario',
+    'scenario_outline' => 'Schema dello scenario',
+    'then' => 'Allora|*',
+    'when' => 'Quando|*',
+  ),
+  'ja' => 
+  array (
+    'and' => 'かつ<|*',
+    'background' => '背景',
+    'but' => 'しかし<|ただし<|但し<|*',
+    'examples' => 'サンプル|例',
+    'feature' => 'フィーチャ|機能',
+    'given' => '前提<|*',
+    'name' => 'Japanese',
+    'native' => '日本語',
+    'scenario' => 'シナリオ',
+    'scenario_outline' => 'シナリオアウトライン|シナリオテンプレート|シナリオテンプレ|テンプレ',
+    'then' => 'ならば<|*',
+    'when' => 'もし<|*',
+  ),
+  'jv' => 
+  array (
+    'and' => 'Lan|*',
+    'background' => 'Dasar',
+    'but' => 'Ananging|Nanging|Tapi|*',
+    'examples' => 'Contone|Conto',
+    'feature' => 'Fitur',
+    'given' => 'Nalikaning|Nalika|*',
+    'name' => 'Javanese',
+    'native' => 'Basa Jawa',
+    'scenario' => 'Skenario',
+    'scenario_outline' => 'Konsep skenario',
+    'then' => 'Banjur|Njuk|*',
+    'when' => 'Menawa|Manawa|*',
+  ),
+  'ka' => 
+  array (
+    'and' => 'და<|*',
+    'background' => 'კონტექსტი',
+    'but' => 'მაგ­რამ<|*',
+    'examples' => 'მაგალითები',
+    'feature' => 'თვისება',
+    'given' => 'მოცემული<|*',
+    'name' => 'Georgian',
+    'native' => 'ქართველი',
+    'scenario' => 'სცენარის',
+    'scenario_outline' => 'სცენარის ნიმუში',
+    'then' => 'მაშინ<|*',
+    'when' => 'როდესაც<|*',
+  ),
+  'kn' => 
+  array (
+    'and' => 'ಮತ್ತು|*',
+    'background' => 'ಹಿನ್ನೆಲೆ',
+    'but' => 'ಆದರೆ|*',
+    'examples' => 'ಉದಾಹರಣೆಗಳು',
+    'feature' => 'ಹೆಚ್ಚಳ',
+    'given' => 'ನೀಡಿದ|*',
+    'name' => 'Kannada',
+    'native' => 'ಕನ್ನಡ',
+    'scenario' => 'ಕಥಾಸಾರಾಂಶ',
+    'scenario_outline' => 'ವಿವರಣೆ',
+    'then' => 'ನಂತರ|*',
+    'when' => 'ಸ್ಥಿತಿಯನ್ನು|*',
+  ),
+  'ko' => 
+  array (
+    'and' => '그리고<|*',
+    'background' => '배경',
+    'but' => '하지만<|단<|*',
+    'examples' => '예',
+    'feature' => '기능',
+    'given' => '먼저<|조건<|*',
+    'name' => 'Korean',
+    'native' => '한국어',
+    'scenario' => '시나리오',
+    'scenario_outline' => '시나리오 개요',
+    'then' => '그러면<|*',
+    'when' => '만약<|만일<|*',
+  ),
+  'lt' => 
+  array (
+    'and' => 'Ir|*',
+    'background' => 'Kontekstas',
+    'but' => 'Bet|*',
+    'examples' => 'Pavyzdžiai|Scenarijai|Variantai',
+    'feature' => 'Savybė',
+    'given' => 'Duota|*',
+    'name' => 'Lithuanian',
+    'native' => 'lietuvių kalba',
+    'scenario' => 'Scenarijus',
+    'scenario_outline' => 'Scenarijaus šablonas',
+    'then' => 'Tada|*',
+    'when' => 'Kai|*',
+  ),
+  'lu' => 
+  array (
+    'and' => 'an|*|a',
+    'background' => 'Hannergrond',
+    'but' => 'awer|mä|*',
+    'examples' => 'Beispiller',
+    'feature' => 'Funktionalitéit',
+    'given' => 'ugeholl|*',
+    'name' => 'Luxemburgish',
+    'native' => 'Lëtzebuergesch',
+    'scenario' => 'Szenario',
+    'scenario_outline' => 'Plang vum Szenario',
+    'then' => 'dann|*',
+    'when' => 'wann|*',
+  ),
+  'lv' => 
+  array (
+    'and' => 'Un|*',
+    'background' => 'Konteksts|Situācija',
+    'but' => 'Bet|*',
+    'examples' => 'Piemēri|Paraugs',
+    'feature' => 'Funkcionalitāte|Fīča',
+    'given' => 'Kad|*',
+    'name' => 'Latvian',
+    'native' => 'latviešu',
+    'scenario' => 'Scenārijs',
+    'scenario_outline' => 'Scenārijs pēc parauga',
+    'then' => 'Tad|*',
+    'when' => 'Ja|*',
+  ),
+  'mk-Cyrl' => 
+  array (
+    'and' => '*|И',
+    'background' => 'Контекст|Содржина',
+    'but' => 'Но|*',
+    'examples' => 'Сценарија|Примери',
+    'feature' => 'Функционалност|Бизнис потреба|Можност',
+    'given' => 'Дадена|Дадено|*',
+    'name' => 'Macedonian',
+    'native' => 'Македонски',
+    'scenario' => 'На пример|Сценарио',
+    'scenario_outline' => 'Преглед на сценарија|Концепт|Скица',
+    'then' => 'Тогаш|*',
+    'when' => 'Кога|*',
+  ),
+  'mk-Latn' => 
+  array (
+    'and' => '*|I',
+    'background' => 'Sodrzhina|Kontekst',
+    'but' => 'No|*',
+    'examples' => 'Scenaria|Primeri',
+    'feature' => 'Funkcionalnost|Biznis potreba|Mozhnost',
+    'given' => 'Dadena|Dadeno|*',
+    'name' => 'Macedonian (Latin)',
+    'native' => 'Makedonski (Latinica)',
+    'scenario' => 'Na primer|Scenario',
+    'scenario_outline' => 'Pregled na scenarija|Koncept|Skica',
+    'then' => 'Togash|*',
+    'when' => 'Koga|*',
+  ),
+  'mn' => 
+  array (
+    'and' => 'Тэгээд|Мөн|*',
+    'background' => 'Агуулга',
+    'but' => 'Гэхдээ|Харин|*',
+    'examples' => 'Тухайлбал',
+    'feature' => 'Функционал|Функц',
+    'given' => 'Өгөгдсөн нь|Анх|*',
+    'name' => 'Mongolian',
+    'native' => 'монгол',
+    'scenario' => 'Сценар',
+    'scenario_outline' => 'Сценарын төлөвлөгөө',
+    'then' => 'Үүний дараа|Тэгэхэд|*',
+    'when' => 'Хэрэв|*',
+  ),
+  'nl' => 
+  array (
+    'and' => 'En|*',
+    'background' => 'Achtergrond',
+    'but' => 'Maar|*',
+    'examples' => 'Voorbeelden',
+    'feature' => 'Functionaliteit',
+    'given' => 'Gegeven|Stel|*',
+    'name' => 'Dutch',
+    'native' => 'Nederlands',
+    'scenario' => 'Scenario',
+    'scenario_outline' => 'Abstract Scenario',
+    'then' => 'Dan|*',
+    'when' => 'Wanneer|Als|*',
+  ),
+  'no' => 
+  array (
+    'and' => 'Og|*',
+    'background' => 'Bakgrunn',
+    'but' => 'Men|*',
+    'examples' => 'Eksempler',
+    'feature' => 'Egenskap',
+    'given' => 'Gitt|*',
+    'name' => 'Norwegian',
+    'native' => 'norsk',
+    'scenario' => 'Scenario',
+    'scenario_outline' => 'Abstrakt Scenario|Scenariomal',
+    'then' => 'Så|*',
+    'when' => 'Når|*',
+  ),
+  'pa' => 
+  array (
+    'and' => 'ਅਤੇ|*',
+    'background' => 'ਪਿਛੋਕੜ',
+    'but' => 'ਪਰ|*',
+    'examples' => 'ਉਦਾਹਰਨਾਂ',
+    'feature' => 'ਨਕਸ਼ ਨੁਹਾਰ|ਮੁਹਾਂਦਰਾ|ਖਾਸੀਅਤ',
+    'given' => 'ਜਿਵੇਂ ਕਿ|ਜੇਕਰ|*',
+    'name' => 'Panjabi',
+    'native' => 'ਪੰਜਾਬੀ',
+    'scenario' => 'ਪਟਕਥਾ',
+    'scenario_outline' => 'ਪਟਕਥਾ ਰੂਪ ਰੇਖਾ|ਪਟਕਥਾ ਢਾਂਚਾ',
+    'then' => 'ਤਦ|*',
+    'when' => 'ਜਦੋਂ|*',
+  ),
+  'pl' => 
+  array (
+    'and' => 'Oraz|*|I',
+    'background' => 'Założenia',
+    'but' => 'Ale|*',
+    'examples' => 'Przykłady',
+    'feature' => 'Potrzeba biznesowa|Właściwość|Funkcja|Aspekt',
+    'given' => 'Zakładając, że|Zakładając|Mając|*',
+    'name' => 'Polish',
+    'native' => 'polski',
+    'scenario' => 'Scenariusz',
+    'scenario_outline' => 'Szablon scenariusza',
+    'then' => 'Wtedy|*',
+    'when' => 'Jeżeli|Jeśli|Kiedy|Gdy|*',
+  ),
+  'pt' => 
+  array (
+    'and' => '*|E',
+    'background' => 'Cenario de Fundo|Cenário de Fundo|Contexto|Fundo',
+    'but' => 'Mas|*',
+    'examples' => 'Exemplos|Cenários|Cenarios',
+    'feature' => 'Funcionalidade|Característica|Caracteristica',
+    'given' => 'Dados|Dadas|Dada|Dado|*',
+    'name' => 'Portuguese',
+    'native' => 'português',
+    'scenario' => 'Cenário|Cenario',
+    'scenario_outline' => 'Delineação do Cenário|Delineacao do Cenario|Esquema do Cenário|Esquema do Cenario',
+    'then' => 'Entao|Então|*',
+    'when' => 'Quando|*',
+  ),
+  'ro' => 
+  array (
+    'and' => 'Și|Si|Şi|*',
+    'background' => 'Context',
+    'but' => 'Dar|*',
+    'examples' => 'Exemple',
+    'feature' => 'Functionalitate|Funcționalitate|Funcţionalitate',
+    'given' => 'Date fiind|Dati fiind|Dați fiind|Daţi fiind|Dat fiind|*',
+    'name' => 'Romanian',
+    'native' => 'română',
+    'scenario' => 'Scenariu',
+    'scenario_outline' => 'Structura scenariu|Structură scenariu',
+    'then' => 'Atunci|*',
+    'when' => 'Când|Cand|*',
+  ),
+  'ru' => 
+  array (
+    'and' => 'К тому же|Также|*|И',
+    'background' => 'Предыстория|Контекст',
+    'but' => 'Но|*|А',
+    'examples' => 'Примеры',
+    'feature' => 'Функциональность|Функционал|Свойство|Функция',
+    'given' => 'Допустим|Пусть|Дано|Если|*',
+    'name' => 'Russian',
+    'native' => 'русский',
+    'scenario' => 'Сценарий',
+    'scenario_outline' => 'Структура сценария',
+    'then' => 'Затем|Тогда|То|*',
+    'when' => 'Когда|*',
+  ),
+  'sk' => 
+  array (
+    'and' => 'A taktiež|A zároveň|A tiež|*|A',
+    'background' => 'Pozadie',
+    'but' => 'Ale|*',
+    'examples' => 'Príklady',
+    'feature' => 'Požiadavka|Vlastnosť|Funkcia',
+    'given' => 'Za predpokladu|Pokiaľ|*',
+    'name' => 'Slovak',
+    'native' => 'Slovensky',
+    'scenario' => 'Scenár',
+    'scenario_outline' => 'Osnova Scenára|Náčrt Scenáru|Náčrt Scenára',
+    'then' => 'Potom|Tak|*',
+    'when' => 'Keď|Ak|*',
+  ),
+  'sl' => 
+  array (
+    'and' => 'Ter|In',
+    'background' => 'Kontekst|Osnova|Ozadje',
+    'but' => 'Vendar|Ampak|Toda',
+    'examples' => 'Scenariji|Primeri',
+    'feature' => 'Funkcionalnost|Značilnost|Funkcija|Možnosti|Moznosti|Lastnost',
+    'given' => 'Privzeto|Zaradi|Podano|Dano',
+    'name' => 'Slovenian',
+    'native' => 'Slovenski',
+    'scenario' => 'Scenarij|Primer',
+    'scenario_outline' => 'Struktura scenarija|Oris scenarija|Koncept|Osnutek|Skica',
+    'then' => 'Takrat|Potem|Nato',
+    'when' => 'Kadar|Ko|Ce|Če',
+  ),
+  'sr-Cyrl' => 
+  array (
+    'and' => '*|И',
+    'background' => 'Контекст|Позадина|Основа',
+    'but' => 'Али|*',
+    'examples' => 'Сценарији|Примери',
+    'feature' => 'Функционалност|Могућност|Особина',
+    'given' => 'За дате|За дато|За дати|*',
+    'name' => 'Serbian',
+    'native' => 'Српски',
+    'scenario' => 'Сценарио|Пример',
+    'scenario_outline' => 'Структура сценарија|Концепт|Скица',
+    'then' => 'Онда|*',
+    'when' => 'Када|Кад|*',
+  ),
+  'sr-Latn' => 
+  array (
+    'and' => '*|I',
+    'background' => 'Kontekst|Pozadina|Osnova',
+    'but' => 'Ali|*',
+    'examples' => 'Scenariji|Primeri',
+    'feature' => 'Funkcionalnost|Mogućnost|Mogucnost|Osobina',
+    'given' => 'Za date|Za dato|Za dati|*',
+    'name' => 'Serbian (Latin)',
+    'native' => 'Srpski (Latinica)',
+    'scenario' => 'Scenario|Primer',
+    'scenario_outline' => 'Struktura scenarija|Koncept|Skica',
+    'then' => 'Onda|*',
+    'when' => 'Kada|Kad|*',
+  ),
+  'sv' => 
+  array (
+    'and' => 'Och|*',
+    'background' => 'Bakgrund',
+    'but' => 'Men|*',
+    'examples' => 'Exempel',
+    'feature' => 'Egenskap',
+    'given' => 'Givet|*',
+    'name' => 'Swedish',
+    'native' => 'Svenska',
+    'scenario' => 'Scenario',
+    'scenario_outline' => 'Abstrakt Scenario|Scenariomall',
+    'then' => 'Så|*',
+    'when' => 'När|*',
+  ),
+  'ta' => 
+  array (
+    'and' => 'மற்றும்|மேலும்|*',
+    'background' => 'பின்னணி',
+    'but' => 'ஆனால்|*',
+    'examples' => 'எடுத்துக்காட்டுகள்| நிலைமைகளில்|காட்சிகள்',
+    'feature' => 'வணிக தேவை|அம்சம்|திறன்',
+    'given' => 'கொடுக்கப்பட்ட|*',
+    'name' => 'Tamil',
+    'native' => 'தமிழ்',
+    'scenario' => 'காட்சி',
+    'scenario_outline' => 'காட்சி வார்ப்புரு|காட்சி சுருக்கம்',
+    'then' => 'அப்பொழுது|*',
+    'when' => 'எப்போது|*',
+  ),
+  'th' => 
+  array (
+    'and' => 'และ|*',
+    'background' => 'แนวคิด',
+    'but' => 'แต่|*',
+    'examples' => 'ชุดของเหตุการณ์|ชุดของตัวอย่าง',
+    'feature' => 'ความต้องการทางธุรกิจ|ความสามารถ|โครงหลัก',
+    'given' => 'กำหนดให้|*',
+    'name' => 'Thai',
+    'native' => 'ไทย',
+    'scenario' => 'เหตุการณ์',
+    'scenario_outline' => 'โครงสร้างของเหตุการณ์|สรุปเหตุการณ์',
+    'then' => 'ดังนั้น|*',
+    'when' => 'เมื่อ|*',
+  ),
+  'tl' => 
+  array (
+    'and' => 'మరియు|*',
+    'background' => 'నేపథ్యం',
+    'but' => 'కాని|*',
+    'examples' => 'ఉదాహరణలు',
+    'feature' => 'గుణము',
+    'given' => 'చెప్పబడినది|*',
+    'name' => 'Telugu',
+    'native' => 'తెలుగు',
+    'scenario' => 'సన్నివేశం',
+    'scenario_outline' => 'కథనం',
+    'then' => 'అప్పుడు|*',
+    'when' => 'ఈ పరిస్థితిలో|*',
+  ),
+  'tlh' => 
+  array (
+    'and' => 'latlh|\'ej|*',
+    'background' => 'mo\'',
+    'but' => '\'ach|\'a|*',
+    'examples' => 'ghantoH|lutmey',
+    'feature' => 'poQbogh malja\'|Qu\'meH \'ut|perbogh|Qap|laH',
+    'given' => 'DaH ghu\' bejlu\'|ghu\' noblu\'|*',
+    'name' => 'Klingon',
+    'native' => 'tlhIngan',
+    'scenario' => 'lut',
+    'scenario_outline' => 'lut chovnatlh',
+    'then' => 'vaj|*',
+    'when' => 'qaSDI\'|*',
+  ),
+  'tr' => 
+  array (
+    'and' => 'Ve|*',
+    'background' => 'Geçmiş',
+    'but' => 'Fakat|Ama|*',
+    'examples' => 'Örnekler',
+    'feature' => 'Özellik',
+    'given' => 'Diyelim ki|*',
+    'name' => 'Turkish',
+    'native' => 'Türkçe',
+    'scenario' => 'Senaryo',
+    'scenario_outline' => 'Senaryo taslağı',
+    'then' => 'O zaman|*',
+    'when' => 'Eğer ki|*',
+  ),
+  'tt' => 
+  array (
+    'and' => 'Һәм|Вә|*',
+    'background' => 'Кереш',
+    'but' => 'Ләкин|Әмма|*',
+    'examples' => 'Үрнәкләр|Мисаллар',
+    'feature' => 'Үзенчәлеклелек|Мөмкинлек',
+    'given' => 'Әйтик|*',
+    'name' => 'Tatar',
+    'native' => 'Татарча',
+    'scenario' => 'Сценарий',
+    'scenario_outline' => 'Сценарийның төзелеше',
+    'then' => 'Нәтиҗәдә|*',
+    'when' => 'Әгәр|*',
+  ),
+  'uk' => 
+  array (
+    'and' => 'А також|Та|*|І',
+    'background' => 'Передумова',
+    'but' => 'Але|*',
+    'examples' => 'Приклади',
+    'feature' => 'Функціонал',
+    'given' => 'Припустимо, що|Припустимо|Нехай|Дано|*',
+    'name' => 'Ukrainian',
+    'native' => 'Українська',
+    'scenario' => 'Сценарій',
+    'scenario_outline' => 'Структура сценарію',
+    'then' => 'Тоді|То|*',
+    'when' => 'Коли|Якщо|*',
+  ),
+  'ur' => 
+  array (
+    'and' => 'اور|*',
+    'background' => 'پس منظر',
+    'but' => 'لیکن|*',
+    'examples' => 'مثالیں',
+    'feature' => 'کاروبار کی ضرورت|صلاحیت|خصوصیت',
+    'given' => 'فرض کیا|بالفرض|اگر|*',
+    'name' => 'Urdu',
+    'native' => 'اردو',
+    'scenario' => 'منظرنامہ',
+    'scenario_outline' => 'منظر نامے کا خاکہ',
+    'then' => 'پھر|تب|*',
+    'when' => 'جب|*',
+  ),
+  'uz' => 
+  array (
+    'and' => 'Ва|*',
+    'background' => 'Тарих',
+    'but' => 'Бирок|Лекин|Аммо|*',
+    'examples' => 'Мисоллар',
+    'feature' => 'Функционал',
+    'given' => 'Агар|*',
+    'name' => 'Uzbek',
+    'native' => 'Узбекча',
+    'scenario' => 'Сценарий',
+    'scenario_outline' => 'Сценарий структураси',
+    'then' => 'Унда|*',
+    'when' => 'Агар|*',
+  ),
+  'vi' => 
+  array (
+    'and' => 'Và|*',
+    'background' => 'Bối cảnh',
+    'but' => 'Nhưng|*',
+    'examples' => 'Dữ liệu',
+    'feature' => 'Tính năng',
+    'given' => 'Biết|Cho|*',
+    'name' => 'Vietnamese',
+    'native' => 'Tiếng Việt',
+    'scenario' => 'Tình huống|Kịch bản',
+    'scenario_outline' => 'Khung tình huống|Khung kịch bản',
+    'then' => 'Thì|*',
+    'when' => 'Khi|*',
+  ),
+  'zh-CN' => 
+  array (
+    'and' => '并且<|而且<|同时<|*',
+    'background' => '背景',
+    'but' => '但是<|*',
+    'examples' => '例子',
+    'feature' => '功能',
+    'given' => '假设<|假如<|假定<|*',
+    'name' => 'Chinese simplified',
+    'native' => '简体中文',
+    'scenario' => '场景|剧本',
+    'scenario_outline' => '场景大纲|剧本大纲',
+    'then' => '那么<|*',
+    'when' => '当<|*',
+  ),
+  'zh-TW' => 
+  array (
+    'and' => '並且<|而且<|同時<|*',
+    'background' => '背景',
+    'but' => '但是<|*',
+    'examples' => '例子',
+    'feature' => '功能',
+    'given' => '假設<|假如<|假定<|*',
+    'name' => 'Chinese traditional',
+    'native' => '繁體中文',
+    'scenario' => '場景|劇本',
+    'scenario_outline' => '場景大綱|劇本大綱',
+    'then' => '那麼<|*',
+    'when' => '當<|*',
+  ),
+);
\ No newline at end of file
diff --git a/vendor/behat/gherkin/libpath.php b/vendor/behat/gherkin/libpath.php
new file mode 100644 (file)
index 0000000..35379fe
--- /dev/null
@@ -0,0 +1,3 @@
+<?php
+
+return __DIR__;
\ No newline at end of file
diff --git a/vendor/behat/gherkin/package.xml.tpl b/vendor/behat/gherkin/package.xml.tpl
new file mode 100644 (file)
index 0000000..1714236
--- /dev/null
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<package packagerversion="1.8.0" version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0
+    http://pear.php.net/dtd/tasks-1.0.xsd
+    http://pear.php.net/dtd/package-2.0
+    http://pear.php.net/dtd/package-2.0.xsd">
+    <name>gherkin</name>
+    <channel>pear.behat.org</channel>
+    <summary>Behat\Gherkin is a BDD DSL for PHP</summary>
+    <description>
+        Behat\Gherkin is an open source behavior driven development DSL for php 5.3.
+    </description>
+    <lead>
+        <name>Konstantin Kudryashov</name>
+        <user>everzet</user>
+        <email>ever.zet@gmail.com</email>
+        <active>yes</active>
+    </lead>
+    <date>##CURRENT_DATE##</date>
+    <version>
+        <release>##GHERKIN_VERSION##</release>
+        <api>1.0.0</api>
+    </version>
+    <stability>
+        <release>##STABILITY##</release>
+        <api>##STABILITY##</api>
+    </stability>
+    <license uri="http://www.opensource.org/licenses/mit-license.php">MIT</license>
+    <notes>-</notes>
+    <contents>
+        <dir name="/">
+
+            ##SOURCE_FILES##
+
+            <file role="php" baseinstalldir="gherkin" name="autoload.php" />
+            <file role="php" baseinstalldir="gherkin" name="libpath.php" />
+            <file role="php" baseinstalldir="gherkin" name="i18n.php" />
+
+            <file role="php" baseinstalldir="gherkin" name="vendor/.composer/autoload.php" />
+            <file role="php" baseinstalldir="gherkin" name="vendor/.composer/autoload_namespaces.php" />
+            <file role="php" baseinstalldir="gherkin" name="phpdoc.ini.dist" />
+            <file role="php" baseinstalldir="gherkin" name="phpunit.xml.dist" />
+            <file role="php" baseinstalldir="gherkin" name="CHANGES.md" />
+            <file role="php" baseinstalldir="gherkin" name="LICENSE" />
+            <file role="php" baseinstalldir="gherkin" name="README.md" />
+
+        </dir>
+    </contents>
+    <dependencies>
+        <required>
+            <php>
+                <min>5.3.1</min>
+            </php>
+            <pearinstaller>
+                <min>1.4.0</min>
+            </pearinstaller>
+            <extension>
+                <name>pcre</name>
+            </extension>
+            <extension>
+                <name>simplexml</name>
+            </extension>
+            <extension>
+                <name>xml</name>
+            </extension>
+            <extension>
+                <name>mbstring</name>
+            </extension>
+        </required>
+    </dependencies>
+    <phprelease />
+</package>
diff --git a/vendor/behat/gherkin/phpdoc.ini.dist b/vendor/behat/gherkin/phpdoc.ini.dist
new file mode 100644 (file)
index 0000000..f983946
--- /dev/null
@@ -0,0 +1,14 @@
+files               = "*.php"
+ignore              = "CVS, .svn, .git, _compiled"
+source_path         = "./src"
+doclet              = standard
+overview            = readme.html
+package_comment_dir = ./
+public              = on
+d                   = "api"
+default_package     = "Behat Gherkin"
+windowtitle         = "Behat Gherkin"
+doctitle            = "Behat Gherkin: PHP 5.3 Gherkin parser"
+header              = "Behat Gherkin"
+footer              = "Behat Gherkin"
+tree                = on
diff --git a/vendor/behat/gherkin/phpunit.xml.dist b/vendor/behat/gherkin/phpunit.xml.dist
new file mode 100644 (file)
index 0000000..24fc8d8
--- /dev/null
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<phpunit backupGlobals="false"
+         backupStaticAttributes="false"
+         colors="true"
+         convertErrorsToExceptions="true"
+         convertNoticesToExceptions="true"
+         convertWarningsToExceptions="true"
+         processIsolation="false"
+         stopOnFailure="false"
+         syntaxCheck="false"
+         bootstrap="vendor/autoload.php"
+>
+    <testsuites>
+        <testsuite name="Behat Gherkin test suite">
+            <directory>./tests/Behat/Gherkin/</directory>
+        </testsuite>
+    </testsuites>
+
+    <filter>
+        <whitelist>
+            <directory>./src/Behat/Gherkin/</directory>
+        </whitelist>
+    </filter>
+</phpunit>
diff --git a/vendor/behat/gherkin/src/Behat/Gherkin/Cache/CacheInterface.php b/vendor/behat/gherkin/src/Behat/Gherkin/Cache/CacheInterface.php
new file mode 100644 (file)
index 0000000..87d4a47
--- /dev/null
@@ -0,0 +1,48 @@
+<?php
+
+/*
+ * This file is part of the Behat Gherkin.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Gherkin\Cache;
+
+use Behat\Gherkin\Node\FeatureNode;
+
+/**
+ * Parser cache interface.
+ *
+ * @author     Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface CacheInterface
+{
+    /**
+     * Checks that cache for feature exists and is fresh.
+     *
+     * @param string  $path      Feature path
+     * @param integer $timestamp The last time feature was updated
+     *
+     * @return Boolean
+     */
+    public function isFresh($path, $timestamp);
+
+    /**
+     * Reads feature cache from path.
+     *
+     * @param string $path Feature path
+     *
+     * @return FeatureNode
+     */
+    public function read($path);
+
+    /**
+     * Caches feature node.
+     *
+     * @param string      $path    Feature path
+     * @param FeatureNode $feature Feature instance
+     */
+    public function write($path, FeatureNode $feature);
+}
diff --git a/vendor/behat/gherkin/src/Behat/Gherkin/Cache/FileCache.php b/vendor/behat/gherkin/src/Behat/Gherkin/Cache/FileCache.php
new file mode 100644 (file)
index 0000000..17a206a
--- /dev/null
@@ -0,0 +1,109 @@
+<?php
+
+/*
+* This file is part of the Behat Gherkin.
+* (c) Konstantin Kudryashov <ever.zet@gmail.com>
+*
+* For the full copyright and license information, please view the LICENSE
+* file that was distributed with this source code.
+*/
+
+namespace Behat\Gherkin\Cache;
+
+use Behat\Gherkin\Exception\CacheException;
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Gherkin;
+
+/**
+ * File cache.
+ * Caches feature into a file.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class FileCache implements CacheInterface
+{
+    private $path;
+
+    /**
+     * Initializes file cache.
+     *
+     * @param string $path Path to the folder where to store caches.
+     *
+     * @throws CacheException
+     */
+    public function __construct($path)
+    {
+        $this->path = rtrim($path, DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR.'v'.Gherkin::VERSION;
+
+        if (!is_dir($this->path)) {
+            @mkdir($this->path, 0777, true);
+        }
+
+        if (!is_writeable($this->path)) {
+            throw new CacheException(sprintf('Cache path "%s" is not writeable. Check your filesystem permissions or disable Gherkin file cache.', $this->path));
+        }
+    }
+
+    /**
+     * Checks that cache for feature exists and is fresh.
+     *
+     * @param string  $path      Feature path
+     * @param integer $timestamp The last time feature was updated
+     *
+     * @return Boolean
+     */
+    public function isFresh($path, $timestamp)
+    {
+        $cachePath = $this->getCachePathFor($path);
+
+        if (!file_exists($cachePath)) {
+            return false;
+        }
+
+        return filemtime($cachePath) > $timestamp;
+    }
+
+    /**
+     * Reads feature cache from path.
+     *
+     * @param string $path Feature path
+     *
+     * @return FeatureNode
+     *
+     * @throws CacheException
+     */
+    public function read($path)
+    {
+        $cachePath = $this->getCachePathFor($path);
+        $feature = unserialize(file_get_contents($cachePath));
+
+        if (!$feature instanceof FeatureNode) {
+            throw new CacheException(sprintf('Can not load cache for a feature "%s" from "%s".', $path, $cachePath ));
+        }
+
+        return $feature;
+    }
+
+    /**
+     * Caches feature node.
+     *
+     * @param string      $path    Feature path
+     * @param FeatureNode $feature Feature instance
+     */
+    public function write($path, FeatureNode $feature)
+    {
+        file_put_contents($this->getCachePathFor($path), serialize($feature));
+    }
+
+    /**
+     * Returns feature cache file path from features path.
+     *
+     * @param string $path Feature path
+     *
+     * @return string
+     */
+    protected function getCachePathFor($path)
+    {
+        return $this->path.'/'.md5($path).'.feature.cache';
+    }
+}
diff --git a/vendor/behat/gherkin/src/Behat/Gherkin/Cache/MemoryCache.php b/vendor/behat/gherkin/src/Behat/Gherkin/Cache/MemoryCache.php
new file mode 100644 (file)
index 0000000..e404f30
--- /dev/null
@@ -0,0 +1,66 @@
+<?php
+
+/*
+* This file is part of the Behat Gherkin.
+* (c) Konstantin Kudryashov <ever.zet@gmail.com>
+*
+* For the full copyright and license information, please view the LICENSE
+* file that was distributed with this source code.
+*/
+
+namespace Behat\Gherkin\Cache;
+
+use Behat\Gherkin\Node\FeatureNode;
+
+/**
+ * Memory cache.
+ * Caches feature into a memory.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class MemoryCache implements CacheInterface
+{
+    private $features = array();
+    private $timestamps = array();
+
+    /**
+     * Checks that cache for feature exists and is fresh.
+     *
+     * @param string  $path      Feature path
+     * @param integer $timestamp The last time feature was updated
+     *
+     * @return Boolean
+     */
+    public function isFresh($path, $timestamp)
+    {
+        if (!isset($this->features[$path])) {
+            return false;
+        }
+
+        return $this->timestamps[$path] > $timestamp;
+    }
+
+    /**
+     * Reads feature cache from path.
+     *
+     * @param string $path Feature path
+     *
+     * @return FeatureNode
+     */
+    public function read($path)
+    {
+        return $this->features[$path];
+    }
+
+    /**
+     * Caches feature node.
+     *
+     * @param string      $path    Feature path
+     * @param FeatureNode $feature Feature instance
+     */
+    public function write($path, FeatureNode $feature)
+    {
+        $this->features[$path]   = $feature;
+        $this->timestamps[$path] = time();
+    }
+}
diff --git a/vendor/behat/gherkin/src/Behat/Gherkin/Exception/CacheException.php b/vendor/behat/gherkin/src/Behat/Gherkin/Exception/CacheException.php
new file mode 100644 (file)
index 0000000..f8b9214
--- /dev/null
@@ -0,0 +1,22 @@
+<?php
+
+/*
+ * This file is part of the Behat Gherkin.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Gherkin\Exception;
+
+use RuntimeException;
+
+/**
+ * Cache exception.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class CacheException extends RuntimeException implements Exception
+{
+}
diff --git a/vendor/behat/gherkin/src/Behat/Gherkin/Exception/Exception.php b/vendor/behat/gherkin/src/Behat/Gherkin/Exception/Exception.php
new file mode 100644 (file)
index 0000000..f377e30
--- /dev/null
@@ -0,0 +1,15 @@
+<?php
+
+/*
+ * This file is part of the Behat Gherkin.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Gherkin\Exception;
+
+interface Exception
+{
+}
diff --git a/vendor/behat/gherkin/src/Behat/Gherkin/Exception/LexerException.php b/vendor/behat/gherkin/src/Behat/Gherkin/Exception/LexerException.php
new file mode 100644 (file)
index 0000000..476d81f
--- /dev/null
@@ -0,0 +1,17 @@
+<?php
+
+/*
+ * This file is part of the Behat Gherkin.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Gherkin\Exception;
+
+use RuntimeException;
+
+class LexerException extends RuntimeException implements Exception
+{
+}
diff --git a/vendor/behat/gherkin/src/Behat/Gherkin/Exception/NodeException.php b/vendor/behat/gherkin/src/Behat/Gherkin/Exception/NodeException.php
new file mode 100644 (file)
index 0000000..b7d7a4c
--- /dev/null
@@ -0,0 +1,17 @@
+<?php
+
+/*
+ * This file is part of the Behat Gherkin.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Gherkin\Exception;
+
+use RuntimeException;
+
+class NodeException extends RuntimeException implements Exception
+{
+}
diff --git a/vendor/behat/gherkin/src/Behat/Gherkin/Exception/ParserException.php b/vendor/behat/gherkin/src/Behat/Gherkin/Exception/ParserException.php
new file mode 100644 (file)
index 0000000..f835e72
--- /dev/null
@@ -0,0 +1,17 @@
+<?php
+
+/*
+ * This file is part of the Behat Gherkin.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Gherkin\Exception;
+
+use RuntimeException;
+
+class ParserException extends RuntimeException implements Exception
+{
+}
diff --git a/vendor/behat/gherkin/src/Behat/Gherkin/Filter/ComplexFilter.php b/vendor/behat/gherkin/src/Behat/Gherkin/Filter/ComplexFilter.php
new file mode 100644 (file)
index 0000000..a3a3b08
--- /dev/null
@@ -0,0 +1,52 @@
+<?php
+
+/*
+ * This file is part of the Behat Gherkin.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Gherkin\Filter;
+
+use Behat\Gherkin\Node\FeatureNode;
+
+/**
+ * Abstract filter class.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+abstract class ComplexFilter implements ComplexFilterInterface
+{
+    /**
+     * Filters feature according to the filter.
+     *
+     * @param FeatureNode $feature
+     *
+     * @return FeatureNode
+     */
+    public function filterFeature(FeatureNode $feature)
+    {
+        $scenarios = array();
+        foreach ($feature->getScenarios() as $scenario) {
+            if (!$this->isScenarioMatch($feature, $scenario)) {
+                continue;
+            }
+
+            $scenarios[] = $scenario;
+        }
+
+        return new FeatureNode(
+            $feature->getTitle(),
+            $feature->getDescription(),
+            $feature->getTags(),
+            $feature->getBackground(),
+            $scenarios,
+            $feature->getKeyword(),
+            $feature->getLanguage(),
+            $feature->getFile(),
+            $feature->getLine()
+        );
+    }
+}
diff --git a/vendor/behat/gherkin/src/Behat/Gherkin/Filter/ComplexFilterInterface.php b/vendor/behat/gherkin/src/Behat/Gherkin/Filter/ComplexFilterInterface.php
new file mode 100644 (file)
index 0000000..8a0ebd5
--- /dev/null
@@ -0,0 +1,32 @@
+<?php
+
+/*
+ * This file is part of the Behat Gherkin.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Gherkin\Filter;
+
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\ScenarioInterface;
+
+/**
+ * Filter interface.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface ComplexFilterInterface extends FeatureFilterInterface
+{
+    /**
+     * Checks if scenario or outline matches specified filter.
+     *
+     * @param FeatureNode       $feature  Feature node instance
+     * @param ScenarioInterface $scenario Scenario or Outline node instance
+     *
+     * @return Boolean
+     */
+    public function isScenarioMatch(FeatureNode $feature, ScenarioInterface $scenario);
+}
diff --git a/vendor/behat/gherkin/src/Behat/Gherkin/Filter/FeatureFilterInterface.php b/vendor/behat/gherkin/src/Behat/Gherkin/Filter/FeatureFilterInterface.php
new file mode 100644 (file)
index 0000000..a7c43ec
--- /dev/null
@@ -0,0 +1,39 @@
+<?php
+
+/*
+ * This file is part of the Behat Gherkin.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Gherkin\Filter;
+
+use Behat\Gherkin\Node\FeatureNode;
+
+/**
+ * Feature filter interface.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface FeatureFilterInterface
+{
+    /**
+     * Checks if Feature matches specified filter.
+     *
+     * @param FeatureNode $feature Feature instance
+     *
+     * @return Boolean
+     */
+    public function isFeatureMatch(FeatureNode $feature);
+
+    /**
+     * Filters feature according to the filter and returns new one.
+     *
+     * @param FeatureNode $feature
+     *
+     * @return FeatureNode
+     */
+    public function filterFeature(FeatureNode $feature);
+}
diff --git a/vendor/behat/gherkin/src/Behat/Gherkin/Filter/FilterInterface.php b/vendor/behat/gherkin/src/Behat/Gherkin/Filter/FilterInterface.php
new file mode 100644 (file)
index 0000000..4a531a0
--- /dev/null
@@ -0,0 +1,30 @@
+<?php
+
+/*
+ * This file is part of the Behat Gherkin.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Gherkin\Filter;
+
+use Behat\Gherkin\Node\ScenarioInterface;
+
+/**
+ * Filter interface.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface FilterInterface extends FeatureFilterInterface
+{
+    /**
+     * Checks if scenario or outline matches specified filter.
+     *
+     * @param ScenarioInterface $scenario Scenario or Outline node instance
+     *
+     * @return Boolean
+     */
+    public function isScenarioMatch(ScenarioInterface $scenario);
+}
diff --git a/vendor/behat/gherkin/src/Behat/Gherkin/Filter/LineFilter.php b/vendor/behat/gherkin/src/Behat/Gherkin/Filter/LineFilter.php
new file mode 100644 (file)
index 0000000..455e9ac
--- /dev/null
@@ -0,0 +1,122 @@
+<?php
+
+/*
+ * This file is part of the Behat Gherkin.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Gherkin\Filter;
+
+use Behat\Gherkin\Node\ExampleTableNode;
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\OutlineNode;
+use Behat\Gherkin\Node\ScenarioInterface;
+
+/**
+ * Filters scenarios by definition line number.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class LineFilter implements FilterInterface
+{
+    protected $filterLine;
+
+    /**
+     * Initializes filter.
+     *
+     * @param string $filterLine Line of the scenario to filter on
+     */
+    public function __construct($filterLine)
+    {
+        $this->filterLine = intval($filterLine);
+    }
+
+    /**
+     * Checks if Feature matches specified filter.
+     *
+     * @param FeatureNode $feature Feature instance
+     *
+     * @return Boolean
+     */
+    public function isFeatureMatch(FeatureNode $feature)
+    {
+        return $this->filterLine === $feature->getLine();
+    }
+
+    /**
+     * Checks if scenario or outline matches specified filter.
+     *
+     * @param ScenarioInterface $scenario Scenario or Outline node instance
+     *
+     * @return Boolean
+     */
+    public function isScenarioMatch(ScenarioInterface $scenario)
+    {
+        if ($this->filterLine === $scenario->getLine()) {
+            return true;
+        }
+
+        if ($scenario instanceof OutlineNode && $scenario->hasExamples()) {
+            return $this->filterLine === $scenario->getLine()
+                || in_array($this->filterLine, $scenario->getExampleTable()->getLines());
+        }
+
+        return false;
+    }
+
+    /**
+     * Filters feature according to the filter and returns new one.
+     *
+     * @param FeatureNode $feature
+     *
+     * @return FeatureNode
+     */
+    public function filterFeature(FeatureNode $feature)
+    {
+        $scenarios = array();
+        foreach ($feature->getScenarios() as $scenario) {
+            if (!$this->isScenarioMatch($scenario)) {
+                continue;
+            }
+
+            if ($scenario instanceof OutlineNode && $scenario->hasExamples()) {
+                $table = $scenario->getExampleTable()->getTable();
+                $lines = array_keys($table);
+
+                if (in_array($this->filterLine, $lines)) {
+                    $filteredTable = array($lines[0] => $table[$lines[0]]);
+
+                    if ($lines[0] !== $this->filterLine) {
+                        $filteredTable[$this->filterLine] = $table[$this->filterLine];
+                    }
+
+                    $scenario = new OutlineNode(
+                        $scenario->getTitle(),
+                        $scenario->getTags(),
+                        $scenario->getSteps(),
+                        new ExampleTableNode($filteredTable, $scenario->getExampleTable()->getKeyword()),
+                        $scenario->getKeyword(),
+                        $scenario->getLine()
+                    );
+                }
+            }
+
+            $scenarios[] = $scenario;
+        }
+
+        return new FeatureNode(
+            $feature->getTitle(),
+            $feature->getDescription(),
+            $feature->getTags(),
+            $feature->getBackground(),
+            $scenarios,
+            $feature->getKeyword(),
+            $feature->getLanguage(),
+            $feature->getFile(),
+            $feature->getLine()
+        );
+    }
+}
diff --git a/vendor/behat/gherkin/src/Behat/Gherkin/Filter/LineRangeFilter.php b/vendor/behat/gherkin/src/Behat/Gherkin/Filter/LineRangeFilter.php
new file mode 100644 (file)
index 0000000..b8062be
--- /dev/null
@@ -0,0 +1,134 @@
+<?php
+
+/*
+ * This file is part of the Behat Gherkin.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Gherkin\Filter;
+
+use Behat\Gherkin\Node\ExampleTableNode;
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\OutlineNode;
+use Behat\Gherkin\Node\ScenarioInterface;
+
+/**
+ * Filters scenarios by definition line number range.
+ *
+ * @author Fabian Kiss <headrevision@gmail.com>
+ */
+class LineRangeFilter implements FilterInterface
+{
+    protected $filterMinLine;
+    protected $filterMaxLine;
+
+    /**
+     * Initializes filter.
+     *
+     * @param string $filterMinLine Minimum line of a scenario to filter on
+     * @param string $filterMaxLine Maximum line of a scenario to filter on
+     */
+    public function __construct($filterMinLine, $filterMaxLine)
+    {
+        $this->filterMinLine = intval($filterMinLine);
+        if ($filterMaxLine == '*') {
+            $this->filterMaxLine = PHP_INT_MAX;
+        } else {
+            $this->filterMaxLine = intval($filterMaxLine);
+        }
+    }
+
+    /**
+     * Checks if Feature matches specified filter.
+     *
+     * @param FeatureNode $feature Feature instance
+     *
+     * @return Boolean
+     */
+    public function isFeatureMatch(FeatureNode $feature)
+    {
+        return $this->filterMinLine <= $feature->getLine()
+            && $this->filterMaxLine >= $feature->getLine();
+    }
+
+    /**
+     * Checks if scenario or outline matches specified filter.
+     *
+     * @param ScenarioInterface $scenario Scenario or Outline node instance
+     *
+     * @return Boolean
+     */
+    public function isScenarioMatch(ScenarioInterface $scenario)
+    {
+        if ($this->filterMinLine <= $scenario->getLine() && $this->filterMaxLine >= $scenario->getLine()) {
+            return true;
+        }
+
+        if ($scenario instanceof OutlineNode && $scenario->hasExamples()) {
+            foreach ($scenario->getExampleTable()->getLines() as $line) {
+                if ($this->filterMinLine <= $line && $this->filterMaxLine >= $line) {
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Filters feature according to the filter.
+     *
+     * @param FeatureNode $feature
+     *
+     * @return FeatureNode
+     */
+    public function filterFeature(FeatureNode $feature)
+    {
+        $scenarios = array();
+        foreach ($feature->getScenarios() as $scenario) {
+            if (!$this->isScenarioMatch($scenario)) {
+                continue;
+            }
+
+            if ($scenario instanceof OutlineNode && $scenario->hasExamples()) {
+                $table = $scenario->getExampleTable()->getTable();
+                $lines = array_keys($table);
+
+                $filteredTable = array($lines[0] => $table[$lines[0]]);
+                unset($table[$lines[0]]);
+
+                foreach ($table as $line => $row) {
+                    if ($this->filterMinLine <= $line && $this->filterMaxLine >= $line) {
+                        $filteredTable[$line] = $row;
+                    }
+                }
+
+                $scenario = new OutlineNode(
+                    $scenario->getTitle(),
+                    $scenario->getTags(),
+                    $scenario->getSteps(),
+                    new ExampleTableNode($filteredTable, $scenario->getExampleTable()->getKeyword()),
+                    $scenario->getKeyword(),
+                    $scenario->getLine()
+                );
+            }
+
+            $scenarios[] = $scenario;
+        }
+
+        return new FeatureNode(
+            $feature->getTitle(),
+            $feature->getDescription(),
+            $feature->getTags(),
+            $feature->getBackground(),
+            $scenarios,
+            $feature->getKeyword(),
+            $feature->getLanguage(),
+            $feature->getFile(),
+            $feature->getLine()
+        );
+    }
+}
diff --git a/vendor/behat/gherkin/src/Behat/Gherkin/Filter/NameFilter.php b/vendor/behat/gherkin/src/Behat/Gherkin/Filter/NameFilter.php
new file mode 100644 (file)
index 0000000..82ae0e5
--- /dev/null
@@ -0,0 +1,68 @@
+<?php
+
+/*
+ * This file is part of the Behat Gherkin.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Gherkin\Filter;
+
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\ScenarioInterface;
+
+/**
+ * Filters scenarios by feature/scenario name.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class NameFilter extends SimpleFilter
+{
+    protected $filterString;
+
+    /**
+     * Initializes filter.
+     *
+     * @param string $filterString Name filter string
+     */
+    public function __construct($filterString)
+    {
+        $this->filterString = trim($filterString);
+    }
+
+    /**
+     * Checks if Feature matches specified filter.
+     *
+     * @param FeatureNode $feature Feature instance
+     *
+     * @return Boolean
+     */
+    public function isFeatureMatch(FeatureNode $feature)
+    {
+        if ('/' === $this->filterString[0]) {
+            return 1 === preg_match($this->filterString, $feature->getTitle());
+        }
+
+        return false !== mb_strpos($feature->getTitle(), $this->filterString, 0, 'utf8');
+    }
+
+    /**
+     * Checks if scenario or outline matches specified filter.
+     *
+     * @param ScenarioInterface $scenario Scenario or Outline node instance
+     *
+     * @return Boolean
+     */
+    public function isScenarioMatch(ScenarioInterface $scenario)
+    {
+        if ('/' === $this->filterString[0] && 1 === preg_match($this->filterString, $scenario->getTitle())) {
+            return true;
+        } elseif (false !== mb_strpos($scenario->getTitle(), $this->filterString, 0, 'utf8')) {
+            return true;
+        }
+
+        return false;
+    }
+}
diff --git a/vendor/behat/gherkin/src/Behat/Gherkin/Filter/NarrativeFilter.php b/vendor/behat/gherkin/src/Behat/Gherkin/Filter/NarrativeFilter.php
new file mode 100644 (file)
index 0000000..61126e5
--- /dev/null
@@ -0,0 +1,61 @@
+<?php
+
+/*
+ * This file is part of the Gherkin.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Gherkin\Filter;
+
+use Behat\Gherkin\Node\ScenarioInterface;
+use Behat\Gherkin\Node\FeatureNode;
+
+/**
+ * Filters features by their narrative using regular expression.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class NarrativeFilter extends SimpleFilter
+{
+    /**
+     * @var string
+     */
+    private $regex;
+
+    /**
+     * Initializes filter.
+     *
+     * @param string $regex
+     */
+    public function __construct($regex)
+    {
+        $this->regex = $regex;
+    }
+
+    /**
+     * Checks if Feature matches specified filter.
+     *
+     * @param FeatureNode $feature Feature instance
+     *
+     * @return Boolean
+     */
+    public function isFeatureMatch(FeatureNode $feature)
+    {
+        return 1 === preg_match($this->regex, $feature->getDescription());
+    }
+
+    /**
+     * Checks if scenario or outline matches specified filter.
+     *
+     * @param ScenarioInterface $scenario Scenario or Outline node instance
+     *
+     * @return Boolean
+     */
+    public function isScenarioMatch(ScenarioInterface $scenario)
+    {
+        return false;
+    }
+}
diff --git a/vendor/behat/gherkin/src/Behat/Gherkin/Filter/PathsFilter.php b/vendor/behat/gherkin/src/Behat/Gherkin/Filter/PathsFilter.php
new file mode 100644 (file)
index 0000000..7f7c1dc
--- /dev/null
@@ -0,0 +1,72 @@
+<?php
+
+/*
+ * This file is part of the Behat Gherkin.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Gherkin\Filter;
+
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\ScenarioInterface;
+
+/**
+ * Filters features by their paths.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class PathsFilter extends SimpleFilter
+{
+    protected $filterPaths = array();
+
+    /**
+     * Initializes filter.
+     *
+     * @param string[] $paths List of approved paths
+     */
+    public function __construct(array $paths)
+    {
+        $this->filterPaths = array_map(
+            function ($realpath) {
+                return rtrim($realpath, DIRECTORY_SEPARATOR) .
+                    (is_dir($realpath) ? DIRECTORY_SEPARATOR : '');
+            },
+            array_filter(
+                array_map('realpath', $paths)
+            )
+        );
+    }
+
+    /**
+     * Checks if Feature matches specified filter.
+     *
+     * @param FeatureNode $feature Feature instance
+     *
+     * @return Boolean
+     */
+    public function isFeatureMatch(FeatureNode $feature)
+    {
+        foreach ($this->filterPaths as $path) {
+            if (0 === strpos(realpath($feature->getFile()), $path)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Checks if scenario or outline matches specified filter.
+     *
+     * @param ScenarioInterface $scenario Scenario or Outline node instance
+     *
+     * @return false This filter is designed to work only with features
+     */
+    public function isScenarioMatch(ScenarioInterface $scenario)
+    {
+        return false;
+    }
+}
diff --git a/vendor/behat/gherkin/src/Behat/Gherkin/Filter/RoleFilter.php b/vendor/behat/gherkin/src/Behat/Gherkin/Filter/RoleFilter.php
new file mode 100644 (file)
index 0000000..19e9377
--- /dev/null
@@ -0,0 +1,63 @@
+<?php
+
+/*
+ * This file is part of the Behat Gherkin.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Gherkin\Filter;
+
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\ScenarioInterface;
+
+/**
+ * Filters features by their actors role.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class RoleFilter extends SimpleFilter
+{
+    protected $pattern;
+
+    /**
+     * Initializes filter.
+     *
+     * @param string $role Approved role wildcard
+     */
+    public function __construct($role)
+    {
+        $this->pattern = '/as an? ' . strtr(preg_quote($role, '/'), array(
+            '\*' => '.*',
+            '\?' => '.',
+            '\[' => '[',
+            '\]' => ']'
+        )) . '[$\n]/i';
+    }
+
+    /**
+     * Checks if Feature matches specified filter.
+     *
+     * @param FeatureNode $feature Feature instance
+     *
+     * @return Boolean
+     */
+    public function isFeatureMatch(FeatureNode $feature)
+    {
+        return 1 === preg_match($this->pattern, $feature->getDescription());
+    }
+
+    /**
+     * Checks if scenario or outline matches specified filter.
+     *
+     * @param ScenarioInterface $scenario Scenario or Outline node instance
+     *
+     * @return false This filter is designed to work only with features
+     */
+    public function isScenarioMatch(ScenarioInterface $scenario)
+    {
+        return false;
+    }
+}
diff --git a/vendor/behat/gherkin/src/Behat/Gherkin/Filter/SimpleFilter.php b/vendor/behat/gherkin/src/Behat/Gherkin/Filter/SimpleFilter.php
new file mode 100644 (file)
index 0000000..10bee8f
--- /dev/null
@@ -0,0 +1,56 @@
+<?php
+
+/*
+ * This file is part of the Behat Gherkin.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Gherkin\Filter;
+
+use Behat\Gherkin\Node\FeatureNode;
+
+/**
+ * Abstract filter class.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+abstract class SimpleFilter implements FilterInterface
+{
+    /**
+     * Filters feature according to the filter.
+     *
+     * @param FeatureNode $feature
+     *
+     * @return FeatureNode
+     */
+    public function filterFeature(FeatureNode $feature)
+    {
+        if ($this->isFeatureMatch($feature)) {
+            return $feature;
+        }
+
+        $scenarios = array();
+        foreach ($feature->getScenarios() as $scenario) {
+            if (!$this->isScenarioMatch($scenario)) {
+                continue;
+            }
+
+            $scenarios[] = $scenario;
+        }
+
+        return new FeatureNode(
+            $feature->getTitle(),
+            $feature->getDescription(),
+            $feature->getTags(),
+            $feature->getBackground(),
+            $scenarios,
+            $feature->getKeyword(),
+            $feature->getLanguage(),
+            $feature->getFile(),
+            $feature->getLine()
+        );
+    }
+}
diff --git a/vendor/behat/gherkin/src/Behat/Gherkin/Filter/TagFilter.php b/vendor/behat/gherkin/src/Behat/Gherkin/Filter/TagFilter.php
new file mode 100644 (file)
index 0000000..fed6c1a
--- /dev/null
@@ -0,0 +1,90 @@
+<?php
+
+/*
+ * This file is part of the Behat Gherkin.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Gherkin\Filter;
+
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\ScenarioInterface;
+
+/**
+ * Filters scenarios by feature/scenario tag.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class TagFilter extends ComplexFilter
+{
+    protected $filterString;
+
+    /**
+     * Initializes filter.
+     *
+     * @param string $filterString Name filter string
+     */
+    public function __construct($filterString)
+    {
+        $this->filterString = trim($filterString);
+    }
+
+    /**
+     * Checks if Feature matches specified filter.
+     *
+     * @param FeatureNode $feature Feature instance
+     *
+     * @return Boolean
+     */
+    public function isFeatureMatch(FeatureNode $feature)
+    {
+        return $this->isTagsMatchCondition($feature->getTags());
+    }
+
+    /**
+     * Checks if scenario or outline matches specified filter.
+     *
+     * @param FeatureNode       $feature  Feature node instance
+     * @param ScenarioInterface $scenario Scenario or Outline node instance
+     *
+     * @return Boolean
+     */
+    public function isScenarioMatch(FeatureNode $feature, ScenarioInterface $scenario)
+    {
+        return $this->isTagsMatchCondition(array_merge($feature->getTags(), $scenario->getTags()));
+    }
+
+    /**
+     * Checks that node matches condition.
+     *
+     * @param string[] $tags
+     *
+     * @return Boolean
+     */
+    protected function isTagsMatchCondition($tags)
+    {
+        $satisfies = true;
+
+        foreach (explode('&&', $this->filterString) as $andTags) {
+            $satisfiesComma = false;
+
+            foreach (explode(',', $andTags) as $tag) {
+                $tag = str_replace('@', '', trim($tag));
+
+                if ('~' === $tag[0]) {
+                    $tag = mb_substr($tag, 1, mb_strlen($tag, 'utf8') - 1, 'utf8');
+                    $satisfiesComma = !in_array($tag, $tags) || $satisfiesComma;
+                } else {
+                    $satisfiesComma = in_array($tag, $tags) || $satisfiesComma;
+                }
+            }
+
+            $satisfies = (false !== $satisfiesComma && $satisfies && $satisfiesComma) || false;
+        }
+
+        return $satisfies;
+    }
+}
diff --git a/vendor/behat/gherkin/src/Behat/Gherkin/Gherkin.php b/vendor/behat/gherkin/src/Behat/Gherkin/Gherkin.php
new file mode 100644 (file)
index 0000000..e457cd8
--- /dev/null
@@ -0,0 +1,142 @@
+<?php
+
+/*
+ * This file is part of the Behat Gherkin.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Gherkin;
+
+use Behat\Gherkin\Filter\FeatureFilterInterface;
+use Behat\Gherkin\Filter\LineFilter;
+use Behat\Gherkin\Filter\LineRangeFilter;
+use Behat\Gherkin\Loader\FileLoaderInterface;
+use Behat\Gherkin\Loader\LoaderInterface;
+
+/**
+ * Gherkin manager.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class Gherkin
+{
+    const VERSION = '4.4-dev';
+
+    /**
+     * @var LoaderInterface[]
+     */
+    protected $loaders = array();
+    /**
+     * @var FeatureFilterInterface[]
+     */
+    protected $filters = array();
+
+    /**
+     * Adds loader to manager.
+     *
+     * @param LoaderInterface $loader Feature loader
+     */
+    public function addLoader(LoaderInterface $loader)
+    {
+        $this->loaders[] = $loader;
+    }
+
+    /**
+     * Adds filter to manager.
+     *
+     * @param FeatureFilterInterface $filter Feature filter
+     */
+    public function addFilter(FeatureFilterInterface $filter)
+    {
+        $this->filters[] = $filter;
+    }
+
+    /**
+     * Sets filters to the parser.
+     *
+     * @param FeatureFilterInterface[] $filters
+     */
+    public function setFilters(array $filters)
+    {
+        $this->filters = array();
+        array_map(array($this, 'addFilter'), $filters);
+    }
+
+    /**
+     * Sets base features path.
+     *
+     * @param string $path Loaders base path
+     */
+    public function setBasePath($path)
+    {
+        foreach ($this->loaders as $loader) {
+            if ($loader instanceof FileLoaderInterface) {
+                $loader->setBasePath($path);
+            }
+        }
+    }
+
+    /**
+     * Loads & filters resource with added loaders.
+     *
+     * @param mixed                    $resource Resource to load
+     * @param FeatureFilterInterface[] $filters  Additional filters
+     *
+     * @return array
+     */
+    public function load($resource, array $filters = array())
+    {
+        $filters = array_merge($this->filters, $filters);
+
+        $matches = array();
+        if (preg_match('/^(.*)\:(\d+)-(\d+|\*)$/', $resource, $matches)) {
+            $resource = $matches[1];
+            $filters[] = new LineRangeFilter($matches[2], $matches[3]);
+        } elseif (preg_match('/^(.*)\:(\d+)$/', $resource, $matches)) {
+            $resource = $matches[1];
+            $filters[] = new LineFilter($matches[2]);
+        }
+
+        $loader = $this->resolveLoader($resource);
+
+        if (null === $loader) {
+            return array();
+        }
+
+        $features = array();
+        foreach ($loader->load($resource) as $feature) {
+            foreach ($filters as $filter) {
+                $feature = $filter->filterFeature($feature);
+
+                if (!$feature->hasScenarios() && !$filter->isFeatureMatch($feature)) {
+                    continue 2;
+                }
+            }
+
+            $features[] = $feature;
+        }
+
+        return $features;
+    }
+
+    /**
+     * Resolves loader by resource.
+     *
+     * @param mixed $resource Resource to load
+     *
+     * @return LoaderInterface
+     */
+    public function resolveLoader($resource)
+    {
+        foreach ($this->loaders as $loader) {
+            if ($loader->supports($resource)) {
+                return $loader;
+            }
+        }
+
+        return null;
+    }
+}
diff --git a/vendor/behat/gherkin/src/Behat/Gherkin/Keywords/ArrayKeywords.php b/vendor/behat/gherkin/src/Behat/Gherkin/Keywords/ArrayKeywords.php
new file mode 100644 (file)
index 0000000..35b9b82
--- /dev/null
@@ -0,0 +1,200 @@
+<?php
+
+/*
+ * This file is part of the Behat Gherkin.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Gherkin\Keywords;
+
+/**
+ * Array initializable keywords holder.
+ *
+ * $keywords = new Behat\Gherkin\Keywords\ArrayKeywords(array(
+ *     'en' => array(
+ *         'feature'          => 'Feature',
+ *         'background'       => 'Background',
+ *         'scenario'         => 'Scenario',
+ *         'scenario_outline' => 'Scenario Outline|Scenario Template',
+ *         'examples'         => 'Examples|Scenarios',
+ *         'given'            => 'Given',
+ *         'when'             => 'When',
+ *         'then'             => 'Then',
+ *         'and'              => 'And',
+ *         'but'              => 'But'
+ *     ),
+ *     'ru' => array(
+ *         'feature'          => 'Функционал',
+ *         'background'       => 'Предыстория',
+ *         'scenario'         => 'Сценарий',
+ *         'scenario_outline' => 'Структура сценария',
+ *         'examples'         => 'Значения',
+ *         'given'            => 'Допустим',
+ *         'when'             => 'Если',
+ *         'then'             => 'То',
+ *         'and'              => 'И',
+ *         'but'              => 'Но'
+ *     )
+ * ));
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class ArrayKeywords implements KeywordsInterface
+{
+    private $keywords = array();
+    private $keywordString = array();
+    private $language;
+
+    /**
+     * Initializes holder with keywords.
+     *
+     * @param array $keywords Keywords array
+     */
+    public function __construct(array $keywords)
+    {
+        $this->keywords = $keywords;
+    }
+
+    /**
+     * Sets keywords holder language.
+     *
+     * @param string $language Language name
+     */
+    public function setLanguage($language)
+    {
+        if (!isset($this->keywords[$language])) {
+            $this->language = 'en';
+        } else {
+            $this->language = $language;
+        }
+    }
+
+    /**
+     * Returns Feature keywords (splitted by "|").
+     *
+     * @return string
+     */
+    public function getFeatureKeywords()
+    {
+        return $this->keywords[$this->language]['feature'];
+    }
+
+    /**
+     * Returns Background keywords (splitted by "|").
+     *
+     * @return string
+     */
+    public function getBackgroundKeywords()
+    {
+        return $this->keywords[$this->language]['background'];
+    }
+
+    /**
+     * Returns Scenario keywords (splitted by "|").
+     *
+     * @return string
+     */
+    public function getScenarioKeywords()
+    {
+        return $this->keywords[$this->language]['scenario'];
+    }
+
+    /**
+     * Returns Scenario Outline keywords (splitted by "|").
+     *
+     * @return string
+     */
+    public function getOutlineKeywords()
+    {
+        return $this->keywords[$this->language]['scenario_outline'];
+    }
+
+    /**
+     * Returns Examples keywords (splitted by "|").
+     *
+     * @return string
+     */
+    public function getExamplesKeywords()
+    {
+        return $this->keywords[$this->language]['examples'];
+    }
+
+    /**
+     * Returns Given keywords (splitted by "|").
+     *
+     * @return string
+     */
+    public function getGivenKeywords()
+    {
+        return $this->keywords[$this->language]['given'];
+    }
+
+    /**
+     * Returns When keywords (splitted by "|").
+     *
+     * @return string
+     */
+    public function getWhenKeywords()
+    {
+        return $this->keywords[$this->language]['when'];
+    }
+
+    /**
+     * Returns Then keywords (splitted by "|").
+     *
+     * @return string
+     */
+    public function getThenKeywords()
+    {
+        return $this->keywords[$this->language]['then'];
+    }
+
+    /**
+     * Returns And keywords (splitted by "|").
+     *
+     * @return string
+     */
+    public function getAndKeywords()
+    {
+        return $this->keywords[$this->language]['and'];
+    }
+
+    /**
+     * Returns But keywords (splitted by "|").
+     *
+     * @return string
+     */
+    public function getButKeywords()
+    {
+        return $this->keywords[$this->language]['but'];
+    }
+
+    /**
+     * Returns all step keywords (Given, When, Then, And, But).
+     *
+     * @return string
+     */
+    public function getStepKeywords()
+    {
+        if (!isset($this->keywordString[$this->language])) {
+            $keywords = array_merge(
+                explode('|', $this->getGivenKeywords()),
+                explode('|', $this->getWhenKeywords()),
+                explode('|', $this->getThenKeywords()),
+                explode('|', $this->getAndKeywords()),
+                explode('|', $this->getButKeywords())
+            );
+
+            usort($keywords, function ($keyword1, $keyword2) {
+                return mb_strlen($keyword2, 'utf8') - mb_strlen($keyword1, 'utf8');
+            });
+
+            $this->keywordString[$this->language] = implode('|', $keywords);
+        }
+
+        return $this->keywordString[$this->language];
+    }
+}
diff --git a/vendor/behat/gherkin/src/Behat/Gherkin/Keywords/CachedArrayKeywords.php b/vendor/behat/gherkin/src/Behat/Gherkin/Keywords/CachedArrayKeywords.php
new file mode 100644 (file)
index 0000000..871f196
--- /dev/null
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ * This file is part of the Behat Gherkin.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Gherkin\Keywords;
+
+/**
+ * File initializable keywords holder.
+ *
+ * $keywords = new Behat\Gherkin\Keywords\CachedArrayKeywords($file);
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class CachedArrayKeywords extends ArrayKeywords
+{
+    /**
+     * Initializes holder with file.
+     *
+     * @param string $file Cached array path
+     */
+    public function __construct($file)
+    {
+        parent::__construct(include($file));
+    }
+}
diff --git a/vendor/behat/gherkin/src/Behat/Gherkin/Keywords/CucumberKeywords.php b/vendor/behat/gherkin/src/Behat/Gherkin/Keywords/CucumberKeywords.php
new file mode 100644 (file)
index 0000000..2a54396
--- /dev/null
@@ -0,0 +1,121 @@
+<?php
+
+/*
+ * This file is part of the Behat Gherkin.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Gherkin\Keywords;
+
+use Symfony\Component\Yaml\Exception\ParseException;
+use Symfony\Component\Yaml\Yaml;
+
+/**
+ * Cucumber-translations reader.
+ *
+ * $keywords = new Behat\Gherkin\Keywords\CucumberKeywords($i18nYmlPath);
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class CucumberKeywords extends ArrayKeywords
+{
+    /**
+     * Initializes holder with yaml string OR file.
+     *
+     * @param string $yaml Yaml string or file path
+     */
+    public function __construct($yaml)
+    {
+        // Handle filename explicitly for BC reasons, as Symfony Yaml 3.0 does not do it anymore
+        $file = null;
+        if (strpos($yaml, "\n") === false && is_file($yaml)) {
+            if (false === is_readable($yaml)) {
+                throw new ParseException(sprintf('Unable to parse "%s" as the file is not readable.', $yaml));
+            }
+
+            $file = $yaml;
+            $yaml = file_get_contents($file);
+        }
+
+        try {
+            $content = Yaml::parse($yaml);
+        } catch (ParseException $e) {
+            if ($file) {
+                $e->setParsedFile($file);
+            }
+
+            throw $e;
+        }
+
+        parent::__construct($content);
+    }
+
+    /**
+     * Returns Feature keywords (splitted by "|").
+     *
+     * @return string
+     */
+    public function getGivenKeywords()
+    {
+        return $this->prepareStepString(parent::getGivenKeywords());
+    }
+
+    /**
+     * Returns When keywords (splitted by "|").
+     *
+     * @return string
+     */
+    public function getWhenKeywords()
+    {
+        return $this->prepareStepString(parent::getWhenKeywords());
+    }
+
+    /**
+     * Returns Then keywords (splitted by "|").
+     *
+     * @return string
+     */
+    public function getThenKeywords()
+    {
+        return $this->prepareStepString(parent::getThenKeywords());
+    }
+
+    /**
+     * Returns And keywords (splitted by "|").
+     *
+     * @return string
+     */
+    public function getAndKeywords()
+    {
+        return $this->prepareStepString(parent::getAndKeywords());
+    }
+
+    /**
+     * Returns But keywords (splitted by "|").
+     *
+     * @return string
+     */
+    public function getButKeywords()
+    {
+        return $this->prepareStepString(parent::getButKeywords());
+    }
+
+    /**
+     * Trim *| from the begining of the list.
+     *
+     * @param string $keywordsString Keywords string
+     *
+     * @return string
+     */
+    private function prepareStepString($keywordsString)
+    {
+        if (0 === mb_strpos($keywordsString, '*|', 0, 'UTF-8')) {
+            $keywordsString = mb_substr($keywordsString, 2, mb_strlen($keywordsString, 'utf8') - 2, 'utf8');
+        }
+
+        return $keywordsString;
+    }
+}
diff --git a/vendor/behat/gherkin/src/Behat/Gherkin/Keywords/KeywordsDumper.php b/vendor/behat/gherkin/src/Behat/Gherkin/Keywords/KeywordsDumper.php
new file mode 100644 (file)
index 0000000..fcd9769
--- /dev/null
@@ -0,0 +1,365 @@
+<?php
+
+/*
+ * This file is part of the Behat Gherkin.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Gherkin\Keywords;
+
+/**
+ * Gherkin keywords dumper.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class KeywordsDumper
+{
+    private $keywords;
+    private $keywordsDumper;
+
+    /**
+     * Initializes dumper.
+     *
+     * @param KeywordsInterface $keywords Keywords instance
+     */
+    public function __construct(KeywordsInterface $keywords)
+    {
+        $this->keywords = $keywords;
+        $this->keywordsDumper = array($this, 'dumpKeywords');
+    }
+
+    /**
+     * Sets keywords mapper function.
+     *
+     * Callable should accept 2 arguments (array $keywords and Boolean $isShort)
+     *
+     * @param callable $mapper Mapper function
+     */
+    public function setKeywordsDumperFunction($mapper)
+    {
+        $this->keywordsDumper = $mapper;
+    }
+
+    /**
+     * Defaults keywords dumper.
+     *
+     * @param array   $keywords Keywords list
+     * @param Boolean $isShort  Is short version
+     *
+     * @return string
+     */
+    public function dumpKeywords(array $keywords, $isShort)
+    {
+        if ($isShort) {
+            return 1 < count($keywords) ? '(' . implode('|', $keywords) . ')' : $keywords[0];
+        }
+
+        return $keywords[0];
+    }
+
+    /**
+     * Dumps keyworded feature into string.
+     *
+     * @param string  $language Keywords language
+     * @param Boolean $short    Dump short version
+     * @param bool    $excludeAsterisk
+     *
+     * @return string|array String for short version and array of features for extended
+     */
+    public function dump($language, $short = true, $excludeAsterisk = false)
+    {
+        $this->keywords->setLanguage($language);
+        $languageComment = '';
+        if ('en' !== $language) {
+            $languageComment = "# language: $language\n";
+        }
+
+        $keywords = explode('|', $this->keywords->getFeatureKeywords());
+
+        if ($short) {
+            $keywords = call_user_func($this->keywordsDumper, $keywords, $short);
+
+            return trim($languageComment . $this->dumpFeature($keywords, $short, $excludeAsterisk));
+        }
+
+        $features = array();
+        foreach ($keywords as $keyword) {
+            $keyword = call_user_func($this->keywordsDumper, array($keyword), $short);
+            $features[] = trim($languageComment . $this->dumpFeature($keyword, $short, $excludeAsterisk));
+        }
+
+        return $features;
+    }
+
+    /**
+     * Dumps feature example.
+     *
+     * @param string  $keyword Item keyword
+     * @param Boolean $short   Dump short version?
+     *
+     * @return string
+     */
+    protected function dumpFeature($keyword, $short = true, $excludeAsterisk = false)
+    {
+        $dump = <<<GHERKIN
+{$keyword}: Internal operations
+  In order to stay secret
+  As a secret organization
+  We need to be able to erase past agents' memory
+
+
+GHERKIN;
+
+        // Background
+        $keywords = explode('|', $this->keywords->getBackgroundKeywords());
+        if ($short) {
+            $keywords = call_user_func($this->keywordsDumper, $keywords, $short);
+            $dump .= $this->dumpBackground($keywords, $short, $excludeAsterisk);
+        } else {
+            $keyword = call_user_func($this->keywordsDumper, array($keywords[0]), $short);
+            $dump .= $this->dumpBackground($keyword, $short, $excludeAsterisk);
+        }
+
+        // Scenario
+        $keywords = explode('|', $this->keywords->getScenarioKeywords());
+        if ($short) {
+            $keywords = call_user_func($this->keywordsDumper, $keywords, $short);
+            $dump .= $this->dumpScenario($keywords, $short, $excludeAsterisk);
+        } else {
+            foreach ($keywords as $keyword) {
+                $keyword = call_user_func($this->keywordsDumper, array($keyword), $short);
+                $dump .= $this->dumpScenario($keyword, $short, $excludeAsterisk);
+            }
+        }
+
+        // Outline
+        $keywords = explode('|', $this->keywords->getOutlineKeywords());
+        if ($short) {
+            $keywords = call_user_func($this->keywordsDumper, $keywords, $short);
+            $dump .= $this->dumpOutline($keywords, $short, $excludeAsterisk);
+        } else {
+            foreach ($keywords as $keyword) {
+                $keyword = call_user_func($this->keywordsDumper, array($keyword), $short);
+                $dump .= $this->dumpOutline($keyword, $short, $excludeAsterisk);
+            }
+        }
+
+        return $dump;
+    }
+
+    /**
+     * Dumps background example.
+     *
+     * @param string  $keyword Item keyword
+     * @param Boolean $short   Dump short version?
+     *
+     * @return string
+     */
+    protected function dumpBackground($keyword, $short = true, $excludeAsterisk = false)
+    {
+        $dump = <<<GHERKIN
+  {$keyword}:
+
+GHERKIN;
+
+        // Given
+        $dump .= $this->dumpStep(
+            $this->keywords->getGivenKeywords(),
+            'there is agent A',
+            $short,
+            $excludeAsterisk
+        );
+
+        // And
+        $dump .= $this->dumpStep(
+            $this->keywords->getAndKeywords(),
+            'there is agent B',
+            $short,
+            $excludeAsterisk
+        );
+
+        return $dump . "\n";
+    }
+
+    /**
+     * Dumps scenario example.
+     *
+     * @param string  $keyword Item keyword
+     * @param Boolean $short   Dump short version?
+     *
+     * @return string
+     */
+    protected function dumpScenario($keyword, $short = true, $excludeAsterisk = false)
+    {
+        $dump = <<<GHERKIN
+  {$keyword}: Erasing agent memory
+
+GHERKIN;
+
+        // Given
+        $dump .= $this->dumpStep(
+            $this->keywords->getGivenKeywords(),
+            'there is agent J',
+            $short,
+            $excludeAsterisk
+        );
+
+        // And
+        $dump .= $this->dumpStep(
+            $this->keywords->getAndKeywords(),
+            'there is agent K',
+            $short,
+            $excludeAsterisk
+        );
+
+        // When
+        $dump .= $this->dumpStep(
+            $this->keywords->getWhenKeywords(),
+            'I erase agent K\'s memory',
+            $short,
+            $excludeAsterisk
+        );
+
+        // Then
+        $dump .= $this->dumpStep(
+            $this->keywords->getThenKeywords(),
+            'there should be agent J',
+            $short,
+            $excludeAsterisk
+        );
+
+        // But
+        $dump .= $this->dumpStep(
+            $this->keywords->getButKeywords(),
+            'there should not be agent K',
+            $short,
+            $excludeAsterisk
+        );
+
+        return $dump . "\n";
+    }
+
+    /**
+     * Dumps outline example.
+     *
+     * @param string  $keyword Item keyword
+     * @param Boolean $short   Dump short version?
+     *
+     * @return string
+     */
+    protected function dumpOutline($keyword, $short = true, $excludeAsterisk = false)
+    {
+        $dump = <<<GHERKIN
+  {$keyword}: Erasing other agents' memory
+
+GHERKIN;
+
+        // Given
+        $dump .= $this->dumpStep(
+            $this->keywords->getGivenKeywords(),
+            'there is agent <agent1>',
+            $short,
+            $excludeAsterisk
+        );
+
+        // And
+        $dump .= $this->dumpStep(
+            $this->keywords->getAndKeywords(),
+            'there is agent <agent2>',
+            $short,
+            $excludeAsterisk
+        );
+
+        // When
+        $dump .= $this->dumpStep(
+            $this->keywords->getWhenKeywords(),
+            'I erase agent <agent2>\'s memory',
+            $short,
+            $excludeAsterisk
+        );
+
+        // Then
+        $dump .= $this->dumpStep(
+            $this->keywords->getThenKeywords(),
+            'there should be agent <agent1>',
+            $short,
+            $excludeAsterisk
+        );
+
+        // But
+        $dump .= $this->dumpStep(
+            $this->keywords->getButKeywords(),
+            'there should not be agent <agent2>',
+            $short,
+            $excludeAsterisk
+        );
+
+        $keywords = explode('|', $this->keywords->getExamplesKeywords());
+        if ($short) {
+            $keyword = call_user_func($this->keywordsDumper, $keywords, $short);
+        } else {
+            $keyword = call_user_func($this->keywordsDumper, array($keywords[0]), $short);
+        }
+
+        $dump .= <<<GHERKIN
+
+    {$keyword}:
+      | agent1 | agent2 |
+      | D      | M      |
+
+GHERKIN;
+
+        return $dump . "\n";
+    }
+
+    /**
+     * Dumps step example.
+     *
+     * @param string  $keywords Item keyword
+     * @param string  $text     Step text
+     * @param Boolean $short    Dump short version?
+     *
+     * @return string
+     */
+    protected function dumpStep($keywords, $text, $short = true, $excludeAsterisk = false)
+    {
+        $dump = '';
+
+        $keywords = explode('|', $keywords);
+        if ($short) {
+            $keywords = array_map(
+                function ($keyword) {
+                    return str_replace('<', '', $keyword);
+                },
+                $keywords
+            );
+            $keywords = call_user_func($this->keywordsDumper, $keywords, $short);
+            $dump .= <<<GHERKIN
+    {$keywords} {$text}
+
+GHERKIN;
+        } else {
+            foreach ($keywords as $keyword) {
+                if ($excludeAsterisk && '*' === $keyword) {
+                    continue;
+                }
+
+                $indent = ' ';
+                if (false !== mb_strpos($keyword, '<', 0, 'utf8')) {
+                    $keyword = mb_substr($keyword, 0, -1, 'utf8');
+                    $indent = '';
+                }
+                $keyword = call_user_func($this->keywordsDumper, array($keyword), $short);
+                $dump .= <<<GHERKIN
+    {$keyword}{$indent}{$text}
+
+GHERKIN;
+            }
+        }
+
+        return $dump;
+    }
+}
diff --git a/vendor/behat/gherkin/src/Behat/Gherkin/Keywords/KeywordsInterface.php b/vendor/behat/gherkin/src/Behat/Gherkin/Keywords/KeywordsInterface.php
new file mode 100644 (file)
index 0000000..279b1a3
--- /dev/null
@@ -0,0 +1,103 @@
+<?php
+
+/*
+ * This file is part of the Behat Gherkin.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Gherkin\Keywords;
+
+/**
+ * Keywords holder interface.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface KeywordsInterface
+{
+    /**
+     * Sets keywords holder language.
+     *
+     * @param string $language Language name
+     */
+    public function setLanguage($language);
+
+    /**
+     * Returns Feature keywords (splitted by "|").
+     *
+     * @return string
+     */
+    public function getFeatureKeywords();
+
+    /**
+     * Returns Background keywords (splitted by "|").
+     *
+     * @return string
+     */
+    public function getBackgroundKeywords();
+
+    /**
+     * Returns Scenario keywords (splitted by "|").
+     *
+     * @return string
+     */
+    public function getScenarioKeywords();
+
+    /**
+     * Returns Scenario Outline keywords (splitted by "|").
+     *
+     * @return string
+     */
+    public function getOutlineKeywords();
+
+    /**
+     * Returns Examples keywords (splitted by "|").
+     *
+     * @return string
+     */
+    public function getExamplesKeywords();
+
+    /**
+     * Returns Given keywords (splitted by "|").
+     *
+     * @return string
+     */
+    public function getGivenKeywords();
+
+    /**
+     * Returns When keywords (splitted by "|").
+     *
+     * @return string
+     */
+    public function getWhenKeywords();
+
+    /**
+     * Returns Then keywords (splitted by "|").
+     *
+     * @return string
+     */
+    public function getThenKeywords();
+
+    /**
+     * Returns And keywords (splitted by "|").
+     *
+     * @return string
+     */
+    public function getAndKeywords();
+
+    /**
+     * Returns But keywords (splitted by "|").
+     *
+     * @return string
+     */
+    public function getButKeywords();
+
+    /**
+     * Returns all step keywords (splitted by "|").
+     *
+     * @return string
+     */
+    public function getStepKeywords();
+}
diff --git a/vendor/behat/gherkin/src/Behat/Gherkin/Lexer.php b/vendor/behat/gherkin/src/Behat/Gherkin/Lexer.php
new file mode 100644 (file)
index 0000000..446d462
--- /dev/null
@@ -0,0 +1,614 @@
+<?php
+
+/*
+ * This file is part of the Behat Gherkin.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Gherkin;
+
+use Behat\Gherkin\Exception\LexerException;
+use Behat\Gherkin\Keywords\KeywordsInterface;
+
+/**
+ * Gherkin lexer.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class Lexer
+{
+    private $language;
+    private $lines;
+    private $linesCount;
+    private $line;
+    private $trimmedLine;
+    private $lineNumber;
+    private $eos;
+    private $keywords;
+    private $keywordsCache = array();
+    private $stepKeywordTypesCache = array();
+    private $deferredObjects = array();
+    private $deferredObjectsCount = 0;
+    private $stashedToken;
+    private $inPyString = false;
+    private $pyStringSwallow = 0;
+    private $featureStarted = false;
+    private $allowMultilineArguments = false;
+    private $allowSteps = false;
+
+    /**
+     * Initializes lexer.
+     *
+     * @param KeywordsInterface $keywords Keywords holder
+     */
+    public function __construct(KeywordsInterface $keywords)
+    {
+        $this->keywords = $keywords;
+    }
+
+    /**
+     * Sets lexer input.
+     *
+     * @param string $input    Input string
+     * @param string $language Language name
+     *
+     * @throws Exception\LexerException
+     */
+    public function analyse($input, $language = 'en')
+    {
+        // try to detect unsupported encoding
+        if ('UTF-8' !== mb_detect_encoding($input, 'UTF-8', true)) {
+            throw new LexerException('Feature file is not in UTF8 encoding');
+        }
+
+        $input = strtr($input, array("\r\n" => "\n", "\r" => "\n"));
+
+        $this->lines = explode("\n", $input);
+        $this->linesCount = count($this->lines);
+        $this->line = $this->lines[0];
+        $this->lineNumber = 1;
+        $this->trimmedLine = null;
+        $this->eos = false;
+
+        $this->deferredObjects = array();
+        $this->deferredObjectsCount = 0;
+        $this->stashedToken = null;
+        $this->inPyString = false;
+        $this->pyStringSwallow = 0;
+
+        $this->featureStarted = false;
+        $this->allowMultilineArguments = false;
+        $this->allowSteps = false;
+
+        $this->keywords->setLanguage($this->language = $language);
+        $this->keywordsCache = array();
+        $this->stepKeywordTypesCache = array();
+    }
+
+    /**
+     * Returns current lexer language.
+     *
+     * @return string
+     */
+    public function getLanguage()
+    {
+        return $this->language;
+    }
+
+    /**
+     * Returns next token or previously stashed one.
+     *
+     * @return array
+     */
+    public function getAdvancedToken()
+    {
+        return $this->getStashedToken() ?: $this->getNextToken();
+    }
+
+    /**
+     * Defers token.
+     *
+     * @param array $token Token to defer
+     */
+    public function deferToken(array $token)
+    {
+        $token['deferred'] = true;
+        $this->deferredObjects[] = $token;
+        ++$this->deferredObjectsCount;
+    }
+
+    /**
+     * Predicts for number of tokens.
+     *
+     * @return array
+     */
+    public function predictToken()
+    {
+        if (null === $this->stashedToken) {
+            $this->stashedToken = $this->getNextToken();
+        }
+
+        return $this->stashedToken;
+    }
+
+    /**
+     * Constructs token with specified parameters.
+     *
+     * @param string $type  Token type
+     * @param string $value Token value
+     *
+     * @return array
+     */
+    public function takeToken($type, $value = null)
+    {
+        return array(
+            'type'     => $type,
+            'line'     => $this->lineNumber,
+            'value'    => $value ?: null,
+            'deferred' => false
+        );
+    }
+
+    /**
+     * Consumes line from input & increments line counter.
+     */
+    protected function consumeLine()
+    {
+        ++$this->lineNumber;
+
+        if (($this->lineNumber - 1) === $this->linesCount) {
+            $this->eos = true;
+
+            return;
+        }
+
+        $this->line = $this->lines[$this->lineNumber - 1];
+        $this->trimmedLine = null;
+    }
+
+    /**
+     * Returns trimmed version of line.
+     *
+     * @return string
+     */
+    protected function getTrimmedLine()
+    {
+        return null !== $this->trimmedLine ? $this->trimmedLine : $this->trimmedLine = trim($this->line);
+    }
+
+    /**
+     * Returns stashed token or null if hasn't.
+     *
+     * @return array|null
+     */
+    protected function getStashedToken()
+    {
+        $stashedToken = $this->stashedToken;
+        $this->stashedToken = null;
+
+        return $stashedToken;
+    }
+
+    /**
+     * Returns deferred token or null if hasn't.
+     *
+     * @return array|null
+     */
+    protected function getDeferredToken()
+    {
+        if (!$this->deferredObjectsCount) {
+            return null;
+        }
+
+        --$this->deferredObjectsCount;
+
+        return array_shift($this->deferredObjects);
+    }
+
+    /**
+     * Returns next token from input.
+     *
+     * @return array
+     */
+    protected function getNextToken()
+    {
+        return $this->getDeferredToken()
+            ?: $this->scanEOS()
+            ?: $this->scanLanguage()
+            ?: $this->scanComment()
+            ?: $this->scanPyStringOp()
+            ?: $this->scanPyStringContent()
+            ?: $this->scanStep()
+            ?: $this->scanScenario()
+            ?: $this->scanBackground()
+            ?: $this->scanOutline()
+            ?: $this->scanExamples()
+            ?: $this->scanFeature()
+            ?: $this->scanTags()
+            ?: $this->scanTableRow()
+            ?: $this->scanNewline()
+            ?: $this->scanText();
+    }
+
+    /**
+     * Scans for token with specified regex.
+     *
+     * @param string $regex Regular expression
+     * @param string $type  Expected token type
+     *
+     * @return null|array
+     */
+    protected function scanInput($regex, $type)
+    {
+        if (!preg_match($regex, $this->line, $matches)) {
+            return null;
+        }
+
+        $token = $this->takeToken($type, $matches[1]);
+        $this->consumeLine();
+
+        return $token;
+    }
+
+    /**
+     * Scans for token with specified keywords.
+     *
+     * @param string $keywords Keywords (splitted with |)
+     * @param string $type     Expected token type
+     *
+     * @return null|array
+     */
+    protected function scanInputForKeywords($keywords, $type)
+    {
+        if (!preg_match('/^(\s*)(' . $keywords . '):\s*(.*)/u', $this->line, $matches)) {
+            return null;
+        }
+
+        $token = $this->takeToken($type, $matches[3]);
+        $token['keyword'] = $matches[2];
+        $token['indent'] = mb_strlen($matches[1], 'utf8');
+
+        $this->consumeLine();
+
+        // turn off language searching
+        if ('Feature' === $type) {
+            $this->featureStarted = true;
+        }
+
+        // turn off PyString and Table searching
+        if ('Feature' === $type || 'Scenario' === $type || 'Outline' === $type) {
+            $this->allowMultilineArguments = false;
+        } elseif ('Examples' === $type) {
+            $this->allowMultilineArguments = true;
+        }
+
+        // turn on steps searching
+        if ('Scenario' === $type || 'Background' === $type || 'Outline' === $type) {
+            $this->allowSteps = true;
+        }
+
+        return $token;
+    }
+
+    /**
+     * Scans EOS from input & returns it if found.
+     *
+     * @return null|array
+     */
+    protected function scanEOS()
+    {
+        if (!$this->eos) {
+            return null;
+        }
+
+        return $this->takeToken('EOS');
+    }
+
+    /**
+     * Returns keywords for provided type.
+     *
+     * @param string $type Keyword type
+     *
+     * @return string
+     */
+    protected function getKeywords($type)
+    {
+        if (!isset($this->keywordsCache[$type])) {
+            $getter = 'get' . $type . 'Keywords';
+            $keywords = $this->keywords->$getter();
+
+            if ('Step' === $type) {
+                $padded = array();
+                foreach (explode('|', $keywords) as $keyword) {
+                    $padded[] = false !== mb_strpos($keyword, '<', 0, 'utf8')
+                        ? preg_quote(mb_substr($keyword, 0, -1, 'utf8'), '/') . '\s*'
+                        : preg_quote($keyword, '/') . '\s+';
+                }
+
+                $keywords = implode('|', $padded);
+            }
+
+            $this->keywordsCache[$type] = $keywords;
+        }
+
+        return $this->keywordsCache[$type];
+    }
+
+    /**
+     * Scans Feature from input & returns it if found.
+     *
+     * @return null|array
+     */
+    protected function scanFeature()
+    {
+        return $this->scanInputForKeywords($this->getKeywords('Feature'), 'Feature');
+    }
+
+    /**
+     * Scans Background from input & returns it if found.
+     *
+     * @return null|array
+     */
+    protected function scanBackground()
+    {
+        return $this->scanInputForKeywords($this->getKeywords('Background'), 'Background');
+    }
+
+    /**
+     * Scans Scenario from input & returns it if found.
+     *
+     * @return null|array
+     */
+    protected function scanScenario()
+    {
+        return $this->scanInputForKeywords($this->getKeywords('Scenario'), 'Scenario');
+    }
+
+    /**
+     * Scans Scenario Outline from input & returns it if found.
+     *
+     * @return null|array
+     */
+    protected function scanOutline()
+    {
+        return $this->scanInputForKeywords($this->getKeywords('Outline'), 'Outline');
+    }
+
+    /**
+     * Scans Scenario Outline Examples from input & returns it if found.
+     *
+     * @return null|array
+     */
+    protected function scanExamples()
+    {
+        return $this->scanInputForKeywords($this->getKeywords('Examples'), 'Examples');
+    }
+
+    /**
+     * Scans Step from input & returns it if found.
+     *
+     * @return null|array
+     */
+    protected function scanStep()
+    {
+        if (!$this->allowSteps) {
+            return null;
+        }
+
+        $keywords = $this->getKeywords('Step');
+        if (!preg_match('/^\s*(' . $keywords . ')([^\s].+)/u', $this->line, $matches)) {
+            return null;
+        }
+
+        $keyword = trim($matches[1]);
+        $token = $this->takeToken('Step', $keyword);
+        $token['keyword_type'] = $this->getStepKeywordType($keyword);
+        $token['text'] = $matches[2];
+
+        $this->consumeLine();
+        $this->allowMultilineArguments = true;
+
+        return $token;
+    }
+
+    /**
+     * Scans PyString from input & returns it if found.
+     *
+     * @return null|array
+     */
+    protected function scanPyStringOp()
+    {
+        if (!$this->allowMultilineArguments) {
+            return null;
+        }
+
+        if (false === ($pos = mb_strpos($this->line, '"""', 0, 'utf8'))) {
+            return null;
+        }
+
+        $this->inPyString = !$this->inPyString;
+        $token = $this->takeToken('PyStringOp');
+        $this->pyStringSwallow = $pos;
+
+        $this->consumeLine();
+
+        return $token;
+    }
+
+    /**
+     * Scans PyString content.
+     *
+     * @return null|array
+     */
+    protected function scanPyStringContent()
+    {
+        if (!$this->inPyString) {
+            return null;
+        }
+
+        $token = $this->scanText();
+        // swallow trailing spaces
+        $token['value'] = preg_replace('/^\s{0,' . $this->pyStringSwallow . '}/u', '', $token['value']);
+
+        return $token;
+    }
+
+    /**
+     * Scans Table Row from input & returns it if found.
+     *
+     * @return null|array
+     */
+    protected function scanTableRow()
+    {
+        if (!$this->allowMultilineArguments) {
+            return null;
+        }
+
+        $line = $this->getTrimmedLine();
+        if (!isset($line[0]) || '|' !== $line[0] || '|' !== substr($line, -1)) {
+            return null;
+        }
+
+        $token = $this->takeToken('TableRow');
+        $line = mb_substr($line, 1, mb_strlen($line, 'utf8') - 2, 'utf8');
+        $columns = array_map(function ($column) {
+            return trim(str_replace('\\|', '|', $column));
+        }, preg_split('/(?<!\\\)\|/u', $line));
+        $token['columns'] = $columns;
+
+        $this->consumeLine();
+
+        return $token;
+    }
+
+    /**
+     * Scans Tags from input & returns it if found.
+     *
+     * @return null|array
+     */
+    protected function scanTags()
+    {
+        $line = $this->getTrimmedLine();
+        if (!isset($line[0]) || '@' !== $line[0]) {
+            return null;
+        }
+
+        $token = $this->takeToken('Tag');
+        $tags = explode('@', mb_substr($line, 1, mb_strlen($line, 'utf8') - 1, 'utf8'));
+        $tags = array_map('trim', $tags);
+        $token['tags'] = $tags;
+
+        $this->consumeLine();
+
+        return $token;
+    }
+
+    /**
+     * Scans Language specifier from input & returns it if found.
+     *
+     * @return null|array
+     */
+    protected function scanLanguage()
+    {
+        if ($this->featureStarted) {
+            return null;
+        }
+
+        if ($this->inPyString) {
+            return null;
+        }
+
+        if (0 !== mb_strpos(ltrim($this->line), '#', 0, 'utf8')) {
+            return null;
+        }
+
+        return $this->scanInput('/^\s*\#\s*language:\s*([\w_\-]+)\s*$/', 'Language');
+    }
+
+    /**
+     * Scans Comment from input & returns it if found.
+     *
+     * @return null|array
+     */
+    protected function scanComment()
+    {
+        if ($this->inPyString) {
+            return null;
+        }
+
+        $line = $this->getTrimmedLine();
+        if (0 !== mb_strpos($line, '#', 0, 'utf8')) {
+            return null;
+        }
+
+        $token = $this->takeToken('Comment', $line);
+        $this->consumeLine();
+
+        return $token;
+    }
+
+    /**
+     * Scans Newline from input & returns it if found.
+     *
+     * @return null|array
+     */
+    protected function scanNewline()
+    {
+        if ('' !== $this->getTrimmedLine()) {
+            return null;
+        }
+
+        $token = $this->takeToken('Newline', mb_strlen($this->line, 'utf8'));
+        $this->consumeLine();
+
+        return $token;
+    }
+
+    /**
+     * Scans text from input & returns it if found.
+     *
+     * @return null|array
+     */
+    protected function scanText()
+    {
+        $token = $this->takeToken('Text', $this->line);
+        $this->consumeLine();
+
+        return $token;
+    }
+
+    /**
+     * Returns step type keyword (Given, When, Then, etc.).
+     *
+     * @param string $native Step keyword in provided language
+     * @return string
+     */
+    private function getStepKeywordType($native)
+    {
+        // Consider "*" as a AND keyword so that it is normalized to the previous step type
+        if ('*' === $native) {
+            return 'And';
+        }
+
+        if (empty($this->stepKeywordTypesCache)) {
+            $this->stepKeywordTypesCache = array(
+                'Given' => explode('|', $this->keywords->getGivenKeywords()),
+                'When' => explode('|', $this->keywords->getWhenKeywords()),
+                'Then' => explode('|', $this->keywords->getThenKeywords()),
+                'And' => explode('|', $this->keywords->getAndKeywords()),
+                'But' => explode('|', $this->keywords->getButKeywords())
+            );
+        }
+
+        foreach ($this->stepKeywordTypesCache as $type => $keywords) {
+            if (in_array($native, $keywords) || in_array($native . '<', $keywords)) {
+                return $type;
+            }
+        }
+
+        return 'Given';
+    }
+}
diff --git a/vendor/behat/gherkin/src/Behat/Gherkin/Loader/AbstractFileLoader.php b/vendor/behat/gherkin/src/Behat/Gherkin/Loader/AbstractFileLoader.php
new file mode 100644 (file)
index 0000000..20932c1
--- /dev/null
@@ -0,0 +1,72 @@
+<?php
+
+/*
+ * This file is part of the Behat Gherkin.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Gherkin\Loader;
+
+/**
+ * Abstract filesystem loader.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+abstract class AbstractFileLoader implements FileLoaderInterface
+{
+    protected $basePath;
+
+    /**
+     * Sets base features path.
+     *
+     * @param string $path Base loader path
+     */
+    public function setBasePath($path)
+    {
+        $this->basePath = realpath($path);
+    }
+
+    /**
+     * Finds relative path for provided absolute (relative to base features path).
+     *
+     * @param string $path Absolute path
+     *
+     * @return string
+     */
+    protected function findRelativePath($path)
+    {
+        if (null !== $this->basePath) {
+            return strtr($path, array($this->basePath . DIRECTORY_SEPARATOR => ''));
+        }
+
+        return $path;
+    }
+
+    /**
+     * Finds absolute path for provided relative (relative to base features path).
+     *
+     * @param string $path Relative path
+     *
+     * @return string
+     */
+    protected function findAbsolutePath($path)
+    {
+        if (is_file($path) || is_dir($path)) {
+            return realpath($path);
+        }
+
+        if (null === $this->basePath) {
+            return false;
+        }
+
+        if (is_file($this->basePath . DIRECTORY_SEPARATOR . $path)
+               || is_dir($this->basePath . DIRECTORY_SEPARATOR . $path)) {
+            return realpath($this->basePath . DIRECTORY_SEPARATOR . $path);
+        }
+
+        return false;
+    }
+}
diff --git a/vendor/behat/gherkin/src/Behat/Gherkin/Loader/ArrayLoader.php b/vendor/behat/gherkin/src/Behat/Gherkin/Loader/ArrayLoader.php
new file mode 100644 (file)
index 0000000..3492d6e
--- /dev/null
@@ -0,0 +1,269 @@
+<?php
+
+/*
+ * This file is part of the Behat Gherkin.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Gherkin\Loader;
+
+use Behat\Gherkin\Node\BackgroundNode;
+use Behat\Gherkin\Node\ExampleTableNode;
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\OutlineNode;
+use Behat\Gherkin\Node\PyStringNode;
+use Behat\Gherkin\Node\ScenarioNode;
+use Behat\Gherkin\Node\StepNode;
+use Behat\Gherkin\Node\TableNode;
+
+/**
+ * From-array loader.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class ArrayLoader implements LoaderInterface
+{
+    /**
+     * Checks if current loader supports provided resource.
+     *
+     * @param mixed $resource Resource to load
+     *
+     * @return Boolean
+     */
+    public function supports($resource)
+    {
+        return is_array($resource) && (isset($resource['features']) || isset($resource['feature']));
+    }
+
+    /**
+     * Loads features from provided resource.
+     *
+     * @param mixed $resource Resource to load
+     *
+     * @return FeatureNode[]
+     */
+    public function load($resource)
+    {
+        $features = array();
+
+        if (isset($resource['features'])) {
+            foreach ($resource['features'] as $iterator => $hash) {
+                $feature = $this->loadFeatureHash($hash, $iterator);
+                $features[] = $feature;
+            }
+        } elseif (isset($resource['feature'])) {
+            $feature = $this->loadFeatureHash($resource['feature']);
+            $features[] = $feature;
+        }
+
+        return $features;
+    }
+
+    /**
+     * Loads feature from provided feature hash.
+     *
+     * @param array   $hash Feature hash
+     * @param integer $line
+     *
+     * @return FeatureNode
+     */
+    protected function loadFeatureHash(array $hash, $line = 0)
+    {
+        $hash = array_merge(
+            array(
+                'title' => null,
+                'description' => null,
+                'tags' => array(),
+                'keyword' => 'Feature',
+                'language' => 'en',
+                'line' => $line,
+                'scenarios' => array(),
+            ),
+            $hash
+        );
+        $background = isset($hash['background']) ? $this->loadBackgroundHash($hash['background']) : null;
+
+        $scenarios = array();
+        foreach ((array) $hash['scenarios'] as $scenarioIterator => $scenarioHash) {
+            if (isset($scenarioHash['type']) && 'outline' === $scenarioHash['type']) {
+                $scenarios[] = $this->loadOutlineHash($scenarioHash, $scenarioIterator);
+            } else {
+                $scenarios[] = $this->loadScenarioHash($scenarioHash, $scenarioIterator);
+            }
+        }
+
+        return new FeatureNode($hash['title'], $hash['description'], $hash['tags'], $background, $scenarios, $hash['keyword'], $hash['language'], null, $hash['line']);
+    }
+
+    /**
+     * Loads background from provided hash.
+     *
+     * @param array $hash Background hash
+     *
+     * @return BackgroundNode
+     */
+    protected function loadBackgroundHash(array $hash)
+    {
+        $hash = array_merge(
+            array(
+                'title' => null,
+                'keyword' => 'Background',
+                'line' => 0,
+                'steps' => array(),
+            ),
+            $hash
+        );
+
+        $steps = $this->loadStepsHash($hash['steps']);
+
+        return new BackgroundNode($hash['title'], $steps, $hash['keyword'], $hash['line']);
+    }
+
+    /**
+     * Loads scenario from provided scenario hash.
+     *
+     * @param array   $hash Scenario hash
+     * @param integer $line Scenario definition line
+     *
+     * @return ScenarioNode
+     */
+    protected function loadScenarioHash(array $hash, $line = 0)
+    {
+        $hash = array_merge(
+            array(
+                'title' => null,
+                'tags' => array(),
+                'keyword' => 'Scenario',
+                'line' => $line,
+                'steps' => array(),
+            ),
+            $hash
+        );
+
+        $steps = $this->loadStepsHash($hash['steps']);
+
+        return new ScenarioNode($hash['title'], $hash['tags'], $steps, $hash['keyword'], $hash['line']);
+    }
+
+    /**
+     * Loads outline from provided outline hash.
+     *
+     * @param array   $hash Outline hash
+     * @param integer $line Outline definition line
+     *
+     * @return OutlineNode
+     */
+    protected function loadOutlineHash(array $hash, $line = 0)
+    {
+        $hash = array_merge(
+            array(
+                'title' => null,
+                'tags' => array(),
+                'keyword' => 'Scenario Outline',
+                'line' => $line,
+                'steps' => array(),
+                'examples' => array(),
+            ),
+            $hash
+        );
+
+        $steps = $this->loadStepsHash($hash['steps']);
+
+        if (isset($hash['examples']['keyword'])) {
+            $examplesKeyword = $hash['examples']['keyword'];
+            unset($hash['examples']['keyword']);
+        } else {
+            $examplesKeyword = 'Examples';
+        }
+
+        $examples = new ExampleTableNode($hash['examples'], $examplesKeyword);
+
+        return new OutlineNode($hash['title'], $hash['tags'], $steps, $examples, $hash['keyword'], $hash['line']);
+    }
+
+    /**
+     * Loads steps from provided hash.
+     *
+     * @param array $hash
+     *
+     * @return StepNode[]
+     */
+    private function loadStepsHash(array $hash)
+    {
+        $steps = array();
+        foreach ($hash as $stepIterator => $stepHash) {
+            $steps[] = $this->loadStepHash($stepHash, $stepIterator);
+        }
+
+        return $steps;
+    }
+
+    /**
+     * Loads step from provided hash.
+     *
+     * @param array   $hash Step hash
+     * @param integer $line Step definition line
+     *
+     * @return StepNode
+     */
+    protected function loadStepHash(array $hash, $line = 0)
+    {
+        $hash = array_merge(
+            array(
+                'keyword_type' => 'Given',
+                'type' => 'Given',
+                'text' => null,
+                'keyword' => 'Scenario',
+                'line' => $line,
+                'arguments' => array(),
+            ),
+            $hash
+        );
+
+        $arguments = array();
+        foreach ($hash['arguments'] as $argumentHash) {
+            if ('table' === $argumentHash['type']) {
+                $arguments[] = $this->loadTableHash($argumentHash['rows']);
+            } elseif ('pystring' === $argumentHash['type']) {
+                $arguments[] = $this->loadPyStringHash($argumentHash, $hash['line'] + 1);
+            }
+        }
+
+        return new StepNode($hash['type'], $hash['text'], $arguments, $hash['line'], $hash['keyword_type']);
+    }
+
+    /**
+     * Loads table from provided hash.
+     *
+     * @param array $hash Table hash
+     *
+     * @return TableNode
+     */
+    protected function loadTableHash(array $hash)
+    {
+        return new TableNode($hash);
+    }
+
+    /**
+     * Loads PyString from provided hash.
+     *
+     * @param array   $hash PyString hash
+     * @param integer $line
+     *
+     * @return PyStringNode
+     */
+    protected function loadPyStringHash(array $hash, $line = 0)
+    {
+        $line = isset($hash['line']) ? $hash['line'] : $line;
+
+        $strings = array();
+        foreach (explode("\n", $hash['text']) as $string) {
+            $strings[] = $string;
+        }
+
+        return new PyStringNode($strings, $line);
+    }
+}
diff --git a/vendor/behat/gherkin/src/Behat/Gherkin/Loader/DirectoryLoader.php b/vendor/behat/gherkin/src/Behat/Gherkin/Loader/DirectoryLoader.php
new file mode 100644 (file)
index 0000000..dcde0e6
--- /dev/null
@@ -0,0 +1,80 @@
+<?php
+
+/*
+ * This file is part of the Behat Gherkin.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Gherkin\Loader;
+
+use Behat\Gherkin\Gherkin;
+use Behat\Gherkin\Node\FeatureNode;
+use RecursiveDirectoryIterator;
+use RecursiveIteratorIterator;
+
+/**
+ * Directory contents loader.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class DirectoryLoader extends AbstractFileLoader
+{
+    protected $gherkin;
+
+    /**
+     * Initializes loader.
+     *
+     * @param Gherkin $gherkin Gherkin manager
+     */
+    public function __construct(Gherkin $gherkin)
+    {
+        $this->gherkin = $gherkin;
+    }
+
+    /**
+     * Checks if current loader supports provided resource.
+     *
+     * @param mixed $path Resource to load
+     *
+     * @return Boolean
+     */
+    public function supports($path)
+    {
+        return is_string($path)
+        && is_dir($this->findAbsolutePath($path));
+    }
+
+    /**
+     * Loads features from provided resource.
+     *
+     * @param string $path Resource to load
+     *
+     * @return FeatureNode[]
+     */
+    public function load($path)
+    {
+        $path = $this->findAbsolutePath($path);
+
+        $iterator = new RecursiveIteratorIterator(
+            new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::SKIP_DOTS)
+        );
+        $paths = array_map('strval', iterator_to_array($iterator));
+        uasort($paths, 'strnatcasecmp');
+
+        $features = array();
+
+        foreach ($paths as $path) {
+            $path = (string) $path;
+            $loader = $this->gherkin->resolveLoader($path);
+
+            if (null !== $loader) {
+                $features = array_merge($features, $loader->load($path));
+            }
+        }
+
+        return $features;
+    }
+}
diff --git a/vendor/behat/gherkin/src/Behat/Gherkin/Loader/FileLoaderInterface.php b/vendor/behat/gherkin/src/Behat/Gherkin/Loader/FileLoaderInterface.php
new file mode 100644 (file)
index 0000000..f18f19a
--- /dev/null
@@ -0,0 +1,26 @@
+<?php
+
+/*
+ * This file is part of the Behat Gherkin.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Gherkin\Loader;
+
+/**
+ * File Loader interface.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface FileLoaderInterface extends LoaderInterface
+{
+    /**
+     * Sets base features path.
+     *
+     * @param string $path Base loader path
+     */
+    public function setBasePath($path);
+}
diff --git a/vendor/behat/gherkin/src/Behat/Gherkin/Loader/GherkinFileLoader.php b/vendor/behat/gherkin/src/Behat/Gherkin/Loader/GherkinFileLoader.php
new file mode 100644 (file)
index 0000000..ae8bf99
--- /dev/null
@@ -0,0 +1,102 @@
+<?php
+
+/*
+ * This file is part of the Behat Gherkin.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Gherkin\Loader;
+
+use Behat\Gherkin\Cache\CacheInterface;
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Parser;
+
+/**
+ * Gherkin *.feature files loader.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class GherkinFileLoader extends AbstractFileLoader
+{
+    protected $parser;
+    protected $cache;
+
+    /**
+     * Initializes loader.
+     *
+     * @param Parser         $parser Parser
+     * @param CacheInterface $cache  Cache layer
+     */
+    public function __construct(Parser $parser, CacheInterface $cache = null)
+    {
+        $this->parser = $parser;
+        $this->cache = $cache;
+    }
+
+    /**
+     * Sets cache layer.
+     *
+     * @param CacheInterface $cache Cache layer
+     */
+    public function setCache(CacheInterface $cache)
+    {
+        $this->cache = $cache;
+    }
+
+    /**
+     * Checks if current loader supports provided resource.
+     *
+     * @param mixed $path Resource to load
+     *
+     * @return Boolean
+     */
+    public function supports($path)
+    {
+        return is_string($path)
+        && is_file($absolute = $this->findAbsolutePath($path))
+        && 'feature' === pathinfo($absolute, PATHINFO_EXTENSION);
+    }
+
+    /**
+     * Loads features from provided resource.
+     *
+     * @param string $path Resource to load
+     *
+     * @return FeatureNode[]
+     */
+    public function load($path)
+    {
+        $path = $this->findAbsolutePath($path);
+
+        if ($this->cache) {
+            if ($this->cache->isFresh($path, filemtime($path))) {
+                $feature = $this->cache->read($path);
+            } elseif (null !== $feature = $this->parseFeature($path)) {
+                $this->cache->write($path, $feature);
+            }
+        } else {
+            $feature = $this->parseFeature($path);
+        }
+
+        return null !== $feature ? array($feature) : array();
+    }
+
+    /**
+     * Parses feature at provided absolute path.
+     *
+     * @param string $path Feature path
+     *
+     * @return FeatureNode
+     */
+    protected function parseFeature($path)
+    {
+        $filename = $this->findRelativePath($path);
+        $content = file_get_contents($path);
+        $feature = $this->parser->parse($content, $filename);
+
+        return $feature;
+    }
+}
diff --git a/vendor/behat/gherkin/src/Behat/Gherkin/Loader/LoaderInterface.php b/vendor/behat/gherkin/src/Behat/Gherkin/Loader/LoaderInterface.php
new file mode 100644 (file)
index 0000000..861332c
--- /dev/null
@@ -0,0 +1,39 @@
+<?php
+
+/*
+ * This file is part of the Behat Gherkin.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Gherkin\Loader;
+
+use Behat\Gherkin\Node\FeatureNode;
+
+/**
+ * Loader interface.
+ *
+ * @author      Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface LoaderInterface
+{
+    /**
+     * Checks if current loader supports provided resource.
+     *
+     * @param mixed $resource Resource to load
+     *
+     * @return Boolean
+     */
+    public function supports($resource);
+
+    /**
+     * Loads features from provided resource.
+     *
+     * @param mixed $resource Resource to load
+     *
+     * @return FeatureNode[]
+     */
+    public function load($resource);
+}
diff --git a/vendor/behat/gherkin/src/Behat/Gherkin/Loader/YamlFileLoader.php b/vendor/behat/gherkin/src/Behat/Gherkin/Loader/YamlFileLoader.php
new file mode 100644 (file)
index 0000000..0c268fd
--- /dev/null
@@ -0,0 +1,73 @@
+<?php
+
+/*
+ * This file is part of the Behat Gherkin.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Gherkin\Loader;
+
+use Behat\Gherkin\Node\FeatureNode;
+use Symfony\Component\Yaml\Yaml;
+
+/**
+ * Yaml files loader.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class YamlFileLoader extends AbstractFileLoader
+{
+    private $loader;
+
+    public function __construct()
+    {
+        $this->loader = new ArrayLoader();
+    }
+
+    /**
+     * Checks if current loader supports provided resource.
+     *
+     * @param mixed $path Resource to load
+     *
+     * @return Boolean
+     */
+    public function supports($path)
+    {
+        return is_string($path)
+            && is_file($absolute = $this->findAbsolutePath($path))
+            && 'yml' === pathinfo($absolute, PATHINFO_EXTENSION);
+    }
+
+    /**
+     * Loads features from provided resource.
+     *
+     * @param string $path Resource to load
+     *
+     * @return FeatureNode[]
+     */
+    public function load($path)
+    {
+        $path = $this->findAbsolutePath($path);
+        $hash = Yaml::parse(file_get_contents($path));
+
+        $features = $this->loader->load($hash);
+        $filename = $this->findRelativePath($path);
+
+        return array_map(function (FeatureNode $feature) use ($filename) {
+            return new FeatureNode(
+                $feature->getTitle(),
+                $feature->getDescription(),
+                $feature->getTags(),
+                $feature->getBackground(),
+                $feature->getScenarios(),
+                $feature->getKeyword(),
+                $feature->getLanguage(),
+                $filename,
+                $feature->getLine()
+            );
+        }, $features);
+    }
+}
diff --git a/vendor/behat/gherkin/src/Behat/Gherkin/Node/ArgumentInterface.php b/vendor/behat/gherkin/src/Behat/Gherkin/Node/ArgumentInterface.php
new file mode 100644 (file)
index 0000000..4457f18
--- /dev/null
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ * This file is part of the Behat Gherkin.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Gherkin\Node;
+
+/**
+ * Gherkin arguments interface.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface ArgumentInterface extends NodeInterface
+{
+}
diff --git a/vendor/behat/gherkin/src/Behat/Gherkin/Node/BackgroundNode.php b/vendor/behat/gherkin/src/Behat/Gherkin/Node/BackgroundNode.php
new file mode 100644 (file)
index 0000000..fb1edb4
--- /dev/null
@@ -0,0 +1,112 @@
+<?php
+
+/*
+ * This file is part of the Behat Gherkin.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Gherkin\Node;
+
+/**
+ * Represents Gherkin Background.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class BackgroundNode implements ScenarioLikeInterface
+{
+    /**
+     * @var string
+     */
+    private $title;
+    /**
+     * @var StepNode[]
+     */
+    private $steps = array();
+    /**
+     * @var string
+     */
+    private $keyword;
+    /**
+     * @var integer
+     */
+    private $line;
+
+    /**
+     * Initializes background.
+     *
+     * @param null|string $title
+     * @param StepNode[]  $steps
+     * @param string      $keyword
+     * @param integer     $line
+     */
+    public function __construct($title, array $steps, $keyword, $line)
+    {
+        $this->title = $title;
+        $this->steps = $steps;
+        $this->keyword = $keyword;
+        $this->line = $line;
+    }
+
+    /**
+     * Returns node type string
+     *
+     * @return string
+     */
+    public function getNodeType()
+    {
+        return 'Background';
+    }
+
+    /**
+     * Returns background title.
+     *
+     * @return null|string
+     */
+    public function getTitle()
+    {
+        return $this->title;
+    }
+
+    /**
+     * Checks if background has steps.
+     *
+     * @return Boolean
+     */
+    public function hasSteps()
+    {
+        return 0 < count($this->steps);
+    }
+
+    /**
+     * Returns background steps.
+     *
+     * @return StepNode[]
+     */
+    public function getSteps()
+    {
+        return $this->steps;
+    }
+
+    /**
+     * Returns background keyword.
+     *
+     * @return string
+     */
+    public function getKeyword()
+    {
+        return $this->keyword;
+    }
+
+    /**
+     * Returns background declaration line number.
+     *
+     * @return integer
+     */
+    public function getLine()
+    {
+        return $this->line;
+    }
+}
diff --git a/vendor/behat/gherkin/src/Behat/Gherkin/Node/ExampleNode.php b/vendor/behat/gherkin/src/Behat/Gherkin/Node/ExampleNode.php
new file mode 100644 (file)
index 0000000..d3366b9
--- /dev/null
@@ -0,0 +1,274 @@
+<?php
+
+/*
+ * This file is part of the Behat Gherkin.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Gherkin\Node;
+
+/**
+ * Represents Gherkin Outline Example.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class ExampleNode implements ScenarioInterface
+{
+    /**
+     * @var string
+     */
+    private $title;
+    /**
+     * @var string[]
+     */
+    private $tags;
+    /**
+     * @var StepNode[]
+     */
+    private $outlineSteps;
+    /**
+     * @var string[]
+     */
+    private $tokens;
+    /**
+     * @var integer
+     */
+    private $line;
+    /**
+     * @var null|StepNode[]
+     */
+    private $steps;
+    /**
+     * @var string
+     */
+    private $outlineTitle;
+
+    /**
+     * Initializes outline.
+     *
+     * @param string      $title
+     * @param string[]    $tags
+     * @param StepNode[]  $outlineSteps
+     * @param string[]    $tokens
+     * @param integer     $line
+     * @param string|null $outlineTitle
+     */
+    public function __construct($title, array $tags, $outlineSteps, array $tokens, $line, $outlineTitle = null)
+    {
+        $this->title = $title;
+        $this->tags = $tags;
+        $this->outlineSteps = $outlineSteps;
+        $this->tokens = $tokens;
+        $this->line = $line;
+        $this->outlineTitle = $outlineTitle;
+    }
+
+    /**
+     * Returns node type string
+     *
+     * @return string
+     */
+    public function getNodeType()
+    {
+        return 'Example';
+    }
+
+    /**
+     * Returns node keyword.
+     *
+     * @return string
+     */
+    public function getKeyword()
+    {
+        return $this->getNodeType();
+    }
+
+    /**
+     * Returns example title.
+     *
+     * @return string
+     */
+    public function getTitle()
+    {
+        return $this->title;
+    }
+
+    /**
+     * Checks if outline is tagged with tag.
+     *
+     * @param string $tag
+     *
+     * @return Boolean
+     */
+    public function hasTag($tag)
+    {
+        return in_array($tag, $this->getTags());
+    }
+
+    /**
+     * Checks if outline has tags (both inherited from feature and own).
+     *
+     * @return Boolean
+     */
+    public function hasTags()
+    {
+        return 0 < count($this->getTags());
+    }
+
+    /**
+     * Returns outline tags (including inherited from feature).
+     *
+     * @return string[]
+     */
+    public function getTags()
+    {
+        return $this->tags;
+    }
+
+    /**
+     * Checks if outline has steps.
+     *
+     * @return Boolean
+     */
+    public function hasSteps()
+    {
+        return 0 < count($this->outlineSteps);
+    }
+
+    /**
+     * Returns outline steps.
+     *
+     * @return StepNode[]
+     */
+    public function getSteps()
+    {
+        return $this->steps = $this->steps ? : $this->createExampleSteps();
+    }
+
+    /**
+     * Returns example tokens.
+     *
+     * @return string[]
+     */
+    public function getTokens()
+    {
+        return $this->tokens;
+    }
+
+    /**
+     * Returns outline declaration line number.
+     *
+     * @return integer
+     */
+    public function getLine()
+    {
+        return $this->line;
+    }
+
+    /**
+     * Returns outline title.
+     *
+     * @return string
+     */
+    public function getOutlineTitle()
+    {
+        return $this->outlineTitle;
+    }
+
+    /**
+     * Creates steps for this example from abstract outline steps.
+     *
+     * @return StepNode[]
+     */
+    protected function createExampleSteps()
+    {
+        $steps = array();
+        foreach ($this->outlineSteps as $outlineStep) {
+            $keyword = $outlineStep->getKeyword();
+            $keywordType = $outlineStep->getKeywordType();
+            $text = $this->replaceTextTokens($outlineStep->getText());
+            $args = $this->replaceArgumentsTokens($outlineStep->getArguments());
+            $line = $outlineStep->getLine();
+
+            $steps[] = new StepNode($keyword, $text, $args, $line, $keywordType);
+        }
+
+        return $steps;
+    }
+
+    /**
+     * Replaces tokens in arguments with row values.
+     *
+     * @param ArgumentInterface[] $arguments
+     *
+     * @return ArgumentInterface[]
+     */
+    protected function replaceArgumentsTokens(array $arguments)
+    {
+        foreach ($arguments as $num => $argument) {
+            if ($argument instanceof TableNode) {
+                $arguments[$num] = $this->replaceTableArgumentTokens($argument);
+            }
+            if ($argument instanceof PyStringNode) {
+                $arguments[$num] = $this->replacePyStringArgumentTokens($argument);
+            }
+        }
+
+        return $arguments;
+    }
+
+    /**
+     * Replaces tokens in table with row values.
+     *
+     * @param TableNode $argument
+     *
+     * @return TableNode
+     */
+    protected function replaceTableArgumentTokens(TableNode $argument)
+    {
+        $table = $argument->getTable();
+        foreach ($table as $line => $row) {
+            foreach (array_keys($row) as $col) {
+                $table[$line][$col] = $this->replaceTextTokens($table[$line][$col]);
+            }
+        }
+
+        return new TableNode($table);
+    }
+
+    /**
+     * Replaces tokens in PyString with row values.
+     *
+     * @param PyStringNode $argument
+     *
+     * @return PyStringNode
+     */
+    protected function replacePyStringArgumentTokens(PyStringNode $argument)
+    {
+        $strings = $argument->getStrings();
+        foreach ($strings as $line => $string) {
+            $strings[$line] = $this->replaceTextTokens($strings[$line]);
+        }
+
+        return new PyStringNode($strings, $argument->getLine());
+    }
+
+    /**
+     * Replaces tokens in text with row values.
+     *
+     * @param string $text
+     *
+     * @return string
+     */
+    protected function replaceTextTokens($text)
+    {
+        foreach ($this->tokens as $key => $val) {
+            $text = str_replace('<' . $key . '>', $val, $text);
+        }
+
+        return $text;
+    }
+}
diff --git a/vendor/behat/gherkin/src/Behat/Gherkin/Node/ExampleTableNode.php b/vendor/behat/gherkin/src/Behat/Gherkin/Node/ExampleTableNode.php
new file mode 100644 (file)
index 0000000..805e659
--- /dev/null
@@ -0,0 +1,57 @@
+<?php
+
+/*
+ * This file is part of the Behat Gherkin.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Gherkin\Node;
+
+/**
+ * Represents Gherkin Outline Example Table.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class ExampleTableNode extends TableNode
+{
+    /**
+     * @var string
+     */
+    private $keyword;
+
+    /**
+     * Initializes example table.
+     *
+     * @param array  $table   Table in form of [$rowLineNumber => [$val1, $val2, $val3]]
+     * @param string $keyword
+     */
+    public function __construct(array $table, $keyword)
+    {
+        $this->keyword = $keyword;
+
+        parent::__construct($table);
+    }
+
+    /**
+     * Returns node type string
+     *
+     * @return string
+     */
+    public function getNodeType()
+    {
+        return 'ExampleTable';
+    }
+
+    /**
+     * Returns example table keyword.
+     *
+     * @return string
+     */
+    public function getKeyword()
+    {
+        return $this->keyword;
+    }
+}
diff --git a/vendor/behat/gherkin/src/Behat/Gherkin/Node/FeatureNode.php b/vendor/behat/gherkin/src/Behat/Gherkin/Node/FeatureNode.php
new file mode 100644 (file)
index 0000000..6413659
--- /dev/null
@@ -0,0 +1,243 @@
+<?php
+
+/*
+ * This file is part of the Behat Gherkin.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Gherkin\Node;
+
+/**
+ * Represents Gherkin Feature.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class FeatureNode implements KeywordNodeInterface, TaggedNodeInterface
+{
+    /**
+     * @var null|string
+     */
+    private $title;
+    /**
+     * @var null|string
+     */
+    private $description;
+    /**
+     * @var string[]
+     */
+    private $tags = array();
+    /**
+     * @var null|BackgroundNode
+     */
+    private $background;
+    /**
+     * @var ScenarioInterface[]
+     */
+    private $scenarios = array();
+    /**
+     * @var string
+     */
+    private $keyword;
+    /**
+     * @var string
+     */
+    private $language;
+    /**
+     * @var null|string
+     */
+    private $file;
+    /**
+     * @var integer
+     */
+    private $line;
+
+    /**
+     * Initializes feature.
+     *
+     * @param null|string         $title
+     * @param null|string         $description
+     * @param string[]            $tags
+     * @param null|BackgroundNode $background
+     * @param ScenarioInterface[] $scenarios
+     * @param string              $keyword
+     * @param string              $language
+     * @param null|string         $file
+     * @param integer             $line
+     */
+    public function __construct(
+        $title,
+        $description,
+        array $tags,
+        BackgroundNode $background = null,
+        array $scenarios,
+        $keyword,
+        $language,
+        $file,
+        $line
+    ) {
+        $this->title = $title;
+        $this->description = $description;
+        $this->tags = $tags;
+        $this->background = $background;
+        $this->scenarios = $scenarios;
+        $this->keyword = $keyword;
+        $this->language = $language;
+        $this->file = $file;
+        $this->line = $line;
+    }
+
+    /**
+     * Returns node type string
+     *
+     * @return string
+     */
+    public function getNodeType()
+    {
+        return 'Feature';
+    }
+
+    /**
+     * Returns feature title.
+     *
+     * @return null|string
+     */
+    public function getTitle()
+    {
+        return $this->title;
+    }
+
+    /**
+     * Checks if feature has a description.
+     *
+     * @return Boolean
+     */
+    public function hasDescription()
+    {
+        return !empty($this->description);
+    }
+
+    /**
+     * Returns feature description.
+     *
+     * @return null|string
+     */
+    public function getDescription()
+    {
+        return $this->description;
+    }
+
+    /**
+     * Checks if feature is tagged with tag.
+     *
+     * @param string $tag
+     *
+     * @return Boolean
+     */
+    public function hasTag($tag)
+    {
+        return in_array($tag, $this->tags);
+    }
+
+    /**
+     * Checks if feature has tags.
+     *
+     * @return Boolean
+     */
+    public function hasTags()
+    {
+        return 0 < count($this->tags);
+    }
+
+    /**
+     * Returns feature tags.
+     *
+     * @return string[]
+     */
+    public function getTags()
+    {
+        return $this->tags;
+    }
+
+    /**
+     * Checks if feature has background.
+     *
+     * @return Boolean
+     */
+    public function hasBackground()
+    {
+        return null !== $this->background;
+    }
+
+    /**
+     * Returns feature background.
+     *
+     * @return null|BackgroundNode
+     */
+    public function getBackground()
+    {
+        return $this->background;
+    }
+
+    /**
+     * Checks if feature has scenarios.
+     *
+     * @return Boolean
+     */
+    public function hasScenarios()
+    {
+        return 0 < count($this->scenarios);
+    }
+
+    /**
+     * Returns feature scenarios.
+     *
+     * @return ScenarioInterface[]
+     */
+    public function getScenarios()
+    {
+        return $this->scenarios;
+    }
+
+    /**
+     * Returns feature keyword.
+     *
+     * @return string
+     */
+    public function getKeyword()
+    {
+        return $this->keyword;
+    }
+
+    /**
+     * Returns feature language.
+     *
+     * @return string
+     */
+    public function getLanguage()
+    {
+        return $this->language;
+    }
+
+    /**
+     * Returns feature file.
+     *
+     * @return null|string
+     */
+    public function getFile()
+    {
+        return $this->file;
+    }
+
+    /**
+     * Returns feature declaration line number.
+     *
+     * @return integer
+     */
+    public function getLine()
+    {
+        return $this->line;
+    }
+}
diff --git a/vendor/behat/gherkin/src/Behat/Gherkin/Node/KeywordNodeInterface.php b/vendor/behat/gherkin/src/Behat/Gherkin/Node/KeywordNodeInterface.php
new file mode 100644 (file)
index 0000000..e6e412f
--- /dev/null
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ * This file is part of the Behat Gherkin.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Gherkin\Node;
+
+/**
+ * Gherkin keyword node interface.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface KeywordNodeInterface extends NodeInterface
+{
+    /**
+     * Returns node keyword.
+     *
+     * @return string
+     */
+    public function getKeyword();
+
+    /**
+     * Returns node title.
+     *
+     * @return null|string
+     */
+    public function getTitle();
+}
diff --git a/vendor/behat/gherkin/src/Behat/Gherkin/Node/NodeInterface.php b/vendor/behat/gherkin/src/Behat/Gherkin/Node/NodeInterface.php
new file mode 100644 (file)
index 0000000..eabe61a
--- /dev/null
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ * This file is part of the Behat Gherkin.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Gherkin\Node;
+
+/**
+ * Gherkin node interface.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface NodeInterface
+{
+    /**
+     * Returns node type string
+     *
+     * @return string
+     */
+    public function getNodeType();
+
+    /**
+     * Returns feature declaration line number.
+     *
+     * @return integer
+     */
+    public function getLine();
+}
diff --git a/vendor/behat/gherkin/src/Behat/Gherkin/Node/OutlineNode.php b/vendor/behat/gherkin/src/Behat/Gherkin/Node/OutlineNode.php
new file mode 100644 (file)
index 0000000..62f5518
--- /dev/null
@@ -0,0 +1,218 @@
+<?php
+
+/*
+ * This file is part of the Behat Gherkin.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Gherkin\Node;
+
+/**
+ * Represents Gherkin Outline.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class OutlineNode implements ScenarioInterface
+{
+    /**
+     * @var string
+     */
+    private $title;
+    /**
+     * @var string[]
+     */
+    private $tags;
+    /**
+     * @var StepNode[]
+     */
+    private $steps;
+    /**
+     * @var ExampleTableNode
+     */
+    private $table;
+    /**
+     * @var string
+     */
+    private $keyword;
+    /**
+     * @var integer
+     */
+    private $line;
+    /**
+     * @var null|ExampleNode[]
+     */
+    private $examples;
+
+    /**
+     * Initializes outline.
+     *
+     * @param null|string      $title
+     * @param string[]         $tags
+     * @param StepNode[]       $steps
+     * @param ExampleTableNode $table
+     * @param string           $keyword
+     * @param integer          $line
+     */
+    public function __construct(
+        $title,
+        array $tags,
+        array $steps,
+        ExampleTableNode $table,
+        $keyword,
+        $line
+    ) {
+        $this->title = $title;
+        $this->tags = $tags;
+        $this->steps = $steps;
+        $this->table = $table;
+        $this->keyword = $keyword;
+        $this->line = $line;
+    }
+
+    /**
+     * Returns node type string
+     *
+     * @return string
+     */
+    public function getNodeType()
+    {
+        return 'Outline';
+    }
+
+    /**
+     * Returns outline title.
+     *
+     * @return null|string
+     */
+    public function getTitle()
+    {
+        return $this->title;
+    }
+
+    /**
+     * Checks if outline is tagged with tag.
+     *
+     * @param string $tag
+     *
+     * @return Boolean
+     */
+    public function hasTag($tag)
+    {
+        return in_array($tag, $this->getTags());
+    }
+
+    /**
+     * Checks if outline has tags (both inherited from feature and own).
+     *
+     * @return Boolean
+     */
+    public function hasTags()
+    {
+        return 0 < count($this->getTags());
+    }
+
+    /**
+     * Returns outline tags (including inherited from feature).
+     *
+     * @return string[]
+     */
+    public function getTags()
+    {
+        return $this->tags;
+    }
+
+    /**
+     * Checks if outline has steps.
+     *
+     * @return Boolean
+     */
+    public function hasSteps()
+    {
+        return 0 < count($this->steps);
+    }
+
+    /**
+     * Returns outline steps.
+     *
+     * @return StepNode[]
+     */
+    public function getSteps()
+    {
+        return $this->steps;
+    }
+
+    /**
+     * Checks if outline has examples.
+     *
+     * @return Boolean
+     */
+    public function hasExamples()
+    {
+        return 0 < count($this->table->getColumnsHash());
+    }
+
+    /**
+     * Returns examples table.
+     *
+     * @return ExampleTableNode
+     */
+    public function getExampleTable()
+    {
+        return $this->table;
+    }
+
+    /**
+     * Returns list of examples for the outline.
+     *
+     * @return ExampleNode[]
+     */
+    public function getExamples()
+    {
+        return $this->examples = $this->examples ? : $this->createExamples();
+    }
+
+    /**
+     * Returns outline keyword.
+     *
+     * @return string
+     */
+    public function getKeyword()
+    {
+        return $this->keyword;
+    }
+
+    /**
+     * Returns outline declaration line number.
+     *
+     * @return integer
+     */
+    public function getLine()
+    {
+        return $this->line;
+    }
+
+    /**
+     * Creates examples for this outline using examples table.
+     *
+     * @return ExampleNode[]
+     */
+    protected function createExamples()
+    {
+        $examples = array();
+        foreach ($this->table->getColumnsHash() as $rowNum => $row) {
+            $examples[] = new ExampleNode(
+                $this->table->getRowAsString($rowNum + 1),
+                $this->tags,
+                $this->getSteps(),
+                $row,
+                $this->table->getRowLine($rowNum + 1),
+                $this->getTitle()
+            );
+        }
+
+        return $examples;
+    }
+}
diff --git a/vendor/behat/gherkin/src/Behat/Gherkin/Node/PyStringNode.php b/vendor/behat/gherkin/src/Behat/Gherkin/Node/PyStringNode.php
new file mode 100644 (file)
index 0000000..f0e8948
--- /dev/null
@@ -0,0 +1,90 @@
+<?php
+
+/*
+ * This file is part of the Behat Gherkin.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Gherkin\Node;
+
+/**
+ * Represents Gherkin PyString argument.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class PyStringNode implements ArgumentInterface
+{
+    /**
+     * @var array
+     */
+    private $strings = array();
+    /**
+     * @var integer
+     */
+    private $line;
+
+    /**
+     * Initializes PyString.
+     *
+     * @param array   $strings String in form of [$stringLine]
+     * @param integer $line    Line number where string been started
+     */
+    public function __construct(array $strings, $line)
+    {
+        $this->strings = $strings;
+        $this->line = $line;
+    }
+
+    /**
+     * Returns node type.
+     *
+     * @return string
+     */
+    public function getNodeType()
+    {
+        return 'PyString';
+    }
+
+    /**
+     * Returns entire PyString lines set.
+     *
+     * @return array
+     */
+    public function getStrings()
+    {
+        return $this->strings;
+    }
+
+    /**
+     * Returns raw string.
+     *
+     * @return string
+     */
+    public function getRaw()
+    {
+        return implode("\n", $this->strings);
+    }
+
+    /**
+     * Converts PyString into string.
+     *
+     * @return string
+     */
+    public function __toString()
+    {
+        return $this->getRaw();
+    }
+
+    /**
+     * Returns line number at which PyString was started.
+     *
+     * @return integer
+     */
+    public function getLine()
+    {
+        return $this->line;
+    }
+}
diff --git a/vendor/behat/gherkin/src/Behat/Gherkin/Node/ScenarioInterface.php b/vendor/behat/gherkin/src/Behat/Gherkin/Node/ScenarioInterface.php
new file mode 100644 (file)
index 0000000..fb29843
--- /dev/null
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ * This file is part of the Behat Gherkin.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Gherkin\Node;
+
+/**
+ * Gherkin scenario interface.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface ScenarioInterface extends ScenarioLikeInterface, TaggedNodeInterface
+{
+}
diff --git a/vendor/behat/gherkin/src/Behat/Gherkin/Node/ScenarioLikeInterface.php b/vendor/behat/gherkin/src/Behat/Gherkin/Node/ScenarioLikeInterface.php
new file mode 100644 (file)
index 0000000..88f7934
--- /dev/null
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ * This file is part of the Behat Gherkin.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Gherkin\Node;
+
+/**
+ * Gherkin scenario-like interface.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface ScenarioLikeInterface extends KeywordNodeInterface, StepContainerInterface
+{
+}
diff --git a/vendor/behat/gherkin/src/Behat/Gherkin/Node/ScenarioNode.php b/vendor/behat/gherkin/src/Behat/Gherkin/Node/ScenarioNode.php
new file mode 100644 (file)
index 0000000..58267e1
--- /dev/null
@@ -0,0 +1,150 @@
+<?php
+
+/*
+ * This file is part of the Behat Gherkin.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Gherkin\Node;
+
+/**
+ * Represents Gherkin Scenario.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class ScenarioNode implements ScenarioInterface
+{
+    /**
+     * @var string
+     */
+    private $title;
+    /**
+     * @var array
+     */
+    private $tags = array();
+    /**
+     * @var StepNode[]
+     */
+    private $steps = array();
+    /**
+     * @var string
+     */
+    private $keyword;
+    /**
+     * @var integer
+     */
+    private $line;
+
+    /**
+     * Initializes scenario.
+     *
+     * @param null|string $title
+     * @param array       $tags
+     * @param StepNode[]  $steps
+     * @param string      $keyword
+     * @param integer     $line
+     */
+    public function __construct($title, array $tags, array $steps, $keyword, $line)
+    {
+        $this->title = $title;
+        $this->tags = $tags;
+        $this->steps = $steps;
+        $this->keyword = $keyword;
+        $this->line = $line;
+    }
+
+    /**
+     * Returns node type string
+     *
+     * @return string
+     */
+    public function getNodeType()
+    {
+        return 'Scenario';
+    }
+
+    /**
+     * Returns scenario title.
+     *
+     * @return null|string
+     */
+    public function getTitle()
+    {
+        return $this->title;
+    }
+
+    /**
+     * Checks if scenario is tagged with tag.
+     *
+     * @param string $tag
+     *
+     * @return Boolean
+     */
+    public function hasTag($tag)
+    {
+        return in_array($tag, $this->getTags());
+    }
+
+    /**
+     * Checks if scenario has tags (both inherited from feature and own).
+     *
+     * @return Boolean
+     */
+    public function hasTags()
+    {
+        return 0 < count($this->getTags());
+    }
+
+    /**
+     * Returns scenario tags (including inherited from feature).
+     *
+     * @return array
+     */
+    public function getTags()
+    {
+        return $this->tags;
+    }
+
+    /**
+     * Checks if scenario has steps.
+     *
+     * @return Boolean
+     */
+    public function hasSteps()
+    {
+        return 0 < count($this->steps);
+    }
+
+    /**
+     * Returns scenario steps.
+     *
+     * @return StepNode[]
+     */
+    public function getSteps()
+    {
+        return $this->steps;
+    }
+
+    /**
+     * Returns scenario keyword.
+     *
+     * @return string
+     */
+    public function getKeyword()
+    {
+        return $this->keyword;
+    }
+
+    /**
+     * Returns scenario declaration line number.
+     *
+     * @return integer
+     */
+    public function getLine()
+    {
+        return $this->line;
+    }
+}
diff --git a/vendor/behat/gherkin/src/Behat/Gherkin/Node/StepContainerInterface.php b/vendor/behat/gherkin/src/Behat/Gherkin/Node/StepContainerInterface.php
new file mode 100644 (file)
index 0000000..2a5c73d
--- /dev/null
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ * This file is part of the Behat Gherkin.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Gherkin\Node;
+
+/**
+ * Gherkin step container interface.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface StepContainerInterface extends NodeInterface
+{
+    /**
+     * Checks if container has steps.
+     *
+     * @return Boolean
+     */
+    public function hasSteps();
+
+    /**
+     * Returns container steps.
+     *
+     * @return StepNode[]
+     */
+    public function getSteps();
+}
diff --git a/vendor/behat/gherkin/src/Behat/Gherkin/Node/StepNode.php b/vendor/behat/gherkin/src/Behat/Gherkin/Node/StepNode.php
new file mode 100644 (file)
index 0000000..82eaef4
--- /dev/null
@@ -0,0 +1,152 @@
+<?php
+
+/*
+ * This file is part of the Behat Gherkin.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Gherkin\Node;
+
+use Behat\Gherkin\Exception\NodeException;
+
+/**
+ * Represents Gherkin Step.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class StepNode implements NodeInterface
+{
+    /**
+     * @var string
+     */
+    private $keyword;
+    /**
+     * @var string
+     */
+    private $keywordType;
+    /**
+     * @var string
+     */
+    private $text;
+    /**
+     * @var ArgumentInterface[]
+     */
+    private $arguments = array();
+    /**
+     * @var integer
+     */
+    private $line;
+
+    /**
+     * Initializes step.
+     *
+     * @param string              $keyword
+     * @param string              $text
+     * @param ArgumentInterface[] $arguments
+     * @param integer             $line
+     * @param string              $keywordType
+     */
+    public function __construct($keyword, $text, array $arguments, $line, $keywordType = null)
+    {
+        if (count($arguments) > 1) {
+            throw new NodeException(sprintf(
+                'Steps could have only one argument, but `%s %s` have %d.',
+                $keyword,
+                $text,
+                count($arguments)
+            ));
+        }
+
+        $this->keyword = $keyword;
+        $this->text = $text;
+        $this->arguments = $arguments;
+        $this->line = $line;
+        $this->keywordType = $keywordType ?: 'Given';
+    }
+
+    /**
+     * Returns node type string
+     *
+     * @return string
+     */
+    public function getNodeType()
+    {
+        return 'Step';
+    }
+
+    /**
+     * Returns step keyword in provided language (Given, When, Then, etc.).
+     *
+     * @return string
+     *
+     * @deprecated use getKeyword() instead
+     */
+    public function getType()
+    {
+        return $this->getKeyword();
+    }
+
+    /**
+     * Returns step keyword in provided language (Given, When, Then, etc.).
+     *
+     * @return string
+     *
+     */
+    public function getKeyword()
+    {
+        return $this->keyword;
+    }
+
+    /**
+     * Returns step type keyword (Given, When, Then, etc.).
+     *
+     * @return string
+     */
+    public function getKeywordType()
+    {
+        return $this->keywordType;
+    }
+
+    /**
+     * Returns step text.
+     *
+     * @return string
+     */
+    public function getText()
+    {
+        return $this->text;
+    }
+
+    /**
+     * Checks if step has arguments.
+     *
+     * @return Boolean
+     */
+    public function hasArguments()
+    {
+        return 0 < count($this->arguments);
+    }
+
+    /**
+     * Returns step arguments.
+     *
+     * @return ArgumentInterface[]
+     */
+    public function getArguments()
+    {
+        return $this->arguments;
+    }
+
+    /**
+     * Returns step declaration line number.
+     *
+     * @return integer
+     */
+    public function getLine()
+    {
+        return $this->line;
+    }
+}
diff --git a/vendor/behat/gherkin/src/Behat/Gherkin/Node/TableNode.php b/vendor/behat/gherkin/src/Behat/Gherkin/Node/TableNode.php
new file mode 100644 (file)
index 0000000..23b794f
--- /dev/null
@@ -0,0 +1,342 @@
+<?php
+
+/*
+ * This file is part of the Behat Gherkin.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Gherkin\Node;
+
+use ArrayIterator;
+use Behat\Gherkin\Exception\NodeException;
+use Iterator;
+use IteratorAggregate;
+
+/**
+ * Represents Gherkin Table argument.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class TableNode implements ArgumentInterface, IteratorAggregate
+{
+    /**
+     * @var array
+     */
+    private $table;
+    /**
+     * @var integer
+     */
+    private $maxLineLength = array();
+
+    /**
+     * Initializes table.
+     *
+     * @param array $table Table in form of [$rowLineNumber => [$val1, $val2, $val3]]
+     *
+     * @throws NodeException If the given table is invalid
+     */
+    public function __construct(array $table)
+    {
+        $this->table = $table;
+        $columnCount = null;
+
+        foreach ($this->getRows() as $row) {
+            if ($columnCount === null) {
+                $columnCount = count($row);
+            }
+
+            if (count($row) !== $columnCount) {
+                throw new NodeException('Table does not have same number of columns in every row.');
+            }
+
+            if (!is_array($row)) {
+                throw new NodeException('Table is not two-dimensional.');
+            }
+
+            foreach ($row as $column => $string) {
+                if (!isset($this->maxLineLength[$column])) {
+                    $this->maxLineLength[$column] = 0;
+                }
+
+                if (!is_scalar($string)) {
+                    throw new NodeException('Table is not two-dimensional.');
+                }
+
+                $this->maxLineLength[$column] = max($this->maxLineLength[$column], mb_strlen($string, 'utf8'));
+            }
+        }
+    }
+
+    /**
+     * Creates a table from a given list.
+     *
+     * @param array $list One-dimensional array
+     *
+     * @return TableNode
+     *
+     * @throws NodeException If the given list is not a one-dimensional array
+     */
+    public static function fromList(array $list)
+    {
+        if (count($list) !== count($list, COUNT_RECURSIVE)) {
+            throw new NodeException('List is not a one-dimensional array.');
+        }
+
+        array_walk($list, function (&$item) {
+            $item = array($item);
+        });
+        return new self($list);
+    }
+
+    /**
+     * Returns node type.
+     *
+     * @return string
+     */
+    public function getNodeType()
+    {
+        return 'Table';
+    }
+
+    /**
+     * Returns table hash, formed by columns (ColumnsHash).
+     *
+     * @return array
+     */
+    public function getHash()
+    {
+        return $this->getColumnsHash();
+    }
+
+    /**
+     * Returns table hash, formed by columns.
+     *
+     * @return array
+     */
+    public function getColumnsHash()
+    {
+        $rows = $this->getRows();
+        $keys = array_shift($rows);
+
+        $hash = array();
+        foreach ($rows as $row) {
+            $hash[] = array_combine($keys, $row);
+        }
+
+        return $hash;
+    }
+
+    /**
+     * Returns table hash, formed by rows.
+     *
+     * @return array
+     */
+    public function getRowsHash()
+    {
+        $hash = array();
+
+        foreach ($this->getRows() as $row) {
+            $hash[array_shift($row)] = (1 == count($row)) ? $row[0] : $row;
+        }
+
+        return $hash;
+    }
+
+    /**
+     * Returns numerated table lines.
+     * Line numbers are keys, lines are values.
+     *
+     * @return array
+     */
+    public function getTable()
+    {
+        return $this->table;
+    }
+
+    /**
+     * Returns table rows.
+     *
+     * @return array
+     */
+    public function getRows()
+    {
+        return array_values($this->table);
+    }
+
+    /**
+     * Returns table definition lines.
+     *
+     * @return array
+     */
+    public function getLines()
+    {
+        return array_keys($this->table);
+    }
+
+    /**
+     * Returns specific row in a table.
+     *
+     * @param integer $index Row number
+     *
+     * @return array
+     *
+     * @throws NodeException If row with specified index does not exist
+     */
+    public function getRow($index)
+    {
+        $rows = $this->getRows();
+
+        if (!isset($rows[$index])) {
+            throw new NodeException(sprintf('Rows #%d does not exist in table.', $index));
+        }
+
+        return $rows[$index];
+    }
+
+    /**
+     * Returns specific column in a table.
+     *
+     * @param integer $index Column number
+     *
+     * @return array
+     *
+     * @throws NodeException If column with specified index does not exist
+     */
+    public function getColumn($index)
+    {
+        if ($index >= count($this->getRow(0))) {
+            throw new NodeException(sprintf('Column #%d does not exist in table.', $index));
+        }
+
+        $rows = $this->getRows();
+        $column = array();
+
+        foreach ($rows as $row) {
+            $column[] = $row[$index];
+        }
+
+        return $column;
+    }
+
+    /**
+     * Returns line number at which specific row was defined.
+     *
+     * @param integer $index
+     *
+     * @return integer
+     *
+     * @throws NodeException If row with specified index does not exist
+     */
+    public function getRowLine($index)
+    {
+        $lines = array_keys($this->table);
+
+        if (!isset($lines[$index])) {
+            throw new NodeException(sprintf('Rows #%d does not exist in table.', $index));
+        }
+
+        return $lines[$index];
+    }
+
+    /**
+     * Converts row into delimited string.
+     *
+     * @param integer $rowNum Row number
+     *
+     * @return string
+     */
+    public function getRowAsString($rowNum)
+    {
+        $values = array();
+        foreach ($this->getRow($rowNum) as $column => $value) {
+            $values[] = $this->padRight(' ' . $value . ' ', $this->maxLineLength[$column] + 2);
+        }
+
+        return sprintf('|%s|', implode('|', $values));
+    }
+
+    /**
+     * Converts row into delimited string.
+     *
+     * @param integer  $rowNum  Row number
+     * @param callable $wrapper Wrapper function
+     *
+     * @return string
+     */
+    public function getRowAsStringWithWrappedValues($rowNum, $wrapper)
+    {
+        $values = array();
+        foreach ($this->getRow($rowNum) as $column => $value) {
+            $value = $this->padRight(' ' . $value . ' ', $this->maxLineLength[$column] + 2);
+
+            $values[] = call_user_func($wrapper, $value, $column);
+        }
+
+        return sprintf('|%s|', implode('|', $values));
+    }
+
+    /**
+     * Converts entire table into string
+     *
+     * @return string
+     */
+    public function getTableAsString()
+    {
+        $lines = array();
+        for ($i = 0; $i < count($this->getRows()); $i++) {
+            $lines[] = $this->getRowAsString($i);
+        }
+
+        return implode("\n", $lines);
+    }
+
+    /**
+     * Returns line number at which table was started.
+     *
+     * @return integer
+     */
+    public function getLine()
+    {
+        return $this->getRowLine(0);
+    }
+
+    /**
+     * Converts table into string
+     *
+     * @return string
+     */
+    public function __toString()
+    {
+        return $this->getTableAsString();
+    }
+
+    /**
+     * Retrieves a hash iterator.
+     *
+     * @return Iterator
+     */
+    public function getIterator()
+    {
+        return new ArrayIterator($this->getHash());
+    }
+
+    /**
+     * Pads string right.
+     *
+     * @param string  $text   Text to pad
+     * @param integer $length Length
+     *
+     * @return string
+     */
+    protected function padRight($text, $length)
+    {
+        while ($length > mb_strlen($text, 'utf8')) {
+            $text = $text . ' ';
+        }
+
+        return $text;
+    }
+}
diff --git a/vendor/behat/gherkin/src/Behat/Gherkin/Node/TaggedNodeInterface.php b/vendor/behat/gherkin/src/Behat/Gherkin/Node/TaggedNodeInterface.php
new file mode 100644 (file)
index 0000000..cce6bca
--- /dev/null
@@ -0,0 +1,42 @@
+<?php
+
+/*
+ * This file is part of the Behat Gherkin.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Gherkin\Node;
+
+/**
+ * Gherkin tagged node interface.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface TaggedNodeInterface extends NodeInterface
+{
+    /**
+     * Checks if node is tagged with tag.
+     *
+     * @param string $tag
+     *
+     * @return Boolean
+     */
+    public function hasTag($tag);
+
+    /**
+     * Checks if node has tags (both inherited from feature and own).
+     *
+     * @return Boolean
+     */
+    public function hasTags();
+
+    /**
+     * Returns node tags (including inherited from feature).
+     *
+     * @return string[]
+     */
+    public function getTags();
+}
diff --git a/vendor/behat/gherkin/src/Behat/Gherkin/Parser.php b/vendor/behat/gherkin/src/Behat/Gherkin/Parser.php
new file mode 100644 (file)
index 0000000..5cc8542
--- /dev/null
@@ -0,0 +1,699 @@
+<?php
+
+/*
+ * This file is part of the Behat Gherkin.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Gherkin;
+
+use Behat\Gherkin\Exception\LexerException;
+use Behat\Gherkin\Exception\ParserException;
+use Behat\Gherkin\Node\BackgroundNode;
+use Behat\Gherkin\Node\ExampleTableNode;
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\OutlineNode;
+use Behat\Gherkin\Node\PyStringNode;
+use Behat\Gherkin\Node\ScenarioInterface;
+use Behat\Gherkin\Node\ScenarioNode;
+use Behat\Gherkin\Node\StepNode;
+use Behat\Gherkin\Node\TableNode;
+
+/**
+ * Gherkin parser.
+ *
+ * $lexer  = new Behat\Gherkin\Lexer($keywords);
+ * $parser = new Behat\Gherkin\Parser($lexer);
+ * $featuresArray = $parser->parse('/path/to/feature.feature');
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class Parser
+{
+    private $lexer;
+    private $input;
+    private $file;
+    private $tags = array();
+    private $languageSpecifierLine;
+
+    /**
+     * Initializes parser.
+     *
+     * @param Lexer $lexer Lexer instance
+     */
+    public function __construct(Lexer $lexer)
+    {
+        $this->lexer = $lexer;
+    }
+
+    /**
+     * Parses input & returns features array.
+     *
+     * @param string $input Gherkin string document
+     * @param string $file  File name
+     *
+     * @return FeatureNode|null
+     *
+     * @throws ParserException
+     */
+    public function parse($input, $file = null)
+    {
+        $this->languageSpecifierLine = null;
+        $this->input = $input;
+        $this->file = $file;
+        $this->tags = array();
+
+        try {
+            $this->lexer->analyse($this->input, 'en');
+        } catch (LexerException $e) {
+            throw new ParserException(
+                sprintf('Lexer exception "%s" thrown for file %s', $e->getMessage(), $file),
+                0,
+                $e
+            );
+        }
+
+        $feature = null;
+        while ('EOS' !== ($predicted = $this->predictTokenType())) {
+            $node = $this->parseExpression();
+
+            if (null === $node || "\n" === $node) {
+                continue;
+            }
+
+            if (!$feature && $node instanceof FeatureNode) {
+                $feature = $node;
+                continue;
+            }
+
+            if ($feature && $node instanceof FeatureNode) {
+                throw new ParserException(sprintf(
+                    'Only one feature is allowed per feature file. But %s got multiple.',
+                    $this->file
+                ));
+            }
+
+            if (is_string($node)) {
+                throw new ParserException(sprintf(
+                    'Expected Feature, but got text: "%s"%s',
+                    $node,
+                    $this->file ? ' in file: ' . $this->file : ''
+                ));
+            }
+
+            if (!$node instanceof FeatureNode) {
+                throw new ParserException(sprintf(
+                    'Expected Feature, but got %s on line: %d%s',
+                    $node->getKeyword(),
+                    $node->getLine(),
+                    $this->file ? ' in file: ' . $this->file : ''
+                ));
+            }
+        }
+
+        return $feature;
+    }
+
+    /**
+     * Returns next token if it's type equals to expected.
+     *
+     * @param string $type Token type
+     *
+     * @return array
+     *
+     * @throws Exception\ParserException
+     */
+    protected function expectTokenType($type)
+    {
+        $types = (array) $type;
+        if (in_array($this->predictTokenType(), $types)) {
+            return $this->lexer->getAdvancedToken();
+        }
+
+        $token = $this->lexer->predictToken();
+
+        throw new ParserException(sprintf(
+            'Expected %s token, but got %s on line: %d%s',
+            implode(' or ', $types),
+            $this->predictTokenType(),
+            $token['line'],
+            $this->file ? ' in file: ' . $this->file : ''
+        ));
+    }
+
+    /**
+     * Returns next token if it's type equals to expected.
+     *
+     * @param string $type Token type
+     *
+     * @return null|array
+     */
+    protected function acceptTokenType($type)
+    {
+        if ($type !== $this->predictTokenType()) {
+            return null;
+        }
+
+        return $this->lexer->getAdvancedToken();
+    }
+
+    /**
+     * Returns next token type without real input reading (prediction).
+     *
+     * @return string
+     */
+    protected function predictTokenType()
+    {
+        $token = $this->lexer->predictToken();
+
+        return $token['type'];
+    }
+
+    /**
+     * Parses current expression & returns Node.
+     *
+     * @return string|FeatureNode|BackgroundNode|ScenarioNode|OutlineNode|TableNode|StepNode
+     *
+     * @throws ParserException
+     */
+    protected function parseExpression()
+    {
+        switch ($type = $this->predictTokenType()) {
+            case 'Feature':
+                return $this->parseFeature();
+            case 'Background':
+                return $this->parseBackground();
+            case 'Scenario':
+                return $this->parseScenario();
+            case 'Outline':
+                return $this->parseOutline();
+            case 'Examples':
+                return $this->parseExamples();
+            case 'TableRow':
+                return $this->parseTable();
+            case 'PyStringOp':
+                return $this->parsePyString();
+            case 'Step':
+                return $this->parseStep();
+            case 'Text':
+                return $this->parseText();
+            case 'Newline':
+                return $this->parseNewline();
+            case 'Tag':
+                return $this->parseTags();
+            case 'Comment':
+                return $this->parseComment();
+            case 'Language':
+                return $this->parseLanguage();
+            case 'EOS':
+                return '';
+        }
+
+        throw new ParserException(sprintf('Unknown token type: %s', $type));
+    }
+
+    /**
+     * Parses feature token & returns it's node.
+     *
+     * @return FeatureNode
+     *
+     * @throws ParserException
+     */
+    protected function parseFeature()
+    {
+        $token = $this->expectTokenType('Feature');
+
+        $title = trim($token['value']) ?: null;
+        $description = null;
+        $tags = $this->popTags();
+        $background = null;
+        $scenarios = array();
+        $keyword = $token['keyword'];
+        $language = $this->lexer->getLanguage();
+        $file = $this->file;
+        $line = $token['line'];
+
+        // Parse description, background, scenarios & outlines
+        while ('EOS' !== $this->predictTokenType()) {
+            $node = $this->parseExpression();
+
+            if (is_string($node)) {
+                $text = preg_replace('/^\s{0,' . ($token['indent'] + 2) . '}|\s*$/', '', $node);
+                $description .= (null !== $description ? "\n" : '') . $text;
+                continue;
+            }
+
+            if (!$background && $node instanceof BackgroundNode) {
+                $background = $node;
+                continue;
+            }
+
+            if ($node instanceof ScenarioInterface) {
+                $scenarios[] = $node;
+                continue;
+            }
+
+            if ($background instanceof BackgroundNode && $node instanceof BackgroundNode) {
+                throw new ParserException(sprintf(
+                    'Each Feature could have only one Background, but found multiple on lines %d and %d%s',
+                    $background->getLine(),
+                    $node->getLine(),
+                    $this->file ? ' in file: ' . $this->file : ''
+                ));
+            }
+
+            if (!$node instanceof ScenarioNode) {
+                throw new ParserException(sprintf(
+                    'Expected Scenario, Outline or Background, but got %s on line: %d%s',
+                    $node->getNodeType(),
+                    $node->getLine(),
+                    $this->file ? ' in file: ' . $this->file : ''
+                ));
+            }
+        }
+
+        return new FeatureNode(
+            rtrim($title) ?: null,
+            rtrim($description) ?: null,
+            $tags,
+            $background,
+            $scenarios,
+            $keyword,
+            $language,
+            $file,
+            $line
+        );
+    }
+
+    /**
+     * Parses background token & returns it's node.
+     *
+     * @return BackgroundNode
+     *
+     * @throws ParserException
+     */
+    protected function parseBackground()
+    {
+        $token = $this->expectTokenType('Background');
+
+        $title = trim($token['value']);
+        $keyword = $token['keyword'];
+        $line = $token['line'];
+
+        if (count($this->popTags())) {
+            throw new ParserException(sprintf(
+                'Background can not be tagged, but it is on line: %d%s',
+                $line,
+                $this->file ? ' in file: ' . $this->file : ''
+            ));
+        }
+
+        // Parse description and steps
+        $steps = array();
+        $allowedTokenTypes = array('Step', 'Newline', 'Text', 'Comment');
+        while (in_array($this->predictTokenType(), $allowedTokenTypes)) {
+            $node = $this->parseExpression();
+
+            if ($node instanceof StepNode) {
+                $steps[] = $this->normalizeStepNodeKeywordType($node, $steps);
+                continue;
+            }
+
+            if (!count($steps) && is_string($node)) {
+                $text = preg_replace('/^\s{0,' . ($token['indent'] + 2) . '}|\s*$/', '', $node);
+                $title .= "\n" . $text;
+                continue;
+            }
+
+            if ("\n" === $node) {
+                continue;
+            }
+
+            if (is_string($node)) {
+                throw new ParserException(sprintf(
+                    'Expected Step, but got text: "%s"%s',
+                    $node,
+                    $this->file ? ' in file: ' . $this->file : ''
+                ));
+            }
+
+            if (!$node instanceof StepNode) {
+                throw new ParserException(sprintf(
+                    'Expected Step, but got %s on line: %d%s',
+                    $node->getNodeType(),
+                    $node->getLine(),
+                    $this->file ? ' in file: ' . $this->file : ''
+                ));
+            }
+        }
+
+        return new BackgroundNode(rtrim($title) ?: null, $steps, $keyword, $line);
+    }
+
+    /**
+     * Parses scenario token & returns it's node.
+     *
+     * @return ScenarioNode
+     *
+     * @throws ParserException
+     */
+    protected function parseScenario()
+    {
+        $token = $this->expectTokenType('Scenario');
+
+        $title = trim($token['value']);
+        $tags = $this->popTags();
+        $keyword = $token['keyword'];
+        $line = $token['line'];
+
+        // Parse description and steps
+        $steps = array();
+        while (in_array($this->predictTokenType(), array('Step', 'Newline', 'Text', 'Comment'))) {
+            $node = $this->parseExpression();
+
+            if ($node instanceof StepNode) {
+                $steps[] = $this->normalizeStepNodeKeywordType($node, $steps);
+                continue;
+            }
+
+            if (!count($steps) && is_string($node)) {
+                $text = preg_replace('/^\s{0,' . ($token['indent'] + 2) . '}|\s*$/', '', $node);
+                $title .= "\n" . $text;
+                continue;
+            }
+
+            if ("\n" === $node) {
+                continue;
+            }
+
+            if (is_string($node)) {
+                throw new ParserException(sprintf(
+                    'Expected Step, but got text: "%s"%s',
+                    $node,
+                    $this->file ? ' in file: ' . $this->file : ''
+                ));
+            }
+
+            if (!$node instanceof StepNode) {
+                throw new ParserException(sprintf(
+                    'Expected Step, but got %s on line: %d%s',
+                    $node->getNodeType(),
+                    $node->getLine(),
+                    $this->file ? ' in file: ' . $this->file : ''
+                ));
+            }
+        }
+
+        return new ScenarioNode(rtrim($title) ?: null, $tags, $steps, $keyword, $line);
+    }
+
+    /**
+     * Parses scenario outline token & returns it's node.
+     *
+     * @return OutlineNode
+     *
+     * @throws ParserException
+     */
+    protected function parseOutline()
+    {
+        $token = $this->expectTokenType('Outline');
+
+        $title = trim($token['value']);
+        $tags = $this->popTags();
+        $keyword = $token['keyword'];
+        $examples = null;
+        $line = $token['line'];
+
+        // Parse description, steps and examples
+        $steps = array();
+        while (in_array($this->predictTokenType(), array('Step', 'Examples', 'Newline', 'Text', 'Comment'))) {
+            $node = $this->parseExpression();
+
+            if ($node instanceof StepNode) {
+                $steps[] = $this->normalizeStepNodeKeywordType($node, $steps);
+                continue;
+            }
+
+            if ($node instanceof ExampleTableNode) {
+                $examples = $node;
+                continue;
+            }
+
+            if (!count($steps) && is_string($node)) {
+                $text = preg_replace('/^\s{0,' . ($token['indent'] + 2) . '}|\s*$/', '', $node);
+                $title .= "\n" . $text;
+                continue;
+            }
+
+            if ("\n" === $node) {
+                continue;
+            }
+
+            if (is_string($node)) {
+                throw new ParserException(sprintf(
+                    'Expected Step or Examples table, but got text: "%s"%s',
+                    $node,
+                    $this->file ? ' in file: ' . $this->file : ''
+                ));
+            }
+
+            if (!$node instanceof StepNode) {
+                throw new ParserException(sprintf(
+                    'Expected Step or Examples table, but got %s on line: %d%s',
+                    $node->getNodeType(),
+                    $node->getLine(),
+                    $this->file ? ' in file: ' . $this->file : ''
+                ));
+            }
+        }
+
+        if (null === $examples) {
+            throw new ParserException(sprintf(
+                'Outline should have examples table, but got none for outline "%s" on line: %d%s',
+                rtrim($title),
+                $line,
+                $this->file ? ' in file: ' . $this->file : ''
+            ));
+        }
+
+        return new OutlineNode(rtrim($title) ?: null, $tags, $steps, $examples, $keyword, $line);
+    }
+
+    /**
+     * Parses step token & returns it's node.
+     *
+     * @return StepNode
+     */
+    protected function parseStep()
+    {
+        $token = $this->expectTokenType('Step');
+
+        $keyword = $token['value'];
+        $keywordType = $token['keyword_type'];
+        $text = trim($token['text']);
+        $line = $token['line'];
+
+        $arguments = array();
+        while (in_array($predicted = $this->predictTokenType(), array('PyStringOp', 'TableRow', 'Newline', 'Comment'))) {
+            if ('Comment' === $predicted || 'Newline' === $predicted) {
+                $this->acceptTokenType($predicted);
+                continue;
+            }
+
+            $node = $this->parseExpression();
+
+            if ($node instanceof PyStringNode || $node instanceof TableNode) {
+                $arguments[] = $node;
+            }
+        }
+
+        return new StepNode($keyword, $text, $arguments, $line, $keywordType);
+    }
+
+    /**
+     * Parses examples table node.
+     *
+     * @return ExampleTableNode
+     */
+    protected function parseExamples()
+    {
+        $token = $this->expectTokenType('Examples');
+
+        $keyword = $token['keyword'];
+
+        return new ExampleTableNode($this->parseTableRows(), $keyword);
+    }
+
+    /**
+     * Parses table token & returns it's node.
+     *
+     * @return TableNode
+     */
+    protected function parseTable()
+    {
+        return new TableNode($this->parseTableRows());
+    }
+
+    /**
+     * Parses PyString token & returns it's node.
+     *
+     * @return PyStringNode
+     */
+    protected function parsePyString()
+    {
+        $token = $this->expectTokenType('PyStringOp');
+
+        $line = $token['line'];
+
+        $strings = array();
+        while ('PyStringOp' !== ($predicted = $this->predictTokenType()) && 'Text' === $predicted) {
+            $token = $this->expectTokenType('Text');
+
+            $strings[] = $token['value'];
+        }
+
+        $this->expectTokenType('PyStringOp');
+
+        return new PyStringNode($strings, $line);
+    }
+
+    /**
+     * Parses tags.
+     *
+     * @return BackgroundNode|FeatureNode|OutlineNode|ScenarioNode|StepNode|TableNode|string
+     */
+    protected function parseTags()
+    {
+        $token = $this->expectTokenType('Tag');
+        $this->tags = array_merge($this->tags, $token['tags']);
+
+        return $this->parseExpression();
+    }
+
+    /**
+     * Returns current set of tags and clears tag buffer.
+     *
+     * @return array
+     */
+    protected function popTags()
+    {
+        $tags = $this->tags;
+        $this->tags = array();
+
+        return $tags;
+    }
+
+    /**
+     * Parses next text line & returns it.
+     *
+     * @return string
+     */
+    protected function parseText()
+    {
+        $token = $this->expectTokenType('Text');
+
+        return $token['value'];
+    }
+
+    /**
+     * Parses next newline & returns \n.
+     *
+     * @return string
+     */
+    protected function parseNewline()
+    {
+        $this->expectTokenType('Newline');
+
+        return "\n";
+    }
+
+    /**
+     * Parses next comment token & returns it's string content.
+     *
+     * @return BackgroundNode|FeatureNode|OutlineNode|ScenarioNode|StepNode|TableNode|string
+     */
+    protected function parseComment()
+    {
+        $this->expectTokenType('Comment');
+
+        return $this->parseExpression();
+    }
+
+    /**
+     * Parses language block and updates lexer configuration based on it.
+     *
+     * @return BackgroundNode|FeatureNode|OutlineNode|ScenarioNode|StepNode|TableNode|string
+     *
+     * @throws ParserException
+     */
+    protected function parseLanguage()
+    {
+        $token = $this->expectTokenType('Language');
+
+        if (null === $this->languageSpecifierLine) {
+            $this->lexer->analyse($this->input, $token['value']);
+            $this->languageSpecifierLine = $token['line'];
+        } elseif ($token['line'] !== $this->languageSpecifierLine) {
+            throw new ParserException(sprintf(
+                'Ambiguous language specifiers on lines: %d and %d%s',
+                $this->languageSpecifierLine,
+                $token['line'],
+                $this->file ? ' in file: ' . $this->file : ''
+            ));
+        }
+
+        return $this->parseExpression();
+    }
+
+    /**
+     * Parses the rows of a table
+     *
+     * @return string[][]
+     */
+    private function parseTableRows()
+    {
+        $table = array();
+        while (in_array($predicted = $this->predictTokenType(), array('TableRow', 'Newline', 'Comment'))) {
+            if ('Comment' === $predicted || 'Newline' === $predicted) {
+                $this->acceptTokenType($predicted);
+                continue;
+            }
+
+            $token = $this->expectTokenType('TableRow');
+
+            $table[$token['line']] = $token['columns'];
+        }
+
+        return $table;
+    }
+
+    /**
+     * Changes step node type for types But, And to type of previous step if it exists else sets to Given
+     *
+     * @param StepNode   $node
+     * @param StepNode[] $steps
+     * @return StepNode
+     */
+    private function normalizeStepNodeKeywordType(StepNode $node, array $steps = array())
+    {
+        if (in_array($node->getKeywordType(), array('And', 'But'))) {
+            if (($prev = end($steps))) {
+                $keywordType = $prev->getKeywordType();
+            } else {
+                $keywordType = 'Given';
+            }
+
+            $node = new StepNode(
+                $node->getKeyword(),
+                $node->getText(),
+                $node->getArguments(),
+                $node->getLine(),
+                $keywordType
+            );
+        }
+        return $node;
+    }
+}
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Cache/FileCacheTest.php b/vendor/behat/gherkin/tests/Behat/Gherkin/Cache/FileCacheTest.php
new file mode 100644 (file)
index 0000000..2f0b7c9
--- /dev/null
@@ -0,0 +1,75 @@
+<?php
+
+namespace Tests\Behat\Gherkin\Cache;
+
+use Behat\Gherkin\Cache\FileCache;
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\ScenarioNode;
+use Behat\Gherkin\Gherkin;
+
+class FileCacheTest extends \PHPUnit_Framework_TestCase
+{
+    private $path;
+    private $cache;
+
+    public function testIsFreshWhenThereIsNoFile()
+    {
+        $this->assertFalse($this->cache->isFresh('unexisting', time() + 100));
+    }
+
+    public function testIsFreshOnFreshFile()
+    {
+        $feature = new FeatureNode(null, null, array(), null, array(), null, null, null, null);
+
+        $this->cache->write('some_path', $feature);
+
+        $this->assertFalse($this->cache->isFresh('some_path', time() + 100));
+    }
+
+    public function testIsFreshOnOutdated()
+    {
+        $feature = new FeatureNode(null, null, array(), null, array(), null, null, null, null);
+
+        $this->cache->write('some_path', $feature);
+
+        $this->assertTrue($this->cache->isFresh('some_path', time() - 100));
+    }
+
+    public function testCacheAndRead()
+    {
+        $scenarios = array(new ScenarioNode('Some scenario', array(), array(), null, null));
+        $feature = new FeatureNode('Some feature', 'some description', array(), null, $scenarios, null, null, null, null);
+
+        $this->cache->write('some_feature', $feature);
+        $featureRead = $this->cache->read('some_feature');
+
+        $this->assertEquals($feature, $featureRead);
+    }
+
+    public function testBrokenCacheRead()
+    {
+        $this->setExpectedException('Behat\Gherkin\Exception\CacheException');
+
+        touch($this->path . '/v' . Gherkin::VERSION . '/' . md5('broken_feature') . '.feature.cache');
+        $this->cache->read('broken_feature');
+    }
+
+    public function testUnwriteableCacheDir()
+    {
+        $this->setExpectedException('Behat\Gherkin\Exception\CacheException');
+
+        new FileCache('/dev/null/gherkin-test');
+    }
+
+    protected function setUp()
+    {
+        $this->cache = new FileCache($this->path = sys_get_temp_dir() . '/gherkin-test');
+    }
+
+    protected function tearDown()
+    {
+        foreach (glob($this->path . '/*.feature.cache') as $file) {
+            unlink((string) $file);
+        }
+    }
+}
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Cache/MemoryCacheTest.php b/vendor/behat/gherkin/tests/Behat/Gherkin/Cache/MemoryCacheTest.php
new file mode 100644 (file)
index 0000000..a0bb6c8
--- /dev/null
@@ -0,0 +1,51 @@
+<?php
+
+namespace Tests\Behat\Gherkin\Cache;
+
+use Behat\Gherkin\Cache\MemoryCache;
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\ScenarioNode;
+
+class MemoryCacheTest extends \PHPUnit_Framework_TestCase
+{
+    private $cache;
+
+    public function testIsFreshWhenThereIsNoFile()
+    {
+        $this->assertFalse($this->cache->isFresh('unexisting', time() + 100));
+    }
+
+    public function testIsFreshOnFreshFile()
+    {
+        $feature = new FeatureNode(null, null, array(), null, array(), null, null, null, null);
+
+        $this->cache->write('some_path', $feature);
+
+        $this->assertFalse($this->cache->isFresh('some_path', time() + 100));
+    }
+
+    public function testIsFreshOnOutdated()
+    {
+        $feature = new FeatureNode(null, null, array(), null, array(), null, null, null, null);
+
+        $this->cache->write('some_path', $feature);
+
+        $this->assertTrue($this->cache->isFresh('some_path', time() - 100));
+    }
+
+    public function testCacheAndRead()
+    {
+        $scenarios = array(new ScenarioNode('Some scenario', array(), array(), null, null));
+        $feature = new FeatureNode('Some feature', 'some description', array(), null, $scenarios, null, null, null, null);
+
+        $this->cache->write('some_feature', $feature);
+        $featureRead = $this->cache->read('some_feature');
+
+        $this->assertEquals($feature, $featureRead);
+    }
+
+    protected function setUp()
+    {
+        $this->cache = new MemoryCache();
+    }
+}
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Filter/FilterTest.php b/vendor/behat/gherkin/tests/Behat/Gherkin/Filter/FilterTest.php
new file mode 100644 (file)
index 0000000..994e656
--- /dev/null
@@ -0,0 +1,64 @@
+<?php
+
+namespace Tests\Behat\Gherkin\Filter;
+
+use Behat\Gherkin\Keywords\ArrayKeywords;
+use Behat\Gherkin\Lexer;
+use Behat\Gherkin\Parser;
+
+abstract class FilterTest extends \PHPUnit_Framework_TestCase
+{
+    protected function getParser()
+    {
+        return new Parser(
+            new Lexer(
+                new ArrayKeywords(array(
+                    'en' => array(
+                        'feature'          => 'Feature',
+                        'background'       => 'Background',
+                        'scenario'         => 'Scenario',
+                        'scenario_outline' => 'Scenario Outline|Scenario Template',
+                        'examples'         => 'Examples|Scenarios',
+                        'given'            => 'Given',
+                        'when'             => 'When',
+                        'then'             => 'Then',
+                        'and'              => 'And',
+                        'but'              => 'But'
+                    )
+                ))
+            )
+        );
+    }
+
+    protected function getGherkinFeature()
+    {
+        return <<<GHERKIN
+Feature: Long feature with outline
+  Scenario: Scenario#1
+    Given initial step
+    When action occurs
+    Then outcomes should be visible
+
+  Scenario: Scenario#2
+    Given initial step
+    And another initial step
+    When action occurs
+    Then outcomes should be visible
+
+  Scenario Outline: Scenario#3
+    When <action> occurs
+    Then <outcome> should be visible
+
+    Examples:
+      | action | outcome |
+      | act#1  | out#1   |
+      | act#2  | out#2   |
+      | act#3  | out#3   |
+GHERKIN;
+    }
+
+    protected function getParsedFeature()
+    {
+        return $this->getParser()->parse($this->getGherkinFeature());
+    }
+}
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Filter/Fixtures/full/file1 b/vendor/behat/gherkin/tests/Behat/Gherkin/Filter/Fixtures/full/file1
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Filter/Fixtures/full/file2 b/vendor/behat/gherkin/tests/Behat/Gherkin/Filter/Fixtures/full/file2
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Filter/Fixtures/full_path/file1 b/vendor/behat/gherkin/tests/Behat/Gherkin/Filter/Fixtures/full_path/file1
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Filter/LineFilterTest.php b/vendor/behat/gherkin/tests/Behat/Gherkin/Filter/LineFilterTest.php
new file mode 100644 (file)
index 0000000..846a719
--- /dev/null
@@ -0,0 +1,103 @@
+<?php
+
+namespace Tests\Behat\Gherkin\Filter;
+
+use Behat\Gherkin\Filter\LineFilter;
+use Behat\Gherkin\Node\ExampleTableNode;
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\OutlineNode;
+use Behat\Gherkin\Node\ScenarioNode;
+
+class LineFilterTest extends FilterTest
+{
+    public function testIsFeatureMatchFilter()
+    {
+        $feature = new FeatureNode(null, null, array(), null, array(), null, null, null, 1);
+
+        $filter = new LineFilter(1);
+        $this->assertTrue($filter->isFeatureMatch($feature));
+
+        $filter = new LineFilter(2);
+        $this->assertFalse($filter->isFeatureMatch($feature));
+
+        $filter = new LineFilter(3);
+        $this->assertFalse($filter->isFeatureMatch($feature));
+    }
+
+    public function testIsScenarioMatchFilter()
+    {
+        $scenario = new ScenarioNode(null, array(), array(), null, 2);
+
+        $filter = new LineFilter(2);
+        $this->assertTrue($filter->isScenarioMatch($scenario));
+
+        $filter = new LineFilter(1);
+        $this->assertFalse($filter->isScenarioMatch($scenario));
+
+        $filter = new LineFilter(5);
+        $this->assertFalse($filter->isScenarioMatch($scenario));
+
+        $outline = new OutlineNode(null, array(), array(), new ExampleTableNode(array(), null), null, 20);
+
+        $filter = new LineFilter(5);
+        $this->assertFalse($filter->isScenarioMatch($outline));
+
+        $filter = new LineFilter(20);
+        $this->assertTrue($filter->isScenarioMatch($outline));
+    }
+
+    public function testFilterFeatureScenario()
+    {
+        $filter = new LineFilter(2);
+        $feature = $filter->filterFeature($this->getParsedFeature());
+        $this->assertCount(1, $scenarios = $feature->getScenarios());
+        $this->assertSame('Scenario#1', $scenarios[0]->getTitle());
+
+        $filter = new LineFilter(7);
+        $feature = $filter->filterFeature($this->getParsedFeature());
+        $this->assertCount(1, $scenarios = $feature->getScenarios());
+        $this->assertSame('Scenario#2', $scenarios[0]->getTitle());
+
+        $filter = new LineFilter(5);
+        $feature = $filter->filterFeature($this->getParsedFeature());
+        $this->assertCount(0, $scenarios = $feature->getScenarios());
+    }
+
+    public function testFilterFeatureOutline()
+    {
+        $filter = new LineFilter(13);
+        $feature = $filter->filterFeature($this->getParsedFeature());
+        $this->assertCount(1, $scenarios = $feature->getScenarios());
+        $this->assertSame('Scenario#3', $scenarios[0]->getTitle());
+        $this->assertCount(4, $scenarios[0]->getExampleTable()->getRows());
+
+        $filter = new LineFilter(19);
+        $feature = $filter->filterFeature($this->getParsedFeature());
+        $this->assertCount(1, $scenarios = $feature->getScenarios());
+        $this->assertSame('Scenario#3', $scenarios[0]->getTitle());
+        $this->assertCount(2, $scenarios[0]->getExampleTable()->getRows());
+        $this->assertSame(array(
+            array('action', 'outcome'),
+            array('act#1', 'out#1'),
+        ), $scenarios[0]->getExampleTable()->getRows());
+
+        $filter = new LineFilter(21);
+        $feature = $filter->filterFeature($this->getParsedFeature());
+        $this->assertCount(1, $scenarios = $feature->getScenarios());
+        $this->assertSame('Scenario#3', $scenarios[0]->getTitle());
+        $this->assertCount(2, $scenarios[0]->getExampleTable()->getRows());
+        $this->assertSame(array(
+            array('action', 'outcome'),
+            array('act#3', 'out#3'),
+        ), $scenarios[0]->getExampleTable()->getRows());
+
+        $filter = new LineFilter(18);
+        $feature = $filter->filterFeature($this->getParsedFeature());
+        $this->assertCount(1, $scenarios = $feature->getScenarios());
+        $this->assertSame('Scenario#3', $scenarios[0]->getTitle());
+        $this->assertCount(1, $scenarios[0]->getExampleTable()->getRows());
+        $this->assertSame(array(
+            array('action', 'outcome'),
+        ), $scenarios[0]->getExampleTable()->getRows());
+    }
+}
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Filter/LineRangeFilterTest.php b/vendor/behat/gherkin/tests/Behat/Gherkin/Filter/LineRangeFilterTest.php
new file mode 100644 (file)
index 0000000..fb8abe1
--- /dev/null
@@ -0,0 +1,101 @@
+<?php
+
+namespace Tests\Behat\Gherkin\Filter;
+
+use Behat\Gherkin\Filter\LineRangeFilter;
+use Behat\Gherkin\Node\ExampleTableNode;
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\OutlineNode;
+use Behat\Gherkin\Node\ScenarioNode;
+
+class LineRangeFilterTest extends FilterTest
+{
+    public function featureLineRangeProvider()
+    {
+        return array(
+            array('1', '1', true),
+            array('1', '2', true),
+            array('1', '*', true),
+            array('2', '2', false),
+            array('2', '*', false)
+        );
+    }
+
+    /**
+     * @dataProvider featureLineRangeProvider
+     */
+    public function testIsFeatureMatchFilter($filterMinLine, $filterMaxLine, $expected)
+    {
+        $feature = new FeatureNode(null, null, array(), null, array(), null, null, null, 1);
+
+        $filter = new LineRangeFilter($filterMinLine, $filterMaxLine);
+        $this->assertSame($expected, $filter->isFeatureMatch($feature));
+    }
+
+    public function scenarioLineRangeProvider()
+    {
+        return array(
+            array('1', '2', 1),
+            array('1', '*', 2),
+            array('2', '2', 1),
+            array('2', '*', 2),
+            array('3', '3', 1),
+            array('3', '*', 1),
+            array('1', '1', 0),
+            array('4', '4', 0),
+            array('4', '*', 0)
+        );
+    }
+
+    /**
+     * @dataProvider scenarioLineRangeProvider
+     */
+    public function testIsScenarioMatchFilter($filterMinLine, $filterMaxLine, $expectedNumberOfMatches)
+    {
+        $scenario = new ScenarioNode(null, array(), array(), null, 2);
+        $outline = new OutlineNode(null, array(), array(), new ExampleTableNode(array(), null), null, 3);
+
+        $filter = new LineRangeFilter($filterMinLine, $filterMaxLine);
+        $this->assertEquals(
+            $expectedNumberOfMatches,
+            intval($filter->isScenarioMatch($scenario)) + intval($filter->isScenarioMatch($outline))
+        );
+    }
+
+    public function testFilterFeatureScenario()
+    {
+        $filter = new LineRangeFilter(1, 3);
+        $feature = $filter->filterFeature($this->getParsedFeature());
+        $this->assertCount(1, $scenarios = $feature->getScenarios());
+        $this->assertSame('Scenario#1', $scenarios[0]->getTitle());
+
+        $filter = new LineRangeFilter(5, 9);
+        $feature = $filter->filterFeature($this->getParsedFeature());
+        $this->assertCount(1, $scenarios = $feature->getScenarios());
+        $this->assertSame('Scenario#2', $scenarios[0]->getTitle());
+
+        $filter = new LineRangeFilter(5, 6);
+        $feature = $filter->filterFeature($this->getParsedFeature());
+        $this->assertCount(0, $scenarios = $feature->getScenarios());
+    }
+
+    public function testFilterFeatureOutline()
+    {
+        $filter = new LineRangeFilter(12, 14);
+        $feature = $filter->filterFeature($this->getParsedFeature());
+        $this->assertCount(1, $scenarios = $feature->getScenarios());
+        $this->assertSame('Scenario#3', $scenarios[0]->getTitle());
+        $this->assertCount(1, $scenarios[0]->getExampleTable()->getRows());
+
+        $filter = new LineRangeFilter(15, 20);
+        $feature = $filter->filterFeature($this->getParsedFeature());
+        $this->assertCount(1, $scenarios = $feature->getScenarios());
+        $this->assertSame('Scenario#3', $scenarios[0]->getTitle());
+        $this->assertCount(3, $scenarios[0]->getExampleTable()->getRows());
+        $this->assertSame(array(
+            array('action', 'outcome'),
+            array('act#1', 'out#1'),
+            array('act#2', 'out#2'),
+        ), $scenarios[0]->getExampleTable()->getRows());
+    }
+}
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Filter/NameFilterTest.php b/vendor/behat/gherkin/tests/Behat/Gherkin/Filter/NameFilterTest.php
new file mode 100644 (file)
index 0000000..24914ec
--- /dev/null
@@ -0,0 +1,79 @@
+<?php
+
+namespace Tests\Behat\Gherkin\Filter;
+
+use Behat\Gherkin\Filter\NameFilter;
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\ScenarioNode;
+
+class NameFilterTest extends \PHPUnit_Framework_TestCase
+{
+    public function testFilterFeature()
+    {
+        $feature = new FeatureNode('feature1', null, array(), null, array(), null, null, null, 1);
+        $filter = new NameFilter('feature1');
+        $this->assertSame($feature, $filter->filterFeature($feature));
+
+        $scenarios = array(
+            new ScenarioNode('scenario1', array(), array(), null, 2),
+            $matchedScenario = new ScenarioNode('scenario2', array(), array(), null, 4)
+        );
+        $feature = new FeatureNode('feature1', null, array(), null, $scenarios, null, null, null, 1);
+        $filter = new NameFilter('scenario2');
+        $filteredFeature = $filter->filterFeature($feature);
+
+        $this->assertSame(array($matchedScenario), $filteredFeature->getScenarios());
+    }
+
+    public function testIsFeatureMatchFilter()
+    {
+        $feature = new FeatureNode('random feature title', null, array(), null, array(), null, null, null, 1);
+
+        $filter = new NameFilter('feature1');
+        $this->assertFalse($filter->isFeatureMatch($feature));
+
+        $feature = new FeatureNode('feature1', null, array(), null, array(), null, null, null, 1);
+        $this->assertTrue($filter->isFeatureMatch($feature));
+
+        $feature = new FeatureNode('feature1 title', null, array(), null, array(), null, null, null, 1);
+        $this->assertTrue($filter->isFeatureMatch($feature));
+
+        $feature = new FeatureNode('some feature1 title', null, array(), null, array(), null, null, null, 1);
+        $this->assertTrue($filter->isFeatureMatch($feature));
+
+        $feature = new FeatureNode('some feature title', null, array(), null, array(), null, null, null, 1);
+        $this->assertFalse($filter->isFeatureMatch($feature));
+
+        $filter = new NameFilter('/fea.ure/');
+        $this->assertTrue($filter->isFeatureMatch($feature));
+
+        $feature = new FeatureNode('some feaSure title', null, array(), null, array(), null, null, null, 1);
+        $this->assertTrue($filter->isFeatureMatch($feature));
+
+        $feature = new FeatureNode('some feture title', null, array(), null, array(), null, null, null, 1);
+        $this->assertFalse($filter->isFeatureMatch($feature));
+    }
+
+    public function testIsScenarioMatchFilter()
+    {
+        $filter = new NameFilter('scenario1');
+
+        $scenario = new ScenarioNode('UNKNOWN', array(), array(), null, 2);
+        $this->assertFalse($filter->isScenarioMatch($scenario));
+
+        $scenario = new ScenarioNode('scenario1', array(), array(), null, 2);
+        $this->assertTrue($filter->isScenarioMatch($scenario));
+
+        $scenario = new ScenarioNode('scenario1 title', array(), array(), null, 2);
+        $this->assertTrue($filter->isScenarioMatch($scenario));
+
+        $scenario = new ScenarioNode('some scenario title', array(), array(), null, 2);
+        $this->assertFalse($filter->isScenarioMatch($scenario));
+
+        $filter = new NameFilter('/sce.ario/');
+        $this->assertTrue($filter->isScenarioMatch($scenario));
+
+        $filter = new NameFilter('/scen.rio/');
+        $this->assertTrue($filter->isScenarioMatch($scenario));
+    }
+}
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Filter/NarrativeFilterTest.php b/vendor/behat/gherkin/tests/Behat/Gherkin/Filter/NarrativeFilterTest.php
new file mode 100644 (file)
index 0000000..6a50e1e
--- /dev/null
@@ -0,0 +1,34 @@
+<?php
+
+namespace Tests\Behat\Gherkin\Filter;
+
+use Behat\Gherkin\Filter\NarrativeFilter;
+use Behat\Gherkin\Node\FeatureNode;
+
+class NarrativeFilterTest extends FilterTest
+{
+    public function testIsFeatureMatchFilter()
+    {
+        $description = <<<NAR
+In order to be able to read news in my own language
+As a french user
+I need to be able to switch website language to french
+NAR;
+        $feature = new FeatureNode(null, $description, array(), null, array(), null, null, null, 1);
+
+        $filter = new NarrativeFilter('/as (?:a|an) french user/');
+        $this->assertFalse($filter->isFeatureMatch($feature));
+
+        $filter = new NarrativeFilter('/as (?:a|an) french user/i');
+        $this->assertTrue($filter->isFeatureMatch($feature));
+
+        $filter = new NarrativeFilter('/french .*/');
+        $this->assertTrue($filter->isFeatureMatch($feature));
+
+        $filter = new NarrativeFilter('/^french/');
+        $this->assertFalse($filter->isFeatureMatch($feature));
+
+        $filter = new NarrativeFilter('/user$/');
+        $this->assertFalse($filter->isFeatureMatch($feature));
+    }
+}
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Filter/PathsFilterTest.php b/vendor/behat/gherkin/tests/Behat/Gherkin/Filter/PathsFilterTest.php
new file mode 100644 (file)
index 0000000..e106d73
--- /dev/null
@@ -0,0 +1,58 @@
+<?php
+
+namespace Tests\Behat\Gherkin\Filter;
+
+use Behat\Gherkin\Filter\PathsFilter;
+use Behat\Gherkin\Node\FeatureNode;
+
+class PathsFilterTest extends FilterTest
+{
+    public function testIsFeatureMatchFilter()
+    {
+        $feature = new FeatureNode(null, null, array(), null, array(), null, null, __FILE__, 1);
+
+        $filter = new PathsFilter(array(__DIR__));
+        $this->assertTrue($filter->isFeatureMatch($feature));
+
+        $filter = new PathsFilter(array('/abc', '/def', dirname(__DIR__)));
+        $this->assertTrue($filter->isFeatureMatch($feature));
+
+        $filter = new PathsFilter(array('/abc', '/def', __DIR__));
+        $this->assertTrue($filter->isFeatureMatch($feature));
+
+        $filter = new PathsFilter(array('/abc', __DIR__, '/def'));
+        $this->assertTrue($filter->isFeatureMatch($feature));
+
+        $filter = new PathsFilter(array('/abc', '/def', '/wrong/path'));
+        $this->assertFalse($filter->isFeatureMatch($feature));
+    }
+
+    public function testItDoesNotMatchPartialPaths()
+    {
+        $fixtures = __DIR__ . DIRECTORY_SEPARATOR . 'Fixtures' . DIRECTORY_SEPARATOR;
+
+        $feature = new FeatureNode(null, null, array(), null, array(), null, null, $fixtures . 'full_path' . DIRECTORY_SEPARATOR . 'file1', 1);
+
+        $filter = new PathsFilter(array($fixtures . 'full'));
+        $this->assertFalse($filter->isFeatureMatch($feature));
+
+        $filter = new PathsFilter(array($fixtures . 'full' . DIRECTORY_SEPARATOR));
+        $this->assertFalse($filter->isFeatureMatch($feature));
+
+        $filter = new PathsFilter(array($fixtures . 'full_path' . DIRECTORY_SEPARATOR));
+        $this->assertTrue($filter->isFeatureMatch($feature));
+
+        $filter = new PathsFilter(array($fixtures . 'full_path'));
+        $this->assertTrue($filter->isFeatureMatch($feature));
+    }
+
+    public function testItDoesNotMatchIfFileWithSameNameButNotPathExistsInFolder()
+    {
+        $fixtures = __DIR__ . DIRECTORY_SEPARATOR . 'Fixtures' . DIRECTORY_SEPARATOR;
+
+        $feature = new FeatureNode(null, null, array(), null, array(), null, null, $fixtures . 'full_path' . DIRECTORY_SEPARATOR . 'file1', 1);
+
+        $filter = new PathsFilter(array($fixtures . 'full'));
+        $this->assertFalse($filter->isFeatureMatch($feature));
+    }
+}
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Filter/RoleFilterTest.php b/vendor/behat/gherkin/tests/Behat/Gherkin/Filter/RoleFilterTest.php
new file mode 100644 (file)
index 0000000..8e8af3e
--- /dev/null
@@ -0,0 +1,73 @@
+<?php
+
+namespace Tests\Behat\Gherkin\Filter;
+
+use Behat\Gherkin\Filter\RoleFilter;
+use Behat\Gherkin\Node\FeatureNode;
+
+class RoleFilterTest extends FilterTest
+{
+    public function testIsFeatureMatchFilter()
+    {
+        $description = <<<NAR
+In order to be able to read news in my own language
+As a french user
+I need to be able to switch website language to french
+NAR;
+        $feature = new FeatureNode(null, $description, array(), null, array(), null, null, null, 1);
+
+        $filter = new RoleFilter('french user');
+        $this->assertTrue($filter->isFeatureMatch($feature));
+
+        $filter = new RoleFilter('french *');
+        $this->assertTrue($filter->isFeatureMatch($feature));
+
+        $filter = new RoleFilter('french');
+        $this->assertFalse($filter->isFeatureMatch($feature));
+
+        $filter = new RoleFilter('user');
+        $this->assertFalse($filter->isFeatureMatch($feature));
+
+        $filter = new RoleFilter('*user');
+        $this->assertTrue($filter->isFeatureMatch($feature));
+
+        $filter = new RoleFilter('French User');
+        $this->assertTrue($filter->isFeatureMatch($feature));
+
+        $feature = new FeatureNode(null, null, array(), null, array(), null, null, null, 1);
+        $filter = new RoleFilter('French User');
+        $this->assertFalse($filter->isFeatureMatch($feature));
+    }
+
+    public function testFeatureRolePrefixedWithAn()
+    {
+        $description = <<<NAR
+In order to be able to read news in my own language
+As an american user
+I need to be able to switch website language to french
+NAR;
+        $feature = new FeatureNode(null, $description, array(), null, array(), null, null, null, 1);
+
+        $filter = new RoleFilter('american user');
+        $this->assertTrue($filter->isFeatureMatch($feature));
+
+        $filter = new RoleFilter('american *');
+        $this->assertTrue($filter->isFeatureMatch($feature));
+
+        $filter = new RoleFilter('american');
+        $this->assertFalse($filter->isFeatureMatch($feature));
+
+        $filter = new RoleFilter('user');
+        $this->assertFalse($filter->isFeatureMatch($feature));
+
+        $filter = new RoleFilter('*user');
+        $this->assertTrue($filter->isFeatureMatch($feature));
+
+        $filter = new RoleFilter('American User');
+        $this->assertTrue($filter->isFeatureMatch($feature));
+
+        $feature = new FeatureNode(null, null, array(), null, array(), null, null, null, 1);
+        $filter = new RoleFilter('American User');
+        $this->assertFalse($filter->isFeatureMatch($feature));
+    }
+}
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Filter/TagFilterTest.php b/vendor/behat/gherkin/tests/Behat/Gherkin/Filter/TagFilterTest.php
new file mode 100644 (file)
index 0000000..5c6c9ab
--- /dev/null
@@ -0,0 +1,144 @@
+<?php
+
+namespace Tests\Behat\Gherkin\Filter;
+
+use Behat\Gherkin\Filter\TagFilter;
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\ScenarioNode;
+
+class TagFilterTest extends \PHPUnit_Framework_TestCase
+{
+    public function testFilterFeature()
+    {
+        $feature = new FeatureNode(null, null, array('wip'), null, array(), null, null, null, 1);
+        $filter = new TagFilter('@wip');
+        $this->assertEquals($feature, $filter->filterFeature($feature));
+
+        $scenarios = array(
+            new ScenarioNode(null, array(), array(), null, 2),
+            $matchedScenario = new ScenarioNode(null, array('wip'), array(), null, 4)
+        );
+        $feature = new FeatureNode(null, null, array(), null, $scenarios, null, null, null, 1);
+        $filteredFeature = $filter->filterFeature($feature);
+
+        $this->assertSame(array($matchedScenario), $filteredFeature->getScenarios());
+
+        $filter = new TagFilter('~@wip');
+        $scenarios = array(
+            $matchedScenario = new ScenarioNode(null, array(), array(), null, 2),
+            new ScenarioNode(null, array('wip'), array(), null, 4)
+        );
+        $feature = new FeatureNode(null, null, array(), null, $scenarios, null, null, null, 1);
+        $filteredFeature = $filter->filterFeature($feature);
+
+        $this->assertSame(array($matchedScenario), $filteredFeature->getScenarios());
+    }
+
+    public function testIsFeatureMatchFilter()
+    {
+        $feature = new FeatureNode(null, null, array(), null, array(), null, null, null, 1);
+
+        $filter = new TagFilter('@wip');
+        $this->assertFalse($filter->isFeatureMatch($feature));
+
+        $feature = new FeatureNode(null, null, array('wip'), null, array(), null, null, null, 1);
+        $this->assertTrue($filter->isFeatureMatch($feature));
+
+        $filter = new TagFilter('~@done');
+        $this->assertTrue($filter->isFeatureMatch($feature));
+
+        $feature = new FeatureNode(null, null, array('wip', 'done'), null, array(), null, null, null, 1);
+        $this->assertFalse($filter->isFeatureMatch($feature));
+
+        $feature = new FeatureNode(null, null, array('tag1', 'tag2', 'tag3'), null, array(), null, null, null, 1);
+        $filter = new TagFilter('@tag5,@tag4,@tag6');
+        $this->assertFalse($filter->isFeatureMatch($feature));
+
+        $feature = new FeatureNode(null, null, array(
+            'tag1',
+            'tag2',
+            'tag3',
+            'tag5'
+        ), null, array(), null, null, null, 1);
+        $this->assertTrue($filter->isFeatureMatch($feature));
+
+        $filter = new TagFilter('@wip&&@vip');
+        $feature = new FeatureNode(null, null, array('wip', 'done'), null, array(), null, null, null, 1);
+        $this->assertFalse($filter->isFeatureMatch($feature));
+
+        $feature = new FeatureNode(null, null, array('wip', 'done', 'vip'), null, array(), null, null, null, 1);
+        $this->assertTrue($filter->isFeatureMatch($feature));
+
+        $filter = new TagFilter('@wip,@vip&&@user');
+        $feature = new FeatureNode(null, null, array('wip'), null, array(), null, null, null, 1);
+        $this->assertFalse($filter->isFeatureMatch($feature));
+
+        $feature = new FeatureNode(null, null, array('vip'), null, array(), null, null, null, 1);
+        $this->assertFalse($filter->isFeatureMatch($feature));
+
+        $feature = new FeatureNode(null, null, array('wip', 'user'), null, array(), null, null, null, 1);
+        $this->assertTrue($filter->isFeatureMatch($feature));
+
+        $feature = new FeatureNode(null, null, array('vip', 'user'), null, array(), null, null, null, 1);
+        $this->assertTrue($filter->isFeatureMatch($feature));
+    }
+
+    public function testIsScenarioMatchFilter()
+    {
+        $feature = new FeatureNode(null, null, array('feature-tag'), null, array(), null, null, null, 1);
+        $scenario = new ScenarioNode(null, array(), array(), null, 2);
+
+        $filter = new TagFilter('@wip');
+        $this->assertFalse($filter->isScenarioMatch($feature, $scenario));
+
+        $filter = new TagFilter('~@done');
+        $this->assertTrue($filter->isScenarioMatch($feature, $scenario));
+
+        $scenario = new ScenarioNode(null, array(
+            'tag1',
+            'tag2',
+            'tag3'
+        ), array(), null, 2);
+        $filter = new TagFilter('@tag5,@tag4,@tag6');
+        $this->assertFalse($filter->isScenarioMatch($feature, $scenario));
+
+        $scenario = new ScenarioNode(null, array(
+            'tag1',
+            'tag2',
+            'tag3',
+            'tag5'
+        ), array(), null, 2);
+        $this->assertTrue($filter->isScenarioMatch($feature, $scenario));
+
+        $filter = new TagFilter('@wip&&@vip');
+        $scenario = new ScenarioNode(null, array('wip', 'not-done'), array(), null, 2);
+        $this->assertFalse($filter->isScenarioMatch($feature, $scenario));
+
+        $scenario = new ScenarioNode(null, array(
+            'wip',
+            'not-done',
+            'vip'
+        ), array(), null, 2);
+        $this->assertTrue($filter->isScenarioMatch($feature, $scenario));
+
+        $filter = new TagFilter('@wip,@vip&&@user');
+        $scenario = new ScenarioNode(null, array(
+            'wip'
+        ), array(), null, 2);
+        $this->assertFalse($filter->isScenarioMatch($feature, $scenario));
+
+        $scenario = new ScenarioNode(null, array('vip'), array(), null, 2);
+        $this->assertFalse($filter->isScenarioMatch($feature, $scenario));
+
+        $scenario = new ScenarioNode(null, array('wip', 'user'), array(), null, 2);
+        $this->assertTrue($filter->isScenarioMatch($feature, $scenario));
+
+        $filter = new TagFilter('@feature-tag&&@user');
+        $scenario = new ScenarioNode(null, array('wip', 'user'), array(), null, 2);
+        $this->assertTrue($filter->isScenarioMatch($feature, $scenario));
+
+        $filter = new TagFilter('@feature-tag&&@user');
+        $scenario = new ScenarioNode(null, array('wip'), array(), null, 2);
+        $this->assertFalse($filter->isScenarioMatch($feature, $scenario));
+    }
+}
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/directories/phps/some_file.php b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/directories/phps/some_file.php
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/addition.yml b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/addition.yml
new file mode 100644 (file)
index 0000000..7627fe6
--- /dev/null
@@ -0,0 +1,29 @@
+feature:
+  title:        Addition
+  language:     en
+  line:         2
+  description:  |-
+    In order to avoid silly mistakes
+    As a math idiot
+    I want to be told the sum of two numbers
+
+  scenarios:
+    -
+      type:     scenario
+      title:    Add two numbers
+      line:     7
+      steps:
+        - { keyword_type: 'Given', type: 'Given',  text: 'I have entered 11 into the calculator',  line: 8 }
+        - { keyword_type: 'Given', type: 'And',    text: 'I have entered 12 into the calculator',  line: 9 }
+        - { keyword_type: 'When',  type: 'When',   text: 'I press add',                            line: 10 }
+        - { keyword_type: 'Then',  type: 'Then',   text: 'the result should be 23 on the screen',  line: 11 }
+
+    -
+      type:     scenario
+      title:    Div two numbers
+      line:     13
+      steps:
+        - { keyword_type: 'Given', type: 'Given',  text: 'I have entered 10 into the calculator',  line: 14 }
+        - { keyword_type: 'Given', type: 'And',    text: 'I have entered 2 into the calculator',   line: 15 }
+        - { keyword_type: 'When',  type: 'When',   text: 'I press div',                            line: 16 }
+        - { keyword_type: 'Then',  type: 'Then',   text: 'the result should be 5 on the screen',   line: 17 }
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/background.yml b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/background.yml
new file mode 100644 (file)
index 0000000..a7b1a7b
--- /dev/null
@@ -0,0 +1,18 @@
+feature:
+  title:        Feature with background
+  language:     en
+  line:         1
+  description:  ~
+
+  background:
+    line:       3
+    steps:
+      - { keyword_type: Given, type: Given, text: a passing step, line: 4 }
+
+  scenarios:
+    -
+      type:     scenario
+      title:    ~
+      line:     6
+      steps:
+        - { keyword_type: Given, type: Given, text: a failing step, line: 7 }
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/background_title.yml b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/background_title.yml
new file mode 100644 (file)
index 0000000..f69277d
--- /dev/null
@@ -0,0 +1,26 @@
+feature:
+  title:        Feature with titled background
+  language:     en
+  line:         1
+  description:  ~
+
+  background:
+    line:       3
+    title:      |-
+      Some Background
+      title with
+       couple
+        of
+         | continuous  |
+       """
+       strings
+    steps:
+      - { keyword_type: Given, type: Given, text: a passing step, line: 10 }
+
+  scenarios:
+    -
+      type:     scenario
+      title:    ~
+      line:     12
+      steps:
+        - { keyword_type: Given, type: Given, text: a failing step, line: 13 }
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/big_pystring.yml b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/big_pystring.yml
new file mode 100644 (file)
index 0000000..31089fd
--- /dev/null
@@ -0,0 +1,18 @@
+feature:
+  line:         1
+  title:        Big PyString
+
+  scenarios:
+    -
+      type:     scenario
+      line:     2
+      steps:
+        -
+          keyword_type: Then
+          type:         Then
+          text:         it should fail with:
+          line:         3
+          arguments:
+            -
+              type:     pystring
+              text:     "\n# language: ru\n\nUUUUUU\n\n2 scenarios (2 undefined)\n6 steps (6 undefined)\n\nYou can implement step definitions for undefined steps with these snippets:\n\n$steps->Given('/^I have entered (\\d+)$/', function($world, $arg1) {\n    throw new \\Everzet\\Behat\\Exception\\Pending();\n});\n\n$steps->Then('/^I must have (\\d+)$/', function($world, $arg1) {\n    throw new \\Everzet\\Behat\\Exception\\Pending();\n});\n\n$steps->Then('/^String must be \\'([^\\']*)\\'$/', function($world, $arg1) {\n    throw new \\Everzet\\Behat\\Exception\\Pending();\n});"
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/clean_tags.yml b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/clean_tags.yml
new file mode 100644 (file)
index 0000000..014c8d3
--- /dev/null
@@ -0,0 +1,20 @@
+feature:
+  title:        Feature N4
+  line:         1
+  description:  ~
+
+  scenarios:
+    -
+      type:     scenario
+      tags:     [normal]
+      line:     4
+      steps:
+        - { keyword_type: 'Given', type: 'Given',  text: 'Some normal step N41',   line: 5 }
+        - { keyword_type: 'Given',   type: 'And',    text: 'Some fast step N42',     line: 6 }
+
+    -
+      type:     scenario
+      tags:     [fast]
+      line:     9
+      steps:
+        - { keyword_type: 'Given', type: 'Given',  text: 'Some slow step N43',     line: 10 }
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/commented_out.yml b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/commented_out.yml
new file mode 100644 (file)
index 0000000..a8a2c51
--- /dev/null
@@ -0,0 +1,10 @@
+feature:
+  title:        Fibonacci
+  language:     en
+  line:         1
+  description:  |-
+    In order to calculate super fast fibonacci series
+    As a pythonista
+    I want to use Python for that
+
+  scenarios:    ~
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/comments.yml b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/comments.yml
new file mode 100644 (file)
index 0000000..2ae46cb
--- /dev/null
@@ -0,0 +1,21 @@
+feature:
+  title:        Using the Console Formatter
+  language:     en
+  line:         3
+  description:  |-
+    In order to verify this error   # comment
+
+
+
+      I want to run this feature using the progress format#comment
+    So that it can be fixed
+
+  scenarios:
+    -
+      type:     scenario
+      title:    "A normal feature #comment in scenario title"
+      line:     19
+      steps:
+        - { keyword_type: 'Given', type: 'Given',  text: 'I have a pending step #comment',                       line: 21 }
+        - { keyword_type: 'When',  type: 'When',   text: 'I run this feature with the progress format #comment', line: 24 }
+        - { keyword_type: 'Then',  type: 'Then',   text: "I should get a no method error for 'backtrace_line'",  line: 31 }
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/complex_descriptions.yml b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/complex_descriptions.yml
new file mode 100644 (file)
index 0000000..d0d65dc
--- /dev/null
@@ -0,0 +1,26 @@
+feature:
+  title:        Complex descriptions
+  language:     en
+  line:         7
+  description:  |-
+    Some description with
+    | table |   row|
+
+      and
+
+    """
+    """
+
+  scenarios:
+    -
+      type:     scenario
+      title:    |-
+        Some
+         | complex |  description     |
+
+        """
+        hell yeah
+        """
+      line:     16
+      steps:
+        - { keyword_type: 'Given', type: 'Given',  text: 'one two three',  line: 22 }
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/empty.yml b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/empty.yml
new file mode 100644 (file)
index 0000000..e13f363
--- /dev/null
@@ -0,0 +1,7 @@
+feature:
+  title:        Some feature
+  language:     en
+  line:         1
+  description:  ~
+
+  scenarios: []
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/empty_scenario.yml b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/empty_scenario.yml
new file mode 100644 (file)
index 0000000..43e7201
--- /dev/null
@@ -0,0 +1,13 @@
+feature:
+  title:        Cucumber command line
+  language:     en
+  line:         1
+  description:  |-
+    In order to write better software
+    Developers should be able to execute requirements as tests
+
+  scenarios:
+    -
+      type:     scenario
+      title:    Pending Scenario at the end of a file with whitespace after it
+      line:     6
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/empty_scenario_without_linefeed.yml b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/empty_scenario_without_linefeed.yml
new file mode 100644 (file)
index 0000000..43e7201
--- /dev/null
@@ -0,0 +1,13 @@
+feature:
+  title:        Cucumber command line
+  language:     en
+  line:         1
+  description:  |-
+    In order to write better software
+    Developers should be able to execute requirements as tests
+
+  scenarios:
+    -
+      type:     scenario
+      title:    Pending Scenario at the end of a file with whitespace after it
+      line:     6
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/empty_scenarios.yml b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/empty_scenarios.yml
new file mode 100644 (file)
index 0000000..35a144b
--- /dev/null
@@ -0,0 +1,30 @@
+feature:
+  title:        Math
+  language:     en
+  line:         1
+  description:  |-
+    In order to avoid silly mistakes
+    As a math idiot
+    I want to be told the calculation of two numbers
+
+  scenarios:
+    -
+      type:  scenario
+      title: Add two numbers
+      line:  6
+      steps: []
+    -
+      type:  scenario
+      title: Div two numbers
+      line:  7
+      steps: []
+    -
+      type:  scenario
+      title: Multiply two numbers
+      line:  9
+      steps: []
+    -
+      type:  scenario
+      title: Sub two numbers
+      line:  12
+      steps: []
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/fibonacci.yml b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/fibonacci.yml
new file mode 100644 (file)
index 0000000..c450a8b
--- /dev/null
@@ -0,0 +1,27 @@
+feature:
+  title:        Fibonacci
+  language:     en
+  line:         1
+  description:  |-
+    In order to calculate super fast fibonacci series
+    As a pythonista
+    I want to use Python for that
+
+  scenarios:
+    -
+      type:     outline
+      title:    Series
+      line:     6
+      steps:
+        - { keyword_type: 'When', type: 'When',  text: 'I ask python to calculate fibonacci up to <n>', line: 7 }
+        - { keyword_type: 'Then', type: 'Then',  text: 'it should give me <series>',                    line: 8 }
+
+      examples:
+        11: [ n   , series                                   ]
+        12: [ 1   , '[]'                                     ]
+        13: [ 2   , '[1, 1]'                                 ]
+        14: [ 3   , '[1, 1, 2]'                              ]
+        15: [ 4   , '[1, 1, 2, 3]'                           ]
+        16: [ 6   , '[1, 1, 2, 3, 5]'                        ]
+        17: [ 9   , '[1, 1, 2, 3, 5, 8]'                     ]
+        18: [ 100 , '[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]' ]
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/hashes_in_quotes.yml b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/hashes_in_quotes.yml
new file mode 100644 (file)
index 0000000..55abe3b
--- /dev/null
@@ -0,0 +1,29 @@
+feature:
+  title:        "Some '#quoted' string"
+  language:     en
+  line:         2
+  description:  |-
+    In order to avoid silly mistakes
+    As a "#math" idiot
+    I want to be told the sum of two numbers
+
+  scenarios:
+    -
+      type:     scenario
+      title:    Add two numbers
+      line:     7
+      steps:
+        - { keyword_type: 'Given', type: 'Given',  text: 'I have entered 11 into the calculator',  line: 8 }
+        - { keyword_type: 'Given', type: 'And',    text: 'I have entered 12 into the calculator',  line: 9 }
+        - { keyword_type: 'When',  type: 'When',   text: 'I press "#add"',                         line: 10 }
+        - { keyword_type: 'Then',  type: 'Then',   text: 'the result should be 23 on the screen',  line: 11 }
+
+    -
+      type:     scenario
+      title:    'Div "#two" numbers # as'
+      line:     13
+      steps:
+        - { keyword_type: 'Given', type: 'Given',  text: 'I have entered 10 into the calculator',  line: 14 }
+        - { keyword_type: 'Given', type: 'And',    text: 'I have entered # 2 into the calculator', line: 15 }
+        - { keyword_type: 'When',  type: 'When',   text: 'I press div',                            line: 16 }
+        - { keyword_type: 'Then',  type: 'Then',   text: 'the result should be 5 on the screen',   line: 17 }
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/issue_13.yml b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/issue_13.yml
new file mode 100644 (file)
index 0000000..091103c
--- /dev/null
@@ -0,0 +1,49 @@
+feature:
+  title:        test pystring
+  description:  second line
+  language:     en
+  line:         1
+
+  scenarios:
+    -
+      type:     scenario
+      title:    |-
+        testing py string in scenario
+        second line
+      line:     4
+      steps:
+        -
+          keyword_type: Given
+          type:         Given
+          text:         the pystring is
+          line:         7
+          arguments:
+            -
+              type: pystring
+              text: |-
+                Test store name
+                Denmark, Kolding
+                6000
+
+    -
+      type:     outline
+      title:    |-
+        testing py string in scenario outline
+        second line
+      line:     14
+      steps:
+        -
+          keyword_type: Given
+          type:         Given
+          text:         the pystring is
+          line:         17
+          arguments:
+          arguments:
+            -
+              type: pystring
+              text: |-
+                Test store name
+                Denmark, Kolding
+                6000
+      examples:
+        24: ['']
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/ja_addition.yml b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/ja_addition.yml
new file mode 100644 (file)
index 0000000..6ac42d4
--- /dev/null
@@ -0,0 +1,21 @@
+feature:
+  title:        '加算'
+  keyword:      'フィーチャ'
+  language:     ja
+  line:         2
+  description:  |-
+    バカな間違いを避けるために
+    数学オンチとして
+    2つの数の合計を知りたい
+
+  scenarios:
+    -
+      type:     scenario
+      keyword:  'シナリオ'
+      title:    '2つの数の加算について'
+      line:     7
+      steps:
+        - { keyword_type: 'Given',  type: '前提',   text: '50 を入力',         line: 8 }
+        - { keyword_type: 'Given',  type: 'かつ',   text: '70 を入力',         line: 9 }
+        - { keyword_type: 'When',  type: 'もし',   text: 'add ボタンを押した',  line: 10 }
+        - { keyword_type: 'Then', type: 'ならば',  text: '結果は 120 を表示',  line: 11 }
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/long_title_feature.yml b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/long_title_feature.yml
new file mode 100644 (file)
index 0000000..7e30cf5
--- /dev/null
@@ -0,0 +1,13 @@
+feature:
+  title:        https://rspec.lighthouseapp.com/projects/16211/tickets/246-distorted-console-output-for-slightly-complicated-step-regexp-match
+  language:     en
+  line:         1
+  description:  ~
+
+  scenarios:
+    -
+      type:     scenario
+      title:    See "No Record(s) Found" for Zero Existing
+      line:     3
+      steps:
+        - { keyword_type: Given, type: Given, text: no public holiday exists in the system, line: 4 }
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/multiline_name.yml b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/multiline_name.yml
new file mode 100644 (file)
index 0000000..b41bc58
--- /dev/null
@@ -0,0 +1,44 @@
+feature:
+  title:        multiline
+  language:     en
+  line:         1
+  description:  ~
+
+  background:
+    line:       3
+    steps:
+      - { keyword_type: Given, type: Given, text: passing without a table, line: 4 }
+
+  scenarios:
+    -
+      type:     scenario
+      title:    |-
+        I'm a multiline name
+                which goes on and on and on for three lines
+                yawn
+      line:     6
+      steps:
+        - { keyword_type: Given, type: Given, text: passing without a table, line: 9 }
+
+    -
+      type:     outline
+      title:    |-
+        I'm a multiline name
+        which goes on and on and on for three lines
+                        yawn
+      line:     11
+      steps:
+        - { keyword_type: Given, type: 'Given',  text: '<state> without a table',  line: 14 }
+      examples:
+        16: [state]
+        17: [passing]
+
+    -
+      type:     outline
+      title:    name
+      line:     19
+      steps:
+        - { keyword_type: Given, type: 'Given',  text: '<state> without a table',  line: 20 }
+      examples:
+        22: [state]
+        23: [passing]
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/multiline_name_with_newlines.yml b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/multiline_name_with_newlines.yml
new file mode 100644 (file)
index 0000000..d7aebc0
--- /dev/null
@@ -0,0 +1,65 @@
+feature:
+  title:        multiline
+  language:     en
+  line:         1
+  description:  |-
+
+    Feature description
+
+    With etc.
+
+  background:
+    line:       8
+    steps:
+      - { keyword_type: Given, type: Given, text: passing without a table, line: 11 }
+
+  scenarios:
+    -
+      type:     scenario
+      title:    |-
+
+        I'm a multiline name
+        which goes on and on and on for three lines
+        yawn
+      line:     13
+      steps:
+        - { keyword_type: Given, type: Given, text: passing without a table, line: 19 }
+
+    -
+      type:     outline
+      title:    |-
+        I'm a multiline name
+
+                        which goes on and on and on for three lines
+
+        yawn
+      line:     21
+      steps:
+        - { keyword_type: 'Given', type: 'Given',  text: '<state> without a table',  line: 28 }
+      examples:
+        34: [state]
+        35: [passing]
+
+    -
+      type:     outline
+      title:    name
+      line:     37
+      steps:
+        - { keyword_type: 'Given', type: 'Given',  text: '<state> without a table',  line: 40 }
+      examples:
+        45: [state]
+        46: [passing]
+    -
+      type:     outline
+      title:    |-
+
+
+        I'm a multiline name
+        which goes on and on and on for three lines
+        yawn
+      line:     48
+      steps:
+        - { keyword_type: 'Given', type: 'Given',  text: '<state> without a table',  line: 55 }
+      examples:
+        60: [state]
+        61: [passing]
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/multiplepystrings.yml b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/multiplepystrings.yml
new file mode 100644 (file)
index 0000000..6c73bba
--- /dev/null
@@ -0,0 +1,47 @@
+feature:
+  title:        A multiple py string feature
+  line:         1
+  language:     en
+  description:  ~
+
+  scenarios:
+    -
+      type:     scenario
+      title:    ~
+      line:     3
+      steps:
+        -
+          keyword_type: When
+          type:         When
+          text:         I enter a string
+          line:         4
+          arguments:
+            -
+              type:     pystring
+              text:     |-
+                -
+                   a string
+                  with something
+                be
+                a
+                u
+                  ti
+                    ful
+
+        -
+          keyword_type: Then
+          type:         Then
+          text:         String must be
+          line:         15
+          arguments:
+            -
+              type:     pystring
+              text:     |-
+                -
+                   a string
+                  with something
+                be
+                a
+                u
+                  ti
+                    ful
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/outline_with_spaces.yml b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/outline_with_spaces.yml
new file mode 100644 (file)
index 0000000..c6e8977
--- /dev/null
@@ -0,0 +1,33 @@
+feature:
+  title:        Login
+  language:     en
+  line:         1
+  description:  |-
+    To ensure the safety of the application
+    A regular user of the system
+    Must authenticate before using the app
+
+  scenarios:
+    -
+      type:     outline
+      title:    Failed Login
+      line:     7
+      steps:
+        - { keyword_type: 'Given', type: 'Given',  text: 'the user "known_user"',                  line: 8 }
+        - { keyword_type: 'When',  type: 'When',   text: 'I go to the main page',                  line: 10 }
+        - { keyword_type: 'Then',  type: 'Then',   text: 'I should see the login form',            line: 11 }
+        - { keyword_type: 'When',  type: 'When',   text: 'I fill in "login" with "<login>"',       line: 13 }
+        - { keyword_type: 'When',  type: 'And',    text: 'I fill in "password" with "<password>"', line: 14 }
+        - { keyword_type: 'When',  type: 'And',    text: 'I press "Log In"',                       line: 15 }
+        - { keyword_type: 'Then',  type: 'Then',   text: 'the login request should fail',          line: 16 }
+        - { keyword_type: 'Then',  type: 'And',    text: 'I should see the error message "Login or Password incorrect"',  line: 17 }
+      examples:
+        20: [login, password]
+        21: ['', '']
+        22: [unknown_user, '']
+        23: [known_user, '']
+        24: ['', wrong_password]
+        25: ['', known_userpass]
+        26: [unknown_user, wrong_password]
+        27: [unknown_user, known_userpass]
+        28: [known_user, wrong_password]
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/outline_with_step_table.yml b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/outline_with_step_table.yml
new file mode 100644 (file)
index 0000000..8c59ff1
--- /dev/null
@@ -0,0 +1,29 @@
+feature:
+  title:        Unsubstituted argument placeholder
+  language:     en
+  line:         1
+  description:  ~
+
+  scenarios:
+    -
+      type:     outline
+      title:    'See Annual Leave Details (as Management & Human Resource)'
+      line:     3
+      steps:
+        -
+          keyword_type: Given
+          type:         Given
+          text:         the following users exist in the system
+          line:         4
+          arguments:
+            -
+              type:   table
+              rows:
+                5: [ name, email, role_assignments, group_memberships ]
+                6: [ Jane, jane@fmail.com, <role>, Sales (manager) ]
+                7: [ Max, max@fmail.com, '', Sales (member) ]
+                8: [ Carol, carol@fmail.com, '', Sales (member) ]
+                9: [ Cat, cat@fmail.com, '', '' ]
+      examples:
+        12: [ role ]
+        13: [ HUMAN RESOURCE ]
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/pystring.yml b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/pystring.yml
new file mode 100644 (file)
index 0000000..bc21a9a
--- /dev/null
@@ -0,0 +1,22 @@
+feature:
+  title:        A py string feature
+  language:     en
+  line:         1
+  description:  ~
+
+  scenarios:
+    -
+      type:     scenario
+      title:    ~
+      line:     3
+      steps:
+        -
+          keyword_type: Then
+          type:         Then
+          text:         I should see
+          line:         4
+          arguments:
+            -
+              type:     pystring
+              swallow:  6
+              text:     "a string with #something"
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/ru_addition.yml b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/ru_addition.yml
new file mode 100644 (file)
index 0000000..9c0db4a
--- /dev/null
@@ -0,0 +1,21 @@
+feature:
+  title:        Сложение чисел
+  keyword:      Функционал
+  language:     ru
+  line:         2
+  description:  |-
+    Чтобы не складывать в уме
+    Все, у кого с этим туго
+    Хотят автоматическое сложение целых чисел
+
+  scenarios:
+    -
+      type:     scenario
+      keyword:  Сценарий
+      title:    Сложение двух целых чисел
+      line:     7
+      steps:
+        - { keyword_type: 'Given', type: 'Допустим', text: 'я ввожу число 50',                   line: 8 }
+        - { keyword_type: 'Given', type: 'И',        text: 'затем ввожу число 70',               line: 9 }
+        - { keyword_type: 'Then',  type: 'Если',     text: 'я нажимаю "+"',                      line: 10 }
+        - { keyword_type: 'When',  type: 'То',       text: 'результатом должно быть число 120',  line: 11 }
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/ru_commented.yml b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/ru_commented.yml
new file mode 100644 (file)
index 0000000..1097d5d
--- /dev/null
@@ -0,0 +1,11 @@
+feature:
+  title:        Тест комментов
+  keyword:      Функционал
+  language:     ru
+  line:         7
+  description:  |-
+    i18n должен правильно считываться
+    Даже если в начале файла 1000
+    комментов!
+
+  scenarios:    ~
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/ru_consecutive_calculations.yml b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/ru_consecutive_calculations.yml
new file mode 100644 (file)
index 0000000..358d867
--- /dev/null
@@ -0,0 +1,34 @@
+feature:
+  title:        Последовательные вычисления
+  keyword:      Функционал
+  language:     ru
+  line:         2
+  description:  |-
+    Чтобы вычислять сложные выражения
+    Пользователи хотят проводить вычисления над результатом предыдущей операций
+
+  background:
+    keyword:    Предыстория
+    line:       6
+    steps:
+      - { keyword_type: Given, type: Допустим, text: я сложил 3 и 5, line: 7 }
+
+  scenarios:
+    -
+      type:     scenario
+      keyword:  Сценарий
+      title:    сложение с результатом последней операций
+      line:     9
+      steps:
+        - { keyword_type: Then, type: Если, text: 'я ввожу число 4',                  line: 10 }
+        - { keyword_type: Then, type: И,    text: 'нажимаю "+"',                      line: 11 }
+        - { keyword_type: When, type: То,   text: 'результатом должно быть число 12', line: 12 }
+    -
+      type:     scenario
+      keyword:  Сценарий
+      title:    деление результата последней операции
+      line:     14
+      steps:
+        - { keyword_type: Then, type: Если, text: 'я ввожу число 2',                  line: 15 }
+        - { keyword_type: Then, type: И,    text: 'нажимаю "/"',                      line: 16 }
+        - { keyword_type: When, type: То,   text: 'результатом должно быть число 4',  line: 17 }
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/ru_division.yml b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/ru_division.yml
new file mode 100644 (file)
index 0000000..b4d3005
--- /dev/null
@@ -0,0 +1,27 @@
+feature:
+  title:        Деление чисел
+  keyword:      Функционал
+  language:     ru
+  line:         2
+  description:  |-
+    Поскольку деление сложный процесс и люди часто допускают ошибки
+    Нужно дать им возможность делить на калькуляторе
+
+  scenarios:
+    -
+      type:     outline
+      keyword:  Структура сценария
+      title:    Целочисленное деление
+      line:     6
+      steps:
+        - { keyword_type: Given, type: 'Допустим', text: 'я ввожу число <делимое>',                  line: 7 }
+        - { keyword_type: Given, type: 'И',        text: 'затем ввожу число <делитель>',             line: 8 }
+        - { keyword_type: Then,  type: 'Если',     text: 'я нажимаю "/"',                            line: 9 }
+        - { keyword_type: When,  type: 'То',       text: 'результатом должно быть число <частное>',  line: 10 }
+
+      examples:
+        keyword: Значения
+        13: [делимое, делитель, частное]
+        14: [100, 2, 50]
+        15: [28, 7, 4]
+        16: [0, 5, 0]
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/start_comments.yml b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/start_comments.yml
new file mode 100644 (file)
index 0000000..45fcd77
--- /dev/null
@@ -0,0 +1,18 @@
+feature:
+  title:        Using the Console Formatter
+  language:     en
+  line:         3
+  description:  |-
+    In order to verify this error
+    I want to run this feature using the progress format
+    So that it can be fixed
+
+  scenarios:
+    -
+      type:     scenario
+      title:    A normal feature
+      line:     8
+      steps:
+        - { keyword_type: 'Given', type: 'Given',  text: 'I have a pending step',                                line: 9 }
+        - { keyword_type: 'When',  type: 'When',   text: 'I run this feature with the progress format',          line: 10 }
+        - { keyword_type: 'Then',  type: 'Then',   text: "I should get a no method error for 'backtrace_line'",  line: 11 }
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/tables.yml b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/tables.yml
new file mode 100644 (file)
index 0000000..9796666
--- /dev/null
@@ -0,0 +1,42 @@
+feature:
+  title:        A scenario outline
+  language:     en
+  line:         1
+  description:  ~
+
+  scenarios:
+    -
+      type:     outline
+      title:    ~
+      line:     3
+      steps:
+        - { keyword_type: Given, type: Given, text: I add <a> and <b>, line: 4 }
+        -
+          keyword_type: When
+          type:         When
+          text:         I pass a table argument
+          line:         6
+          arguments:
+            -
+              type:   table
+              rows:
+                7: [foo, bar]
+                8: [bar, baz]
+        - { keyword_type: Then, type: Then, text: I the result should be <c>, line: 10 }
+        -
+          keyword_type: Then
+          type:         And
+          text:         the table should be properly escaped:
+          line:         12
+          arguments:
+            -
+              type:   table
+              rows:
+                13: ['|a', b, c]
+                14: [1, '|2', 3]
+                15: [2, 3, '|4']
+
+      examples:
+        18: [ a, b, c ]
+        19: [ 1, '|2', 3 ]
+        20: [ 2, 3, 4 ]
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/tags_sample.yml b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/tags_sample.yml
new file mode 100644 (file)
index 0000000..486d958
--- /dev/null
@@ -0,0 +1,35 @@
+feature:
+  title:        Tag samples
+  language:     en
+  tags:         [sample_one]
+  line:         2
+  description:  ~
+
+  scenarios:
+    -
+      type:     scenario
+      title:    Passing
+      tags:     [sample_two, sample_four]
+      line:     5
+      steps:
+        - { keyword_type: 'Given', type: 'Given',  text: 'missing',  line: 6 }
+
+    -
+      type:     outline
+      title:    ~
+      tags:     [sample_three]
+      line:     9
+      steps:
+        - { keyword_type: 'Given', type: 'Given',  text: '<state>',  line: 10 }
+
+      examples:
+        12: [state]
+        13: [missing]
+
+    -
+      type:     scenario
+      title:    Skipped
+      tags:     [sample_three, sample_four]
+      line:     16
+      steps:
+        - { keyword_type: 'Given', type: 'Given',  text: 'missing',  line: 17 }
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/test_unit.yml b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/test_unit.yml
new file mode 100644 (file)
index 0000000..fca7e20
--- /dev/null
@@ -0,0 +1,18 @@
+feature:
+  title:        Test::Unit
+  language:     en
+  line:         1
+  description:  |-
+    In order to please people who like Test::Unit
+    As a Cucumber user
+    I want to be able to use assert* in my step definitions
+
+  scenarios:
+    -
+      type:     scenario
+      title:    assert_equal
+      line:     6
+      steps:
+        - { keyword_type: 'Given', type: 'Given',  text: 'x = 5',                    line: 7 }
+        - { keyword_type: 'Given', type: 'And',    text: 'y = 5',                    line: 8 }
+        - { keyword_type: 'Then',  type: 'Then',   text: 'I can assert that x == y', line: 9 }
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/trimpystring.yml b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/trimpystring.yml
new file mode 100644 (file)
index 0000000..3857fdf
--- /dev/null
@@ -0,0 +1,29 @@
+feature:
+  title:        A py string feature
+  language:     en
+  line:         1
+  description:  ~
+
+  scenarios:
+    -
+      type:     scenario
+      title:    ~
+      line:     3
+      steps:
+        -
+          keyword_type: Then
+          type:         Then
+          text:         String must be
+          line:         4
+          arguments:
+            -
+              type:     pystring
+              text:     |-
+                -
+                   a string
+                  with something
+                be
+                a
+                u
+                  ti
+                    ful
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/undefined_multiline_args.yml b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/etalons/undefined_multiline_args.yml
new file mode 100644 (file)
index 0000000..84cb8ff
--- /dev/null
@@ -0,0 +1,38 @@
+feature:
+  title:        undefined multiline args
+  language:     en
+  line:         1
+  description:  ~
+
+  scenarios:
+    -
+      type:     scenario
+      title:    pystring
+      line:     3
+      steps:
+        -
+          keyword_type: Given
+          type:         Given
+          text:         a pystring
+          line:         4
+          arguments:
+            -
+              type:     pystring
+              text:     '  example'
+
+    -
+      type:     scenario
+      title:    table
+      line:     9
+      steps:
+        -
+          keyword_type: Given
+          type:         Given
+          text:         a table
+          line:         10
+          arguments:
+            -
+              type:     table
+              rows:
+                11: [table]
+                12: [example]
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/addition.feature b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/addition.feature
new file mode 100644 (file)
index 0000000..744184f
--- /dev/null
@@ -0,0 +1,17 @@
+# language: en
+Feature: Addition
+  In order to avoid silly mistakes
+  As a math idiot 
+  I want to be told the sum of two numbers
+
+  Scenario: Add two numbers
+    Given I have entered 11 into the calculator
+    And I have entered 12 into the calculator
+    When I press add
+    Then the result should be 23 on the screen
+
+  Scenario: Div two numbers
+    Given I have entered 10 into the calculator
+    And I have entered 2 into the calculator
+    When I press div
+    Then the result should be 5 on the screen
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/background.feature b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/background.feature
new file mode 100644 (file)
index 0000000..9a3ffb8
--- /dev/null
@@ -0,0 +1,7 @@
+Feature: Feature with background
+  
+  Background:
+    Given a passing step
+
+  Scenario: 
+    Given a failing step
\ No newline at end of file
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/background_title.feature b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/background_title.feature
new file mode 100644 (file)
index 0000000..d8ed4d3
--- /dev/null
@@ -0,0 +1,13 @@
+Feature: Feature with titled background
+
+  Background: Some Background
+    title with
+     couple
+      of
+       | continuous  |
+     """
+     strings
+    Given a passing step
+
+  Scenario:
+    Given a failing step
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/big_pystring.feature b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/big_pystring.feature
new file mode 100644 (file)
index 0000000..900d6c7
--- /dev/null
@@ -0,0 +1,26 @@
+Feature: Big PyString
+  Scenario:
+    Then it should fail with:
+      """
+
+      # language: ru
+
+      UUUUUU
+
+      2 scenarios (2 undefined)
+      6 steps (6 undefined)
+
+      You can implement step definitions for undefined steps with these snippets:
+
+      $steps->Given('/^I have entered (\d+)$/', function($world, $arg1) {
+          throw new \Everzet\Behat\Exception\Pending();
+      });
+
+      $steps->Then('/^I must have (\d+)$/', function($world, $arg1) {
+          throw new \Everzet\Behat\Exception\Pending();
+      });
+
+      $steps->Then('/^String must be \'([^\']*)\'$/', function($world, $arg1) {
+          throw new \Everzet\Behat\Exception\Pending();
+      });
+      """
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/clean_tags.feature b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/clean_tags.feature
new file mode 100644 (file)
index 0000000..e3e9cc7
--- /dev/null
@@ -0,0 +1,10 @@
+Feature: Feature N4
+
+  @normal
+  Scenario:
+    Given Some normal step N41
+    And Some fast step N42
+
+  @fast
+  Scenario:
+    Given Some slow step N43
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/commented_out.feature b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/commented_out.feature
new file mode 100644 (file)
index 0000000..61d7bef
--- /dev/null
@@ -0,0 +1,34 @@
+Feature: Fibonacci
+  In order to calculate super fast fibonacci series
+  As a pythonista
+  I want to use Python for that
+
+#
+#  Background:
+#    Given passing without a table
+#
+#  Scenario: I'm a multiline name
+#            which goes on and on and on for three lines
+#            yawn
+#    Given passing without a table
+#
+#  Scenario:
+#    Then I should see
+#      """
+#      a string with #something
+#      """
+#
+#  Scenario Outline: Series
+#    When I ask python to calculate fibonacci up to <n>
+#    Then it should give me <series>
+#
+#    Examples:
+#      | n   | series                                 |
+#      | 1   | []                                     |
+#      | 2   | [1, 1]                                 |
+#      | 3   | [1, 1, 2]                              |
+#      | 4   | [1, 1, 2, 3]                           |
+#      | 6   | [1, 1, 2, 3, 5]                        |
+#      | 9   | [1, 1, 2, 3, 5, 8]                     |
+#      | 100 | [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89] |
+#
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/comments.feature b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/comments.feature
new file mode 100644 (file)
index 0000000..02ca25c
--- /dev/null
@@ -0,0 +1,32 @@
+# Users want to use cucumber, so tests are necessary to verify
+# it is all working as expected
+Feature: Using the Console Formatter
+# com
+# comment
+#com
+  In order to verify this error   # comment
+
+
+
+    I want to run this feature using the progress format#comment
+  # COMMENT
+  # COMMENT
+  # COMMENT
+  # COMMENT
+  So that it can be fixed
+
+  #comment
+  Scenario: A normal feature #comment in scenario title
+    #comment
+    Given I have a pending step #comment
+    #comment
+    #comment
+    When  I run this feature with the progress format #comment
+
+
+#comment
+  #comment
+    #comment
+
+    Then  I should get a no method error for 'backtrace_line'
+
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/complex_descriptions.feature b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/complex_descriptions.feature
new file mode 100644 (file)
index 0000000..4db3b87
--- /dev/null
@@ -0,0 +1,22 @@
+# language: en
+
+# multiline
+# comment
+# YEAH
+
+Feature: Complex descriptions
+  Some description with
+  | table |   row|
+
+    and
+
+  """
+  """
+
+    Scenario: Some
+       | complex |  description     |
+
+"""
+hell yeah
+"""
+Given one two three
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/empty.feature b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/empty.feature
new file mode 100644 (file)
index 0000000..8a560d7
--- /dev/null
@@ -0,0 +1,2 @@
+Feature: Some feature
+#
\ No newline at end of file
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/empty_scenario.feature b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/empty_scenario.feature
new file mode 100644 (file)
index 0000000..6c661c1
--- /dev/null
@@ -0,0 +1,7 @@
+Feature: Cucumber command line
+  In order to write better software
+  Developers should be able to execute requirements as tests
+  
+
+  Scenario: Pending Scenario at the end of a file with whitespace after it
+  
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/empty_scenario_without_linefeed.feature b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/empty_scenario_without_linefeed.feature
new file mode 100644 (file)
index 0000000..7e17ff2
--- /dev/null
@@ -0,0 +1,7 @@
+Feature: Cucumber command line
+  In order to write better software
+  Developers should be able to execute requirements as tests
+
+
+  Scenario: Pending Scenario at the end of a file with whitespace after it
+    #
\ No newline at end of file
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/empty_scenarios.feature b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/empty_scenarios.feature
new file mode 100644 (file)
index 0000000..f17bef5
--- /dev/null
@@ -0,0 +1,12 @@
+Feature: Math
+  In order to avoid silly mistakes
+  As a math idiot
+  I want to be told the calculation of two numbers
+
+  Scenario: Add two numbers
+  Scenario: Div two numbers
+
+  Scenario: Multiply two numbers
+
+
+  Scenario: Sub two numbers
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/fibonacci.feature b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/fibonacci.feature
new file mode 100644 (file)
index 0000000..4a743ea
--- /dev/null
@@ -0,0 +1,19 @@
+Feature: Fibonacci
+  In order to calculate super fast fibonacci series
+  As a pythonista
+  I want to use Python for that
+  
+  Scenario Outline: Series
+    When I ask python to calculate fibonacci up to <n>
+    Then it should give me <series>
+
+    Examples:
+      | n   | series                                 |
+      | 1   | []                                     |
+      | 2   | [1, 1]                                 |
+      | 3   | [1, 1, 2]                              |
+      | 4   | [1, 1, 2, 3]                           |
+      | 6   | [1, 1, 2, 3, 5]                        |
+      | 9   | [1, 1, 2, 3, 5, 8]                     |
+      | 100 | [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89] |
+  
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/hashes_in_quotes.feature b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/hashes_in_quotes.feature
new file mode 100644 (file)
index 0000000..e08fa70
--- /dev/null
@@ -0,0 +1,17 @@
+# language: en
+Feature: Some '#quoted' string
+  In order to avoid silly mistakes
+  As a "#math" idiot 
+  I want to be told the sum of two numbers
+
+  Scenario: Add two numbers
+    Given I have entered 11 into the calculator
+    And I have entered 12 into the calculator
+    When I press "#add"
+    Then the result should be 23 on the screen
+
+  Scenario: Div "#two" numbers # as
+    Given I have entered 10 into the calculator
+    And I have entered # 2 into the calculator
+    When I press div
+    Then the result should be 5 on the screen
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/issue_13.feature b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/issue_13.feature
new file mode 100644 (file)
index 0000000..4218a97
--- /dev/null
@@ -0,0 +1,24 @@
+Feature: test pystring
+second line
+
+Scenario: testing py string in scenario
+second line
+
+Given the pystring is
+"""
+Test store name
+Denmark, Kolding
+6000
+"""
+
+Scenario Outline: testing py string in scenario outline
+second line
+
+Given the pystring is
+"""
+Test store name
+Denmark, Kolding
+6000
+"""
+    Examples:
+      ||
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/ja_addition.feature b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/ja_addition.feature
new file mode 100644 (file)
index 0000000..b843852
--- /dev/null
@@ -0,0 +1,11 @@
+# language: ja
+フィーチャ: 加算
+  バカな間違いを避けるために
+  数学オンチとして
+  2つの数の合計を知りたい
+
+  シナリオ: 2つの数の加算について
+    前提 50 を入力
+    かつ 70 を入力
+    もし add ボタンを押した
+    ならば結果は 120 を表示
\ No newline at end of file
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/long_title_feature.feature b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/long_title_feature.feature
new file mode 100644 (file)
index 0000000..a93cb4d
--- /dev/null
@@ -0,0 +1,4 @@
+Feature: https://rspec.lighthouseapp.com/projects/16211/tickets/246-distorted-console-output-for-slightly-complicated-step-regexp-match
+
+Scenario: See "No Record(s) Found" for Zero Existing
+   Given no public holiday exists in the system
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/multiline_name.feature b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/multiline_name.feature
new file mode 100644 (file)
index 0000000..95b9d55
--- /dev/null
@@ -0,0 +1,23 @@
+Feature: multiline
+
+  Background:
+    Given passing without a table
+
+  Scenario: I'm a multiline name
+            which goes on and on and on for three lines
+            yawn
+    Given passing without a table
+
+  Scenario Outline: I'm a multiline name
+    which goes on and on and on for three lines
+                    yawn
+    Given <state> without a table
+    Examples:
+      | state |
+      |passing|
+
+  Scenario Outline: name
+    Given <state> without a table
+    Examples:
+      | state |
+      |passing|
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/multiline_name_with_newlines.feature b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/multiline_name_with_newlines.feature
new file mode 100644 (file)
index 0000000..bfc3e06
--- /dev/null
@@ -0,0 +1,61 @@
+Feature: multiline
+
+  Feature description
+
+  With etc.
+
+
+  Background:
+
+
+    Given passing without a table
+
+  Scenario:
+    I'm a multiline name
+    which goes on and on and on for three lines
+    yawn
+
+
+    Given passing without a table
+
+  Scenario Outline: I'm a multiline name
+
+                    which goes on and on and on for three lines
+
+    yawn
+
+
+    Given <state> without a table
+
+
+    Examples:
+
+
+      | state |
+      |passing|
+
+  Scenario Outline: name
+
+
+    Given <state> without a table
+
+
+    Examples:
+
+      | state |
+      |passing|
+
+  Scenario Outline:
+
+    I'm a multiline name
+    which goes on and on and on for three lines
+    yawn
+
+
+    Given <state> without a table
+
+
+    Examples:
+
+      | state |
+      |passing|
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/multiplepystrings.feature b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/multiplepystrings.feature
new file mode 100644 (file)
index 0000000..f5526af
--- /dev/null
@@ -0,0 +1,25 @@
+Feature: A multiple py string feature
+
+  Scenario: 
+    When I enter a string
+   """
+-
+      a string
+     with something
+  be
+ a
+   u
+     ti
+       ful
+   """
+    Then String must be
+    """
+-
+       a string
+      with something
+  be
+ a
+    u
+      ti
+        ful
+    """
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/outline_with_spaces.feature b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/outline_with_spaces.feature
new file mode 100644 (file)
index 0000000..e587faa
--- /dev/null
@@ -0,0 +1,28 @@
+Feature: Login
+  To ensure the safety of the application
+  A regular user of the system
+  Must authenticate before using the app
+
+
+  Scenario Outline: Failed Login
+    Given the user "known_user"
+
+    When I go to the main page
+    Then I should see the login form
+
+    When I fill in "login" with "<login>"
+    And I fill in "password" with "<password>"
+    And I press "Log In"
+    Then the login request should fail
+    And I should see the error message "Login or Password incorrect"
+
+    Examples:
+      | login        | password       |
+      |              |                |
+      | unknown_user |                |
+      | known_user   |                |
+      |              | wrong_password |
+      |              | known_userpass |
+      | unknown_user | wrong_password |
+      | unknown_user | known_userpass |
+      | known_user   | wrong_password |
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/outline_with_step_table.feature b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/outline_with_step_table.feature
new file mode 100644 (file)
index 0000000..9d31771
--- /dev/null
@@ -0,0 +1,13 @@
+Feature: Unsubstituted argument placeholder 
+
+  Scenario Outline: See Annual Leave Details (as Management & Human Resource)
+    Given the following users exist in the system
+      | name  | email           | role_assignments | group_memberships |
+      | Jane  | jane@fmail.com  | <role>           | Sales (manager)   |
+      | Max   | max@fmail.com   |                  | Sales (member)    |
+      | Carol | carol@fmail.com |                  | Sales (member)    |
+      | Cat   | cat@fmail.com   |                  |                   |
+
+    Examples:
+      | role           |
+      | HUMAN RESOURCE |
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/pystring.feature b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/pystring.feature
new file mode 100644 (file)
index 0000000..601373f
--- /dev/null
@@ -0,0 +1,8 @@
+Feature: A py string feature
+
+  Scenario: 
+    Then I should see
+      """
+      a string with #something
+      """
+  
\ No newline at end of file
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/ru_addition.feature b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/ru_addition.feature
new file mode 100644 (file)
index 0000000..eda5722
--- /dev/null
@@ -0,0 +1,11 @@
+# language: ru
+Функционал: Сложение чисел
+  Чтобы не складывать в уме
+  Все, у кого с этим туго
+  Хотят автоматическое сложение целых чисел
+
+  Сценарий: Сложение двух целых чисел
+    Допустим я ввожу число 50
+    И затем ввожу число 70
+    Если я нажимаю "+"
+    То результатом должно быть число 120
\ No newline at end of file
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/ru_commented.feature b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/ru_commented.feature
new file mode 100644 (file)
index 0000000..36cbd05
--- /dev/null
@@ -0,0 +1,10 @@
+# Comments
+# comments 
+# COOOOOMMEEEENTS
+#
+# language: ru
+
+Функционал: Тест комментов
+  i18n должен правильно считываться
+  Даже если в начале файла 1000
+  комментов!
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/ru_consecutive_calculations.feature b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/ru_consecutive_calculations.feature
new file mode 100644 (file)
index 0000000..87cc7f2
--- /dev/null
@@ -0,0 +1,17 @@
+# language: ru
+Функционал: Последовательные вычисления
+  Чтобы вычислять сложные выражения
+  Пользователи хотят проводить вычисления над результатом предыдущей операций
+
+  Предыстория:
+    Допустим я сложил 3 и 5
+
+  Сценарий: сложение с результатом последней операций
+    Если я ввожу число 4
+    И нажимаю "+"
+    То результатом должно быть число 12
+  
+  Сценарий: деление результата последней операции
+    Если я ввожу число 2
+    И нажимаю "/"
+    То результатом должно быть число 4
\ No newline at end of file
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/ru_division.feature b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/ru_division.feature
new file mode 100644 (file)
index 0000000..7f024f6
--- /dev/null
@@ -0,0 +1,16 @@
+# language: ru
+Функционал: Деление чисел
+  Поскольку деление сложный процесс и люди часто допускают ошибки
+  Нужно дать им возможность делить на калькуляторе
+
+  Структура сценария: Целочисленное деление
+    Допустим я ввожу число <делимое>
+    И затем ввожу число <делитель>
+    Если я нажимаю "/"
+    То результатом должно быть число <частное>
+
+  Значения:
+    | делимое | делитель | частное |
+    | 100     | 2        | 50      |
+    | 28      | 7        | 4       |
+    | 0       | 5        | 0       |
\ No newline at end of file
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/start_comments.feature b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/start_comments.feature
new file mode 100644 (file)
index 0000000..45dd501
--- /dev/null
@@ -0,0 +1,12 @@
+# Users want to use cucumber, so tests are necessary to verify
+# it is all working as expected
+Feature: Using the Console Formatter
+  In order to verify this error
+  I want to run this feature using the progress format
+  So that it can be fixed
+  
+  Scenario: A normal feature
+    Given I have a pending step
+    When  I run this feature with the progress format
+    Then  I should get a no method error for 'backtrace_line'
+
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/tables.feature b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/tables.feature
new file mode 100644 (file)
index 0000000..92f4c78
--- /dev/null
@@ -0,0 +1,20 @@
+Feature: A scenario outline
+  # COMMENT
+  Scenario Outline:
+    Given I add <a> and <b>
+    # comment
+    When I pass a table argument
+      | foo | bar |
+      | bar | baz |
+          #comment
+    Then I the result should be <c>
+    # comment
+    And the table should be properly escaped:
+      | \|a | b   | c   |
+      | 1   | \|2 | 3   |  
+      | 2   | 3   | \|4 |
+#comment
+    Examples:
+      | a   | b   | c |
+      | 1   | \|2 | 3 |
+      | 2   | 3   | 4 | 
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/tags_sample.feature b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/tags_sample.feature
new file mode 100644 (file)
index 0000000..21eaaab
--- /dev/null
@@ -0,0 +1,17 @@
+@sample_one
+Feature: Tag samples
+
+  @sample_two @sample_four
+  Scenario: Passing
+    Given missing
+
+  @sample_three
+  Scenario Outline:
+    Given <state>
+  Examples:
+    |state|
+    |missing|
+
+  @sample_three @sample_four
+  Scenario: Skipped
+    Given missing
\ No newline at end of file
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/test_unit.feature b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/test_unit.feature
new file mode 100644 (file)
index 0000000..ed08ba4
--- /dev/null
@@ -0,0 +1,9 @@
+Feature: Test::Unit
+  In order to please people who like Test::Unit
+  As a Cucumber user
+  I want to be able to use assert* in my step definitions
+
+  Scenario: assert_equal
+    Given x = 5
+    And y = 5
+    Then I can assert that x == y
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/trimpystring.feature b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/trimpystring.feature
new file mode 100644 (file)
index 0000000..4e04950
--- /dev/null
@@ -0,0 +1,14 @@
+Feature: A py string feature
+
+  Scenario: 
+    Then String must be
+    """
+    -
+       a string
+      with something
+  be
+ a
+    u
+      ti
+        ful
+    """
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/undefined_multiline_args.feature b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/features/undefined_multiline_args.feature
new file mode 100644 (file)
index 0000000..ae3c732
--- /dev/null
@@ -0,0 +1,12 @@
+Feature: undefined multiline args
+
+  Scenario: pystring
+    Given a pystring
+    """
+      example
+    """
+
+  Scenario: table
+    Given a table 
+      | table |
+      |example|
\ No newline at end of file
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/i18n.yml b/vendor/behat/gherkin/tests/Behat/Gherkin/Fixtures/i18n.yml
new file mode 100644 (file)
index 0000000..398c60c
--- /dev/null
@@ -0,0 +1,606 @@
+
+#
+# !!! DON'T TOUCH THIS FILE, IT WAS AUTODOWNLOADED FROM:
+#     https://github.com/cucumber/gherkin/blob/master/lib/gherkin/i18n.yml
+#
+
+# encoding: UTF-8
+#
+# We use ISO 639-1 (language) and ISO 3166 alpha-2 (region - if applicable):
+# http://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
+# http://en.wikipedia.org/wiki/ISO_3166-1
+#
+# If you want several aliases for a keyword, just separate them
+# with a | character. The * is a step keyword alias for all translations.
+#
+# If you do *not* want a trailing space after a keyword, end it with a < character.
+# (See Chinese for examples).
+#
+"en":
+  name: English
+  native: English
+  feature: Feature
+  background: Background
+  scenario: Scenario
+  scenario_outline: Scenario Outline|Scenario Template
+  examples: Examples|Scenarios
+  given: "*|Given"
+  when: "*|When"
+  then: "*|Then"
+  and: "*|And"
+  but: "*|But"
+
+# Please keep the grammars in alphabetical order by name from here and down.
+
+"ar":
+  name: Arabic
+  native: العربية
+  feature: خاصية
+  background: الخلفية
+  scenario: سيناريو
+  scenario_outline: سيناريو مخطط
+  examples: امثلة
+  given: "*|بفرض"
+  when: "*|متى|عندما"
+  then: "*|اذاً|ثم"
+  and: "*|و"
+  but: "*|لكن"
+"bg":
+  name: Bulgarian
+  native: български
+  feature: Функционалност
+  background: Предистория
+  scenario: Сценарий
+  scenario_outline: Рамка на сценарий
+  examples: Примери
+  given: "*|Дадено"
+  when: "*|Когато"
+  then: "*|То"
+  and: "*|И"
+  but: "*|Но"
+"ca":
+  name: Catalan
+  native: català
+  background: Rerefons|Antecedents
+  feature: Característica|Funcionalitat
+  scenario: Escenari
+  scenario_outline: Esquema de l'escenari
+  examples: Exemples
+  given: "*|Donat|Donada|Atès|Atesa"
+  when: "*|Quan"
+  then: "*|Aleshores|Cal"
+  and: "*|I"
+  but: "*|Però"
+"cy-GB":
+  name: Welsh
+  native: Cymraeg
+  background: Cefndir
+  feature: Arwedd
+  scenario: Scenario
+  scenario_outline: Scenario Amlinellol
+  examples: Enghreifftiau
+  given: "*|Anrhegedig a"
+  when: "*|Pryd"
+  then: "*|Yna"
+  and: "*|A"
+  but: "*|Ond"
+"cs":
+  name: Czech
+  native: Česky
+  feature: Požadavek
+  background: Pozadí|Kontext
+  scenario: Scénář
+  scenario_outline: Náčrt Scénáře|Osnova scénáře
+  examples: Příklady
+  given: "*|Pokud"
+  when: "*|Když"
+  then: "*|Pak"
+  and: "*|A také|A"
+  but: "*|Ale"
+"da":
+  name: Danish
+  native: dansk
+  feature: Egenskab
+  background: Baggrund
+  scenario: Scenarie
+  scenario_outline: Abstrakt Scenario
+  examples: Eksempler
+  given: "*|Givet"
+  when: "*|Når"
+  then: "*|Så"
+  and: "*|Og"
+  but: "*|Men"
+"de":
+  name: German
+  native: Deutsch
+  feature: Funktionalität
+  background: Grundlage
+  scenario: Szenario
+  scenario_outline: Szenariogrundriss
+  examples: Beispiele
+  given: "*|Angenommen|Gegeben sei"
+  when: "*|Wenn"
+  then: "*|Dann"
+  and: "*|Und"
+  but: "*|Aber"
+"en-au":
+  name: Australian
+  native: Australian
+  feature: Crikey
+  background: Background
+  scenario: Mate
+  scenario_outline: Blokes
+  examples: Cobber
+  given: "*|Ya know how"
+  when: "*|When"
+  then: "*|Ya gotta"
+  and: "*|N"
+  but: "*|Cept"
+"en-lol":
+  name: LOLCAT
+  native: LOLCAT
+  feature: OH HAI
+  background: B4
+  scenario: MISHUN
+  scenario_outline: MISHUN SRSLY
+  examples: EXAMPLZ
+  given: "*|I CAN HAZ"
+  when: "*|WEN"
+  then: "*|DEN"
+  and: "*|AN"
+  but: "*|BUT"
+"en-pirate":
+  name: Pirate
+  native: Pirate
+  feature: Ahoy matey!
+  background: Yo-ho-ho
+  scenario: Heave to
+  scenario_outline: Shiver me timbers
+  examples: Dead men tell no tales
+  given: "*|Gangway!"
+  when: "*|Blimey!"
+  then: "*|Let go and haul"
+  and: "*|Aye"
+  but: "*|Avast!"
+"en-Scouse":
+  name: Scouse
+  native: Scouse
+  feature: Feature
+  background: "Dis is what went down"
+  scenario: "The thing of it is"
+  scenario_outline: "Wharrimean is"
+  examples: Examples
+  given: "*|Givun|Youse know when youse got"
+  when: "*|Wun|Youse know like when"
+  then: "*|Dun|Den youse gotta"
+  and: "*|An"
+  but: "*|Buh"
+"en-tx":
+  name: Texan
+  native: Texan
+  feature: Feature
+  background: Background
+  scenario: Scenario
+  scenario_outline: All y'all
+  examples: Examples
+  given: "*|Given y'all"
+  when: "*|When y'all"
+  then: "*|Then y'all"
+  and: "*|And y'all"
+  but: "*|But y'all"
+"eo":
+  name: Esperanto
+  native: Esperanto
+  feature: Trajto
+  background: Fono
+  scenario: Scenaro
+  scenario_outline: Konturo de la scenaro
+  examples: Ekzemploj
+  given: "*|Donitaĵo"
+  when: "*|Se"
+  then: "*|Do"
+  and: "*|Kaj"
+  but: "*|Sed"
+"es":
+  name: Spanish
+  native: español
+  background: Antecedentes
+  feature: Característica
+  scenario: Escenario
+  scenario_outline: Esquema del escenario
+  examples: Ejemplos
+  given: "*|Dado|Dada|Dados|Dadas"
+  when: "*|Cuando"
+  then: "*|Entonces"
+  and: "*|Y"
+  but: "*|Pero"
+"et":
+  name: Estonian
+  native: eesti keel
+  feature: Omadus
+  background: Taust
+  scenario: Stsenaarium
+  scenario_outline: Raamstsenaarium
+  examples: Juhtumid
+  given: "*|Eeldades"
+  when: "*|Kui"
+  then: "*|Siis"
+  and: "*|Ja"
+  but: "*|Kuid"
+"fi":
+  name: Finnish
+  native: suomi
+  feature: Ominaisuus
+  background: Tausta
+  scenario: Tapaus
+  scenario_outline: Tapausaihio
+  examples: Tapaukset
+  given: "*|Oletetaan"
+  when: "*|Kun"
+  then: "*|Niin"
+  and: "*|Ja"
+  but: "*|Mutta"
+"fr":
+  name: French
+  native: français
+  feature: Fonctionnalité
+  background: Contexte
+  scenario: Scénario
+  scenario_outline: Plan du scénario|Plan du Scénario
+  examples: Exemples
+  given: "*|Soit|Etant donné|Etant donnée|Etant donnés|Etant données|Étant donné|Étant donnée|Étant donnés|Étant données"
+  when: "*|Quand|Lorsque|Lorsqu'<"
+  then: "*|Alors"
+  and: "*|Et"
+  but: "*|Mais"
+"he":
+  name: Hebrew
+  native: עברית
+  feature: תכונה
+  background: רקע
+  scenario: תרחיש
+  scenario_outline: תבנית תרחיש
+  examples: דוגמאות
+  given: "*|בהינתן"
+  when: "*|כאשר"
+  then: "*|אז|אזי"
+  and: "*|וגם"
+  but: "*|אבל"
+"hr":
+  name: Croatian
+  native: hrvatski
+  feature: Osobina|Mogućnost|Mogucnost
+  background: Pozadina
+  scenario: Scenarij
+  scenario_outline: Skica|Koncept
+  examples: Primjeri|Scenariji
+  given: "*|Zadan|Zadani|Zadano"
+  when: "*|Kada|Kad"
+  then: "*|Onda"
+  and: "*|I"
+  but: "*|Ali"
+"hu":
+  name: Hungarian
+  native: magyar
+  feature: Jellemző
+  background: Háttér
+  scenario: Forgatókönyv
+  scenario_outline: Forgatókönyv vázlat
+  examples: Példák
+  given: "*|Amennyiben|Adott"
+  when: "*|Majd|Ha|Amikor"
+  then: "*|Akkor"
+  and: "*|És"
+  but: "*|De"
+"id":
+  name: Indonesian
+  native: Bahasa Indonesia
+  feature: Fitur
+  background: Dasar
+  scenario: Skenario
+  scenario_outline: Skenario konsep
+  examples: Contoh
+  given: "*|Dengan"
+  when: "*|Ketika"
+  then: "*|Maka"
+  and: "*|Dan"
+  but: "*|Tapi"
+"is":
+  name: Icelandic
+  native: Íslenska
+  feature: Eiginleiki
+  background: Bakgrunnur
+  scenario: Atburðarás
+  scenario_outline: Lýsing Atburðarásar|Lýsing Dæma
+  examples: Dæmi|Atburðarásir
+  given: "*|Ef"
+  when: "*|Þegar"
+  then: "*|Þá"
+  and: "*|Og"
+  but: "*|En"
+"it":
+  name: Italian
+  native: italiano
+  feature: Funzionalità
+  background: Contesto
+  scenario: Scenario
+  scenario_outline: Schema dello scenario
+  examples: Esempi
+  given: "*|Dato|Data|Dati|Date"
+  when: "*|Quando"
+  then: "*|Allora"
+  and: "*|E"
+  but: "*|Ma"
+"ja":
+  name: Japanese
+  native: 日本語
+  feature: フィーチャ|機能
+  background: 背景
+  scenario: シナリオ
+  scenario_outline: シナリオアウトライン|シナリオテンプレート|テンプレ|シナリオテンプレ
+  examples: 例|サンプル
+  given: "*|前提<"
+  when: "*|もし<"
+  then: "*|ならば<"
+  and: "*|かつ<"
+  but: "*|しかし<|但し<|ただし<"
+"ko":
+  name: Korean
+  native: 한국어
+  background: 배경
+  feature: 기능
+  scenario: 시나리오
+  scenario_outline: 시나리오 개요
+  examples: 예
+  given: "*|조건<|먼저<"
+  when: "*|만일<|만약<"
+  then: "*|그러면<"
+  and: "*|그리고<"
+  but: "*|하지만<|단<"
+"lt":
+  name: Lithuanian
+  native: lietuvių kalba
+  feature: Savybė
+  background: Kontekstas
+  scenario: Scenarijus
+  scenario_outline: Scenarijaus šablonas
+  examples: Pavyzdžiai|Scenarijai|Variantai
+  given: "*|Duota"
+  when: "*|Kai"
+  then: "*|Tada"
+  and: "*|Ir"
+  but: "*|Bet"
+"lu":
+  name: Luxemburgish
+  native: Lëtzebuergesch
+  feature: Funktionalitéit
+  background: Hannergrond
+  scenario: Szenario
+  scenario_outline: Plang vum Szenario
+  examples: Beispiller
+  given: "*|ugeholl"
+  when: "*|wann"
+  then: "*|dann"
+  and: "*|an|a"
+  but: "*|awer|mä"
+"lv":
+  name: Latvian
+  native: latviešu
+  feature: Funkcionalitāte|Fīča
+  background: Konteksts|Situācija
+  scenario: Scenārijs
+  scenario_outline: Scenārijs pēc parauga
+  examples: Piemēri|Paraugs
+  given: "*|Kad"
+  when: "*|Ja"
+  then: "*|Tad"
+  and: "*|Un"
+  but: "*|Bet"
+"nl":
+  name: Dutch
+  native: Nederlands
+  feature: Functionaliteit
+  background: Achtergrond
+  scenario: Scenario
+  scenario_outline: Abstract Scenario
+  examples: Voorbeelden
+  given: "*|Gegeven|Stel"
+  when: "*|Als"
+  then: "*|Dan"
+  and: "*|En"
+  but: "*|Maar"
+"no":
+  name: Norwegian
+  native: norsk
+  feature: Egenskap
+  background: Bakgrunn
+  scenario: Scenario
+  scenario_outline: Scenariomal|Abstrakt Scenario
+  examples: Eksempler
+  given: "*|Gitt"
+  when: "*|Når"
+  then: "*|Så"
+  and: "*|Og"
+  but: "*|Men"
+"pl":
+  name: Polish
+  native: polski
+  feature: Właściwość
+  background: Założenia
+  scenario: Scenariusz
+  scenario_outline: Szablon scenariusza
+  examples: Przykłady
+  given: "*|Zakładając|Mając"
+  when: "*|Jeżeli|Jeśli"
+  then: "*|Wtedy"
+  and: "*|Oraz|I"
+  but: "*|Ale"
+"pt":
+  name: Portuguese
+  native: português
+  background: Contexto
+  feature: Funcionalidade
+  scenario: Cenário|Cenario
+  scenario_outline: Esquema do Cenário|Esquema do Cenario
+  examples: Exemplos
+  given: "*|Dado|Dada|Dados|Dadas"
+  when: "*|Quando"
+  then: "*|Então|Entao"
+  and: "*|E"
+  but: "*|Mas"
+"ro":
+  name: Romanian
+  native: română
+  background: Context
+  feature: Functionalitate|Funcționalitate|Funcţionalitate
+  scenario: Scenariu
+  scenario_outline: Structura scenariu|Structură scenariu
+  examples: Exemple
+  given: "*|Date fiind|Dat fiind|Dati fiind|Dați fiind|Daţi fiind"
+  when: "*|Cand|Când"
+  then: "*|Atunci"
+  and: "*|Si|Și|Şi"
+  but: "*|Dar"
+"ru":
+  name: Russian
+  native: русский
+  feature: Функция|Функционал|Свойство
+  background: Предыстория|Контекст
+  scenario: Сценарий
+  scenario_outline: Структура сценария
+  examples: Примеры
+  given: "*|Допустим|Дано|Пусть"
+  when: "*|Если|Когда"
+  then: "*|То|Тогда"
+  and: "*|И|К тому же"
+  but: "*|Но|А"
+"sv":
+  name: Swedish
+  native: Svenska
+  feature: Egenskap
+  background: Bakgrund
+  scenario: Scenario
+  scenario_outline: Abstrakt Scenario|Scenariomall
+  examples: Exempel
+  given: "*|Givet"
+  when: "*|När"
+  then: "*|Så"
+  and: "*|Och"
+  but: "*|Men"
+"sk":
+  name: Slovak
+  native: Slovensky
+  feature: Požiadavka
+  background: Pozadie
+  scenario: Scenár
+  scenario_outline: Náčrt Scenáru
+  examples: Príklady
+  given: "*|Pokiaľ"
+  when: "*|Keď"
+  then: "*|Tak"
+  and: "*|A"
+  but: "*|Ale"
+"sr-Latn":
+  name: Serbian (Latin)
+  native: Srpski (Latinica)
+  feature: Funkcionalnost|Mogućnost|Mogucnost|Osobina
+  background: Kontekst|Osnova|Pozadina
+  scenario: Scenario|Primer
+  scenario_outline: Struktura scenarija|Skica|Koncept
+  examples: Primeri|Scenariji
+  given: "*|Zadato|Zadate|Zatati"
+  when: "*|Kada|Kad"
+  then: "*|Onda"
+  and: "*|I"
+  but: "*|Ali"
+"sr-Cyrl":
+  name: Serbian
+  native: Српски
+  feature: Функционалност|Могућност|Особина
+  background: Контекст|Основа|Позадина
+  scenario: Сценарио|Пример
+  scenario_outline: Структура сценарија|Скица|Концепт
+  examples: Примери|Сценарији
+  given: "*|Задато|Задате|Задати"
+  when: "*|Када|Кад"
+  then: "*|Онда"
+  and: "*|И"
+  but: "*|Али"
+"tr":
+  name: Turkish
+  native: Türkçe
+  feature: Özellik
+  background: Geçmiş
+  scenario: Senaryo
+  scenario_outline: Senaryo taslağı
+  examples: Örnekler
+  given: "*|Diyelim ki"
+  when: "*|Eğer ki"
+  then: "*|O zaman"
+  and: "*|Ve"
+  but: "*|Fakat|Ama"
+"uk":
+  name: Ukrainian
+  native: Українська
+  feature: Функціонал
+  background: Передумова
+  scenario: Сценарій
+  scenario_outline: Структура сценарію
+  examples: Приклади
+  given: "*|Припустимо|Припустимо, що|Нехай|Дано"
+  when: "*|Якщо|Коли"
+  then: "*|То|Тоді"
+  and: "*|І|А також|Та"
+  but: "*|Але"
+"uz":
+  name: Uzbek
+  native: Узбекча
+  feature: Функционал
+  background: Тарих
+  scenario: Сценарий
+  scenario_outline: Сценарий структураси
+  examples: Мисоллар
+  given: "*|Агар"
+  when: "*|Агар"
+  then: "*|Унда"
+  and: "*|Ва"
+  but: "*|Лекин|Бирок|Аммо"
+"vi":
+  name: Vietnamese
+  native: Tiếng Việt
+  feature: Tính năng
+  background: Bối cảnh
+  scenario: Tình huống|Kịch bản
+  scenario_outline: Khung tình huống|Khung kịch bản
+  examples: Dữ liệu
+  given: "*|Biết|Cho"
+  when: "*|Khi"
+  then: "*|Thì"
+  and: "*|Và"
+  but: "*|Nhưng"
+"zh-CN":
+  name: Chinese simplified
+  native: 简体中文
+  feature: 功能
+  background: 背景
+  scenario: 场景
+  scenario_outline: 场景大纲
+  examples: 例子
+  given: "*|假如<"
+  when: "*|当<"
+  then: "*|那么<"
+  and: "*|而且<"
+  but: "*|但是<"
+"zh-TW":
+  name: Chinese traditional
+  native: 繁體中文
+  feature: 功能
+  background: 背景
+  scenario: 場景|劇本
+  scenario_outline: 場景大綱|劇本大綱
+  examples: 例子
+  given: "*|假設<"
+  when: "*|當<"
+  then: "*|那麼<"
+  and: "*|而且<|並且<"
+  but: "*|但是<"
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/GherkinTest.php b/vendor/behat/gherkin/tests/Behat/Gherkin/GherkinTest.php
new file mode 100644 (file)
index 0000000..9e5c0cb
--- /dev/null
@@ -0,0 +1,184 @@
+<?php
+
+namespace Tests\Behat\Gherkin;
+
+use Behat\Gherkin\Gherkin;
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\ScenarioNode;
+
+class GherkinTest extends \PHPUnit_Framework_TestCase
+{
+    public function testLoader()
+    {
+        $customFilter1 = $this->getCustomFilterMock();
+        $customFilter2 = $this->getCustomFilterMock();
+
+        $gherkin = new Gherkin();
+        $gherkin->addLoader($loader = $this->getLoaderMock());
+        $gherkin->addFilter($nameFilter = $this->getNameFilterMock());
+        $gherkin->addFilter($tagFilter = $this->getTagFilterMock());
+
+        $scenario = new ScenarioNode(null, array(), array(), null, null);
+        $feature = new FeatureNode(null, null, array(), null, array($scenario), null, null, null, null);
+
+        $loader
+            ->expects($this->once())
+            ->method('supports')
+            ->with($resource = 'some/feature/resource')
+            ->will($this->returnValue(true));
+        $loader
+            ->expects($this->once())
+            ->method('load')
+            ->with($resource)
+            ->will($this->returnValue(array($feature)));
+
+        $nameFilter
+            ->expects($this->once())
+            ->method('filterFeature')
+            ->with($this->identicalTo($feature))
+            ->will($this->returnValue($feature));
+        $tagFilter
+            ->expects($this->once())
+            ->method('filterFeature')
+            ->with($this->identicalTo($feature))
+            ->will($this->returnValue($feature));
+        $customFilter1
+            ->expects($this->once())
+            ->method('filterFeature')
+            ->with($this->identicalTo($feature))
+            ->will($this->returnValue($feature));
+        $customFilter2
+            ->expects($this->once())
+            ->method('filterFeature')
+            ->with($this->identicalTo($feature))
+            ->will($this->returnValue($feature));
+
+        $features = $gherkin->load($resource, array($customFilter1, $customFilter2));
+        $this->assertEquals(1, count($features));
+
+        $scenarios = $features[0]->getScenarios();
+        $this->assertEquals(1, count($scenarios));
+        $this->assertSame($scenario, $scenarios[0]);
+    }
+
+    public function testNotFoundLoader()
+    {
+        $gherkin = new Gherkin();
+
+        $this->assertEquals(array(), $gherkin->load('some/feature/resource'));
+    }
+
+    public function testLoaderFiltersFeatures()
+    {
+        $gherkin = new Gherkin();
+        $gherkin->addLoader($loader = $this->getLoaderMock());
+        $gherkin->addFilter($nameFilter = $this->getNameFilterMock());
+
+        $feature = new FeatureNode(null, null, array(), null, array(), null, null, null, null);
+
+        $loader
+            ->expects($this->once())
+            ->method('supports')
+            ->with($resource = 'some/feature/resource')
+            ->will($this->returnValue(true));
+        $loader
+            ->expects($this->once())
+            ->method('load')
+            ->with($resource)
+            ->will($this->returnValue(array($feature)));
+
+        $nameFilter
+            ->expects($this->once())
+            ->method('filterFeature')
+            ->with($this->identicalTo($feature))
+            ->will($this->returnValue($feature));
+        $nameFilter
+            ->expects($this->once())
+            ->method('isFeatureMatch')
+            ->with($this->identicalTo($feature))
+            ->will($this->returnValue(false));
+
+        $features = $gherkin->load($resource);
+        $this->assertEquals(0, count($features));
+    }
+
+    public function testSetFiltersOverridesAllFilters()
+    {
+        $gherkin = new Gherkin();
+        $gherkin->addLoader($loader = $this->getLoaderMock());
+        $gherkin->addFilter($nameFilter = $this->getNameFilterMock());
+        $gherkin->setFilters(array());
+
+        $feature = new FeatureNode(null, null, array(), null, array(), null, null, null, null);
+
+        $loader
+            ->expects($this->once())
+            ->method('supports')
+            ->with($resource = 'some/feature/resource')
+            ->will($this->returnValue(true));
+        $loader
+            ->expects($this->once())
+            ->method('load')
+            ->with($resource)
+            ->will($this->returnValue(array($feature)));
+
+        $nameFilter
+            ->expects($this->never())
+            ->method('filterFeature');
+        $nameFilter
+            ->expects($this->never())
+            ->method('isFeatureMatch');
+
+        $features = $gherkin->load($resource);
+        $this->assertEquals(1, count($features));
+    }
+
+    public function testSetBasePath()
+    {
+        $gherkin = new Gherkin();
+        $gherkin->addLoader($loader1 = $this->getLoaderMock());
+        $gherkin->addLoader($loader2 = $this->getLoaderMock());
+
+        $loader1
+            ->expects($this->once())
+            ->method('setBasePath')
+            ->with($basePath = '/base/path')
+            ->will($this->returnValue(null));
+
+        $loader2
+            ->expects($this->once())
+            ->method('setBasePath')
+            ->with($basePath = '/base/path')
+            ->will($this->returnValue(null));
+
+        $gherkin->setBasePath($basePath);
+    }
+
+    protected function getLoaderMock()
+    {
+        return $this->getMockBuilder('Behat\Gherkin\Loader\GherkinFileLoader')
+            ->disableOriginalConstructor()
+            ->getMock();
+    }
+
+    protected function getCustomFilterMock()
+    {
+        return $this->getMockBuilder('Behat\Gherkin\Filter\FilterInterface')
+            ->disableOriginalConstructor()
+            ->getMock();
+    }
+
+    protected function getNameFilterMock()
+    {
+        return $this->getMockBuilder('Behat\Gherkin\Filter\NameFilter')
+            ->disableOriginalConstructor()
+            ->getMock();
+    }
+
+    protected function getTagFilterMock()
+    {
+        return $this->getMockBuilder('Behat\Gherkin\Filter\TagFilter')
+            ->disableOriginalConstructor()
+            ->getMock();
+    }
+}
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Keywords/ArrayKeywordsTest.php b/vendor/behat/gherkin/tests/Behat/Gherkin/Keywords/ArrayKeywordsTest.php
new file mode 100644 (file)
index 0000000..e6c18dc
--- /dev/null
@@ -0,0 +1,48 @@
+<?php
+
+namespace Tests\Behat\Gherkin\Keywords;
+
+use Behat\Gherkin\Keywords\ArrayKeywords;
+use Behat\Gherkin\Node\StepNode;
+
+class ArrayKeywordsTest extends KeywordsTest
+{
+    protected function getKeywords()
+    {
+        return new ArrayKeywords($this->getKeywordsArray());
+    }
+
+    protected function getKeywordsArray()
+    {
+        return array(
+            'with_special_chars' => array(
+                'and' => 'And/foo',
+                'background' => 'Background.',
+                'but' => 'But[',
+                'examples' => 'Examples|Scenarios',
+                'feature' => 'Feature|Business Need|Ability',
+                'given' => 'Given',
+                'name' => 'English',
+                'native' => 'English',
+                'scenario' => 'Scenario',
+                'scenario_outline' => 'Scenario Outline|Scenario Template',
+                'then' => 'Then',
+                'when' => 'When',
+            ),
+        );
+    }
+
+    protected function getSteps($keywords, $text, &$line, $keywordType)
+    {
+        $steps = array();
+        foreach (explode('|', $keywords) as $keyword) {
+            if (false !== mb_strpos($keyword, '<')) {
+                $keyword = mb_substr($keyword, 0, -1);
+            }
+
+            $steps[] = new StepNode($keyword, $text, array(), $line++, $keywordType);
+        }
+
+        return $steps;
+    }
+}
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Keywords/CachedArrayKeywordsTest.php b/vendor/behat/gherkin/tests/Behat/Gherkin/Keywords/CachedArrayKeywordsTest.php
new file mode 100644 (file)
index 0000000..bf10cb3
--- /dev/null
@@ -0,0 +1,37 @@
+<?php
+
+namespace Tests\Behat\Gherkin\Keywords;
+
+use Behat\Gherkin\Keywords\CachedArrayKeywords;
+use Behat\Gherkin\Node\StepNode;
+
+class CachedArrayKeywordsTest extends KeywordsTest
+{
+    protected function getKeywords()
+    {
+        return new CachedArrayKeywords(__DIR__ . '/../../../../i18n.php');
+    }
+
+    protected function getKeywordsArray()
+    {
+        return include(__DIR__ . '/../../../../i18n.php');
+    }
+
+    protected function getSteps($keywords, $text, &$line, $keywordType)
+    {
+        $steps = array();
+        foreach (explode('|', $keywords) as $keyword) {
+            if ('*' === $keyword) {
+                continue;
+            }
+
+            if (false !== mb_strpos($keyword, '<')) {
+                $keyword = mb_substr($keyword, 0, -1);
+            }
+
+            $steps[] = new StepNode($keyword, $text, array(), $line++, $keywordType);
+        }
+
+        return $steps;
+    }
+}
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Keywords/CucumberKeywordsTest.php b/vendor/behat/gherkin/tests/Behat/Gherkin/Keywords/CucumberKeywordsTest.php
new file mode 100644 (file)
index 0000000..b2b0783
--- /dev/null
@@ -0,0 +1,34 @@
+<?php
+
+namespace Tests\Behat\Gherkin\Keywords;
+
+use Behat\Gherkin\Keywords\CucumberKeywords;
+use Behat\Gherkin\Node\StepNode;
+use Symfony\Component\Yaml\Yaml;
+
+class CucumberKeywordsTest extends KeywordsTest
+{
+    protected function getKeywords()
+    {
+        return new CucumberKeywords(__DIR__ . '/../Fixtures/i18n.yml');
+    }
+
+    protected function getKeywordsArray()
+    {
+        return Yaml::parse(file_get_contents(__DIR__ . '/../Fixtures/i18n.yml'));
+    }
+
+    protected function getSteps($keywords, $text, &$line, $keywordType)
+    {
+        $steps = array();
+        foreach (explode('|', mb_substr($keywords, 2)) as $keyword) {
+            if (false !== mb_strpos($keyword, '<')) {
+                $keyword = mb_substr($keyword, 0, -1);
+            }
+
+            $steps[] = new StepNode($keyword, $text, array(), $line++, $keywordType);
+        }
+
+        return $steps;
+    }
+}
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Keywords/KeywordsDumperTest.php b/vendor/behat/gherkin/tests/Behat/Gherkin/Keywords/KeywordsDumperTest.php
new file mode 100644 (file)
index 0000000..cf7f853
--- /dev/null
@@ -0,0 +1,270 @@
+<?php
+
+namespace Tests\Behat\Gherkin\Keywords;
+
+use Behat\Gherkin\Keywords\ArrayKeywords;
+use Behat\Gherkin\Keywords\KeywordsDumper;
+
+class KeywordsDumperTest extends \PHPUnit_Framework_TestCase
+{
+    private $keywords;
+
+    protected function setUp()
+    {
+        $this->keywords = new ArrayKeywords(array(
+           'en' => array(
+               'feature'          => 'Feature',
+               'background'       => 'Background',
+               'scenario'         => 'Scenario',
+               'scenario_outline' => 'Scenario Outline|Scenario Template',
+               'examples'         => 'Examples|Scenarios',
+               'given'            => 'Given',
+               'when'             => 'When',
+               'then'             => 'Then',
+               'and'              => 'And',
+               'but'              => 'But'
+           ),
+           'ru' => array(
+               'feature'          => 'Функционал|Фича',
+               'background'       => 'Предыстория|Бэкграунд',
+               'scenario'         => 'Сценарий|История',
+               'scenario_outline' => 'Структура сценария|Аутлайн',
+               'examples'         => 'Значения',
+               'given'            => 'Допустим',
+               'when'             => 'Если|@',
+               'then'             => 'То',
+               'and'              => 'И',
+               'but'              => 'Но'
+           )
+        ));
+    }
+
+    public function testEnKeywordsDumper()
+    {
+        $dumper = new KeywordsDumper($this->keywords);
+
+        $dumped = $dumper->dump('en');
+        $etalon = <<<GHERKIN
+Feature: Internal operations
+  In order to stay secret
+  As a secret organization
+  We need to be able to erase past agents' memory
+
+  Background:
+    Given there is agent A
+    And there is agent B
+
+  Scenario: Erasing agent memory
+    Given there is agent J
+    And there is agent K
+    When I erase agent K's memory
+    Then there should be agent J
+    But there should not be agent K
+
+  (Scenario Outline|Scenario Template): Erasing other agents' memory
+    Given there is agent <agent1>
+    And there is agent <agent2>
+    When I erase agent <agent2>'s memory
+    Then there should be agent <agent1>
+    But there should not be agent <agent2>
+
+    (Examples|Scenarios):
+      | agent1 | agent2 |
+      | D      | M      |
+GHERKIN;
+
+        $this->assertEquals($etalon, $dumped);
+    }
+
+    public function testRuKeywordsDumper()
+    {
+        $dumper = new KeywordsDumper($this->keywords);
+
+        $dumped = $dumper->dump('ru');
+        $etalon = <<<GHERKIN
+# language: ru
+(Функционал|Фича): Internal operations
+  In order to stay secret
+  As a secret organization
+  We need to be able to erase past agents' memory
+
+  (Предыстория|Бэкграунд):
+    Допустим there is agent A
+    И there is agent B
+
+  (Сценарий|История): Erasing agent memory
+    Допустим there is agent J
+    И there is agent K
+    (Если|@) I erase agent K's memory
+    То there should be agent J
+    Но there should not be agent K
+
+  (Структура сценария|Аутлайн): Erasing other agents' memory
+    Допустим there is agent <agent1>
+    И there is agent <agent2>
+    (Если|@) I erase agent <agent2>'s memory
+    То there should be agent <agent1>
+    Но there should not be agent <agent2>
+
+    Значения:
+      | agent1 | agent2 |
+      | D      | M      |
+GHERKIN;
+
+        $this->assertEquals($etalon, $dumped);
+    }
+
+    public function testRuKeywordsCustomKeywordsDumper()
+    {
+        $dumper = new KeywordsDumper($this->keywords);
+        $dumper->setKeywordsDumperFunction(function ($keywords) {
+            return '<keyword>'.implode(', ', $keywords).'</keyword>';
+        });
+
+        $dumped = $dumper->dump('ru');
+        $etalon = <<<GHERKIN
+# language: ru
+<keyword>Функционал, Фича</keyword>: Internal operations
+  In order to stay secret
+  As a secret organization
+  We need to be able to erase past agents' memory
+
+  <keyword>Предыстория, Бэкграунд</keyword>:
+    <keyword>Допустим</keyword> there is agent A
+    <keyword>И</keyword> there is agent B
+
+  <keyword>Сценарий, История</keyword>: Erasing agent memory
+    <keyword>Допустим</keyword> there is agent J
+    <keyword>И</keyword> there is agent K
+    <keyword>Если, @</keyword> I erase agent K's memory
+    <keyword>То</keyword> there should be agent J
+    <keyword>Но</keyword> there should not be agent K
+
+  <keyword>Структура сценария, Аутлайн</keyword>: Erasing other agents' memory
+    <keyword>Допустим</keyword> there is agent <agent1>
+    <keyword>И</keyword> there is agent <agent2>
+    <keyword>Если, @</keyword> I erase agent <agent2>'s memory
+    <keyword>То</keyword> there should be agent <agent1>
+    <keyword>Но</keyword> there should not be agent <agent2>
+
+    <keyword>Значения</keyword>:
+      | agent1 | agent2 |
+      | D      | M      |
+GHERKIN;
+
+        $this->assertEquals($etalon, $dumped);
+    }
+
+    public function testExtendedVersionDumper()
+    {
+        $dumper = new KeywordsDumper($this->keywords);
+
+        $dumped = $dumper->dump('ru', false);
+        $etalon = array(
+            <<<GHERKIN
+# language: ru
+Функционал: Internal operations
+  In order to stay secret
+  As a secret organization
+  We need to be able to erase past agents' memory
+
+  Предыстория:
+    Допустим there is agent A
+    И there is agent B
+
+  Сценарий: Erasing agent memory
+    Допустим there is agent J
+    И there is agent K
+    Если I erase agent K's memory
+    @ I erase agent K's memory
+    То there should be agent J
+    Но there should not be agent K
+
+  История: Erasing agent memory
+    Допустим there is agent J
+    И there is agent K
+    Если I erase agent K's memory
+    @ I erase agent K's memory
+    То there should be agent J
+    Но there should not be agent K
+
+  Структура сценария: Erasing other agents' memory
+    Допустим there is agent <agent1>
+    И there is agent <agent2>
+    Если I erase agent <agent2>'s memory
+    @ I erase agent <agent2>'s memory
+    То there should be agent <agent1>
+    Но there should not be agent <agent2>
+
+    Значения:
+      | agent1 | agent2 |
+      | D      | M      |
+
+  Аутлайн: Erasing other agents' memory
+    Допустим there is agent <agent1>
+    И there is agent <agent2>
+    Если I erase agent <agent2>'s memory
+    @ I erase agent <agent2>'s memory
+    То there should be agent <agent1>
+    Но there should not be agent <agent2>
+
+    Значения:
+      | agent1 | agent2 |
+      | D      | M      |
+GHERKIN
+            , <<<GHERKIN
+# language: ru
+Фича: Internal operations
+  In order to stay secret
+  As a secret organization
+  We need to be able to erase past agents' memory
+
+  Предыстория:
+    Допустим there is agent A
+    И there is agent B
+
+  Сценарий: Erasing agent memory
+    Допустим there is agent J
+    И there is agent K
+    Если I erase agent K's memory
+    @ I erase agent K's memory
+    То there should be agent J
+    Но there should not be agent K
+
+  История: Erasing agent memory
+    Допустим there is agent J
+    И there is agent K
+    Если I erase agent K's memory
+    @ I erase agent K's memory
+    То there should be agent J
+    Но there should not be agent K
+
+  Структура сценария: Erasing other agents' memory
+    Допустим there is agent <agent1>
+    И there is agent <agent2>
+    Если I erase agent <agent2>'s memory
+    @ I erase agent <agent2>'s memory
+    То there should be agent <agent1>
+    Но there should not be agent <agent2>
+
+    Значения:
+      | agent1 | agent2 |
+      | D      | M      |
+
+  Аутлайн: Erasing other agents' memory
+    Допустим there is agent <agent1>
+    И there is agent <agent2>
+    Если I erase agent <agent2>'s memory
+    @ I erase agent <agent2>'s memory
+    То there should be agent <agent1>
+    Но there should not be agent <agent2>
+
+    Значения:
+      | agent1 | agent2 |
+      | D      | M      |
+GHERKIN
+        );
+
+        $this->assertEquals($etalon, $dumped);
+    }
+}
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Keywords/KeywordsTest.php b/vendor/behat/gherkin/tests/Behat/Gherkin/Keywords/KeywordsTest.php
new file mode 100644 (file)
index 0000000..fdfc65e
--- /dev/null
@@ -0,0 +1,139 @@
+<?php
+
+namespace Tests\Behat\Gherkin\Keywords;
+
+use Behat\Gherkin\Keywords\KeywordsDumper;
+use Behat\Gherkin\Lexer;
+use Behat\Gherkin\Node\BackgroundNode;
+use Behat\Gherkin\Node\ExampleTableNode;
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\OutlineNode;
+use Behat\Gherkin\Node\ScenarioNode;
+use Behat\Gherkin\Parser;
+
+abstract class KeywordsTest extends \PHPUnit_Framework_TestCase
+{
+    abstract protected function getKeywords();
+    abstract protected function getKeywordsArray();
+    abstract protected function getSteps($keywords, $text, &$line, $keywordType);
+
+    public function translationTestDataProvider()
+    {
+        $keywords = $this->getKeywords();
+        $lexer = new Lexer($keywords);
+        $parser = new Parser($lexer);
+        $dumper = new KeywordsDumper($keywords);
+        $keywordsArray = $this->getKeywordsArray();
+
+        // Remove languages with repeated keywords
+        unset($keywordsArray['en-old'], $keywordsArray['uz']);
+
+        $data = array();
+        foreach ($keywordsArray as $lang => $i18nKeywords) {
+            $features = array();
+            foreach (explode('|', $i18nKeywords['feature']) as $transNum => $featureKeyword) {
+                $line = 1;
+                if ('en' !== $lang) {
+                    $line = 2;
+                }
+
+                $featureLine = $line;
+                $line += 5;
+
+                $keywords = explode('|', $i18nKeywords['background']);
+                $backgroundLine = $line;
+                $line += 1;
+                $background = new BackgroundNode(null, array_merge(
+                    $this->getSteps($i18nKeywords['given'], 'there is agent A', $line, 'Given'),
+                    $this->getSteps($i18nKeywords['and'], 'there is agent B', $line, 'Given')
+                ), $keywords[0], $backgroundLine);
+
+                $line += 1;
+
+                $scenarios = array();
+
+                foreach (explode('|', $i18nKeywords['scenario']) as $scenarioKeyword) {
+                    $scenarioLine = $line;
+                    $line += 1;
+
+                    $steps = array_merge(
+                        $this->getSteps($i18nKeywords['given'], 'there is agent J', $line, 'Given'),
+                        $this->getSteps($i18nKeywords['and'], 'there is agent K', $line, 'Given'),
+                        $this->getSteps($i18nKeywords['when'], 'I erase agent K\'s memory', $line, 'When'),
+                        $this->getSteps($i18nKeywords['then'], 'there should be agent J', $line, 'Then'),
+                        $this->getSteps($i18nKeywords['but'], 'there should not be agent K', $line, 'Then')
+                    );
+
+                    $scenarios[] = new ScenarioNode('Erasing agent memory', array(), $steps, $scenarioKeyword, $scenarioLine);
+                    $line += 1;
+                }
+                foreach (explode('|', $i18nKeywords['scenario_outline']) as $outlineKeyword) {
+                    $outlineLine = $line;
+                    $line += 1;
+
+                    $steps = array_merge(
+                        $this->getSteps($i18nKeywords['given'], 'there is agent <agent1>', $line, 'Given'),
+                        $this->getSteps($i18nKeywords['and'], 'there is agent <agent2>', $line, 'Given'),
+                        $this->getSteps($i18nKeywords['when'], 'I erase agent <agent2>\'s memory', $line, 'When'),
+                        $this->getSteps($i18nKeywords['then'], 'there should be agent <agent1>', $line, 'Then'),
+                        $this->getSteps($i18nKeywords['but'], 'there should not be agent <agent2>', $line, 'Then')
+                    );
+                    $line += 1;
+
+                    $keywords = explode('|', $i18nKeywords['examples']);
+                    $table = new ExampleTableNode(array(
+                        ++$line => array('agent1', 'agent2'),
+                        ++$line => array('D', 'M')
+                    ), $keywords[0]);
+                    $line += 1;
+
+                    $scenarios[] = new OutlineNode('Erasing other agents\' memory', array(), $steps, $table, $outlineKeyword, $outlineLine);
+                    $line += 1;
+                }
+
+                $features[] = new FeatureNode(
+                    'Internal operations',
+                    <<<DESC
+In order to stay secret
+As a secret organization
+We need to be able to erase past agents' memory
+DESC
+                    ,
+                    array(),
+                    $background,
+                    $scenarios,
+                    $featureKeyword,
+                    $lang,
+                    $lang . '_' . ($transNum + 1) . '.feature',
+                    $featureLine
+                );
+            }
+
+            $dumped = $dumper->dump($lang, false, true);
+            $parsed = array();
+            try {
+                foreach ($dumped as $num => $dumpedFeature) {
+                    $parsed[] = $parser->parse($dumpedFeature, $lang . '_' . ($num + 1) . '.feature');
+                }
+            } catch (\Exception $e) {
+                throw new \Exception($e->getMessage() . ":\n" . json_encode($dumped), 0, $e);
+            }
+
+            $data[] = array($lang, $features, $parsed);
+        }
+
+        return $data;
+    }
+
+    /**
+     * @dataProvider translationTestDataProvider
+     *
+     * @param string $language language name
+     * @param array  $etalon   etalon features (to test against)
+     * @param array  $features array of parsed feature(s)
+     */
+    public function testTranslation($language, array $etalon, array $features)
+    {
+        $this->assertEquals($etalon, $features);
+    }
+}
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Loader/ArrayLoaderTest.php b/vendor/behat/gherkin/tests/Behat/Gherkin/Loader/ArrayLoaderTest.php
new file mode 100644 (file)
index 0000000..697d1d3
--- /dev/null
@@ -0,0 +1,379 @@
+<?php
+
+namespace Tests\Behat\Gherkin\Loader;
+
+use Behat\Gherkin\Loader\ArrayLoader;
+
+class ArrayLoaderTest extends \PHPUnit_Framework_TestCase
+{
+    private $loader;
+
+    protected function setUp()
+    {
+        $this->loader = new ArrayLoader();
+    }
+
+    public function testSupports()
+    {
+        $this->assertFalse($this->loader->supports(__DIR__));
+        $this->assertFalse($this->loader->supports(__FILE__));
+        $this->assertFalse($this->loader->supports('string'));
+        $this->assertFalse($this->loader->supports(array('wrong_root')));
+        $this->assertFalse($this->loader->supports(array('features')));
+        $this->assertTrue($this->loader->supports(array('features' => array())));
+        $this->assertTrue($this->loader->supports(array('feature' => array())));
+    }
+
+    public function testLoadEmpty()
+    {
+        $this->assertEquals(array(), $this->loader->load(array('features' => array())));
+    }
+
+    public function testLoadFeatures()
+    {
+        $features = $this->loader->load(array(
+            'features' => array(
+                array(
+                    'title'         => 'First feature',
+                    'line'          => 3,
+                ),
+                array(
+                    'description'   => 'Second feature description',
+                    'language'      => 'ru',
+                    'tags'          => array('some', 'tags')
+                )
+            ),
+        ));
+
+        $this->assertEquals(2, count($features));
+
+        $this->assertEquals(3, $features[0]->getLine());
+        $this->assertEquals('First feature', $features[0]->getTitle());
+        $this->assertNull($features[0]->getDescription());
+        $this->assertNull($features[0]->getFile());
+        $this->assertEquals('en', $features[0]->getLanguage());
+        $this->assertFalse($features[0]->hasTags());
+
+        $this->assertEquals(1, $features[1]->getLine());
+        $this->assertNull($features[1]->getTitle());
+        $this->assertEquals('Second feature description', $features[1]->getDescription());
+        $this->assertNull($features[1]->getFile());
+        $this->assertEquals('ru', $features[1]->getLanguage());
+        $this->assertEquals(array('some', 'tags'), $features[1]->getTags());
+    }
+
+    public function testLoadScenarios()
+    {
+        $features = $this->loader->load(array(
+            'features' => array(
+                array(
+                    'title'     => 'Feature',
+                    'scenarios' => array(
+                        array(
+                            'title' => 'First scenario',
+                            'line'  => 2
+                        ),
+                        array(
+                            'tags'  => array('second', 'scenario', 'tags')
+                        ),
+                        array(
+                            'tags'  => array('third', 'scenario'),
+                            'line'  => 3
+                        )
+                    )
+                )
+            ),
+        ));
+
+        $this->assertEquals(1, count($features));
+
+        $scenarios = $features[0]->getScenarios();
+
+        $this->assertEquals(3, count($scenarios));
+
+        $this->assertInstanceOf('Behat\Gherkin\Node\ScenarioNode', $scenarios[0]);
+        $this->assertEquals('First scenario', $scenarios[0]->getTitle());
+        $this->assertFalse($scenarios[0]->hasTags());
+        $this->assertEquals(2, $scenarios[0]->getLine());
+
+        $this->assertInstanceOf('Behat\Gherkin\Node\ScenarioNode', $scenarios[1]);
+        $this->assertNull($scenarios[1]->getTitle());
+        $this->assertEquals(array('second', 'scenario', 'tags'), $scenarios[1]->getTags());
+        $this->assertEquals(1, $scenarios[1]->getLine());
+
+        $this->assertInstanceOf('Behat\Gherkin\Node\ScenarioNode', $scenarios[2]);
+        $this->assertNull($scenarios[2]->getTitle());
+        $this->assertEquals(array('third', 'scenario'), $scenarios[2]->getTags());
+        $this->assertEquals(3, $scenarios[2]->getLine());
+    }
+
+    public function testLoadOutline()
+    {
+        $features = $this->loader->load(array(
+            'features' => array(
+                array(
+                    'title'     => 'Feature',
+                    'scenarios' => array(
+                        array(
+                            'type'  => 'outline',
+                            'title' => 'First outline',
+                            'line'  => 2
+                        ),
+                        array(
+                            'type'  => 'outline',
+                            'tags'  => array('second', 'outline', 'tags')
+                        )
+                    )
+                )
+            ),
+        ));
+
+        $this->assertEquals(1, count($features));
+
+        $outlines = $features[0]->getScenarios();
+
+        $this->assertEquals(2, count($outlines));
+
+        $this->assertInstanceOf('Behat\Gherkin\Node\OutlineNode', $outlines[0]);
+        $this->assertEquals('First outline', $outlines[0]->getTitle());
+        $this->assertFalse($outlines[0]->hasTags());
+        $this->assertEquals(2, $outlines[0]->getLine());
+
+        $this->assertInstanceOf('Behat\Gherkin\Node\OutlineNode', $outlines[1]);
+        $this->assertNull($outlines[1]->getTitle());
+        $this->assertEquals(array('second', 'outline', 'tags'), $outlines[1]->getTags());
+        $this->assertEquals(1, $outlines[1]->getLine());
+    }
+
+    public function testOutlineExamples()
+    {
+        $features = $this->loader->load(array(
+            'features' => array(
+                array(
+                    'title'     => 'Feature',
+                    'scenarios' => array(
+                        array(
+                            'type'      => 'outline',
+                            'title'     => 'First outline',
+                            'line'      => 2,
+                            'examples'  => array(
+                                array('user', 'pass'),
+                                array('ever', 'sdsd'),
+                                array('anto', 'fdfd')
+                            )
+                        ),
+                        array(
+                            'type'  => 'outline',
+                            'tags'  => array('second', 'outline', 'tags')
+                        )
+                    )
+                )
+            ),
+        ));
+
+        $this->assertEquals(1, count($features));
+
+        $scenarios = $features[0]->getScenarios();
+        $scenario  = $scenarios[0];
+
+        $this->assertEquals(
+            array(array('user' => 'ever', 'pass' => 'sdsd'), array('user' => 'anto', 'pass' => 'fdfd')),
+            $scenario->getExampleTable()->getHash()
+        );
+    }
+
+    public function testLoadBackground()
+    {
+        $features = $this->loader->load(array(
+            'features' => array(
+                array(
+                ),
+                array(
+                    'background' => array()
+                ),
+                array(
+                    'background' => array(
+                        'line' => 2
+                    )
+                ),
+            )
+        ));
+
+        $this->assertEquals(3, count($features));
+
+        $this->assertFalse($features[0]->hasBackground());
+        $this->assertTrue($features[1]->hasBackground());
+        $this->assertEquals(0, $features[1]->getBackground()->getLine());
+        $this->assertTrue($features[2]->hasBackground());
+        $this->assertEquals(2, $features[2]->getBackground()->getLine());
+    }
+
+    public function testLoadSteps()
+    {
+        $features = $this->loader->load(array(
+            'features' => array(
+                array(
+                    'background' => array(
+                        'steps' => array(
+                            array('type' => 'Gangway!', 'keyword_type' => 'Given', 'text' => 'bg step 1', 'line' => 3),
+                            array('type' => 'Blimey!', 'keyword_type' => 'When', 'text' => 'bg step 2')
+                        )
+                    ),
+                    'scenarios' => array(
+                        array(
+                            'title' => 'Scenario',
+                            'steps' => array(
+                                array('type' => 'Gangway!', 'keyword_type' => 'Given', 'text' => 'sc step 1'),
+                                array('type' => 'Blimey!', 'keyword_type' => 'When', 'text' => 'sc step 2')
+                            )
+                        ),
+                        array(
+                            'title' => 'Outline',
+                            'type'  => 'outline',
+                            'steps' => array(
+                                array('type' => 'Gangway!', 'keyword_type' => 'Given', 'text' => 'out step 1'),
+                                array('type' => 'Blimey!', 'keyword_type' => 'When', 'text' => 'out step 2')
+                            )
+                        )
+                    )
+                )
+            )
+        ));
+
+        $background = $features[0]->getBackground();
+        $this->assertTrue($background->hasSteps());
+        $this->assertEquals(2, count($background->getSteps()));
+        $steps = $background->getSteps();
+        $this->assertEquals('Gangway!', $steps[0]->getType());
+        $this->assertEquals('Gangway!', $steps[0]->getKeyword());
+        $this->assertEquals('Given', $steps[0]->getKeywordType());
+        $this->assertEquals('bg step 1', $steps[0]->getText());
+        $this->assertEquals(3, $steps[0]->getLine());
+        $this->assertEquals('Blimey!', $steps[1]->getType());
+        $this->assertEquals('Blimey!', $steps[1]->getKeyword());
+        $this->assertEquals('When', $steps[1]->getKeywordType());
+        $this->assertEquals('bg step 2', $steps[1]->getText());
+        $this->assertEquals(1, $steps[1]->getLine());
+
+        $scenarios  = $features[0]->getScenarios();
+
+        $scenario = $scenarios[0];
+        $this->assertTrue($scenario->hasSteps());
+        $this->assertEquals(2, count($scenario->getSteps()));
+        $steps = $scenario->getSteps();
+        $this->assertEquals('Gangway!', $steps[0]->getType());
+        $this->assertEquals('Gangway!', $steps[0]->getKeyword());
+        $this->assertEquals('Given', $steps[0]->getKeywordType());
+        $this->assertEquals('sc step 1', $steps[0]->getText());
+        $this->assertEquals(0, $steps[0]->getLine());
+        $this->assertEquals('Blimey!', $steps[1]->getType());
+        $this->assertEquals('Blimey!', $steps[1]->getKeyword());
+        $this->assertEquals('When', $steps[1]->getKeywordType());
+        $this->assertEquals('sc step 2', $steps[1]->getText());
+        $this->assertEquals(1, $steps[1]->getLine());
+
+        $outline = $scenarios[1];
+        $this->assertTrue($outline->hasSteps());
+        $this->assertEquals(2, count($outline->getSteps()));
+        $steps = $outline->getSteps();
+        $this->assertEquals('Gangway!', $steps[0]->getType());
+        $this->assertEquals('Gangway!', $steps[0]->getKeyword());
+        $this->assertEquals('Given', $steps[0]->getKeywordType());
+        $this->assertEquals('out step 1', $steps[0]->getText());
+        $this->assertEquals(0, $steps[0]->getLine());
+        $this->assertEquals('Blimey!', $steps[1]->getType());
+        $this->assertEquals('Blimey!', $steps[1]->getKeyword());
+        $this->assertEquals('When', $steps[1]->getKeywordType());
+        $this->assertEquals('out step 2', $steps[1]->getText());
+        $this->assertEquals(1, $steps[1]->getLine());
+    }
+
+    public function testLoadStepArguments()
+    {
+        $features = $this->loader->load(array(
+            'features' => array(
+                array(
+                    'background' => array(
+                        'steps' => array(
+                            array(
+                                'type' => 'Gangway!', 'keyword_type' => 'Given', 'text' => 'step with table argument',
+                                'arguments' => array(
+                                    array(
+                                        'type'  => 'table',
+                                        'rows'  => array(
+                                            array('key', 'val'),
+                                            array(1, 2),
+                                            array(3, 4)
+                                        )
+                                    )
+                                )
+                            ),
+                            array(
+                                'type' => 'Blimey!', 'keyword_type' => 'When', 'text' => 'step with pystring argument',
+                                'arguments' => array(
+                                    array(
+                                        'type'      => 'pystring',
+                                        'text'      => '    some text',
+                                    )
+                                )
+                            ),
+                            array(
+                                'type' => 'Let go and haul', 'keyword_type' => 'Then', 'text' => '2nd step with pystring argument',
+                                'arguments' => array(
+                                    array(
+                                        'type'      => 'pystring',
+                                        'text'      => 'some text',
+                                    )
+                                )
+                            )
+                        )
+                    )
+                )
+            )
+        ));
+
+        $background = $features[0]->getBackground();
+
+        $this->assertTrue($background->hasSteps());
+
+        $steps = $background->getSteps();
+
+        $this->assertEquals(3, count($steps));
+
+        $arguments = $steps[0]->getArguments();
+        $this->assertEquals('Gangway!', $steps[0]->getType());
+        $this->assertEquals('Gangway!', $steps[0]->getKeyword());
+        $this->assertEquals('Given', $steps[0]->getKeywordType());
+        $this->assertEquals('step with table argument', $steps[0]->getText());
+        $this->assertInstanceOf('Behat\Gherkin\Node\TableNode', $arguments[0]);
+        $this->assertEquals(array(array('key'=>1, 'val'=>2), array('key'=>3,'val'=>4)), $arguments[0]->getHash());
+
+        $arguments = $steps[1]->getArguments();
+        $this->assertEquals('Blimey!', $steps[1]->getType());
+        $this->assertEquals('Blimey!', $steps[1]->getKeyword());
+        $this->assertEquals('When', $steps[1]->getKeywordType());
+        $this->assertEquals('step with pystring argument', $steps[1]->getText());
+        $this->assertInstanceOf('Behat\Gherkin\Node\PyStringNode', $arguments[0]);
+        $this->assertEquals('    some text', (string) $arguments[0]);
+
+        $arguments = $steps[2]->getArguments();
+        $this->assertEquals('Let go and haul', $steps[2]->getType());
+        $this->assertEquals('Let go and haul', $steps[2]->getKeyword());
+        $this->assertEquals('Then', $steps[2]->getKeywordType());
+        $this->assertEquals('2nd step with pystring argument', $steps[2]->getText());
+        $this->assertInstanceOf('Behat\Gherkin\Node\PyStringNode', $arguments[0]);
+        $this->assertEquals('some text', (string) $arguments[0]);
+    }
+
+    public function testSingleFeatureArray()
+    {
+        $features = $this->loader->load(array(
+            'feature' => array(
+                'title' => 'Some feature'
+            )
+        ));
+
+        $this->assertEquals(1, count($features));
+        $this->assertEquals('Some feature', $features[0]->getTitle());
+    }
+}
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Loader/DirectoryLoaderTest.php b/vendor/behat/gherkin/tests/Behat/Gherkin/Loader/DirectoryLoaderTest.php
new file mode 100644 (file)
index 0000000..de32708
--- /dev/null
@@ -0,0 +1,92 @@
+<?php
+
+namespace Tests\Behat\Gherkin\Loader;
+
+use Behat\Gherkin\Loader\DirectoryLoader;
+
+class DirectoryLoaderTest extends \PHPUnit_Framework_TestCase
+{
+    private $gherkin;
+    private $loader;
+    private $featuresPath;
+
+    protected function setUp()
+    {
+        $this->gherkin      = $this->createGherkinMock();
+        $this->loader       = new DirectoryLoader($this->gherkin);
+
+        $this->featuresPath = realpath(__DIR__ . '/../Fixtures/directories');
+    }
+
+    protected function createGherkinMock()
+    {
+        $gherkin = $this->getMockBuilder('Behat\Gherkin\Gherkin')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        return $gherkin;
+    }
+
+    protected function createGherkinFileLoaderMock()
+    {
+        $loader = $this->getMockBuilder('Behat\Gherkin\Loader\GherkinFileLoader')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        return $loader;
+    }
+
+    public function testSupports()
+    {
+        $this->assertFalse($this->loader->supports('non-existent path'));
+        $this->assertFalse($this->loader->supports('non-existent path:2'));
+
+        $this->assertFalse($this->loader->supports(__DIR__ . ':d'));
+        $this->assertFalse($this->loader->supports(__DIR__ . '/../Fixtures/features/pystring.feature'));
+        $this->assertTrue($this->loader->supports(__DIR__));
+        $this->assertTrue($this->loader->supports(__DIR__ . '/../Fixtures/features'));
+    }
+
+    public function testUndefinedFileLoad()
+    {
+        $this->gherkin
+            ->expects($this->once())
+            ->method('resolveLoader')
+            ->with($this->featuresPath.DIRECTORY_SEPARATOR.'phps'.DIRECTORY_SEPARATOR.'some_file.php')
+            ->will($this->returnValue(null));
+
+        $this->assertEquals(array(), $this->loader->load($this->featuresPath . '/phps'));
+    }
+
+    public function testBasePath()
+    {
+        $this->gherkin
+            ->expects($this->once())
+            ->method('resolveLoader')
+            ->with($this->featuresPath.DIRECTORY_SEPARATOR.'phps'.DIRECTORY_SEPARATOR.'some_file.php')
+            ->will($this->returnValue(null));
+
+        $this->loader->setBasePath($this->featuresPath);
+
+        $this->assertEquals(array(), $this->loader->load('phps'));
+    }
+
+    public function testDefinedFileLoad()
+    {
+        $loaderMock = $this->createGherkinFileLoaderMock();
+
+        $this->gherkin
+            ->expects($this->once())
+            ->method('resolveLoader')
+            ->with($this->featuresPath.DIRECTORY_SEPARATOR.'phps'.DIRECTORY_SEPARATOR.'some_file.php')
+            ->will($this->returnValue($loaderMock));
+
+        $loaderMock
+            ->expects($this->once())
+            ->method('load')
+            ->with($this->featuresPath.DIRECTORY_SEPARATOR.'phps'.DIRECTORY_SEPARATOR.'some_file.php')
+            ->will($this->returnValue(array('feature1', 'feature2')));
+
+        $this->assertEquals(array('feature1', 'feature2'), $this->loader->load($this->featuresPath . '/phps'));
+    }
+}
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Loader/GherkinFileLoaderTest.php b/vendor/behat/gherkin/tests/Behat/Gherkin/Loader/GherkinFileLoaderTest.php
new file mode 100644 (file)
index 0000000..8f5d2c1
--- /dev/null
@@ -0,0 +1,111 @@
+<?php
+
+namespace Tests\Behat\Gherkin\Loader;
+
+use Behat\Gherkin\Keywords\CucumberKeywords;
+use Behat\Gherkin\Lexer;
+use Behat\Gherkin\Loader\GherkinFileLoader;
+use Behat\Gherkin\Parser;
+
+class GherkinFileLoaderTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var GherkinFileLoader
+     */
+    private $loader;
+    private $featuresPath;
+
+    public function testSupports()
+    {
+        $this->assertFalse($this->loader->supports('non-existent path'));
+        $this->assertFalse($this->loader->supports('non-existent path:2'));
+
+        $this->assertFalse($this->loader->supports(__DIR__));
+        $this->assertFalse($this->loader->supports(__DIR__ . ':d'));
+        $this->assertFalse($this->loader->supports(__FILE__));
+        $this->assertTrue($this->loader->supports(__DIR__ . '/../Fixtures/features/pystring.feature'));
+    }
+
+    public function testLoad()
+    {
+        $features = $this->loader->load($this->featuresPath . '/pystring.feature');
+        $this->assertEquals(1, count($features));
+        $this->assertEquals('A py string feature', $features[0]->getTitle());
+        $this->assertEquals($this->featuresPath . DIRECTORY_SEPARATOR . 'pystring.feature', $features[0]->getFile());
+
+        $features = $this->loader->load($this->featuresPath . '/multiline_name.feature');
+        $this->assertEquals(1, count($features));
+        $this->assertEquals('multiline', $features[0]->getTitle());
+        $this->assertEquals($this->featuresPath . DIRECTORY_SEPARATOR . 'multiline_name.feature', $features[0]->getFile());
+    }
+
+    public function testParsingUncachedFeature()
+    {
+        $cache = $this->getMockBuilder('Behat\Gherkin\Cache\CacheInterface')->getMock();
+        $this->loader->setCache($cache);
+
+        $cache->expects($this->once())
+            ->method('isFresh')
+            ->with($path = $this->featuresPath . DIRECTORY_SEPARATOR . 'pystring.feature', filemtime($path))
+            ->will($this->returnValue(false));
+
+        $cache->expects($this->once())
+            ->method('write');
+
+        $features = $this->loader->load($this->featuresPath . '/pystring.feature');
+        $this->assertEquals(1, count($features));
+    }
+
+    public function testParsingCachedFeature()
+    {
+        $cache = $this->getMockBuilder('Behat\Gherkin\Cache\CacheInterface')->getMock();
+        $this->loader->setCache($cache);
+
+        $cache->expects($this->once())
+            ->method('isFresh')
+            ->with($path = $this->featuresPath . DIRECTORY_SEPARATOR . 'pystring.feature', filemtime($path))
+            ->will($this->returnValue(true));
+
+        $cache->expects($this->once())
+            ->method('read')
+            ->with($path)
+            ->will($this->returnValue('cache'));
+
+        $cache->expects($this->never())
+            ->method('write');
+
+        $features = $this->loader->load($this->featuresPath . '/pystring.feature');
+        $this->assertEquals('cache', $features[0]);
+    }
+
+    public function testBasePath()
+    {
+        $this->assertFalse($this->loader->supports('features'));
+        $this->assertFalse($this->loader->supports('tables.feature'));
+
+        $this->loader->setBasePath($this->featuresPath . '/../');
+        $this->assertFalse($this->loader->supports('features'));
+        $this->assertFalse($this->loader->supports('tables.feature'));
+        $this->assertTrue($this->loader->supports('features/tables.feature'));
+
+        $features = $this->loader->load('features/pystring.feature');
+        $this->assertEquals(1, count($features));
+        $this->assertEquals('A py string feature', $features[0]->getTitle());
+        $this->assertEquals('features' . DIRECTORY_SEPARATOR . 'pystring.feature', $features[0]->getFile());
+
+        $this->loader->setBasePath($this->featuresPath);
+        $features = $this->loader->load('multiline_name.feature');
+        $this->assertEquals(1, count($features));
+        $this->assertEquals('multiline', $features[0]->getTitle());
+        $this->assertEquals('multiline_name.feature', $features[0]->getFile());
+    }
+
+    protected function setUp()
+    {
+        $keywords = new CucumberKeywords(__DIR__ . '/../Fixtures/i18n.yml');
+        $parser = new Parser(new Lexer($keywords));
+        $this->loader = new GherkinFileLoader($parser);
+
+        $this->featuresPath = realpath(__DIR__ . '/../Fixtures/features');
+    }
+}
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Loader/YamlFileLoaderTest.php b/vendor/behat/gherkin/tests/Behat/Gherkin/Loader/YamlFileLoaderTest.php
new file mode 100644 (file)
index 0000000..83b2739
--- /dev/null
@@ -0,0 +1,67 @@
+<?php
+
+namespace Tests\Behat\Gherkin\Loader;
+
+use Behat\Gherkin\Loader\YamlFileLoader;
+
+class YamlFileLoaderTest extends \PHPUnit_Framework_TestCase
+{
+    private $loader;
+
+    protected function setUp()
+    {
+        $this->loader = new YamlFileLoader();
+    }
+
+    public function testSupports()
+    {
+        $this->assertFalse($this->loader->supports(__DIR__));
+        $this->assertFalse($this->loader->supports(__FILE__));
+        $this->assertFalse($this->loader->supports('string'));
+        $this->assertFalse($this->loader->supports(__DIR__ . '/file.yml'));
+        $this->assertTrue($this->loader->supports(__DIR__ . '/../Fixtures/etalons/addition.yml'));
+    }
+
+    public function testLoadAddition()
+    {
+        $this->loader->setBasePath(__DIR__ . '/../Fixtures');
+        $features = $this->loader->load('etalons/addition.yml');
+
+        $this->assertEquals(1, count($features));
+        $this->assertEquals('etalons'.DIRECTORY_SEPARATOR.'addition.yml', $features[0]->getFile());
+        $this->assertEquals('Addition', $features[0]->getTitle());
+        $this->assertEquals(2, $features[0]->getLine());
+        $this->assertEquals('en', $features[0]->getLanguage());
+        $expectedDescription = <<<EOS
+In order to avoid silly mistakes
+As a math idiot
+I want to be told the sum of two numbers
+EOS;
+        $this->assertEquals($expectedDescription, $features[0]->getDescription());
+
+        $scenarios = $features[0]->getScenarios();
+
+        $this->assertEquals(2, count($scenarios));
+        $this->assertInstanceOf('Behat\Gherkin\Node\ScenarioNode', $scenarios[0]);
+        $this->assertEquals(7, $scenarios[0]->getLine());
+        $this->assertEquals('Add two numbers', $scenarios[0]->getTitle());
+        $steps = $scenarios[0]->getSteps();
+        $this->assertEquals(4, count($steps));
+        $this->assertEquals(9, $steps[1]->getLine());
+        $this->assertEquals('And', $steps[1]->getType());
+        $this->assertEquals('And', $steps[1]->getKeyword());
+        $this->assertEquals('Given', $steps[1]->getKeywordType());
+        $this->assertEquals('I have entered 12 into the calculator', $steps[1]->getText());
+
+        $this->assertInstanceOf('Behat\Gherkin\Node\ScenarioNode', $scenarios[1]);
+        $this->assertEquals(13, $scenarios[1]->getLine());
+        $this->assertEquals('Div two numbers', $scenarios[1]->getTitle());
+        $steps = $scenarios[1]->getSteps();
+        $this->assertEquals(4, count($steps));
+        $this->assertEquals(16, $steps[2]->getLine());
+        $this->assertEquals('When', $steps[2]->getType());
+        $this->assertEquals('When', $steps[2]->getKeyword());
+        $this->assertEquals('When', $steps[2]->getKeywordType());
+        $this->assertEquals('I press div', $steps[2]->getText());
+    }
+}
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Node/ExampleNodeTest.php b/vendor/behat/gherkin/tests/Behat/Gherkin/Node/ExampleNodeTest.php
new file mode 100644 (file)
index 0000000..c6f46be
--- /dev/null
@@ -0,0 +1,92 @@
+<?php
+
+namespace Tests\Behat\Gherkin\Node;
+
+use Behat\Gherkin\Node\ExampleTableNode;
+use Behat\Gherkin\Node\OutlineNode;
+use Behat\Gherkin\Node\PyStringNode;
+use Behat\Gherkin\Node\StepNode;
+use Behat\Gherkin\Node\TableNode;
+
+class ExampleNodeTest extends \PHPUnit_Framework_TestCase
+{
+    public function testCreateExampleSteps()
+    {
+        $steps = array(
+            $step1 = new StepNode('Gangway!', 'I am <name>', array(), null, 'Given'),
+            $step2 = new StepNode('Aye!', 'my email is <email>', array(), null, 'And'),
+            $step3 = new StepNode('Blimey!', 'I open homepage', array(), null, 'When'),
+            $step4 = new StepNode('Let go and haul', 'website should recognise me', array(), null, 'Then'),
+        );
+
+        $table = new ExampleTableNode(array(
+            array('name', 'email'),
+            array('everzet', 'ever.zet@gmail.com'),
+            array('example', 'example@example.com')
+        ), 'Examples');
+
+        $outline = new OutlineNode(null, array(), $steps, $table, null, null);
+        $examples = $outline->getExamples();
+
+        $this->assertCount(4, $steps = $examples[0]->getSteps());
+
+        $this->assertEquals('Gangway!', $steps[0]->getType());
+        $this->assertEquals('Gangway!', $steps[0]->getKeyword());
+        $this->assertEquals('Given', $steps[0]->getKeywordType());
+        $this->assertEquals('I am everzet', $steps[0]->getText());
+        $this->assertEquals('Aye!', $steps[1]->getType());
+        $this->assertEquals('Aye!', $steps[1]->getKeyword());
+        $this->assertEquals('And', $steps[1]->getKeywordType());
+        $this->assertEquals('my email is ever.zet@gmail.com', $steps[1]->getText());
+        $this->assertEquals('Blimey!', $steps[2]->getType());
+        $this->assertEquals('Blimey!', $steps[2]->getKeyword());
+        $this->assertEquals('When', $steps[2]->getKeywordType());
+        $this->assertEquals('I open homepage', $steps[2]->getText());
+
+        $this->assertCount(4, $steps = $examples[1]->getSteps());
+
+        $this->assertEquals('Gangway!', $steps[0]->getType());
+        $this->assertEquals('Gangway!', $steps[0]->getKeyword());
+        $this->assertEquals('Given', $steps[0]->getKeywordType());
+        $this->assertEquals('I am example', $steps[0]->getText());
+        $this->assertEquals('Aye!', $steps[1]->getType());
+        $this->assertEquals('Aye!', $steps[1]->getKeyword());
+        $this->assertEquals('And', $steps[1]->getKeywordType());
+        $this->assertEquals('my email is example@example.com', $steps[1]->getText());
+        $this->assertEquals('Blimey!', $steps[2]->getType());
+        $this->assertEquals('Blimey!', $steps[2]->getKeyword());
+        $this->assertEquals('When', $steps[2]->getKeywordType());
+        $this->assertEquals('I open homepage', $steps[2]->getText());
+    }
+
+    public function testCreateExampleStepsWithArguments()
+    {
+        $steps = array(
+            $step1 = new StepNode('Gangway!', 'I am <name>', array(), null, 'Given'),
+            $step2 = new StepNode('Aye!', 'my email is <email>', array(), null, 'And'),
+            $step3 = new StepNode('Blimey!', 'I open:', array(
+                new PyStringNode(array('page: <url>'), null)
+            ), null, 'When'),
+            $step4 = new StepNode('Let go and haul',  'website should recognise me', array(
+                new TableNode(array(array('page', '<url>')))
+            ), null, 'Then'),
+        );
+
+        $table = new ExampleTableNode(array(
+            array('name', 'email', 'url'),
+            array('everzet', 'ever.zet@gmail.com', 'homepage'),
+            array('example', 'example@example.com', 'other page')
+        ), 'Examples');
+
+        $outline = new OutlineNode(null, array(), $steps, $table, null, null);
+        $examples = $outline->getExamples();
+
+        $steps = $examples[0]->getSteps();
+
+        $args = $steps[2]->getArguments();
+        $this->assertEquals('page: homepage', $args[0]->getRaw());
+
+        $args = $steps[3]->getArguments();
+        $this->assertEquals('| page | homepage |', $args[0]->getTableAsString());
+    }
+}
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Node/OutlineNodeTest.php b/vendor/behat/gherkin/tests/Behat/Gherkin/Node/OutlineNodeTest.php
new file mode 100644 (file)
index 0000000..1e889b8
--- /dev/null
@@ -0,0 +1,68 @@
+<?php
+
+namespace Tests\Behat\Gherkin\Node;
+
+use Behat\Gherkin\Node\ExampleTableNode;
+use Behat\Gherkin\Node\OutlineNode;
+use Behat\Gherkin\Node\StepNode;
+
+class OutlineNodeTest extends \PHPUnit_Framework_TestCase
+{
+    public function testCreatesExamplesForExampleTable()
+    {
+        $steps = array(
+            new StepNode('Gangway!', 'I am <name>', array(), null, 'Given'),
+            new StepNode('Aye!', 'my email is <email>', array(), null, 'And'),
+            new StepNode('Blimey!', 'I open homepage', array(), null, 'When'),
+            new StepNode('Let go and haul',  'website should recognise me', array(), null, 'Then'),
+        );
+
+        $table = new ExampleTableNode(array(
+            array('name', 'email'),
+            array('everzet', 'ever.zet@gmail.com'),
+            array('example', 'example@example.com')
+        ), 'Examples');
+
+        $outline = new OutlineNode(null, array(), $steps, $table, null, null);
+
+        $this->assertCount(2, $examples = $outline->getExamples());
+        $this->assertEquals(1, $examples[0]->getLine());
+        $this->assertEquals(2, $examples[1]->getLine());
+        $this->assertEquals(array('name' => 'everzet', 'email' => 'ever.zet@gmail.com'), $examples[0]->getTokens());
+        $this->assertEquals(array('name'  => 'example', 'email' => 'example@example.com'), $examples[1]->getTokens());
+    }
+
+    public function testCreatesEmptyExamplesForEmptyExampleTable()
+    {
+        $steps = array(
+            new StepNode('Gangway!', 'I am <name>', array(), null, 'Given'),
+            new StepNode('Aye!', 'my email is <email>', array(), null, 'And'),
+            new StepNode('Blimey!', 'I open homepage', array(), null, 'When'),
+            new StepNode('Let go and haul',  'website should recognise me', array(), null, 'Then'),
+        );
+
+        $table = new ExampleTableNode(array(
+            array('name', 'email')
+        ), 'Examples');
+
+        $outline = new OutlineNode(null, array(), $steps, $table, null, null);
+
+        $this->assertCount(0, $examples = $outline->getExamples());
+    }
+
+    public function testCreatesEmptyExamplesForNoExampleTable()
+    {
+        $steps = array(
+            new StepNode('Gangway!', 'I am <name>', array(), null, 'Given'),
+            new StepNode('Aye!', 'my email is <email>', array(), null, 'And'),
+            new StepNode('Blimey!', 'I open homepage', array(), null, 'When'),
+            new StepNode('Let go and haul',  'website should recognise me', array(), null, 'Then'),
+        );
+
+        $table = new ExampleTableNode(array(), 'Examples');
+
+        $outline = new OutlineNode(null, array(), $steps, $table, null, null);
+
+        $this->assertCount(0, $examples = $outline->getExamples());
+    }
+}
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Node/PyStringNodeTest.php b/vendor/behat/gherkin/tests/Behat/Gherkin/Node/PyStringNodeTest.php
new file mode 100644 (file)
index 0000000..1beed38
--- /dev/null
@@ -0,0 +1,27 @@
+<?php
+
+namespace Tests\Behat\Gherkin\Node;
+
+use Behat\Gherkin\Node\PyStringNode;
+
+class PyStringNodeTest extends \PHPUnit_Framework_TestCase
+{
+    public function testGetStrings()
+    {
+        $str = new PyStringNode(array('line1', 'line2', 'line3'), 0);
+
+        $this->assertEquals(array('line1', 'line2', 'line3'), $str->getStrings());
+    }
+
+    public function testGetRaw()
+    {
+        $str = new PyStringNode(array('line1', 'line2', 'line3'), 0);
+
+        $expected = <<<STR
+line1
+line2
+line3
+STR;
+        $this->assertEquals($expected, $str->getRaw());
+    }
+}
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Node/StepNodeTest.php b/vendor/behat/gherkin/tests/Behat/Gherkin/Node/StepNodeTest.php
new file mode 100644 (file)
index 0000000..d334415
--- /dev/null
@@ -0,0 +1,20 @@
+<?php
+
+namespace Tests\Behat\Gherkin\Node;
+
+use Behat\Gherkin\Node\PyStringNode;
+use Behat\Gherkin\Node\StepNode;
+use Behat\Gherkin\Node\TableNode;
+
+class StepNodeTest extends \PHPUnit_Framework_TestCase
+{
+    public function testThatStepCanHaveOnlyOneArgument()
+    {
+        $this->setExpectedException('Behat\Gherkin\Exception\NodeException');
+
+        new StepNode('Gangway!', 'I am on the page:', array(
+            new PyStringNode(array('one', 'two'), 11),
+            new TableNode(array(array('one', 'two'))),
+        ), 10, 'Given');
+    }
+}
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/Node/TableNodeTest.php b/vendor/behat/gherkin/tests/Behat/Gherkin/Node/TableNodeTest.php
new file mode 100644 (file)
index 0000000..a229955
--- /dev/null
@@ -0,0 +1,269 @@
+<?php
+
+namespace Tests\Behat\Gherkin\Node;
+
+use Behat\Gherkin\Node\TableNode;
+
+class TableNodeTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @expectedException \Behat\Gherkin\Exception\NodeException
+     */
+    public function testConstructorExpectsSameNumberOfColumnsInEachRow()
+    {
+        new TableNode(array(
+            array('username', 'password'),
+            array('everzet'),
+            array('antono', 'pa$sword')
+        ));
+    }
+
+    public function constructorTestDataProvider() {
+        return array(
+            'One-dimensional array' => array(
+                array('everzet', 'antono')
+            ),
+            'Three-dimensional array' => array(
+                array(array(array('everzet', 'antono')))
+            )
+        );
+    }
+
+    /**
+     * @dataProvider constructorTestDataProvider
+     * @expectedException \Behat\Gherkin\Exception\NodeException
+     * @expectedExceptionMessage Table is not two-dimensional.
+     */
+    public function testConstructorExpectsTwoDimensionalArrays($table)
+    {
+        new TableNode($table);
+    }
+
+    public function testHashTable()
+    {
+        $table = new TableNode(array(
+            array('username', 'password'),
+            array('everzet', 'qwerty'),
+            array('antono', 'pa$sword')
+        ));
+
+        $this->assertEquals(
+            array(
+                array('username' => 'everzet', 'password' => 'qwerty')
+              , array('username' => 'antono', 'password' => 'pa$sword')
+            ),
+            $table->getHash()
+        );
+
+        $table = new TableNode(array(
+            array('username', 'password'),
+            array('', 'qwerty'),
+            array('antono', ''),
+            array('', '')
+        ));
+
+        $this->assertEquals(
+            array(
+                array('username' => '', 'password' => 'qwerty'),
+                array('username' => 'antono', 'password' => ''),
+                array('username' => '', 'password' => ''),
+            ),
+            $table->getHash()
+        );
+    }
+
+    public function testIterator()
+    {
+        $table = new TableNode(array(
+            array('username', 'password'),
+            array('', 'qwerty'),
+            array('antono', ''),
+            array('', ''),
+        ));
+
+        $this->assertEquals(
+            array(
+                array('username' => '', 'password' => 'qwerty'),
+                array('username' => 'antono', 'password' => ''),
+                array('username' => '', 'password' => ''),
+            ),
+            iterator_to_array($table)
+        );
+    }
+
+    public function testRowsHashTable()
+    {
+        $table = new TableNode(array(
+            array('username', 'everzet'),
+            array('password', 'qwerty'),
+            array('uid', '35'),
+        ));
+
+        $this->assertEquals(
+            array('username' => 'everzet', 'password' => 'qwerty', 'uid' => '35'),
+            $table->getRowsHash()
+        );
+    }
+
+    public function testLongRowsHashTable()
+    {
+        $table = new TableNode(array(
+            array('username', 'everzet', 'marcello'),
+            array('password', 'qwerty', '12345'),
+            array('uid', '35', '22')
+        ));
+
+        $this->assertEquals(array(
+            'username' => array('everzet', 'marcello'),
+            'password' => array('qwerty', '12345'),
+            'uid'      => array('35', '22')
+        ), $table->getRowsHash());
+    }
+
+    public function testGetRows()
+    {
+        $table = new TableNode(array(
+            array('username', 'password'),
+            array('everzet', 'qwerty'),
+            array('antono', 'pa$sword')
+        ));
+
+        $this->assertEquals(array(
+            array('username', 'password'),
+            array('everzet', 'qwerty'),
+            array('antono', 'pa$sword')
+        ), $table->getRows());
+    }
+
+    public function testGetLines()
+    {
+        $table = new TableNode(array(
+            5  => array('username', 'password'),
+            10 => array('everzet', 'qwerty'),
+            13 => array('antono', 'pa$sword')
+        ));
+
+        $this->assertEquals(array(5, 10, 13), $table->getLines());
+    }
+
+    public function testGetRow()
+    {
+        $table = new TableNode(array(
+            array('username', 'password'),
+            array('everzet', 'qwerty'),
+            array('antono', 'pa$sword')
+        ));
+
+        $this->assertEquals(array('username', 'password'), $table->getRow(0));
+        $this->assertEquals(array('antono', 'pa$sword'), $table->getRow(2));
+    }
+
+    public function testGetColumn()
+    {
+        $table = new TableNode(array(
+            array('username', 'password'),
+            array('everzet', 'qwerty'),
+            array('antono', 'pa$sword')
+        ));
+
+        $this->assertEquals(array('username', 'everzet', 'antono'), $table->getColumn(0));
+        $this->assertEquals(array('password', 'qwerty', 'pa$sword'), $table->getColumn(1));
+
+        $table = new TableNode(array(
+            array('username'),
+            array('everzet'),
+            array('antono')
+        ));
+
+        $this->assertEquals(array('username', 'everzet', 'antono'), $table->getColumn(0));
+    }
+
+    public function testGetRowWithLineNumbers()
+    {
+        $table = new TableNode(array(
+            5  => array('username', 'password'),
+            10 => array('everzet', 'qwerty'),
+            13 => array('antono', 'pa$sword')
+        ));
+
+        $this->assertEquals(array('username', 'password'), $table->getRow(0));
+        $this->assertEquals(array('antono', 'pa$sword'), $table->getRow(2));
+    }
+
+    public function testGetTable()
+    {
+        $table = new TableNode($a = array(
+            5  => array('username', 'password'),
+            10 => array('everzet', 'qwerty'),
+            13 => array('antono', 'pa$sword')
+        ));
+
+        $this->assertEquals($a, $table->getTable());
+    }
+
+    public function testGetRowLine()
+    {
+        $table = new TableNode(array(
+            5  => array('username', 'password'),
+            10 => array('everzet', 'qwerty'),
+            13 => array('antono', 'pa$sword')
+        ));
+
+        $this->assertEquals(5, $table->getRowLine(0));
+        $this->assertEquals(13, $table->getRowLine(2));
+    }
+
+    public function testGetRowAsString()
+    {
+        $table = new TableNode(array(
+            5  => array('username', 'password'),
+            10 => array('everzet', 'qwerty'),
+            13 => array('antono', 'pa$sword')
+        ));
+
+        $this->assertEquals('| username | password |', $table->getRowAsString(0));
+        $this->assertEquals('| antono   | pa$sword |', $table->getRowAsString(2));
+    }
+
+    public function testGetTableAsString()
+    {
+        $table = new TableNode(array(
+            5  => array('id', 'username', 'password'),
+            10 => array('42', 'everzet', 'qwerty'),
+            13 => array('2', 'antono', 'pa$sword')
+        ));
+
+        $expected = <<<TABLE
+| id | username | password |
+| 42 | everzet  | qwerty   |
+| 2  | antono   | pa\$sword |
+TABLE;
+        $this->assertEquals($expected, $table->getTableAsString());
+    }
+
+    public function testFromList()
+    {
+        $table = TableNode::fromList(array(
+            'everzet',
+            'antono'
+        ));
+
+        $expected = new TableNode(array(
+            array('everzet'),
+            array('antono'),
+        ));
+        $this->assertEquals($expected, $table);
+    }
+
+    /**
+     * @expectedException \Behat\Gherkin\Exception\NodeException
+     */
+    public function testGetTableFromListWithMultidimensionalArrayArgument()
+    {
+        TableNode::fromList(array(
+            array(1, 2, 3),
+            array(4, 5, 6)
+        ));
+    }
+
+}
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/ParserExceptionsTest.php b/vendor/behat/gherkin/tests/Behat/Gherkin/ParserExceptionsTest.php
new file mode 100644 (file)
index 0000000..c416ec2
--- /dev/null
@@ -0,0 +1,291 @@
+<?php
+
+namespace Tests\Behat\Gherkin;
+
+use Behat\Gherkin\Lexer;
+use Behat\Gherkin\Parser;
+use Behat\Gherkin\Keywords\ArrayKeywords;
+
+class ParserExceptionsTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var Parser
+     */
+    private $gherkin;
+
+    protected function setUp()
+    {
+        $keywords       = new ArrayKeywords(array(
+            'en' => array(
+                'feature'          => 'Feature',
+                'background'       => 'Background',
+                'scenario'         => 'Scenario',
+                'scenario_outline' => 'Scenario Outline',
+                'examples'         => 'Examples',
+                'given'            => 'Given',
+                'when'             => 'When',
+                'then'             => 'Then',
+                'and'              => 'And',
+                'but'              => 'But'
+            ),
+            'ru' => array(
+                'feature'          => 'Функционал',
+                'background'       => 'Предыстория',
+                'scenario'         => 'Сценарий',
+                'scenario_outline' => 'Структура сценария',
+                'examples'         => 'Значения',
+                'given'            => 'Допустим',
+                'when'             => 'То',
+                'then'             => 'Если',
+                'and'              => 'И',
+                'but'              => 'Но'
+            )
+        ));
+        $this->gherkin = new Parser(new Lexer($keywords));
+    }
+
+    public function testStepRightAfterFeature()
+    {
+        $feature = <<<GHERKIN
+Feature: Some feature
+
+    Given some step-like line
+GHERKIN;
+
+        $parsed = $this->gherkin->parse($feature);
+
+        $this->assertEquals("\n  Given some step-like line", $parsed->getDescription());
+    }
+
+    public function testTextInBackground()
+    {
+        $feature = <<<GHERKIN
+Feature: Behat bug test
+    Background: remove X to couse bug
+    Step is red form is not valid
+    asd
+    asd
+    as
+    da
+    sd
+    as
+    das
+    d
+
+
+Scenario: bug user edit date
+GHERKIN;
+
+        $this->gherkin->parse($feature);
+    }
+
+    public function testTextInScenario()
+    {
+        $feature = <<<GHERKIN
+Feature: Behat bug test
+    Scenario: remove X to cause bug
+    Step is red form is not valid
+    asd
+    asd
+    as
+    da
+    sd
+    as
+    das
+    d
+
+
+Scenario Outline: bug user edit date
+Step is red form is not valid
+asd
+asd
+as
+da
+sd
+as
+das
+d
+Examples:
+ ||
+
+GHERKIN;
+
+        $feature = $this->gherkin->parse($feature);
+
+        $this->assertCount(2, $scenarios = $feature->getScenarios());
+        $firstTitle = <<<TEXT
+remove X to cause bug
+Step is red form is not valid
+asd
+asd
+as
+da
+sd
+as
+das
+d
+TEXT;
+        $this->assertEquals($firstTitle, $scenarios[0]->getTitle());
+        $secondTitle = <<<TEXT
+bug user edit date
+Step is red form is not valid
+asd
+asd
+as
+da
+sd
+as
+das
+d
+TEXT;
+        $this->assertEquals($secondTitle, $scenarios[1]->getTitle());
+    }
+
+    /**
+     * @expectedException \Behat\Gherkin\Exception\ParserException
+     */
+    public function testAmbigiousLanguage()
+    {
+        $feature = <<<GHERKIN
+# language: en
+
+# language: ru
+
+Feature: Some feature
+
+    Given something wrong
+GHERKIN;
+
+        $this->gherkin->parse($feature);
+    }
+
+    /**
+     * @expectedException \Behat\Gherkin\Exception\ParserException
+     */
+    public function testEmptyOutline()
+    {
+        $feature = <<<GHERKIN
+Feature: Some feature
+
+    Scenario Outline:
+GHERKIN;
+
+        $this->gherkin->parse($feature);
+    }
+
+    /**
+     * @expectedException \Behat\Gherkin\Exception\ParserException
+     */
+    public function testWrongTagPlacement()
+    {
+        $feature = <<<GHERKIN
+Feature: Some feature
+
+    Scenario:
+        Given some step
+        @some_tag
+        Then some additional step
+GHERKIN;
+
+        $this->gherkin->parse($feature);
+    }
+
+    /**
+     * @expectedException \Behat\Gherkin\Exception\ParserException
+     */
+    public function testBackgroundWithTag()
+    {
+        $feature = <<<GHERKIN
+Feature: Some feature
+
+    @some_tag
+    Background:
+        Given some step
+GHERKIN;
+
+        $this->gherkin->parse($feature);
+    }
+
+    /**
+     * @expectedException \Behat\Gherkin\Exception\ParserException
+     */
+    public function testEndlessPyString()
+    {
+        $feature = <<<GHERKIN
+Feature:
+
+    Scenario:
+        Given something with:
+            """
+            some text
+GHERKIN;
+
+        $this->gherkin->parse($feature);
+    }
+
+    /**
+     * @expectedException \Behat\Gherkin\Exception\ParserException
+     */
+    public function testWrongStepType()
+    {
+        $feature = <<<GHERKIN
+Feature:
+
+    Scenario:
+        Given some step
+
+        Aaand some step
+GHERKIN;
+
+        $this->gherkin->parse($feature);
+    }
+
+    /**
+     * @expectedException \Behat\Gherkin\Exception\ParserException
+     */
+    public function testMultipleBackgrounds()
+    {
+        $feature = <<<GHERKIN
+Feature:
+
+    Background:
+        Given some step
+
+    Background:
+        Aaand some step
+GHERKIN;
+
+        $this->gherkin->parse($feature);
+    }
+
+    /**
+     * @expectedException \Behat\Gherkin\Exception\ParserException
+     */
+    public function testMultipleFeatures()
+    {
+        $feature = <<<GHERKIN
+Feature:
+
+Feature:
+GHERKIN;
+
+        $this->gherkin->parse($feature);
+    }
+
+    /**
+     * @expectedException \Behat\Gherkin\Exception\ParserException
+     */
+    public function testTableWithoutRightBorder()
+    {
+        $feature = <<<GHERKIN
+Feature:
+
+    Scenario:
+        Given something with:
+        | foo | bar
+        | 42  | 42
+GHERKIN;
+
+        $this->gherkin->parse($feature);
+    }
+}
diff --git a/vendor/behat/gherkin/tests/Behat/Gherkin/ParserTest.php b/vendor/behat/gherkin/tests/Behat/Gherkin/ParserTest.php
new file mode 100644 (file)
index 0000000..aff585c
--- /dev/null
@@ -0,0 +1,147 @@
+<?php
+
+namespace Tests\Behat\Gherkin;
+
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Lexer;
+use Behat\Gherkin\Parser;
+use Behat\Gherkin\Keywords\ArrayKeywords;
+use Behat\Gherkin\Loader\YamlFileLoader;
+
+class ParserTest extends \PHPUnit_Framework_TestCase
+{
+    private $gherkin;
+    private $yaml;
+
+    public function parserTestDataProvider()
+    {
+        $data = array();
+
+        foreach (glob(__DIR__ . '/Fixtures/etalons/*.yml') as $file) {
+            $testname = basename($file, '.yml');
+
+            $data[] = array($testname);
+        }
+
+        return $data;
+    }
+
+    /**
+     * @dataProvider parserTestDataProvider
+     *
+     * @param string $fixtureName name of the fixture
+     */
+    public function testParser($fixtureName)
+    {
+        $etalon = $this->parseEtalon($fixtureName . '.yml');
+        $features = $this->parseFixture($fixtureName . '.feature');
+
+        $this->assertInternalType('array', $features);
+        $this->assertEquals(1, count($features));
+        $fixture = $features[0];
+
+        $this->assertEquals($etalon, $fixture);
+    }
+
+    public function testParserResetsTagsBetweenFeatures()
+    {
+        $parser = $this->getGherkinParser();
+
+        $parser->parse(<<<FEATURE
+Feature:
+Scenario:
+Given step
+@skipped
+FEATURE
+        );
+        $feature2 = $parser->parse(<<<FEATURE
+Feature:
+Scenario:
+Given step
+FEATURE
+        );
+
+        $this->assertFalse($feature2->hasTags());
+    }
+
+    protected function getGherkinParser()
+    {
+        if (null === $this->gherkin) {
+            $keywords       = new ArrayKeywords(array(
+                'en' => array(
+                    'feature'          => 'Feature',
+                    'background'       => 'Background',
+                    'scenario'         => 'Scenario',
+                    'scenario_outline' => 'Scenario Outline',
+                    'examples'         => 'Examples',
+                    'given'            => 'Given',
+                    'when'             => 'When',
+                    'then'             => 'Then',
+                    'and'              => 'And',
+                    'but'              => 'But'
+                ),
+                'ru' => array(
+                    'feature'          => 'Функционал',
+                    'background'       => 'Предыстория',
+                    'scenario'         => 'Сценарий',
+                    'scenario_outline' => 'Структура сценария',
+                    'examples'         => 'Значения',
+                    'given'            => 'Допустим',
+                    'when'             => 'То',
+                    'then'             => 'Если',
+                    'and'              => 'И',
+                    'but'              => 'Но'
+                ),
+                'ja' => array (
+                    'feature'           => 'フィーチャ',
+                    'background'        => '背景',
+                    'scenario'          => 'シナリオ',
+                    'scenario_outline'  => 'シナリオアウトライン',
+                    'examples'          => '例|サンプル',
+                    'given'             => '前提<',
+                    'when'              => 'もし<',
+                    'then'              => 'ならば<',
+                    'and'               => 'かつ<',
+                    'but'               => 'しかし<'
+                )
+            ));
+            $this->gherkin  = new Parser(new Lexer($keywords));
+        }
+
+        return $this->gherkin;
+    }
+
+    protected function getYamlParser()
+    {
+        if (null === $this->yaml) {
+            $this->yaml = new YamlFileLoader();
+        }
+
+        return $this->yaml;
+    }
+
+    protected function parseFixture($fixture)
+    {
+        $file = __DIR__ . '/Fixtures/features/' . $fixture;
+
+        return array($this->getGherkinParser()->parse(file_get_contents($file), $file));
+    }
+
+    protected function parseEtalon($etalon)
+    {
+        $features = $this->getYamlParser()->load(__DIR__ . '/Fixtures/etalons/' . $etalon);
+        $feature  = $features[0];
+
+        return new FeatureNode(
+            $feature->getTitle(),
+            $feature->getDescription(),
+            $feature->getTags(),
+            $feature->getBackground(),
+            $feature->getScenarios(),
+            $feature->getKeyword(),
+            $feature->getLanguage(),
+            __DIR__ . '/Fixtures/features/' . basename($etalon, '.yml') . '.feature',
+            $feature->getLine()
+        );
+    }
+}
diff --git a/vendor/behat/mink-extension/.gitignore b/vendor/behat/mink-extension/.gitignore
new file mode 100644 (file)
index 0000000..e389710
--- /dev/null
@@ -0,0 +1,4 @@
+*.tgz
+*.phar
+composer.lock
+vendor
diff --git a/vendor/behat/mink-extension/.travis.yml b/vendor/behat/mink-extension/.travis.yml
new file mode 100644 (file)
index 0000000..f125a61
--- /dev/null
@@ -0,0 +1,38 @@
+language: php
+
+sudo: false
+
+cache:
+  directories:
+    - $HOME/.composer/cache/files
+
+php:
+  - 5.3
+  - 5.4
+  - 5.5
+  - 5.6
+  - hhvm
+
+matrix:
+  include:
+    - php: 5.5
+      env: SYMFONY_VERSION='2.3.*'
+    # Test against dev dependencies
+    - php: 5.6
+      env: DEPS=dev
+
+before_install:
+  - composer self-update
+  - if [ "$SYMFONY_VERSION" != "" ]; then composer require --no-update symfony/symfony=$SYMFONY_VERSION; fi;
+  - if [ "$DEPS" = 'dev' ]; then perl -pi -e 's/^}$/,"minimum-stability":"dev"}/' composer.json; fi;
+
+install:
+  - composer install --no-progress
+
+before_script:
+  - export PATH=./vendor/bin:$PATH
+  - export PATH=./vendor/bin:$PATH
+
+script:
+  - phpspec run -f pretty
+  - behat -fprogress --strict
diff --git a/vendor/behat/mink-extension/LICENSE b/vendor/behat/mink-extension/LICENSE
new file mode 100644 (file)
index 0000000..29864dd
--- /dev/null
@@ -0,0 +1,22 @@
+Copyright (c) 2012 Konstantin Kudryashov <ever.zet@gmail.com>
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
diff --git a/vendor/behat/mink-extension/README.md b/vendor/behat/mink-extension/README.md
new file mode 100755 (executable)
index 0000000..5f90365
--- /dev/null
@@ -0,0 +1,44 @@
+# MinkExtension
+
+[![Build
+Status](https://travis-ci.org/Behat/MinkExtension.svg?branch=master)](https://travis-ci.org/Behat/MinkExtension)
+[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/Behat/MinkExtension/badges/quality-score.png?s=c6474ca52322f5176a2f0cab10974aeee5e6133c)](https://scrutinizer-ci.com/g/Behat/MinkExtension/)
+
+MinkExtension is an integration layer between Behat 3.0+ and Mink 1.5+
+and it provides:
+
+* Additional services for Behat (``Mink``, ``Sessions``, ``Drivers``).
+* ``Behat\MinkExtension\Context\MinkAwareContext`` which provides ``Mink``
+  instance for your contexts.
+* Base ``Behat\MinkExtension\Context\MinkContext`` context which provides base
+  step definitions and hooks for your contexts or subcontexts. Or it could be
+  even used as context on its own.
+
+## Docs
+
+[Official documentation](doc/index.rst).
+
+## Translated languages
+
+For now exist 11 translated languages: `cs`,`de`,`es`,`fr`,`ja`,`nl`,`pl`,`pt`,`ro`,`ru`,`sv`.
+
+**Note:** The `ja`,`nl` and `sv` are outdated.
+
+#### How to add a new translated language?
+
+If you want to translate another language, you can use as reference the `ru` language file under
+[translations folder](https://github.com/Behat/MinkExtension/tree/master/i18n).
+
+**Important:** The filename must match with the same translated language name in [Behat](https://github.com/Behat/Behat/blob/master/i18n.php) and [Gherkin](https://github.com/Behat/Gherkin/blob/master/i18n.php) in order to work correctly.
+
+If the language does not exist in [Gherkin](https://github.com/Behat/Gherkin/blob/master/i18n.php).
+You should consider [contributing to Gherkin translations](https://github.com/Behat/Gherkin/blob/master/CONTRIBUTING.md#contributing-to-gherkin-translations).
+
+## Copyright
+
+Copyright (c) 2012 Konstantin Kudryashov (ever.zet). See LICENSE for details.
+
+## Contributors
+
+* Konstantin Kudryashov [everzet](http://github.com/everzet) [lead developer]
+* Other [awesome developers](https://github.com/Behat/MinkExtension/graphs/contributors)
diff --git a/vendor/behat/mink-extension/behat.yml.dist b/vendor/behat/mink-extension/behat.yml.dist
new file mode 100644 (file)
index 0000000..e0cbd41
--- /dev/null
@@ -0,0 +1,11 @@
+default:
+  suites:
+    default:
+      path: %paths.base%/features
+      contexts: [Behat\MinkExtension\Context\MinkContext]
+  extensions:
+    Behat\MinkExtension:
+      base_url: http://en.wikipedia.org/
+      sessions:
+        default:
+          goutte: ~
diff --git a/vendor/behat/mink-extension/build.php b/vendor/behat/mink-extension/build.php
new file mode 100755 (executable)
index 0000000..e18f5dd
--- /dev/null
@@ -0,0 +1,61 @@
+<?php
+
+/*
+ * This file is part of the Behat
+ *
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+$filename = 'mink_extension.phar';
+
+if (file_exists($filename)) {
+    unlink($filename);
+}
+
+$phar = new \Phar($filename, 0, 'extension.phar');
+$phar->setSignatureAlgorithm(\Phar::SHA1);
+$phar->startBuffering();
+
+foreach (findFiles('src') as $path) {
+    $phar->addFromString($path, file_get_contents(__DIR__.'/'.$path));
+}
+
+$phar->addFromString('init.php', file_get_contents(__DIR__.'/init.php'));
+
+$phar->setStub(<<<STUB
+<?php
+
+/*
+ * This file is part of the Behat
+ *
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+Phar::mapPhar('extension.phar');
+
+return require 'phar://extension.phar/init.php';
+
+__HALT_COMPILER();
+STUB
+);
+$phar->stopBuffering();
+
+function findFiles($dir) {
+    $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir),
+      RecursiveIteratorIterator::CHILD_FIRST);
+
+    $files = array();
+    foreach ($iterator as $path) {
+      if ($path->isFile()) {
+          $files[] = $path->getPath().DIRECTORY_SEPARATOR.$path->getFilename();
+      }
+    }
+
+    return $files;
+}
diff --git a/vendor/behat/mink-extension/composer.json b/vendor/behat/mink-extension/composer.json
new file mode 100644 (file)
index 0000000..2e721d1
--- /dev/null
@@ -0,0 +1,40 @@
+{
+    "name": "behat/mink-extension",
+    "type": "behat-extension",
+    "description": "Mink extension for Behat",
+    "keywords": ["web", "test", "browser", "gui"],
+    "homepage": "http://extensions.behat.org/mink",
+    "license": "MIT",
+    "authors": [
+        {
+            "name": "Konstantin Kudryashov",
+            "email": "ever.zet@gmail.com"
+        },
+        {
+            "name": "Christophe Coevoet",
+            "email": "stof@notk.org"
+        }
+    ],
+
+    "require": {
+        "php":          ">=5.3.2",
+        "behat/behat":  "~3.0,>=3.0.5",
+        "behat/mink":   "~1.5",
+        "symfony/config": "~2.2|~3.0"
+    },
+
+    "require-dev": {
+        "phpspec/phpspec":          "~2.0",
+        "behat/mink-goutte-driver": "~1.1"
+    },
+
+    "autoload": {
+        "psr-0": { "Behat\\MinkExtension": "src/" }
+    },
+
+    "extra": {
+        "branch-alias": {
+            "dev-master": "2.1.x-dev"
+        }
+    }
+}
diff --git a/vendor/behat/mink-extension/doc/index.rst b/vendor/behat/mink-extension/doc/index.rst
new file mode 100644 (file)
index 0000000..144dfec
--- /dev/null
@@ -0,0 +1,349 @@
+Mink Extension
+==============
+
+You can use Behat to describe anything, that you can describe in business
+logic. It’s tools, gui applications, web applications. Most interesting part
+is web applications. First, behavioral testing already exists in web world -
+it’s called functional or acceptance testing. Almost all popular frameworks
+and languages provide functional testing tools. Today we’ll talk about how to
+use Behat for functional testing of web applications. `Mink <http://mink.behat.org>`_
+is a tool exactly for that and this extension provides integration for it.
+
+Basically, MinkExtension is an integration layer between Behat 3.0+ and Mink 1.4+
+and it provides:
+
+* Additional services for Behat (``Mink``, ``Sessions``, ``Drivers``).
+* ``Behat\MinkExtension\Context\MinkAwareContext`` which provides ``Mink``
+  instance for your contexts.
+* Base ``Behat\MinkExtension\Context\MinkContext`` context which provides base
+  step definitions and hooks for your contexts or subcontexts. Or it could be
+  even used as context on its own.
+
+Installation
+------------
+
+This extension requires:
+
+* Behat 3.0+
+* Mink 1.4+
+
+Through Composer
+~~~~~~~~~~~~~~~~
+
+The easiest way to keep your suite updated is to use `Composer <http://getcomposer.org>`_:
+
+1. Install with composer:
+
+    .. code-block:: bash
+
+        $ composer require --dev behat/mink-extension
+
+2. Activate extension by specifying its class in your ``behat.yml``:
+
+    .. code-block:: yaml
+
+        # behat.yml
+        default:
+          # ...
+          extensions:
+            Behat\MinkExtension:
+              base_url:  'http://example.com'
+              sessions:
+                default:
+                  goutte: ~
+
+Usage
+-----
+
+After installing extension, there would be 6 usage options available for you:
+
+1. Extending ``Behat\MinkExtension\Context\RawMinkContext`` in your feature suite.
+   This will give you ability to use a preconfigured `Mink` instance altogether with some
+   convenience methods:
+
+   * ``getSession($name = null)``
+   * ``assertSession($name = null)``
+
+   ``RawMinkContext`` doesn't provide any hooks or definitions, so you can inherit from it
+   in as many contexts as you want - you'll never get ``RedundantStepException``.
+
+2. Extending ``Behat\MinkExtension\Context\MinkContext`` with one of your contexts.
+   Exactly like the previous option, but also provides lots of predefined step definitions out
+   of the box. As this context provides step definitions and hooks, you can use it **only once**
+   inside your feature context tree.
+
+    .. code-block:: php
+
+        <?php
+
+        use Behat\MinkExtension\Context\MinkContext;
+
+        class FeatureContext extends MinkContext
+        {
+            /**
+             * @Then /^I wait for the suggestion box to appear$/
+             */
+            public function iWaitForTheSuggestionBoxToAppear()
+            {
+                $this->getSession()->wait(5000, "$('.suggestions-results').children().length > 0");
+            }
+        }
+
+    .. warning::
+
+        Keep in mind, that you can not have multiple step definitions with the same regex.
+        It will cause a ``RedundantException``. So, you can inherit from ``MinkContext``
+        only with one of your context/subcontext classes.
+
+3. Adding ``Behat\MinkExtension\Context\MinkContext`` as context in your suite.
+   Exactly like previous option, but gives you the ability to keep your main context
+   class clean.
+
+    .. code-block:: yaml
+
+        default:
+          suites:
+            my_suite:
+              contexts:
+                - FeatureContext
+                - Behat\MinkExtension\Context\MinkContext
+
+    .. note::
+
+        Keep in mind, that you can not have multiple step definitions with the same regex.
+        It will cause a ``RedundantException``. So, you can inherit from ``MinkContext``
+        only with one of your context/subcontext classes.
+
+4. Implementing ``Behat\MinkExtension\Context\MinkAwareContext`` with your context.
+
+There are common things between these methods. In each of those, the target context will implement
+``setMink(Mink $mink)`` and ``setMinkParameters(array $parameters)`` methods. Those methods would
+be automatically called **immediately after** each context creation before each scenario. And
+this ``$mink`` instance will be preconfigured based on the settings you've provided in your
+``behat.yml``.
+
+Configuration
+-------------
+
+MinkExtension comes with a flexible configuration system, that gives you
+the ability to configure Mink inside Behat to fulfil all your needs.
+
+Sessions
+--------
+
+You can register as many Mink sessions as you want. For each session, you
+will need to choose the driver you want to use.
+
+.. code-block:: yaml
+
+    default:
+        extensions:
+            Behat\MinkExtension:
+                sessions:
+                    first_session:
+                        selenium2: ~
+                    second_session:
+                        goutte: ~
+                    third_session:
+                        selenium2: ~
+
+MinkExtension will set the default Mink session for each scenario based on
+the configuration settings ``default_session`` and ``javascript_session``
+and on scenario tags:
+
+* A scenario tagged with ``@mink:foo`` will use ``foo`` as default session;
+* A scenario tagged with ``@javascript`` will use the javascript session as default session;
+* Other scenarios will use the default session.
+
+The default session and the default javascript session can also be configured for
+each suite:
+
+.. code-block:: yaml
+
+    default:
+        suites:
+            first:
+                mink_session: foo
+                mink_javascript_session: sahi
+
+If it is not configured explicitly, the javascript session is set to the first
+session using a javascript driver in the order of the configuration (it would
+be ``first_session`` in the example above as ``selenium2`` supports Javascript).
+If it is not configured explicitly, the default session is set to the first
+session using a non-javascript driver if any, or to the first javascript session
+otherwise (it would be ``second_session`` above as ``goutte`` does not support
+javascript).
+
+Drivers
+~~~~~~~
+
+First of all, there are drivers enabling configuration. MinkExtension comes
+with support for 6 drivers out of the box:
+
+* ``GoutteDriver`` - headless driver without JavaScript support. In order to use
+  it, modify your ``behat.yml`` profile:
+
+    .. code-block:: yaml
+
+        default:
+            extensions:
+                Behat\MinkExtension:
+                    sessions:
+                        my_session:
+                            goutte: ~
+
+  .. Tips : HTTPS and self-signed certificate
+  In case you use Behat/Mink/Goutte to test your application, and want to test an
+  application secured with HTTPS, but with a self-signed certificate, you can use
+  the following parameters to avoid the validation error triggered by Guzzle:
+
+  * For ``Guzzle 4`` or later:
+  
+      .. code-block:: yaml
+
+          default:
+              extensions:
+                  Behat\MinkExtension:
+                      sessions:
+                          my_session:
+                              goutte:
+                                  guzzle_parameters:
+                                      verify: false
+  
+  * For ``Guzzle 3`` or earlier:
+  
+      .. code-block:: yaml
+
+          default:
+              extensions:
+                  Behat\MinkExtension:
+                      sessions:
+                          my_session:
+                              goutte:
+                                  guzzle_parameters:
+                                      ssl.certificate_authority: false
+
+* ``Selenium2Driver`` - javascript driver. In order to use it, modify your
+  ``behat.yml`` profile:
+
+    .. code-block:: yaml
+
+        default:
+            extensions:
+                Behat\MinkExtension:
+                    sessions:
+                        my_session:
+                            selenium2: ~
+
+* ``SauceLabsDriver`` - special flavor of the Selenium2Driver configured to use the
+  selenium2 hosted installation of saucelabs.com. In order to use it, modify your
+  ``behat.yml`` profile:
+
+    .. code-block:: yaml
+
+        default:
+            extensions:
+                Behat\MinkExtension:
+                    sessions:
+                        my_session:
+                            sauce_labs: ~
+
+* ``BrowserStackDriver`` - special flavor of the Selenium2Driver configured to use the
+  selenium2 hosted installation of browserstack.com. In order to use it, modify your
+  ``behat.yml`` profile:
+
+    .. code-block:: yaml
+
+        default:
+            extensions:
+                Behat\MinkExtension:
+                    sessions:
+                        my_session:
+                            browser_stack: ~
+
+* ``SeleniumDriver`` - javascript driver. In order to use it, modify your ``behat.yml``
+  profile:
+
+    .. code-block:: yaml
+
+        default:
+            extensions:
+                Behat\MinkExtension:
+                    sessions:
+                        my_session:
+                            selenium: ~
+
+* ``SahiDriver`` - javascript driver. In order to use it, modify your ``behat.yml``
+  profile:
+
+    .. code-block:: yaml
+
+        default:
+            extensions:
+                Behat\MinkExtension:
+                    sessions:
+                        my_session:
+                            sahi: ~
+
+* ``ZombieDriver`` - zombie.js javascript headless driver. In order to use it, modify
+  your ``behat.yml`` profile:
+
+    .. code-block:: yaml
+
+        default:
+            extensions:
+                Behat\MinkExtension:
+                    sessions:
+                        default:
+                            zombie:
+                                # Specify the path to the node_modules directory.
+                                node_modules_path: /usr/local/lib/node_modules/
+
+.. note::
+
+    The phar version of Mink comes bundled with all 5 drivers and you don't need to do
+    anything except enabling them in order to use them.
+
+    But if you're using Composer, you need to install drivers that you need first:
+
+    - GoutteDriver - ``behat/mink-goutte-driver``
+    - SeleniumDriver - ``behat/mink-selenium-driver``
+    - Selenium2Driver (also used for Saucelabs) - ``behat/mink-selenium2-driver``
+    - SahiDriver - ``behat/mink-sahi-driver``
+    - ZombieDriver - ``behat/mink-zombie-driver``
+
+.. note::
+
+    All drivers share the same API, which means that you could use multiple drivers
+    for the same suite - which one fits your needs for concrete scenarios. Don't
+    try to stick to a single driver as there's simply no universal solution - every
+    driver has its pros and cons.
+
+Additional Parameters
+~~~~~~~~~~~~~~~~~~~~~
+
+There's other useful parameters, that you can use to configure your suite:
+
+* ``base_url`` - if you're using relative paths in your ``*.feature`` files
+  (and you should), then this option will define which url to use as a basename
+  for them.
+* ``files_path`` - there's a special step definition for file upload inputs
+  usage. You can use relative paths in those steps. ``files_path`` defines
+  base path in which Mink should search those relative files.
+* ``show_cmd`` - there's a special definition in MinkExtension, that saves
+  currently opened page into temporary file and opens it with some browser
+  utility (for debugging). This option defines command to be used for opening.
+  For example: ``show_cmd: 'firefox %s'``.
+* ``show_tmp_dir`` - the temporary folder used to show the opened page (defaults
+  to the system temp dir)
+* ``show_auto`` - Whether the opened page should be shown automatically when
+  a step fails.
+* ``browser_name`` - meta-option, that defines which browser to use for Sahi,
+  Selenium and Selenium2 drivers.
+* ``default_session`` - defines default session (driver) to be used for all
+  untagged scenarios. Could be any enabled session name.
+* ``javascript_session`` - defines javascript session (driver) (the one, which
+  will be used for ``@javascript`` tagged scenarios). Could be any enabled session
+  name.
+* ``mink_loader`` - path to a file loaded to make Mink available (useful when
+  using the PHAR archive for Mink, useless when using Composer)
diff --git a/vendor/behat/mink-extension/features/search.feature b/vendor/behat/mink-extension/features/search.feature
new file mode 100644 (file)
index 0000000..b4e08ef
--- /dev/null
@@ -0,0 +1,16 @@
+Feature: Search
+  In order to see a word definition
+  As a website user
+  I need to be able to search for a word
+
+  Scenario: Searching for a page that does exist
+    Given I am on "/wiki/Main_Page"
+    When I fill in "search" with "Behavior Driven Development"
+    And I press "searchButton"
+    Then I should see "agile software development"
+
+  Scenario: Searching for a page that does NOT exist
+    Given I am on "/wiki/Main_Page"
+    When I fill in "search" with "Glory Driven Development"
+    And I press "searchButton"
+    Then I should see "Search results"
diff --git a/vendor/behat/mink-extension/i18n/cs.xliff b/vendor/behat/mink-extension/i18n/cs.xliff
new file mode 100644 (file)
index 0000000..74ec33a
--- /dev/null
@@ -0,0 +1,143 @@
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+  <file original="global" source-language="en" target-language="cs" datatype="plaintext">
+    <header />
+    <body>
+        <trans-unit id="i-am-on-page">
+            <source><![CDATA[/^(?:|I )am on "(?P<page>[^"]+)"$/]]></source>
+            <target><![CDATA[/^jsem na(?:| stránce) "(?P<page>[^"]+)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-go-to-page">
+            <source><![CDATA[/^(?:|I )go to "(?P<page>[^"]+)"$/]]></source>
+            <target><![CDATA[/^(?:|pře)jdu na(?:| stránku) "(?P<page>[^"]+)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="reload-the-page">
+            <source><![CDATA[/^(?:|I )reload the page$/]]></source>
+            <target><![CDATA[/^obnovím stránku$/]]></target>
+        </trans-unit>
+        <trans-unit id="move-backward-one-page">
+            <source><![CDATA[/^(?:|I )move backward one page$/]]></source>
+            <target><![CDATA[/^(?:|pře)jdu o jednu stránku zpět$/]]></target>
+        </trans-unit>
+        <trans-unit id="move-forward-one-page">
+            <source><![CDATA[/^(?:|I )move forward one page$/]]></source>
+            <target><![CDATA[/^(?:|pře)jdu o jednu stránku vpřed$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-press-button">
+            <source><![CDATA[/^(?:|I )press "(?P<button>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^stisknu(?:| tlačítko) "(?P<button>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-follow-link">
+            <source><![CDATA[/^(?:|I )follow "(?P<link>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^kliknu na(?:| odkaz) "(?P<link>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-fill-in-field-with-value">
+            <source><![CDATA[/^(?:|I )fill in "(?P<field>(?:[^"]|\\")*)" with "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^zadám do "(?P<field>(?:[^"]|\\")*)" hodnotu "(?P<value>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-fill-in-value-for-field">
+            <source><![CDATA[/^(?:|I )fill in "(?P<value>(?:[^"]|\\")*)" for "(?P<field>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^zadám "(?P<value>(?:[^"]|\\")*)" do "(?P<field>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-fill-in-the-following">
+            <source><![CDATA[/^(?:|I )fill in the following:$/]]></source>
+            <target><![CDATA[/^vyplním formulář:$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-select-option-from-select">
+            <source><![CDATA[/^(?:|I )select "(?P<option>(?:[^"]|\\")*)" from "(?P<select>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^vyberu "(?P<option>(?:[^"]|\\")*)" z "(?P<select>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-additionally-select-option-from-select">
+            <source><![CDATA[/^(?:|I )additionally select "(?P<option>(?:[^"]|\\")*)" from "(?P<select>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^ještě vyberu "(?P<option>(?:[^"]|\\")*)" z "(?P<select>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-check-option">
+            <source><![CDATA[/^(?:|I )check "(?P<option>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:zaškrtnu|označím) "(?P<option>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-uncheck-option">
+            <source><![CDATA[/^(?:|I )uncheck "(?P<option>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^odznačím "(?P<option>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-attach-the-file-to-field">
+            <source><![CDATA[/^(?:|I )attach the file "(?P<path>[^"]*)" to "(?P<field>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^nahraji soubor "(?P<path>[^"]*)" do "(?P<field>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-text">
+            <source><![CDATA[/^(?:|I )should see "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^musím vidět(?:| text) "(?P<text>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-should-contain">
+            <source><![CDATA[/^the response should contain "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^stránka musí obsahovat "(?P<text>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-not-see-text">
+            <source><![CDATA[/^(?:|I )should not see "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^nesmím vidět(?:| text) "(?P<text>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-should-not-contain">
+            <source><![CDATA[/^the response should not contain "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^stránka nesmí obsahovat "(?P<text>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-field-should-contain-value">
+            <source><![CDATA[/^the "(?P<field>(?:[^"]|\\")*)" field should contain "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^pole "(?P<field>(?:[^"]|\\")*)" musí obsahovat "(?P<value>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-field-should-not-contain-value">
+            <source><![CDATA[/^the "(?P<field>(?:[^"]|\\")*)" field should not contain "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^pole "(?P<field>(?:[^"]|\\")*)" nesmí obsahovat "(?P<value>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-checkbox-should-be-checked">
+            <source><![CDATA[/^the "(?P<checkbox>(?:[^"]|\\")*)" checkbox should be checked$/]]></source>
+            <target><![CDATA[/^pole "(?P<checkbox>(?:[^"]|\\")*)" musí být (?:zaškrtnuto|vybráno|označeno)$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-checkbox-should-not-be-checked">
+            <source><![CDATA[/^the "(?P<checkbox>(?:[^"]|\\")*)" checkbox should not be checked$/]]></source>
+            <target><![CDATA[/^pole "(?P<checkbox>(?:[^"]|\\")*)" nesmí být (?:zaškrtnuto|vybráno|označeno)$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-be-on-page">
+            <source><![CDATA[/^(?:|I )should be on "(?P<page>[^"]+)"$/]]></source>
+            <target><![CDATA[/^musím být na stránce "(?P<page>[^"]+)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-url-should-match">
+            <source><![CDATA[/^the (?i)url(?-i) should match (?P<pattern>"(?:[^"]|\\")*")$/]]></source>
+            <target><![CDATA[/^(?:url|adresa|url adresa) musí mít tvar (?P<pattern>"(?:[^"]|\\")*")$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-element-should-contain">
+            <source><![CDATA[/^the "(?P<element>[^"]*)" element should contain "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^element "(?P<element>[^"]*)" musí obsahovat "(?P<value>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-text-in-element">
+            <source><![CDATA[/^(?:|I )should see "(?P<text>(?:[^"]|\\")*)" in the "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^musím vidět(?:| text) "(?P<text>(?:[^"]|\\")*)" uvnitř elementu "(?P<element>[^"]*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-element">
+            <source><![CDATA[/^(?:|I )should see an? "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^musím vidět element "(?P<element>[^"]*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-not-see-element">
+            <source><![CDATA[/^(?:|I )should not see an? "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^nesmím vidět element "(?P<element>[^"]*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-num-elements">
+            <source><![CDATA[/^(?:|I )should see (?P<num>\d+) "(?P<element>[^"]*)" elements?$/]]></source>
+            <target><![CDATA[/^musím vidět (?P<num>\d+) element(?:|y|ů) "(?P<element>[^"]*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-status-code-should-be">
+            <source><![CDATA[/^the response status code should be (?P<code>\d+)$/]]></source>
+            <target><![CDATA[/^(?:|stavový )kód odpovědi serveru musí být (?P<code>\d+)$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-status-code-should-not-be">
+            <source><![CDATA[/^the response status code should not be (?P<code>\d+)$/]]></source>
+            <target><![CDATA[/^(?:|stavový )kód odpovědi serveru nesmí být (?P<code>\d+)$/]]></target>
+        </trans-unit>
+        <trans-unit id="print-last-response">
+            <source><![CDATA[/^print last response$/]]></source>
+            <target><![CDATA[/^vypiš (?:|poslední )stránku$/]]></target>
+        </trans-unit>
+        <trans-unit id="show-last-response">
+            <source><![CDATA[/^show last response$/]]></source>
+            <target><![CDATA[/^zobraz (?:|poslední )stránku$/]]></target>
+        </trans-unit>
+    </body>
+  </file>
+</xliff>
diff --git a/vendor/behat/mink-extension/i18n/da.xliff b/vendor/behat/mink-extension/i18n/da.xliff
new file mode 100644 (file)
index 0000000..cf584e3
--- /dev/null
@@ -0,0 +1,192 @@
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+  <file original="global" source-language="en" target-language="da" datatype="plaintext">
+    <header />
+    <body>
+        <trans-unit id="i-am-homepage">
+            <source><![CDATA[/^(?:|I )am on (?:|the )homepage$/]]></source>
+            <target><![CDATA[/^(?:|jeg )er på hjemmesiden$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-go-to-homepage">
+            <source><![CDATA[/^(?:|I )go to (?:|the )homepage$/]]></source>
+            <target><![CDATA[/^(?:|jeg )går til hjemmesiden$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-am-on-page">
+            <source><![CDATA[/^(?:|I )am on "(?P<page>[^"]+)"$/]]></source>
+            <target><![CDATA[/^(?:|jeg )er på "(?P<side>[^"]+)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-go-to-page">
+            <source><![CDATA[/^(?:|I )go to "(?P<page>[^"]+)"$/]]></source>
+            <target><![CDATA[/^(?:|jeg )går til "(?P<side>[^"]+)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="reload-the-page">
+            <source><![CDATA[/^(?:|I )reload the page$/]]></source>
+            <target><![CDATA[/^(?:|jeg )genindlæser siden$/]]></target>
+        </trans-unit>
+        <trans-unit id="move-backward-one-page">
+            <source><![CDATA[/^(?:|I )move backward one page$/]]></source>
+            <target><![CDATA[/^(?:|jeg )går en side tilbage$/]]></target>
+        </trans-unit>
+        <trans-unit id="move-forward-one-page">
+            <source><![CDATA[/^(?:|I )move forward one page$/]]></source>
+            <target><![CDATA[/^(?:|jeg )går en side frem$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-press-button">
+            <source><![CDATA[/^(?:|I )press "(?P<button>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|jeg )trykker "(?P<knap>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-follow-link">
+            <source><![CDATA[/^(?:|I )follow "(?P<link>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|jeg )følger "(?P<link>(?:[^"]|\\")*)"$/]]></target>
+            <target><![CDATA[/^(?:|jeg )klikker "(?P<link>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-fill-in-field-with-value">
+            <source><![CDATA[/^(?:|I )fill in "(?P<field>(?:[^"]|\\")*)" with "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|jeg )udfylder "(?P<felt>(?:[^"]|\\")*)" med "(?P<value>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-fill-in-field-with">
+            <source><![CDATA[/^(?:|I )fill in "(?P<field>(?:[^"]|\\")*)" with:$/]]></source>
+            <target><![CDATA[/^(?:|jeg )udfylder "(?P<felt>(?:[^"]|\\")*)" med:$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-fill-in-value-for-field">
+            <source><![CDATA[/^(?:|I )fill in "(?P<value>(?:[^"]|\\")*)" for "(?P<field>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|jeg )udfylder "(?P<value>(?:[^"]|\\")*)" for "(?P<felt>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-fill-in-the-following">
+            <source><![CDATA[/^(?:|I )fill in the following:$/]]></source>
+            <target><![CDATA[/^(?:|jeg )udfylder følgende:$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-select-option-from-select">
+            <source><![CDATA[/^(?:|I )select "(?P<option>(?:[^"]|\\")*)" from "(?P<select>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|jeg )vælger "(?P<valgmulighed>(?:[^"]|\\")*)" fra "(?P<select>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-additionally-select-option-from-select">
+            <source><![CDATA[/^(?:|I )additionally select "(?P<option>(?:[^"]|\\")*)" from "(?P<select>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|jeg )derudover vælger "(?P<valgmulighed>(?:[^"]|\\")*)" fra "(?P<select>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-check-option">
+            <source><![CDATA[/^(?:|I )check "(?P<option>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|jeg )markerer "(?P<valgmulighed>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-uncheck-option">
+            <source><![CDATA[/^(?:|I )uncheck "(?P<option>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|jeg )afmarkerer "(?P<valgmulighed>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-attach-the-file-to-field">
+            <source><![CDATA[/^(?:|I )attach the file "(?P<path>[^"]*)" to "(?P<field>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|jeg )vedhæfter filen "(?P<sti>[^"]*)" til "(?P<felt>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-text">
+            <source><![CDATA[/^(?:|I )should see "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|skulle jeg )se "(?P<tekst>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-text-matching">
+            <source><![CDATA[/^(?:|I )should see text matching (?P<pattern>"(?:[^"]|\\")*")$/]]></source>
+            <target><![CDATA[/^(?:|skulle jeg )se tekst matche (?P<pattern>"(?:[^"]|\\")*")$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-not-see-text-matching">
+            <source><![CDATA[/^(?:|I )should not see text matching (?P<pattern>"(?:[^"]|\\")*")$/]]></source>
+            <target><![CDATA[/^(?:|skulle jeg )ikke se tekst matche (?P<pattern>"(?:[^"]|\\")*")$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-should-contain">
+            <source><![CDATA[/^the response should contain "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^skulle responsen indeholde "(?P<tekst>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-not-see-text">
+            <source><![CDATA[/^(?:|I )should not see "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|skulle jeg )ikke se "(?P<tekst>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-should-not-contain">
+            <source><![CDATA[/^the response should not contain "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^skulle responsen ikke indeholde "(?P<tekst>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-field-should-contain-value">
+            <source><![CDATA[/^the "(?P<field>(?:[^"]|\\")*)" field should contain "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^skulle feltet "(?P<felt>(?:[^"]|\\")*)" indeholde "(?P<value>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-field-should-not-contain-value">
+            <source><![CDATA[/^the "(?P<field>(?:[^"]|\\")*)" field should not contain "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^skulle feltet "(?P<felt>(?:[^"]|\\")*)" ikke indeholde "(?P<value>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-checkbox-should-be-checked">
+            <source><![CDATA[/^the "(?P<checkbox>(?:[^"]|\\")*)" checkbox should be checked$/]]></source>
+            <target><![CDATA[/^skulle afkrydsningsfeltet "(?P<felt>(?:[^"]|\\")*)" være markeret$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-checkbox-should-is-checked">
+            <source><![CDATA[/^the checkbox "(?P<checkbox>(?:[^"]|\\")*)" (?:is|should be) checked$/]]></source>
+            <target><![CDATA[/^er afkrydsningsfeltet "(?P<felt>(?:[^"]|\\")*)" markeret$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-checkbox-should-be-unchecked">
+            <source><![CDATA[/^the checkbox "(?P<checkbox>(?:[^"]|\\")*)" should (?:be unchecked|not be checked)$/]]></source>
+            <target><![CDATA[/^skulle afkrydsningsfeltet "(?P<checkbox>(?:[^"]|\\")*)" være afmarkeret$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-checkbox-is-unchecked">
+            <source><![CDATA[/^the checkbox "(?P<checkbox>(?:[^"]|\\")*)" is (?:unchecked|not checked)$/]]></source>
+            <target><![CDATA[/^er afkrydsningsfeltet "(?P<felt>(?:[^"]|\\")*)" afmarkeret$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-checkbox-should-not-be-checked">
+            <source><![CDATA[/^the "(?P<checkbox>(?:[^"]|\\")*)" checkbox should not be checked$/]]></source>
+            <target><![CDATA[/^skulle afkrydsningsfeltet "(?P<felt>(?:[^"]|\\")*)" ikke være markeret$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-be-on-page">
+            <source><![CDATA[/^(?:|I )should be on "(?P<page>[^"]+)"$/]]></source>
+            <target><![CDATA[/^(?:|skulle jeg )være på "(?P<side>[^"]+)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-be-on-homepage">
+            <source><![CDATA[/^(?:|I )should be on (?:|the )homepage$/]]></source>
+            <target><![CDATA[/^(?:|skulle jeg )være på hjemmesiden$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-url-should-match">
+            <source><![CDATA[/^the (?i)url(?-i) should match (?P<pattern>"(?:[^"]|\\")*")$/]]></source>
+            <target><![CDATA[/^skulle webadressen matche (?P<pattern>"(?:[^"]|\\")*")$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-element-should-contain">
+            <source><![CDATA[/^the "(?P<element>[^"]*)" element should contain "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^skulle elementet "(?P<element>[^"]*)" indeholde "(?P<value>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-element-should-not-contain">
+            <source><![CDATA[/^the "(?P<element>[^"]*)" element should not contain "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^skulle elementet "(?P<element>[^"]*)" ikke indeholde "(?P<value>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-text-in-element">
+            <source><![CDATA[/^(?:|I )should see "(?P<text>(?:[^"]|\\")*)" in the "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^(?:|skulle jeg )se "(?P<tekst>(?:[^"]|\\")*)" i elementet "(?P<element>[^"]*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-not-see-text-in-element">
+            <source><![CDATA[/^(?:|I )should not see "(?P<text>(?:[^"]|\\")*)" in the "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^(?:|skulle jeg )ikke se "(?P<tekst>(?:[^"]|\\")*)" i elementet "(?P<element>[^"]*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-element">
+            <source><![CDATA[/^(?:|I )should see an? "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^(?:|skulle jeg )se et element "(?P<element>[^"]*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-not-see-element">
+            <source><![CDATA[/^(?:|I )should not see an? "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^(?:|skulle jeg )ikke se et element "(?P<element>[^"]*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-num-elements">
+            <source><![CDATA[/^(?:|I )should see (?P<num>\d+) "(?P<element>[^"]*)" elements?$/]]></source>
+            <target><![CDATA[/^(?:|skulle jeg )se (?P<num>\d+) "(?P<element>[^"]*)" elementer?$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-status-code-should-be">
+            <source><![CDATA[/^the response status code should be (?P<code>\d+)$/]]></source>
+            <target><![CDATA[/^skulle statuskoderesponsen være (?P<kode>\d+)$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-status-code-should-not-be">
+            <source><![CDATA[/^the response status code should not be (?P<code>\d+)$/]]></source>
+            <target><![CDATA[/^skulle statuskoderesponsen ikke være (?P<kode>\d+)$/]]></target>
+        </trans-unit>
+        <trans-unit id="print-current-URL">
+            <source><![CDATA[/^print current URL$/]]></source>
+            <target><![CDATA[/^print den aktuelle URL$/]]></target>
+        </trans-unit>
+        <trans-unit id="print-last-response">
+            <source><![CDATA[/^print last response$/]]></source>
+            <target><![CDATA[/^udskriv sidste respons$/]]></target>
+        </trans-unit>
+        <trans-unit id="show-last-response">
+            <source><![CDATA[/^show last response$/]]></source>
+            <target><![CDATA[/^vis sidste respons$/]]></target>
+        </trans-unit>
+    </body>
+  </file>
+</xliff>
diff --git a/vendor/behat/mink-extension/i18n/de.xliff b/vendor/behat/mink-extension/i18n/de.xliff
new file mode 100644 (file)
index 0000000..ed7b3b1
--- /dev/null
@@ -0,0 +1,167 @@
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+  <file original="global" source-language="en" target-language="de" datatype="plaintext">
+    <header />
+    <body>
+        <trans-unit id="i-am-on-homepage">
+            <source><![CDATA[/^(?:|I )am on (?:|the )homepage$/]]></source>
+            <target><![CDATA[/^(?:|ich )bin (?:|ich )auf (?:|der )Startseite$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-go-to-homepage">
+            <source><![CDATA[/^(?:|I )go to (?:|the )homepage$/]]></source>
+            <target><![CDATA[/^(?:|ich )gehe (?:|ich )auf (?:|die )Startseite$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-am-on-page">
+            <source><![CDATA[/^(?:|I )am on "(?P<page>[^"]+)"$/]]></source>
+            <target><![CDATA[/^(?:|ich )bin (?:|ich )auf "(?P<page>[^"]+)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-go-to-page">
+            <source><![CDATA[/^(?:|I )go to "(?P<page>[^"]+)"$/]]></source>
+            <target><![CDATA[/^(?:|ich )gehe (?:|ich )nach "(?P<page>[^"]+)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="reload-the-page">
+            <source><![CDATA[/^(?:|I )reload the page$/]]></source>
+            <target><![CDATA[/^(?:|ich )aktualisiere (?:|ich )die Seite$/]]></target>
+        </trans-unit>
+        <trans-unit id="move-backward-one-page">
+            <source><![CDATA[/^(?:|I )move backward one page$/]]></source>
+            <target><![CDATA[/^(?:|ich )gehe (?:|ich )eine Seite zurück$/]]></target>
+        </trans-unit>
+        <trans-unit id="move-forward-one-page">
+            <source><![CDATA[/^(?:|I )move forward one page$/]]></source>
+            <target><![CDATA[/^(?:|ich )gehe (?:|ich )eine Seite vorwärts$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-press-button">
+            <source><![CDATA[/^(?:|I )press "(?P<button>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|ich )drücke (?:|ich )"(?P<button>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-follow-link">
+            <source><![CDATA[/^(?:|I )follow "(?P<link>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|ich )folge (?:|ich )"(?P<link>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-fill-in-field-with-value">
+            <source><![CDATA[/^(?:|I )fill in "(?P<field>(?:[^"]|\\")*)" with "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|ich )gebe (?:|ich )in das Feld "(?P<field>(?:[^"]|\\")*)" "(?P<value>(?:[^"]|\\")*)" ein$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-fill-in-value-for-field">
+            <source><![CDATA[/^(?:|I )fill in "(?P<value>(?:[^"]|\\")*)" for "(?P<field>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|ich )gebe (?:|ich )"(?P<value>(?:[^"]|\\")*)" in "(?P<field>(?:[^"]|\\")*)" ein$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-fill-in-the-following">
+            <source><![CDATA[/^(?:|I )fill in the following:$/]]></source>
+            <target><![CDATA[/^(?:|ich )gebe (?:|ich )das folgende ein:$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-select-option-from-select">
+            <source><![CDATA[/^(?:|I )select "(?P<option>(?:[^"]|\\")*)" from "(?P<select>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|ich )wähle (?:|ich )"(?P<option>(?:[^"]|\\")*)" von "(?P<select>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-additionally-select-option-from-select">
+            <source><![CDATA[/^(?:|I )additionally select "(?P<option>(?:[^"]|\\")*)" from "(?P<select>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|ich )wähle (?:|ich )zusätzlich "(?P<option>(?:[^"]|\\")*)" von "(?P<select>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-check-option">
+            <source><![CDATA[/^(?:|I )check "(?P<option>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|ich )aktiviere (?:|ich )"(?P<option>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-uncheck-option">
+            <source><![CDATA[/^(?:|I )uncheck "(?P<option>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|ich )deaktiviere (?:|ich )"(?P<option>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-attach-the-file-to-field">
+            <source><![CDATA[/^(?:|I )attach the file "(?P<path>[^"]*)" to "(?P<field>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|ich )lade (?:|ich )die Datei "(?P<path>[^"]*)" in "(?P<field>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-be-on-page">
+            <source><![CDATA[/^(?:|I )should be on "(?P<page>[^"]+)"$/]]></source>
+            <target><![CDATA[/^(?:|ich )sollte (?:|ich )auf "(?P<page>[^"]+)" sein$/]]></target>
+        </trans-unit>
+       <trans-unit id="the-url-should-match">
+            <source><![CDATA[/^the (?i)url(?-i) should match (?P<pattern>"(?:[^"]|\\")*")$/]]></source>
+            <target><![CDATA[/^(?:|sollte )die Webadresse (?:|sollte )mit (?P<pattern>"(?:[^"]|\\")*") übereinstimmen$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-status-code-should-be">
+            <source><![CDATA[/^the response status code should be (?P<code>\d+)$/]]></source>
+            <target><![CDATA[/^(?:|sollte )die Status-Code-Rückmeldung (?:|sollte )(?P<code>\d+) sein$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-status-code-should-not-be">
+            <source><![CDATA[/^the response status code should not be (?P<code>\d+)$/]]></source>
+            <target><![CDATA[/^(?:|sollte )die Status-Code-Rückmeldung (?:|sollte )nicht (?P<code>\d+) sein$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-text">
+            <source><![CDATA[/^(?:|I )should see "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|ich )sollte (?:|ich )"(?P<text>(?:[^"]|\\")*)" sehen$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-not-see-text">
+            <source><![CDATA[/^(?:|I )should not see "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|ich )sollte (?:|ich )nicht "(?P<text>(?:[^"]|\\")*)" sehen$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-text-matching">
+            <source><![CDATA[/^(?:|I )should see text matching (?P<pattern>"(?:[^"]|\\")*")$/]]></source>
+            <target><![CDATA[/^(?:|ich )sollte (?:|ich )folgenden Text sehen (?P<pattern>"(?:[^"]|\\")*")$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-not-see-text-matching">
+            <source><![CDATA[/^(?:|I )should not see text matching (?P<pattern>"(?:[^"]|\\")*")$/]]></source>
+            <target><![CDATA[/^(?:|ich )sollte (?:|ich )nicht folgenden Text sehen (?P<pattern>"(?:[^"]|\\")*")$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-should-contain">
+            <source><![CDATA[/^the response should contain "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|sollte )die Rückmeldung (?:|sollte )"(?P<text>(?:[^"]|\\")*)" enthalten$/]]></target>
+        </trans-unit>
+       <trans-unit id="the-response-should-not-contain">
+            <source><![CDATA[/^the response should not contain "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|sollte )die Rückmeldung (?:|sollte )nicht "(?P<text>(?:[^"]|\\")*)" enthalten$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-text-in-element">
+            <source><![CDATA[/^(?:|I )should see "(?P<text>(?:[^"]|\\")*)" in the "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^(?:|ich )sollte (?:|ich )"(?P<text>(?:[^"]|\\")*)" im "(?P<element>[^"]*)" Element sehen$/]]></target>
+        </trans-unit>
+         <trans-unit id="i-should-not-see-text-in-element">
+            <source><![CDATA[/^(?:|I )should not see "(?P<text>(?:[^"]|\\")*)" in the "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^(?:|ich )sollte (?:|ich )nicht "(?P<text>(?:[^"]|\\")*)" im "(?P<element>[^"]*)" Element sehen$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-element-should-contain">
+            <source><![CDATA[/^the "(?P<element>[^"]*)" element should contain "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|sollte )das "(?P<element>[^"]*)" Element (?:|sollte )"(?P<value>(?:[^"]|\\")*)" enthalten$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-element-should-not-contain">
+            <source><![CDATA[/^the "(?P<element>[^"]*)" element should not contain "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|sollte )das "(?P<element>[^"]*)" Element (?:|sollte )nicht "(?P<value>(?:[^"]|\\")*)" enthalten$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-element">
+            <source><![CDATA[/^(?:|I )should see an? "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^(?:|ich )sollte (?:|ich )ein "(?P<element>[^"]*)" Element sehen$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-not-see-element">
+            <source><![CDATA[/^(?:|I )should not see an? "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^(?:|ich )sollte (?:|ich )kein "(?P<element>[^"]*)" Element sehen$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-field-should-contain-value">
+            <source><![CDATA[/^the "(?P<field>(?:[^"]|\\")*)" field should contain "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|sollte )das "(?P<field>(?:[^"]|\\")*)" Feld (?:|sollte )"(?P<value>(?:[^"]|\\")*)" enthalten$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-field-should-not-contain-value">
+            <source><![CDATA[/^the "(?P<field>(?:[^"]|\\")*)" field should not contain "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|sollte )das "(?P<field>(?:[^"]|\\")*)" Feld (?:|sollte )nicht "(?P<value>(?:[^"]|\\")*)" enthalten$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-checkbox-should-be-checked">
+            <source><![CDATA[/^the "(?P<checkbox>(?:[^"]|\\")*)" checkbox should be checked$/]]></source>
+            <target><![CDATA[/^(?:|sollte )die "(?P<checkbox>(?:[^"]|\\")*)" checkbox (?:|sollte )aktiviert sein$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-checkbox-should-not-be-checked">
+            <source><![CDATA[/^the "(?P<checkbox>(?:[^"]|\\")*)" checkbox should not be checked$/]]></source>
+            <target><![CDATA[/^(?:|sollte )die "(?P<checkbox>(?:[^"]|\\")*)" checkbox (?:|sollte )nicht aktiviert sein$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-num-elements">
+            <source><![CDATA[/^(?:|I )should see (?P<num>\d+) "(?P<element>[^"]*)" elements?$/]]></source>
+            <target><![CDATA[/^(?:|ich )sollte (?:|ich )(?P<num>\d+) "(?P<element>[^"]*)" Elemente? sehen$/]]></target>
+        </trans-unit>
+        <trans-unit id="print-last-response">
+            <source><![CDATA[/^print last response$/]]></source>
+            <target><![CDATA[/^gib die letzte Rückmeldung aus$/]]></target>
+        </trans-unit>
+        <trans-unit id="show-last-response">
+            <source><![CDATA[/^show last response$/]]></source>
+            <target><![CDATA[/^zeige die letzte Rückmeldung$/]]></target>
+        </trans-unit>
+    </body>
+  </file>
+</xliff>
diff --git a/vendor/behat/mink-extension/i18n/es.xliff b/vendor/behat/mink-extension/i18n/es.xliff
new file mode 100644 (file)
index 0000000..da25c71
--- /dev/null
@@ -0,0 +1,163 @@
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+  <file original="global" source-language="en" target-language="es" datatype="plaintext">
+    <header />
+    <body>
+        <trans-unit id="i-am-homepage">
+            <source><![CDATA[/^(?:|I )am on (?:|the )homepage$/]]></source>
+            <target><![CDATA[/^estoy en la página de inicio/]]></target>
+        </trans-unit>
+        <trans-unit id="i-go-to-homepage">
+            <source><![CDATA[/^(?:|I )go to (?:|the )homepage$/]]></source>
+            <target><![CDATA[/^voy a la página de inicio/]]></target>
+        </trans-unit>
+        <trans-unit id="i-am-on-page">
+            <source><![CDATA[/^(?:|I )am on "(?P<page>[^"]+)"$/]]></source>
+            <target><![CDATA[/^estoy en "(?P<page>[^"]+)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-go-to-page">
+            <source><![CDATA[/^(?:|I )go to "(?P<page>[^"]+)"$/]]></source>
+            <target><![CDATA[/^voy a "(?P<page>[^"]+)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="reload-the-page">
+            <source><![CDATA[/^(?:|I )reload the page$/]]></source>
+            <target><![CDATA[/^recargo la página$/]]></target>
+        </trans-unit>
+        <trans-unit id="move-backward-one-page">
+            <source><![CDATA[/^(?:|I )move backward one page$/]]></source>
+            <target><![CDATA[/^voy hacia atrás una página$/]]></target>
+        </trans-unit>
+        <trans-unit id="move-forward-one-page">
+            <source><![CDATA[/^(?:|I )move forward one page$/]]></source>
+            <target><![CDATA[/^voy hacia adelante una página$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-press-button">
+            <source><![CDATA[/^(?:|I )press "(?P<button>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^presiono "(?P<button>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-follow-link">
+            <source><![CDATA[/^(?:|I )follow "(?P<link>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^sigo "(?P<link>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-fill-in-field-with-value">
+            <source><![CDATA[/^(?:|I )fill in "(?P<field>(?:[^"]|\\")*)" with "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^relleno "(?P<field>(?:[^"]|\\")*)" con "(?P<value>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-fill-in-value-for-field">
+            <source><![CDATA[/^(?:|I )fill in "(?P<value>(?:[^"]|\\")*)" for "(?P<field>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^relleno con "(?P<value>(?:[^"]|\\")*)" a "(?P<field>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-fill-in-the-following">
+            <source><![CDATA[/^(?:|I )fill in the following:$/]]></source>
+            <target><![CDATA[/^relleno lo siguiente:$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-select-option-from-select">
+            <source><![CDATA[/^(?:|I )select "(?P<option>(?:[^"]|\\")*)" from "(?P<select>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^selecciono "(?P<option>(?:[^"]|\\")*)" de "(?P<select>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-additionally-select-option-from-select">
+            <source><![CDATA[/^(?:|I )additionally select "(?P<option>(?:[^"]|\\")*)" from "(?P<select>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^adicionalmente selecciono "(?P<option>(?:[^"]|\\")*)" de "(?P<select>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-check-option">
+            <source><![CDATA[/^(?:|I )check "(?P<option>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^marco "(?P<option>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-uncheck-option">
+            <source><![CDATA[/^(?:|I )uncheck "(?P<option>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^desmarco "(?P<option>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-attach-the-file-to-field">
+            <source><![CDATA[/^(?:|I )attach the file "(?P<path>[^"]*)" to "(?P<field>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^adjunto el archivo "(?P<path>[^"]*)" a "(?P<field>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-text">
+            <source><![CDATA[/^(?:|I )should see "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^debo ver "(?P<text>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-not-see-text">
+            <source><![CDATA[/^(?:|I )should not see "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^no debo ver "(?P<text>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-text-matching">
+            <source><![CDATA[/^(?:|I )should see text matching (?P<pattern>"(?:[^"]|\\")*")$/]]></source>
+            <target><![CDATA[/^debo ver texto que siga el patrón (?P<pattern>"(?:[^"]|\\")*")$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-not-see-text-matching">
+            <source><![CDATA[/^(?:|I )should not see text matching (?P<pattern>"(?:[^"]|\\")*")$/]]></source>
+            <target><![CDATA[/^no debo ver texto que siga el patrón (?P<pattern>"(?:[^"]|\\")*")$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-should-contain">
+            <source><![CDATA[/^the response should contain "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^la respuesta debe contener "(?P<text>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-should-not-contain">
+            <source><![CDATA[/^the response should not contain "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^la respuesta no debe contener "(?P<text>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-field-should-contain-value">
+            <source><![CDATA[/^the "(?P<field>(?:[^"]|\\")*)" field should contain "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^el campo "(?P<field>(?:[^"]|\\")*)" debe contener "(?P<value>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-field-should-not-contain-value">
+            <source><![CDATA[/^the "(?P<field>(?:[^"]|\\")*)" field should not contain "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^el campo "(?P<field>(?:[^"]|\\")*)" no debe contener "(?P<value>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-checkbox-should-be-checked">
+            <source><![CDATA[/^the "(?P<checkbox>(?:[^"]|\\")*)" checkbox should be checked$/]]></source>
+            <target><![CDATA[/^la casilla de selección "(?P<checkbox>[^"]*)" debe estar marcada$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-checkbox-should-not-be-checked">
+            <source><![CDATA[/^the "(?P<checkbox>(?:[^"]|\\")*)" checkbox should not be checked$/]]></source>
+            <target><![CDATA[/^la casilla de selección "(?P<checkbox>(?:[^"]|\\")*)" no debe estar marcada$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-be-on-page">
+            <source><![CDATA[/^(?:|I )should be on "(?P<page>[^"]+)"$/]]></source>
+            <target><![CDATA[/^debo estar en "(?P<page>[^"]+)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-url-should-match">
+            <source><![CDATA[/^the (?i)url(?-i) should match (?P<pattern>"(?:[^"]|\\")*")$/]]></source>
+            <target><![CDATA[/^la URL debe seguir el patrón (?P<pattern>"(?:[^"]|\\")*")$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-element-should-contain">
+            <source><![CDATA[/^the "(?P<element>[^"]*)" element should contain "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^el elemento "(?P<element>[^"]*)" debe contener "(?P<value>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-text-in-element">
+            <source><![CDATA[/^(?:|I )should see "(?P<text>(?:[^"]|\\")*)" in the "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^debo ver "(?P<text>(?:[^"]|\\")*)" en el elemento "(?P<element>[^"]*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-not-see-text-in-element">
+            <source><![CDATA[/^(?:|I )should not see "(?P<text>(?:[^"]|\\")*)" in the "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^no debo ver "(?P<text>(?:[^"]|\\")*)" en el elemento "(?P<element>[^"]*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-element">
+            <source><![CDATA[/^(?:|I )should see an? "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^debo ver un elemento "(?P<element>[^"]*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-not-see-element">
+            <source><![CDATA[/^(?:|I )should not see an? "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^no debo ver un elemento "(?P<element>[^"]*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-num-elements">
+            <source><![CDATA[/^(?:|I )should see (?P<num>\d+) "(?P<element>[^"]*)" elements?$/]]></source>
+            <target><![CDATA[/^debo ver (?P<num>\d+) "(?P<element>[^"]*)" elementos$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-status-code-should-be">
+            <source><![CDATA[/^the response status code should be (?P<code>\d+)$/]]></source>
+            <target><![CDATA[/^el código de estado de la respuesta debe ser (?P<code>\d+)$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-status-code-should-not-be">
+            <source><![CDATA[/^the response status code should not be (?P<code>\d+)$/]]></source>
+            <target><![CDATA[/^el código de estado de la respuesta no debe ser (?P<code>\d+)$/]]></target>
+        </trans-unit>
+        <trans-unit id="print-last-response">
+            <source><![CDATA[/^print last response$/]]></source>
+            <target><![CDATA[/^imprime la última respuesta$/]]></target>
+        </trans-unit>
+        <trans-unit id="show-last-response">
+            <source><![CDATA[/^show last response$/]]></source>
+            <target><![CDATA[/^muestra la última respuesta$/]]></target>
+        </trans-unit>
+    </body>
+  </file>
+</xliff>
diff --git a/vendor/behat/mink-extension/i18n/fr.xliff b/vendor/behat/mink-extension/i18n/fr.xliff
new file mode 100644 (file)
index 0000000..0cf6adb
--- /dev/null
@@ -0,0 +1,171 @@
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+  <file original="global" source-language="en" target-language="fr" datatype="plaintext">
+    <header />
+    <body>
+        <trans-unit id="i-am-homepage">
+            <source><![CDATA[/^(?:|I )am on (?:|the )homepage$/]]></source>
+            <target><![CDATA[/^(?:|je )suis sur la page d'accueil$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-go-to-homepage">
+            <source><![CDATA[/^(?:|I )go to (?:|the )homepage$/]]></source>
+            <target><![CDATA[/^(?:|je )vais sur la page d'accueil$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-am-on-page">
+            <source><![CDATA[/^(?:|I )am on "(?P<page>[^"]+)"$/]]></source>
+            <target><![CDATA[/^(?:|je )suis sur "(?P<page>[^"]+)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-go-to-page">
+            <source><![CDATA[/^(?:|I )go to "(?P<page>[^"]+)"$/]]></source>
+            <target><![CDATA[/^(?:|je )vais sur "(?P<page>[^"]+)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="reload-the-page">
+            <source><![CDATA[/^(?:|I )reload the page$/]]></source>
+            <target><![CDATA[/^(?:|je )recharge la page$/]]></target>
+        </trans-unit>
+        <trans-unit id="move-backward-one-page">
+            <source><![CDATA[/^(?:|I )move backward one page$/]]></source>
+            <target><![CDATA[/^(?:|je )recule d'une page$/]]></target>
+        </trans-unit>
+        <trans-unit id="move-forward-one-page">
+            <source><![CDATA[/^(?:|I )move forward one page$/]]></source>
+            <target><![CDATA[/^(?:|j')avance d'une page$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-press-button">
+            <source><![CDATA[/^(?:|I )press "(?P<button>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|je )presse "(?P<button>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-follow-link">
+            <source><![CDATA[/^(?:|I )follow "(?P<link>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|je )suis "(?P<link>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-fill-in-field-with-value">
+            <source><![CDATA[/^(?:|I )fill in "(?P<field>(?:[^"]|\\")*)" with "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|je )remplis "(?P<field>(?:[^"]|\\")*)" avec "(?P<value>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-fill-in-value-for-field">
+            <source><![CDATA[/^(?:|I )fill in "(?P<value>(?:[^"]|\\")*)" for "(?P<field>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|je )remplis "(?P<value>(?:[^"]|\\")*)" pour "(?P<field>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-fill-in-the-following">
+            <source><![CDATA[/^(?:|I )fill in the following:$/]]></source>
+            <target><![CDATA[/^(?:|je )remplis le texte suivant:$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-select-option-from-select">
+            <source><![CDATA[/^(?:|I )select "(?P<option>(?:[^"]|\\")*)" from "(?P<select>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|je )sélectionne "(?P<option>(?:[^"]|\\")*)" depuis "(?P<select>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-additionally-select-option-from-select">
+            <source><![CDATA[/^(?:|I )additionally select "(?P<option>(?:[^"]|\\")*)" from "(?P<select>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|je )sélectionne une autre option "(?P<option>(?:[^"]|\\")*)" depuis "(?P<select>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-check-option">
+            <source><![CDATA[/^(?:|I )check "(?P<option>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|je )coche "(?P<option>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-uncheck-option">
+            <source><![CDATA[/^(?:|I )uncheck "(?P<option>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|je )décoche "(?P<option>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-attach-the-file-to-field">
+            <source><![CDATA[/^(?:|I )attach the file "(?P<path>[^"]*)" to "(?P<field>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|j')attache le fichier "(?P<path>[^"]*)" à "(?P<field>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-text">
+            <source><![CDATA[/^(?:|I )should see "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|je )devrais voir "(?P<text>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-text-matching">
+            <source><![CDATA[/^(?:|I )should see text matching (?P<pattern>"(?:[^"]|\\")*")$/]]></source>
+            <target><![CDATA[/^(?:|je )devrais voir un texte suivant le motif (?P<pattern>"(?:[^"]|\\")*")$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-not-see-text-matching">
+            <source><![CDATA[/^(?:|I )should not see text matching (?P<pattern>"(?:[^"]|\\")*")$/]]></source>
+            <target><![CDATA[/^(?:|je )ne devrais pas voir de texte suivant le motif (?P<pattern>"(?:[^"]|\\")*")$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-should-contain">
+            <source><![CDATA[/^the response should contain "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^la réponse devrait contenir "(?P<text>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-not-see-text">
+            <source><![CDATA[/^(?:|I )should not see "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|je )ne devrais pas voir "(?P<text>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-should-not-contain">
+            <source><![CDATA[/^the response should not contain "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^la réponse ne devrait pas contenir "(?P<text>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-field-should-contain-value">
+            <source><![CDATA[/^the "(?P<field>(?:[^"]|\\")*)" field should contain "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^le champ "(?P<field>(?:[^"]|\\")*)" devrait contenir "(?P<value>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-field-should-not-contain-value">
+            <source><![CDATA[/^the "(?P<field>(?:[^"]|\\")*)" field should not contain "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^le champ "(?P<field>(?:[^"]|\\")*)" ne devrait pas contenir "(?P<value>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-checkbox-should-be-checked">
+            <source><![CDATA[/^the "(?P<checkbox>(?:[^"]|\\")*)" checkbox should be checked$/]]></source>
+            <target><![CDATA[/^la case à cocher "(?P<checkbox>[^"]*)" devrait être cochée$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-checkbox-should-not-be-checked">
+            <source><![CDATA[/^the "(?P<checkbox>(?:[^"]|\\")*)" checkbox should not be checked$/]]></source>
+            <target><![CDATA[/^la case à cocher "(?P<checkbox>(?:[^"]|\\")*)" ne devrait pas être cochée$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-be-on-page">
+            <source><![CDATA[/^(?:|I )should be on "(?P<page>[^"]+)"$/]]></source>
+            <target><![CDATA[/^(?:|je )devrais être sur "(?P<page>[^"]+)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-be-on-homepage">
+            <source><![CDATA[/^(?:|I )should be on (?:|the )homepage$/]]></source>
+            <target><![CDATA[/^(?:|je )devrais être sur la page d'accueil$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-url-should-match">
+            <source><![CDATA[/^the (?i)url(?-i) should match (?P<pattern>"(?:[^"]|\\")*")$/]]></source>
+            <target><![CDATA[/^l'(?i)url(?-i) devrait suivre le motif (?P<pattern>"(?:[^"]|\\")*")$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-element-should-contain">
+            <source><![CDATA[/^the "(?P<element>[^"]*)" element should contain "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^l'élément "(?P<element>[^"]*)" devrait contenir "(?P<value>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-element-should-not-contain">
+            <source><![CDATA[/^the "(?P<element>[^"]*)" element should not contain "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^l'élément "(?P<element>[^"]*)" ne devrait pas contenir "(?P<value>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-text-in-element">
+            <source><![CDATA[/^(?:|I )should see "(?P<text>(?:[^"]|\\")*)" in the "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^(?:|je )devrais voir "(?P<text>(?:[^"]|\\")*)" dans l'élément "(?P<element>[^"]*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-not-see-text-in-element">
+            <source><![CDATA[/^(?:|I )should not see "(?P<text>(?:[^"]|\\")*)" in the "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^(?:|je )ne devrais pas voir "(?P<text>(?:[^"]|\\")*)" dans l'élément "(?P<element>[^"]*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-element">
+            <source><![CDATA[/^(?:|I )should see an? "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^(?:|je )devrais voir l'élément "(?P<element>[^"]*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-not-see-element">
+            <source><![CDATA[/^(?:|I )should not see an? "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^(?:|je )ne devrais pas voir l'élément "(?P<element>[^"]*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-num-elements">
+            <source><![CDATA[/^(?:|I )should see (?P<num>\d+) "(?P<element>[^"]*)" elements?$/]]></source>
+            <target><![CDATA[/^(?:|je )devrais voir (?P<num>\d+) éléments? "(?P<element>[^"]*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-status-code-should-be">
+            <source><![CDATA[/^the response status code should be (?P<code>\d+)$/]]></source>
+            <target><![CDATA[/^le code de status de la réponse devrait être (?P<code>\d+)$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-status-code-should-not-be">
+            <source><![CDATA[/^the response status code should not be (?P<code>\d+)$/]]></source>
+            <target><![CDATA[/^le code de status de la réponse ne devrait pas être (?P<code>\d+)$/]]></target>
+        </trans-unit>
+        <trans-unit id="print-last-response">
+            <source><![CDATA[/^print last response$/]]></source>
+            <target><![CDATA[/^imprimer la dernière réponse$/]]></target>
+        </trans-unit>
+        <trans-unit id="show-last-response">
+            <source><![CDATA[/^show last response$/]]></source>
+            <target><![CDATA[/^montrer la dernière réponse$/]]></target>
+        </trans-unit>
+    </body>
+  </file>
+</xliff>
diff --git a/vendor/behat/mink-extension/i18n/hu.xliff b/vendor/behat/mink-extension/i18n/hu.xliff
new file mode 100644 (file)
index 0000000..a618fcb
--- /dev/null
@@ -0,0 +1,187 @@
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+  <file original="global" source-language="en" target-language="hu" datatype="plaintext">
+    <header />
+    <body>
+        <trans-unit id="i-am-homepage">
+            <source><![CDATA[/^(?:|I )am on (?:|the )homepage$/]]></source>
+            <target><![CDATA[/^a címlapon (vagyok|van)$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-go-to-homepage">
+            <source><![CDATA[/^(?:|I )go to (?:|the )homepage$/]]></source>
+            <target><![CDATA[/^(ellátogat|ellátogatok) a címlapra$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-am-on-page">
+            <source><![CDATA[/^(?:|I )am on "(?P<page>[^"]+)"$/]]></source>
+            <target><![CDATA[/^az? "(?P<page>[^"]+)" oldalon (vagyok|van)$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-go-to-page">
+            <source><![CDATA[/^(?:|I )go to "(?P<page>[^"]+)"$/]]></source>
+            <target><![CDATA[/^(ellátogat|ellátogatok) az? "(?P<page>[^"]+) oldalra"$/]]></target>
+        </trans-unit>
+        <trans-unit id="reload-the-page">
+            <source><![CDATA[/^(?:|I )reload the page$/]]></source>
+            <target><![CDATA[/^(újratöltöm|újratölti) az oldalt$/]]></target>
+        </trans-unit>
+        <trans-unit id="move-backward-one-page">
+            <source><![CDATA[/^(?:|I )move backward one page$/]]></source>
+            <target><![CDATA[/^az előző oldalra (látogatok|látogat)$/]]></target>
+        </trans-unit>
+        <trans-unit id="move-forward-one-page">
+            <source><![CDATA[/^(?:|I )move forward one page$/]]></source>
+            <target><![CDATA[/^a következő oldalra (látogatok|látogat)$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-press-button">
+            <source><![CDATA[/^(?:|I )press "(?P<button>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(megnyomom|megnyomja|lenyomom|lenyomja) az? "(?P<button>(?:[^"]|\\")*)" gombot$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-follow-link">
+            <source><![CDATA[/^(?:|I )follow "(?P<link>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(követem|követi) az? "(?P<link>(?:[^"]|\\")*)" linket$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-fill-in-field-with-value">
+            <source><![CDATA[/^(?:|I )fill in "(?P<field>(?:[^"]|\\")*)" with "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(kitöltöm|kitölti) az? "(?P<field>(?:[^"]|\\")*)" mezőt "(?P<value>(?:[^"]|\\")*)" értékkel$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-fill-in-field-with">
+            <source><![CDATA[/^(?:|I )fill in "(?P<field>(?:[^"]|\\")*)" with:$/]]></source>
+            <target><![CDATA[/^(kitöltöm|kitölti) az? "(?P<field>(?:[^"]|\\")*)" mezőt a következő értékekkel:$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-fill-in-value-for-field">
+            <source><![CDATA[/^(?:|I )fill in "(?P<value>(?:[^"]|\\")*)" for "(?P<field>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^az? "(?P<value>(?:[^"]|\\")*)" értékkel (kitöltöm|kitölti) az? "(?P<field>(?:[^"]|\\")*)" mezőt$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-fill-in-the-following">
+            <source><![CDATA[/^(?:|I )fill in the following:$/]]></source>
+            <target><![CDATA[/^Amennyiben (kitöltöm|kitölti) a következőket:$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-select-option-from-select">
+            <source><![CDATA[/^(?:|I )select "(?P<option>(?:[^"]|\\")*)" from "(?P<select>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(kiválasztom|kiválasztja) az? "(?P<option>(?:[^"]|\\")*)" leheőséget az? "(?P<select>(?:[^"]|\\")*)" legördülő listából$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-additionally-select-option-from-select">
+            <source><![CDATA[/^(?:|I )additionally select "(?P<option>(?:[^"]|\\")*)" from "(?P<select>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(kiválasztom|kiválasztja) a "(?P<option>(?:[^"]|\\")*)" további lehetőséget az? "(?P<select>(?:[^"]|\\")*)" legördülő listából$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-check-option">
+            <source><![CDATA[/^(?:|I )check "(?P<option>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(kiválasztom|kiválasztja) az? "(?P<option>(?:[^"]|\\")*) opciót"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-uncheck-option">
+            <source><![CDATA[/^(?:|I )uncheck "(?P<option>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(törlöm|törli) az? "(?P<option>(?:[^"]|\\")*)" opciót$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-attach-the-file-to-field">
+            <source><![CDATA[/^(?:|I )attach the file "(?P<path>[^"]*)" to "(?P<field>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(csatolom|csatolja) az? "(?P<path>[^"]*)" fájlt az? "(?P<field>(?:[^"]|\\")*)" mezőhöz$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-text">
+            <source><![CDATA[/^(?:|I )should see "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^az? "(?P<text>(?:[^"]|\\")*)" szöveget kell (látnom|látnia)$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-text-matching">
+            <source><![CDATA[/^(?:|I )should see text matching (?P<pattern>"(?:[^"]|\\")*")$/]]></source>
+            <target><![CDATA[/^az? (?P<pattern>"(?:[^"]|\\")*") mintára illeszkedő szöveget (látnom|látnia) kell$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-not-see-text-matching">
+            <source><![CDATA[/^(?:|I )should not see text matching (?P<pattern>"(?:[^"]|\\")*")$/]]></source>
+            <target><![CDATA[/^az? (?P<pattern>"(?:[^"]|\\")*") mintára illeszkedő szöveget nem szabad (látnom|látnia)$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-should-contain">
+            <source><![CDATA[/^the response should contain "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^a válasznak tartalmaznia kell a következőt: "(?P<text>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-not-see-text">
+            <source><![CDATA[/^(?:|I )should not see "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^az? "(?P<text>(?:[^"]|\\")*)" szöveget nem szabad (látnom|látnia)$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-should-not-contain">
+            <source><![CDATA[/^the response should not contain "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^a válasznak nem szabad tartalmaznia "(?P<text>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-field-should-contain-value">
+            <source><![CDATA[/^the "(?P<field>(?:[^"]|\\")*)" field should contain "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^az? "(?P<field>(?:[^"]|\\")*)" mezőnek tartalmaznia kell a következő értéket: "(?P<value>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-field-should-not-contain-value">
+            <source><![CDATA[/^the "(?P<field>(?:[^"]|\\")*)" field should not contain "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^az? "(?P<field>(?:[^"]|\\")*)" mezőnek nem szabad tartalmaznia a következő értéket: "(?P<value>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-checkbox-should-be-checked">
+            <source><![CDATA[/^the "(?P<checkbox>(?:[^"]|\\")*)" checkbox should be checked$/]]></source>
+            <target><![CDATA[/^az? "(?P<checkbox>(?:[^"]|\\")*)" jelölőnégyzetnek be kell jelölve lennie$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-checkbox-should-is-checked">
+            <source><![CDATA[/^the checkbox "(?P<checkbox>(?:[^"]|\\")*)" (?:is|should be) checked$/]]></source>
+            <target><![CDATA[/^az? "(?P<checkbox>(?:[^"]|\\")*)" jelölőnégyzetnek be kell lennie jelölve$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-checkbox-should-be-unchecked">
+            <source><![CDATA[/^the checkbox "(?P<checkbox>(?:[^"]|\\")*)" should (?:be unchecked|not be checked)$/]]></source>
+            <target><![CDATA[/^az? "(?P<checkbox>(?:[^"]|\\")*)" jelölőnégyzetnek törölve kell lennie$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-checkbox-is-unchecked">
+            <source><![CDATA[/^the checkbox "(?P<checkbox>(?:[^"]|\\")*)" is (?:unchecked|not checked)$/]]></source>
+            <target><![CDATA[/^az? "(?P<checkbox>(?:[^"]|\\")*)" jelölőnégyzet törölve van$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-be-on-page">
+            <source><![CDATA[/^(?:|I )should be on "(?P<page>[^"]+)"$/]]></source>
+            <target><![CDATA[/^a? "(?P<page>[^"]+)" oldalon kell (lennem|lennie)$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-be-on-homepage">
+            <source><![CDATA[/^(?:|I )should be on (?:|the )homepage$/]]></source>
+            <target><![CDATA[/^a címlapon kell (lennem|lennie)/]]></target>
+        </trans-unit>
+        <trans-unit id="the-url-should-match">
+            <source><![CDATA[/^the (?i)url(?-i) should match (?P<pattern>"([^"]|\\")*")$/]]></source>
+            <target><![CDATA[/^az? (url|webcím) illeszkedik a következő mintára: (?P<pattern>"([^"]|\\")*")$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-element-should-contain">
+            <source><![CDATA[/^the "(?P<element>[^"]*)" element should contain "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^az? "(?P<element>[^"]*)" tartalmaznia kell a következő értéket: "(?P<value>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-element-should-not-contain">
+            <source><![CDATA[/^the "(?P<element>[^"]*)" element should not contain "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^az? "(?P<element>[^"]*)" nem szabad tartalmaznia a következő értéket: "(?P<value>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-text-in-element">
+            <source><![CDATA[/^(?:|I )should see "(?P<text>(?:[^"]|\\")*)" in the "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^az? "(?P<text>(?:[^"]|\\")*)" szöveget (látnom|látnia) kell az? "(?P<element>[^"]*)" elemben$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-not-see-text-in-element">
+            <source><![CDATA[/^(?:|I )should not see "(?P<text>(?:[^"]|\\")*)" in the "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^az? "(?P<text>(?:[^"]|\\")*)" szöveget nem szabad (látnom|látnia) az? "(?P<element>[^"]*)" elemben$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-element">
+            <source><![CDATA[/^(?:|I )should see an? "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^az? "(?P<element>[^"]*)" elemet (látnom|látnia) kell$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-not-see-element">
+            <source><![CDATA[/^(?:|I )should not see an? "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^az? "(?P<element>[^"]*)" elemet nem szabad látnia$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-num-elements">
+            <source><![CDATA[/^(?:|I )should see (?P<num>\d+) "(?P<element>[^"]*)" elements?$/]]></source>
+            <target><![CDATA[/^(?P<num>\d+) darab "(?P<element>[^"]*)" elemet kell (látnom|látnia)$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-status-code-should-be">
+            <source><![CDATA[/^the response status code should be (?P<code>\d+)$/]]></source>
+            <target><![CDATA[/^a válaszüzenet kódjának a következőnek kell lennie: (?P<code>\d+)$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-status-code-should-not-be">
+            <source><![CDATA[/^the response status code should not be (?P<code>\d+)$/]]></source>
+            <target><![CDATA[/^a válaszüzenet kódja nem lehet a következő: (?P<code>\d+)$/]]></target>
+        </trans-unit>
+        <trans-unit id="print-current-URL">
+            <source><![CDATA[/^print current URL$/]]></source>
+            <target><![CDATA[/^nyomtassa ki az aktuális URL-t$/]]></target>
+        </trans-unit>
+        <trans-unit id="print-last-response">
+            <source><![CDATA[/^print last response$/]]></source>
+            <target><![CDATA[/^nyomtassa ki a legutóbbi választ$/]]></target>
+        </trans-unit>
+        <trans-unit id="show-last-response">
+            <source><![CDATA[/^show last response$/]]></source>
+            <target><![CDATA[/^mutassa a legutóbi választ$/]]></target>
+        </trans-unit>
+    </body>
+  </file>
+</xliff>
diff --git a/vendor/behat/mink-extension/i18n/id.xliff b/vendor/behat/mink-extension/i18n/id.xliff
new file mode 100644 (file)
index 0000000..8e045de
--- /dev/null
@@ -0,0 +1,187 @@
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+  <file original="global" source-language="en" target-language="id" datatype="plaintext">
+    <header />
+    <body>
+        <trans-unit id="i-am-homepage">
+            <source><![CDATA[/^(?:|I )am on (?:|the )homepage$/]]></source>
+            <target><![CDATA[/^(?:|saya )(?:berada di |di )(?:|halaman )beranda$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-go-to-homepage">
+            <source><![CDATA[/^(?:|I )go to (?:|the )homepage$/]]></source>
+            <target><![CDATA[/^(?:|saya )ke (?:|halaman )beranda$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-am-on-page">
+            <source><![CDATA[/^(?:|I )am on "(?P<page>[^"]+)"$/]]></source>
+            <target><![CDATA[/^(?:|saya )(?:berada di |di )(?:|halaman )"(?P<page>[^"]+)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-go-to-page">
+            <source><![CDATA[/^(?:|I )go to "(?P<page>[^"]+)"$/]]></source>
+            <target><![CDATA[/^(?:|saya )ke (?:|halaman )"(?P<page>[^"]+)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="reload-the-page">
+            <source><![CDATA[/^(?:|I )reload the page$/]]></source>
+            <target><![CDATA[/^(?:|saya )mereload halaman$/]]></target>
+        </trans-unit>
+        <trans-unit id="move-backward-one-page">
+            <source><![CDATA[/^(?:|I )move backward one page$/]]></source>
+            <target><![CDATA[/^(?:|saya )mundur satu halaman$/]]></target>
+        </trans-unit>
+        <trans-unit id="move-forward-one-page">
+            <source><![CDATA[/^(?:|I )move forward one page$/]]></source>
+            <target><![CDATA[/^(?:|saya )maju satu halaman$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-press-button">
+            <source><![CDATA[/^(?:|I )press "(?P<button>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|saya )menekan (?:|tombol )"(?P<button>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-follow-link">
+            <source><![CDATA[/^(?:|I )follow "(?P<link>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|saya )mengikuti (?:|tautan )"(?P<link>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-fill-in-field-with-value">
+            <source><![CDATA[/^(?:|I )fill in "(?P<field>(?:[^"]|\\")*)" with "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+           <target><![CDATA[/^(?:|saya )mengisi (?:|isian )"(?P<field>(?:[^"]|\\")*)" dengan (?:|nilai )"(?P<value>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-fill-in-field-with">
+            <source><![CDATA[/^(?:|I )fill in "(?P<field>(?:[^"]|\\")*)" with:$/]]></source>
+            <target><![CDATA[/^(?:|saya )mengisi (?:|isian )"(?P<field>(?:[^"]|\\")*)" dengan (?:|nilai ):$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-fill-in-value-for-field">
+            <source><![CDATA[/^(?:|I )fill in "(?P<value>(?:[^"]|\\")*)" for "(?P<field>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|saya )mengisi (?:|nilai )"(?P<value>(?:[^"]|\\")*)" untuk (?:|isian )"(?P<field>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-fill-in-the-following">
+            <source><![CDATA[/^(?:|I )fill in the following:$/]]></source>
+            <target><![CDATA[/^(?:|saya )mengisi:$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-select-option-from-select">
+            <source><![CDATA[/^(?:|I )select "(?P<option>(?:[^"]|\\")*)" from "(?P<select>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|saya )memilih (?:|opsi )"(?P<option>(?:[^"]|\\")*)" pada (?:|pilihan )"(?P<select>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-additionally-select-option-from-select">
+            <source><![CDATA[/^(?:|I )additionally select "(?P<option>(?:[^"]|\\")*)" from "(?P<select>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|saya )menambahkan pilihan "(?P<option>(?:[^"]|\\")*)" pada (?:|pilihan )"(?P<select>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-check-option">
+            <source><![CDATA[/^(?:|I )check "(?P<option>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|saya )menandai (?:|opsi )"(?P<option>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-uncheck-option">
+            <source><![CDATA[/^(?:|I )uncheck "(?P<option>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|saya )tidak menandai (?:|opsi )"(?P<option>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-attach-the-file-to-field">
+            <source><![CDATA[/^(?:|I )attach the file "(?P<path>[^"]*)" to "(?P<field>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|saya )melampirkan file "(?P<path>[^"]*)" untuk (?:|isian )"(?P<field>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-text">
+            <source><![CDATA[/^(?:|I )should see "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|saya )harus melihat (?:|teks |pesan )"(?P<text>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-text-matching">
+            <source><![CDATA[/^(?:|I )should see text matching (?P<pattern>"(?:[^"]|\\")*")$/]]></source>
+            <target><![CDATA[/^(?:|saya )harus melihat teks yang cocok dengan (?:|pola )(?P<pattern>"(?:[^"]|\\")*")$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-not-see-text-matching">
+            <source><![CDATA[/^(?:|I )should not see text matching (?P<pattern>"(?:[^"]|\\")*")$/]]></source>
+            <target><![CDATA[/^(?:|saya )tidak melihat teks yang cocok dengan (?:|pola )(?P<pattern>"(?:[^"]|\\")*")$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-should-contain">
+            <source><![CDATA[/^the response should contain "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^respon harus memiliki (?:|teks )"(?P<text>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-not-see-text">
+            <source><![CDATA[/^(?:|I )should not see "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|saya )tidak melihat (?:|teks )"(?P<text>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-should-not-contain">
+            <source><![CDATA[/^the response should not contain "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^respon tidak memiliki (?:|teks )"(?P<text>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-field-should-contain-value">
+            <source><![CDATA[/^the "(?P<field>(?:[^"]|\\")*)" field should contain "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^isian "(?P<field>(?:[^"]|\\")*)" harus memiliki nilai "(?P<value>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-field-should-not-contain-value">
+            <source><![CDATA[/^the "(?P<field>(?:[^"]|\\")*)" field should not contain "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^isian "(?P<field>(?:[^"]|\\")*)" tidak memiliki nilai "(?P<value>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-checkbox-should-be-checked">
+            <source><![CDATA[/^the "(?P<checkbox>(?:[^"]|\\")*)" checkbox should be checked$/]]></source>
+            <target><![CDATA[/^pilihan "(?P<checkbox>(?:[^"]|\\")*)" dicentang$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-checkbox-should-is-checked">
+            <source><![CDATA[/^the checkbox "(?P<checkbox>(?:[^"]|\\")*)" (?:is|should be) checked$/]]></source>
+            <target><![CDATA[/^pilihan "(?P<checkbox>(?:[^"]|\\")*)" (?:harus|seharusnya) dicentang$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-checkbox-should-be-unchecked">
+            <source><![CDATA[/^the checkbox "(?P<checkbox>(?:[^"]|\\")*)" should (?:be unchecked|not be checked)$/]]></source>
+            <target><![CDATA[/^pilihan "(?P<checkbox>(?:[^"]|\\")*)" tidak (?:harus|seharusnya) dicentang$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-checkbox-is-unchecked">
+            <source><![CDATA[/^the checkbox "(?P<checkbox>(?:[^"]|\\")*)" is (?:unchecked|not checked)$/]]></source>
+            <target><![CDATA[/^pilihan "(?P<checkbox>(?:[^"]|\\")*)" (?:seharusnya |harus )tidak dicentang$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-be-on-page">
+            <source><![CDATA[/^(?:|I )should be on "(?P<page>[^"]+)"$/]]></source>
+            <target><![CDATA[/^(?:|saya )harus (?:|berada )di (?:|halaman )"(?P<page>[^"]+)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-be-on-homepage">
+            <source><![CDATA[/^(?:|I )should be on (?:|the )homepage$/]]></source>
+            <target><![CDATA[/^(?:|saya )harus (?:|berada )di (?:|halaman )beranda$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-url-should-match">
+            <source><![CDATA[/^the (?i)url(?-i) should match (?P<pattern>"(?:[^"]|\\")*")$/]]></source>
+            <target><![CDATA[/^url (?i)url(?-i) harus cocok dengan (?:|pola )(?P<pattern>"(?:[^"]|\\")*")$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-element-should-contain">
+            <source><![CDATA[/^the "(?P<element>[^"]*)" element should contain "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^elemen "(?P<element>[^"]*)" harus memiliki nilai "(?P<value>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-element-should-not-contain">
+            <source><![CDATA[/^the "(?P<element>[^"]*)" element should not contain "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^elemen "(?P<element>[^"]*)" tidak memiliki nilai "(?P<value>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-text-in-element">
+            <source><![CDATA[/^(?:|I )should see "(?P<text>(?:[^"]|\\")*)" in the "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^(?:|saya )harus melihat (?:|teks )"(?P<text>(?:[^"]|\\")*)" pada elemen "(?P<element>[^"]*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-not-see-text-in-element">
+            <source><![CDATA[/^(?:|I )should not see "(?P<text>(?:[^"]|\\")*)" in the "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^(?:|saya )tidak melihat (?:|teks )"(?P<text>(?:[^"]|\\")*)" pada elemen "(?P<element>[^"]*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-element">
+            <source><![CDATA[/^(?:|I )should see an? "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^(?:|saya )harus melihat elemen "(?P<element>[^"]*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-not-see-element">
+            <source><![CDATA[/^(?:|I )should not see an? "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^(?:|saya )tidak melihat elemen "(?P<element>[^"]*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-num-elements">
+            <source><![CDATA[/^(?:|I )should see (?P<num>\d+) "(?P<element>[^"]*)" elements?$/]]></source>
+            <target><![CDATA[/^(?:|saya )harus melihat (?P<num>\d+) elemen "(?P<element>[^"]*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-status-code-should-be">
+            <source><![CDATA[/^the response status code should be (?P<code>\d+)$/]]></source>
+            <target><![CDATA[/^kode status respon harus (?P<code>\d+)$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-status-code-should-not-be">
+            <source><![CDATA[/^the response status code should not be (?P<code>\d+)$/]]></source>
+            <target><![CDATA[/^kode status respon bukan (?P<code>\d+)$/]]></target>
+        </trans-unit>
+        <trans-unit id="print-current-URL">
+            <source><![CDATA[/^print current URL$/]]></source>
+            <target><![CDATA[/^cetak URL sekarang$/]]></target>
+        </trans-unit>
+        <trans-unit id="print-last-response">
+            <source><![CDATA[/^print last response$/]]></source>
+            <target><![CDATA[/^cetak respon terakhir$/]]></target>
+        </trans-unit>
+        <trans-unit id="show-last-response">
+            <source><![CDATA[/^show last response$/]]></source>
+            <target><![CDATA[/^tampilkan respon terakhir$/]]></target>
+        </trans-unit>
+    </body>
+  </file>
+</xliff>
diff --git a/vendor/behat/mink-extension/i18n/it.xliff b/vendor/behat/mink-extension/i18n/it.xliff
new file mode 100644 (file)
index 0000000..34ca281
--- /dev/null
@@ -0,0 +1,151 @@
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+  <file original="global" source-language="en" target-language="it" datatype="plaintext">
+    <header />
+    <body>
+        <trans-unit id="i-am-on-page">
+            <source><![CDATA[/^(?:|I )am on "(?P<page>[^"]+)"$/]]></source>
+            <target><![CDATA[/^(?:|io )sono sulla pagina "(?P<page>[^"]+)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-go-to-page">
+            <source><![CDATA[/^(?:|I )go to "(?P<page>[^"]+)"$/]]></source>
+            <target><![CDATA[/^(?:|io )vado alla pagina "(?P<page>[^"]+)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="reload-the-page">
+            <source><![CDATA[/^(?:|I )reload the page$/]]></source>
+            <target><![CDATA[/^(?:|io )ricarico la pagina$/]]></target>
+        </trans-unit>
+        <trans-unit id="move-backward-one-page">
+            <source><![CDATA[/^(?:|I )move backward one page$/]]></source>
+            <target><![CDATA[/^(?:|io )torno alla pagina precedente$/]]></target>
+        </trans-unit>
+        <trans-unit id="move-forward-one-page">
+            <source><![CDATA[/^(?:|I )move forward one page$/]]></source>
+            <target><![CDATA[/^(?:|io )avanzo di una pagina$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-press-button">
+            <source><![CDATA[/^(?:|I )press "(?P<button>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|io )premo "(?P<button>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-follow-link">
+            <source><![CDATA[/^(?:|I )follow "(?P<link>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|io )clicco sul link "(?P<link>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-fill-in-field-with-value">
+            <source><![CDATA[/^(?:|I )fill in "(?P<field>(?:[^"]|\\")*)" with "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|io )compilo il campo "(?P<field>(?:[^"]|\\")*)" con "(?P<value>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-fill-in-value-for-field">
+            <source><![CDATA[/^(?:|I )fill in "(?P<value>(?:[^"]|\\")*)" for "(?P<field>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|io )inserisco il valore "(?P<value>(?:[^"]|\\")*)" per il campo "(?P<field>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-fill-in-the-following">
+            <source><![CDATA[/^(?:|I )fill in the following:$/]]></source>
+            <target><![CDATA[/^(?:|io )compilo con:$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-select-option-from-select">
+            <source><![CDATA[/^(?:|I )select "(?P<option>(?:[^"]|\\")*)" from "(?P<select>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|io )seleziono "(?P<option>(?:[^"]|\\")*)" da "(?P<select>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-additionally-select-option-from-select">
+            <source><![CDATA[/^(?:|I )additionally select "(?P<option>(?:[^"]|\\")*)" from "(?P<select>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|io )seleziono anche "(?P<option>(?:[^"]|\\")*)" da "(?P<select>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-check-option">
+            <source><![CDATA[/^(?:|I )check "(?P<option>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|io )metto la spunta a "(?P<option>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-uncheck-option">
+            <source><![CDATA[/^(?:|I )uncheck "(?P<option>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|io )rimuovo la spunta da "(?P<option>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-attach-the-file-to-field">
+            <source><![CDATA[/^(?:|I )attach the file "(?P<path>[^"]*)" to "(?P<field>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|io )aggiungo il file "(?P<path>[^"]*)" a "(?P<field>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-text">
+            <source><![CDATA[/^(?:|I )should see "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|io )dovrei vedere "(?P<text>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-text-matching">
+            <source><![CDATA[/^(?:|I )should see text matching (?P<pattern>"(?:[^"]|\\")*")$/]]></source>
+            <target><![CDATA[/^(?:|io )dovrei vedere un testo nel formato (?P<pattern>"(?:[^"]|\\")*")$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-not-see-text-matching">
+            <source><![CDATA[/^(?:|I )should not see text matching (?P<pattern>"(?:[^"]|\\")*")$/]]></source>
+            <target><![CDATA[/^(?:|io )non dovrei vedere un testo nel formato (?P<pattern>"(?:[^"]|\\")*")$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-should-contain">
+            <source><![CDATA[/^the response should contain "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^la risposta dovrebbe contenere "(?P<text>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-not-see-text">
+            <source><![CDATA[/^(?:|I )should not see "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|io )non dovrei vedere "(?P<text>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-should-not-contain">
+            <source><![CDATA[/^the response should not contain "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^la risposta non dovrebbe contenere "(?P<text>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-field-should-contain-value">
+            <source><![CDATA[/^the "(?P<field>(?:[^"]|\\")*)" field should contain "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^il campo "(?P<field>(?:[^"]|\\")*)" dovrebbe contenere "(?P<value>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-field-should-not-contain-value">
+            <source><![CDATA[/^the "(?P<field>(?:[^"]|\\")*)" field should not contain "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^il campo "(?P<field>(?:[^"]|\\")*)" non dovrebbe contenere "(?P<value>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-checkbox-should-be-checked">
+            <source><![CDATA[/^the "(?P<checkbox>(?:[^"]|\\")*)" checkbox should be checked$/]]></source>
+            <target><![CDATA[/^l'opzione "(?P<checkbox>[^"]*)" dovrebbe essere spuntata$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-checkbox-should-not-be-checked">
+            <source><![CDATA[/^the "(?P<checkbox>(?:[^"]|\\")*)" checkbox should not be checked$/]]></source>
+            <target><![CDATA[/^l'opzione "(?P<checkbox>(?:[^"]|\\")*)" non dovrebbe essere spuntata$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-be-on-page">
+            <source><![CDATA[/^(?:|I )should be on "(?P<page>[^"]+)"$/]]></source>
+            <target><![CDATA[/^(?:|io )dovrei essere sulla pagina "(?P<page>[^"]+)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-url-should-match">
+            <source><![CDATA[/^the (?i)url(?-i) should match (?P<pattern>"(?:[^"]|\\")*")$/]]></source>
+            <target><![CDATA[/^l'(?i)url(?-i) dovrebbe essere (?P<pattern>"(?:[^"]|\\")*")$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-element-should-contain">
+            <source><![CDATA[/^the "(?P<element>[^"]*)" element should contain "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^l'elemento "(?P<element>[^"]*)" dovrebbe contenere "(?P<value>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-text-in-element">
+            <source><![CDATA[/^(?:|I )should see "(?P<text>(?:[^"]|\\")*)" in the "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^(?:|io )dovrei vedere "(?P<text>(?:[^"]|\\")*)" nell'elemento "(?P<element>[^"]*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-element">
+            <source><![CDATA[/^(?:|I )should see an? "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^(?:|io )dovrei vedere l'elemento? "(?P<element>[^"]*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-not-see-element">
+            <source><![CDATA[/^(?:|I )should not see an? "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^(?:|io )non dovrei vedere l'elemento? "(?P<element>[^"]*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-num-elements">
+            <source><![CDATA[/^(?:|I )should see (?P<num>\d+) "(?P<element>[^"]*)" elements?$/]]></source>
+            <target><![CDATA[/^(?:|io )dovrei vedere (?P<num>\d+) elementi? "(?P<element>[^"]*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-status-code-should-be">
+            <source><![CDATA[/^the response status code should be (?P<code>\d+)$/]]></source>
+            <target><![CDATA[/^il codice di risposta dovrebbe essere (?P<code>\d+)$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-status-code-should-not-be">
+            <source><![CDATA[/^the response status code should not be (?P<code>\d+)$/]]></source>
+            <target><![CDATA[/^il codice di risposta non dovrebbe essere (?P<code>\d+)$/]]></target>
+        </trans-unit>
+        <trans-unit id="print-last-response">
+            <source><![CDATA[/^print last response$/]]></source>
+            <target><![CDATA[/^stampa l'ultima risposta$/]]></target>
+        </trans-unit>
+        <trans-unit id="show-last-response">
+            <source><![CDATA[/^show last response$/]]></source>
+            <target><![CDATA[/^mostra l'ultima risposta$/]]></target>
+        </trans-unit>
+    </body>
+  </file>
+</xliff>
diff --git a/vendor/behat/mink-extension/i18n/ja.xliff b/vendor/behat/mink-extension/i18n/ja.xliff
new file mode 100644 (file)
index 0000000..8d4e91f
--- /dev/null
@@ -0,0 +1,179 @@
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+  <file original="global" source-language="en" target-language="ja" datatype="plaintext">
+    <header />
+    <body>
+        <trans-unit id="i-am-homepage">
+            <source><![CDATA[/^(?:|I )am on (?:|the )homepage$/]]></source>
+            <target><![CDATA[/^(?:|ユーザーは )ホームページを表示している$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-go-to-homepage">
+            <source><![CDATA[/^(?:|I )go to (?:|the )homepage$/]]></source>
+            <target><![CDATA[/^(?:|ユーザーは )ホームページへ移動する$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-am-on-page">
+            <source><![CDATA[/^(?:|I )am on "(?P<page>[^"]+)"$/]]></source>
+            <target><![CDATA[/^(?:|ユーザーは )"(?P<page>[^\s]+)" を表示している$/u]]></target>
+        </trans-unit>
+        <trans-unit id="i-go-to-page">
+            <source><![CDATA[/^(?:|I )go to "(?P<page>[^"]+)"$/]]></source>
+            <target><![CDATA[/^(?:|ユーザーが )"(?P<page>[^\s]+)" へ移動する$/u]]></target>
+        </trans-unit>
+        <trans-unit id="reload-the-page">
+            <source><![CDATA[/^(?:|I )reload the page$/]]></source>
+            <target><![CDATA[/^(?:|ユーザーが )ページをリロードする$/u]]></target>
+        </trans-unit>
+        <trans-unit id="move-backward-one-page">
+            <source><![CDATA[/^(?:|I )move backward one page$/]]></source>
+            <target><![CDATA[/^(?:|ユーザーが )履歴の前のページに戻る$/u]]></target>
+        </trans-unit>
+        <trans-unit id="move-forward-one-page">
+            <source><![CDATA[/^(?:|I )move forward one page$/]]></source>
+            <target><![CDATA[/^(?:|ユーザーが )履歴の次のページヘ進む$/u]]></target>
+        </trans-unit>
+        <trans-unit id="i-press-button">
+            <source><![CDATA[/^(?:|I )press "(?P<button>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|ユーザーが )"(?P<button>(?:[^"]|\\")*)" ボタンをクリックする$/u]]></target>
+        </trans-unit>
+        <trans-unit id="i-follow-link">
+            <source><![CDATA[/^(?:|I )follow "(?P<link>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|ユーザーが )"(?P<link>(?:[^"]|\\")*)" のリンク先へ移動する$/u]]></target>
+        </trans-unit>
+        <trans-unit id="i-fill-in-field-with-value">
+            <source><![CDATA[/^(?:|I )fill in "(?P<field>(?:[^"]|\\")*)" with "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|ユーザーが )"(?P<field>(?:[^"]|\\")*)" フィールドに "(?P<value>(?:[^"]|\\")*)" と入力する$/u]]></target>
+        </trans-unit>
+        <trans-unit id="i-fill-in-field-with">
+            <source><![CDATA[/^(?:|I )fill in "(?P<field>(?:[^"]|\\")*)" with:$/]]></source>
+            <target><![CDATA[/^(?:|ユーザーが )"(?P<field>(?:[^"]|\\")*)" フィールドに以下の値を入力する:$/u]]></target>
+        </trans-unit>
+        <trans-unit id="i-fill-in-value-for-field">
+            <source><![CDATA[/^(?:|I )fill in "(?P<value>(?:[^"]|\\")*)" for "(?P<field>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|ユーザーが )"(?P<value>(?:[^"]|\\")*)" という値を "(?P<field>(?:[^"]|\\")*)" に入力する$/u]]></target>
+        </trans-unit>
+        <trans-unit id="i-fill-in-the-following">
+            <source><![CDATA[/^(?:|I )fill in the following:$/]]></source>
+            <target><![CDATA[/^(?:|ユーザーが)次のように入力する:$/u]]></target>
+        </trans-unit>
+        <trans-unit id="i-select-option-from-select">
+            <source><![CDATA[/^(?:|I )select "(?P<option>(?:[^"]|\\")*)" from "(?P<select>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|ユーザーが )"(?P<option>(?:[^"]|\\")*)" という値を "(?P<select>(?:[^"]|\\")*)" から選択する$/u]]></target>
+        </trans-unit>
+        <trans-unit id="i-additionally-select-option-from-select">
+            <source><![CDATA[/^(?:|I )additionally select "(?P<option>(?:[^"]|\\")*)" from "(?P<select>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|ユーザーが )"(?P<option>(?:[^"]|\\")*)" という値を "(?P<select>(?:[^"]|\\")*)" から追加で選択する$/u]]></target>
+        </trans-unit>
+        <trans-unit id="i-check-option">
+            <source><![CDATA[/^(?:|I )check "(?P<option>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|ユーザーが )"(?P<option>(?:[^"]|\\")*)" にチェックをつける$/u]]></target>
+        </trans-unit>
+        <trans-unit id="i-uncheck-option">
+            <source><![CDATA[/^(?:|I )uncheck "(?P<option>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|ユーザーが )"(?P<option>(?:[^"]|\\")*)" のチェックをはずす$/u]]></target>
+        </trans-unit>
+        <trans-unit id="i-attach-the-file-to-field">
+            <source><![CDATA[/^(?:|I )attach the file "(?P<path>[^"]*)" to "(?P<field>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|ユーザーが)パス "(?P<path>[^"]*)" にあるファイルを "(?P<field>(?:[^"]|\\")*)" に添付する$/u]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-text">
+            <source><![CDATA[/^(?:|I )should see "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|画面に )"(?P<text>(?:[^"]|\\")*)" と表示されていること$/u]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-should-contain">
+            <source><![CDATA[/^the response should contain "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^レスポンスに "(?P<text>(?:[^"]|\\")*)" が含まれていること$/u]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-not-see-text">
+            <source><![CDATA[/^(?:|I )should not see "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|画面に )"(?P<text>(?:[^"]|\\")*)" と表示されていないこと$/u]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-should-not-contain">
+            <source><![CDATA[/^the response should not contain "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^レスポンスに "(?P<text>(?:[^"]|\\")*)" が含まれていないこと$/u]]></target>
+        </trans-unit>
+        <trans-unit id="the-field-should-contain-value">
+            <source><![CDATA[/^the "(?P<field>(?:[^"]|\\")*)" field should contain "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^"(?P<field>(?:[^"]|\\")*)" フィールドに "(?P<value>(?:[^"]|\\")*)" が含まれていること$/u]]></target>
+        </trans-unit>
+        <trans-unit id="the-field-should-not-contain-value">
+            <source><![CDATA[/^the "(?P<field>(?:[^"]|\\")*)" field should not contain "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^"(?P<field>(?:[^"]|\\")*)" フィールドに "(?P<value>(?:[^"]|\\")*)" が含まれていないこと$/u]]></target>
+        </trans-unit>
+        <trans-unit id="the-checkbox-should-be-checked">
+            <source><![CDATA[/^the "(?P<checkbox>(?:[^"]|\\")*)" checkbox should be checked$/]]></source>
+            <target><![CDATA[/^チェックボックス "(?P<checkbox>(?:[^"]|\\")*)" のチェックがついていること$/u]]></target>
+        </trans-unit>
+        <trans-unit id="the-checkbox-should-not-be-checked">
+            <source><![CDATA[/^the "(?P<checkbox>(?:[^"]|\\")*)" checkbox should not be checked$/]]></source>
+            <target><![CDATA[/^チェックボックス "(?P<checkbox>(?:[^"]|\\")*)" のチェックがはずれていること$/u]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-be-on-page">
+            <source><![CDATA[/^(?:|I )should be on "(?P<page>[^"]+)"$/]]></source>
+            <target><![CDATA[/^(?:|ユーザーが )(?P<page>[^\s]+) を表示していること$/u]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-be-on-homepage">
+            <source><![CDATA[/^(?:|I )should be on (?:|the )homepage$/]]></source>
+            <target><![CDATA[/^(?:|ユーザーが )ホームページを表示していること$/u]]></target>
+        </trans-unit>
+        <trans-unit id="the-url-should-match">
+            <source><![CDATA[/^the (?i)url(?-i) should match (?P<pattern>"(?:[^"]|\\")*")$/]]></source>
+            <target><![CDATA[/^(?i)url(?-i)が (?P<pattern>"(?:[^"]|\\")*") にマッチすること$/u]]></target>
+        </trans-unit>
+        <trans-unit id="the-element-should-contain">
+            <source><![CDATA[/^the "(?P<element>[^"]*)" element should contain "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^"(?P<element>[^"]*)" エレメントに "(?P<value>(?:[^"]|\\")*)" という値が含まれていること$/u]]></target>
+        </trans-unit>
+        <trans-unit id="the-element-should-not-contain">
+            <source><![CDATA[/^the "(?P<element>[^"]*)" element should not contain "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^"(?P<element>[^"]*)" エレメントに "(?P<value>(?:[^"]|\\")*)" という値が含まれていないこと$/u]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-text-in-element">
+            <source><![CDATA[/^(?:|I )should see "(?P<text>(?:[^"]|\\")*)" in the "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^"(?P<element>[^"]*)" エレメントに "(?P<text>(?:[^"]|\\")*)" と表示されていること$/u]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-not-see-text-in-element">
+            <source><![CDATA[/^(?:|I )should not see "(?P<text>(?:[^"]|\\")*)" in the "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^"(?P<element>[^"]*)" エレメントに "(?P<text>(?:[^"]|\\")*)" と表示されていないこと$/u]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-element">
+            <source><![CDATA[/^(?:|I )should see an? "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^(?:|画面に )"(?P<element>[^"]*)" エレメントが表示されていること$/u]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-not-see-element">
+            <source><![CDATA[/^(?:|I )should not see an? "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^(?:|画面に )"(?P<element>[^"]*)" エレメントが表示されていないこと$/u]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-num-elements">
+            <source><![CDATA[/^(?:|I )should see (?P<num>\d+) "(?P<element>[^"]*)" elements?$/]]></source>
+            <target><![CDATA[/^(?:|画面に )(?P<num>\d+) 個の "(?P<element>[^"]*)" エレメントが表示されていること$/u]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-status-code-should-be">
+            <source><![CDATA[/^the response status code should be (?P<code>\d+)$/]]></source>
+            <target><![CDATA[/^レスポンスコードが (?P<code>\d+) であること$/u]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-status-code-should-not-be">
+            <source><![CDATA[/^the response status code should not be (?P<code>\d+)$/]]></source>
+            <target><![CDATA[/^レスポンスコードが (?P<code>\d+) ではないこと$/u]]></target>
+        </trans-unit>
+        <trans-unit id="print-last-response">
+            <source><![CDATA[/^print last response$/]]></source>
+            <target><![CDATA[/^最後のレスポンスを表示$/u]]></target>
+        </trans-unit>
+        <trans-unit id="show-last-response">
+            <source><![CDATA[/^show last response$/]]></source>
+            <target><![CDATA[/^最後のレスポンスをブラウザで表示$/u]]></target>
+        </trans-unit>
+        <trans-unit id="print-current-URL">
+            <source><![CDATA[/^print current URL$/]]></source>
+            <target><![CDATA[/^現在のURLを表示$/]]></target>
+        </trans-unit>
+        <trans-unit id="-should-see-text-matching">
+            <source><![CDATA[/^(?:|I )should see text matching (?P<pattern>"(?:[^"]|\\")*")$/]]></source>
+            <target><![CDATA[/^(?:|画面に )"(?P<pattern>"(?:[^"]|\\")*")" にマッチするテキストが表示されていること$/u]]></target>
+        </trans-unit>
+        <trans-unit id="-should-not-see-text-matching">
+            <source><![CDATA[/^(?:|I )should not see text matching (?P<pattern>"(?:[^"]|\\")*")$/]]></source>
+            <target><![CDATA[/^(?:|画面に )"(?P<pattern>"(?:[^"]|\\")*")" にマッチするテキストが表示されていないこと$/u]]></target>
+        </trans-unit>
+    </body>
+  </file>
+</xliff>
diff --git a/vendor/behat/mink-extension/i18n/nl.xliff b/vendor/behat/mink-extension/i18n/nl.xliff
new file mode 100644 (file)
index 0000000..ac20a3a
--- /dev/null
@@ -0,0 +1,191 @@
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+  <file original="global" source-language="en" target-language="nl" datatype="plaintext">
+    <header />
+    <body>
+        <trans-unit id="i-am-homepage">
+            <source><![CDATA[/^(?:|I )am on (?:|the )homepage$/]]></source>
+            <target><![CDATA[/^dat (?:|ik )op de homepage ben$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-go-to-homepage">
+            <source><![CDATA[/^(?:|I )go to (?:|the )homepage$/]]></source>
+            <target><![CDATA[/^(?:|ik )naar de homepage ga$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-am-on-page">
+            <source><![CDATA[/^(?:|I )am on "(?P<page>[^"]+)"$/]]></source>
+            <target><![CDATA[/^dat (?:|ik )op "(?P<page>[^"]+)" ben$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-go-to-page">
+            <source><![CDATA[/^(?:|I )go to "(?P<page>[^"]+)"$/]]></source>
+            <target><![CDATA[/^(?:|ik )naar "(?P<page>[^"]+)" ga$/]]></target>
+        </trans-unit>
+        <trans-unit id="reload-the-page">
+            <source><![CDATA[/^(?:|I )reload the page$/]]></source>
+            <target><![CDATA[/^(?:|ik )de pagina herlaad$/]]></target>
+        </trans-unit>
+        <trans-unit id="move-backward-one-page">
+            <source><![CDATA[/^(?:|I )move backward one page$/]]></source>
+            <target><![CDATA[/^(?:|ik )een pagina terugga$/]]></target>
+        </trans-unit>
+        <trans-unit id="move-forward-one-page">
+            <source><![CDATA[/^(?:|I )move forward one page$/]]></source>
+            <target><![CDATA[/^(?:|ik )een pagina vooruit ga$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-press-button">
+            <source><![CDATA[/^(?:|I )press "(?P<button>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|ik )druk op "(?P<button>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-follow-link">
+            <source><![CDATA[/^(?:|I )follow "(?P<link>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|ik )"(?P<link>(?:[^"]|\\")*)" volg$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-fill-in-field-with-value">
+            <source><![CDATA[/^(?:|I )fill in "(?P<field>(?:[^"]|\\")*)" with "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|ik )het veld "(?P<field>(?:[^"]|\\")*)" invul met "(?P<value>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-fill-in-field-with">
+            <source><![CDATA[/^(?:|I )fill in "(?P<field>(?:[^"]|\\")*)" with:$/]]></source>
+            <target><![CDATA[/^(?:|ik )het veld "(?P<field>(?:[^"]|\\")*)" invul met:$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-fill-in-value-for-field">
+            <source><![CDATA[/^(?:|I )fill in "(?P<value>(?:[^"]|\\")*)" for "(?P<field>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|ik )de waarde "(?P<value>(?:[^"]|\\")*)" invul in "(?P<field>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-fill-in-the-following">
+            <source><![CDATA[/^(?:|I )fill in the following:$/]]></source>
+            <target><![CDATA[/^(?:|ik )het volgende invul:$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-select-option-from-select">
+            <source><![CDATA[/^(?:|I )select "(?P<option>(?:[^"]|\\")*)" from "(?P<select>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|ik )de optie "(?P<option>(?:[^"]|\\")*)" selecteer voor "(?P<select>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-additionally-select-option-from-select">
+            <source><![CDATA[/^(?:|I )additionally select "(?P<option>(?:[^"]|\\")*)" from "(?P<select>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|ik )daarnaast de optie "(?P<option>(?:[^"]|\\")*)" selecteer voor "(?P<select>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-check-option">
+            <source><![CDATA[/^(?:|I )check "(?P<option>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|ik )"(?P<option>(?:[^"]|\\")*)" aanvink$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-uncheck-option">
+            <source><![CDATA[/^(?:|I )uncheck "(?P<option>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|ik )"(?P<option>(?:[^"]|\\")*)" uitvink$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-attach-the-file-to-field">
+            <source><![CDATA[/^(?:|I )attach the file "(?P<path>[^"]*)" to "(?P<field>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|ik )het bestand "(?P<path>[^"]*)" toevoeg aan "(?P<field>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-text">
+            <source><![CDATA[/^(?:|I )should see "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^moet (?:|ik )"(?P<text>(?:[^"]|\\")*)" zien$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-text-matching">
+            <source><![CDATA[/^(?:|I )should see text matching (?P<pattern>"(?:[^"]|\\")*")$/]]></source>
+            <target><![CDATA[/^moet (?:|ik )de volgende tekst zien (?P<pattern>"(?:[^"]|\\")*")$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-not-see-text-matching">
+            <source><![CDATA[/^(?:|I )should not see text matching (?P<pattern>"(?:[^"]|\\")*")$/]]></source>
+            <target><![CDATA[/^moet (?:|ik )de volgende tekst niet zien (?P<pattern>"(?:[^"]|\\")*")$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-should-contain">
+            <source><![CDATA[/^the response should contain "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^moet het antwoord "(?P<text>(?:[^"]|\\")*)" bevatten$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-not-see-text">
+            <source><![CDATA[/^(?:|I )should not see "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^moet (?:|ik )niet "(?P<text>(?:[^"]|\\")*)" zien$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-should-not-contain">
+            <source><![CDATA[/^the response should not contain "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^moet het antwoord "(?P<text>(?:[^"]|\\")*)" niet bevatten$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-field-should-contain-value">
+            <source><![CDATA[/^the "(?P<field>(?:[^"]|\\")*)" field should contain "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^moet "(?P<field>(?:[^"]|\\")*)" "(?P<value>(?:[^"]|\\")*)" bevatten$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-field-should-not-contain-value">
+            <source><![CDATA[/^the "(?P<field>(?:[^"]|\\")*)" field should not contain "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^moet "(?P<field>(?:[^"]|\\")*)" "(?P<value>(?:[^"]|\\")*)" niet bevatten$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-checkbox-should-be-checked">
+            <source><![CDATA[/^the "(?P<checkbox>(?:[^"]|\\")*)" checkbox should be checked$/]]></source>
+            <target><![CDATA[/^moet "(?P<checkbox>(?:[^"]|\\")*)" aangevinkt zijn$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-checkbox-should-is-checked">
+            <source><![CDATA[/^the checkbox "(?P<checkbox>(?:[^"]|\\")*)" (?:is|should be) checked$/]]></source>
+            <target><![CDATA[/^"(?P<checkbox>(?:[^"]|\\")*)" (?:is|zou moeten zijn) aangevinkt$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-checkbox-should-be-unchecked">
+            <source><![CDATA[/^the checkbox "(?P<checkbox>(?:[^"]|\\")*)" should (?:be unchecked|not be checked)$/]]></source>
+            <target><![CDATA[/^moet "(?P<checkbox>(?:[^"]|\\")*)" niet aangevinkt zijn$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-checkbox-should-not-be-checked">
+            <source><![CDATA[/^the "(?P<checkbox>(?:[^"]|\\")*)" checkbox should not be checked$/]]></source>
+            <target><![CDATA[/^moet "(?P<checkbox>(?:[^"]|\\")*)" niet aangevinkt zijn$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-checkbox-is-unchecked">
+            <source><![CDATA[/^the checkbox "(?P<checkbox>(?:[^"]|\\")*)" is (?:unchecked|not checked)$/]]></source>
+            <target><![CDATA[/^"(?P<checkbox>(?:[^"]|\\")*)" is niet aangevinkt$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-be-on-page">
+            <source><![CDATA[/^(?:|I )should be on "(?P<page>[^"]+)"$/]]></source>
+            <target><![CDATA[/^moet (?:|ik )op "(?P<page>[^"]+)" zijn$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-be-on-homepage">
+            <source><![CDATA[/^(?:|I )should be on (?:|the )homepage$/]]></source>
+            <target><![CDATA[/^moet (?:|ik )op de homepage zijn$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-url-should-match">
+            <source><![CDATA[/^the (?i)url(?-i) should match (?P<pattern>"(?:[^"]|\\")*")$/]]></source>
+            <target><![CDATA[/^moet de url overeenkomen met (?P<pattern>"(?:[^"]|\\")*")$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-element-should-contain">
+            <source><![CDATA[/^the "(?P<element>[^"]*)" element should contain "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^moet het element "(?P<element>[^"]*)" "(?P<value>(?:[^"]|\\")*)" bevatten$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-element-should-not-contain">
+            <source><![CDATA[/^the "(?P<element>[^"]*)" element should not contain "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^moet het element "(?P<element>[^"]*)" niet "(?P<value>(?:[^"]|\\")*)" bevatten$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-text-in-element">
+            <source><![CDATA[/^(?:|I )should see "(?P<text>(?:[^"]|\\")*)" in the "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^moet (?:|ik )"(?P<text>(?:[^"]|\\")*)" zien in "(?P<element>[^"]*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-not-see-text-in-element">
+            <source><![CDATA[/^(?:|I )should not see "(?P<text>(?:[^"]|\\")*)" in the "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^moet (?:|ik )de tekst "(?P<text>(?:[^"]|\\")*)" niet zien in "(?P<element>[^"]*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-element">
+            <source><![CDATA[/^(?:|I )should see an? "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^moet (?:|ik )een element "(?P<element>[^"]*)" zien$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-not-see-element">
+            <source><![CDATA[/^(?:|I )should not see an? "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^moet (?:|ik )een element "(?P<element>[^"]*)" niet zien$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-num-elements">
+            <source><![CDATA[/^(?:|I )should see (?P<num>\d+) "(?P<element>[^"]*)" elements?$/]]></source>
+            <target><![CDATA[/^moet (?:|ik )(?P<num>\d+) "(?P<element>[^"]*)" elementen zien$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-status-code-should-be">
+            <source><![CDATA[/^the response status code should be (?P<code>\d+)$/]]></source>
+            <target><![CDATA[/^moet de statuscode van het antwoord (?P<code>\d+) zijn$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-status-code-should-not-be">
+            <source><![CDATA[/^the response status code should not be (?P<code>\d+)$/]]></source>
+            <target><![CDATA[/^moet de statuscode van het antwoord niet (?P<code>\d+) zijn$/]]></target>
+        </trans-unit>
+        <trans-unit id="print-current-URL">
+            <source><![CDATA[/^print current URL$/]]></source>
+            <target><![CDATA[/^print huidige URL$/]]></target>
+        </trans-unit>
+        <trans-unit id="print-last-response">
+            <source><![CDATA[/^print last response$/]]></source>
+            <target><![CDATA[/^print het laatste antwoord$/]]></target>
+        </trans-unit>
+        <trans-unit id="show-last-response">
+            <source><![CDATA[/^show last response$/]]></source>
+            <target><![CDATA[/^toon het laatste antwoord$/]]></target>
+        </trans-unit>
+    </body>
+  </file>
+</xliff>
diff --git a/vendor/behat/mink-extension/i18n/pl.xliff b/vendor/behat/mink-extension/i18n/pl.xliff
new file mode 100644 (file)
index 0000000..8ba30cc
--- /dev/null
@@ -0,0 +1,143 @@
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+  <file original="global" source-language="en" target-language="pl" datatype="plaintext">
+    <header />
+    <body>
+        <trans-unit id="i-am-on-page">
+            <source><![CDATA[/^(?:|I )am on "(?P<page>[^"]+)"$/]]></source>
+            <target><![CDATA[/^(?:|że )jestem na stronie "(?P<page>[^"]+)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-go-to-page">
+            <source><![CDATA[/^(?:|I )go to "(?P<page>[^"]+)"$/]]></source>
+            <target><![CDATA[/^(?:|że )odwiedzę stronę "(?P<page>[^"]+)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="reload-the-page">
+            <source><![CDATA[/^(?:|I )reload the page$/]]></source>
+            <target><![CDATA[/^(?:|że )odświeżę stronę$/]]></target>
+        </trans-unit>
+        <trans-unit id="move-backward-one-page">
+            <source><![CDATA[/^(?:|I )move backward one page$/]]></source>
+            <target><![CDATA[/^(?:|że )cofnę się do poprzedniej strony$/]]></target>
+        </trans-unit>
+        <trans-unit id="move-forward-one-page">
+            <source><![CDATA[/^(?:|I )move forward one page$/]]></source>
+            <target><![CDATA[/^(?:|że )przejdę na kolejną stronę$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-press-button">
+            <source><![CDATA[/^(?:|I )press "(?P<button>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|że )nacisnę przycisk "(?P<button>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-follow-link">
+            <source><![CDATA[/^(?:|I )follow "(?P<link>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|że )kliknę na link "(?P<link>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-fill-in-field-with-value">
+            <source><![CDATA[/^(?:|I )fill in "(?P<field>(?:[^"]|\\")*)" with "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|że )wypełnię pole "(?P<field>(?:[^"]|\\")*)" wartością "(?P<value>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-fill-in-value-for-field">
+            <source><![CDATA[/^(?:|I )fill in "(?P<value>(?:[^"]|\\")*)" for "(?P<field>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|że )wpiszę "(?P<value>(?:[^"]|\\")*)" w polu "(?P<field>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-fill-in-the-following">
+            <source><![CDATA[/^(?:|I )fill in the following:$/]]></source>
+            <target><![CDATA[/^(?:|że )wypełnię następujące pola:$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-select-option-from-select">
+            <source><![CDATA[/^(?:|I )select "(?P<option>(?:[^"]|\\")*)" from "(?P<select>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|że )wybiorę opcję "(?P<option>(?:[^"]|\\")*)" w polu "(?P<select>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-additionally-select-option-from-select">
+            <source><![CDATA[/^(?:|I )additionally select "(?P<option>(?:[^"]|\\")*)" from "(?P<select>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|że )dodatkowo zaznaczę opcję "(?P<option>(?:[^"]|\\")*)" w polu "(?P<select>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-check-option">
+            <source><![CDATA[/^(?:|I )check "(?P<option>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|że )zaznaczę opcję "(?P<option>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-uncheck-option">
+            <source><![CDATA[/^(?:|I )uncheck "(?P<option>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|że )odznaczę opcję "(?P<option>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-attach-the-file-to-field">
+            <source><![CDATA[/^(?:|I )attach the file "(?P<path>[^"]*)" to "(?P<field>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|że )załączę plik "(?P<path>[^"]*)" w polu "(?P<field>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-text">
+            <source><![CDATA[/^(?:|I )should see "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|że )zobaczę tekst "(?P<text>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-should-contain">
+            <source><![CDATA[/^the response should contain "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^odpowiedź powinna zawierać tekst "(?P<text>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-not-see-text">
+            <source><![CDATA[/^(?:|I )should not see "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|że )nie zobaczę tekstu "(?P<text>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-should-not-contain">
+            <source><![CDATA[/^the response should not contain "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^odpowiedź nie powinna zawierać tekstu "(?P<text>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-field-should-contain-value">
+            <source><![CDATA[/^the "(?P<field>(?:[^"]|\\")*)" field should contain "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^pole "(?P<field>(?:[^"]|\\")*)" powinno zawierać wartość "(?P<value>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-field-should-not-contain-value">
+            <source><![CDATA[/^the "(?P<field>(?:[^"]|\\")*)" field should not contain "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^pole "(?P<field>(?:[^"]|\\")*)" nie powinno zawierać wartości "(?P<value>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-checkbox-should-be-checked">
+            <source><![CDATA[/^the "(?P<checkbox>(?:[^"]|\\")*)" checkbox should be checked$/]]></source>
+            <target><![CDATA[/^pole "(?P<checkbox>(?:[^"]|\\")*)" jest zaznaczone$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-checkbox-should-not-be-checked">
+            <source><![CDATA[/^the "(?P<checkbox>(?:[^"]|\\")*)" checkbox should not be checked$/]]></source>
+            <target><![CDATA[/^pole "(?P<checkbox>(?:[^"]|\\")*)" jest odznaczone$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-be-on-page">
+            <source><![CDATA[/^(?:|I )should be on "(?P<page>[^"]+)"$/]]></source>
+            <target><![CDATA[/^(?:|że )powinienem być na stronie "(?P<page>[^"]+)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-url-should-match">
+            <source><![CDATA[/^the (?i)url(?-i) should match (?P<pattern>"(?:[^"]|\\")*")$/]]></source>
+            <target><![CDATA[/^(?:url|adres) powinien odpowiadać (?P<pattern>"(?:[^"]|\\")*")$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-element-should-contain">
+            <source><![CDATA[/^the "(?P<element>[^"]*)" element should contain "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^element "(?P<element>[^"]*)" powinien zawierać "(?P<value>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-text-in-element">
+            <source><![CDATA[/^(?:|I )should see "(?P<text>(?:[^"]|\\")*)" in the "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^(?:|że )powinienem widzieć "(?P<text>(?:[^"]|\\")*)" wewnątrz elementu "(?P<element>[^"]*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-element">
+            <source><![CDATA[/^(?:|I )should see an? "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^(?:|że )powinienem widzieć element "(?P<element>[^"]*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-not-see-element">
+            <source><![CDATA[/^(?:|I )should not see an? "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^(?:|że )nie powinienem widzieć elementu "(?P<element>[^"]*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-num-elements">
+            <source><![CDATA[/^(?:|I )should see (?P<num>\d+) "(?P<element>[^"]*)" elements?$/]]></source>
+            <target><![CDATA[/^(?:|że )powinienem widzieć (?P<num>\d+) element(y|ów)? "(?P<element>[^"]*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-status-code-should-be">
+            <source><![CDATA[/^the response status code should be (?P<code>\d+)$/]]></source>
+            <target><![CDATA[/^kod statusu odpowiedzi powinien być równy (?P<code>\d+)$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-status-code-should-not-be">
+            <source><![CDATA[/^the response status code should not be (?P<code>\d+)$/]]></source>
+            <target><![CDATA[/^kod statusu odpowiedzi nie powinien być równy (?P<code>\d+)$/]]></target>
+        </trans-unit>
+        <trans-unit id="print-last-response">
+            <source><![CDATA[/^print last response$/]]></source>
+            <target><![CDATA[/^wypisz ostatnią odpowiedź$/]]></target>
+        </trans-unit>
+        <trans-unit id="show-last-response">
+            <source><![CDATA[/^show last response$/]]></source>
+            <target><![CDATA[/^pokaż ostatnią odpowiedź$/]]></target>
+        </trans-unit>
+    </body>
+  </file>
+</xliff>
diff --git a/vendor/behat/mink-extension/i18n/pt-br.xliff b/vendor/behat/mink-extension/i18n/pt-br.xliff
new file mode 100644 (file)
index 0000000..6a8e41e
--- /dev/null
@@ -0,0 +1,187 @@
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+  <file original="global" source-language="en" target-language="pt-br" datatype="plaintext">
+    <header />
+    <body>
+        <trans-unit id="i-am-homepage">
+            <source><![CDATA[/^(?:|I )am on (?:|the )homepage$/]]></source>
+            <target><![CDATA[/^(?:|Eu )estou na página inicial$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-go-to-homepage">
+            <source><![CDATA[/^(?:|I )go to (?:|the )homepage$/]]></source>
+            <target><![CDATA[/^(?:|Eu )vou à página inicial$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-am-on-page">
+            <source><![CDATA[/^(?:|I )am on "(?P<page>[^"]+)"$/]]></source>
+            <target><![CDATA[/^(?:|Eu )estou em "(?P<page>[^"]+)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-go-to-page">
+            <source><![CDATA[/^(?:|I )go to "(?P<page>[^"]+)"$/]]></source>
+            <target><![CDATA[/^(?:|Eu )vou à "(?P<page>[^"]+)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="reload-the-page">
+            <source><![CDATA[/^(?:|I )reload the page$/]]></source>
+            <target><![CDATA[/^(?:|Eu )recarrego a página$/]]></target>
+        </trans-unit>
+        <trans-unit id="move-backward-one-page">
+            <source><![CDATA[/^(?:|I )move backward one page$/]]></source>
+            <target><![CDATA[/^(?:|Eu )volto uma página$/]]></target>
+        </trans-unit>
+        <trans-unit id="move-forward-one-page">
+            <source><![CDATA[/^(?:|I )move forward one page$/]]></source>
+            <target><![CDATA[/^(?:|Eu )avanço uma página$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-press-button">
+            <source><![CDATA[/^(?:|I )press "(?P<button>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|Eu )pressiono o botão "(?P<button>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-follow-link">
+            <source><![CDATA[/^(?:|I )follow "(?P<link>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|Eu )sigo o link "(?P<link>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-fill-in-field-with-value">
+            <source><![CDATA[/^(?:|I )fill in "(?P<field>(?:[^"]|\\")*)" with "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|Eu )preencho o campo "(?P<field>(?:[^"]|\\")*)" com "(?P<value>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-fill-in-field-with">
+            <source><![CDATA[/^(?:|I )fill in "(?P<field>(?:[^"]|\\")*)" with:$/]]></source>
+            <target><![CDATA[/^(?:|Eu )preencho o campo "(?P<field>(?:[^"]|\\")*)" com:$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-fill-in-value-for-field">
+            <source><![CDATA[/^(?:|I )fill in "(?P<value>(?:[^"]|\\")*)" for "(?P<field>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|Eu )preencho o valor "(?P<value>(?:[^"]|\\")*)" no campo "(?P<field>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-fill-in-the-following">
+            <source><![CDATA[/^(?:|I )fill in the following:$/]]></source>
+            <target><![CDATA[/^(?:|Eu )preencho os seguintes valores:$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-select-option-from-select">
+            <source><![CDATA[/^(?:|I )select "(?P<option>(?:[^"]|\\")*)" from "(?P<select>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|Eu )seleciono a opção "(?P<option>(?:[^"]|\\")*)" no campo "(?P<select>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-additionally-select-option-from-select">
+            <source><![CDATA[/^(?:|I )additionally select "(?P<option>(?:[^"]|\\")*)" from "(?P<select>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|Eu )seleciono também "(?P<option>(?:[^"]|\\")*)" no campo "(?P<select>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-check-option">
+            <source><![CDATA[/^(?:|I )check "(?P<option>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|Eu )marco a opção "(?P<option>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-uncheck-option">
+            <source><![CDATA[/^(?:|I )uncheck "(?P<option>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|Eu )desmarco a opção "(?P<option>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-attach-the-file-to-field">
+            <source><![CDATA[/^(?:|I )attach the file "(?P<path>[^"]*)" to "(?P<field>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|Eu )anexo o arquivo "(?P<path>[^"]*)" no campo "(?P<field>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-text">
+            <source><![CDATA[/^(?:|I )should see "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|Eu )devo ver o texto "(?P<text>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-text-matching">
+            <source><![CDATA[/^(?:|I )should see text matching (?P<pattern>"(?:[^"]|\\")*")$/]]></source>
+            <target><![CDATA[/^(?:|Eu )devo ver o texto que coincide com (?P<pattern>"(?:[^"]|\\")*")$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-not-see-text-matching">
+            <source><![CDATA[/^(?:|I )should not see text matching (?P<pattern>"(?:[^"]|\\")*")$/]]></source>
+            <target><![CDATA[/^(?:|Eu )não devo ver o texto que coincide com (?P<pattern>"(?:[^"]|\\")*")$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-should-contain">
+            <source><![CDATA[/^the response should contain "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^a resposta deve conter "(?P<text>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-not-see-text">
+            <source><![CDATA[/^(?:|I )should not see "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|Eu )não devo ver o texto "(?P<text>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-should-not-contain">
+            <source><![CDATA[/^the response should not contain "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^a resposta não deve conter "(?P<text>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-field-should-contain-value">
+            <source><![CDATA[/^the "(?P<field>(?:[^"]|\\")*)" field should contain "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^o campo "(?P<field>(?:[^"]|\\")*)" deve conter o valor "(?P<value>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-field-should-not-contain-value">
+            <source><![CDATA[/^the "(?P<field>(?:[^"]|\\")*)" field should not contain "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^o campo "(?P<field>(?:[^"]|\\")*)" não deve conter o valor "(?P<value>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-checkbox-should-be-checked">
+            <source><![CDATA[/^the "(?P<checkbox>(?:[^"]|\\")*)" checkbox should be checked$/]]></source>
+            <target><![CDATA[/^o checkbox "(?P<checkbox>(?:[^"]|\\")*)" deve ser marcado$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-checkbox-should-is-checked">
+            <source><![CDATA[/^the checkbox "(?P<checkbox>(?:[^"]|\\")*)" (?:is|should be) checked$/]]></source>
+            <target><![CDATA[/^o checkbox "(?P<checkbox>(?:[^"]|\\")*)" deve estar marcado$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-checkbox-should-be-unchecked">
+            <source><![CDATA[/^the checkbox "(?P<checkbox>(?:[^"]|\\")*)" should (?:be unchecked|not be checked)$/]]></source>
+            <target><![CDATA[/^o checkbox "(?P<checkbox>(?:[^"]|\\")*)" deve ser desmarcado$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-checkbox-is-unchecked">
+            <source><![CDATA[/^the checkbox "(?P<checkbox>(?:[^"]|\\")*)" is (?:unchecked|not checked)$/]]></source>
+            <target><![CDATA[/^o checkbox "(?P<checkbox>(?:[^"]|\\")*)" deve estar desmarcado$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-be-on-page">
+            <source><![CDATA[/^(?:|I )should be on "(?P<page>[^"]+)"$/]]></source>
+            <target><![CDATA[/^(?:|Eu )devo estar em "(?P<page>[^"]+)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-be-on-homepage">
+            <source><![CDATA[/^(?:|I )should be on (?:|the )homepage$/]]></source>
+            <target><![CDATA[/^(?:|Eu )devo estar na página inicial/]]></target>
+        </trans-unit>
+        <trans-unit id="the-url-should-match">
+            <source><![CDATA[/^the (?i)url(?-i) should match (?P<pattern>"([^"]|\\")*")$/]]></source>
+            <target><![CDATA[/^a url deve coincidir com (?P<pattern>"([^"]|\\")*")$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-element-should-contain">
+            <source><![CDATA[/^the "(?P<element>[^"]*)" element should contain "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^o elemento "(?P<element>[^"]*)" deve conter "(?P<value>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-element-should-not-contain">
+            <source><![CDATA[/^the "(?P<element>[^"]*)" element should not contain "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^o elemento "(?P<element>[^"]*)" não deve conter "(?P<value>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-text-in-element">
+            <source><![CDATA[/^(?:|I )should see "(?P<text>(?:[^"]|\\")*)" in the "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^(?:|Eu )eu devo ver o texto "(?P<text>(?:[^"]|\\")*)" no elemento "(?P<element>[^"]*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-not-see-text-in-element">
+            <source><![CDATA[/^(?:|I )should not see "(?P<text>(?:[^"]|\\")*)" in the "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^(?:|Eu )não devo ver o texto "(?P<text>(?:[^"]|\\")*)" no elemento "(?P<element>[^"]*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-element">
+            <source><![CDATA[/^(?:|I )should see an? "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^(?:|Eu )devo ver o elemento "(?P<element>[^"]*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-not-see-element">
+            <source><![CDATA[/^(?:|I )should not see an? "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^(?:|Eu )não devo ver o elemento "(?P<element>[^"]*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-num-elements">
+            <source><![CDATA[/^(?:|I )should see (?P<num>\d+) "(?P<element>[^"]*)" elements?$/]]></source>
+            <target><![CDATA[/^(?:|Eu )devo ver (?P<num>\d+) elementos? "(?P<element>[^"]*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-status-code-should-be">
+            <source><![CDATA[/^the response status code should be (?P<code>\d+)$/]]></source>
+            <target><![CDATA[/^o código da resposta deve ser (?P<code>\d+)$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-status-code-should-not-be">
+            <source><![CDATA[/^the response status code should not be (?P<code>\d+)$/]]></source>
+            <target><![CDATA[/^o código da resposta não deve ser (?P<code>\d+)$/]]></target>
+        </trans-unit>
+        <trans-unit id="print-current-URL">
+            <source><![CDATA[/^print current URL$/]]></source>
+            <target><![CDATA[/^imprimir url atual$/]]></target>
+        </trans-unit>
+        <trans-unit id="print-last-response">
+            <source><![CDATA[/^print last response$/]]></source>
+            <target><![CDATA[/^imprimir última resposta$/]]></target>
+        </trans-unit>
+        <trans-unit id="show-last-response">
+            <source><![CDATA[/^show last response$/]]></source>
+            <target><![CDATA[/^mostrar última resposta$/]]></target>
+        </trans-unit>
+    </body>
+  </file>
+</xliff>
diff --git a/vendor/behat/mink-extension/i18n/pt.xliff b/vendor/behat/mink-extension/i18n/pt.xliff
new file mode 100644 (file)
index 0000000..ac997ca
--- /dev/null
@@ -0,0 +1,163 @@
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+  <file original="global" source-language="en" target-language="pt" datatype="plaintext">
+    <header />
+    <body>
+        <trans-unit id="i-am-homepage">
+            <source><![CDATA[/^(?:|I )am on (?:|the )homepage$/]]></source>
+            <target><![CDATA[/^(?:|Eu )estou na página de entrada/]]></target>
+        </trans-unit>
+        <trans-unit id="i-go-to-homepage">
+            <source><![CDATA[/^(?:|I )go to (?:|the )homepage$/]]></source>
+            <target><![CDATA[/^(?:|Eu )vou para a página de entrada$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-am-on-page">
+            <source><![CDATA[/^(?:|I )am on "(?P<page>[^"]+)"$/]]></source>
+            <target><![CDATA[/^(?:|Eu )estou em "(?P<page>[^"]+)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-go-to-page">
+            <source><![CDATA[/^(?:|I )go to "(?P<page>[^"]+)"$/]]></source>
+            <target><![CDATA[/^(?:|Eu )vou para "(?P<page>[^"]+)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="reload-the-page">
+            <source><![CDATA[/^(?:|I )reload the page$/]]></source>
+            <target><![CDATA[/^(?:|Eu )recarrego a página$/]]></target>
+        </trans-unit>
+        <trans-unit id="move-backward-one-page">
+            <source><![CDATA[/^(?:|I )move backward one page$/]]></source>
+            <target><![CDATA[/^(?:|Eu )voltei uma página$/]]></target>
+        </trans-unit>
+        <trans-unit id="move-forward-one-page">
+            <source><![CDATA[/^(?:|I )move forward one page$/]]></source>
+            <target><![CDATA[/^(?:|Eu )avancei uma página$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-press-button">
+            <source><![CDATA[/^(?:|I )press "(?P<button>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|Eu )pressiono "(?P<button>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-follow-link">
+            <source><![CDATA[/^(?:|I )follow "(?P<link>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|Eu )sigo o link "(?P<link>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-fill-in-field-with-value">
+            <source><![CDATA[/^(?:|I )fill in "(?P<field>(?:[^"]|\\")*)" with "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|Eu )preencho "(?P<field>(?:[^"]|\\")*)" com "(?P<value>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-fill-in-value-for-field">
+            <source><![CDATA[/^(?:|I )fill in "(?P<value>(?:[^"]|\\")*)" for "(?P<field>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|Eu )preencho "(?P<value>(?:[^"]|\\")*)" para "(?P<field>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-fill-in-the-following">
+            <source><![CDATA[/^(?:|I )fill in the following:$/]]></source>
+            <target><![CDATA[/^(?:|Eu )preencho o seguinte:$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-select-option-from-select">
+            <source><![CDATA[/^(?:|I )select "(?P<option>(?:[^"]|\\")*)" from "(?P<select>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|Eu )seleciono "(?P<option>(?:[^"]|\\")*)" de "(?P<select>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-additionally-select-option-from-select">
+            <source><![CDATA[/^(?:|I )additionally select "(?P<option>(?:[^"]|\\")*)" from "(?P<select>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|Eu )seleciono também "(?P<option>(?:[^"]|\\")*)" de "(?P<select>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-check-option">
+            <source><![CDATA[/^(?:|I )check "(?P<option>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|Eu )marco "(?P<option>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-uncheck-option">
+            <source><![CDATA[/^(?:|I )uncheck "(?P<option>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|Eu )desmarco "(?P<option>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-attach-the-file-to-field">
+            <source><![CDATA[/^(?:|I )attach the file "(?P<path>[^"]*)" to "(?P<field>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|Eu )anexo o arquivo "(?P<path>[^"]*)" ao "(?P<field>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-text">
+            <source><![CDATA[/^(?:|I )should see "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|Eu )devo ver "(?P<text>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-text-matching">
+            <source><![CDATA[/^(?:|I )should see text matching (?P<pattern>"(?:[^"]|\\")*")$/]]></source>
+            <target><![CDATA[/^(?:|Eu )devo ver o texto que coincide com (?P<pattern>"(?:[^"]|\\")*")$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-not-see-text-matching">
+            <source><![CDATA[/^(?:|I )should not see text matching (?P<pattern>"(?:[^"]|\\")*")$/]]></source>
+            <target><![CDATA[/^(?:|Eu )não devo ver o texto que coincide com (?P<pattern>"(?:[^"]|\\")*")$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-should-contain">
+            <source><![CDATA[/^the response should contain "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^a resposta deve conter "(?P<text>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-not-see-text">
+            <source><![CDATA[/^(?:|I )should not see "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|Eu )não devo ver "(?P<text>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-should-not-contain">
+            <source><![CDATA[/^the response should not contain "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^a resposta não deve conter "(?P<text>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-field-should-contain-value">
+            <source><![CDATA[/^the "(?P<field>(?:[^"]|\\")*)" field should contain "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^o campo "(?P<field>(?:[^"]|\\")*)" deve conter "(?P<value>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-field-should-not-contain-value">
+            <source><![CDATA[/^the "(?P<field>(?:[^"]|\\")*)" field should not contain "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^o campo "(?P<field>(?:[^"]|\\")*)" não deve conter "(?P<value>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-checkbox-should-be-checked">
+            <source><![CDATA[/^the "(?P<checkbox>(?:[^"]|\\")*)" checkbox should be checked$/]]></source>
+            <target><![CDATA[/^o checkbox "(?P<checkbox>(?:[^"]|\\")*)" deve (?:ser|estar) marcado$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-checkbox-should-not-be-checked">
+            <source><![CDATA[/^the "(?P<checkbox>(?:[^"]|\\")*)" checkbox should not be checked$/]]></source>
+            <target><![CDATA[/^o checkbox "(?P<checkbox>(?:[^"]|\\")*)" não deve (?:ser|estar) marcado$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-be-on-page">
+            <source><![CDATA[/^(?:|I )should be on "(?P<page>[^"]+)"$/]]></source>
+            <target><![CDATA[/^(?:|Eu )devo estar em "(?P<page>[^"]+)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-url-should-match">
+            <source><![CDATA[/^the (?i)url(?-i) should match (?P<pattern>"(?:[^"]|\\")*")$/]]></source>
+            <target><![CDATA[/^a (?i)url(?-i) deve coincidir com (?P<pattern>"(?:[^"]|\\")*")$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-element-should-contain">
+            <source><![CDATA[/^the "(?P<element>[^"]*)" element should contain "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^o elemento "(?P<element>[^"]*)" deve conter "(?P<value>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-text-in-element">
+            <source><![CDATA[/^(?:|I )should see "(?P<text>(?:[^"]|\\")*)" in the "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^(?:|Eu )devo ver "(?P<text>(?:[^"]|\\")*)" no elemento "(?P<element>[^"]*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-not-see-text-in-element">
+            <source><![CDATA[/^(?:|I )should not see "(?P<text>(?:[^"]|\\")*)" in the "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^(?:|Eu )não deveria de ver "(?P<text>(?:[^"]|\\")*)" no elemento "(?P<element>[^"]*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-element">
+            <source><![CDATA[/^(?:|I )should see an? "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^(?:|Eu )devo ver um elemento "(?P<element>[^"]*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-not-see-element">
+            <source><![CDATA[/^(?:|I )should not see an? "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^(?:|Eu )não devo ver um elemento "(?P<element>[^"]*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-num-elements">
+            <source><![CDATA[/^(?:|I )should see (?P<num>\d+) "(?P<element>[^"]*)" elements?$/]]></source>
+            <target><![CDATA[/^(?:|Eu )devo ver (?P<num>\d+) elementos? "(?P<element>[^"]*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-status-code-should-be">
+            <source><![CDATA[/^the response status code should be (?P<code>\d+)$/]]></source>
+            <target><![CDATA[/^o código de status da resposta deve ser (?P<code>\d+)$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-status-code-should-not-be">
+            <source><![CDATA[/^the response status code should not be (?P<code>\d+)$/]]></source>
+            <target><![CDATA[/^o código de status da resposta não deve ser (?P<code>\d+)$/]]></target>
+        </trans-unit>
+        <trans-unit id="print-last-response">
+            <source><![CDATA[/^print last response$/]]></source>
+            <target><![CDATA[/^imprimir última resposta$/]]></target>
+        </trans-unit>
+        <trans-unit id="show-last-response">
+            <source><![CDATA[/^show last response$/]]></source>
+            <target><![CDATA[/^mostrar última resposta$/]]></target>
+        </trans-unit>
+    </body>
+  </file>
+</xliff>
diff --git a/vendor/behat/mink-extension/i18n/ro.xliff b/vendor/behat/mink-extension/i18n/ro.xliff
new file mode 100644 (file)
index 0000000..52cbc76
--- /dev/null
@@ -0,0 +1,191 @@
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+  <file original="global" source-language="en" target-language="ro" datatype="plaintext">
+    <header />
+    <body>
+        <trans-unit id="i-am-homepage">
+            <source><![CDATA[/^(?:|I )am on (?:|the )homepage$/]]></source>
+            <target><![CDATA[/^(?:|Eu )sunt pe prima pagina$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-go-to-homepage">
+            <source><![CDATA[/^(?:|I )go to (?:|the )homepage$/]]></source>
+            <target><![CDATA[/^(?:|Eu )accesez prima pagina$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-am-on-page">
+            <source><![CDATA[/^(?:|I )am on "(?P<page>[^"]+)"$/]]></source>
+            <target><![CDATA[/^(?:|Eu )sunt pe pagina "(?P<page>[^"]+)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-go-to-page">
+            <source><![CDATA[/^(?:|I )go to "(?P<page>[^"]+)"$/]]></source>
+            <target><![CDATA[/^(?:|Eu )accesez "(?P<page>[^"]+)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="reload-the-page">
+            <source><![CDATA[/^(?:|I )reload the page$/]]></source>
+            <target><![CDATA[/^(?:|Eu )reîncarc pagina$/]]></target>
+        </trans-unit>
+        <trans-unit id="move-backward-one-page">
+            <source><![CDATA[/^(?:|I )move backward one page$/]]></source>
+            <target><![CDATA[/^(?:|Eu )mă întorc la pagina anterioară$/]]></target>
+        </trans-unit>
+        <trans-unit id="move-forward-one-page">
+            <source><![CDATA[/^(?:|I )move forward one page$/]]></source>
+            <target><![CDATA[/^(?:|Eu )merg la pagina următoare$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-press-button">
+            <source><![CDATA[/^(?:|I )press "(?P<button>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|Eu )apăs "(?P<button>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-follow-link">
+            <source><![CDATA[/^(?:|I )follow "(?P<link>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|Eu )urmez "(?P<link>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-fill-in-field-with-value">
+            <source><![CDATA[/^(?:|I )fill in "(?P<field>(?:[^"]|\\")*)" with "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|Eu )completez "(?P<field>(?:[^"]|\\")*)" cu "(?P<value>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-fill-in-field-with">
+            <source><![CDATA[/^(?:|I )fill in "(?P<field>(?:[^"]|\\")*)" with:$/]]></source>
+            <target><![CDATA[/^(?:|Eu )completez "(?P<field>(?:[^"]|\\")*)" cu:$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-fill-in-value-for-field">
+            <source><![CDATA[/^(?:|I )fill in "(?P<value>(?:[^"]|\\")*)" for "(?P<field>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|Eu )completez cu "(?P<value>(?:[^"]|\\")*)" pentru "(?P<field>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-fill-in-the-following">
+            <source><![CDATA[/^(?:|I )fill in the following:$/]]></source>
+            <target><![CDATA[/^(?:|Eu ) completez următoarele:$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-select-option-from-select">
+            <source><![CDATA[/^(?:|I )select "(?P<option>(?:[^"]|\\")*)" from "(?P<select>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|Eu )selectez "(?P<option>(?:[^"]|\\")*)" din "(?P<select>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-additionally-select-option-from-select">
+            <source><![CDATA[/^(?:|I )additionally select "(?P<option>(?:[^"]|\\")*)" from "(?P<select>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|Eu )selectez în plus "(?P<option>(?:[^"]|\\")*)" din "(?P<select>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-check-option">
+            <source><![CDATA[/^(?:|I )check "(?P<option>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|Eu )bifez "(?P<option>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-uncheck-option">
+            <source><![CDATA[/^(?:|I )uncheck "(?P<option>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|Eu )debifez "(?P<option>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-attach-the-file-to-field">
+            <source><![CDATA[/^(?:|I )attach the file "(?P<path>[^"]*)" to "(?P<field>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|Eu )atașez fișierul "(?P<path>[^"]*)" la "(?P<field>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-text">
+            <source><![CDATA[/^(?:|I )should see "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|Eu )ar trebui să văd "(?P<text>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-text-matching">
+            <source><![CDATA[/^(?:|I )should see text matching (?P<pattern>"(?:[^"]|\\")*")$/]]></source>
+            <target><![CDATA[/^(?:|Eu )ar trebui să văd un text care coincide cu (?P<pattern>"(?:[^"]|\\")*")$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-not-see-text-matching">
+            <source><![CDATA[/^(?:|I )should not see text matching (?P<pattern>"(?:[^"]|\\")*")$/]]></source>
+            <target><![CDATA[/^(?:|Eu )ar trebui să văd un text care coincide cu (?P<pattern>"(?:[^"]|\\")*")$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-should-contain">
+            <source><![CDATA[/^the response should contain "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^răspunsul ar trebui să conțină "(?P<text>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-not-see-text">
+            <source><![CDATA[/^(?:|I )should not see "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|Eu )nu ar trebui să văd "(?P<text>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-should-not-contain">
+            <source><![CDATA[/^the response should not contain "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^răspunsul nu ar trebui să conțină "(?P<text>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-field-should-contain-value">
+            <source><![CDATA[/^the "(?P<field>(?:[^"]|\\")*)" field should contain "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^câmpul "(?P<field>(?:[^"]|\\")*)" ar trebui să conțină "(?P<value>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-field-should-not-contain-value">
+            <source><![CDATA[/^the "(?P<field>(?:[^"]|\\")*)" field should not contain "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^câmpul "(?P<field>(?:[^"]|\\")*)" nu ar trebui să conțină "(?P<value>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-checkbox-should-be-checked">
+            <source><![CDATA[/^the "(?P<checkbox>(?:[^"]|\\")*)" checkbox should be checked$/]]></source>
+            <target><![CDATA[/^căsuța "(?P<checkbox>(?:[^"]|\\")*)" ar trebui bifată$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-checkbox-should-is-checked">
+            <source><![CDATA[/^the checkbox "(?P<checkbox>(?:[^"]|\\")*)" (?:is|should be) checked$/]]></source>
+            <target><![CDATA[/^căsuța "(?P<checkbox>(?:[^"]|\\")*)" este bifată$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-checkbox-should-be-unchecked">
+            <source><![CDATA[/^the checkbox "(?P<checkbox>(?:[^"]|\\")*)" should (?:be unchecked|not be checked)$/]]></source>
+            <target><![CDATA[/^căsuța "(?P<checkbox>(?:[^"]|\\")*)" ar trebui să fie nebifată$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-checkbox-should-not-be-checked">
+            <source><![CDATA[/^the "(?P<checkbox>(?:[^"]|\\")*)" checkbox should not be checked$/]]></source>
+            <target><![CDATA[/^căsuța "(?P<checkbox>(?:[^"]|\\")*)" ar trebui să nu fie bifată$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-checkbox-is-unchecked">
+            <source><![CDATA[/^the checkbox "(?P<checkbox>(?:[^"]|\\")*)" is (?:unchecked|not checked)$/]]></source>
+            <target><![CDATA[/^căsuța "(?P<checkbox>(?:[^"]|\\")*)" este nebifată$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-be-on-page">
+            <source><![CDATA[/^(?:|I )should be on "(?P<page>[^"]+)"$/]]></source>
+            <target><![CDATA[/^(?:|Eu )ar trebui să fiu pe pagina "(?P<page>[^"]+)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-be-on-homepage">
+            <source><![CDATA[/^(?:|I )should be on (?:|the )homepage$/]]></source>
+            <target><![CDATA[/^(?:|Eu )ar trebui să fiu pe prima pagină/]]></target>
+        </trans-unit>
+        <trans-unit id="the-url-should-match">
+            <source><![CDATA[/^the (?i)url(?-i) should match (?P<pattern>"(?:[^"]|\\")*")$/]]></source>
+            <target><![CDATA[/^(?:url|адрес) ar trebui să aibă tiparul (?P<pattern>"(?:[^"]|\\")*")$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-element-should-contain">
+            <source><![CDATA[/^the "(?P<element>[^"]*)" element should contain "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^elementul "(?P<element>[^"]*)" ar trebui să conțină "(?P<value>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-element-should-not-contain">
+            <source><![CDATA[/^the "(?P<element>[^"]*)" element should not contain "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^elementul "(?P<element>[^"]*)" ar trebui să nu conțină "(?P<value>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-text-in-element">
+            <source><![CDATA[/^(?:|I )should see "(?P<text>(?:[^"]|\\")*)" in the "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^(?:|Eu )ar trebui să văd textul "(?P<text>(?:[^"]|\\")*)" în elementul "(?P<element>[^"]*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-not-see-text-in-element">
+            <source><![CDATA[/^(?:|I )should not see "(?P<text>(?:[^"]|\\")*)" in the "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^(?:|Eu )ar trebui să nu văd textul "(?P<text>(?:[^"]|\\")*)" în elementul "(?P<element>[^"]*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-element">
+            <source><![CDATA[/^(?:|I )should see an? "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^(?:|Eu )ar trebui să văd un "(?P<element>[^"]*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-not-see-element">
+            <source><![CDATA[/^(?:|I )should not see an? "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^(?:|Eu )nu ar trebui să văd un? "(?P<element>[^"]*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-num-elements">
+            <source><![CDATA[/^(?:|I )should see (?P<num>\d+) "(?P<element>[^"]*)" elements?$/]]></source>
+            <target><![CDATA[/^(?:|Eu )ar trebui să văd (?P<num>\d+) element(e|а)? "(?P<element>[^"]*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-status-code-should-be">
+            <source><![CDATA[/^the response status code should be (?P<code>\d+)$/]]></source>
+            <target><![CDATA[/^codul de răspuns ar trebui să fie (?P<code>\d+)$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-status-code-should-not-be">
+            <source><![CDATA[/^the response status code should not be (?P<code>\d+)$/]]></source>
+            <target><![CDATA[/^codul de răspuns nu ar trebui să fie (?P<code>\d+)$/]]></target>
+        </trans-unit>
+        <trans-unit id="print-current-URL">
+            <source><![CDATA[/^print current URL$/]]></source>
+            <target><![CDATA[/^afișează URL-ul curent$/]]></target>
+        </trans-unit>
+        <trans-unit id="print-last-response">
+            <source><![CDATA[/^print last response$/]]></source>
+            <target><![CDATA[/^afișează ultimul răspuns$/]]></target>
+        </trans-unit>
+        <trans-unit id="show-last-response">
+            <source><![CDATA[/^show last response$/]]></source>
+            <target><![CDATA[/^arată ultimul răspuns$/]]></target>
+        </trans-unit>
+    </body>
+  </file>
+</xliff>
diff --git a/vendor/behat/mink-extension/i18n/ru.xliff b/vendor/behat/mink-extension/i18n/ru.xliff
new file mode 100644 (file)
index 0000000..00309d3
--- /dev/null
@@ -0,0 +1,191 @@
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+  <file original="global" source-language="en" target-language="ru" datatype="plaintext">
+    <header />
+    <body>
+        <trans-unit id="i-am-homepage">
+            <source><![CDATA[/^(?:|I )am on (?:|the )homepage$/]]></source>
+            <target><![CDATA[/^(?:|я )на главной странице$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-go-to-homepage">
+            <source><![CDATA[/^(?:|I )go to (?:|the )homepage$/]]></source>
+            <target><![CDATA[/^(?:|я )перехожу на главную страницу$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-am-on-page">
+            <source><![CDATA[/^(?:|I )am on "(?P<page>[^"]+)"$/]]></source>
+            <target><![CDATA[/^(?:|я )на странице "(?P<page>[^"]+)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-go-to-page">
+            <source><![CDATA[/^(?:|I )go to "(?P<page>[^"]+)"$/]]></source>
+            <target><![CDATA[/^(?:|я )перехожу на "(?P<page>[^"]+)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="reload-the-page">
+            <source><![CDATA[/^(?:|I )reload the page$/]]></source>
+            <target><![CDATA[/^(?:|я )обновляю страницу$/]]></target>
+        </trans-unit>
+        <trans-unit id="move-backward-one-page">
+            <source><![CDATA[/^(?:|I )move backward one page$/]]></source>
+            <target><![CDATA[/^(?:|я )перехожу на одну страницу назад$/]]></target>
+        </trans-unit>
+        <trans-unit id="move-forward-one-page">
+            <source><![CDATA[/^(?:|I )move forward one page$/]]></source>
+            <target><![CDATA[/^(?:|я )перехожу на одну страницу вперед$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-press-button">
+            <source><![CDATA[/^(?:|I )press "(?P<button>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|я )нажимаю "(?P<button>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-follow-link">
+            <source><![CDATA[/^(?:|I )follow "(?P<link>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|я )кликаю по ссылке "(?P<link>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-fill-in-field-with-value">
+            <source><![CDATA[/^(?:|I )fill in "(?P<field>(?:[^"]|\\")*)" with "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|я )заполняю поле "(?P<field>(?:[^"]|\\")*)" значением "(?P<value>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-fill-in-field-with">
+            <source><![CDATA[/^(?:|I )fill in "(?P<field>(?:[^"]|\\")*)" with:$/]]></source>
+            <target><![CDATA[/^(?:|я )заполняю поле "(?P<field>(?:[^"]|\\")*)" значениями:$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-fill-in-value-for-field">
+            <source><![CDATA[/^(?:|I )fill in "(?P<value>(?:[^"]|\\")*)" for "(?P<field>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|я )ввожу "(?P<value>(?:[^"]|\\")*)" в поле "(?P<field>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-fill-in-the-following">
+            <source><![CDATA[/^(?:|I )fill in the following:$/]]></source>
+            <target><![CDATA[/^(?:|я )ввожу следующие значения:$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-select-option-from-select">
+            <source><![CDATA[/^(?:|I )select "(?P<option>(?:[^"]|\\")*)" from "(?P<select>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|я )выбираю "(?P<option>(?:[^"]|\\")*)" в поле "(?P<select>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-additionally-select-option-from-select">
+            <source><![CDATA[/^(?:|I )additionally select "(?P<option>(?:[^"]|\\")*)" from "(?P<select>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|я )дополнительно выбираю "(?P<option>(?:[^"]|\\")*)" в поле "(?P<select>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-check-option">
+            <source><![CDATA[/^(?:|I )check "(?P<option>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|я )ставлю галочку "(?P<option>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-uncheck-option">
+            <source><![CDATA[/^(?:|I )uncheck "(?P<option>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|я )снимаю галочку "(?P<option>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-attach-the-file-to-field">
+            <source><![CDATA[/^(?:|I )attach the file "(?P<path>[^"]*)" to "(?P<field>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|я )выбираю файл "(?P<path>[^"]*)" в поле "(?P<field>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-text">
+            <source><![CDATA[/^(?:|I )should see "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|я )должен видеть "(?P<text>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-text-matching">
+            <source><![CDATA[/^(?:|I )should see text matching (?P<pattern>"(?:[^"]|\\")*")$/]]></source>
+            <target><![CDATA[/^(?:|я )должен видеть текст соответствующий (?P<pattern>"(?:[^"]|\\")*")$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-not-see-text-matching">
+            <source><![CDATA[/^(?:|I )should not see text matching (?P<pattern>"(?:[^"]|\\")*")$/]]></source>
+            <target><![CDATA[/^(?:|я )не должен видеть текст соответствующий (?P<pattern>"(?:[^"]|\\")*")$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-should-contain">
+            <source><![CDATA[/^the response should contain "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^тело ответа должно содержать "(?P<text>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-not-see-text">
+            <source><![CDATA[/^(?:|I )should not see "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|я )не должен видеть "(?P<text>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-should-not-contain">
+            <source><![CDATA[/^the response should not contain "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^тело ответа не должно содержать "(?P<text>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-field-should-contain-value">
+            <source><![CDATA[/^the "(?P<field>(?:[^"]|\\")*)" field should contain "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^поле "(?P<field>(?:[^"]|\\")*)" должно содержать "(?P<value>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-field-should-not-contain-value">
+            <source><![CDATA[/^the "(?P<field>(?:[^"]|\\")*)" field should not contain "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^поле "(?P<field>(?:[^"]|\\")*)" не должно содержать "(?P<value>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-checkbox-should-be-checked">
+            <source><![CDATA[/^the "(?P<checkbox>(?:[^"]|\\")*)" checkbox should be checked$/]]></source>
+            <target><![CDATA[/^галочка "(?P<checkbox>(?:[^"]|\\")*)" должна быть отмечена$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-checkbox-should-is-checked">
+            <source><![CDATA[/^the checkbox "(?P<checkbox>(?:[^"]|\\")*)" (?:is|should be) checked$/]]></source>
+            <target><![CDATA[/^галочка "(?P<checkbox>(?:[^"]|\\")*)" отмечена$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-checkbox-should-be-unchecked">
+            <source><![CDATA[/^the checkbox "(?P<checkbox>(?:[^"]|\\")*)" should (?:be unchecked|not be checked)$/]]></source>
+            <target><![CDATA[/^галочка "(?P<checkbox>(?:[^"]|\\")*)" не должна быть отмечена$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-checkbox-should-not-be-checked">
+            <source><![CDATA[/^the "(?P<checkbox>(?:[^"]|\\")*)" checkbox should not be checked$/]]></source>
+            <target><![CDATA[/^галочка "(?P<checkbox>(?:[^"]|\\")*)" должна быть не отмечена$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-checkbox-is-unchecked">
+            <source><![CDATA[/^the checkbox "(?P<checkbox>(?:[^"]|\\")*)" is (?:unchecked|not checked)$/]]></source>
+            <target><![CDATA[/^галочка "(?P<checkbox>(?:[^"]|\\")*)" не отмечена$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-be-on-page">
+            <source><![CDATA[/^(?:|I )should be on "(?P<page>[^"]+)"$/]]></source>
+            <target><![CDATA[/^(?:|я )должен быть на странице "(?P<page>[^"]+)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-be-on-homepage">
+            <source><![CDATA[/^(?:|I )should be on (?:|the )homepage$/]]></source>
+            <target><![CDATA[/^(?:|я )должен быть на главной странице/]]></target>
+        </trans-unit>
+        <trans-unit id="the-url-should-match">
+            <source><![CDATA[/^the (?i)url(?-i) should match (?P<pattern>"(?:[^"]|\\")*")$/]]></source>
+            <target><![CDATA[/^(?:url|адрес) должен соответствовать (?P<pattern>"(?:[^"]|\\")*")$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-element-should-contain">
+            <source><![CDATA[/^the "(?P<element>[^"]*)" element should contain "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^элемент "(?P<element>[^"]*)" должен содержать "(?P<value>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-element-should-not-contain">
+            <source><![CDATA[/^the "(?P<element>[^"]*)" element should not contain "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^элемент "(?P<element>[^"]*)" не должен содержать "(?P<value>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-text-in-element">
+            <source><![CDATA[/^(?:|I )should see "(?P<text>(?:[^"]|\\")*)" in the "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^(?:|я )должен видеть "(?P<text>(?:[^"]|\\")*)" внутри элемента "(?P<element>[^"]*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-not-see-text-in-element">
+            <source><![CDATA[/^(?:|I )should not see "(?P<text>(?:[^"]|\\")*)" in the "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^(?:|я )не должен видеть "(?P<text>(?:[^"]|\\")*)" внутри элемента "(?P<element>[^"]*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-element">
+            <source><![CDATA[/^(?:|I )should see an? "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^(?:|я )должен видеть элемент "(?P<element>[^"]*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-not-see-element">
+            <source><![CDATA[/^(?:|I )should not see an? "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^(?:|я )не должен видеть элемент "(?P<element>[^"]*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-num-elements">
+            <source><![CDATA[/^(?:|I )should see (?P<num>\d+) "(?P<element>[^"]*)" elements?$/]]></source>
+            <target><![CDATA[/^(?:|я )должен видеть (?P<num>\d+) элемент(ов|а)? "(?P<element>[^"]*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-status-code-should-be">
+            <source><![CDATA[/^the response status code should be (?P<code>\d+)$/]]></source>
+            <target><![CDATA[/^код ответа сервера должен быть (?P<code>\d+)$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-status-code-should-not-be">
+            <source><![CDATA[/^the response status code should not be (?P<code>\d+)$/]]></source>
+            <target><![CDATA[/^код ответа сервера не должен быть (?P<code>\d+)$/]]></target>
+        </trans-unit>
+        <trans-unit id="print-current-URL">
+            <source><![CDATA[/^print current URL$/]]></source>
+            <target><![CDATA[/^покажи текущий URL$/]]></target>
+        </trans-unit>
+        <trans-unit id="print-last-response">
+            <source><![CDATA[/^print last response$/]]></source>
+            <target><![CDATA[/^выведи последний ответ сервера$/]]></target>
+        </trans-unit>
+        <trans-unit id="show-last-response">
+            <source><![CDATA[/^show last response$/]]></source>
+            <target><![CDATA[/^покажи последний ответ сервера$/]]></target>
+        </trans-unit>
+    </body>
+  </file>
+</xliff>
diff --git a/vendor/behat/mink-extension/i18n/sk.xliff b/vendor/behat/mink-extension/i18n/sk.xliff
new file mode 100644 (file)
index 0000000..8d06b23
--- /dev/null
@@ -0,0 +1,151 @@
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+  <file original="global" source-language="en" target-language="sk" datatype="plaintext">
+    <header />
+    <body>
+        <trans-unit id="i-am-on-page">
+            <source><![CDATA[/^(?:|I )am on "(?P<page>[^"]+)"$/]]></source>
+            <target><![CDATA[/^(?:som|nachádzam sa) na(?:| stránke) "(?P<page>[^"]+)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-go-to-page">
+            <source><![CDATA[/^(?:|I )go to "(?P<page>[^"]+)"$/]]></source>
+            <target><![CDATA[/^(?:prej|pôj)dem na(?:| stránku) "(?P<page>[^"]+)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="reload-the-page">
+            <source><![CDATA[/^(?:|I )reload the page$/]]></source>
+            <target><![CDATA[/^obnovím stránku$/]]></target>
+        </trans-unit>
+        <trans-unit id="move-backward-one-page">
+            <source><![CDATA[/^(?:|I )move backward one page$/]]></source>
+            <target><![CDATA[/^(?:prej|pôj)dem o jednu stránku (?:|na)späť$/]]></target>
+        </trans-unit>
+        <trans-unit id="move-forward-one-page">
+            <source><![CDATA[/^(?:|I )move forward one page$/]]></source>
+            <target><![CDATA[/^(?:prej|pôj)dem o jednu stránku (?:vpred|vopred|dopredu)$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-press-button">
+            <source><![CDATA[/^(?:|I )press "(?P<button>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:stlačím|stisnem|kliknem na) (?:tlačídko|tlačidlo|tlačítko) "(?P<button>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-follow-link">
+            <source><![CDATA[/^(?:|I )follow "(?P<link>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^kliknem na(?:| odkaz| link) "(?P<link>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-fill-in-field-with-value">
+            <source><![CDATA[/^(?:|I )fill in "(?P<field>(?:[^"]|\\")*)" with "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:vyplním|zadám do) "(?P<field>(?:[^"]|\\")*)" (?:hodnotou|hodnotu) "(?P<value>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-fill-in-value-for-field">
+            <source><![CDATA[/^(?:|I )fill in "(?P<value>(?:[^"]|\\")*)" for "(?P<field>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:zadám|vyplním) "(?P<value>(?:[^"]|\\")*)" (?:hodnotu|hodnotou) "(?P<field>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-fill-in-the-following">
+            <source><![CDATA[/^(?:|I )fill in the following:$/]]></source>
+            <target><![CDATA[/^vyplním formulár(?:| nasledujúco):$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-select-option-from-select">
+            <source><![CDATA[/^(?:|I )select "(?P<option>(?:[^"]|\\")*)" from "(?P<select>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:vyberiem|zvolím)(?:| možnosť) "(?P<option>(?:[^"]|\\")*)" z "(?P<select>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-additionally-select-option-from-select">
+            <source><![CDATA[/^(?:|I )additionally select "(?P<option>(?:[^"]|\\")*)" from "(?P<select>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^ešte (?:vyberiem|zvolím)(?:| možnosť) "(?P<option>(?:[^"]|\\")*)" z "(?P<select>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-check-option">
+            <source><![CDATA[/^(?:|I )check "(?P<option>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:zaškrtnem|označím) "(?P<option>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-uncheck-option">
+            <source><![CDATA[/^(?:|I )uncheck "(?P<option>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:odškrtnem|odznačím) "(?P<option>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-attach-the-file-to-field">
+            <source><![CDATA[/^(?:|I )attach the file "(?P<path>[^"]*)" to "(?P<field>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:vyberiem|zvolím|zadám|nahrajem|načítam) súbor "(?P<path>[^"]*)" do "(?P<field>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-text">
+            <source><![CDATA[/^(?:|I )should see "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:by som mal(?:|a)|mal(?:|a) by som|musím) (?:|u)vidieť(?:| text| hlášku| správu) "(?P<text>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-text-matching">
+            <source><![CDATA[/^(?:|I )should see text matching (?P<pattern>"(?:[^"]|\\")*")$/]]></source>
+            <target><![CDATA[/^(?:mal(?:|a) by som|by som mal(?:|a)|musím) (?:|u)vidieť(?:| text| hlášku| správu) zodpovedajúcu(?:| vzoru) (?P<pattern>"(?:[^"]|\\")*")$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-not-see-text-matching">
+            <source><![CDATA[/^(?:|I )should not see text matching (?P<pattern>"(?:[^"]|\\")*")$/]]></source>
+            <target><![CDATA[/^(?:nemal(?:|a) by som|by som nemal(?:|a)|nesmiem) (?:|u)vidieť(?:| text| hlášku| správu) zodpovedajúcu(?:| vzoru) (?P<pattern>"(?:[^"]|\\")*")$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-should-contain">
+            <source><![CDATA[/^the response should contain "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:odpoveď|stránka) (?:musí|by mala) obsahovať(?:| text) "(?P<text>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-not-see-text">
+            <source><![CDATA[/^(?:|I )should not see "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:nemal(?:|a) by som|by som nemal(?:|a))|nesmiem) (?:|u)vidieť(?:| text) "(?P<text>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-should-not-contain">
+            <source><![CDATA[/^the response should not contain "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:odpoveď|stránka) (?:by nemala|nesmie) obsahovať(?:| text) "(?P<text>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-field-should-contain-value">
+            <source><![CDATA[/^the "(?P<field>(?:[^"]|\\")*)" field should contain "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^pole "(?P<field>(?:[^"]|\\")*)" (?:musí obsahovať|malo by obsahovať|by malo obsahovať|obsahuje)(?:| text| hodnotu) "(?P<value>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-field-should-not-contain-value">
+            <source><![CDATA[/^the "(?P<field>(?:[^"]|\\")*)" field should not contain "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^pole "(?P<field>(?:[^"]|\\")*)" (?:nesmie obsahovať|nemalo by obsahovať|by nemalo obsahovať|neobsahuje)(?:| text| hodnotu) "(?P<value>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-checkbox-should-be-checked">
+            <source><![CDATA[/^the "(?P<checkbox>(?:[^"]|\\")*)" checkbox should be checked$/]]></source>
+            <target><![CDATA[/^(?:pole|políčko|zaškrtávacie pole|zaškrtávacie políčko) "(?P<checkbox>(?:[^"]|\\")*)" (?:by malo byť|je) (?:zaškrtnuté|označené)$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-checkbox-should-not-be-checked">
+            <source><![CDATA[/^the "(?P<checkbox>(?:[^"]|\\")*)" checkbox should not be checked$/]]></source>
+            <target><![CDATA[/^(?:pole|políčko|zaškrtávacie pole|zaškrtávacie políčko) "(?P<checkbox>(?:[^"]|\\")*)" (?:by nemalo byť|nie je) (?:zaškrtnuté|označené)$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-be-on-page">
+            <source><![CDATA[/^(?:|I )should be on "(?P<page>[^"]+)"$/]]></source>
+            <target><![CDATA[/^(?:mal(?:|a) by som byť|by som mal(?:|a) byť|som|musím byť) na(?:| stránke) "(?P<page>[^"]+)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-url-should-match">
+            <source><![CDATA[/^the (?i)url(?-i) should match (?P<pattern>"(?:[^"]|\\")*")$/]]></source>
+            <target><![CDATA[/^(?:url|adresa|link) (?:by mal(?:|a)|mal(?:|a) by|musí) zodpovedať(?:| vzoru) (?P<pattern>"(?:[^"]|\\")*")$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-element-should-contain">
+            <source><![CDATA[/^the "(?P<element>[^"]*)" element should contain "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^element "(?P<element>[^"]*)" (?:by mal|mal by|musí) obsahovať(?:| text| hodnotu) "(?P<value>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-text-in-element">
+            <source><![CDATA[/^(?:|I )should see "(?P<text>(?:[^"]|\\")*)" in the "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^(?:mal(?:|a) by som|by som mal(?:|a)|musím) (?:|u)vidieť(?:| text| hodnotu| hlášku| správu) "(?P<text>(?:[^"]|\\")*)" v elemente "(?P<element>[^"]*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-element">
+            <source><![CDATA[/^(?:|I )should see an? "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^(?:mal(?:|a) by|by som mal(?:|a)|musím) (?:|u)vidieť element "(?P<element>[^"]*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-not-see-element">
+            <source><![CDATA[/^(?:|I )should not see an? "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^(?:nemal(?:|a) by som|by som nemal(?:|a)|nesmiem) (?:|u)vidieť element "(?P<element>[^"]*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-num-elements">
+            <source><![CDATA[/^(?:|I )should see (?P<num>\d+) "(?P<element>[^"]*)" elements?$/]]></source>
+            <target><![CDATA[/^(?:mal(?:|a) by som|by som mal(?:|a)|musím) (?:|u)vidieť (?P<num>\d+) elementov "(?P<element>[^"]*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-status-code-should-be">
+            <source><![CDATA[/^the response status code should be (?P<code>\d+)$/]]></source>
+            <target><![CDATA[/^(?:|stavový )kód odpovede (?:je|by mal byť|musí byť) (?P<code>\d+)$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-status-code-should-not-be">
+            <source><![CDATA[/^the response status code should not be (?P<code>\d+)$/]]></source>
+            <target><![CDATA[/^(?:|stavový )kód odpovede (?:nie je|by nemal byť|nesmie byť) (?P<code>\d+)$/]]></target>
+        </trans-unit>
+        <trans-unit id="print-last-response">
+            <source><![CDATA[/^print last response$/]]></source>
+            <target><![CDATA[/^vyťlač poslednú odpoveď$/]]></target>
+        </trans-unit>
+        <trans-unit id="show-last-response">
+            <source><![CDATA[/^show last response$/]]></source>
+            <target><![CDATA[/^ukáž poslednú odpoveď$/]]></target>
+        </trans-unit>
+    </body>
+  </file>
+</xliff>
diff --git a/vendor/behat/mink-extension/i18n/sv.xliff b/vendor/behat/mink-extension/i18n/sv.xliff
new file mode 100644 (file)
index 0000000..d3c60b8
--- /dev/null
@@ -0,0 +1,131 @@
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+  <file original="global" source-language="en" target-language="sv" datatype="plaintext">
+    <header />
+    <body>
+        <trans-unit id="i-am-on-page">
+            <source><![CDATA[/^(?:|I )am on "(?P<page>[^"]+)"$/]]></source>
+            <target><![CDATA[/^(?:|jag )är på "(?P<page>[^"]+)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-go-to-page">
+            <source><![CDATA[/^(?:|I )go to "(?P<page>[^"]+)"$/]]></source>
+            <target><![CDATA[/^(?:|jag )gå till "(?P<page>[^"]+)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="reload-the-page">
+            <source><![CDATA[/^(?:|I )reload the page$/]]></source>
+            <target><![CDATA[/^(?:|jag )ladda om sidan$/]]></target>
+        </trans-unit>
+        <trans-unit id="move-backward-one-page">
+            <source><![CDATA[/^(?:|I )move backward one page$/]]></source>
+            <target><![CDATA[/^(?:|jag )gå tillbaka en sida$/]]></target>
+        </trans-unit>
+        <trans-unit id="move-forward-one-page">
+            <source><![CDATA[/^(?:|I )move forward one page$/]]></source>
+            <target><![CDATA[/^(?:|jag )gå en sida framåt$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-press-button">
+            <source><![CDATA[/^(?:|I )press "(?P<button>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|jag )trycka "(?P<button>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-follow-link">
+            <source><![CDATA[/^(?:|I )follow "(?P<link>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|jag )följa "(?P<link>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-fill-in-field-with-value">
+            <source><![CDATA[/^(?:|I )fill in "(?P<field>(?:[^"]|\\")*)" with "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|jag )fylla in "(?P<field>(?:[^"]|\\")*)" med "(?P<value>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-fill-in-value-for-field">
+            <source><![CDATA[/^(?:|I )fill in "(?P<value>(?:[^"]|\\")*)" for "(?P<field>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|jag )fylla in "(?P<value>(?:[^"]|\\")*)" för "(?P<field>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-fill-in-the-following">
+            <source><![CDATA[/^(?:|I )fill in the following:$/]]></source>
+            <target><![CDATA[/^(?:|jag )fylla in följande:$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-select-option-from-select">
+            <source><![CDATA[/^(?:|I )select "(?P<option>(?:[^"]|\\")*)" from "(?P<select>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|jag )välja "(?P<option>(?:[^"]|\\")*)" från "(?P<select>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-check-option">
+            <source><![CDATA[/^(?:|I )check "(?P<option>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|jag )markera "(?P<option>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-uncheck-option">
+            <source><![CDATA[/^(?:|I )uncheck "(?P<option>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|jag )avmarkera "(?P<option>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-attach-the-file-to-field">
+            <source><![CDATA[/^(?:|I )attach the file "(?P<path>[^"]*)" to "(?P<field>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|jag )bifoga filen "(?P<path>[^"]*)" till "(?P<field>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-text">
+            <source><![CDATA[/^(?:|I )should see "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|jag )skulle se "(?P<text>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-should-contain">
+            <source><![CDATA[/^the response should contain "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^responsen skulle innehålla "(?P<text>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-not-see-text">
+            <source><![CDATA[/^(?:|I )should not see "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|jag )skulle inte se "(?P<text>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-should-not-contain">
+            <source><![CDATA[/^the response should not contain "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^responsen skulle inte innehålla "(?P<text>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-field-should-contain-value">
+            <source><![CDATA[/^the "(?P<field>(?:[^"]|\\")*)" field should contain "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^fältet "(?P<field>(?:[^"]|\\")*)" skulle inehålla "(?P<value>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-field-should-not-contain-value">
+            <source><![CDATA[/^the "(?P<field>(?:[^"]|\\")*)" field should not contain "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^fältet "(?P<field>(?:[^"]|\\")*)" skulle inte innehålla "(?P<value>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-checkbox-should-be-checked">
+            <source><![CDATA[/^the "(?P<checkbox>(?:[^"]|\\")*)" checkbox should be checked$/]]></source>
+            <target><![CDATA[/^kryssrutan "(?P<checkbox>(?:[^"]|\\")*)" skulle vara markerat$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-checkbox-should-not-be-checked">
+            <source><![CDATA[/^the "(?P<checkbox>(?:[^"]|\\")*)" checkbox should not be checked$/]]></source>
+            <target><![CDATA[/^kryssrutan "(?P<checkbox>(?:[^"]|\\")*)" skulle inte vara markerat$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-be-on-page">
+            <source><![CDATA[/^(?:|I )should be on "(?P<page>[^"]+)"$/]]></source>
+            <target><![CDATA[/^(?:|jag )skulle vara på "(?P<page>[^"]+)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-url-should-match">
+            <source><![CDATA[/^the (?i)url(?-i) should match (?P<pattern>"(?:[^"]|\\")*")$/]]></source>
+            <target><![CDATA[/^webbadressen skulle matcha (?P<pattern>"(?:[^"]|\\")*")$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-element-should-contain">
+            <source><![CDATA[/^the "(?P<element>[^"]*)" element should contain "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^elementen "(?P<element>[^"]*)" skulle innehålla "(?P<value>(?:[^"]|\\")*)"$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-text-in-element">
+            <source><![CDATA[/^(?:|I )should see "(?P<text>(?:[^"]|\\")*)" in the "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^(?:|jag )skulle se "(?P<text>(?:[^"]|\\")*)" i "(?P<element>[^"]*)" elementet$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-element">
+            <source><![CDATA[/^(?:|I )should see an? "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^(?:|jag )skulle se ett "(?P<element>[^"]*)" element$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-not-see-element">
+            <source><![CDATA[/^(?:|I )should not see an? "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^(?:|jag )skulle inte se ett "(?P<element>[^"]*)" element$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-status-code-should-be">
+            <source><![CDATA[/^the response status code should be (?P<code>\d+)$/]]></source>
+            <target><![CDATA[/^status code responsen skulle vara (?P<code>\d+)$/]]></target>
+        </trans-unit>
+        <trans-unit id="print-last-response">
+            <source><![CDATA[/^print last response$/]]></source>
+            <target><![CDATA[/^skriva ut sista respons$/]]></target>
+        </trans-unit>
+        <trans-unit id="show-last-response">
+            <source><![CDATA[/^show last response$/]]></source>
+            <target><![CDATA[/^visa sista respons$/]]></target>
+        </trans-unit>
+    </body>
+  </file>
+</xliff>
diff --git a/vendor/behat/mink-extension/i18n/zh-CN.xliff b/vendor/behat/mink-extension/i18n/zh-CN.xliff
new file mode 100644 (file)
index 0000000..99136cb
--- /dev/null
@@ -0,0 +1,157 @@
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+  <file original="global" source-language="en" target-language="zh-CN" datatype="plaintext">
+    <header />
+    <body>
+        <trans-unit id="i-am-on-page">
+            <source><![CDATA[/^(?:|I )am on "(?P<page>[^"]+)"$/]]></source>
+            <target><![CDATA[/^(?:|我)打开了“(?P<page>[^\s]+)”$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-go-to-page">
+            <source><![CDATA[/^(?:|I )go to "(?P<page>[^"]+)"$/]]></source>
+            <target><![CDATA[/^(?:|我)转到了“(?P<page>[^\s]+)”$/]]></target>
+        </trans-unit>
+        <trans-unit id="reload-the-page">
+            <source><![CDATA[/^(?:|I )reload the page$/]]></source>
+            <target><![CDATA[/^(?:|我)重新刷新了该网页$/]]></target>
+        </trans-unit>
+        <trans-unit id="move-backward-one-page">
+            <source><![CDATA[/^(?:|I )move backward one page$/]]></source>
+            <target><![CDATA[/^(?:|我)后退了一页$/]]></target>
+        </trans-unit>
+        <trans-unit id="move-forward-one-page">
+            <source><![CDATA[/^(?:|I )move forward one page$/]]></source>
+            <target><![CDATA[/^(?:|我)前进了一页$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-press-button">
+            <source><![CDATA[/^(?:|I )press "(?P<button>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|我)点击了“(?P<button>(?:[^"]|\\")*)”按钮$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-follow-link">
+            <source><![CDATA[/^(?:|I )follow "(?P<link>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|我)点击了“(?P<link>(?:[^"]|\\")*)”链接$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-fill-in-field-with-value">
+            <source><![CDATA[/^(?:|I )fill in "(?P<field>(?:[^"]|\\")*)" with "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|我)在“(?P<field>(?:[^"]|\\")*)”文本框内填写了“(?P<value>(?:[^"]|\\")*)”$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-fill-in-value-for-field">
+            <source><![CDATA[/^(?:|I )fill in "(?P<value>(?:[^"]|\\")*)" for "(?P<field>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|我)内填写了“(?P<value>(?:[^"]|\\")*)”到“(?P<field>(?:[^"]|\\")*)”文本框$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-fill-in-the-following">
+            <source><![CDATA[/^(?:|I )fill in the following:$/]]></source>
+            <target><![CDATA[/^(?:|我)使用以下数据输入:$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-select-option-from-select">
+            <source><![CDATA[/^(?:|I )select "(?P<option>(?:[^"]|\\")*)" from "(?P<select>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|我)在“(?P<select>(?:[^"]|\\")*)”选择框里面选择了“(?P<option>(?:[^"]|\\")*)”$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-additionally-select-option-from-select">
+            <source><![CDATA[/^(?:|I )additionally select "(?P<option>(?:[^"]|\\")*)" from "(?P<select>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|我)在“(?P<select>(?:[^"]|\\")*)”选择框里面添加了“(?P<option>(?:[^"]|\\")*)”选择$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-check-option">
+            <source><![CDATA[/^(?:|I )check "(?P<option>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|我)选中了“(?P<option>(?:[^"]|\\")*)”选项$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-uncheck-option">
+            <source><![CDATA[/^(?:|I )uncheck "(?P<option>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|我)取消了“(?P<option>(?:[^"]|\\")*)”选项$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-attach-the-file-to-field">
+            <source><![CDATA[/^(?:|I )attach the file "(?P<path>[^"]*)" to "(?P<field>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|我)添加了文件“(?P<path>[^"]*)”到“(?P<field>(?:[^"]|\\")*)”文件选择框$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-text">
+            <source><![CDATA[/^(?:|I )should see "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|我)应该可以看见包含“(?P<text>(?:[^"]|\\")*)”的内容$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-should-contain">
+            <source><![CDATA[/^the response should contain "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^响应应该包含“(?P<text>(?:[^"]|\\")*)”的内容$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-not-see-text">
+            <source><![CDATA[/^(?:|I )should not see "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^(?:|我)应该不能看见包含“(?P<text>(?:[^"]|\\")*)”的内容$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-should-not-contain">
+            <source><![CDATA[/^the response should not contain "(?P<text>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^响应不应该包含“(?P<text>(?:[^"]|\\")*)”的内容$/]]></target>
+
+        </trans-unit>
+        <trans-unit id="the-field-should-contain-value">
+            <source><![CDATA[/^the "(?P<field>(?:[^"]|\\")*)" field should contain "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^“(?P<field>(?:[^"]|\\")*)”文本框应该包含值“(?P<value>(?:[^"]|\\")*)”$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-field-should-not-contain-value">
+            <source><![CDATA[/^the "(?P<field>(?:[^"]|\\")*)" field should not contain "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^“(?P<field>(?:[^"]|\\")*)”文本框应该不包含值“(?P<value>(?:[^"]|\\")*)”$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-checkbox-should-be-checked">
+            <source><![CDATA[/^the "(?P<checkbox>(?:[^"]|\\")*)" checkbox should be checked$/]]></source>
+            <target><![CDATA[/^“(?P<checkbox>(?:[^"]|\\")*)”选项框应该已经选中了$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-checkbox-should-not-be-checked">
+            <source><![CDATA[/^the "(?P<checkbox>(?:[^"]|\\")*)" checkbox should not be checked$/]]></source>
+            <target><![CDATA[/^“(?P<checkbox>(?:[^"]|\\")*)”选项框应该还没有选中$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-be-on-page">
+            <source><![CDATA[/^(?:|I )should be on "(?P<page>[^"]+)"$/]]></source>
+            <target><![CDATA[/^(?:|我)应该到了“(?P<page>[^\s]+)”$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-url-should-match">
+            <source><![CDATA[/^the (?i)url(?-i) should match (?P<pattern>"(?:[^"]|\\")*")$/]]></source>
+            <target><![CDATA[/^(?i)url(?-i) 应该匹配“(?P<pattern>"(?:[^"]|\\")*")”$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-element-should-contain">
+            <source><![CDATA[/^the "(?P<element>[^"]*)" element should contain "(?P<value>(?:[^"]|\\")*)"$/]]></source>
+            <target><![CDATA[/^“(?P<element>[^"]*)”元素应该包含“(?P<value>(?:[^"]|\\")*)”内容$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-text-in-element">
+            <source><![CDATA[/^(?:|I )should see "(?P<text>(?:[^"]|\\")*)" in the "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^“(?P<element>[^"]*)”元素应该有“(?P<value>(?:[^"]|\\")*)”内容$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-not-see-text-in-element">
+            <source><![CDATA[/^(?:|I )should not see "(?P<text>(?:[^"]|\\")*)" in the "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^“(?P<element>[^"]*)”元素应该没有“(?P<value>(?:[^"]|\\")*)”内容$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-element">
+            <source><![CDATA[/^(?:|I )should see an? "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^(?:|我)应该可以看见“(?P<element>[^"]*)”元素$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-not-see-element">
+            <source><![CDATA[/^(?:|I )should not see an? "(?P<element>[^"]*)" element$/]]></source>
+            <target><![CDATA[/^(?:|我)应该不能看见“(?P<element>[^"]*)”元素$/]]></target>
+        </trans-unit>
+        <trans-unit id="i-should-see-num-elements">
+            <source><![CDATA[/^(?:|I )should see (?P<num>\d+) "(?P<element>[^"]*)" elements?$/]]></source>
+            <target><![CDATA[/^(?:|我)应该可以看见 (?P<num>\d+) 个“(?P<element>[^"]*)”元素$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-status-code-should-be">
+            <source><![CDATA[/^the response status code should be (?P<code>\d+)$/]]></source>
+            <target><![CDATA[/^返回状态代码应该是 (?P<code>\d+)$/]]></target>
+        </trans-unit>
+        <trans-unit id="the-response-status-code-should-not-be">
+            <source><![CDATA[/^the response status code should not be (?P<code>\d+)$/]]></source>
+            <target><![CDATA[/^返回状态代码应该不是 (?P<code>\d+)$/]]></target>
+        </trans-unit>
+        <trans-unit id="print-last-response">
+            <source><![CDATA[/^print last response$/]]></source>
+            <target><![CDATA[/^打印最后一次响应$/]]></target>
+        </trans-unit>
+        <trans-unit id="show-last-response">
+            <source><![CDATA[/^show last response$/]]></source>
+            <target><![CDATA[/^显示最后一次响应$/]]></target>
+        </trans-unit>
+        <trans-unit id="-should-see-text-matching">
+            <source><![CDATA[/^(?:|I )should see text matching (?P<pattern>"(?:[^"]|\\")*")$/]]></source>
+            <target><![CDATA[/^(?:|我)应该可以看见文本内容匹配“(?P<pattern>"(?:[^"]|\\")*")”$/]]></target>
+
+        </trans-unit>
+        <trans-unit id="-should-not-see-text-matching">
+            <source><![CDATA[/^(?:|I )should not see text matching (?P<pattern>"(?:[^"]|\\")*")$/]]></source>
+            <target><![CDATA[/^(?:|我)应该可以看见文本内容不匹配“(?P<pattern>"(?:[^"]|\\")*")”$/]]></target>
+        </trans-unit>
+    </body>
+  </file>
+</xliff>
diff --git a/vendor/behat/mink-extension/init.php b/vendor/behat/mink-extension/init.php
new file mode 100644 (file)
index 0000000..db8e96b
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+
+/*
+ * This file is part of the Behat
+ *
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+spl_autoload_register(function($class) {
+    if (false !== strpos($class, 'Behat\\MinkExtension')) {
+        require_once(__DIR__.'/src/'.str_replace('\\', '/', $class).'.php');
+        return true;
+    }
+}, true, false);
+
+return new Behat\MinkExtension\ServiceContainer\MinkExtension;
diff --git a/vendor/behat/mink-extension/spec/Behat/MinkExtension/Context/Initializer/MinkAwareInitializerSpec.php b/vendor/behat/mink-extension/spec/Behat/MinkExtension/Context/Initializer/MinkAwareInitializerSpec.php
new file mode 100644 (file)
index 0000000..84b208a
--- /dev/null
@@ -0,0 +1,33 @@
+<?php
+
+namespace spec\Behat\MinkExtension\Context\Initializer;
+
+use Behat\Behat\Context\Context;
+use Behat\Mink\Mink;
+use Behat\MinkExtension\Context\MinkAwareContext;
+use PhpSpec\ObjectBehavior;
+
+class MinkAwareInitializerSpec extends ObjectBehavior
+{
+    function let(Mink $mink)
+    {
+        $this->beConstructedWith($mink, array('base_url' => 'foo'));
+    }
+
+    function it_is_a_context_initializer()
+    {
+        $this->shouldHaveType('Behat\Behat\Context\Initializer\ContextInitializer');
+    }
+
+    function it_does_nothing_for_basic_contexts(Context $context)
+    {
+        $this->initializeContext($context);
+    }
+
+    function it_injects_mink_and_parameters_in_mink_aware_contexts(MinkAwareContext $context, $mink)
+    {
+        $context->setMink($mink)->shouldBeCalled();
+        $context->setMinkParameters(array('base_url' => 'foo'))->shouldBeCalled();
+        $this->initializeContext($context);
+    }
+}
diff --git a/vendor/behat/mink-extension/spec/Behat/MinkExtension/Listener/SessionsListenerSpec.php b/vendor/behat/mink-extension/spec/Behat/MinkExtension/Listener/SessionsListenerSpec.php
new file mode 100644 (file)
index 0000000..be72e21
--- /dev/null
@@ -0,0 +1,174 @@
+<?php
+
+namespace spec\Behat\MinkExtension\Listener;
+
+use Behat\Behat\EventDispatcher\Event\ScenarioTested;
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\ScenarioNode;
+use Behat\Mink\Mink;
+use Behat\Testwork\ServiceContainer\Exception\ProcessingException;
+use Behat\Testwork\Suite\Exception\SuiteConfigurationException;
+use Behat\Testwork\Suite\Suite;
+use PhpSpec\ObjectBehavior;
+
+class SessionsListenerSpec extends ObjectBehavior
+{
+    function let(Mink $mink, ScenarioTested $event, FeatureNode $feature, ScenarioNode $scenario, Suite $suite)
+    {
+        $this->beConstructedWith($mink, 'goutte', 'selenium2', array('selenium2', 'sahi'));
+
+        $event->getSuite()->willReturn($suite);
+        $event->getFeature()->willReturn($feature);
+        $event->getScenario()->willReturn($scenario);
+
+        $suite->hasSetting('mink_session')->willReturn(false);
+        $suite->getName()->willReturn('default');
+
+        $feature->hasTag('insulated')->willReturn(false);
+        $feature->getTags()->willReturn(array());
+        $scenario->hasTag('insulated')->willReturn(false);
+        $scenario->getTags()->willReturn(array());
+    }
+
+    function it_is_an_event_subscriber()
+    {
+        $this->shouldHaveType('Symfony\Component\EventDispatcher\EventSubscriberInterface');
+    }
+
+    function it_resets_the_default_session_before_scenarios($event, $mink)
+    {
+        $mink->resetSessions()->shouldBeCalled();
+        $mink->setDefaultSessionName('goutte')->shouldBeCalled();
+
+        $this->prepareDefaultMinkSession($event);
+    }
+
+    function it_supports_changing_the_default_session_per_suite($event, $mink, $suite)
+    {
+        $suite->hasSetting('mink_session')->willReturn(true);
+        $suite->getSetting('mink_session')->willReturn('test');
+
+        $mink->resetSessions()->shouldBeCalled();
+        $mink->setDefaultSessionName('test')->shouldBeCalled();
+
+        $this->prepareDefaultMinkSession($event);
+    }
+
+    function it_fails_for_non_string_default_suite_session($event, $suite)
+    {
+        $suite->hasSetting('mink_session')->willReturn(true);
+        $suite->getSetting('mink_session')->willReturn(array());
+
+        $this->shouldThrow(new SuiteConfigurationException('`mink_session` setting of the "default" suite is expected to be a string, array given.', 'default'))
+            ->duringPrepareDefaultMinkSession($event);
+    }
+
+    function it_switches_to_the_javascript_session_for_tagged_scenarios($event, $mink, $scenario, $suite)
+    {
+        $suite->hasSetting('mink_javascript_session')->willReturn(false);
+        $scenario->getTags()->willReturn(array('javascript'));
+        $mink->resetSessions()->shouldBeCalled();
+        $mink->setDefaultSessionName('selenium2')->shouldBeCalled();
+
+        $this->prepareDefaultMinkSession($event);
+    }
+
+    function it_switches_to_the_javascript_session_for_tagged_features($event, $mink, $feature, $suite)
+    {
+        $suite->hasSetting('mink_javascript_session')->willReturn(false);
+        $feature->getTags()->willReturn(array('javascript'));
+        $mink->resetSessions()->shouldBeCalled();
+        $mink->setDefaultSessionName('selenium2')->shouldBeCalled();
+
+        $this->prepareDefaultMinkSession($event);
+    }
+
+    function it_supports_changing_the_default_javascript_session_per_suite($event, $mink, $scenario, $suite)
+    {
+        $suite->hasSetting('mink_javascript_session')->willReturn(true);
+        $suite->getSetting('mink_javascript_session')->willReturn('sahi');
+
+        $scenario->getTags()->willReturn(array('javascript'));
+        $mink->resetSessions()->shouldBeCalled();
+        $mink->setDefaultSessionName('sahi')->shouldBeCalled();
+
+        $this->prepareDefaultMinkSession($event);
+    }
+
+    function it_fails_for_non_string_javascript_suite_session($event, $scenario, $suite)
+    {
+        $suite->hasSetting('mink_javascript_session')->willReturn(true);
+        $suite->getSetting('mink_javascript_session')->willReturn(array());
+
+        $scenario->getTags()->willReturn(array('javascript'));
+
+        $this->shouldThrow(new SuiteConfigurationException('`mink_javascript_session` setting of the "default" suite is expected to be a string, array given.', 'default'))
+            ->duringPrepareDefaultMinkSession($event);
+    }
+
+    function it_fails_for_invalid_javascript_suite_session($event, $scenario, $suite)
+    {
+        $suite->hasSetting('mink_javascript_session')->willReturn(true);
+        $suite->getSetting('mink_javascript_session')->willReturn('test');
+
+        $scenario->getTags()->willReturn(array('javascript'));
+
+        $this->shouldThrow(new SuiteConfigurationException('`mink_javascript_session` setting of the "default" suite is not a javascript session. test given but expected one of selenium2, sahi.', 'default'))
+            ->duringPrepareDefaultMinkSession($event);
+    }
+
+    function it_fails_when_the_javascript_session_is_used_but_not_defined($event, $mink, $feature, $suite)
+    {
+        $suite->hasSetting('mink_javascript_session')->willReturn(false);
+        $this->beConstructedWith($mink, 'goutte', null);
+        $feature->getTags()->willReturn(array('javascript'));
+
+        $this->shouldThrow(new ProcessingException('The @javascript tag cannot be used without enabling a javascript session'))
+            ->duringPrepareDefaultMinkSession($event);
+    }
+
+    function it_switches_to_a_named_session($event, $mink, $scenario)
+    {
+        $scenario->getTags()->willReturn(array('mink:test'));
+        $mink->resetSessions()->shouldBeCalled();
+        $mink->setDefaultSessionName('test')->shouldBeCalled();
+
+        $this->prepareDefaultMinkSession($event);
+    }
+
+    function it_prefers_the_scenario_over_the_feature($event, $mink, $scenario, $feature, $suite)
+    {
+        $suite->hasSetting('mink_javascript_session')->willReturn(false);
+        $scenario->getTags()->willReturn(array('mink:test'));
+        $feature->getTags()->willReturn(array('javascript'));
+        $mink->resetSessions()->shouldBeCalled();
+        $mink->setDefaultSessionName('test')->shouldBeCalled();
+
+        $this->prepareDefaultMinkSession($event);
+    }
+
+    function it_stops_the_sessions_for_insulated_scenarios($event, $mink, $scenario)
+    {
+        $scenario->hasTag('insulated')->willReturn(true);
+        $mink->stopSessions()->shouldBeCalled();
+        $mink->setDefaultSessionName('goutte')->shouldBeCalled();
+
+        $this->prepareDefaultMinkSession($event);
+    }
+
+    function it_stops_the_sessions_for_insulated_features($event, $mink, $feature)
+    {
+        $feature->hasTag('insulated')->willReturn(true);
+        $mink->stopSessions()->shouldBeCalled();
+        $mink->setDefaultSessionName('goutte')->shouldBeCalled();
+
+        $this->prepareDefaultMinkSession($event);
+    }
+
+    function it_stops_the_sessions_at_the_end_of_the_exercise($mink)
+    {
+        $mink->stopSessions()->shouldBeCalled();
+
+        $this->tearDownMinkSessions();
+    }
+}
diff --git a/vendor/behat/mink-extension/spec/Behat/MinkExtension/ServiceContainer/Driver/BrowserStackFactorySpec.php b/vendor/behat/mink-extension/spec/Behat/MinkExtension/ServiceContainer/Driver/BrowserStackFactorySpec.php
new file mode 100644 (file)
index 0000000..00922e7
--- /dev/null
@@ -0,0 +1,24 @@
+<?php
+
+namespace spec\Behat\MinkExtension\ServiceContainer\Driver;
+
+use PhpSpec\ObjectBehavior;
+use Prophecy\Argument;
+
+class BrowserStackFactorySpec extends ObjectBehavior
+{
+    function it_is_a_driver_factory()
+    {
+        $this->shouldHaveType('Behat\MinkExtension\ServiceContainer\Driver\DriverFactory');
+    }
+
+    function it_is_named_browser_stack()
+    {
+        $this->getDriverName()->shouldReturn('browser_stack');
+    }
+
+    function it_supports_javascript()
+    {
+        $this->supportsJavascript()->shouldBe(true);
+    }
+}
diff --git a/vendor/behat/mink-extension/spec/Behat/MinkExtension/ServiceContainer/Driver/GoutteFactorySpec.php b/vendor/behat/mink-extension/spec/Behat/MinkExtension/ServiceContainer/Driver/GoutteFactorySpec.php
new file mode 100644 (file)
index 0000000..484e6e7
--- /dev/null
@@ -0,0 +1,23 @@
+<?php
+
+namespace spec\Behat\MinkExtension\ServiceContainer\Driver;
+
+use PhpSpec\ObjectBehavior;
+
+class GoutteFactorySpec extends ObjectBehavior
+{
+    function it_is_a_driver_factory()
+    {
+        $this->shouldHaveType('Behat\MinkExtension\ServiceContainer\Driver\DriverFactory');
+    }
+
+    function it_is_named_goutte()
+    {
+        $this->getDriverName()->shouldReturn('goutte');
+    }
+
+    function it_does_not_support_javascript()
+    {
+        $this->supportsJavascript()->shouldBe(false);
+    }
+}
diff --git a/vendor/behat/mink-extension/spec/Behat/MinkExtension/ServiceContainer/Driver/SahiFactorySpec.php b/vendor/behat/mink-extension/spec/Behat/MinkExtension/ServiceContainer/Driver/SahiFactorySpec.php
new file mode 100644 (file)
index 0000000..abdb7d5
--- /dev/null
@@ -0,0 +1,23 @@
+<?php
+
+namespace spec\Behat\MinkExtension\ServiceContainer\Driver;
+
+use PhpSpec\ObjectBehavior;
+
+class SahiFactorySpec extends ObjectBehavior
+{
+    function it_is_a_driver_factory()
+    {
+        $this->shouldHaveType('Behat\MinkExtension\ServiceContainer\Driver\DriverFactory');
+    }
+
+    function it_is_named_sahi()
+    {
+        $this->getDriverName()->shouldReturn('sahi');
+    }
+
+    function it_supports_javascript()
+    {
+        $this->supportsJavascript()->shouldBe(true);
+    }
+}
diff --git a/vendor/behat/mink-extension/spec/Behat/MinkExtension/ServiceContainer/Driver/SauceLabsFactorySpec.php b/vendor/behat/mink-extension/spec/Behat/MinkExtension/ServiceContainer/Driver/SauceLabsFactorySpec.php
new file mode 100644 (file)
index 0000000..21bb10c
--- /dev/null
@@ -0,0 +1,23 @@
+<?php
+
+namespace spec\Behat\MinkExtension\ServiceContainer\Driver;
+
+use PhpSpec\ObjectBehavior;
+
+class SauceLabsFactorySpec extends ObjectBehavior
+{
+    function it_is_a_driver_factory()
+    {
+        $this->shouldHaveType('Behat\MinkExtension\ServiceContainer\Driver\DriverFactory');
+    }
+
+    function it_is_named_sauce_labs()
+    {
+        $this->getDriverName()->shouldReturn('sauce_labs');
+    }
+
+    function it_supports_javascript()
+    {
+        $this->supportsJavascript()->shouldBe(true);
+    }
+}
diff --git a/vendor/behat/mink-extension/spec/Behat/MinkExtension/ServiceContainer/Driver/Selenium2FactorySpec.php b/vendor/behat/mink-extension/spec/Behat/MinkExtension/ServiceContainer/Driver/Selenium2FactorySpec.php
new file mode 100644 (file)
index 0000000..5ec5c16
--- /dev/null
@@ -0,0 +1,23 @@
+<?php
+
+namespace spec\Behat\MinkExtension\ServiceContainer\Driver;
+
+use PhpSpec\ObjectBehavior;
+
+class Selenium2FactorySpec extends ObjectBehavior
+{
+    function it_is_a_driver_factory()
+    {
+        $this->shouldHaveType('Behat\MinkExtension\ServiceContainer\Driver\DriverFactory');
+    }
+
+    function it_is_named_selenium2()
+    {
+        $this->getDriverName()->shouldReturn('selenium2');
+    }
+
+    function it_supports_javascript()
+    {
+        $this->supportsJavascript()->shouldBe(true);
+    }
+}
diff --git a/vendor/behat/mink-extension/spec/Behat/MinkExtension/ServiceContainer/Driver/SeleniumFactorySpec.php b/vendor/behat/mink-extension/spec/Behat/MinkExtension/ServiceContainer/Driver/SeleniumFactorySpec.php
new file mode 100644 (file)
index 0000000..a1fb505
--- /dev/null
@@ -0,0 +1,23 @@
+<?php
+
+namespace spec\Behat\MinkExtension\ServiceContainer\Driver;
+
+use PhpSpec\ObjectBehavior;
+
+class SeleniumFactorySpec extends ObjectBehavior
+{
+    function it_is_a_driver_factory()
+    {
+        $this->shouldHaveType('Behat\MinkExtension\ServiceContainer\Driver\DriverFactory');
+    }
+
+    function it_is_named_selenium()
+    {
+        $this->getDriverName()->shouldReturn('selenium');
+    }
+
+    function it_supports_javascript()
+    {
+        $this->supportsJavascript()->shouldBe(true);
+    }
+}
diff --git a/vendor/behat/mink-extension/spec/Behat/MinkExtension/ServiceContainer/Driver/ZombieFactorySpec.php b/vendor/behat/mink-extension/spec/Behat/MinkExtension/ServiceContainer/Driver/ZombieFactorySpec.php
new file mode 100644 (file)
index 0000000..f0e0445
--- /dev/null
@@ -0,0 +1,23 @@
+<?php
+
+namespace spec\Behat\MinkExtension\ServiceContainer\Driver;
+
+use PhpSpec\ObjectBehavior;
+
+class ZombieFactorySpec extends ObjectBehavior
+{
+    function it_is_a_driver_factory()
+    {
+        $this->shouldHaveType('Behat\MinkExtension\ServiceContainer\Driver\DriverFactory');
+    }
+
+    function it_is_named_zombie()
+    {
+        $this->getDriverName()->shouldReturn('zombie');
+    }
+
+    function it_supports_javascript()
+    {
+        $this->supportsJavascript()->shouldBe(true);
+    }
+}
diff --git a/vendor/behat/mink-extension/spec/Behat/MinkExtension/ServiceContainer/MinkExtensionSpec.php b/vendor/behat/mink-extension/spec/Behat/MinkExtension/ServiceContainer/MinkExtensionSpec.php
new file mode 100644 (file)
index 0000000..c16533b
--- /dev/null
@@ -0,0 +1,18 @@
+<?php
+
+namespace spec\Behat\MinkExtension\ServiceContainer;
+
+use PhpSpec\ObjectBehavior;
+
+class MinkExtensionSpec extends ObjectBehavior
+{
+    function it_is_a_testwork_extension()
+    {
+        $this->shouldHaveType('Behat\Testwork\ServiceContainer\Extension');
+    }
+
+    function it_is_named_mink()
+    {
+        $this->getConfigKey()->shouldReturn('mink');
+    }
+}
diff --git a/vendor/behat/mink-extension/src/Behat/MinkExtension/Context/Initializer/MinkAwareInitializer.php b/vendor/behat/mink-extension/src/Behat/MinkExtension/Context/Initializer/MinkAwareInitializer.php
new file mode 100644 (file)
index 0000000..bbb45ab
--- /dev/null
@@ -0,0 +1,56 @@
+<?php
+
+/*
+ * This file is part of the Behat MinkExtension.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\MinkExtension\Context\Initializer;
+
+use Behat\Behat\Context\Context;
+use Behat\Behat\Context\Initializer\ContextInitializer;
+
+use Behat\Mink\Mink;
+use Behat\MinkExtension\Context\MinkAwareContext;
+
+/**
+ * Mink aware contexts initializer.
+ * Sets Mink instance and parameters to the MinkAware contexts.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class MinkAwareInitializer implements ContextInitializer
+{
+    private $mink;
+    private $parameters;
+
+    /**
+     * Initializes initializer.
+     *
+     * @param Mink  $mink
+     * @param array $parameters
+     */
+    public function __construct(Mink $mink, array $parameters)
+    {
+        $this->mink       = $mink;
+        $this->parameters = $parameters;
+    }
+
+    /**
+     * Initializes provided context.
+     *
+     * @param Context $context
+     */
+    public function initializeContext(Context $context)
+    {
+        if (!$context instanceof MinkAwareContext) {
+            return;
+        }
+
+        $context->setMink($this->mink);
+        $context->setMinkParameters($this->parameters);
+    }
+}
diff --git a/vendor/behat/mink-extension/src/Behat/MinkExtension/Context/MinkAwareContext.php b/vendor/behat/mink-extension/src/Behat/MinkExtension/Context/MinkAwareContext.php
new file mode 100644 (file)
index 0000000..11aaa4f
--- /dev/null
@@ -0,0 +1,36 @@
+<?php
+
+/*
+ * This file is part of the Behat MinkExtension.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\MinkExtension\Context;
+
+use Behat\Behat\Context\Context;
+use Behat\Mink\Mink;
+
+/**
+ * Mink aware interface for contexts.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface MinkAwareContext extends Context
+{
+    /**
+     * Sets Mink instance.
+     *
+     * @param Mink $mink Mink session manager
+     */
+    public function setMink(Mink $mink);
+
+    /**
+     * Sets parameters provided for Mink.
+     *
+     * @param array $parameters
+     */
+    public function setMinkParameters(array $parameters);
+}
diff --git a/vendor/behat/mink-extension/src/Behat/MinkExtension/Context/MinkContext.php b/vendor/behat/mink-extension/src/Behat/MinkExtension/Context/MinkContext.php
new file mode 100644 (file)
index 0000000..a5bfa30
--- /dev/null
@@ -0,0 +1,571 @@
+<?php
+
+/*
+ * This file is part of the Behat MinkExtension.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\MinkExtension\Context;
+
+use Behat\Behat\Context\TranslatableContext;
+use Behat\Gherkin\Node\TableNode;
+
+/**
+ * Mink context for Behat BDD tool.
+ * Provides Mink integration and base step definitions.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class MinkContext extends RawMinkContext implements TranslatableContext
+{
+    /**
+     * Opens homepage
+     * Example: Given I am on "/"
+     * Example: When I go to "/"
+     * Example: And I go to "/"
+     *
+     * @Given /^(?:|I )am on (?:|the )homepage$/
+     * @When /^(?:|I )go to (?:|the )homepage$/
+     */
+    public function iAmOnHomepage()
+    {
+        $this->visitPath('/');
+    }
+
+    /**
+     * Opens specified page
+     * Example: Given I am on "http://batman.com"
+     * Example: And I am on "/articles/isBatmanBruceWayne"
+     * Example: When I go to "/articles/isBatmanBruceWayne"
+     *
+     * @Given /^(?:|I )am on "(?P<page>[^"]+)"$/
+     * @When /^(?:|I )go to "(?P<page>[^"]+)"$/
+     */
+    public function visit($page)
+    {
+        $this->visitPath($page);
+    }
+
+    /**
+     * Reloads current page
+     * Example: When I reload the page
+     * Example: And I reload the page
+     *
+     * @When /^(?:|I )reload the page$/
+     */
+    public function reload()
+    {
+        $this->getSession()->reload();
+    }
+
+    /**
+     * Moves backward one page in history
+     * Example: When I move backward one page
+     *
+     * @When /^(?:|I )move backward one page$/
+     */
+    public function back()
+    {
+        $this->getSession()->back();
+    }
+
+    /**
+     * Moves forward one page in history
+     * Example: And I move forward one page
+     *
+     * @When /^(?:|I )move forward one page$/
+     */
+    public function forward()
+    {
+        $this->getSession()->forward();
+    }
+
+    /**
+     * Presses button with specified id|name|title|alt|value
+     * Example: When I press "Log In"
+     * Example: And I press "Log In"
+     *
+     * @When /^(?:|I )press "(?P<button>(?:[^"]|\\")*)"$/
+     */
+    public function pressButton($button)
+    {
+        $button = $this->fixStepArgument($button);
+        $this->getSession()->getPage()->pressButton($button);
+    }
+
+    /**
+     * Clicks link with specified id|title|alt|text
+     * Example: When I follow "Log In"
+     * Example: And I follow "Log In"
+     *
+     * @When /^(?:|I )follow "(?P<link>(?:[^"]|\\")*)"$/
+     */
+    public function clickLink($link)
+    {
+        $link = $this->fixStepArgument($link);
+        $this->getSession()->getPage()->clickLink($link);
+    }
+
+    /**
+     * Fills in form field with specified id|name|label|value
+     * Example: When I fill in "username" with: "bwayne"
+     * Example: And I fill in "bwayne" for "username"
+     *
+     * @When /^(?:|I )fill in "(?P<field>(?:[^"]|\\")*)" with "(?P<value>(?:[^"]|\\")*)"$/
+     * @When /^(?:|I )fill in "(?P<field>(?:[^"]|\\")*)" with:$/
+     * @When /^(?:|I )fill in "(?P<value>(?:[^"]|\\")*)" for "(?P<field>(?:[^"]|\\")*)"$/
+     */
+    public function fillField($field, $value)
+    {
+        $field = $this->fixStepArgument($field);
+        $value = $this->fixStepArgument($value);
+        $this->getSession()->getPage()->fillField($field, $value);
+    }
+
+    /**
+     * Fills in form fields with provided table
+     * Example: When I fill in the following"
+     *              | username | bruceWayne |
+     *              | password | iLoveBats123 |
+     * Example: And I fill in the following"
+     *              | username | bruceWayne |
+     *              | password | iLoveBats123 |
+     *
+     * @When /^(?:|I )fill in the following:$/
+     */
+    public function fillFields(TableNode $fields)
+    {
+        foreach ($fields->getRowsHash() as $field => $value) {
+            $this->fillField($field, $value);
+        }
+    }
+
+    /**
+     * Selects option in select field with specified id|name|label|value
+     * Example: When I select "Bats" from "user_fears"
+     * Example: And I select "Bats" from "user_fears"
+     *
+     * @When /^(?:|I )select "(?P<option>(?:[^"]|\\")*)" from "(?P<select>(?:[^"]|\\")*)"$/
+     */
+    public function selectOption($select, $option)
+    {
+        $select = $this->fixStepArgument($select);
+        $option = $this->fixStepArgument($option);
+        $this->getSession()->getPage()->selectFieldOption($select, $option);
+    }
+
+    /**
+     * Selects additional option in select field with specified id|name|label|value
+     * Example: When I additionally select "Deceased" from "parents_alive_status"
+     * Example: And I additionally select "Deceased" from "parents_alive_status"
+     *
+     * @When /^(?:|I )additionally select "(?P<option>(?:[^"]|\\")*)" from "(?P<select>(?:[^"]|\\")*)"$/
+     */
+    public function additionallySelectOption($select, $option)
+    {
+        $select = $this->fixStepArgument($select);
+        $option = $this->fixStepArgument($option);
+        $this->getSession()->getPage()->selectFieldOption($select, $option, true);
+    }
+
+    /**
+     * Checks checkbox with specified id|name|label|value
+     * Example: When I check "Pearl Necklace" from "itemsClaimed"
+     * Example: And I check "Pearl Necklace" from "itemsClaimed"
+     *
+     * @When /^(?:|I )check "(?P<option>(?:[^"]|\\")*)"$/
+     */
+    public function checkOption($option)
+    {
+        $option = $this->fixStepArgument($option);
+        $this->getSession()->getPage()->checkField($option);
+    }
+
+    /**
+     * Unchecks checkbox with specified id|name|label|value
+     * Example: When I uncheck "Broadway Plays" from "hobbies"
+     * Example: And I uncheck "Broadway Plays" from "hobbies"
+     *
+     * @When /^(?:|I )uncheck "(?P<option>(?:[^"]|\\")*)"$/
+     */
+    public function uncheckOption($option)
+    {
+        $option = $this->fixStepArgument($option);
+        $this->getSession()->getPage()->uncheckField($option);
+    }
+
+    /**
+     * Attaches file to field with specified id|name|label|value
+     * Example: When I attach "bwayne_profile.png" to "profileImageUpload"
+     * Example: And I attach "bwayne_profile.png" to "profileImageUpload"
+     *
+     * @When /^(?:|I )attach the file "(?P<path>[^"]*)" to "(?P<field>(?:[^"]|\\")*)"$/
+     */
+    public function attachFileToField($field, $path)
+    {
+        $field = $this->fixStepArgument($field);
+
+        if ($this->getMinkParameter('files_path')) {
+            $fullPath = rtrim(realpath($this->getMinkParameter('files_path')), DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR.$path;
+            if (is_file($fullPath)) {
+                $path = $fullPath;
+            }
+        }
+
+        $this->getSession()->getPage()->attachFileToField($field, $path);
+    }
+
+    /**
+     * Checks, that current page PATH is equal to specified
+     * Example: Then I should be on "/"
+     * Example: And I should be on "/bats"
+     * Example: And I should be on "http://google.com"
+     *
+     * @Then /^(?:|I )should be on "(?P<page>[^"]+)"$/
+     */
+    public function assertPageAddress($page)
+    {
+        $this->assertSession()->addressEquals($this->locatePath($page));
+    }
+
+    /**
+     * Checks, that current page is the homepage
+     * Example: Then I should be on the homepage
+     * Example: And I should be on the homepage
+     *
+     * @Then /^(?:|I )should be on (?:|the )homepage$/
+     */
+    public function assertHomepage()
+    {
+        $this->assertSession()->addressEquals($this->locatePath('/'));
+    }
+
+    /**
+     * Checks, that current page PATH matches regular expression
+     * Example: Then the url should match "superman is dead"
+     * Example: Then the uri should match "log in"
+     * Example: And the url should match "log in"
+     *
+     * @Then /^the (?i)url(?-i) should match (?P<pattern>"(?:[^"]|\\")*")$/
+     */
+    public function assertUrlRegExp($pattern)
+    {
+        $this->assertSession()->addressMatches($this->fixStepArgument($pattern));
+    }
+
+    /**
+     * Checks, that current page response status is equal to specified
+     * Example: Then the response status code should be 200
+     * Example: And the response status code should be 400
+     *
+     * @Then /^the response status code should be (?P<code>\d+)$/
+     */
+    public function assertResponseStatus($code)
+    {
+        $this->assertSession()->statusCodeEquals($code);
+    }
+
+    /**
+     * Checks, that current page response status is not equal to specified
+     * Example: Then the response status code should not be 501
+     * Example: And the response status code should not be 404
+     *
+     * @Then /^the response status code should not be (?P<code>\d+)$/
+     */
+    public function assertResponseStatusIsNot($code)
+    {
+        $this->assertSession()->statusCodeNotEquals($code);
+    }
+
+    /**
+     * Checks, that page contains specified text
+     * Example: Then I should see "Who is the Batman?"
+     * Example: And I should see "Who is the Batman?"
+     *
+     * @Then /^(?:|I )should see "(?P<text>(?:[^"]|\\")*)"$/
+     */
+    public function assertPageContainsText($text)
+    {
+        $this->assertSession()->pageTextContains($this->fixStepArgument($text));
+    }
+
+    /**
+     * Checks, that page doesn't contain specified text
+     * Example: Then I should not see "Batman is Bruce Wayne"
+     * Example: And I should not see "Batman is Bruce Wayne"
+     *
+     * @Then /^(?:|I )should not see "(?P<text>(?:[^"]|\\")*)"$/
+     */
+    public function assertPageNotContainsText($text)
+    {
+        $this->assertSession()->pageTextNotContains($this->fixStepArgument($text));
+    }
+
+    /**
+     * Checks, that page contains text matching specified pattern
+     * Example: Then I should see text matching "Batman, the vigilante"
+     * Example: And I should not see "Batman, the vigilante"
+     *
+     * @Then /^(?:|I )should see text matching (?P<pattern>"(?:[^"]|\\")*")$/
+     */
+    public function assertPageMatchesText($pattern)
+    {
+        $this->assertSession()->pageTextMatches($this->fixStepArgument($pattern));
+    }
+
+    /**
+     * Checks, that page doesn't contain text matching specified pattern
+     * Example: Then I should see text matching "Bruce Wayne, the vigilante"
+     * Example: And I should not see "Bruce Wayne, the vigilante"
+     *
+     * @Then /^(?:|I )should not see text matching (?P<pattern>"(?:[^"]|\\")*")$/
+     */
+    public function assertPageNotMatchesText($pattern)
+    {
+        $this->assertSession()->pageTextNotMatches($this->fixStepArgument($pattern));
+    }
+
+    /**
+     * Checks, that HTML response contains specified string
+     * Example: Then the response should contain "Batman is the hero Gotham deserves."
+     * Example: And the response should contain "Batman is the hero Gotham deserves."
+     *
+     * @Then /^the response should contain "(?P<text>(?:[^"]|\\")*)"$/
+     */
+    public function assertResponseContains($text)
+    {
+        $this->assertSession()->responseContains($this->fixStepArgument($text));
+    }
+
+    /**
+     * Checks, that HTML response doesn't contain specified string
+     * Example: Then the response should not contain "Bruce Wayne is a billionaire, play-boy, vigilante."
+     * Example: And the response should not contain "Bruce Wayne is a billionaire, play-boy, vigilante."
+     *
+     * @Then /^the response should not contain "(?P<text>(?:[^"]|\\")*)"$/
+     */
+    public function assertResponseNotContains($text)
+    {
+        $this->assertSession()->responseNotContains($this->fixStepArgument($text));
+    }
+
+    /**
+     * Checks, that element with specified CSS contains specified text
+     * Example: Then I should see "Batman" in the "heroes_list" element
+     * Example: And I should see "Batman" in the "heroes_list" element
+     *
+     * @Then /^(?:|I )should see "(?P<text>(?:[^"]|\\")*)" in the "(?P<element>[^"]*)" element$/
+     */
+    public function assertElementContainsText($element, $text)
+    {
+        $this->assertSession()->elementTextContains('css', $element, $this->fixStepArgument($text));
+    }
+
+    /**
+     * Checks, that element with specified CSS doesn't contain specified text
+     * Example: Then I should not see "Bruce Wayne" in the "heroes_alter_egos" element
+     * Example: And I should not see "Bruce Wayne" in the "heroes_alter_egos" element
+     *
+     * @Then /^(?:|I )should not see "(?P<text>(?:[^"]|\\")*)" in the "(?P<element>[^"]*)" element$/
+     */
+    public function assertElementNotContainsText($element, $text)
+    {
+        $this->assertSession()->elementTextNotContains('css', $element, $this->fixStepArgument($text));
+    }
+
+    /**
+     * Checks, that element with specified CSS contains specified HTML
+     * Example: Then the "body" element should contain "style=\"color:black;\""
+     * Example: And the "body" element should contain "style=\"color:black;\""
+     *
+     * @Then /^the "(?P<element>[^"]*)" element should contain "(?P<value>(?:[^"]|\\")*)"$/
+     */
+    public function assertElementContains($element, $value)
+    {
+        $this->assertSession()->elementContains('css', $element, $this->fixStepArgument($value));
+    }
+
+    /**
+     * Checks, that element with specified CSS doesn't contain specified HTML
+     * Example: Then the "body" element should not contain "style=\"color:black;\""
+     * Example: And the "body" element should not contain "style=\"color:black;\""
+     *
+     * @Then /^the "(?P<element>[^"]*)" element should not contain "(?P<value>(?:[^"]|\\")*)"$/
+     */
+    public function assertElementNotContains($element, $value)
+    {
+        $this->assertSession()->elementNotContains('css', $element, $this->fixStepArgument($value));
+    }
+
+    /**
+     * Checks, that element with specified CSS exists on page
+     * Example: Then I should see a "body" element
+     * Example: And I should see a "body" element
+     *
+     * @Then /^(?:|I )should see an? "(?P<element>[^"]*)" element$/
+     */
+    public function assertElementOnPage($element)
+    {
+        $this->assertSession()->elementExists('css', $element);
+    }
+
+    /**
+     * Checks, that element with specified CSS doesn't exist on page
+     * Example: Then I should not see a "canvas" element
+     * Example: And I should not see a "canvas" element
+     *
+     * @Then /^(?:|I )should not see an? "(?P<element>[^"]*)" element$/
+     */
+    public function assertElementNotOnPage($element)
+    {
+        $this->assertSession()->elementNotExists('css', $element);
+    }
+
+    /**
+     * Checks, that form field with specified id|name|label|value has specified value
+     * Example: Then the "username" field should contain "bwayne"
+     * Example: And the "username" field should contain "bwayne"
+     *
+     * @Then /^the "(?P<field>(?:[^"]|\\")*)" field should contain "(?P<value>(?:[^"]|\\")*)"$/
+     */
+    public function assertFieldContains($field, $value)
+    {
+        $field = $this->fixStepArgument($field);
+        $value = $this->fixStepArgument($value);
+        $this->assertSession()->fieldValueEquals($field, $value);
+    }
+
+    /**
+     * Checks, that form field with specified id|name|label|value doesn't have specified value
+     * Example: Then the "username" field should not contain "batman"
+     * Example: And the "username" field should not contain "batman"
+     *
+     * @Then /^the "(?P<field>(?:[^"]|\\")*)" field should not contain "(?P<value>(?:[^"]|\\")*)"$/
+     */
+    public function assertFieldNotContains($field, $value)
+    {
+        $field = $this->fixStepArgument($field);
+        $value = $this->fixStepArgument($value);
+        $this->assertSession()->fieldValueNotEquals($field, $value);
+    }
+
+    /**
+     * Checks, that (?P<num>\d+) CSS elements exist on the page
+     * Example: Then I should see 5 "div" elements
+     * Example: And I should see 5 "div" elements
+     *
+     * @Then /^(?:|I )should see (?P<num>\d+) "(?P<element>[^"]*)" elements?$/
+     */
+    public function assertNumElements($num, $element)
+    {
+        $this->assertSession()->elementsCount('css', $element, intval($num));
+    }
+
+    /**
+     * Checks, that checkbox with specified in|name|label|value is checked
+     * Example: Then the "remember_me" checkbox should be checked
+     * Example: And the "remember_me" checkbox is checked
+     *
+     * @Then /^the "(?P<checkbox>(?:[^"]|\\")*)" checkbox should be checked$/
+     * @Then /^the checkbox "(?P<checkbox>(?:[^"]|\\")*)" (?:is|should be) checked$/
+     */
+    public function assertCheckboxChecked($checkbox)
+    {
+        $this->assertSession()->checkboxChecked($this->fixStepArgument($checkbox));
+    }
+
+    /**
+     * Checks, that checkbox with specified in|name|label|value is unchecked
+     * Example: Then the "newsletter" checkbox should be unchecked
+     * Example: Then the "newsletter" checkbox should not be checked
+     * Example: And the "newsletter" checkbox is unchecked
+     *
+     * @Then /^the "(?P<checkbox>(?:[^"]|\\")*)" checkbox should not be checked$/
+     * @Then /^the checkbox "(?P<checkbox>(?:[^"]|\\")*)" should (?:be unchecked|not be checked)$/
+     * @Then /^the checkbox "(?P<checkbox>(?:[^"]|\\")*)" is (?:unchecked|not checked)$/
+     */
+    public function assertCheckboxNotChecked($checkbox)
+    {
+        $this->assertSession()->checkboxNotChecked($this->fixStepArgument($checkbox));
+    }
+
+    /**
+     * Prints current URL to console.
+     * Example: Then print current URL
+     * Example: And print current URL
+     *
+     * @Then /^print current URL$/
+     */
+    public function printCurrentUrl()
+    {
+        echo $this->getSession()->getCurrentUrl();
+    }
+
+    /**
+     * Prints last response to console
+     * Example: Then print current response
+     * Example: And print current response
+     *
+     * @Then /^print last response$/
+     */
+    public function printLastResponse()
+    {
+        echo (
+            $this->getSession()->getCurrentUrl()."\n\n".
+            $this->getSession()->getPage()->getContent()
+        );
+    }
+
+    /**
+     * Opens last response content in browser
+     * Example: Then show last response
+     * Example: And show last response
+     *
+     * @Then /^show last response$/
+     */
+    public function showLastResponse()
+    {
+        if (null === $this->getMinkParameter('show_cmd')) {
+            throw new \RuntimeException('Set "show_cmd" parameter in behat.yml to be able to open page in browser (ex.: "show_cmd: firefox %s")');
+        }
+
+        $filename = rtrim($this->getMinkParameter('show_tmp_dir'), DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR.uniqid().'.html';
+        file_put_contents($filename, $this->getSession()->getPage()->getContent());
+        system(sprintf($this->getMinkParameter('show_cmd'), escapeshellarg($filename)));
+    }
+
+    /**
+     * Returns list of definition translation resources paths
+     *
+     * @return array
+     */
+    public static function getTranslationResources()
+    {
+        return self::getMinkTranslationResources();
+    }
+
+    /**
+     * Returns list of definition translation resources paths for this dictionary
+     *
+     * @return array
+     */
+    public static function getMinkTranslationResources()
+    {
+        return glob(__DIR__.'/../../../../i18n/*.xliff');
+    }
+
+    /**
+     * Returns fixed step argument (with \\" replaced back to ")
+     *
+     * @param string $argument
+     *
+     * @return string
+     */
+    protected function fixStepArgument($argument)
+    {
+        return str_replace('\\"', '"', $argument);
+    }
+}
diff --git a/vendor/behat/mink-extension/src/Behat/MinkExtension/Context/RawMinkContext.php b/vendor/behat/mink-extension/src/Behat/MinkExtension/Context/RawMinkContext.php
new file mode 100644 (file)
index 0000000..d07610e
--- /dev/null
@@ -0,0 +1,165 @@
+<?php
+
+/*
+ * This file is part of the Behat MinkExtension.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\MinkExtension\Context;
+
+use Behat\Mink\Mink;
+use Behat\Mink\WebAssert;
+use Behat\Mink\Session;
+
+/**
+ * Raw Mink context for Behat BDD tool.
+ * Provides raw Mink integration (without step definitions) and web assertions.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class RawMinkContext implements MinkAwareContext
+{
+    private $mink;
+    private $minkParameters;
+
+    /**
+     * Sets Mink instance.
+     *
+     * @param Mink $mink Mink session manager
+     */
+    public function setMink(Mink $mink)
+    {
+        $this->mink = $mink;
+    }
+
+    /**
+     * Returns Mink instance.
+     *
+     * @return Mink
+     */
+    public function getMink()
+    {
+        if (null === $this->mink) {
+            throw new \RuntimeException(
+                'Mink instance has not been set on Mink context class. ' . 
+                'Have you enabled the Mink Extension?'
+            );
+        }
+
+        return $this->mink;
+    }
+
+    /**
+     * Returns the parameters provided for Mink.
+     *
+     * @return array
+     */
+    public function getMinkParameters()
+    {
+        return $this->minkParameters;
+    }
+
+    /**
+     * Sets parameters provided for Mink.
+     *
+     * @param array $parameters
+     */
+    public function setMinkParameters(array $parameters)
+    {
+        $this->minkParameters = $parameters;
+    }
+
+    /**
+     * Returns specific mink parameter.
+     *
+     * @param string $name
+     *
+     * @return mixed
+     */
+    public function getMinkParameter($name)
+    {
+        return isset($this->minkParameters[$name]) ? $this->minkParameters[$name] : null;
+    }
+
+    /**
+     * Applies the given parameter to the Mink configuration. Consider that all parameters get reset for each
+     * feature context.
+     *
+     * @param string $name  The key of the parameter
+     * @param string $value The value of the parameter
+     */
+    public function setMinkParameter($name, $value)
+    {
+        $this->minkParameters[$name] = $value;
+    }
+
+    /**
+     * Returns Mink session.
+     *
+     * @param string|null $name name of the session OR active session will be used
+     *
+     * @return Session
+     */
+    public function getSession($name = null)
+    {
+        return $this->getMink()->getSession($name);
+    }
+
+    /**
+     * Returns Mink session assertion tool.
+     *
+     * @param string|null $name name of the session OR active session will be used
+     *
+     * @return WebAssert
+     */
+    public function assertSession($name = null)
+    {
+        return $this->getMink()->assertSession($name);
+    }
+
+    /**
+     * Visits provided relative path using provided or default session.
+     *
+     * @param string      $path
+     * @param string|null $sessionName
+     */
+    public function visitPath($path, $sessionName = null)
+    {
+        $this->getSession($sessionName)->visit($this->locatePath($path));
+    }
+
+    /**
+     * Locates url, based on provided path.
+     * Override to provide custom routing mechanism.
+     *
+     * @param string $path
+     *
+     * @return string
+     */
+    public function locatePath($path)
+    {
+        $startUrl = rtrim($this->getMinkParameter('base_url'), '/') . '/';
+
+        return 0 !== strpos($path, 'http') ? $startUrl . ltrim($path, '/') : $path;
+    }
+
+    /**
+     * Save a screenshot of the current window to the file system.
+     *
+     * @param string $filename Desired filename, defaults to
+     *                         <browser_name>_<ISO 8601 date>_<randomId>.png
+     * @param string $filepath Desired filepath, defaults to
+     *                         upload_tmp_dir, falls back to sys_get_temp_dir()
+     */
+    public function saveScreenshot($filename = null, $filepath = null)
+    {
+        // Under Cygwin, uniqid with more_entropy must be set to true.
+        // No effect in other environments.
+        $filename = $filename ?: sprintf('%s_%s_%s.%s', $this->getMinkParameter('browser_name'), date('c'), uniqid('', true), 'png');
+        $filepath = $filepath ? $filepath : (ini_get('upload_tmp_dir') ? ini_get('upload_tmp_dir') : sys_get_temp_dir());
+        file_put_contents($filepath . '/' . $filename, $this->getSession()->getScreenshot());
+    }
+}
diff --git a/vendor/behat/mink-extension/src/Behat/MinkExtension/Listener/FailureShowListener.php b/vendor/behat/mink-extension/src/Behat/MinkExtension/Listener/FailureShowListener.php
new file mode 100644 (file)
index 0000000..3e8a0d3
--- /dev/null
@@ -0,0 +1,86 @@
+<?php
+
+/*
+ * This file is part of the Behat MinkExtension.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\MinkExtension\Listener;
+
+use Behat\Behat\EventDispatcher\Event\AfterStepTested;
+use Behat\Behat\EventDispatcher\Event\StepTested;
+use Behat\Testwork\Tester\Result\ExceptionResult;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+use Behat\Mink\Mink;
+use Behat\Mink\Exception\Exception as MinkException;
+
+/**
+ * Failed step response show listener.
+ * Listens to failed Behat steps and shows last response in a browser.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class FailureShowListener implements EventSubscriberInterface
+{
+    private $mink;
+    private $parameters;
+
+    /**
+     * Initializes initializer.
+     *
+     * @param Mink  $mink
+     * @param array $parameters
+     */
+    public function __construct(Mink $mink, array $parameters)
+    {
+        $this->mink       = $mink;
+        $this->parameters = $parameters;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public static function getSubscribedEvents()
+    {
+        return array(
+            StepTested::AFTER => array('showFailedStepResponse', -10)
+        );
+    }
+
+    /**
+     * Shows last response of failed step with preconfigured command.
+     *
+     * Configuration is based on `behat.yml`:
+     *
+     * `show_auto` enable this listener (default to false)
+     * `show_cmd` command to run (`open %s` to open default browser on Mac)
+     * `show_tmp_dir` folder where to store temp files (default is system temp)
+     *
+     * @param AfterStepTested $event
+     *
+     * @throws \RuntimeException if show_cmd is not configured
+     */
+    public function showFailedStepResponse(AfterStepTested $event)
+    {
+        $testResult = $event->getTestResult();
+
+        if (!$testResult instanceof ExceptionResult) {
+            return;
+        }
+
+        if (!$testResult->getException() instanceof MinkException) {
+            return;
+        }
+
+        if (null === $this->parameters['show_cmd']) {
+            throw new \RuntimeException('Set "show_cmd" parameter in behat.yml to be able to open page in browser (ex.: "show_cmd: open %s")');
+        }
+
+        $filename = rtrim($this->parameters['show_tmp_dir'], DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR.uniqid().'.html';
+        file_put_contents($filename, $this->mink->getSession()->getPage()->getContent());
+        system(sprintf($this->parameters['show_cmd'], escapeshellarg($filename)));
+    }
+}
diff --git a/vendor/behat/mink-extension/src/Behat/MinkExtension/Listener/SessionsListener.php b/vendor/behat/mink-extension/src/Behat/MinkExtension/Listener/SessionsListener.php
new file mode 100644 (file)
index 0000000..7a18cc9
--- /dev/null
@@ -0,0 +1,177 @@
+<?php
+
+/*
+ * This file is part of the Behat MinkExtension.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\MinkExtension\Listener;
+
+use Behat\Behat\EventDispatcher\Event\ExampleTested;
+use Behat\Behat\EventDispatcher\Event\ScenarioLikeTested;
+use Behat\Behat\EventDispatcher\Event\ScenarioTested;
+use Behat\Mink\Mink;
+use Behat\Testwork\EventDispatcher\Event\ExerciseCompleted;
+use Behat\Testwork\ServiceContainer\Exception\ProcessingException;
+use Behat\Testwork\Suite\Exception\SuiteConfigurationException;
+use Behat\Testwork\Suite\Suite;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+
+/**
+ * Mink sessions listener.
+ * Listens Behat events and configures/stops Mink sessions.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class SessionsListener implements EventSubscriberInterface
+{
+    private $mink;
+    private $defaultSession;
+    private $javascriptSession;
+
+    /**
+     * @var string[] The available javascript sessions
+     */
+    private $availableJavascriptSessions;
+
+    /**
+     * Initializes initializer.
+     *
+     * @param Mink        $mink
+     * @param string      $defaultSession
+     * @param string|null $javascriptSession
+     * @param string[]    $availableJavascriptSessions
+     */
+    public function __construct(Mink $mink, $defaultSession, $javascriptSession, array $availableJavascriptSessions = array())
+    {
+        $this->mink              = $mink;
+        $this->defaultSession    = $defaultSession;
+        $this->javascriptSession = $javascriptSession;
+        $this->availableJavascriptSessions = $availableJavascriptSessions;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public static function getSubscribedEvents()
+    {
+        return array(
+            ScenarioTested::BEFORE   => array('prepareDefaultMinkSession', 10),
+            ExampleTested::BEFORE    => array('prepareDefaultMinkSession', 10),
+            ExerciseCompleted::AFTER => array('tearDownMinkSessions', -10)
+        );
+    }
+
+    /**
+     * Configures default Mink session before each scenario.
+     * Configuration is based on provided scenario tags:
+     *
+     * `@javascript` tagged scenarios will get `javascript_session` as default session
+     * `@mink:CUSTOM_NAME tagged scenarios will get `CUSTOM_NAME` as default session
+     * Other scenarios get `default_session` as default session
+     *
+     * `@insulated` tag will cause Mink to stop current sessions before scenario
+     * instead of just soft-resetting them
+     *
+     * @param ScenarioLikeTested $event
+     *
+     * @throws ProcessingException when the @javascript tag is used without a javascript session
+     */
+    public function prepareDefaultMinkSession(ScenarioLikeTested $event)
+    {
+        $scenario = $event->getScenario();
+        $feature  = $event->getFeature();
+        $session  = null;
+
+        foreach (array_merge($feature->getTags(), $scenario->getTags()) as $tag) {
+            if ('javascript' === $tag) {
+                $session = $this->getJavascriptSession($event->getSuite());
+            } elseif (preg_match('/^mink\:(.+)/', $tag, $matches)) {
+                $session = $matches[1];
+            }
+        }
+
+        if (null === $session) {
+            $session = $this->getDefaultSession($event->getSuite());
+        }
+
+        if ($scenario->hasTag('insulated') || $feature->hasTag('insulated')) {
+            $this->mink->stopSessions();
+        } else {
+            $this->mink->resetSessions();
+        }
+
+        $this->mink->setDefaultSessionName($session);
+    }
+
+    /**
+     * Stops all started Mink sessions.
+     */
+    public function tearDownMinkSessions()
+    {
+        $this->mink->stopSessions();
+    }
+
+    private function getDefaultSession(Suite $suite)
+    {
+        if (!$suite->hasSetting('mink_session')) {
+            return $this->defaultSession;
+        }
+
+        $session = $suite->getSetting('mink_session');
+
+        if (!is_string($session)) {
+            throw new SuiteConfigurationException(
+                sprintf(
+                    '`mink_session` setting of the "%s" suite is expected to be a string, %s given.',
+                    $suite->getName(),
+                    gettype($session)
+                ),
+                $suite->getName()
+            );
+        }
+
+        return $session;
+    }
+
+    private function getJavascriptSession(Suite $suite)
+    {
+        if (!$suite->hasSetting('mink_javascript_session')) {
+            if (null === $this->javascriptSession) {
+                throw new ProcessingException('The @javascript tag cannot be used without enabling a javascript session');
+            }
+
+            return $this->javascriptSession;
+        }
+
+        $session = $suite->getSetting('mink_javascript_session');
+
+        if (!is_string($session)) {
+            throw new SuiteConfigurationException(
+                sprintf(
+                    '`mink_javascript_session` setting of the "%s" suite is expected to be a string, %s given.',
+                    $suite->getName(),
+                    gettype($session)
+                ),
+                $suite->getName()
+            );
+        }
+
+        if (!in_array($session, $this->availableJavascriptSessions)) {
+            throw new SuiteConfigurationException(
+                sprintf(
+                    '`mink_javascript_session` setting of the "%s" suite is not a javascript session. %s given but expected one of %s.',
+                    $suite->getName(),
+                    $session,
+                    implode(', ', $this->availableJavascriptSessions)
+                ),
+                $suite->getName()
+            );
+        }
+
+        return $session;
+    }
+}
diff --git a/vendor/behat/mink-extension/src/Behat/MinkExtension/ServiceContainer/Driver/BrowserStackFactory.php b/vendor/behat/mink-extension/src/Behat/MinkExtension/ServiceContainer/Driver/BrowserStackFactory.php
new file mode 100644 (file)
index 0000000..abf16b1
--- /dev/null
@@ -0,0 +1,70 @@
+<?php
+
+/*
+ * This file is part of the Behat MinkExtension.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\MinkExtension\ServiceContainer\Driver;
+
+use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
+
+class BrowserStackFactory extends Selenium2Factory
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function getDriverName()
+    {
+        return 'browser_stack';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function configure(ArrayNodeDefinition $builder)
+    {
+        $builder
+            ->children()
+                ->scalarNode('username')->defaultValue(getenv('BROWSERSTACK_USERNAME'))->end()
+                ->scalarNode('access_key')->defaultValue(getenv('BROWSERSTACK_ACCESS_KEY'))->end()
+                ->scalarNode('browser')->defaultValue('firefox')->end()
+                ->append($this->getCapabilitiesNode())
+            ->end()
+        ;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function buildDriver(array $config)
+    {
+        $config['wd_host'] = sprintf('%s:%s@hub.browserstack.com/wd/hub', $config['username'], $config['access_key']);
+
+        return parent::buildDriver($config);
+    }
+
+    protected function getCapabilitiesNode()
+    {
+        $node = parent::getCapabilitiesNode();
+
+        $node
+            ->children()
+                ->scalarNode('project')->end()
+                ->scalarNode('resolution')->end()
+                ->scalarNode('build')->info('will be set automatically based on the TRAVIS_JOB_NUMBER environment variable if available')->end()
+                ->scalarNode('os')->end()
+                ->scalarNode('os_version')->end()
+                ->scalarNode('device')->end()
+                ->booleanNode('browserstack-debug')->end()
+                ->booleanNode('browserstack-tunnel')->end()
+                ->booleanNode('emulator')->end()
+            ->end()
+        ;
+
+        return $node;
+    }
+}
diff --git a/vendor/behat/mink-extension/src/Behat/MinkExtension/ServiceContainer/Driver/DriverFactory.php b/vendor/behat/mink-extension/src/Behat/MinkExtension/ServiceContainer/Driver/DriverFactory.php
new file mode 100644 (file)
index 0000000..b2adf83
--- /dev/null
@@ -0,0 +1,52 @@
+<?php
+
+/*
+ * This file is part of the Behat MinkExtension.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\MinkExtension\ServiceContainer\Driver;
+
+use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
+use Symfony\Component\DependencyInjection\Definition;
+
+/**
+ * @author Christophe Coevoet <stof@notk.org>
+ */
+interface DriverFactory
+{
+    /**
+     * Gets the name of the driver being configured.
+     *
+     * This will be the key of the configuration for the driver.
+     *
+     * @return string
+     */
+    public function getDriverName();
+
+    /**
+     * Defines whether a session using this driver is eligible as default javascript session
+     *
+     * @return boolean
+     */
+    public function supportsJavascript();
+
+    /**
+     * Setups configuration for the driver factory.
+     *
+     * @param ArrayNodeDefinition $builder
+     */
+    public function configure(ArrayNodeDefinition $builder);
+
+    /**
+     * Builds the service definition for the driver.
+     *
+     * @param array $config
+     *
+     * @return Definition
+     */
+    public function buildDriver(array $config);
+}
diff --git a/vendor/behat/mink-extension/src/Behat/MinkExtension/ServiceContainer/Driver/GoutteFactory.php b/vendor/behat/mink-extension/src/Behat/MinkExtension/ServiceContainer/Driver/GoutteFactory.php
new file mode 100644 (file)
index 0000000..2bb3416
--- /dev/null
@@ -0,0 +1,115 @@
+<?php
+
+/*
+ * This file is part of the Behat MinkExtension.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\MinkExtension\ServiceContainer\Driver;
+
+use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
+use Symfony\Component\DependencyInjection\Definition;
+
+/**
+ * @author Christophe Coevoet <stof@notk.org>
+ */
+class GoutteFactory implements DriverFactory
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function getDriverName()
+    {
+        return 'goutte';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function supportsJavascript()
+    {
+        return false;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function configure(ArrayNodeDefinition $builder)
+    {
+        $builder
+            ->children()
+                ->arrayNode('server_parameters')
+                    ->useAttributeAsKey('key')
+                    ->prototype('variable')->end()
+                ->end()
+                ->arrayNode('guzzle_parameters')
+                    ->useAttributeAsKey('key')
+                    ->prototype('variable')->end()
+                    ->info(
+                        "For Goutte 1.x, these are the second argument of the Guzzle3 client constructor.\n".
+                        'For Goutte 2.x, these are the elements passed in the "defaults" key of the Guzzle4 config.'
+                    )
+                ->end()
+            ->end()
+        ;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function buildDriver(array $config)
+    {
+        if (!class_exists('Behat\Mink\Driver\GoutteDriver')) {
+            throw new \RuntimeException(
+                'Install MinkGoutteDriver in order to use goutte driver.'
+            );
+        }
+
+        if ($this->isGoutte1()) {
+            $guzzleClient = $this->buildGuzzle3Client($config['guzzle_parameters']);
+        } else {
+            $guzzleClient = $this->buildGuzzle4Client($config['guzzle_parameters']);
+        }
+
+        $clientDefinition = new Definition('Behat\Mink\Driver\Goutte\Client', array(
+            $config['server_parameters'],
+        ));
+        $clientDefinition->addMethodCall('setClient', array($guzzleClient));
+
+        return new Definition('Behat\Mink\Driver\GoutteDriver', array(
+            $clientDefinition,
+        ));
+    }
+
+    private function buildGuzzle4Client(array $parameters)
+    {
+        // Force the parameters set by default in Goutte to reproduce its behavior
+        $parameters['allow_redirects'] = false;
+        $parameters['cookies'] = true;
+
+        return new Definition('GuzzleHttp\Client', array($parameters));
+
+    }
+
+    private function buildGuzzle3Client(array $parameters)
+    {
+        // Force the parameters set by default in Goutte to reproduce its behavior
+        $parameters['redirect.disable'] = true;
+
+        return new Definition('Guzzle\Http\Client', array(null, $parameters));
+    }
+
+    private function isGoutte1()
+    {
+        $refl = new \ReflectionParameter(array('Goutte\Client', 'setClient'), 0);
+
+        if ($refl->getClass() && 'Guzzle\Http\ClientInterface' === $refl->getClass()->getName()) {
+            return true;
+        }
+
+        return false;
+    }
+}
diff --git a/vendor/behat/mink-extension/src/Behat/MinkExtension/ServiceContainer/Driver/SahiFactory.php b/vendor/behat/mink-extension/src/Behat/MinkExtension/ServiceContainer/Driver/SahiFactory.php
new file mode 100644 (file)
index 0000000..860f3cf
--- /dev/null
@@ -0,0 +1,74 @@
+<?php
+
+/*
+ * This file is part of the Behat MinkExtension.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\MinkExtension\ServiceContainer\Driver;
+
+use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
+use Symfony\Component\DependencyInjection\Definition;
+
+class SahiFactory implements DriverFactory
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function getDriverName()
+    {
+        return 'sahi';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function supportsJavascript()
+    {
+        return true;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function configure(ArrayNodeDefinition $builder)
+    {
+        $builder
+            ->children()
+                ->scalarNode('sid')->defaultNull()->end()
+                ->scalarNode('host')->defaultValue('localhost')->end()
+                ->scalarNode('port')->defaultValue(9999)->end()
+                ->scalarNode('browser')->defaultNull()->end()
+                ->scalarNode('limit')->defaultValue(600)->end()
+            ->end()
+        ;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function buildDriver(array $config)
+    {
+        if (!class_exists('Behat\Mink\Driver\SahiDriver')) {
+            throw new \RuntimeException(
+                'Install MinkSahiDriver in order to use sahi driver.'
+            );
+        }
+
+        return new Definition('Behat\Mink\Driver\SahiDriver', array(
+            '%mink.browser_name%',
+            new Definition('Behat\SahiClient\Client', array(
+                new Definition('Behat\SahiClient\Connection', array(
+                    $config['sid'],
+                    $config['host'],
+                    $config['port'],
+                    $config['browser'],
+                    $config['limit'],
+                )),
+            )),
+        ));
+    }
+}
diff --git a/vendor/behat/mink-extension/src/Behat/MinkExtension/ServiceContainer/Driver/SauceLabsFactory.php b/vendor/behat/mink-extension/src/Behat/MinkExtension/ServiceContainer/Driver/SauceLabsFactory.php
new file mode 100644 (file)
index 0000000..ee436a5
--- /dev/null
@@ -0,0 +1,98 @@
+<?php
+
+/*
+ * This file is part of the Behat MinkExtension.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\MinkExtension\ServiceContainer\Driver;
+
+use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
+
+class SauceLabsFactory extends Selenium2Factory
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function getDriverName()
+    {
+        return 'sauce_labs';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function configure(ArrayNodeDefinition $builder)
+    {
+        $builder
+            ->children()
+                ->scalarNode('username')->defaultValue(getenv('SAUCE_USERNAME'))->end()
+                ->scalarNode('access_key')->defaultValue(getenv('SAUCE_ACCESS_KEY'))->end()
+                ->booleanNode('connect')->defaultFalse()->end()
+                ->scalarNode('browser')->defaultValue('firefox')->end()
+                ->append($this->getCapabilitiesNode())
+            ->end()
+        ;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function buildDriver(array $config)
+    {
+        $host = 'ondemand.saucelabs.com';
+        if ($config['connect']) {
+            $host = 'localhost:4445';
+        }
+
+        $config['wd_host'] = sprintf('%s:%s@%s/wd/hub', $config['username'], $config['access_key'], $host);
+
+        return parent::buildDriver($config);
+    }
+
+    protected function getCapabilitiesNode()
+    {
+        $node = parent::getCapabilitiesNode();
+
+        $node
+            ->children()
+                ->scalarNode('platform')->defaultValue('Linux')->end()
+                ->scalarNode('selenium-version')->end()
+                ->scalarNode('max-duration')->end()
+                ->scalarNode('command-timeout')->end()
+                ->scalarNode('idle-timeout')->end()
+                ->scalarNode('build')->info('will be set automatically based on the TRAVIS_BUILD_NUMBER environment variable if available')->end()
+                ->arrayNode('custom-data')
+                    ->useAttributeAsKey('')
+                    ->prototype('variable')->end()
+                ->end()
+                ->scalarNode('screen-resolution')->end()
+                ->scalarNode('tunnel-identifier')->info('will be set automatically based on the TRAVIS_JOB_NUMBER environment variable if available')->end()
+                ->arrayNode('prerun')
+                    ->children()
+                        ->scalarNode('executable')->isRequired()->end()
+                        ->arrayNode('args')->prototype('scalar')->end()->end()
+                        ->booleanNode('background')->defaultFalse()->end()
+                    ->end()
+                ->end()
+                ->booleanNode('record-video')->end()
+                ->booleanNode('record-screenshots')->end()
+                ->booleanNode('capture-html')->end()
+                ->booleanNode('disable-popup-handler')->end()
+            ->end()
+            ->validate()
+                ->ifTrue(function ($v) {return empty($v['custom-data']);})
+                ->then(function ($v) {
+                    unset ($v['custom-data']);
+
+                    return $v;
+                })
+            ->end()
+        ;
+
+        return $node;
+    }
+}
diff --git a/vendor/behat/mink-extension/src/Behat/MinkExtension/ServiceContainer/Driver/Selenium2Factory.php b/vendor/behat/mink-extension/src/Behat/MinkExtension/ServiceContainer/Driver/Selenium2Factory.php
new file mode 100644 (file)
index 0000000..ee3c528
--- /dev/null
@@ -0,0 +1,159 @@
+<?php
+
+/*
+ * This file is part of the Behat MinkExtension.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\MinkExtension\ServiceContainer\Driver;
+
+use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
+use Symfony\Component\DependencyInjection\Definition;
+
+class Selenium2Factory implements DriverFactory
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function getDriverName()
+    {
+        return 'selenium2';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function supportsJavascript()
+    {
+        return true;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function configure(ArrayNodeDefinition $builder)
+    {
+        $builder
+            ->children()
+                ->scalarNode('browser')->defaultValue('%mink.browser_name%')->end()
+                ->append($this->getCapabilitiesNode())
+                ->scalarNode('wd_host')->defaultValue('http://localhost:4444/wd/hub')->end()
+            ->end()
+        ;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function buildDriver(array $config)
+    {
+        if (!class_exists('Behat\Mink\Driver\Selenium2Driver')) {
+            throw new \RuntimeException(sprintf(
+                'Install MinkSelenium2Driver in order to use %s driver.',
+                $this->getDriverName()
+            ));
+        }
+
+        $extraCapabilities = $config['capabilities']['extra_capabilities'];
+        unset($config['capabilities']['extra_capabilities']);
+
+        if (getenv('TRAVIS_JOB_NUMBER')) {
+            $guessedCapabilities = array(
+                'tunnel-identifier' => getenv('TRAVIS_JOB_NUMBER'),
+                'build' => getenv('TRAVIS_BUILD_NUMBER'),
+                'tags' => array('Travis-CI', 'PHP '.phpversion()),
+            );
+        } elseif (getenv('JENKINS_HOME')) {
+            $guessedCapabilities = array(
+                'tunnel-identifier' => getenv('JOB_NAME'),
+                'build' => getenv('BUILD_NUMBER'),
+                'tags' => array('Jenkins', 'PHP '.phpversion(), getenv('BUILD_TAG')),
+            );
+        } else {
+            $guessedCapabilities = array(
+                'tags' => array(php_uname('n'), 'PHP '.phpversion()),
+            );
+        }
+
+        return new Definition('Behat\Mink\Driver\Selenium2Driver', array(
+            $config['browser'],
+            array_replace($guessedCapabilities, $extraCapabilities, $config['capabilities']),
+            $config['wd_host'],
+        ));
+    }
+
+    protected function getCapabilitiesNode()
+    {
+        $node = new ArrayNodeDefinition('capabilities');
+
+        $node
+            ->addDefaultsIfNotSet()
+            ->normalizeKeys(false)
+            ->children()
+                ->scalarNode('browserName')->end()
+                ->scalarNode('version')->end()
+                ->scalarNode('platform')->end()
+                ->scalarNode('browserVersion')->end()
+                ->scalarNode('browser')->defaultValue('firefox')->end()
+                ->booleanNode('ignoreZoomSetting')->defaultFalse()->end()
+                ->scalarNode('name')->defaultValue('Behat feature suite')->end()
+                ->scalarNode('deviceOrientation')->end()
+                ->scalarNode('deviceType')->end()
+                ->booleanNode('javascriptEnabled')->end()
+                ->booleanNode('databaseEnabled')->end()
+                ->booleanNode('locationContextEnabled')->end()
+                ->booleanNode('applicationCacheEnabled')->end()
+                ->booleanNode('browserConnectionEnabled')->end()
+                ->booleanNode('webStorageEnabled')->end()
+                ->booleanNode('rotatable')->end()
+                ->booleanNode('acceptSslCerts')->end()
+                ->booleanNode('nativeEvents')->end()
+                ->arrayNode('proxy')
+                    ->children()
+                        ->scalarNode('proxyType')->end()
+                        ->scalarNode('proxyAuthconfigUrl')->end()
+                        ->scalarNode('ftpProxy')->end()
+                        ->scalarNode('httpProxy')->end()
+                        ->scalarNode('sslProxy')->end()
+                    ->end()
+                    ->validate()
+                        ->ifTrue(function ($v) {
+                            return empty($v);
+                        })
+                        ->thenUnset()
+                    ->end()
+                ->end()
+                ->arrayNode('firefox')
+                    ->children()
+                        ->scalarNode('profile')
+                            ->validate()
+                                ->ifTrue(function ($v) {
+                                    return !file_exists($v);
+                                })
+                                ->thenInvalid('Cannot find profile zip file %s')
+                            ->end()
+                        ->end()
+                        ->scalarNode('binary')->end()
+                    ->end()
+                ->end()
+                ->arrayNode('chrome')
+                    ->children()
+                        ->arrayNode('switches')->prototype('scalar')->end()->end()
+                        ->scalarNode('binary')->end()
+                        ->arrayNode('extensions')->prototype('scalar')->end()->end()
+                    ->end()
+                ->end()
+                ->arrayNode('extra_capabilities')
+                    ->info('Custom capabilities merged with the known ones')
+                    ->normalizeKeys(false)
+                    ->useAttributeAsKey('name')
+                    ->prototype('variable')->end()
+                ->end()
+            ->end();
+
+        return $node;
+    }
+}
diff --git a/vendor/behat/mink-extension/src/Behat/MinkExtension/ServiceContainer/Driver/SeleniumFactory.php b/vendor/behat/mink-extension/src/Behat/MinkExtension/ServiceContainer/Driver/SeleniumFactory.php
new file mode 100644 (file)
index 0000000..03fb9a5
--- /dev/null
@@ -0,0 +1,68 @@
+<?php
+
+/*
+ * This file is part of the Behat MinkExtension.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\MinkExtension\ServiceContainer\Driver;
+
+use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
+use Symfony\Component\DependencyInjection\Definition;
+
+class SeleniumFactory implements DriverFactory
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function getDriverName()
+    {
+        return 'selenium';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function supportsJavascript()
+    {
+        return true;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function configure(ArrayNodeDefinition $builder)
+    {
+        $builder
+            ->children()
+                ->scalarNode('host')->defaultValue('127.0.0.1')->end()
+                ->scalarNode('port')->defaultValue(4444)->end()
+                ->scalarNode('browser')->defaultValue('*%mink.browser_name%')->end()
+            ->end()
+        ;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function buildDriver(array $config)
+    {
+        if (!class_exists('Behat\Mink\Driver\SeleniumDriver')) {
+            throw new \RuntimeException(
+                'Install MinkSeleniumDriver in order to activate selenium session.'
+            );
+        }
+
+        return new Definition('Behat\Mink\Driver\SeleniumDriver', array(
+            $config['browser'],
+            '%mink.base_url%',
+            new Definition('Selenium\Client', array(
+                $config['host'],
+                $config['port'],
+            )),
+        ));
+    }
+}
diff --git a/vendor/behat/mink-extension/src/Behat/MinkExtension/ServiceContainer/Driver/ZombieFactory.php b/vendor/behat/mink-extension/src/Behat/MinkExtension/ServiceContainer/Driver/ZombieFactory.php
new file mode 100644 (file)
index 0000000..9bafc84
--- /dev/null
@@ -0,0 +1,73 @@
+<?php
+
+/*
+ * This file is part of the Behat MinkExtension.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\MinkExtension\ServiceContainer\Driver;
+
+use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
+use Symfony\Component\DependencyInjection\Definition;
+
+class ZombieFactory implements DriverFactory
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function getDriverName()
+    {
+        return 'zombie';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function supportsJavascript()
+    {
+        return true;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function configure(ArrayNodeDefinition $builder)
+    {
+        $builder
+            ->children()
+                ->scalarNode('host')->defaultValue('127.0.0.1')->end()
+                ->scalarNode('port')->defaultValue(8124)->end()
+                ->scalarNode('node_bin')->defaultValue('node')->end()
+                ->scalarNode('server_path')->defaultNull()->end()
+                ->scalarNode('threshold')->defaultValue(2000000)->end()
+                ->scalarNode('node_modules_path')->defaultValue('')->end()
+            ->end()
+        ;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function buildDriver(array $config)
+    {
+        if (!class_exists('Behat\Mink\Driver\ZombieDriver')) {
+            throw new \RuntimeException(
+                'Install MinkZombieDriver in order to use zombie driver.'
+            );
+        }
+
+        return new Definition('Behat\Mink\Driver\ZombieDriver', array(
+            new Definition('Behat\Mink\Driver\NodeJS\Server\ZombieServer', array(
+                $config['host'],
+                $config['port'],
+                $config['node_bin'],
+                $config['server_path'],
+                $config['threshold'],
+                $config['node_modules_path'],
+            )),
+        ));
+    }
+}
diff --git a/vendor/behat/mink-extension/src/Behat/MinkExtension/ServiceContainer/MinkExtension.php b/vendor/behat/mink-extension/src/Behat/MinkExtension/ServiceContainer/MinkExtension.php
new file mode 100644 (file)
index 0000000..aac4831
--- /dev/null
@@ -0,0 +1,305 @@
+<?php
+
+/*
+ * This file is part of the Behat MinkExtension.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\MinkExtension\ServiceContainer;
+
+use Behat\Behat\Context\ServiceContainer\ContextExtension;
+use Behat\MinkExtension\ServiceContainer\Driver\BrowserStackFactory;
+use Behat\MinkExtension\ServiceContainer\Driver\DriverFactory;
+use Behat\MinkExtension\ServiceContainer\Driver\GoutteFactory;
+use Behat\MinkExtension\ServiceContainer\Driver\SahiFactory;
+use Behat\MinkExtension\ServiceContainer\Driver\SauceLabsFactory;
+use Behat\MinkExtension\ServiceContainer\Driver\Selenium2Factory;
+use Behat\MinkExtension\ServiceContainer\Driver\SeleniumFactory;
+use Behat\MinkExtension\ServiceContainer\Driver\ZombieFactory;
+use Behat\Testwork\EventDispatcher\ServiceContainer\EventDispatcherExtension;
+use Behat\Testwork\ServiceContainer\Exception\ProcessingException;
+use Behat\Testwork\ServiceContainer\Extension as ExtensionInterface;
+use Behat\Testwork\ServiceContainer\ExtensionManager;
+use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
+use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Definition;
+use Symfony\Component\DependencyInjection\Reference;
+
+/**
+ * Mink extension for Behat class.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ * @author Christophe Coevoet <stof@notk.org>
+ */
+class MinkExtension implements ExtensionInterface
+{
+    const MINK_ID = 'mink';
+    const SELECTORS_HANDLER_ID = 'mink.selectors_handler';
+
+    const SELECTOR_TAG = 'mink.selector';
+
+    /**
+     * @var DriverFactory[]
+     */
+    private $driverFactories = array();
+
+    public function __construct()
+    {
+        $this->registerDriverFactory(new GoutteFactory());
+        $this->registerDriverFactory(new SahiFactory());
+        $this->registerDriverFactory(new SeleniumFactory());
+        $this->registerDriverFactory(new Selenium2Factory());
+        $this->registerDriverFactory(new SauceLabsFactory());
+        $this->registerDriverFactory(new BrowserStackFactory());
+        $this->registerDriverFactory(new ZombieFactory());
+    }
+
+    public function registerDriverFactory(DriverFactory $driverFactory)
+    {
+        $this->driverFactories[$driverFactory->getDriverName()] = $driverFactory;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function load(ContainerBuilder $container, array $config)
+    {
+        if (isset($config['mink_loader'])) {
+            $basePath = $container->getParameter('paths.base');
+
+            if (file_exists($basePath.DIRECTORY_SEPARATOR.$config['mink_loader'])) {
+                require($basePath.DIRECTORY_SEPARATOR.$config['mink_loader']);
+            } else {
+                require($config['mink_loader']);
+            }
+        }
+
+        $this->loadMink($container);
+        $this->loadContextInitializer($container);
+        $this->loadSelectorsHandler($container);
+        $this->loadSessions($container, $config);
+        $this->loadSessionsListener($container);
+
+        if ($config['show_auto']) {
+            $this->loadFailureShowListener($container);
+        }
+
+        unset($config['sessions']);
+
+        $container->setParameter('mink.parameters', $config);
+        $container->setParameter('mink.base_url', $config['base_url']);
+        $container->setParameter('mink.browser_name', $config['browser_name']);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function configure(ArrayNodeDefinition $builder)
+    {
+        // Rewrite keys to define a shortcut way without allowing conflicts with real keys
+        $renamedKeys = array_diff(
+            array_keys($this->driverFactories),
+            array('mink_loader', 'base_url', 'files_path', 'show_auto', 'show_cmd', 'show_tmp_dir', 'default_session', 'javascript_session', 'browser_name', 'sessions')
+        );
+
+        $builder
+            ->beforeNormalization()
+                ->always()
+                ->then(function ($v) use ($renamedKeys) {
+                    foreach ($renamedKeys as $driverType) {
+                        if (!array_key_exists($driverType, $v) || isset($v['sessions'][$driverType])) {
+                            continue;
+                        }
+
+                        $v['sessions'][$driverType][$driverType] = $v[$driverType];
+                        unset($v[$driverType]);
+                    }
+
+                    return $v;
+                })
+            ->end()
+            ->addDefaultsIfNotSet()
+            ->children()
+                ->scalarNode('mink_loader')->defaultNull()->end()
+                ->scalarNode('base_url')->defaultNull()->end()
+                ->scalarNode('files_path')->defaultNull()->end()
+                ->booleanNode('show_auto')->defaultFalse()->end()
+                ->scalarNode('show_cmd')->defaultNull()->end()
+                ->scalarNode('show_tmp_dir')->defaultValue(sys_get_temp_dir())->end()
+                ->scalarNode('default_session')->defaultNull()->info('Defaults to the first non-javascript session if any, or the first session otherwise')->end()
+                ->scalarNode('javascript_session')->defaultNull()->info('Defaults to the first javascript session if any')->end()
+                ->scalarNode('browser_name')->defaultValue('firefox')->end()
+            ->end()
+        ->end();
+
+        /** @var ArrayNodeDefinition $sessionsBuilder */
+        $sessionsBuilder = $builder
+            ->children()
+                ->arrayNode('sessions')
+                    ->isRequired()
+                    ->requiresAtLeastOneElement()
+                    ->useAttributeAsKey('name')
+                    ->prototype('array')
+        ;
+
+        foreach ($this->driverFactories as $factory) {
+            $factoryNode = $sessionsBuilder->children()->arrayNode($factory->getDriverName())->canBeUnset();
+
+            $factory->configure($factoryNode);
+        }
+
+        $sessionsBuilder
+            ->validate()
+                ->ifTrue(function ($v) {return count($v) > 1;})
+                ->thenInvalid('You cannot set multiple driver types for the same session')
+            ->end()
+            ->validate()
+                ->ifTrue(function ($v) {return count($v) === 0;})
+                ->thenInvalid('You must set a driver definition for the session.')
+            ->end()
+        ;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getConfigKey()
+    {
+        return 'mink';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function initialize(ExtensionManager $extensionManager)
+    {
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function process(ContainerBuilder $container)
+    {
+        $this->processSelectors($container);
+    }
+
+    private function loadMink(ContainerBuilder $container)
+    {
+        $container->setDefinition(self::MINK_ID, new Definition('Behat\Mink\Mink'));
+    }
+
+    private function loadContextInitializer(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\MinkExtension\Context\Initializer\MinkAwareInitializer', array(
+            new Reference(self::MINK_ID),
+            '%mink.parameters%',
+        ));
+        $definition->addTag(ContextExtension::INITIALIZER_TAG, array('priority' => 0));
+        $container->setDefinition('mink.context_initializer', $definition);
+    }
+
+    private function loadSelectorsHandler(ContainerBuilder $container)
+    {
+        $container->setDefinition(self::SELECTORS_HANDLER_ID, new Definition('Behat\Mink\Selector\SelectorsHandler'));
+
+        $cssSelectorDefinition = new Definition('Behat\Mink\Selector\CssSelector');
+        $cssSelectorDefinition->addTag(self::SELECTOR_TAG, array('alias' => 'css'));
+        $container->setDefinition(self::SELECTOR_TAG . '.css', $cssSelectorDefinition);
+
+        $namedSelectorDefinition = new Definition('Behat\Mink\Selector\NamedSelector');
+        $namedSelectorDefinition->addTag(self::SELECTOR_TAG, array('alias' => 'named'));
+        $container->setDefinition(self::SELECTOR_TAG . '.named', $namedSelectorDefinition);
+    }
+
+    private function loadSessions(ContainerBuilder $container, array $config)
+    {
+        $defaultSession = $config['default_session'];
+        $javascriptSession = $config['javascript_session'];
+        $javascriptSessions = $nonJavascriptSessions = array();
+
+        $minkDefinition = $container->getDefinition(self::MINK_ID);
+
+        foreach ($config['sessions'] as $name => $session) {
+            $driver = key($session);
+            $factory = $this->driverFactories[$driver];
+
+            $definition = new Definition('Behat\Mink\Session', array(
+                $factory->buildDriver($session[$driver]),
+                new Reference(self::SELECTORS_HANDLER_ID),
+            ));
+            $minkDefinition->addMethodCall('registerSession', array($name, $definition));
+
+            if ($factory->supportsJavascript()) {
+                $javascriptSessions[] = $name;
+            } else {
+                $nonJavascriptSessions[] = $name;
+            }
+        }
+
+        if (null === $javascriptSession && !empty($javascriptSessions)) {
+            $javascriptSession = $javascriptSessions[0];
+        } elseif (null !== $javascriptSession && !in_array($javascriptSession, $javascriptSessions)) {
+            throw new InvalidConfigurationException(sprintf(
+                'The javascript session must be one of the enabled javascript sessions (%s), but got %s',
+                json_encode($javascriptSessions),
+                $javascriptSession
+            ));
+        }
+
+        if (null === $defaultSession) {
+            $defaultSession = !empty($nonJavascriptSessions) ? $nonJavascriptSessions[0] : $javascriptSessions[0];
+        } elseif (!isset($config['sessions'][$defaultSession])) {
+            throw new InvalidConfigurationException(sprintf('The default session must be one of the enabled sessions, but got %s', $defaultSession));
+        }
+
+        $container->setParameter('mink.default_session', $defaultSession);
+        $container->setParameter('mink.javascript_session', $javascriptSession);
+        $container->setParameter('mink.available_javascript_sessions', $javascriptSessions);
+    }
+
+    private function loadSessionsListener(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\MinkExtension\Listener\SessionsListener', array(
+            new Reference(self::MINK_ID),
+            '%mink.default_session%',
+            '%mink.javascript_session%',
+            '%mink.available_javascript_sessions%',
+        ));
+        $definition->addTag(EventDispatcherExtension::SUBSCRIBER_TAG, array('priority' => 0));
+        $container->setDefinition('mink.listener.sessions', $definition);
+    }
+
+    private function loadFailureShowListener(ContainerBuilder $container)
+    {
+        $definition = new Definition('Behat\MinkExtension\Listener\FailureShowListener', array(
+            new Reference(self::MINK_ID),
+            '%mink.parameters%',
+        ));
+        $definition->addTag(EventDispatcherExtension::SUBSCRIBER_TAG, array('priority' => 0));
+        $container->setDefinition('mink.listener.failure_show', $definition);
+    }
+
+    private function processSelectors(ContainerBuilder $container)
+    {
+        $handlerDefinition = $container->getDefinition(self::SELECTORS_HANDLER_ID);
+
+        foreach ($container->findTaggedServiceIds(self::SELECTOR_TAG) as $id => $tags) {
+            foreach ($tags as $tag) {
+                if (!isset($tag['alias'])) {
+                    throw new ProcessingException(sprintf(
+                        'All `%s` tags should have an `alias` attribute, but `%s` service has none.',
+                        $tag,
+                        $id
+                    ));
+                }
+                $handlerDefinition->addMethodCall(
+                    'registerSelector', array($tag['alias'], new Reference($id))
+                );
+            }
+        }
+    }
+}
diff --git a/vendor/behat/mink-selenium2-driver/.gitignore b/vendor/behat/mink-selenium2-driver/.gitignore
new file mode 100644 (file)
index 0000000..1d034f4
--- /dev/null
@@ -0,0 +1,4 @@
+vendor
+composer.phar
+composer.lock
+phpunit.xml
diff --git a/vendor/behat/mink-selenium2-driver/.travis.yml b/vendor/behat/mink-selenium2-driver/.travis.yml
new file mode 100644 (file)
index 0000000..fa9f556
--- /dev/null
@@ -0,0 +1,43 @@
+language: php
+
+sudo: false
+
+cache:
+  directories:
+    - $HOME/.composer/cache/files
+
+php: [5.3, 5.4, 5.5, 5.6, 7.0, hhvm]
+
+env:
+  - WEBDRIVER=selenium
+
+matrix:
+  allow_failures:
+    - env: 'WEBDRIVER=phantomjs'
+    - env: WEBDRIVER=phantomjs PHANTOM_VERSION=2
+  fast_finish: true
+  include:
+    - php: 5.5
+      env: WEBDRIVER=phantomjs
+    - php: 5.5
+      env: WEBDRIVER=phantomjs PHANTOM_VERSION=2
+
+before_script:
+  - export WEB_FIXTURES_HOST=http://localhost:8000
+  - export WEB_FIXTURES_BROWSER=firefox
+
+  - sh bin/run-"$WEBDRIVER".sh
+
+  - composer install --prefer-source
+
+  # Start a webserver for web fixtures. Force using PHP 5.6 to be able to run it on PHP 5.3 and HHVM jobs too
+  - ~/.phpenv/versions/5.6/bin/php -S localhost:8000 -t vendor/behat/mink/driver-testsuite/web-fixtures > /dev/null 2>&1 &
+
+script: phpunit -v --coverage-clover=coverage.clover
+
+after_script:
+  - wget https://scrutinizer-ci.com/ocular.phar
+  - php ocular.phar code-coverage:upload --format=php-clover coverage.clover
+
+after_failure:
+  - cat /tmp/webdriver_output.txt
diff --git a/vendor/behat/mink-selenium2-driver/CHANGELOG.md b/vendor/behat/mink-selenium2-driver/CHANGELOG.md
new file mode 100644 (file)
index 0000000..fc9e09a
--- /dev/null
@@ -0,0 +1,66 @@
+1.3.1 / 2016-03-05
+==================
+
+Bug fixes:
+
+* Fixed the handling of cookies with semicolon in the value
+
+Testsuite:
+
+* Add testing on PHP 7
+
+1.3.0 / 2015-09-21
+==================
+
+New features:
+
+* Updated the driver to use findElementsXpaths for Mink 1.7 and forward compatibility with Mink 2
+
+Testsuite:
+
+* Fixed the window name test for the chrome driver
+* Add testing on PhantomJS 2
+
+Misc:
+
+* Updated the repository structure to PSR-4
+
+1.2.0 / 2014-09-29
+==================
+
+BC break:
+
+* Changed the behavior of `getValue` for checkboxes according to the BC break in Mink 1.6
+
+New features:
+
+* Added the support of the `chromeOptions` argument in capabilities
+* Added the support of select elements in `setValue`
+* Added the support of checbox and radio elements in `setValue`
+* Added the support of HTML5 input types in `setValue` (for those supported by WebDriver itself)
+* Added `getWebDriverSessionId` to get the WebDriver session id
+* Added a way to configure the webdriver timeouts
+* Implemented `getOuterHtml`
+* Implemented `getWindowNames` and `getWindowName`
+* Implemented `maximizeWindow`
+* Implemented `submitForm`
+* Implemented `isSelected`
+
+Bug fixes:
+
+* Fixed the selection of options for radio groups
+* Fixed `getValue` for radio groups
+* Fixed the selection of options for multiple selects to ensure the change event is triggered only once
+* Fixed mouse interactions to use the webDriver API rather than using JS and emulating events
+* Fixed duplicate change events being triggered when setting the value
+* Fixed the code to throw exceptions for invalid usages of the driver
+* Fixed the implementation of `mouseOver`
+* Fixed `evaluateScript` and `executeScript` to support all syntaxes required by the Mink API
+* Fixed the retrieval of HTML attributes in `getAttribute`
+* Fixed form interactions to use the webDriver API rather than using JS and emulating change events
+* Fixed the clearing of the value when the caret is at the beginning of the field in `setValue`
+
+Testing:
+
+* Updated the testsuite to use the new Mink 1.6 driver testsuite
+* Added testing on HHVM
diff --git a/vendor/behat/mink-selenium2-driver/README.md b/vendor/behat/mink-selenium2-driver/README.md
new file mode 100644 (file)
index 0000000..3c9fec0
--- /dev/null
@@ -0,0 +1,60 @@
+Mink Selenium2 (webdriver) Driver
+=================================
+[![Latest Stable Version](https://poser.pugx.org/behat/mink-selenium2-driver/v/stable.svg)](https://packagist.org/packages/behat/mink-selenium2-driver)
+[![Latest Unstable Version](https://poser.pugx.org/behat/mink-selenium2-driver/v/unstable.svg)](https://packagist.org/packages/behat/mink-selenium2-driver)
+[![Total Downloads](https://poser.pugx.org/behat/mink-selenium2-driver/downloads.svg)](https://packagist.org/packages/behat/mink-selenium2-driver)
+[![Build Status](https://travis-ci.org/minkphp/MinkSelenium2Driver.svg?branch=master)](https://travis-ci.org/minkphp/MinkSelenium2Driver)
+[![Scrutinizer Quality Score](https://scrutinizer-ci.com/g/minkphp/MinkSelenium2Driver/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/minkphp/MinkSelenium2Driver/)
+[![Code Coverage](https://scrutinizer-ci.com/g/minkphp/MinkSelenium2Driver/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/minkphp/MinkSelenium2Driver/)
+[![License](https://poser.pugx.org/behat/mink-selenium2-driver/license.svg)](https://packagist.org/packages/behat/mink-selenium2-driver)
+
+Usage Example
+-------------
+
+``` php
+<?php
+
+use Behat\Mink\Mink,
+    Behat\Mink\Session,
+    Behat\Mink\Driver\Selenium2Driver;
+
+use Selenium\Client as SeleniumClient;
+
+$url = 'http://example.com';
+
+$mink = new Mink(array(
+    'selenium2' => new Session(new Selenium2Driver($browser, null, $url)),
+));
+
+$mink->getSession('selenium2')->getPage()->findLink('Chat')->click();
+```
+
+Please refer to [MinkExtension-example](https://github.com/Behat/MinkExtension-example) for an executable example.
+
+Installation
+------------
+
+``` json
+{
+    "require": {
+        "behat/mink":                   "~1.5",
+        "behat/mink-selenium2-driver":  "~1.1"
+    }
+}
+```
+
+``` bash
+$> curl -sS http://getcomposer.org/installer | php
+$> php composer.phar install
+```
+
+Copyright
+---------
+
+Copyright (c) 2012 Pete Otaqui <pete@otaqui.com>.
+
+Maintainers
+-----------
+
+* Christophe Coevoet [stof](https://github.com/stof)
+* Pete Otaqui [pete-otaqui](http://github.com/pete-otaqui)
diff --git a/vendor/behat/mink-selenium2-driver/bin/run-phantomjs.sh b/vendor/behat/mink-selenium2-driver/bin/run-phantomjs.sh
new file mode 100644 (file)
index 0000000..d597427
--- /dev/null
@@ -0,0 +1,13 @@
+#!/usr/bin/env sh
+set -e
+
+if [ "2" = "$PHANTOM_VERSION" ]; then
+    mkdir travis-phantomjs
+    wget https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-linux-x86_64.tar.bz2 -O $PWD/travis-phantomjs/phantomjs-2.1.1-linux-x86_64.tar.bz2
+    tar -xvf $PWD/travis-phantomjs/phantomjs-2.1.1-linux-x86_64.tar.bz2 -C $PWD/travis-phantomjs
+    export PATH=$PWD/travis-phantomjs:$PATH
+fi
+
+phantomjs --version
+echo '    Running PhantomJS'
+phantomjs --webdriver=4444 > /tmp/webdriver_output.txt &
diff --git a/vendor/behat/mink-selenium2-driver/bin/run-selenium.sh b/vendor/behat/mink-selenium2-driver/bin/run-selenium.sh
new file mode 100644 (file)
index 0000000..43ccf01
--- /dev/null
@@ -0,0 +1,12 @@
+#!/usr/bin/env sh
+set -e
+
+echo '    Starting XVFB'
+sh -e /etc/init.d/xvfb start
+export DISPLAY=:99.0
+sleep 4
+
+echo '    Downloading selenium'
+curl -L http://selenium-release.storage.googleapis.com/2.52/selenium-server-standalone-2.52.0.jar > selenium.jar
+echo '    Running selenium'
+java -jar selenium.jar -log /tmp/webdriver.log > /tmp/webdriver_output.txt 2>&1 &
diff --git a/vendor/behat/mink-selenium2-driver/composer.json b/vendor/behat/mink-selenium2-driver/composer.json
new file mode 100644 (file)
index 0000000..948b295
--- /dev/null
@@ -0,0 +1,49 @@
+{
+    "name":         "behat/mink-selenium2-driver",
+    "description":  "Selenium2 (WebDriver) driver for Mink framework",
+    "keywords":     ["selenium", "webdriver", "javascript", "ajax", "testing", "browser"],
+    "homepage":     "http://mink.behat.org/",
+    "type":         "mink-driver",
+    "license":      "MIT",
+
+    "authors": [
+        {
+            "name":      "Pete Otaqui",
+            "email":     "pete@otaqui.com",
+            "homepage":  "https://github.com/pete-otaqui"
+        },
+        {
+            "name":      "Konstantin Kudryashov",
+            "email":     "ever.zet@gmail.com",
+            "homepage":  "http://everzet.com"
+        }
+    ],
+
+    "require": {
+        "php":                       ">=5.3.1",
+        "behat/mink":                "~1.7@dev",
+        "instaclick/php-webdriver":  "~1.1"
+    },
+
+    "require-dev": {
+        "symfony/phpunit-bridge": "~2.7"
+    },
+
+    "autoload": {
+        "psr-4": {
+            "Behat\\Mink\\Driver\\": "src/"
+        }
+    },
+
+    "autoload-dev": {
+        "psr-4": {
+            "Behat\\Mink\\Tests\\Driver\\": "tests"
+        }
+    },
+
+    "extra": {
+        "branch-alias": {
+            "dev-master": "1.3.x-dev"
+        }
+    }
+}
diff --git a/vendor/behat/mink-selenium2-driver/phpunit.xml.dist b/vendor/behat/mink-selenium2-driver/phpunit.xml.dist
new file mode 100644 (file)
index 0000000..13e8087
--- /dev/null
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<phpunit colors="true" bootstrap="vendor/behat/mink/driver-testsuite/bootstrap.php">
+    <testsuites>
+        <testsuite name="Driver test suite">
+            <directory>tests</directory>
+            <directory>vendor/behat/mink/driver-testsuite/tests</directory>
+        </testsuite>
+    </testsuites>
+
+    <php>
+        <var name="driver_config_factory" value="Behat\Mink\Tests\Driver\Selenium2Config::getInstance" />
+
+        <!--server name="WEB_FIXTURES_HOST" value="http://test.mink.dev" /-->
+        <!--server name="WEB_FIXTURES_BROWSER" value="firefox" /-->
+
+        <!-- where driver will connect to -->
+        <server name="DRIVER_URL" value="http://localhost:4444/wd/hub" />
+
+        <!-- where DocumentRoot of 'Test Machine' is mounted to on 'Driver Machine' (only if these are 2 different machines) -->
+        <!--server name="DRIVER_MACHINE_BASE_PATH" value="" /-->
+        <!--server name="TEST_MACHINE_BASE_PATH" value="" /-->
+    </php>
+
+    <filter>
+        <whitelist>
+            <directory>./src</directory>
+        </whitelist>
+    </filter>
+</phpunit>
diff --git a/vendor/behat/mink-selenium2-driver/src/Resources/syn.js b/vendor/behat/mink-selenium2-driver/src/Resources/syn.js
new file mode 100644 (file)
index 0000000..8c07bf8
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+Syn - a Standalone Synthetic Event Library.
+
+Syn is used to simulate user actions such as typing, clicking, dragging
+the mouse.  It creates synthetic events and performs default event behavior.
+
+http://jupiterjs.com/news/syn-a-standalone-synthetic-event-library
+
+*/(function(){var e=function(k,a){for(var b in a)k[b]=a[b];return k},j={msie:!(!window.attachEvent||window.opera),opera:!!window.opera,webkit:-1<navigator.userAgent.indexOf("AppleWebKit/"),safari:-1<navigator.userAgent.indexOf("AppleWebKit/")&&-1===navigator.userAgent.indexOf("Chrome/"),gecko:-1<navigator.userAgent.indexOf("Gecko"),mobilesafari:!!navigator.userAgent.match(/Apple.*Mobile.*Safari/),rhino:navigator.userAgent.match(/Rhino/)&&!0},m=function(k,a,b){k=b.ownerDocument.createEventObject();return e(k,
+a)},h={},i=1,a="_synthetic"+(new Date).getTime(),b,d,g=/keypress|keyup|keydown/,c=/load|unload|abort|error|select|change|submit|reset|focus|blur|resize|scroll/,l,f=function(k,a,b,g){return new f.init(k,a,b,g)};b=function(k,a,b){return k.addEventListener?k.addEventListener(a,b,!1):k.attachEvent("on"+a,b)};d=function(k,a,b){return k.addEventListener?k.removeEventListener(a,b,!1):k.detachEvent("on"+a,b)};e(f,{init:function(k,a,b,g){var c=f.args(a,b,g),d=this;this.queue=[];this.element=c.element;if("function"===
+typeof this[k])this[k](c.options,c.element,function(k,a){c.callback&&c.callback.apply(d,arguments);d.done.apply(d,arguments)});else this.result=f.trigger(k,c.options,c.element),c.callback&&c.callback.call(this,c.element,this.result)},jquery:function(k){return window.FuncUnit&&window.FuncUnit.jquery?window.FuncUnit.jquery:k?f.helpers.getWindow(k).jQuery||window.jQuery:window.jQuery},args:function(){for(var k={},a=0;a<arguments.length;a++)if("function"===typeof arguments[a])k.callback=arguments[a];
+else if(arguments[a]&&arguments[a].jquery)k.element=arguments[a][0];else if(arguments[a]&&arguments[a].nodeName)k.element=arguments[a];else if(k.options&&"string"===typeof arguments[a])k.element=document.getElementById(arguments[a]);else if(arguments[a])k.options=arguments[a];return k},click:function(a,b,c){f("click!",a,b,c)},defaults:{focus:function(){if(!f.support.focusChanges){var a=this,c=a.nodeName.toLowerCase();f.data(a,"syntheticvalue",a.value);("input"===c||"textarea"===c)&&b(a,"blur",function(){f.data(a,
+"syntheticvalue")!=a.value&&f.trigger("change",{},a);d(a,"blur",arguments.callee)})}},submit:function(){f.onParents(this,function(a){if("form"===a.nodeName.toLowerCase())return a.submit(),!1})}},changeOnBlur:function(a,c,g){b(a,"blur",function(){g!==a[c]&&f.trigger("change",{},a);d(a,"blur",arguments.callee)})},closest:function(a,b){for(;a&&a.nodeName.toLowerCase()!==b.toLowerCase();)a=a.parentNode;return a},data:function(b,c,g){b[a]||(b[a]=i++);h[b[a]]||(h[b[a]]={});if(g)h[b[a]][c]=g;else return h[b[a]][c]},
+onParents:function(a,b){for(var c;a&&!1!==c;)c=b(a),a=a.parentNode;return a},focusable:/^(a|area|frame|iframe|label|input|select|textarea|button|html|object)$/i,isFocusable:function(a){var b;return(this.focusable.test(a.nodeName)||(b=a.getAttributeNode("tabIndex"))&&b.specified)&&f.isVisible(a)},isVisible:function(a){return a.offsetWidth&&a.offsetHeight||a.clientWidth&&a.clientHeight},tabIndex:function(a){var b=a.getAttributeNode("tabIndex");return b&&b.specified&&(parseInt(a.getAttribute("tabIndex"))||
+0)},bind:b,unbind:d,browser:j,helpers:{createEventObject:m,createBasicStandardEvent:function(a,b,c){var g;try{g=c.createEvent("Events")}catch(f){g=c.createEvent("UIEvents")}finally{g.initEvent(a,!0,!0),e(g,b)}return g},inArray:function(a,b){for(var c=0;c<b.length;c++)if(b[c]===a)return c;return-1},getWindow:function(a){return a.ownerDocument.defaultView||a.ownerDocument.parentWindow},extend:e,scrollOffset:function(a,b){var c=a.document.documentElement,g=a.document.body;if(b)window.scrollTo(b.left,
+b.top);else return{left:(c&&c.scrollLeft||g&&g.scrollLeft||0)+(c.clientLeft||0),top:(c&&c.scrollTop||g&&g.scrollTop||0)+(c.clientTop||0)}},scrollDimensions:function(a){var b=a.document.documentElement,c=a.document.body,g=b.clientWidth,b=b.clientHeight,a="CSS1Compat"===a.document.compatMode;return{height:a&&b||c.clientHeight||b,width:a&&g||c.clientWidth||g}},addOffset:function(a,b){var c=f.jquery(b);if("object"===typeof a&&void 0===a.clientX&&void 0===a.clientY&&void 0===a.pageX&&void 0===a.pageY&&
+c)b=c(b),c=b.offset(),a.pageX=c.left+b.width()/2,a.pageY=c.top+b.height()/2}},key:{ctrlKey:null,altKey:null,shiftKey:null,metaKey:null},dispatch:function(a,c,g,f){if(c.dispatchEvent&&a){var l=a.preventDefault,h=f?-1:0;f&&b(c,g,function(a){a.preventDefault();d(this,g,arguments.callee)});a.preventDefault=function(){h++;0<++h&&l.apply(this,[])};c.dispatchEvent(a);return 0>=h}try{window.event=a}catch(e){}return 0>=c.sourceIndex||c.fireEvent&&c.fireEvent("on"+g,a)},create:{page:{event:function(a,b,c){var g=
+f.helpers.getWindow(c).document||document,d;if(g.createEvent)d=g.createEvent("Events"),d.initEvent(a,!0,!0);else try{d=m(a,b,c)}catch(l){}return d}},focus:{event:function(a,b,c){f.onParents(c,function(a){if(f.isFocusable(a)){if("html"!==a.nodeName.toLowerCase())a.focus(),l=a;else if(l)a=f.helpers.getWindow(c).document,a===window.document&&(a.activeElement?a.activeElement.blur():l.blur(),l=null);return!1}});return!0}}},support:{clickChanges:!1,clickSubmits:!1,keypressSubmits:!1,mouseupSubmits:!1,radioClickChanges:!1,
+focusChanges:!1,linkHrefJS:!1,keyCharacters:!1,backspaceWorks:!1,mouseDownUpClicks:!1,tabKeyTabs:!1,keypressOnAnchorClicks:!1,optionClickBubbles:!1,ready:0},trigger:function(a,b,d){b||(b={});var l=f.create,h=l[a]&&l[a].setup,e=g.test(a)?"key":c.test(a)?"page":"mouse",i=l[a]||{},e=l[e],l=d;2===f.support.ready&&h&&h(a,b,d);h=b._autoPrevent;delete b._autoPrevent;if(i.event)i=i.event(a,b,d);else{b=e.options?e.options(a,b,d):b;if(!f.support.changeBubbles&&/option/i.test(d.nodeName))l=d.parentNode;i=e.event(a,
+b,l);i=f.dispatch(i,l,a,h)}i&&2===f.support.ready&&f.defaults[a]&&f.defaults[a].call(d,b,h);return i},eventSupported:function(a){var b=document.createElement("div"),a="on"+a,c=a in b;c||(b.setAttribute(a,"return;"),c="function"===typeof b[a]);return c}});e(f.init.prototype,{then:function(a,b,c,g){f.autoDelay&&this.delay();var d=f.args(b,c,g),l=this;this.queue.unshift(function(b){if("function"===typeof this[a])this.element=d.element||b,this[a](d.options,this.element,function(a,b){d.callback&&d.callback.apply(l,
+arguments);l.done.apply(l,arguments)});else return this.result=f.trigger(a,d.options,d.element),d.callback&&d.callback.call(this,d.element,this.result),this});return this},delay:function(a,b){"function"===typeof a&&(b=a,a=null);var a=a||600,c=this;this.queue.unshift(function(){setTimeout(function(){b&&b.apply(c,[]);c.done.apply(c,arguments)},a)});return this},done:function(a,b){b&&(this.element=b);this.queue.length&&this.queue.pop().call(this,this.element,a)},_click:function(a,b,c,g){f.helpers.addOffset(a,
+b);f.trigger("mousedown",a,b);setTimeout(function(){f.trigger("mouseup",a,b);!f.support.mouseDownUpClicks||g?(f.trigger("click",a,b),c(!0)):(f.create.click.setup("click",a,b),f.defaults.click.call(b),setTimeout(function(){c(!0)},1))},1)},_rightClick:function(a,b,c){f.helpers.addOffset(a,b);var g=e(e({},f.mouse.browser.right.mouseup),a);f.trigger("mousedown",g,b);setTimeout(function(){f.trigger("mouseup",g,b);f.mouse.browser.right.contextmenu&&f.trigger("contextmenu",e(e({},f.mouse.browser.right.contextmenu),
+a),b);c(!0)},1)},_dblclick:function(a,b,c){f.helpers.addOffset(a,b);var g=this;this._click(a,b,function(){setTimeout(function(){g._click(a,b,function(){f.trigger("dblclick",a,b);c(!0)},!0)},2)})}});for(var j="click,dblclick,move,drag,key,type,rightClick".split(","),v=function(a){f[a]=function(b,c,g){return f("_"+a,b,c,g)};f.init.prototype[a]=function(b,c,g){return this.then("_"+a,b,c,g)}},r=0;r<j.length;r++)v(j[r]);if(window.FuncUnit&&window.FuncUnit.jQuery||window.jQuery)(window.FuncUnit&&window.FuncUnit.jQuery||
+window.jQuery).fn.triggerSyn=function(a,b,c){f(a,b,this[0],c);return this};window.Syn=f})(!0);
+(function(){var e=Syn.helpers,j=e.getWindow;Syn.mouse={};e.extend(Syn.defaults,{mousedown:function(){Syn.trigger("focus",{},this)},click:function(){var e=Syn.data(this,"radioChanged"),h=j(this),i=this.nodeName.toLowerCase();if(!Syn.support.linkHrefJS&&/^\s*javascript:/.test(this.href)){var a=this.href.replace(/^\s*javascript:/,"");"//"!=a&&-1==a.indexOf("void(0)")&&(window.selenium?eval("with(selenium.browserbot.getCurrentWindow()){"+a+"}"):eval("with(scope){"+a+"}"))}if(!Syn.support.clickSubmits&&
+"input"==i&&"submit"==this.type||"button"==i)(a=Syn.closest(this,"form"))&&Syn.trigger("submit",{},a);if("a"==i&&this.href&&!/^\s*javascript:/.test(this.href))h.location.href=this.href;"input"==i&&"checkbox"==this.type&&(Syn.support.clickChanges||Syn.trigger("change",{},this));"input"==i&&"radio"==this.type&&e&&!Syn.support.radioClickChanges&&Syn.trigger("change",{},this);"option"==i&&Syn.data(this,"createChange")&&(Syn.trigger("change",{},this.parentNode),Syn.data(this,"createChange",!1))}});e.extend(Syn.create,
+{mouse:{options:function(j,h){var i=document.documentElement,a=document.body,b=[h.pageX||0,h.pageY||0],d=Syn.mouse.browser&&Syn.mouse.browser.left[j],g=Syn.mouse.browser&&Syn.mouse.browser.right[j];return e.extend({bubbles:!0,cancelable:!0,view:window,detail:1,screenX:1,screenY:1,clientX:h.clientX||b[0]-(i&&i.scrollLeft||a&&a.scrollLeft||0)-(i.clientLeft||0),clientY:h.clientY||b[1]-(i&&i.scrollTop||a&&a.scrollTop||0)-(i.clientTop||0),ctrlKey:!!Syn.key.ctrlKey,altKey:!!Syn.key.altKey,shiftKey:!!Syn.key.shiftKey,
+metaKey:!!Syn.key.metaKey,button:d&&null!=d.button?d.button:g&&g.button||("contextmenu"==j?2:0),relatedTarget:document.documentElement},h)},event:function(m,h,i){var a=j(i).document||document;if(a.createEvent){var b;try{b=a.createEvent("MouseEvents"),b.initMouseEvent(m,h.bubbles,h.cancelable,h.view,h.detail,h.screenX,h.screenY,h.clientX,h.clientY,h.ctrlKey,h.altKey,h.shiftKey,h.metaKey,h.button,h.relatedTarget)}catch(d){b=e.createBasicStandardEvent(m,h,a)}b.synthetic=!0}else try{b=e.createEventObject(m,
+h,i)}catch(g){}return b}},click:{setup:function(e,h,i){h=i.nodeName.toLowerCase();if(!Syn.support.clickChecks&&!Syn.support.changeChecks&&"input"===h){e=i.type.toLowerCase();if("checkbox"===e)i.checked=!i.checked;if("radio"===e&&!i.checked){try{Syn.data(i,"radioChanged",!0)}catch(a){}i.checked=!0}}"a"==h&&i.href&&!/^\s*javascript:/.test(i.href)&&Syn.data(i,"href",i.href);if(/option/i.test(i.nodeName)){e=i.parentNode.firstChild;for(h=-1;e&&!(1==e.nodeType&&(h++,e==i));)e=e.nextSibling;if(h!==i.parentNode.selectedIndex)i.parentNode.selectedIndex=
+h,Syn.data(i,"createChange",!0)}}},mousedown:{setup:function(e,h,i){e=i.nodeName.toLowerCase();if(Syn.browser.safari&&("select"==e||"option"==e))h._autoPrevent=!0}}});(function(){if(document.body){var e=window.__synthTest;window.__synthTest=function(){Syn.support.linkHrefJS=!0};var h=document.createElement("div"),i,a,b,d;h.innerHTML="<form id='outer'><input name='checkbox' type='checkbox'/><input name='radio' type='radio' /><input type='submit' name='submitter'/><input type='input' name='inputter'/><input name='one'><input name='two'/><a href='javascript:__synthTest()' id='synlink'></a><select><option></option></select></form>";
+document.documentElement.appendChild(h);b=h.firstChild;i=b.childNodes[0];a=b.childNodes[2];d=b.getElementsByTagName("select")[0];i.checked=!1;i.onchange=function(){Syn.support.clickChanges=!0};Syn.trigger("click",{},i);Syn.support.clickChecks=i.checked;i.checked=!1;Syn.trigger("change",{},i);Syn.support.changeChecks=i.checked;b.onsubmit=function(a){a.preventDefault&&a.preventDefault();Syn.support.clickSubmits=!0;return!1};Syn.trigger("click",{},a);b.childNodes[1].onchange=function(){Syn.support.radioClickChanges=
+!0};Syn.trigger("click",{},b.childNodes[1]);Syn.bind(h,"click",function(){Syn.support.optionClickBubbles=!0;Syn.unbind(h,"click",arguments.callee)});Syn.trigger("click",{},d.firstChild);Syn.support.changeBubbles=Syn.eventSupported("change");h.onclick=function(){Syn.support.mouseDownUpClicks=!0};Syn.trigger("mousedown",{},h);Syn.trigger("mouseup",{},h);document.documentElement.removeChild(h);window.__synthTest=e;Syn.support.ready++}else setTimeout(arguments.callee,1)})()})(!0);
+(function(){Syn.key.browsers={webkit:{prevent:{keyup:[],keydown:["char","keypress"],keypress:["char"]},character:{keydown:[0,"key"],keypress:["char","char"],keyup:[0,"key"]},specialChars:{keydown:[0,"char"],keyup:[0,"char"]},navigation:{keydown:[0,"key"],keyup:[0,"key"]},special:{keydown:[0,"key"],keyup:[0,"key"]},tab:{keydown:[0,"char"],keyup:[0,"char"]},"pause-break":{keydown:[0,"key"],keyup:[0,"key"]},caps:{keydown:[0,"key"],keyup:[0,"key"]},escape:{keydown:[0,"key"],keyup:[0,"key"]},"num-lock":{keydown:[0,
+"key"],keyup:[0,"key"]},"scroll-lock":{keydown:[0,"key"],keyup:[0,"key"]},print:{keyup:[0,"key"]},"function":{keydown:[0,"key"],keyup:[0,"key"]},"\r":{keydown:[0,"key"],keypress:["char","key"],keyup:[0,"key"]}},gecko:{prevent:{keyup:[],keydown:["char"],keypress:["char"]},character:{keydown:[0,"key"],keypress:["char",0],keyup:[0,"key"]},specialChars:{keydown:[0,"key"],keypress:[0,"key"],keyup:[0,"key"]},navigation:{keydown:[0,"key"],keypress:[0,"key"],keyup:[0,"key"]},special:{keydown:[0,"key"],keyup:[0,
+"key"]},"\t":{keydown:[0,"key"],keypress:[0,"key"],keyup:[0,"key"]},"pause-break":{keydown:[0,"key"],keypress:[0,"key"],keyup:[0,"key"]},caps:{keydown:[0,"key"],keyup:[0,"key"]},escape:{keydown:[0,"key"],keypress:[0,"key"],keyup:[0,"key"]},"num-lock":{keydown:[0,"key"],keyup:[0,"key"]},"scroll-lock":{keydown:[0,"key"],keyup:[0,"key"]},print:{keyup:[0,"key"]},"function":{keydown:[0,"key"],keyup:[0,"key"]},"\r":{keydown:[0,"key"],keypress:[0,"key"],keyup:[0,"key"]}},msie:{prevent:{keyup:[],keydown:["char",
+"keypress"],keypress:["char"]},character:{keydown:[null,"key"],keypress:[null,"char"],keyup:[null,"key"]},specialChars:{keydown:[null,"char"],keyup:[null,"char"]},navigation:{keydown:[null,"key"],keyup:[null,"key"]},special:{keydown:[null,"key"],keyup:[null,"key"]},tab:{keydown:[null,"char"],keyup:[null,"char"]},"pause-break":{keydown:[null,"key"],keyup:[null,"key"]},caps:{keydown:[null,"key"],keyup:[null,"key"]},escape:{keydown:[null,"key"],keypress:[null,"key"],keyup:[null,"key"]},"num-lock":{keydown:[null,
+"key"],keyup:[null,"key"]},"scroll-lock":{keydown:[null,"key"],keyup:[null,"key"]},print:{keyup:[null,"key"]},"function":{keydown:[null,"key"],keyup:[null,"key"]},"\r":{keydown:[null,"key"],keypress:[null,"key"],keyup:[null,"key"]}},opera:{prevent:{keyup:[],keydown:[],keypress:["char"]},character:{keydown:[null,"key"],keypress:[null,"char"],keyup:[null,"key"]},specialChars:{keydown:[null,"char"],keypress:[null,"char"],keyup:[null,"char"]},navigation:{keydown:[null,"key"],keypress:[null,"key"]},special:{keydown:[null,
+"key"],keypress:[null,"key"],keyup:[null,"key"]},tab:{keydown:[null,"char"],keypress:[null,"char"],keyup:[null,"char"]},"pause-break":{keydown:[null,"key"],keypress:[null,"key"],keyup:[null,"key"]},caps:{keydown:[null,"key"],keyup:[null,"key"]},escape:{keydown:[null,"key"],keypress:[null,"key"]},"num-lock":{keyup:[null,"key"],keydown:[null,"key"],keypress:[null,"key"]},"scroll-lock":{keydown:[null,"key"],keypress:[null,"key"],keyup:[null,"key"]},print:{},"function":{keydown:[null,"key"],keypress:[null,
+"key"],keyup:[null,"key"]},"\r":{keydown:[null,"key"],keypress:[null,"key"],keyup:[null,"key"]}}};Syn.mouse.browsers={webkit:{right:{mousedown:{button:2,which:3},mouseup:{button:2,which:3},contextmenu:{button:2,which:3}},left:{mousedown:{button:0,which:1},mouseup:{button:0,which:1},click:{button:0,which:1}}},opera:{right:{mousedown:{button:2,which:3},mouseup:{button:2,which:3}},left:{mousedown:{button:0,which:1},mouseup:{button:0,which:1},click:{button:0,which:1}}},msie:{right:{mousedown:{button:2},
+mouseup:{button:2},contextmenu:{button:0}},left:{mousedown:{button:1},mouseup:{button:1},click:{button:0}}},chrome:{right:{mousedown:{button:2,which:3},mouseup:{button:2,which:3},contextmenu:{button:2,which:3}},left:{mousedown:{button:0,which:1},mouseup:{button:0,which:1},click:{button:0,which:1}}},gecko:{left:{mousedown:{button:0,which:1},mouseup:{button:0,which:1},click:{button:0,which:1}},right:{mousedown:{button:2,which:3},mouseup:{button:2,which:3},contextmenu:{button:2,which:3}}}};Syn.key.browser=
+function(){if(Syn.key.browsers[window.navigator.userAgent])return Syn.key.browsers[window.navigator.userAgent];for(var e in Syn.browser)if(Syn.browser[e]&&Syn.key.browsers[e])return Syn.key.browsers[e];return Syn.key.browsers.gecko}();Syn.mouse.browser=function(){if(Syn.mouse.browsers[window.navigator.userAgent])return Syn.mouse.browsers[window.navigator.userAgent];for(var e in Syn.browser)if(Syn.browser[e]&&Syn.mouse.browsers[e])return Syn.mouse.browsers[e];return Syn.mouse.browsers.gecko}()})(!0);
+(function(){var e=Syn.helpers,j=Syn,m=function(a){if(void 0!==a.selectionStart)return document.activeElement&&document.activeElement!=a&&a.selectionStart==a.selectionEnd&&0==a.selectionStart?{start:a.value.length,end:a.value.length}:{start:a.selectionStart,end:a.selectionEnd};try{if("input"==a.nodeName.toLowerCase()){var b=e.getWindow(a).document.selection.createRange(),d=a.createTextRange();d.setEndPoint("EndToStart",b);var g=d.text.length;return{start:g,end:g+b.text.length}}var b=e.getWindow(a).document.selection.createRange(),
+d=b.duplicate(),c=b.duplicate(),l=b.duplicate();c.collapse();l.collapse(!1);c.moveStart("character",-1);l.moveStart("character",-1);d.moveToElementText(a);d.setEndPoint("EndToEnd",b);var g=d.text.length-b.text.length,f=d.text.length;0!=g&&""==c.text&&(g+=2);0!=f&&""==l.text&&(f+=2);return{start:g,end:f}}catch(h){return{start:a.value.length,end:a.value.length}}},h=function(a){for(var a=e.getWindow(a).document,b=[],d=a.getElementsByTagName("*"),g=d.length,c=0;c<g;c++)Syn.isFocusable(d[c])&&d[c]!=a.documentElement&&
+b.push(d[c]);return b};e.extend(Syn,{keycodes:{"\u0008":"8","\t":"9","\r":"13",shift:"16",ctrl:"17",alt:"18","pause-break":"19",caps:"20",escape:"27","num-lock":"144","scroll-lock":"145",print:"44","page-up":"33","page-down":"34",end:"35",home:"36",left:"37",up:"38",right:"39",down:"40",insert:"45","delete":"46"," ":"32","0":"48",1:"49",2:"50",3:"51",4:"52",5:"53",6:"54",7:"55",8:"56",9:"57",a:"65",b:"66",c:"67",d:"68",e:"69",f:"70",g:"71",h:"72",i:"73",j:"74",k:"75",l:"76",m:"77",n:"78",o:"79",p:"80",
+q:"81",r:"82",s:"83",t:"84",u:"85",v:"86",w:"87",x:"88",y:"89",z:"90",num0:"96",num1:"97",num2:"98",num3:"99",num4:"100",num5:"101",num6:"102",num7:"103",num8:"104",num9:"105","*":"106","+":"107","-":"109",".":"110","/":"111",";":"186","=":"187",",":"188","-":"189",".":"190","/":"191","`":"192","[":"219","\\":"220","]":"221","'":"222","left window key":"91","right window key":"92","select key":"93",f1:"112",f2:"113",f3:"114",f4:"115",f5:"116",f6:"117",f7:"118",f8:"119",f9:"120",f10:"121",f11:"122",
+f12:"123"},typeable:/input|textarea/i,selectText:function(a,b,d){if(a.setSelectionRange)d?(a.selectionStart=b,a.selectionEnd=d):(a.focus(),a.setSelectionRange(b,b));else if(a.createTextRange){var g=a.createTextRange();g.moveStart("character",b);g.moveEnd("character",(d||b)-a.value.length);g.select()}},getText:function(a){if(Syn.typeable.test(a.nodeName)){var b=m(a);return a.value.substring(b.start,b.end)}a=Syn.helpers.getWindow(a);return a.getSelection?a.getSelection().toString():a.document.getSelection?
+a.document.getSelection().toString():a.document.selection.createRange().text},getSelection:m});e.extend(Syn.key,{data:function(a){if(j.key.browser[a])return j.key.browser[a];for(var b in j.key.kinds)if(-1<e.inArray(a,j.key.kinds[b]))return j.key.browser[b];return j.key.browser.character},isSpecial:function(a){for(var b=j.key.kinds.special,d=0;d<b.length;d++)if(Syn.keycodes[b[d]]==a)return b[d]},options:function(a,b){var d=Syn.key.data(a);if(!d[b])return null;var g=d[b][0],d=d[b][1],c={};c.keyCode=
+"key"==d?Syn.keycodes[a]:"char"==d?a.charCodeAt(0):d;if("char"==g)c.charCode=a.charCodeAt(0);else if(null!==g)c.charCode=g;return c},kinds:{special:["shift","ctrl","alt","caps"],specialChars:["\u0008"],navigation:"page-up,page-down,end,home,left,up,right,down,insert,delete".split(","),"function":"f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12".split(",")},getDefault:function(a){if(Syn.key.defaults[a])return Syn.key.defaults[a];for(var b in Syn.key.kinds)if(-1<e.inArray(a,Syn.key.kinds[b])&&Syn.key.defaults[b])return Syn.key.defaults[b];
+return Syn.key.defaults.character},defaults:{character:function(a,b,d,g,c){/num\d+/.test(d)&&(d=d.match(/\d+/)[0]);if(g||!j.support.keyCharacters&&Syn.typeable.test(this.nodeName))b=this.value,a=b.substr(0,c.start),c=b.substr(c.end),this.value=a+d+c,Syn.selectText(this,a.length+("\n"==d&&j.support.textareaCarriage?2:d.length))},c:function(a,b,d,g,c){Syn.key.ctrlKey?Syn.key.clipboard=Syn.getText(this):Syn.key.defaults.character.apply(this,arguments)},v:function(a,b,d,g,c){Syn.key.ctrlKey?Syn.key.defaults.character.call(this,
+a,b,Syn.key.clipboard,!0,c):Syn.key.defaults.character.apply(this,arguments)},a:function(a,b,d,g,c){Syn.key.ctrlKey?Syn.selectText(this,0,this.value.length):Syn.key.defaults.character.apply(this,arguments)},home:function(){Syn.onParents(this,function(a){if(a.scrollHeight!=a.clientHeight)return a.scrollTop=0,!1})},end:function(){Syn.onParents(this,function(a){if(a.scrollHeight!=a.clientHeight)return a.scrollTop=a.scrollHeight,!1})},"page-down":function(){Syn.onParents(this,function(a){if(a.scrollHeight!=
+a.clientHeight)return a.scrollTop+=a.clientHeight,!1})},"page-up":function(){Syn.onParents(this,function(a){if(a.scrollHeight!=a.clientHeight)return a.scrollTop-=a.clientHeight,!1})},"\u0008":function(a,b,d,g,c){if(!j.support.backspaceWorks&&Syn.typeable.test(this.nodeName))b=this.value,a=b.substr(0,c.start),b=b.substr(c.end),c.start==c.end&&0<c.start?(this.value=a.substring(0,a.length-1)+b,Syn.selectText(this,c.start-1)):(this.value=a+b,Syn.selectText(this,c.start))},"delete":function(a,b,d,g,c){if(!j.support.backspaceWorks&&
+Syn.typeable.test(this.nodeName))b=this.value,a=b.substr(0,c.start),b=b.substr(c.end),this.value=c.start==c.end&&c.start<=this.value.length-1?a+b.substring(1):a+b,Syn.selectText(this,c.start)},"\r":function(a,b,d,g,c){d=this.nodeName.toLowerCase();!j.support.keypressSubmits&&"input"==d&&(g=Syn.closest(this,"form"))&&Syn.trigger("submit",{},g);!j.support.keyCharacters&&"textarea"==d&&Syn.key.defaults.character.call(this,a,b,"\n",void 0,c);!j.support.keypressOnAnchorClicks&&"a"==d&&Syn.trigger("click",
+{},this)},"\t":function(){var a=h(this);Syn.tabIndex(this);var b=null,d=0,g;for(orders=[];d<a.length;d++)orders.push([a[d],d]);orders.sort(function(a,b){var g=b[0],d=Syn.tabIndex(a[0])||0,g=Syn.tabIndex(g)||0;return d==g?a[1]-b[1]:0==d?1:0==g?-1:d-g});for(d=0;d<orders.length;d++)g=orders[d][0],this==g&&(Syn.key.shiftKey?(b=orders[d-1][0])||(b=orders[a.length-1][0]):(b=orders[d+1][0])||(b=orders[0][0]));b||(b=void 0);b&&b.focus();return b},left:function(a,b,d,g,c){Syn.typeable.test(this.nodeName)&&
+(Syn.key.shiftKey?Syn.selectText(this,0==c.start?0:c.start-1,c.end):Syn.selectText(this,0==c.start?0:c.start-1))},right:function(a,b,d,g,c){Syn.typeable.test(this.nodeName)&&(Syn.key.shiftKey?Syn.selectText(this,c.start,c.end+1>this.value.length?this.value.length:c.end+1):Syn.selectText(this,c.end+1>this.value.length?this.value.length:c.end+1))},up:function(){if(/select/i.test(this.nodeName))this.selectedIndex=this.selectedIndex?this.selectedIndex-1:0},down:function(){/select/i.test(this.nodeName)&&
+(Syn.changeOnBlur(this,"selectedIndex",this.selectedIndex),this.selectedIndex+=1)},shift:function(){return null}}});e.extend(Syn.create,{keydown:{setup:function(a,b,d){-1!=e.inArray(b,Syn.key.kinds.special)&&(Syn.key[b+"Key"]=d)}},keypress:{setup:function(a,b,d){j.support.keyCharacters&&!j.support.keysOnNotFocused&&d.focus()}},keyup:{setup:function(a,b){-1!=e.inArray(b,Syn.key.kinds.special)&&(Syn.key[b+"Key"]=null)}},key:{options:function(a,b){b="object"!=typeof b?{character:b}:b;b=e.extend({},b);
+b.character&&(e.extend(b,j.key.options(b.character,a)),delete b.character);return b=e.extend({ctrlKey:!!Syn.key.ctrlKey,altKey:!!Syn.key.altKey,shiftKey:!!Syn.key.shiftKey,metaKey:!!Syn.key.metaKey},b)},event:function(a,b,d){var g=e.getWindow(d).document||document;if(g.createEvent){var c;try{c=g.createEvent("KeyEvents"),c.initKeyEvent(a,!0,!0,window,b.ctrlKey,b.altKey,b.shiftKey,b.metaKey,b.keyCode,b.charCode)}catch(l){c=e.createBasicStandardEvent(a,b,g)}c.synthetic=!0}else try{c=e.createEventObject.apply(this,
+arguments),e.extend(c,b)}catch(f){}return c}}});var i={enter:"\r",backspace:"\u0008",tab:"\t",space:" "};e.extend(Syn.init.prototype,{_key:function(a,b,d){if(/-up$/.test(a)&&-1!=e.inArray(a.replace("-up",""),Syn.key.kinds.special))Syn.trigger("keyup",a.replace("-up",""),b),d(!0,b);else{var g=Syn.typeable.test(b.nodeName)&&m(b),c=i[a]||a,l=Syn.trigger("keydown",c,b),a=Syn.key.getDefault,f=Syn.key.browser.prevent,h,j=Syn.key.options(c,"keypress");l?j?(l=Syn.trigger("keypress",j,b))&&(h=a(c).call(b,
+j,e.getWindow(b),c,void 0,g)):h=a(c).call(b,j,e.getWindow(b),c,void 0,g):j&&-1==e.inArray("keypress",f.keydown)&&Syn.trigger("keypress",j,b);h&&h.nodeName&&(b=h);null!==h?setTimeout(function(){Syn.trigger("keyup",Syn.key.options(c,"keyup"),b);d(l,b)},1):d(l,b);return b}},_type:function(a,b,d){var g=a.match(/(\[[^\]]+\])|([^\[])/g),c=this,e=function(a,h){var i=g.shift();i?(h=h||b,1<i.length&&(i=i.substr(1,i.length-2)),c._key(i,h,e)):d(a,h)};e()}});(function(){if(document.body){var a=document.createElement("div"),
+b,d,g,c;a.innerHTML="<form id='outer'><input name='checkbox' type='checkbox'/><input name='radio' type='radio' /><input type='submit' name='submitter'/><input type='input' name='inputter'/><input name='one'><input name='two'/><a href='#abc'></a><textarea>1\n2</textarea></form>";document.documentElement.appendChild(a);b=a.firstChild;d=b.getElementsByTagName("a")[0];g=b.getElementsByTagName("textarea")[0];c=b.childNodes[3];b.onsubmit=function(a){a.preventDefault&&a.preventDefault();j.support.keypressSubmits=
+!0;return a.returnValue=!1};c.focus();Syn.trigger("keypress","\r",c);Syn.trigger("keypress","a",c);j.support.keyCharacters="a"==c.value;c.value="a";Syn.trigger("keypress","\u0008",c);j.support.backspaceWorks=""==c.value;c.onchange=function(){j.support.focusChanges=!0};c.focus();Syn.trigger("keypress","a",c);b.childNodes[5].focus();Syn.trigger("keypress","b",c);j.support.keysOnNotFocused="ab"==c.value;j.bind(d,"click",function(a){a.preventDefault&&a.preventDefault();j.support.keypressOnAnchorClicks=
+!0;return a.returnValue=!1});Syn.trigger("keypress","\r",d);j.support.textareaCarriage=4==g.value.length;document.documentElement.removeChild(a);j.support.ready++}else setTimeout(arguments.callee,1)})()})(!0);
+(function(){(function(){if(document.body){var a=document.createElement("div");document.body.appendChild(a);Syn.helpers.extend(a.style,{width:"100px",height:"10000px",backgroundColor:"blue",position:"absolute",top:"10px",left:"0px",zIndex:19999});document.body.scrollTop=11;if(document.elementFromPoint)document.elementFromPoint(3,1)==a?Syn.support.elementFromClient=!0:Syn.support.elementFromPage=!0,document.body.removeChild(a),document.body.scrollTop=0}else setTimeout(arguments.callee,1)})();var e=
+function(a,b){var d=a.clientX,f=a.clientY,e=Syn.helpers.getWindow(b);if(Syn.support.elementFromPage)var h=Syn.helpers.scrollOffset(e),d=d+h.left,f=f+h.top;d=e.document.elementFromPoint?e.document.elementFromPoint(d,f):b;return d===e.document.documentElement&&(0>a.clientY||0>a.clientX)?b:d},j=function(a,b,d){var f=e(b,d);Syn.trigger(a,b,f||d);return f},m=function(a,b,d){var f=e(a,b);if(d!=f&&f&&d){var h=Syn.helpers.extend({},a);h.relatedTarget=f;Syn.trigger("mouseout",h,d);h.relatedTarget=d;Syn.trigger("mouseover",
+h,f)}Syn.trigger("mousemove",a,f||b);return f},h=function(a,b,d,f,h){var i=new Date,j=b.clientX-a.clientX,u=b.clientY-a.clientY,n=Syn.helpers.getWindow(f),o=e(a,f),p=n.document.createElement("div"),s=0;move=function(){var e=new Date,t=Syn.helpers.scrollOffset(n),e=(0==s?0:e-i)/d,q={clientX:j*e+a.clientX,clientY:u*e+a.clientY};s++;1>e?(Syn.helpers.extend(p.style,{left:q.clientX+t.left+2+"px",top:q.clientY+t.top+2+"px"}),o=m(q,f,o),setTimeout(arguments.callee,15)):(o=m(b,f,o),n.document.body.removeChild(p),
+h())};Syn.helpers.extend(p.style,{height:"5px",width:"5px",backgroundColor:"red",position:"absolute",zIndex:19999,fontSize:"1px"});n.document.body.appendChild(p);move()},i=function(a,b,d,f,e){j("mousedown",a,f);h(a,b,d,f,function(){j("mouseup",b,f);e()})},a=function(a){var a=Syn.jquery()(a),b=a.offset();return{pageX:b.left+a.width()/2,pageY:b.top+a.height()/2}},b=function(b,c,d){var f=/(\d+)[x ](\d+)/,e=/(\d+)X(\d+)/,h=/([+-]\d+)[xX ]([+-]\d+)/;"string"==typeof b&&h.test(b)&&d&&(d=a(d),b=b.match(h),
+b={pageX:d.pageX+parseInt(b[1]),pageY:d.pageY+parseInt(b[2])});"string"==typeof b&&f.test(b)&&(b=b.match(f),b={pageX:parseInt(b[1]),pageY:parseInt(b[2])});"string"==typeof b&&e.test(b)&&(b=b.match(e),b={clientX:parseInt(b[1]),clientY:parseInt(b[2])});"string"==typeof b&&(b=Syn.jquery()(b,c.document)[0]);b.nodeName&&(b=a(b));b.pageX&&(c=Syn.helpers.scrollOffset(c),b={clientX:b.pageX-c.left,clientY:b.pageY-c.top});return b},d=function(a,b,d){if(0>a.clientY){var f=Syn.helpers.scrollOffset(d);Syn.helpers.scrollDimensions(d);
+var e=f.top+a.clientY-100,h=e-f.top;0<e||(e=0,h=-f.top);a.clientY-=h;b.clientY-=h;Syn.helpers.scrollOffset(d,{top:e,left:f.left})}};Syn.helpers.extend(Syn.init.prototype,{_move:function(a,c,e){var f=Syn.helpers.getWindow(c),i=b(a.from||c,f,c),j=b(a.to||a,f,c);!1!==a.adjust&&d(i,j,f);h(i,j,a.duration||500,c,e)},_drag:function(a,c,e){var f=Syn.helpers.getWindow(c),h=b(a.from||c,f,c),j=b(a.to||a,f,c);!1!==a.adjust&&d(h,j,f);i(h,j,a.duration||500,c,e)}})})();
\ No newline at end of file
diff --git a/vendor/behat/mink-selenium2-driver/src/Selenium2Driver.php b/vendor/behat/mink-selenium2-driver/src/Selenium2Driver.php
new file mode 100755 (executable)
index 0000000..b0d7ca7
--- /dev/null
@@ -0,0 +1,1097 @@
+<?php
+
+/*
+ * This file is part of the Behat\Mink.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Mink\Driver;
+
+use Behat\Mink\Exception\DriverException;
+use Behat\Mink\Selector\Xpath\Escaper;
+use WebDriver\Element;
+use WebDriver\Exception\NoSuchElement;
+use WebDriver\Exception\UnknownError;
+use WebDriver\Exception;
+use WebDriver\Key;
+use WebDriver\WebDriver;
+
+/**
+ * Selenium2 driver.
+ *
+ * @author Pete Otaqui <pete@otaqui.com>
+ */
+class Selenium2Driver extends CoreDriver
+{
+    /**
+     * Whether the browser has been started
+     * @var Boolean
+     */
+    private $started = false;
+
+    /**
+     * The WebDriver instance
+     * @var WebDriver
+     */
+    private $webDriver;
+
+    /**
+     * @var string
+     */
+    private $browserName;
+
+    /**
+     * @var array
+     */
+    private $desiredCapabilities;
+
+    /**
+     * The WebDriverSession instance
+     * @var \WebDriver\Session
+     */
+    private $wdSession;
+
+    /**
+     * The timeout configuration
+     * @var array
+     */
+    private $timeouts = array();
+
+    /**
+     * @var Escaper
+     */
+    private $xpathEscaper;
+
+    /**
+     * Instantiates the driver.
+     *
+     * @param string $browserName         Browser name
+     * @param array  $desiredCapabilities The desired capabilities
+     * @param string $wdHost              The WebDriver host
+     */
+    public function __construct($browserName = 'firefox', $desiredCapabilities = null, $wdHost = 'http://localhost:4444/wd/hub')
+    {
+        $this->setBrowserName($browserName);
+        $this->setDesiredCapabilities($desiredCapabilities);
+        $this->setWebDriver(new WebDriver($wdHost));
+        $this->xpathEscaper = new Escaper();
+    }
+
+    /**
+     * Sets the browser name
+     *
+     * @param string $browserName the name of the browser to start, default is 'firefox'
+     */
+    protected function setBrowserName($browserName = 'firefox')
+    {
+        $this->browserName = $browserName;
+    }
+
+    /**
+     * Sets the desired capabilities - called on construction.  If null is provided, will set the
+     * defaults as desired.
+     *
+     * See http://code.google.com/p/selenium/wiki/DesiredCapabilities
+     *
+     * @param array $desiredCapabilities an array of capabilities to pass on to the WebDriver server
+     */
+    public function setDesiredCapabilities($desiredCapabilities = null)
+    {
+        if (null === $desiredCapabilities) {
+            $desiredCapabilities = self::getDefaultCapabilities();
+        }
+
+        if (isset($desiredCapabilities['firefox'])) {
+            foreach ($desiredCapabilities['firefox'] as $capability => $value) {
+                switch ($capability) {
+                    case 'profile':
+                        $desiredCapabilities['firefox_'.$capability] = base64_encode(file_get_contents($value));
+                        break;
+                    default:
+                        $desiredCapabilities['firefox_'.$capability] = $value;
+                }
+            }
+
+            unset($desiredCapabilities['firefox']);
+        }
+
+        // See https://sites.google.com/a/chromium.org/chromedriver/capabilities
+        if (isset($desiredCapabilities['chrome'])) {
+
+            $chromeOptions = array();
+
+            foreach ($desiredCapabilities['chrome'] as $capability => $value) {
+                if ($capability == 'switches') {
+                    $chromeOptions['args'] = $value;
+                } else {
+                    $chromeOptions[$capability] = $value;
+                }
+                $desiredCapabilities['chrome.'.$capability] = $value;
+            }
+
+            $desiredCapabilities['chromeOptions'] = $chromeOptions;
+
+            unset($desiredCapabilities['chrome']);
+        }
+
+        $this->desiredCapabilities = $desiredCapabilities;
+    }
+
+    /**
+     * Sets the WebDriver instance
+     *
+     * @param WebDriver $webDriver An instance of the WebDriver class
+     */
+    public function setWebDriver(WebDriver $webDriver)
+    {
+        $this->webDriver = $webDriver;
+    }
+
+    /**
+     * Gets the WebDriverSession instance
+     *
+     * @return \WebDriver\Session
+     */
+    public function getWebDriverSession()
+    {
+        return $this->wdSession;
+    }
+
+    /**
+     * Returns the default capabilities
+     *
+     * @return array
+     */
+    public static function getDefaultCapabilities()
+    {
+        return array(
+            'browserName'       => 'firefox',
+            'version'           => '9',
+            'platform'          => 'ANY',
+            'browserVersion'    => '9',
+            'browser'           => 'firefox',
+            'name'              => 'Behat Test',
+            'deviceOrientation' => 'portrait',
+            'deviceType'        => 'tablet',
+            'selenium-version'  => '2.31.0'
+        );
+    }
+
+    /**
+     * Makes sure that the Syn event library has been injected into the current page,
+     * and return $this for a fluid interface,
+     *
+     *     $this->withSyn()->executeJsOnXpath($xpath, $script);
+     *
+     * @return Selenium2Driver
+     */
+    protected function withSyn()
+    {
+        $hasSyn = $this->wdSession->execute(array(
+            'script' => 'return typeof window["Syn"]!=="undefined" && typeof window["Syn"].trigger!=="undefined"',
+            'args'   => array()
+        ));
+
+        if (!$hasSyn) {
+            $synJs = file_get_contents(__DIR__.'/Resources/syn.js');
+            $this->wdSession->execute(array(
+                'script' => $synJs,
+                'args'   => array()
+            ));
+        }
+
+        return $this;
+    }
+
+    /**
+     * Creates some options for key events
+     *
+     * @param string $char     the character or code
+     * @param string $modifier one of 'shift', 'alt', 'ctrl' or 'meta'
+     *
+     * @return string a json encoded options array for Syn
+     */
+    protected static function charToOptions($char, $modifier = null)
+    {
+        $ord = ord($char);
+        if (is_numeric($char)) {
+            $ord = $char;
+        }
+
+        $options = array(
+            'keyCode'  => $ord,
+            'charCode' => $ord
+        );
+
+        if ($modifier) {
+            $options[$modifier.'Key'] = 1;
+        }
+
+        return json_encode($options);
+    }
+
+    /**
+     * Executes JS on a given element - pass in a js script string and {{ELEMENT}} will
+     * be replaced with a reference to the result of the $xpath query
+     *
+     * @example $this->executeJsOnXpath($xpath, 'return {{ELEMENT}}.childNodes.length');
+     *
+     * @param string  $xpath  the xpath to search with
+     * @param string  $script the script to execute
+     * @param Boolean $sync   whether to run the script synchronously (default is TRUE)
+     *
+     * @return mixed
+     */
+    protected function executeJsOnXpath($xpath, $script, $sync = true)
+    {
+        return $this->executeJsOnElement($this->findElement($xpath), $script, $sync);
+    }
+
+    /**
+     * Executes JS on a given element - pass in a js script string and {{ELEMENT}} will
+     * be replaced with a reference to the element
+     *
+     * @example $this->executeJsOnXpath($xpath, 'return {{ELEMENT}}.childNodes.length');
+     *
+     * @param Element $element the webdriver element
+     * @param string  $script  the script to execute
+     * @param Boolean $sync    whether to run the script synchronously (default is TRUE)
+     *
+     * @return mixed
+     */
+    private function executeJsOnElement(Element $element, $script, $sync = true)
+    {
+        $script  = str_replace('{{ELEMENT}}', 'arguments[0]', $script);
+
+        $options = array(
+            'script' => $script,
+            'args'   => array(array('ELEMENT' => $element->getID())),
+        );
+
+        if ($sync) {
+            return $this->wdSession->execute($options);
+        }
+
+        return $this->wdSession->execute_async($options);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function start()
+    {
+        try {
+            $this->wdSession = $this->webDriver->session($this->browserName, $this->desiredCapabilities);
+            $this->applyTimeouts();
+        } catch (\Exception $e) {
+            throw new DriverException('Could not open connection: '.$e->getMessage(), 0, $e);
+        }
+
+        if (!$this->wdSession) {
+            throw new DriverException('Could not connect to a Selenium 2 / WebDriver server');
+        }
+        $this->started = true;
+    }
+
+    /**
+     * Sets the timeouts to apply to the webdriver session
+     *
+     * @param array $timeouts The session timeout settings: Array of {script, implicit, page} => time in milliseconds
+     *
+     * @throws DriverException
+     */
+    public function setTimeouts($timeouts)
+    {
+        $this->timeouts = $timeouts;
+
+        if ($this->isStarted()) {
+            $this->applyTimeouts();
+        }
+    }
+
+    /**
+     * Applies timeouts to the current session
+     */
+    private function applyTimeouts()
+    {
+        try {
+            foreach ($this->timeouts as $type => $param) {
+                $this->wdSession->timeouts($type, $param);
+            }
+        } catch (UnknownError $e) {
+            throw new DriverException('Error setting timeout: ' . $e->getMessage(), 0, $e);
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function isStarted()
+    {
+        return $this->started;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function stop()
+    {
+        if (!$this->wdSession) {
+            throw new DriverException('Could not connect to a Selenium 2 / WebDriver server');
+        }
+
+        $this->started = false;
+        try {
+            $this->wdSession->close();
+        } catch (\Exception $e) {
+            throw new DriverException('Could not close connection', 0, $e);
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function reset()
+    {
+        $this->wdSession->deleteAllCookies();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function visit($url)
+    {
+        $this->wdSession->open($url);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getCurrentUrl()
+    {
+        return $this->wdSession->url();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function reload()
+    {
+        $this->wdSession->refresh();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function forward()
+    {
+        $this->wdSession->forward();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function back()
+    {
+        $this->wdSession->back();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function switchToWindow($name = null)
+    {
+        $this->wdSession->focusWindow($name ? $name : '');
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function switchToIFrame($name = null)
+    {
+        $this->wdSession->frame(array('id' => $name));
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setCookie($name, $value = null)
+    {
+        if (null === $value) {
+            $this->wdSession->deleteCookie($name);
+
+            return;
+        }
+
+        $cookieArray = array(
+            'name'   => $name,
+            'value'  => urlencode($value),
+            'secure' => false, // thanks, chibimagic!
+        );
+
+        $this->wdSession->setCookie($cookieArray);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getCookie($name)
+    {
+        $cookies = $this->wdSession->getAllCookies();
+        foreach ($cookies as $cookie) {
+            if ($cookie['name'] === $name) {
+                return urldecode($cookie['value']);
+            }
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getContent()
+    {
+        return $this->wdSession->source();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getScreenshot()
+    {
+        return base64_decode($this->wdSession->screenshot());
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getWindowNames()
+    {
+        return $this->wdSession->window_handles();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getWindowName()
+    {
+        return $this->wdSession->window_handle();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function findElementXpaths($xpath)
+    {
+        $nodes = $this->wdSession->elements('xpath', $xpath);
+
+        $elements = array();
+        foreach ($nodes as $i => $node) {
+            $elements[] = sprintf('(%s)[%d]', $xpath, $i+1);
+        }
+
+        return $elements;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getTagName($xpath)
+    {
+        return $this->findElement($xpath)->name();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getText($xpath)
+    {
+        $node = $this->findElement($xpath);
+        $text = $node->text();
+        $text = (string) str_replace(array("\r", "\r\n", "\n"), ' ', $text);
+
+        return $text;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getHtml($xpath)
+    {
+        return $this->executeJsOnXpath($xpath, 'return {{ELEMENT}}.innerHTML;');
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getOuterHtml($xpath)
+    {
+        return $this->executeJsOnXpath($xpath, 'return {{ELEMENT}}.outerHTML;');
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getAttribute($xpath, $name)
+    {
+        $script = 'return {{ELEMENT}}.getAttribute(' . json_encode((string) $name) . ')';
+
+        return $this->executeJsOnXpath($xpath, $script);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getValue($xpath)
+    {
+        $element = $this->findElement($xpath);
+        $elementName = strtolower($element->name());
+        $elementType = strtolower($element->attribute('type'));
+
+        // Getting the value of a checkbox returns its value if selected.
+        if ('input' === $elementName && 'checkbox' === $elementType) {
+            return $element->selected() ? $element->attribute('value') : null;
+        }
+
+        if ('input' === $elementName && 'radio' === $elementType) {
+            $script = <<<JS
+var node = {{ELEMENT}},
+    value = null;
+
+var name = node.getAttribute('name');
+if (name) {
+    var fields = window.document.getElementsByName(name),
+        i, l = fields.length;
+    for (i = 0; i < l; i++) {
+        var field = fields.item(i);
+        if (field.form === node.form && field.checked) {
+            value = field.value;
+            break;
+        }
+    }
+}
+
+return value;
+JS;
+
+            return $this->executeJsOnElement($element, $script);
+        }
+
+        // Using $element->attribute('value') on a select only returns the first selected option
+        // even when it is a multiple select, so a custom retrieval is needed.
+        if ('select' === $elementName && $element->attribute('multiple')) {
+            $script = <<<JS
+var node = {{ELEMENT}},
+    value = [];
+
+for (var i = 0; i < node.options.length; i++) {
+    if (node.options[i].selected) {
+        value.push(node.options[i].value);
+    }
+}
+
+return value;
+JS;
+
+            return $this->executeJsOnElement($element, $script);
+        }
+
+        return $element->attribute('value');
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setValue($xpath, $value)
+    {
+        $element = $this->findElement($xpath);
+        $elementName = strtolower($element->name());
+
+        if ('select' === $elementName) {
+            if (is_array($value)) {
+                $this->deselectAllOptions($element);
+
+                foreach ($value as $option) {
+                    $this->selectOptionOnElement($element, $option, true);
+                }
+
+                return;
+            }
+
+            $this->selectOptionOnElement($element, $value);
+
+            return;
+        }
+
+        if ('input' === $elementName) {
+            $elementType = strtolower($element->attribute('type'));
+
+            if (in_array($elementType, array('submit', 'image', 'button', 'reset'))) {
+                throw new DriverException(sprintf('Impossible to set value an element with XPath "%s" as it is not a select, textarea or textbox', $xpath));
+            }
+
+            if ('checkbox' === $elementType) {
+                if ($element->selected() xor (bool) $value) {
+                    $this->clickOnElement($element);
+                }
+
+                return;
+            }
+
+            if ('radio' === $elementType) {
+                $this->selectRadioValue($element, $value);
+
+                return;
+            }
+
+            if ('file' === $elementType) {
+                $element->postValue(array('value' => array(strval($value))));
+
+                return;
+            }
+        }
+
+        $value = strval($value);
+
+        if (in_array($elementName, array('input', 'textarea'))) {
+            $existingValueLength = strlen($element->attribute('value'));
+            // Add the TAB key to ensure we unfocus the field as browsers are triggering the change event only
+            // after leaving the field.
+            $value = str_repeat(Key::BACKSPACE . Key::DELETE, $existingValueLength) . $value . Key::TAB;
+        }
+
+        $element->postValue(array('value' => array($value)));
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function check($xpath)
+    {
+        $element = $this->findElement($xpath);
+        $this->ensureInputType($element, $xpath, 'checkbox', 'check');
+
+        if ($element->selected()) {
+            return;
+        }
+
+        $this->clickOnElement($element);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function uncheck($xpath)
+    {
+        $element = $this->findElement($xpath);
+        $this->ensureInputType($element, $xpath, 'checkbox', 'uncheck');
+
+        if (!$element->selected()) {
+            return;
+        }
+
+        $this->clickOnElement($element);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function isChecked($xpath)
+    {
+        return $this->findElement($xpath)->selected();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function selectOption($xpath, $value, $multiple = false)
+    {
+        $element = $this->findElement($xpath);
+        $tagName = strtolower($element->name());
+
+        if ('input' === $tagName && 'radio' === strtolower($element->attribute('type'))) {
+            $this->selectRadioValue($element, $value);
+
+            return;
+        }
+
+        if ('select' === $tagName) {
+            $this->selectOptionOnElement($element, $value, $multiple);
+
+            return;
+        }
+
+        throw new DriverException(sprintf('Impossible to select an option on the element with XPath "%s" as it is not a select or radio input', $xpath));
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function isSelected($xpath)
+    {
+        return $this->findElement($xpath)->selected();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function click($xpath)
+    {
+        $this->clickOnElement($this->findElement($xpath));
+    }
+
+    private function clickOnElement(Element $element)
+    {
+        $this->wdSession->moveto(array('element' => $element->getID()));
+        $element->click();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function doubleClick($xpath)
+    {
+        $this->mouseOver($xpath);
+        $this->wdSession->doubleclick();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function rightClick($xpath)
+    {
+        $this->mouseOver($xpath);
+        $this->wdSession->click(array('button' => 2));
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function attachFile($xpath, $path)
+    {
+        $element = $this->findElement($xpath);
+        $this->ensureInputType($element, $xpath, 'file', 'attach a file on');
+
+        $element->postValue(array('value' => array($path)));
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function isVisible($xpath)
+    {
+        return $this->findElement($xpath)->displayed();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function mouseOver($xpath)
+    {
+        $this->wdSession->moveto(array(
+            'element' => $this->findElement($xpath)->getID()
+        ));
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function focus($xpath)
+    {
+        $script = 'Syn.trigger("focus", {}, {{ELEMENT}})';
+        $this->withSyn()->executeJsOnXpath($xpath, $script);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function blur($xpath)
+    {
+        $script = 'Syn.trigger("blur", {}, {{ELEMENT}})';
+        $this->withSyn()->executeJsOnXpath($xpath, $script);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function keyPress($xpath, $char, $modifier = null)
+    {
+        $options = self::charToOptions($char, $modifier);
+        $script = "Syn.trigger('keypress', $options, {{ELEMENT}})";
+        $this->withSyn()->executeJsOnXpath($xpath, $script);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function keyDown($xpath, $char, $modifier = null)
+    {
+        $options = self::charToOptions($char, $modifier);
+        $script = "Syn.trigger('keydown', $options, {{ELEMENT}})";
+        $this->withSyn()->executeJsOnXpath($xpath, $script);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function keyUp($xpath, $char, $modifier = null)
+    {
+        $options = self::charToOptions($char, $modifier);
+        $script = "Syn.trigger('keyup', $options, {{ELEMENT}})";
+        $this->withSyn()->executeJsOnXpath($xpath, $script);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function dragTo($sourceXpath, $destinationXpath)
+    {
+        $source      = $this->findElement($sourceXpath);
+        $destination = $this->findElement($destinationXpath);
+
+        $this->wdSession->moveto(array(
+            'element' => $source->getID()
+        ));
+
+        $script = <<<JS
+(function (element) {
+    var event = document.createEvent("HTMLEvents");
+
+    event.initEvent("dragstart", true, true);
+    event.dataTransfer = {};
+
+    element.dispatchEvent(event);
+}({{ELEMENT}}));
+JS;
+        $this->withSyn()->executeJsOnElement($source, $script);
+
+        $this->wdSession->buttondown();
+        $this->wdSession->moveto(array(
+            'element' => $destination->getID()
+        ));
+        $this->wdSession->buttonup();
+
+        $script = <<<JS
+(function (element) {
+    var event = document.createEvent("HTMLEvents");
+
+    event.initEvent("drop", true, true);
+    event.dataTransfer = {};
+
+    element.dispatchEvent(event);
+}({{ELEMENT}}));
+JS;
+        $this->withSyn()->executeJsOnElement($destination, $script);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function executeScript($script)
+    {
+        if (preg_match('/^function[\s\(]/', $script)) {
+            $script = preg_replace('/;$/', '', $script);
+            $script = '(' . $script . ')';
+        }
+
+        $this->wdSession->execute(array('script' => $script, 'args' => array()));
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function evaluateScript($script)
+    {
+        if (0 !== strpos(trim($script), 'return ')) {
+            $script = 'return ' . $script;
+        }
+
+        return $this->wdSession->execute(array('script' => $script, 'args' => array()));
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function wait($timeout, $condition)
+    {
+        $script = "return $condition;";
+        $start = microtime(true);
+        $end = $start + $timeout / 1000.0;
+
+        do {
+            $result = $this->wdSession->execute(array('script' => $script, 'args' => array()));
+            usleep(100000);
+        } while (microtime(true) < $end && !$result);
+
+        return (bool) $result;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function resizeWindow($width, $height, $name = null)
+    {
+        $this->wdSession->window($name ? $name : 'current')->postSize(
+            array('width' => $width, 'height' => $height)
+        );
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function submitForm($xpath)
+    {
+        $this->findElement($xpath)->submit();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function maximizeWindow($name = null)
+    {
+        $this->wdSession->window($name ? $name : 'current')->maximize();
+    }
+
+    /**
+     * Returns Session ID of WebDriver or `null`, when session not started yet.
+     *
+     * @return string|null
+     */
+    public function getWebDriverSessionId()
+    {
+        return $this->isStarted() ? basename($this->wdSession->getUrl()) : null;
+    }
+
+    /**
+     * @param string $xpath
+     *
+     * @return Element
+     */
+    private function findElement($xpath)
+    {
+        return $this->wdSession->element('xpath', $xpath);
+    }
+
+    /**
+     * Selects a value in a radio button group
+     *
+     * @param Element $element An element referencing one of the radio buttons of the group
+     * @param string  $value   The value to select
+     *
+     * @throws DriverException when the value cannot be found
+     */
+    private function selectRadioValue(Element $element, $value)
+    {
+        // short-circuit when we already have the right button of the group to avoid XPath queries
+        if ($element->attribute('value') === $value) {
+            $element->click();
+
+            return;
+        }
+
+        $name = $element->attribute('name');
+
+        if (!$name) {
+            throw new DriverException(sprintf('The radio button does not have the value "%s"', $value));
+        }
+
+        $formId = $element->attribute('form');
+
+        try {
+            if (null !== $formId) {
+                $xpath = <<<'XPATH'
+//form[@id=%1$s]//input[@type="radio" and not(@form) and @name=%2$s and @value = %3$s]
+|
+//input[@type="radio" and @form=%1$s and @name=%2$s and @value = %3$s]
+XPATH;
+
+                $xpath = sprintf(
+                    $xpath,
+                    $this->xpathEscaper->escapeLiteral($formId),
+                    $this->xpathEscaper->escapeLiteral($name),
+                    $this->xpathEscaper->escapeLiteral($value)
+                );
+                $input = $this->wdSession->element('xpath', $xpath);
+            } else {
+                $xpath = sprintf(
+                    './ancestor::form//input[@type="radio" and not(@form) and @name=%s and @value = %s]',
+                    $this->xpathEscaper->escapeLiteral($name),
+                    $this->xpathEscaper->escapeLiteral($value)
+                );
+                $input = $element->element('xpath', $xpath);
+            }
+        } catch (NoSuchElement $e) {
+            $message = sprintf('The radio group "%s" does not have an option "%s"', $name, $value);
+
+            throw new DriverException($message, 0, $e);
+        }
+
+        $input->click();
+    }
+
+    /**
+     * @param Element $element
+     * @param string  $value
+     * @param bool    $multiple
+     */
+    private function selectOptionOnElement(Element $element, $value, $multiple = false)
+    {
+        $escapedValue = $this->xpathEscaper->escapeLiteral($value);
+        // The value of an option is the normalized version of its text when it has no value attribute
+        $optionQuery = sprintf('.//option[@value = %s or (not(@value) and normalize-space(.) = %s)]', $escapedValue, $escapedValue);
+        $option = $element->element('xpath', $optionQuery);
+
+        if ($multiple || !$element->attribute('multiple')) {
+            if (!$option->selected()) {
+                $option->click();
+            }
+
+            return;
+        }
+
+        // Deselect all options before selecting the new one
+        $this->deselectAllOptions($element);
+        $option->click();
+    }
+
+    /**
+     * Deselects all options of a multiple select
+     *
+     * Note: this implementation does not trigger a change event after deselecting the elements.
+     *
+     * @param Element $element
+     */
+    private function deselectAllOptions(Element $element)
+    {
+        $script = <<<JS
+var node = {{ELEMENT}};
+var i, l = node.options.length;
+for (i = 0; i < l; i++) {
+    node.options[i].selected = false;
+}
+JS;
+
+        $this->executeJsOnElement($element, $script);
+    }
+
+    /**
+     * Ensures the element is a checkbox
+     *
+     * @param Element $element
+     * @param string  $xpath
+     * @param string  $type
+     * @param string  $action
+     *
+     * @throws DriverException
+     */
+    private function ensureInputType(Element $element, $xpath, $type, $action)
+    {
+        if ('input' !== strtolower($element->name()) || $type !== strtolower($element->attribute('type'))) {
+            $message = 'Impossible to %s the element with XPath "%s" as it is not a %s input';
+
+            throw new DriverException(sprintf($message, $action, $xpath, $type));
+        }
+    }
+}
diff --git a/vendor/behat/mink-selenium2-driver/tests/Custom/TimeoutTest.php b/vendor/behat/mink-selenium2-driver/tests/Custom/TimeoutTest.php
new file mode 100644 (file)
index 0000000..7cda495
--- /dev/null
@@ -0,0 +1,39 @@
+<?php
+
+namespace Behat\Mink\Tests\Driver\Custom;
+
+use Behat\Mink\Tests\Driver\TestCase;
+
+class TimeoutTest extends TestCase
+{
+    /**
+     * @expectedException \Behat\Mink\Exception\DriverException
+     */
+    public function testInvalidTimeoutSettingThrowsException()
+    {
+        $this->getSession()->getDriver()->setTimeouts(array('invalid' => 0));
+    }
+
+    public function testShortTimeoutDoesNotWaitForElementToAppear()
+    {
+        $this->getSession()->getDriver()->setTimeouts(array('implicit' => 0));
+
+        $this->getSession()->visit($this->pathTo('/js_test.html'));
+        $this->findById('waitable')->click();
+
+        $element = $this->getSession()->getPage()->find('css', '#waitable > div');
+
+        $this->assertNull($element);
+    }
+
+    public function testLongTimeoutWaitsForElementToAppear()
+    {
+        $this->getSession()->getDriver()->setTimeouts(array('implicit' => 5000));
+
+        $this->getSession()->visit($this->pathTo('/js_test.html'));
+        $this->findById('waitable')->click();
+        $element = $this->getSession()->getPage()->find('css', '#waitable > div');
+
+        $this->assertNotNull($element);
+    }
+}
diff --git a/vendor/behat/mink-selenium2-driver/tests/Custom/WebDriverTest.php b/vendor/behat/mink-selenium2-driver/tests/Custom/WebDriverTest.php
new file mode 100644 (file)
index 0000000..13734e9
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+
+namespace Behat\Mink\Tests\Driver\Custom;
+
+use Behat\Mink\Driver\Selenium2Driver;
+use Behat\Mink\Tests\Driver\TestCase;
+
+class WebDriverTest extends TestCase
+{
+    public function testGetWebDriverSessionId()
+    {
+        /** @var Selenium2Driver $driver */
+        $driver = $this->getSession()->getDriver();
+        $this->assertNotEmpty($driver->getWebDriverSessionId(), 'Started session has an ID');
+
+        $driver = new Selenium2Driver();
+        $this->assertNull($driver->getWebDriverSessionId(), 'Not started session don\'t have an ID');
+    }
+}
diff --git a/vendor/behat/mink-selenium2-driver/tests/Custom/WindowNameTest.php b/vendor/behat/mink-selenium2-driver/tests/Custom/WindowNameTest.php
new file mode 100644 (file)
index 0000000..2671320
--- /dev/null
@@ -0,0 +1,29 @@
+<?php
+
+namespace Behat\Mink\Tests\Driver\Custom;
+
+use Behat\Mink\Tests\Driver\TestCase;
+
+class WindowNameTest extends TestCase
+{
+    const WINDOW_NAME_REGEXP = '/[a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{12}/i';
+
+    public function testPatternGetWindowNames()
+    {
+        $session = $this->getSession();
+
+        $windowNames = $session->getWindowNames();
+        $this->assertArrayHasKey(0, $windowNames);
+
+        foreach ($windowNames as $name) {
+            $this->assertRegExp(self::WINDOW_NAME_REGEXP, $name);
+        }
+    }
+
+    public function testGetWindowName()
+    {
+        $session = $this->getSession();
+
+        $this->assertRegExp(self::WINDOW_NAME_REGEXP, $session->getWindowName());
+    }
+}
diff --git a/vendor/behat/mink-selenium2-driver/tests/Selenium2Config.php b/vendor/behat/mink-selenium2-driver/tests/Selenium2Config.php
new file mode 100644 (file)
index 0000000..ef3f56d
--- /dev/null
@@ -0,0 +1,80 @@
+<?php
+
+namespace Behat\Mink\Tests\Driver;
+
+use Behat\Mink\Driver\Selenium2Driver;
+
+class Selenium2Config extends AbstractConfig
+{
+    public static function getInstance()
+    {
+        return new self();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function createDriver()
+    {
+        $browser = $_SERVER['WEB_FIXTURES_BROWSER'];
+        $seleniumHost = $_SERVER['DRIVER_URL'];
+
+        return new Selenium2Driver($browser, null, $seleniumHost);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function skipMessage($testCase, $test)
+    {
+        if ('phantomjs' === getenv('WEBDRIVER') && null !== $message = $this->skipPhantomJs($testCase, $test)) {
+            return $message;
+        }
+
+        if (
+            'phantomjs' !== getenv('WEBDRIVER')
+            && 'Behat\Mink\Tests\Driver\Form\Html5Test' === $testCase
+            && 'testHtml5Types' === $test
+        ) {
+            return 'WebDriver does not support setting value in color inputs. See https://code.google.com/p/selenium/issues/detail?id=7650';
+        }
+
+        if (
+            'Behat\Mink\Tests\Driver\Js\WindowTest' === $testCase
+            && 'testWindowMaximize' === $test
+            && 'true' === getenv('TRAVIS')
+        ) {
+            return 'Maximizing the window does not work when running the browser in Xvfb.';
+        }
+
+        return parent::skipMessage($testCase, $test);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function supportsCss()
+    {
+        return true;
+    }
+
+    private function skipPhantomJs($testCase, $test)
+    {
+        if (
+            'Behat\Mink\Tests\Driver\Js\WindowTest' === $testCase
+            && in_array($test, array('testResizeWindow', 'testWindowMaximize'))
+        ) {
+            return 'PhantomJS is headless so resizing the window does not make sense.';
+        }
+
+
+        if (
+            'Behat\Mink\Tests\Driver\Basic\CookieTest' === $testCase
+            && 'testHttpOnlyCookieIsDeleted' === $test
+        ) {
+            return 'This test does not work for PhantomJS. See https://github.com/detro/ghostdriver/issues/170';
+        }
+
+        return null;
+    }
+}
diff --git a/vendor/behat/transliterator/CHANGELOG.md b/vendor/behat/transliterator/CHANGELOG.md
new file mode 100644 (file)
index 0000000..f8031f1
--- /dev/null
@@ -0,0 +1,22 @@
+
+
+1.2.0 / 2017-04-04
+==================
+
+ * Stop Transliterator::postProcessText() breaking words containing apostrophes
+
+1.1.0 / 2015-09-28
+==================
+
+ * Updated unicode bank files
+ * Added a testsuite for the library
+
+1.0.1 / 2014-05-14
+==================
+
+ * fixed the regex used to replace non-word characters
+
+1.0.0 / 2014-01-12
+==================
+
+ * Initial release as a standalone component
diff --git a/vendor/behat/transliterator/CONTRIBUTING.md b/vendor/behat/transliterator/CONTRIBUTING.md
new file mode 100644 (file)
index 0000000..29d047f
--- /dev/null
@@ -0,0 +1,18 @@
+Contributing to Behat Transliterator
+====================================
+
+Updating data
+-------------
+
+Setup dependencies with [Composer](https://getcomposer.org):
+
+```bash
+composer install
+```
+
+Run, char tables in Behat Transliterator will be synced from Perl library 
+using version  defined in `\Behat\Transliterator\SyncTool::LIB_VERSION`
+
+```bash
+bin/update-data
+```
diff --git a/vendor/behat/transliterator/LICENSE b/vendor/behat/transliterator/LICENSE
new file mode 100644 (file)
index 0000000..886394c
--- /dev/null
@@ -0,0 +1,128 @@
+                        The "Artistic License"
+
+                               Preamble
+
+The intent of this document is to state the conditions under which a
+Package may be copied, such that the Copyright Holder maintains some
+semblance of artistic control over the development of the package,
+while giving the users of the package the right to use and distribute
+the Package in a more-or-less customary fashion, plus the right to make
+reasonable modifications.
+
+Definitions:
+
+       "Package" refers to the collection of files distributed by the
+       Copyright Holder, and derivatives of that collection of files
+       created through textual modification.
+
+       "Standard Version" refers to such a Package if it has not been
+       modified, or has been modified in accordance with the wishes
+       of the Copyright Holder as specified below.
+
+       "Copyright Holder" is whoever is named in the copyright or
+       copyrights for the package.
+
+       "You" is you, if you're thinking about copying or distributing
+       this Package.
+
+       "Reasonable copying fee" is whatever you can justify on the
+       basis of media cost, duplication charges, time of people involved,
+       and so on.  (You will not be required to justify it to the
+       Copyright Holder, but only to the computing community at large
+       as a market that must bear the fee.)
+
+       "Freely Available" means that no fee is charged for the item
+       itself, though there may be fees involved in handling the item.
+       It also means that recipients of the item may redistribute it
+       under the same conditions they received it.
+
+1. You may make and give away verbatim copies of the source form of the
+Standard Version of this Package without restriction, provided that you
+duplicate all of the original copyright notices and associated disclaimers.
+
+2. You may apply bug fixes, portability fixes and other modifications
+derived from the Public Domain or from the Copyright Holder.  A Package
+modified in such a way shall still be considered the Standard Version.
+
+3. You may otherwise modify your copy of this Package in any way, provided
+that you insert a prominent notice in each changed file stating how and
+when you changed that file, and provided that you do at least ONE of the
+following:
+
+    a) place your modifications in the Public Domain or otherwise make them
+    Freely Available, such as by posting said modifications to Usenet or
+    an equivalent medium, or placing the modifications on a major archive
+    site such as uunet.uu.net, or by allowing the Copyright Holder to include
+    your modifications in the Standard Version of the Package.
+
+    b) use the modified Package only within your corporation or organization.
+
+    c) rename any non-standard executables so the names do not conflict
+    with standard executables, which must also be provided, and provide
+    a separate manual page for each non-standard executable that clearly
+    documents how it differs from the Standard Version.
+
+    d) make other distribution arrangements with the Copyright Holder.
+
+4. You may distribute the programs of this Package in object code or
+executable form, provided that you do at least ONE of the following:
+
+    a) distribute a Standard Version of the executables and library files,
+    together with instructions (in the manual page or equivalent) on where
+    to get the Standard Version.
+
+    b) accompany the distribution with the machine-readable source of
+    the Package with your modifications.
+
+    c) give non-standard executables non-standard names, and clearly
+    document the differences in manual pages (or equivalent), together
+    with instructions on where to get the Standard Version.
+
+    d) make other distribution arrangements with the Copyright Holder.
+
+5. You may charge a reasonable copying fee for any distribution of this
+Package.  You may charge any fee you choose for support of this
+Package.  You may not charge a fee for this Package itself.  However,
+you may distribute this Package in aggregate with other (possibly
+commercial) programs as part of a larger (possibly commercial) software
+distribution provided that you do not advertise this Package as a
+product of your own.  You may embed this Package's interpreter within
+an executable of yours (by linking); this shall be construed as a mere
+form of aggregation, provided that the complete Standard Version of the
+interpreter is so embedded.
+
+6. The scripts and library files supplied as input to or produced as
+output from the programs of this Package do not automatically fall
+under the copyright of this Package, but belong to whoever generated
+them, and may be sold commercially, and may be aggregated with this
+Package.  If such scripts or library files are aggregated with this
+Package via the so-called "undump" or "unexec" methods of producing a
+binary executable image, then distribution of such an image shall
+neither be construed as a distribution of this Package nor shall it
+fall under the restrictions of Paragraphs 3 and 4, provided that you do
+not represent such an executable image as a Standard Version of this
+Package.
+
+7. C subroutines (or comparably compiled subroutines in other
+languages) supplied by you and linked into this Package in order to
+emulate subroutines and variables of the language defined by this
+Package shall not be considered part of this Package, but are the
+equivalent of input as in Paragraph 6, provided these subroutines do
+not change the language in any way that would cause it to fail the
+regression tests for the language.
+
+8. Aggregation of this Package with a commercial distribution is always
+permitted provided that the use of this Package is embedded; that is,
+when no overt attempt is made to make this Package's interfaces visible
+to the end user of the commercial distribution.  Such use shall not be
+construed as a distribution of this Package.
+
+9. The name of the Copyright Holder may not be used to endorse or promote
+products derived from this software without specific prior written permission.
+
+10. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+                               The End
+
diff --git a/vendor/behat/transliterator/README.md b/vendor/behat/transliterator/README.md
new file mode 100644 (file)
index 0000000..7847595
--- /dev/null
@@ -0,0 +1,27 @@
+Behat Transliterator
+====================
+
+Behat Transliterator provides transliteration utilities for PHP.
+
+Transliteration data are ported from the [Perl Text-Unidecode module](http://search.cpan.org/~sburke/Text-Unidecode-0.04/lib/Text/Unidecode.pm).
+
+[![License](https://poser.pugx.org/behat/transliterator/license.svg)](https://packagist.org/packages/behat/transliterator)
+[![Build Status](https://travis-ci.org/Behat/Transliterator.svg)](https://travis-ci.org/Behat/Transliterator)
+[![HHVM Status](http://hhvm.h4cc.de/badge/behat/transliterator.svg?branch=master)](http://hhvm.h4cc.de/package/behat/transliterator)
+[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/Behat/Transliterator/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/Behat/Transliterator/?branch=master)
+[![Code Coverage](https://scrutinizer-ci.com/g/Behat/Transliterator/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/Behat/Transliterator/?branch=master)
+[![Total Downloads](https://poser.pugx.org/behat/transliterator/downloads.svg)](https://packagist.org/packages/behat/transliterator)
+
+Installation
+------------
+
+The easiest way to install Behat is by using [Composer](https://getcomposer.org):
+
+```bash
+$ composer require behat/transliterator
+```
+
+Usage
+-----
+
+All features of the library are exposed as static public methods in the [``Behat\Transliterator\Transliterator`` class](src/Behat/Transliterator/Transliterator.php).
diff --git a/vendor/behat/transliterator/composer.json b/vendor/behat/transliterator/composer.json
new file mode 100644 (file)
index 0000000..def1afb
--- /dev/null
@@ -0,0 +1,34 @@
+{
+    "name":         "behat/transliterator",
+    "description":  "String transliterator",
+    "keywords":     ["transliterator", "slug", "i18n"],
+    "type":         "library",
+    "license":      "Artistic-1.0",
+
+    "require": {
+        "php": ">=5.3.3"
+    },
+
+    "require-dev": {
+        "php-yaoi/php-yaoi": "^1.0",
+        "chuyskywalker/rolling-curl": "^3.1"
+    },
+
+    "autoload": {
+        "psr-0": {
+            "Behat\\Transliterator": "src/"
+        }
+    },
+
+    "autoload-dev": {
+        "psr-4": {
+            "Behat\\Tests\\Transliterator\\": "tests"
+        }
+    },
+
+    "extra": {
+        "branch-alias": {
+            "dev-master": "1.2-dev"
+        }
+    }
+}
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/SyncTool.php b/vendor/behat/transliterator/src/Behat/Transliterator/SyncTool.php
new file mode 100644 (file)
index 0000000..87a07c7
--- /dev/null
@@ -0,0 +1,213 @@
+<?php
+
+namespace Behat\Transliterator;
+
+use RollingCurl\Request;
+use RollingCurl\RollingCurl;
+use Yaoi\Command;
+use Yaoi\Command\Option;
+use Yaoi\Http\Client;
+use Yaoi\String\Lexer\Parsed;
+use Yaoi\String\Lexer\Parser;
+use Yaoi\String\Lexer\Renderer;
+use Yaoi\String\Lexer\Token;
+use Yaoi\String\StringValue;
+use Yaoi\String\Parser as StringParser;
+
+/**
+ * Tool for converting char tables for Behat/Transliterator from Perl to PHP
+ * @internal
+ */
+class SyncTool extends Command
+{
+    const LIB_VERSION = '1.27';
+
+    private $tokenizer;
+    private $renderer;
+    private $phpTable;
+    private $itemIndex;
+    private $nonQuestionBoxFound;
+    private $block;
+
+    public function __construct()
+    {
+        $escape = array(
+            '\\}' => '}',
+            '\\\\' => '\\',
+            '\\{' => '{',
+            '\\@' => '@',
+            '\\$' => '$',
+        );
+
+        $this->tokenizer = new Parser();
+        $this->tokenizer->addLineStopper('#');
+        $this->tokenizer->addQuote('qq{', '}', $escape);
+        $this->tokenizer->addQuote('q{', '}', $escape);
+        $this->tokenizer->addQuote('"', '"');
+        $this->tokenizer->addQuote("'", "'");
+        $this->tokenizer->addBracket('[', ']');
+        $this->tokenizer->addDelimiter(';');
+
+        $this->renderer = new Renderer();
+        $this->renderer
+            ->setBindKey('-~z', 'z~-')
+            ->strip('#')
+            ->keepBoundaries('[');
+    }
+
+    public static function setUpDefinition(\Yaoi\Command\Definition $definition, $options)
+    {
+        $definition->name = 'update-data';
+        $definition->description = 'Tool for converting char tables for Behat/Transliterator from Perl to PHP';
+    }
+
+    public function performAction()
+    {
+        $rollingCurl = new RollingCurl();
+
+        foreach ($this->getPerlTablesUrlList() as $url) {
+            $rollingCurl->get($url);
+        }
+
+        $rollingCurl->setCallback(function (Request $request, RollingCurl $rollingCurl) {
+            $this->response->addContent($request->getUrl());
+            $content = $request->getResponseText();
+            $this->parsePerlTable($content);
+        })
+            ->execute();
+    }
+
+    private function removePhpCharTable($phpFilePath, $reason)
+    {
+        $this->response->addContent($reason);
+        if (file_exists($phpFilePath)) {
+            if (unlink($phpFilePath)) {
+                $this->response->success('Deleted');
+            } else {
+                $this->response->error('Failed to delete');
+            }
+        } else {
+            $this->response->success('No PHP file, skipped');
+        }
+    }
+
+    private function pushItem($item)
+    {
+        if ($this->itemIndex >= 16) {
+            $this->phpTable = trim($this->phpTable);
+            $this->phpTable .= "\n";
+            $this->itemIndex = 0;
+        }
+        ++$this->itemIndex;
+
+        $item = new StringValue($item);
+        if ($item->starts('\x') || $item->starts('\n')) {
+            $this->phpTable .= '"' . $item . '", ';
+            $this->nonQuestionBoxFound = true;
+        } else {
+            // TODO check if this hack should be removed for chinese letters
+            if ($item->value === '[?] ') {
+                $item->value = '[?]';
+            }
+            //
+
+            if ($item->value !== '[?]') {
+                $this->nonQuestionBoxFound = true;
+            }
+
+            $this->phpTable .= "'" . str_replace(array('\\', '\''), array('\\\\', '\\\''), $item) . "', ";
+        }
+    }
+
+    private function tokenizePerlTable($content)
+    {
+        $tokens = $this->tokenizer->tokenize($content);
+
+        $expression = $this->renderer->getExpression($tokens);
+        $statement = $expression->getStatement();
+        /** @var Parsed[] $binds */
+        $binds = $expression->getBinds();
+
+        $parser = new StringParser($statement);
+        $block = (string)$parser->inner('$Text::Unidecode::Char[', ']');
+        if (!$block) {
+            throw new \Exception('Block not found');
+        }
+        $this->block = $this->renderer->getExpression($binds[$block])->getStatement();
+
+        $itemsBind = (string)$parser->inner('[', ']');
+
+        if (!$itemsBind) {
+            $items = array();
+        }
+        else {
+            $items = $binds[$itemsBind];
+        }
+
+        return $items;
+    }
+
+    private function parsePerlTable($content)
+    {
+        $items = $this->tokenizePerlTable($content);
+
+        $phpFilePath = __DIR__ . '/data/' . substr($this->block, 1) . '.php';
+        if (!$items) {
+            $this->removePhpCharTable($phpFilePath, 'Empty char table for block ' . $this->block);
+            return;
+        }
+
+        $this->phpTable = <<<PHP
+<?php
+\$UTF8_TO_ASCII[$this->block] = array(
+
+PHP;
+
+        $itemsExpression = $this->renderer->getExpression($items);
+        $itemsStatement = $itemsExpression->getStatement();
+        $itemsBinds = $itemsExpression->getBinds();
+
+        $itemsStatement = explode(',', $itemsStatement);
+        $this->itemIndex = 0;
+        $this->nonQuestionBoxFound = false;
+        foreach ($itemsStatement as $item) {
+            $item = trim($item);
+            if (!$item) {
+                break;
+            }
+
+            if (isset($itemsBinds[$item])) {
+                /** @var Token $token */
+                $token = $itemsBinds[$item];
+                $item = $token->unEscapedContent;
+            }
+
+            $this->pushItem($item);
+        }
+
+        if ($this->nonQuestionBoxFound) {
+            $this->phpTable = trim($this->phpTable) . "\n" . ');' . "\n";
+            if (file_put_contents($phpFilePath, $this->phpTable)) {
+                $this->response->success('Block ' . $this->block . ' converted to ' . $phpFilePath);
+            } else {
+                $this->response->error('Failed to save ' . $phpFilePath);
+            }
+        } else {
+            $this->removePhpCharTable($phpFilePath, 'Block ' . $this->block . ' contains only [?]');
+        }
+
+    }
+
+    private function getPerlTablesUrlList()
+    {
+        $client = new Client();
+        $list = array();
+        $page = $client->fetch('http://cpansearch.perl.org/src/SBURKE/Text-Unidecode-' . self::LIB_VERSION . '/lib/Text/Unidecode/');
+        foreach (StringParser::create($page)->innerAll('.pm">', '</a>') as $xXXpm) {
+            $list[] = 'http://cpansearch.perl.org/src/SBURKE/Text-Unidecode-' . self::LIB_VERSION . '/lib/Text/Unidecode/'
+                . $xXXpm;
+        }
+        return $list;
+    }
+}
+
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/Transliterator.php b/vendor/behat/transliterator/src/Behat/Transliterator/Transliterator.php
new file mode 100644 (file)
index 0000000..5dc07d3
--- /dev/null
@@ -0,0 +1,590 @@
+<?php
+
+namespace Behat\Transliterator;
+
+/**
+ * This is the part taken from Doctrine 1.2.3
+ * Doctrine inflector has static methods for inflecting text.
+ *
+ * The methods in these classes are from several different sources collected
+ * across several different php projects and several different authors. The
+ * original author names and emails are not known
+ *
+ * Uses 3rd party libraries and functions:
+ *         http://sourceforge.net/projects/phputf8
+ *
+ * @license        http://www.opensource.org/licenses/lgpl-license.php LGPL
+ *
+ * @since          1.0
+ *
+ * @author         Konsta Vesterinen <kvesteri@cc.hut.fi>
+ * @author         Jonathan H. Wage <jonwage@gmail.com>
+ * @author         <hsivonen@iki.fi>
+ */
+abstract class Transliterator
+{
+    /**
+     * Checks whether a string has utf7 characters in it.
+     *
+     * By bmorel at ssi dot fr
+     *
+     * @param string $string
+     *
+     * @return bool
+     */
+    public static function seemsUtf8($string)
+    {
+        $stringLength = strlen($string);
+
+        for ($i = 0; $i < $stringLength; ++$i) {
+            if (ord($string[$i]) < 0x80) { // 0bbbbbbb
+                continue;
+            }  elseif ((ord($string[$i]) & 0xE0) == 0xC0) { // 110bbbbb
+                $n = 1;
+            } elseif ((ord($string[$i]) & 0xF0) == 0xE0) { //1110bbbb
+                $n = 2;
+            } elseif ((ord($string[$i]) & 0xF8) == 0xF0) { // 11110bbb
+                $n = 3;
+            } elseif ((ord($string[$i]) & 0xFC) == 0xF8) { // 111110bb
+                $n = 4;
+            } elseif ((ord($string[$i]) & 0xFE) == 0xFC) { // 1111110b
+                $n = 5;
+            } else {
+                return false; // Does not match any model
+            }
+
+            for ($j = 0; $j < $n; ++$j) { // n bytes matching 10bbbbbb follow ?
+                if (++$i === $stringLength || ((ord($string[$i]) & 0xC0) !== 0x80)) {
+                    return false;
+                }
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Replaces accentuated chars (and a few others) with their ASCII base char.
+     *
+     * @see Transliterator::utf8ToAscii for a full transliteration to ASCII
+     *
+     * @param string $string String to unaccent
+     *
+     * @return string Unaccented string
+     */
+    public static function unaccent($string)
+    {
+        if (!preg_match('/[\x80-\xff]/', $string)) {
+            return $string;
+        }
+
+        if (self::seemsUtf8($string)) {
+            $chars = array(
+                // Decompositions for Latin-1 Supplement
+                chr(195).chr(128) => 'A',
+                chr(195).chr(129) => 'A',
+                chr(195).chr(130) => 'A',
+                chr(195).chr(131) => 'A',
+                chr(195).chr(132) => 'A',
+                chr(195).chr(133) => 'A',
+                chr(195).chr(135) => 'C',
+                chr(195).chr(136) => 'E',
+                chr(195).chr(137) => 'E',
+                chr(195).chr(138) => 'E',
+                chr(195).chr(139) => 'E',
+                chr(195).chr(140) => 'I',
+                chr(195).chr(141) => 'I',
+                chr(195).chr(142) => 'I',
+                chr(195).chr(143) => 'I',
+                chr(195).chr(145) => 'N',
+                chr(195).chr(146) => 'O',
+                chr(195).chr(147) => 'O',
+                chr(195).chr(148) => 'O',
+                chr(195).chr(149) => 'O',
+                chr(195).chr(150) => 'O',
+                chr(195).chr(153) => 'U',
+                chr(195).chr(154) => 'U',
+                chr(195).chr(155) => 'U',
+                chr(195).chr(156) => 'U',
+                chr(195).chr(157) => 'Y',
+                chr(195).chr(159) => 's',
+                chr(195).chr(160) => 'a',
+                chr(195).chr(161) => 'a',
+                chr(195).chr(162) => 'a',
+                chr(195).chr(163) => 'a',
+                chr(195).chr(164) => 'a',
+                chr(195).chr(165) => 'a',
+                chr(195).chr(167) => 'c',
+                chr(195).chr(168) => 'e',
+                chr(195).chr(169) => 'e',
+                chr(195).chr(170) => 'e',
+                chr(195).chr(171) => 'e',
+                chr(195).chr(172) => 'i',
+                chr(195).chr(173) => 'i',
+                chr(195).chr(174) => 'i',
+                chr(195).chr(175) => 'i',
+                chr(195).chr(177) => 'n',
+                chr(195).chr(178) => 'o',
+                chr(195).chr(179) => 'o',
+                chr(195).chr(180) => 'o',
+                chr(195).chr(181) => 'o',
+                chr(195).chr(182) => 'o',
+                chr(195).chr(182) => 'o',
+                chr(195).chr(185) => 'u',
+                chr(195).chr(186) => 'u',
+                chr(195).chr(187) => 'u',
+                chr(195).chr(188) => 'u',
+                chr(195).chr(189) => 'y',
+                chr(195).chr(191) => 'y',
+                // Decompositions for Latin Extended-A
+                chr(196).chr(128) => 'A',
+                chr(196).chr(129) => 'a',
+                chr(196).chr(130) => 'A',
+                chr(196).chr(131) => 'a',
+                chr(196).chr(132) => 'A',
+                chr(196).chr(133) => 'a',
+                chr(196).chr(134) => 'C',
+                chr(196).chr(135) => 'c',
+                chr(196).chr(136) => 'C',
+                chr(196).chr(137) => 'c',
+                chr(196).chr(138) => 'C',
+                chr(196).chr(139) => 'c',
+                chr(196).chr(140) => 'C',
+                chr(196).chr(141) => 'c',
+                chr(196).chr(142) => 'D',
+                chr(196).chr(143) => 'd',
+                chr(196).chr(144) => 'D',
+                chr(196).chr(145) => 'd',
+                chr(196).chr(146) => 'E',
+                chr(196).chr(147) => 'e',
+                chr(196).chr(148) => 'E',
+                chr(196).chr(149) => 'e',
+                chr(196).chr(150) => 'E',
+                chr(196).chr(151) => 'e',
+                chr(196).chr(152) => 'E',
+                chr(196).chr(153) => 'e',
+                chr(196).chr(154) => 'E',
+                chr(196).chr(155) => 'e',
+                chr(196).chr(156) => 'G',
+                chr(196).chr(157) => 'g',
+                chr(196).chr(158) => 'G',
+                chr(196).chr(159) => 'g',
+                chr(196).chr(160) => 'G',
+                chr(196).chr(161) => 'g',
+                chr(196).chr(162) => 'G',
+                chr(196).chr(163) => 'g',
+                chr(196).chr(164) => 'H',
+                chr(196).chr(165) => 'h',
+                chr(196).chr(166) => 'H',
+                chr(196).chr(167) => 'h',
+                chr(196).chr(168) => 'I',
+                chr(196).chr(169) => 'i',
+                chr(196).chr(170) => 'I',
+                chr(196).chr(171) => 'i',
+                chr(196).chr(172) => 'I',
+                chr(196).chr(173) => 'i',
+                chr(196).chr(174) => 'I',
+                chr(196).chr(175) => 'i',
+                chr(196).chr(176) => 'I',
+                chr(196).chr(177) => 'i',
+                chr(196).chr(178) => 'IJ',
+                chr(196).chr(179) => 'ij',
+                chr(196).chr(180) => 'J',
+                chr(196).chr(181) => 'j',
+                chr(196).chr(182) => 'K',
+                chr(196).chr(183) => 'k',
+                chr(196).chr(184) => 'k',
+                chr(196).chr(185) => 'L',
+                chr(196).chr(186) => 'l',
+                chr(196).chr(187) => 'L',
+                chr(196).chr(188) => 'l',
+                chr(196).chr(189) => 'L',
+                chr(196).chr(190) => 'l',
+                chr(196).chr(191) => 'L',
+                chr(197).chr(128) => 'l',
+                chr(197).chr(129) => 'L',
+                chr(197).chr(130) => 'l',
+                chr(197).chr(131) => 'N',
+                chr(197).chr(132) => 'n',
+                chr(197).chr(133) => 'N',
+                chr(197).chr(134) => 'n',
+                chr(197).chr(135) => 'N',
+                chr(197).chr(136) => 'n',
+                chr(197).chr(137) => 'N',
+                chr(197).chr(138) => 'n',
+                chr(197).chr(139) => 'N',
+                chr(197).chr(140) => 'O',
+                chr(197).chr(141) => 'o',
+                chr(197).chr(142) => 'O',
+                chr(197).chr(143) => 'o',
+                chr(197).chr(144) => 'O',
+                chr(197).chr(145) => 'o',
+                chr(197).chr(146) => 'OE',
+                chr(197).chr(147) => 'oe',
+                chr(197).chr(148) => 'R',
+                chr(197).chr(149) => 'r',
+                chr(197).chr(150) => 'R',
+                chr(197).chr(151) => 'r',
+                chr(197).chr(152) => 'R',
+                chr(197).chr(153) => 'r',
+                chr(197).chr(154) => 'S',
+                chr(197).chr(155) => 's',
+                chr(197).chr(156) => 'S',
+                chr(197).chr(157) => 's',
+                chr(197).chr(158) => 'S',
+                chr(197).chr(159) => 's',
+                chr(197).chr(160) => 'S',
+                chr(197).chr(161) => 's',
+                chr(197).chr(162) => 'T',
+                chr(197).chr(163) => 't',
+                chr(197).chr(164) => 'T',
+                chr(197).chr(165) => 't',
+                chr(197).chr(166) => 'T',
+                chr(197).chr(167) => 't',
+                chr(197).chr(168) => 'U',
+                chr(197).chr(169) => 'u',
+                chr(197).chr(170) => 'U',
+                chr(197).chr(171) => 'u',
+                chr(197).chr(172) => 'U',
+                chr(197).chr(173) => 'u',
+                chr(197).chr(174) => 'U',
+                chr(197).chr(175) => 'u',
+                chr(197).chr(176) => 'U',
+                chr(197).chr(177) => 'u',
+                chr(197).chr(178) => 'U',
+                chr(197).chr(179) => 'u',
+                chr(197).chr(180) => 'W',
+                chr(197).chr(181) => 'w',
+                chr(197).chr(182) => 'Y',
+                chr(197).chr(183) => 'y',
+                chr(197).chr(184) => 'Y',
+                chr(197).chr(185) => 'Z',
+                chr(197).chr(186) => 'z',
+                chr(197).chr(187) => 'Z',
+                chr(197).chr(188) => 'z',
+                chr(197).chr(189) => 'Z',
+                chr(197).chr(190) => 'z',
+                chr(197).chr(191) => 's',
+                // Euro Sign
+                chr(226).chr(130).chr(172) => 'E',
+                // GBP (Pound) Sign
+                chr(194).chr(163) => '',
+                'Ä' => 'Ae',
+                'ä' => 'ae',
+                'Ü' => 'Ue',
+                'ü' => 'ue',
+                'Ö' => 'Oe',
+                'ö' => 'oe',
+                'ß' => 'ss',
+                // Norwegian characters
+                'Å' => 'Aa',
+                'Æ' => 'Ae',
+                'Ø' => 'O',
+                'æ' => 'a',
+                'ø' => 'o',
+                'å' => 'aa',
+            );
+
+            $string = strtr($string, $chars);
+        } else {
+            $chars = array();
+            // Assume ISO-8859-1 if not UTF-8
+            $chars['in'] = chr(128).chr(131).chr(138).chr(142).chr(154).chr(158)
+                .chr(159).chr(162).chr(165).chr(181).chr(192).chr(193).chr(194)
+                .chr(195).chr(196).chr(197).chr(199).chr(200).chr(201).chr(202)
+                .chr(203).chr(204).chr(205).chr(206).chr(207).chr(209).chr(210)
+                .chr(211).chr(212).chr(213).chr(214).chr(216).chr(217).chr(218)
+                .chr(219).chr(220).chr(221).chr(224).chr(225).chr(226).chr(227)
+                .chr(228).chr(229).chr(231).chr(232).chr(233).chr(234).chr(235)
+                .chr(236).chr(237).chr(238).chr(239).chr(241).chr(242).chr(243)
+                .chr(244).chr(245).chr(246).chr(248).chr(249).chr(250).chr(251)
+                .chr(252).chr(253).chr(255);
+
+            $chars['out'] = 'EfSZszYcYuAAAAAACEEEEIIIINOOOOOOUUUUYaaaaaaceeeeiiiinoooooouuuuyy';
+
+            $string = strtr($string, $chars['in'], $chars['out']);
+
+            $doubleChars = array();
+            $doubleChars['in'] = array(
+                chr(140),
+                chr(156),
+                chr(198),
+                chr(208),
+                chr(222),
+                chr(223),
+                chr(230),
+                chr(240),
+                chr(254),
+            );
+            $doubleChars['out'] = array('OE', 'oe', 'AE', 'DH', 'TH', 'ss', 'ae', 'dh', 'th');
+            $string = str_replace($doubleChars['in'], $doubleChars['out'], $string);
+        }
+
+        return $string;
+    }
+
+    /**
+     * Transliterates an UTF-8 string to ASCII.
+     *
+     * US-ASCII transliterations of Unicode text
+     * Ported Sean M. Burke's Text::Unidecode Perl module (He did all the hard work!)
+     * Warning: you should only pass this well formed UTF-8!
+     * Be aware it works by making a copy of the input string which it appends transliterated
+     * characters to - it uses a PHP output buffer to do this - it means, memory use will increase,
+     * requiring up to the same amount again as the input string.
+     *
+     * @see http://search.cpan.org/~sburke/Text-Unidecode-0.04/lib/Text/Unidecode.pm
+     *
+     * @author <hsivonen@iki.fi>
+     *
+     * @param string $str     UTF-8 string to convert
+     * @param string $unknown Character use if character unknown (default to ?)
+     *
+     * @return string US-ASCII string
+     */
+    public static function utf8ToAscii($str, $unknown = '?')
+    {
+        static $UTF8_TO_ASCII;
+
+        if (strlen($str) == 0) {
+            return '';
+        }
+
+        preg_match_all('/.{1}|[^\x00]{1,1}$/us', $str, $ar);
+        $chars = $ar[0];
+
+        foreach ($chars as $i => $c) {
+            if (ord($c{0}) >= 0 && ord($c{0}) <= 127) {
+                continue;
+            } // ASCII - next please
+            if (ord($c{0}) >= 192 && ord($c{0}) <= 223) {
+                $ord = (ord($c{0}) - 192) * 64 + (ord($c{1}) - 128);
+            }
+            if (ord($c{0}) >= 224 && ord($c{0}) <= 239) {
+                $ord = (ord($c{0}) - 224) * 4096 + (ord($c{1}) - 128) * 64 + (ord($c{2}) - 128);
+            }
+            if (ord($c{0}) >= 240 && ord($c{0}) <= 247) {
+                $ord = (ord($c{0}) - 240) * 262144 + (ord($c{1}) - 128) * 4096 + (ord($c{2}) - 128) * 64 + (ord($c{3}) - 128);
+            }
+            if (ord($c{0}) >= 248 && ord($c{0}) <= 251) {
+                $ord = (ord($c{0}) - 248) * 16777216 + (ord($c{1}) - 128) * 262144 + (ord($c{2}) - 128) * 4096 + (ord($c{3}) - 128) * 64 + (ord($c{4}) - 128);
+            }
+            if (ord($c{0}) >= 252 && ord($c{0}) <= 253) {
+                $ord = (ord($c{0}) - 252) * 1073741824 + (ord($c{1}) - 128) * 16777216 + (ord($c{2}) - 128) * 262144 + (ord($c{3}) - 128) * 4096 + (ord($c{4}) - 128) * 64 + (ord($c{5}) - 128);
+            }
+            if (ord($c{0}) >= 254 && ord($c{0}) <= 255) {
+                $chars{$i} = $unknown;
+                continue;
+            } //error
+
+            $bank = $ord >> 8;
+
+            if (!array_key_exists($bank, (array) $UTF8_TO_ASCII)) {
+                $bankfile = __DIR__.'/data/'.sprintf('x%02x', $bank).'.php';
+                if (file_exists($bankfile)) {
+                    include $bankfile;
+                } else {
+                    $UTF8_TO_ASCII[$bank] = array();
+                }
+            }
+
+            $newchar = $ord & 255;
+            if (array_key_exists($newchar, $UTF8_TO_ASCII[$bank])) {
+                $chars{$i} = $UTF8_TO_ASCII[$bank][$newchar];
+            } else {
+                $chars{$i} = $unknown;
+            }
+        }
+
+        return implode('', $chars);
+    }
+
+    /**
+     * Generates a slug of the text.
+     *
+     * Does not transliterate correctly eastern languages.
+     *
+     * @see Transliterator::unaccent for the transliteration logic
+     *
+     * @param string $text
+     * @param string $separator
+     *
+     * @return string
+     */
+    public static function urlize($text, $separator = '-')
+    {
+        $text = self::unaccent($text);
+
+        return self::postProcessText($text, $separator);
+    }
+
+    /**
+     * Generates a slug of the text after transliterating the UTF-8 string to ASCII.
+     *
+     * Uses transliteration tables to convert any kind of utf8 character.
+     *
+     * @param string $text
+     * @param string $separator
+     *
+     * @return string $text
+     */
+    public static function transliterate($text, $separator = '-')
+    {
+        if (preg_match('/[\x80-\xff]/', $text) && self::validUtf8($text)) {
+            $text = self::utf8ToAscii($text);
+        }
+
+        return self::postProcessText($text, $separator);
+    }
+
+    /**
+     * Tests a string as to whether it's valid UTF-8 and supported by the
+     * Unicode standard.
+     *
+     * Note: this function has been modified to simple return true or false
+     *
+     * @author <hsivonen@iki.fi>
+     *
+     * @param string $str UTF-8 encoded string
+     *
+     * @return bool
+     *
+     * @see    http://hsivonen.iki.fi/php-utf8/
+     */
+    public static function validUtf8($str)
+    {
+        $mState = 0; // cached expected number of octets after the current octet
+        // until the beginning of the next UTF8 character sequence
+        $mUcs4 = 0; // cached Unicode character
+        $mBytes = 1; // cached expected number of octets in the current sequence
+
+        $len = strlen($str);
+        for ($i = 0; $i < $len; ++$i) {
+            $in = ord($str{$i});
+            if ($mState == 0) {
+                // When mState is zero we expect either a US-ASCII character or a
+                // multi-octet sequence.
+                if (0 == (0x80 & ($in))) {
+                    // US-ASCII, pass straight through.
+                    $mBytes = 1;
+                } elseif (0xC0 == (0xE0 & ($in))) {
+                    // First octet of 2 octet sequence
+                    $mUcs4 = ($in);
+                    $mUcs4 = ($mUcs4 & 0x1F) << 6;
+                    $mState = 1;
+                    $mBytes = 2;
+                } elseif (0xE0 == (0xF0 & ($in))) {
+                    // First octet of 3 octet sequence
+                    $mUcs4 = ($in);
+                    $mUcs4 = ($mUcs4 & 0x0F) << 12;
+                    $mState = 2;
+                    $mBytes = 3;
+                } elseif (0xF0 == (0xF8 & ($in))) {
+                    // First octet of 4 octet sequence
+                    $mUcs4 = ($in);
+                    $mUcs4 = ($mUcs4 & 0x07) << 18;
+                    $mState = 3;
+                    $mBytes = 4;
+                } elseif (0xF8 == (0xFC & ($in))) {
+                    /* First octet of 5 octet sequence.
+                    *
+                    * This is illegal because the encoded codepoint must be either
+                    * (a) not the shortest form or
+                    * (b) outside the Unicode range of 0-0x10FFFF.
+                    * Rather than trying to resynchronize, we will carry on until the end
+                    * of the sequence and let the later error handling code catch it.
+                    */
+                    $mUcs4 = ($in);
+                    $mUcs4 = ($mUcs4 & 0x03) << 24;
+                    $mState = 4;
+                    $mBytes = 5;
+                } elseif (0xFC == (0xFE & ($in))) {
+                    // First octet of 6 octet sequence, see comments for 5 octet sequence.
+                    $mUcs4 = ($in);
+                    $mUcs4 = ($mUcs4 & 1) << 30;
+                    $mState = 5;
+                    $mBytes = 6;
+                } else {
+                    /* Current octet is neither in the US-ASCII range nor a legal first
+                     * octet of a multi-octet sequence.
+                     */
+                    return false;
+                }
+            } else {
+                // When mState is non-zero, we expect a continuation of the multi-octet
+                // sequence
+                if (0x80 == (0xC0 & ($in))) {
+                    // Legal continuation.
+                    $shift = ($mState - 1) * 6;
+                    $tmp = $in;
+                    $tmp = ($tmp & 0x0000003F) << $shift;
+                    $mUcs4 |= $tmp;
+                    /*
+                     * End of the multi-octet sequence. mUcs4 now contains the final
+                     * Unicode codepoint to be output
+                     */
+                    if (0 == --$mState) {
+                        /*
+                        * Check for illegal sequences and codepoints.
+                        */
+                        // From Unicode 3.1, non-shortest form is illegal
+                        if (((2 == $mBytes) && ($mUcs4 < 0x0080)) ||
+                            ((3 == $mBytes) && ($mUcs4 < 0x0800)) ||
+                            ((4 == $mBytes) && ($mUcs4 < 0x10000)) ||
+                            (4 < $mBytes) ||
+                            // From Unicode 3.2, surrogate characters are illegal
+                            (($mUcs4 & 0xFFFFF800) == 0xD800) ||
+                            // Codepoints outside the Unicode range are illegal
+                            ($mUcs4 > 0x10FFFF)
+                        ) {
+                            return false;
+                        }
+                        //initialize UTF8 cache
+                        $mState = 0;
+                        $mUcs4 = 0;
+                        $mBytes = 1;
+                    }
+                } else {
+                    /*
+                     *((0xC0 & (*in) != 0x80) && (mState != 0))
+                     * Incomplete multi-octet sequence.
+                     */
+                    return false;
+                }
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Cleans up the text and adds separator.
+     *
+     * @param string $text
+     * @param string $separator
+     *
+     * @return string
+     */
+    private static function postProcessText($text, $separator)
+    {
+        if (function_exists('mb_strtolower')) {
+            $text = mb_strtolower($text);
+        } else {
+            $text = strtolower($text);
+        }
+
+        // Remove apostrophes which are not used as quotes around a string
+        $text = preg_replace('/(\\w)\'(\\w)/', '${1}${2}', $text);
+
+        // Replace all none word characters with a space
+        $text = preg_replace('/\W/', ' ', $text);
+
+        // More stripping. Replace spaces with dashes
+        $text = strtolower(preg_replace('/[^A-Za-z0-9\/]+/', $separator,
+            preg_replace('/([a-z\d])([A-Z])/', '\1_\2',
+                preg_replace('/([A-Z]+)([A-Z][a-z])/', '\1_\2',
+                    preg_replace('/::/', '/', $text)))));
+
+        return trim($text, $separator);
+    }
+}
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x00.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x00.php
new file mode 100644 (file)
index 0000000..9177c74
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x00] = array(
+"\x00", "\x01", "\x02", "\x03", "\x04", "\x05", "\x06", "\x07", "\x08", "\x09", "\x0a", "\x0b", "\x0c", "\x0d", "\x0e", "\x0f",
+"\x10", "\x11", "\x12", "\x13", "\x14", "\x15", "\x16", "\x17", "\x18", "\x19", "\x1a", "\x1b", "\x1c", "\x1d", "\x1e", "\x1f",
+' ', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/',
+'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?',
+'@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
+'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^', '_',
+'`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
+'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', "\x7f",
+'EUR', '', ',', 'f', ',,', '...', '+', '++', '^', '%0', 'S', '<', 'OE', '', 'Z', '',
+'', '\'', '\'', '"', '"', '*', '-', '--', '~', 'tm', 's', '>', 'oe', '', 'z', 'Y',
+' ', '!', 'C/', 'PS', '$?', 'Y=', '|', 'SS', '"', '(c)', 'a', '<<', '!', '', '(r)', '-',
+'deg', '+-', '2', '3', '\'', 'u', 'P', '*', ',', '1', 'o', '>>', '1/4', '1/2', '3/4', '?',
+'A', 'A', 'A', 'A', 'A', 'A', 'AE', 'C', 'E', 'E', 'E', 'E', 'I', 'I', 'I', 'I',
+'D', 'N', 'O', 'O', 'O', 'O', 'O', 'x', 'O', 'U', 'U', 'U', 'U', 'Y', 'Th', 'ss',
+'a', 'a', 'a', 'a', 'a', 'a', 'ae', 'c', 'e', 'e', 'e', 'e', 'i', 'i', 'i', 'i',
+'d', 'n', 'o', 'o', 'o', 'o', 'o', '/', 'o', 'u', 'u', 'u', 'u', 'y', 'th', 'y',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x01.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x01.php
new file mode 100644 (file)
index 0000000..d746817
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x01] = array(
+'A', 'a', 'A', 'a', 'A', 'a', 'C', 'c', 'C', 'c', 'C', 'c', 'C', 'c', 'D', 'd',
+'D', 'd', 'E', 'e', 'E', 'e', 'E', 'e', 'E', 'e', 'E', 'e', 'G', 'g', 'G', 'g',
+'G', 'g', 'G', 'g', 'H', 'h', 'H', 'h', 'I', 'i', 'I', 'i', 'I', 'i', 'I', 'i',
+'I', 'i', 'IJ', 'ij', 'J', 'j', 'K', 'k', 'k', 'L', 'l', 'L', 'l', 'L', 'l', 'L',
+'l', 'L', 'l', 'N', 'n', 'N', 'n', 'N', 'n', '\'n', 'ng', 'NG', 'O', 'o', 'O', 'o',
+'O', 'o', 'OE', 'oe', 'R', 'r', 'R', 'r', 'R', 'r', 'S', 's', 'S', 's', 'S', 's',
+'S', 's', 'T', 't', 'T', 't', 'T', 't', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u',
+'U', 'u', 'U', 'u', 'W', 'w', 'Y', 'y', 'Y', 'Z', 'z', 'Z', 'z', 'Z', 'z', 's',
+'b', 'B', 'B', 'b', '6', '6', 'O', 'C', 'c', 'D', 'D', 'D', 'd', 'd', '3', '@',
+'E', 'F', 'f', 'G', 'G', 'hv', 'I', 'I', 'K', 'k', 'l', 'l', 'W', 'N', 'n', 'O',
+'O', 'o', 'OI', 'oi', 'P', 'p', 'YR', '2', '2', 'SH', 'sh', 't', 'T', 't', 'T', 'U',
+'u', 'Y', 'V', 'Y', 'y', 'Z', 'z', 'ZH', 'ZH', 'zh', 'zh', '2', '5', '5', 'ts', 'w',
+'|', '||', '|=', '!', 'DZ', 'Dz', 'dz', 'LJ', 'Lj', 'lj', 'NJ', 'Nj', 'nj', 'A', 'a', 'I',
+'i', 'O', 'o', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', '@', 'A', 'a',
+'A', 'a', 'AE', 'ae', 'G', 'g', 'G', 'g', 'K', 'k', 'O', 'o', 'O', 'o', 'ZH', 'zh',
+'j', 'DZ', 'Dz', 'dz', 'G', 'g', 'HV', 'W', 'N', 'n', 'A', 'a', 'AE', 'ae', 'O', 'o',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x02.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x02.php
new file mode 100644 (file)
index 0000000..c6e3a08
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x02] = array(
+'A', 'a', 'A', 'a', 'E', 'e', 'E', 'e', 'I', 'i', 'I', 'i', 'O', 'o', 'O', 'o',
+'R', 'r', 'R', 'r', 'U', 'u', 'U', 'u', 'S', 's', 'T', 't', 'Y', 'y', 'H', 'h',
+'N', 'd', 'OU', 'ou', 'Z', 'z', 'A', 'a', 'E', 'e', 'O', 'o', 'O', 'o', 'O', 'o',
+'O', 'o', 'Y', 'y', 'l', 'n', 't', 'j', 'db', 'qp', 'A', 'C', 'c', 'L', 'T', 's',
+'z', '[?]', '[?]', 'B', 'U', '^', 'E', 'e', 'J', 'j', 'q', 'q', 'R', 'r', 'Y', 'y',
+'a', 'a', 'a', 'b', 'o', 'c', 'd', 'd', 'e', '@', '@', 'e', 'e', 'e', 'e', 'j',
+'g', 'g', 'g', 'g', 'u', 'Y', 'h', 'h', 'i', 'i', 'I', 'l', 'l', 'l', 'lZ', 'W',
+'W', 'm', 'n', 'n', 'n', 'o', 'OE', 'O', 'F', 'r', 'r', 'r', 'r', 'r', 'r', 'r',
+'R', 'R', 's', 'S', 'j', 'S', 'S', 't', 't', 'u', 'U', 'v', '^', 'w', 'y', 'Y',
+'z', 'z', 'Z', 'Z', '?', '?', '?', 'C', '@', 'B', 'E', 'G', 'H', 'j', 'k', 'L',
+'q', '?', '?', 'dz', 'dZ', 'dz', 'ts', 'tS', 'tC', 'fN', 'ls', 'lz', 'WW', ']]', 'h', 'h',
+'h', 'h', 'j', 'r', 'r', 'r', 'r', 'w', 'y', '\'', '"', '`', '\'', '`', '`', '\'',
+'?', '?', '<', '>', '^', 'V', '^', 'V', '\'', '-', '/', '\\', ',', '_', '\\', '/',
+':', '.', '`', '\'', '^', 'V', '+', '-', 'V', '.', '@', ',', '~', '"', 'R', 'X',
+'G', 'l', 's', 'x', '?', '', '', '', '', '', '', '', 'V', '=', '"', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x03.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x03.php
new file mode 100644 (file)
index 0000000..a923ec0
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x03] = array(
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'', '', '', 'a', 'e', 'i', 'o', 'u', 'c', 'd', 'h', 'm', 'r', 't', 'v', 'x',
+'[?]', '[?]', '[?]', '[?]', '\'', ',', '[?]', '[?]', '[?]', '[?]', '', '[?]', '[?]', '[?]', '?', '[?]',
+'[?]', '[?]', '[?]', '[?]', '', '', 'A', ';', 'E', 'E', 'I', '[?]', 'O', '[?]', 'U', 'O',
+'I', 'A', 'B', 'G', 'D', 'E', 'Z', 'E', 'Th', 'I', 'K', 'L', 'M', 'N', 'Ks', 'O',
+'P', 'R', '[?]', 'S', 'T', 'U', 'Ph', 'Kh', 'Ps', 'O', 'I', 'U', 'a', 'e', 'e', 'i',
+'u', 'a', 'b', 'g', 'd', 'e', 'z', 'e', 'th', 'i', 'k', 'l', 'm', 'n', 'x', 'o',
+'p', 'r', 's', 's', 't', 'u', 'ph', 'kh', 'ps', 'o', 'i', 'u', 'o', 'u', 'o', '[?]',
+'b', 'th', 'U', 'U', 'U', 'ph', 'p', '&', '[?]', '[?]', 'St', 'st', 'W', 'w', 'Q', 'q',
+'Sp', 'sp', 'Sh', 'sh', 'F', 'f', 'Kh', 'kh', 'H', 'h', 'G', 'g', 'CH', 'ch', 'Ti', 'ti',
+'k', 'r', 'c', 'j', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x04.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x04.php
new file mode 100644 (file)
index 0000000..302181f
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x04] = array(
+'Ie', 'Io', 'Dj', 'Gj', 'E', 'Dz', 'I', 'Yi', 'J', 'Lj', 'Nj', 'Tsh', 'Kj', 'I', 'U', 'Dzh',
+'A', 'B', 'V', 'G', 'D', 'E', 'Zh', 'Z', 'I', 'I', 'K', 'L', 'M', 'N', 'O', 'P',
+'R', 'S', 'T', 'U', 'F', 'Kh', 'Ts', 'Ch', 'Sh', 'Shch', '', 'Y', '\'', 'E', 'Iu', 'Ia',
+'a', 'b', 'v', 'g', 'd', 'e', 'zh', 'z', 'i', 'i', 'k', 'l', 'm', 'n', 'o', 'p',
+'r', 's', 't', 'u', 'f', 'kh', 'ts', 'ch', 'sh', 'shch', '', 'y', '\'', 'e', 'iu', 'ia',
+'ie', 'io', 'dj', 'gj', 'ie', 'dz', 'i', 'yi', 'j', 'lj', 'nj', 'tsh', 'kj', 'i', 'u', 'dzh',
+'O', 'o', 'E', 'e', 'Ie', 'ie', 'E', 'e', 'Ie', 'ie', 'O', 'o', 'Io', 'io', 'Ks', 'ks',
+'Ps', 'ps', 'F', 'f', 'Y', 'y', 'Y', 'y', 'u', 'u', 'O', 'o', 'O', 'o', 'Ot', 'ot',
+'Q', 'q', '*1000*', '', '', '', '', '[?]', '*100.000*', '*1.000.000*', '[?]', '[?]', '"', '"', 'R\'', 'r\'',
+'G\'', 'g\'', 'G\'', 'g\'', 'G\'', 'g\'', 'Zh\'', 'zh\'', 'Z\'', 'z\'', 'K\'', 'k\'', 'K\'', 'k\'', 'K\'', 'k\'',
+'K\'', 'k\'', 'N\'', 'n\'', 'Ng', 'ng', 'P\'', 'p\'', 'Kh', 'kh', 'S\'', 's\'', 'T\'', 't\'', 'U', 'u',
+'U\'', 'u\'', 'Kh\'', 'kh\'', 'Tts', 'tts', 'Ch\'', 'ch\'', 'Ch\'', 'ch\'', 'H', 'h', 'Ch', 'ch', 'Ch\'', 'ch\'',
+'`', 'Zh', 'zh', 'K\'', 'k\'', '[?]', '[?]', 'N\'', 'n\'', '[?]', '[?]', 'Ch', 'ch', '[?]', '[?]', '[?]',
+'a', 'a', 'A', 'a', 'Ae', 'ae', 'Ie', 'ie', '@', '@', '@', '@', 'Zh', 'zh', 'Z', 'z',
+'Dz', 'dz', 'I', 'i', 'I', 'i', 'O', 'o', 'O', 'o', 'O', 'o', 'E', 'e', 'U', 'u',
+'U', 'u', 'U', 'u', 'Ch', 'ch', '[?]', '[?]', 'Y', 'y', '[?]', '[?]', '[?]', '[?]', '[?]',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x05.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x05.php
new file mode 100644 (file)
index 0000000..197c54c
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x05] = array(
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', 'A', 'B', 'G', 'D', 'E', 'Z', 'E', 'E', 'T`', 'Zh', 'I', 'L', 'Kh', 'Ts', 'K',
+'H', 'Dz', 'Gh', 'Ch', 'M', 'Y', 'N', 'Sh', 'O', 'Ch`', 'P', 'J', 'Rh', 'S', 'V', 'T',
+'R', 'Ts`', 'W', 'P`', 'K`', 'O', 'F', '[?]', '[?]', '<', '\'', '/', '!', ',', '?', '.',
+'[?]', 'a', 'b', 'g', 'd', 'e', 'z', 'e', 'e', 't`', 'zh', 'i', 'l', 'kh', 'ts', 'k',
+'h', 'dz', 'gh', 'ch', 'm', 'y', 'n', 'sh', 'o', 'ch`', 'p', 'j', 'rh', 's', 'v', 't',
+'r', 'ts`', 'w', 'p`', 'k`', 'o', 'f', 'ew', '[?]', '.', '-', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '[?]', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'@', 'e', 'a', 'o', 'i', 'e', 'e', 'a', 'a', 'o', '[?]', 'u', '\'', '', '', '',
+'|', '', '', ':', '', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'', 'b', 'g', 'd', 'h', 'v', 'z', 'kh', 't', 'y', 'k', 'k', 'l', 'm', 'm', 'n',
+'n', 's', '`', 'p', 'p', 'ts', 'ts', 'q', 'r', 'sh', 't', '[?]', '[?]', '[?]', '[?]', '[?]',
+'V', 'oy', 'i', '\'', '"', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x06.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x06.php
new file mode 100644 (file)
index 0000000..7f10faf
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x06] = array(
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', ',', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', ';', '[?]', '[?]', '[?]', '?',
+'[?]', '', 'a', '\'', 'w\'', '', 'y\'', '', 'b', '@', 't', 'th', 'j', 'H', 'kh', 'd',
+'dh', 'r', 'z', 's', 'sh', 'S', 'D', 'T', 'Z', '`', 'G', '[?]', '[?]', '[?]', '[?]', '[?]',
+'', 'f', 'q', 'k', 'l', 'm', 'n', 'h', 'w', '~', 'y', 'an', 'un', 'in', 'a', 'u',
+'i', 'W', '', '', '\'', '\'', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '%', '.', ',', '*', '[?]', '[?]',
+'', '\'', '\'', '\'', '', '\'', '\'w', '\'u', '\'y', 'tt', 'tth', 'b', 't', 'T', 'p', 'th',
+'bh', '\'h', 'H', 'ny', 'dy', 'H', 'ch', 'cch', 'dd', 'D', 'D', 'Dt', 'dh', 'ddh', 'd', 'D',
+'D', 'rr', 'R', 'R', 'R', 'R', 'R', 'R', 'j', 'R', 'S', 'S', 'S', 'S', 'S', 'T',
+'GH', 'F', 'F', 'F', 'v', 'f', 'ph', 'Q', 'Q', 'kh', 'k', 'K', 'K', 'ng', 'K', 'g',
+'G', 'N', 'G', 'G', 'G', 'L', 'L', 'L', 'L', 'N', 'N', 'N', 'N', 'N', 'h', 'Ch',
+'hy', 'h', 'H', '@', 'W', 'oe', 'oe', 'u', 'yu', 'yu', 'W', 'v', 'y', 'Y', 'Y', 'W',
+'', '', 'y', 'y\'', '.', 'ae', '', '', '', '', '', '', '', '@', '#', '',
+'', '', '', '', '', '', '', '', '', '^', '', '', '', '', '[?]', '[?]',
+'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'Sh', 'D', 'Gh', '&', '+m',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x07.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x07.php
new file mode 100644 (file)
index 0000000..96f76f1
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x07] = array(
+'//', '/', ',', '!', '!', '-', ',', ',', ';', '?', '~', '{', '}', '*', '[?]', '',
+'\'', '', 'b', 'g', 'g', 'd', 'd', 'h', 'w', 'z', 'H', 't', 't', 'y', 'yh', 'k',
+'l', 'm', 'n', 's', 's', '`', 'p', 'p', 'S', 'q', 'r', 'sh', 't', '[?]', '[?]', '[?]',
+'a', 'a', 'a', 'A', 'A', 'A', 'e', 'e', 'e', 'E', 'i', 'i', 'u', 'u', 'u', 'o',
+'', '`', '\'', '', '', 'X', 'Q', '@', '@', '|', '+', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'h', 'sh', 'n', 'r', 'b', 'L', 'k', '\'', 'v', 'm', 'f', 'dh', 'th', 'l', 'g', 'ny',
+'s', 'd', 'z', 't', 'y', 'p', 'j', 'ch', 'tt', 'hh', 'kh', 'th', 'z', 'sh', 's', 'd',
+'t', 'z', '`', 'gh', 'q', 'w', 'a', 'aa', 'i', 'ee', 'u', 'oo', 'e', 'ey', 'o', 'oa',
+'', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x09.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x09.php
new file mode 100644 (file)
index 0000000..7d70c24
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x09] = array(
+'[?]', 'N', 'N', 'H', '[?]', 'a', 'aa', 'i', 'ii', 'u', 'uu', 'R', 'L', 'eN', 'e', 'e',
+'ai', 'oN', 'o', 'o', 'au', 'k', 'kh', 'g', 'gh', 'ng', 'c', 'ch', 'j', 'jh', 'ny', 'tt',
+'tth', 'dd', 'ddh', 'nn', 't', 'th', 'd', 'dh', 'n', 'nnn', 'p', 'ph', 'b', 'bh', 'm', 'y',
+'r', 'rr', 'l', 'l', 'lll', 'v', 'sh', 'ss', 's', 'h', '[?]', '[?]', '\'', '\'', 'aa', 'i',
+'ii', 'u', 'uu', 'R', 'RR', 'eN', 'e', 'e', 'ai', 'oN', 'o', 'o', 'au', '', '[?]', '[?]',
+'AUM', '\'', '\'', '`', '\'', '[?]', '[?]', '[?]', 'q', 'khh', 'ghh', 'z', 'dddh', 'rh', 'f', 'yy',
+'RR', 'LL', 'L', 'LL', ' / ', ' // ', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+'.', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', 'N', 'N', 'H', '[?]', 'a', 'aa', 'i', 'ii', 'u', 'uu', 'R', 'RR', '[?]', '[?]', 'e',
+'ai', '[?]', '[?]', 'o', 'au', 'k', 'kh', 'g', 'gh', 'ng', 'c', 'ch', 'j', 'jh', 'ny', 'tt',
+'tth', 'dd', 'ddh', 'nn', 't', 'th', 'd', 'dh', 'n', '[?]', 'p', 'ph', 'b', 'bh', 'm', 'y',
+'r', '[?]', 'l', '[?]', '[?]', '[?]', 'sh', 'ss', 's', 'h', '[?]', '[?]', '\'', '[?]', 'aa', 'i',
+'ii', 'u', 'uu', 'R', 'RR', '[?]', '[?]', 'e', 'ai', '[?]', '[?]', 'o', 'au', '', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '+', '[?]', '[?]', '[?]', '[?]', 'rr', 'rh', '[?]', 'yy',
+'RR', 'LL', 'L', 'LL', '[?]', '[?]', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+'r\'', 'r`', 'Rs', 'Rs', '1/', '2/', '3/', '4/', ' 1 - 1/', '/16', '', '[?]', '[?]', '[?]', '[?]',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x0a.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x0a.php
new file mode 100644 (file)
index 0000000..3121209
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x0a] = array(
+'[?]', '[?]', 'N', '[?]', '[?]', 'a', 'aa', 'i', 'ii', 'u', 'uu', '[?]', '[?]', '[?]', '[?]', 'ee',
+'ai', '[?]', '[?]', 'oo', 'au', 'k', 'kh', 'g', 'gh', 'ng', 'c', 'ch', 'j', 'jh', 'ny', 'tt',
+'tth', 'dd', 'ddh', 'nn', 't', 'th', 'd', 'dh', 'n', '[?]', 'p', 'ph', 'b', 'bb', 'm', 'y',
+'r', '[?]', 'l', 'll', '[?]', 'v', 'sh', '[?]', 's', 'h', '[?]', '[?]', '\'', '[?]', 'aa', 'i',
+'ii', 'u', 'uu', '[?]', '[?]', '[?]', '[?]', 'ee', 'ai', '[?]', '[?]', 'oo', 'au', '', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', 'khh', 'ghh', 'z', 'rr', '[?]', 'f', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+'N', 'H', '', '', 'G.E.O.', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', 'N', 'N', 'H', '[?]', 'a', 'aa', 'i', 'ii', 'u', 'uu', 'R', '[?]', 'eN', '[?]', 'e',
+'ai', 'oN', '[?]', 'o', 'au', 'k', 'kh', 'g', 'gh', 'ng', 'c', 'ch', 'j', 'jh', 'ny', 'tt',
+'tth', 'dd', 'ddh', 'nn', 't', 'th', 'd', 'dh', 'n', '[?]', 'p', 'ph', 'b', 'bh', 'm', 'ya',
+'r', '[?]', 'l', 'll', '[?]', 'v', 'sh', 'ss', 's', 'h', '[?]', '[?]', '\'', '\'', 'aa', 'i',
+'ii', 'u', 'uu', 'R', 'RR', 'eN', '[?]', 'e', 'ai', 'oN', '[?]', 'o', 'au', '', '[?]', '[?]',
+'AUM', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'RR', '[?]', '[?]', '[?]', '[?]', '[?]', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x0b.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x0b.php
new file mode 100644 (file)
index 0000000..a8b1f08
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x0b] = array(
+'[?]', 'N', 'N', 'H', '[?]', 'a', 'aa', 'i', 'ii', 'u', 'uu', 'R', 'L', '[?]', '[?]', 'e',
+'ai', '[?]', '[?]', 'o', 'au', 'k', 'kh', 'g', 'gh', 'ng', 'c', 'ch', 'j', 'jh', 'ny', 'tt',
+'tth', 'dd', 'ddh', 'nn', 't', 'th', 'd', 'dh', 'n', '[?]', 'p', 'ph', 'b', 'bh', 'm', 'y',
+'r', '[?]', 'l', 'll', '[?]', '', 'sh', 'ss', 's', 'h', '[?]', '[?]', '\'', '\'', 'aa', 'i',
+'ii', 'u', 'uu', 'R', '[?]', '[?]', '[?]', 'e', 'ai', '[?]', '[?]', 'o', 'au', '', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '+', '+', '[?]', '[?]', '[?]', '[?]', 'rr', 'rh', '[?]', 'yy',
+'RR', 'LL', '[?]', '[?]', '[?]', '[?]', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+'', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', 'N', 'H', '[?]', 'a', 'aa', 'i', 'ii', 'u', 'uu', '[?]', '[?]', '[?]', 'e', 'ee',
+'ai', '[?]', 'o', 'oo', 'au', 'k', '[?]', '[?]', '[?]', 'ng', 'c', '[?]', 'j', '[?]', 'ny', 'tt',
+'[?]', '[?]', '[?]', 'nn', 't', '[?]', '[?]', '[?]', 'n', 'nnn', 'p', '[?]', '[?]', '[?]', 'm', 'y',
+'r', 'rr', 'l', 'll', 'lll', 'v', '[?]', 'ss', 's', 'h', '[?]', '[?]', '[?]', '[?]', 'aa', 'i',
+'ii', 'u', 'uu', '[?]', '[?]', '[?]', 'e', 'ee', 'ai', '[?]', 'o', 'oo', 'au', '', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '+', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+'+10+', '+100+', '+1000+', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x0c.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x0c.php
new file mode 100644 (file)
index 0000000..68dd1ba
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x0c] = array(
+'[?]', 'N', 'N', 'H', '[?]', 'a', 'aa', 'i', 'ii', 'u', 'uu', 'R', 'L', '[?]', 'e', 'ee',
+'ai', '[?]', 'o', 'oo', 'au', 'k', 'kh', 'g', 'gh', 'ng', 'c', 'ch', 'j', 'jh', 'ny', 'tt',
+'tth', 'dd', 'ddh', 'nn', 't', 'th', 'd', 'dh', 'n', '[?]', 'p', 'ph', 'b', 'bh', 'm', 'y',
+'r', 'rr', 'l', 'll', '[?]', 'v', 'sh', 'ss', 's', 'h', '[?]', '[?]', '[?]', '[?]', 'aa', 'i',
+'ii', 'u', 'uu', 'R', 'RR', '[?]', 'e', 'ee', 'ai', '[?]', 'o', 'oo', 'au', '', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '+', '+', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'RR', 'LL', '[?]', '[?]', '[?]', '[?]', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', 'N', 'H', '[?]', 'a', 'aa', 'i', 'ii', 'u', 'uu', 'R', 'L', '[?]', 'e', 'ee',
+'ai', '[?]', 'o', 'oo', 'au', 'k', 'kh', 'g', 'gh', 'ng', 'c', 'ch', 'j', 'jh', 'ny', 'tt',
+'tth', 'dd', 'ddh', 'nn', 't', 'th', 'd', 'dh', 'n', '[?]', 'p', 'ph', 'b', 'bh', 'm', 'y',
+'r', 'rr', 'l', 'll', '[?]', 'v', 'sh', 'ss', 's', 'h', '[?]', '[?]', '[?]', '[?]', 'aa', 'i',
+'ii', 'u', 'uu', 'R', 'RR', '[?]', 'e', 'ee', 'ai', '[?]', 'o', 'oo', 'au', '', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '+', '+', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', 'lll', '[?]',
+'RR', 'LL', '[?]', '[?]', '[?]', '[?]', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x0d.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x0d.php
new file mode 100644 (file)
index 0000000..c710e2c
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x0d] = array(
+'[?]', '[?]', 'N', 'H', '[?]', 'a', 'aa', 'i', 'ii', 'u', 'uu', 'R', 'L', '[?]', 'e', 'ee',
+'ai', '[?]', 'o', 'oo', 'au', 'k', 'kh', 'g', 'gh', 'ng', 'c', 'ch', 'j', 'jh', 'ny', 'tt',
+'tth', 'dd', 'ddh', 'nn', 't', 'th', 'd', 'dh', 'n', '[?]', 'p', 'ph', 'b', 'bh', 'm', 'y',
+'r', 'rr', 'l', 'll', 'lll', 'v', 'sh', 'ss', 's', 'h', '[?]', '[?]', '[?]', '[?]', 'aa', 'i',
+'ii', 'u', 'uu', 'R', '[?]', '[?]', 'e', 'ee', 'ai', '', 'o', 'oo', 'au', '', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '+', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'RR', 'LL', '[?]', '[?]', '[?]', '[?]', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', 'N', 'H', '[?]', 'a', 'aa', 'ae', 'aae', 'i', 'ii', 'u', 'uu', 'R', 'RR', 'L',
+'LL', 'e', 'ee', 'ai', 'o', 'oo', 'au', '[?]', '[?]', '[?]', 'k', 'kh', 'g', 'gh', 'ng', 'nng',
+'c', 'ch', 'j', 'jh', 'ny', 'jny', 'nyj', 'tt', 'tth', 'dd', 'ddh', 'nn', 'nndd', 't', 'th', 'd',
+'dh', 'n', '[?]', 'nd', 'p', 'ph', 'b', 'bh', 'm', 'mb', 'y', 'r', '[?]', 'l', '[?]', '[?]',
+'v', 'sh', 'ss', 's', 'h', 'll', 'f', '[?]', '[?]', '[?]', '', '[?]', '[?]', '[?]', '[?]', 'aa',
+'ae', 'aae', 'i', 'ii', 'u', '[?]', 'uu', '[?]', 'R', 'e', 'ee', 'ai', 'o', 'oo', 'au', 'L',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', 'RR', 'LL', ' . ', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x0e.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x0e.php
new file mode 100644 (file)
index 0000000..57604bd
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x0e] = array(
+'[?]', 'k', 'kh', 'kh', 'kh', 'kh', 'kh', 'ng', 'cch', 'ch', 'ch', 'ch', 'ch', 'y', 'd', 't',
+'th', 'th', 'th', 'n', 'd', 't', 'th', 'th', 'th', 'n', 'b', 'p', 'ph', 'f', 'ph', 'f',
+'ph', 'm', 'y', 'r', 'R', 'l', 'L', 'w', 's', 's', 's', 'h', 'l', '`', 'h', '~',
+'a', 'a', 'aa', 'am', 'i', 'ii', 'ue', 'uue', 'u', 'uu', '\'', '[?]', '[?]', '[?]', '[?]', 'Bh.',
+'e', 'ae', 'o', 'ai', 'ai', 'ao', '+', '', '', '', '', '', '', 'M', '', ' * ',
+'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ' // ', ' /// ', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', 'k', 'kh', '[?]', 'kh', '[?]', '[?]', 'ng', 'ch', '[?]', 's', '[?]', '[?]', 'ny', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', 'd', 'h', 'th', 'th', '[?]', 'n', 'b', 'p', 'ph', 'f', 'ph', 'f',
+'[?]', 'm', 'y', 'r', '[?]', 'l', '[?]', 'w', '[?]', '[?]', 's', 'h', '[?]', '`', '', '~',
+'a', '', 'aa', 'am', 'i', 'ii', 'y', 'yy', 'u', 'uu', '[?]', 'o', 'l', 'ny', '[?]', '[?]',
+'e', 'ei', 'o', 'ay', 'ai', '[?]', '+', '[?]', '', '', '', '', '', 'M', '[?]', '[?]',
+'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '[?]', '[?]', 'hn', 'hm', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x0f.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x0f.php
new file mode 100644 (file)
index 0000000..9011d76
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x0f] = array(
+'AUM', '', '', '', '', '', '', '', ' // ', ' * ', '', '-', ' / ', ' / ', ' // ', ' -/ ',
+' +/ ', ' X/ ', ' /XX/ ', ' /X/ ', ', ', '', '', '', '', '', '', '', '', '', '', '',
+'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.5', '1.5', '2.5', '3.5', '4.5', '5.5',
+'6.5', '7.5', '8.5', '-.5', '+', '*', '^', '_', '', '~', '[?]', ']', '[[', ']]', '', '',
+'k', 'kh', 'g', 'gh', 'ng', 'c', 'ch', 'j', '[?]', 'ny', 'tt', 'tth', 'dd', 'ddh', 'nn', 't',
+'th', 'd', 'dh', 'n', 'p', 'ph', 'b', 'bh', 'm', 'ts', 'tsh', 'dz', 'dzh', 'w', 'zh', 'z',
+'\'', 'y', 'r', 'l', 'sh', 'ssh', 's', 'h', 'a', 'kss', 'r', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', 'aa', 'i', 'ii', 'u', 'uu', 'R', 'RR', 'L', 'LL', 'e', 'ee', 'o', 'oo', 'M', 'H',
+'i', 'ii', '', '', '', '', '', '', '', '', '', '', '[?]', '[?]', '[?]', '[?]',
+'k', 'kh', 'g', 'gh', 'ng', 'c', 'ch', 'j', '[?]', 'ny', 'tt', 'tth', 'dd', 'ddh', 'nn', 't',
+'th', 'd', 'dh', 'n', 'p', 'ph', 'b', 'bh', 'm', 'ts', 'tsh', 'dz', 'dzh', 'w', 'zh', 'z',
+'\'', 'y', 'r', 'l', 'sh', 'ss', 's', 'h', 'a', 'kss', 'w', 'y', 'r', '[?]', 'X', ' :X: ',
+' /O/ ', ' /o/ ', ' \\o\\ ', ' (O) ', '', '', '', '', '', '', '', '', '', '[?]', '[?]', '',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x10.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x10.php
new file mode 100644 (file)
index 0000000..eeee18e
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x10] = array(
+'k', 'kh', 'g', 'gh', 'ng', 'c', 'ch', 'j', 'jh', 'ny', 'nny', 'tt', 'tth', 'dd', 'ddh', 'nn',
+'tt', 'th', 'd', 'dh', 'n', 'p', 'ph', 'b', 'bh', 'm', 'y', 'r', 'l', 'w', 's', 'h',
+'ll', 'a', '[?]', 'i', 'ii', 'u', 'uu', 'e', '[?]', 'o', 'au', '[?]', 'aa', 'i', 'ii', 'u',
+'uu', 'e', 'ai', '[?]', '[?]', '[?]', 'N', '\'', ':', '', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ' / ', ' // ', 'n*', 'r*', 'l*', 'e*',
+'sh', 'ss', 'R', 'RR', 'L', 'LL', 'R', 'RR', 'L', 'LL', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'A', 'B', 'G', 'D', 'E', 'V', 'Z', 'T`', 'I', 'K', 'L', 'M', 'N', 'O', 'P', 'Zh',
+'R', 'S', 'T', 'U', 'P`', 'K`', 'G\'', 'Q', 'Sh', 'Ch`', 'C`', 'Z\'', 'C', 'Ch', 'X', 'J',
+'H', 'E', 'Y', 'W', 'Xh', 'OE', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'a', 'b', 'g', 'd', 'e', 'v', 'z', 't`', 'i', 'k', 'l', 'm', 'n', 'o', 'p', 'zh',
+'r', 's', 't', 'u', 'p`', 'k`', 'g\'', 'q', 'sh', 'ch`', 'c`', 'z\'', 'c', 'ch', 'x', 'j',
+'h', 'e', 'y', 'w', 'xh', 'oe', 'f', '[?]', '[?]', '[?]', '[?]', ' // ', '[?]', '[?]', '[?]',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x11.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x11.php
new file mode 100644 (file)
index 0000000..56de2a8
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x11] = array(
+'g', 'gg', 'n', 'd', 'dd', 'r', 'm', 'b', 'bb', 's', 'ss', '', 'j', 'jj', 'c', 'k',
+'t', 'p', 'h', 'ng', 'nn', 'nd', 'nb', 'dg', 'rn', 'rr', 'rh', 'rN', 'mb', 'mN', 'bg', 'bn',
+'', 'bs', 'bsg', 'bst', 'bsb', 'bss', 'bsj', 'bj', 'bc', 'bt', 'bp', 'bN', 'bbN', 'sg', 'sn', 'sd',
+'sr', 'sm', 'sb', 'sbg', 'sss', 's', 'sj', 'sc', 'sk', 'st', 'sp', 'sh', '', '', '', '',
+'Z', 'g', 'd', 'm', 'b', 's', 'Z', '', 'j', 'c', 't', 'p', 'N', 'j', '', '',
+'', '', 'ck', 'ch', '', '', 'pb', 'pN', 'hh', 'Q', '[?]', '[?]', '[?]', '[?]', '[?]', '',
+'', 'a', 'ae', 'ya', 'yae', 'eo', 'e', 'yeo', 'ye', 'o', 'wa', 'wae', 'oe', 'yo', 'u', 'weo',
+'we', 'wi', 'yu', 'eu', 'yi', 'i', 'a-o', 'a-u', 'ya-o', 'ya-yo', 'eo-o', 'eo-u', 'eo-eu', 'yeo-o', 'yeo-u', 'o-eo',
+'o-e', 'o-ye', 'o-o', 'o-u', 'yo-ya', 'yo-yae', 'yo-yeo', 'yo-o', 'yo-i', 'u-a', 'u-ae', 'u-eo-eu', 'u-ye', 'u-u', 'yu-a', 'yu-eo',
+'yu-e', 'yu-yeo', 'yu-ye', 'yu-u', 'yu-i', 'eu-u', 'eu-eu', 'yi-u', 'i-a', 'i-ya', 'i-o', 'i-u', 'i-eu', 'i-U', 'U', 'U-eo',
+'U-u', 'U-i', 'UU', '[?]', '[?]', '[?]', '[?]', '[?]', 'g', 'gg', 'gs', 'n', 'nj', 'nh', 'd', 'l',
+'lg', 'lm', 'lb', 'ls', 'lt', 'lp', 'lh', 'm', 'b', 'bs', 's', 'ss', 'ng', 'j', 'c', 'k',
+'t', 'p', 'h', 'gl', 'gsg', 'ng', 'nd', 'ns', 'nZ', 'nt', 'dg', 'tl', 'lgs', 'ln', 'ld', 'lth',
+'ll', 'lmg', 'lms', 'lbs', 'lbh', 'rNp', 'lss', 'lZ', 'lk', 'lQ', 'mg', 'ml', 'mb', 'ms', 'mss', 'mZ',
+'mc', 'mh', 'mN', 'bl', 'bp', 'ph', 'pN', 'sg', 'sd', 'sl', 'sb', 'Z', 'g', 'ss', '', 'kh',
+'N', 'Ns', 'NZ', 'pb', 'pN', 'hn', 'hl', 'hm', 'hb', 'Q', '[?]', '[?]', '[?]', '[?]', '[?]',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x12.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x12.php
new file mode 100644 (file)
index 0000000..35e39cc
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x12] = array(
+'ha', 'hu', 'hi', 'haa', 'hee', 'he', 'ho', '[?]', 'la', 'lu', 'li', 'laa', 'lee', 'le', 'lo', 'lwa',
+'hha', 'hhu', 'hhi', 'hhaa', 'hhee', 'hhe', 'hho', 'hhwa', 'ma', 'mu', 'mi', 'maa', 'mee', 'me', 'mo', 'mwa',
+'sza', 'szu', 'szi', 'szaa', 'szee', 'sze', 'szo', 'szwa', 'ra', 'ru', 'ri', 'raa', 'ree', 're', 'ro', 'rwa',
+'sa', 'su', 'si', 'saa', 'see', 'se', 'so', 'swa', 'sha', 'shu', 'shi', 'shaa', 'shee', 'she', 'sho', 'shwa',
+'qa', 'qu', 'qi', 'qaa', 'qee', 'qe', 'qo', '[?]', 'qwa', '[?]', 'qwi', 'qwaa', 'qwee', 'qwe', '[?]', '[?]',
+'qha', 'qhu', 'qhi', 'qhaa', 'qhee', 'qhe', 'qho', '[?]', 'qhwa', '[?]', 'qhwi', 'qhwaa', 'qhwee', 'qhwe', '[?]', '[?]',
+'ba', 'bu', 'bi', 'baa', 'bee', 'be', 'bo', 'bwa', 'va', 'vu', 'vi', 'vaa', 'vee', 've', 'vo', 'vwa',
+'ta', 'tu', 'ti', 'taa', 'tee', 'te', 'to', 'twa', 'ca', 'cu', 'ci', 'caa', 'cee', 'ce', 'co', 'cwa',
+'xa', 'xu', 'xi', 'xaa', 'xee', 'xe', 'xo', '[?]', 'xwa', '[?]', 'xwi', 'xwaa', 'xwee', 'xwe', '[?]', '[?]',
+'na', 'nu', 'ni', 'naa', 'nee', 'ne', 'no', 'nwa', 'nya', 'nyu', 'nyi', 'nyaa', 'nyee', 'nye', 'nyo', 'nywa',
+'\'a', '\'u', '[?]', '\'aa', '\'ee', '\'e', '\'o', '\'wa', 'ka', 'ku', 'ki', 'kaa', 'kee', 'ke', 'ko', '[?]',
+'kwa', '[?]', 'kwi', 'kwaa', 'kwee', 'kwe', '[?]', '[?]', 'kxa', 'kxu', 'kxi', 'kxaa', 'kxee', 'kxe', 'kxo', '[?]',
+'kxwa', '[?]', 'kxwi', 'kxwaa', 'kxwee', 'kxwe', '[?]', '[?]', 'wa', 'wu', 'wi', 'waa', 'wee', 'we', 'wo', '[?]',
+'`a', '`u', '`i', '`aa', '`ee', '`e', '`o', '[?]', 'za', 'zu', 'zi', 'zaa', 'zee', 'ze', 'zo', 'zwa',
+'zha', 'zhu', 'zhi', 'zhaa', 'zhee', 'zhe', 'zho', 'zhwa', 'ya', 'yu', 'yi', 'yaa', 'yee', 'ye', 'yo', '[?]',
+'da', 'du', 'di', 'daa', 'dee', 'de', 'do', 'dwa', 'dda', 'ddu', 'ddi', 'ddaa', 'ddee', 'dde', 'ddo', 'ddwa',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x13.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x13.php
new file mode 100644 (file)
index 0000000..d98dac1
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x13] = array(
+'ja', 'ju', 'ji', 'jaa', 'jee', 'je', 'jo', 'jwa', 'ga', 'gu', 'gi', 'gaa', 'gee', 'ge', 'go', '[?]',
+'gwa', '[?]', 'gwi', 'gwaa', 'gwee', 'gwe', '[?]', '[?]', 'gga', 'ggu', 'ggi', 'ggaa', 'ggee', 'gge', 'ggo', '[?]',
+'tha', 'thu', 'thi', 'thaa', 'thee', 'the', 'tho', 'thwa', 'cha', 'chu', 'chi', 'chaa', 'chee', 'che', 'cho', 'chwa',
+'pha', 'phu', 'phi', 'phaa', 'phee', 'phe', 'pho', 'phwa', 'tsa', 'tsu', 'tsi', 'tsaa', 'tsee', 'tse', 'tso', 'tswa',
+'tza', 'tzu', 'tzi', 'tzaa', 'tzee', 'tze', 'tzo', '[?]', 'fa', 'fu', 'fi', 'faa', 'fee', 'fe', 'fo', 'fwa',
+'pa', 'pu', 'pi', 'paa', 'pee', 'pe', 'po', 'pwa', 'rya', 'mya', 'fya', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', ' ', '.', ',', ';', ':', ':: ', '?', '//', '1', '2', '3', '4', '5', '6', '7',
+'8', '9', '10+', '20+', '30+', '40+', '50+', '60+', '70+', '80+', '90+', '100+', '10,000+', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'a', 'e', 'i', 'o', 'u', 'v', 'ga', 'ka', 'ge', 'gi', 'go', 'gu', 'gv', 'ha', 'he', 'hi',
+'ho', 'hu', 'hv', 'la', 'le', 'li', 'lo', 'lu', 'lv', 'ma', 'me', 'mi', 'mo', 'mu', 'na', 'hna',
+'nah', 'ne', 'ni', 'no', 'nu', 'nv', 'qua', 'que', 'qui', 'quo', 'quu', 'quv', 'sa', 's', 'se', 'si',
+'so', 'su', 'sv', 'da', 'ta', 'de', 'te', 'di', 'ti', 'do', 'du', 'dv', 'dla', 'tla', 'tle', 'tli',
+'tlo', 'tlu', 'tlv', 'tsa', 'tse', 'tsi', 'tso', 'tsu', 'tsv', 'wa', 'we', 'wi', 'wo', 'wu', 'wv', 'ya',
+'ye', 'yi', 'yo', 'yu', 'yv', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x14.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x14.php
new file mode 100644 (file)
index 0000000..c6f5906
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x14] = array(
+'[?]', 'e', 'aai', 'i', 'ii', 'o', 'oo', 'oo', 'ee', 'i', 'a', 'aa', 'we', 'we', 'wi', 'wi',
+'wii', 'wii', 'wo', 'wo', 'woo', 'woo', 'woo', 'wa', 'wa', 'waa', 'waa', 'waa', 'ai', 'w', '\'', 't',
+'k', 'sh', 's', 'n', 'w', 'n', '[?]', 'w', 'c', '?', 'l', 'en', 'in', 'on', 'an', 'pe',
+'paai', 'pi', 'pii', 'po', 'poo', 'poo', 'hee', 'hi', 'pa', 'paa', 'pwe', 'pwe', 'pwi', 'pwi', 'pwii', 'pwii',
+'pwo', 'pwo', 'pwoo', 'pwoo', 'pwa', 'pwa', 'pwaa', 'pwaa', 'pwaa', 'p', 'p', 'h', 'te', 'taai', 'ti', 'tii',
+'to', 'too', 'too', 'dee', 'di', 'ta', 'taa', 'twe', 'twe', 'twi', 'twi', 'twii', 'twii', 'two', 'two', 'twoo',
+'twoo', 'twa', 'twa', 'twaa', 'twaa', 'twaa', 't', 'tte', 'tti', 'tto', 'tta', 'ke', 'kaai', 'ki', 'kii', 'ko',
+'koo', 'koo', 'ka', 'kaa', 'kwe', 'kwe', 'kwi', 'kwi', 'kwii', 'kwii', 'kwo', 'kwo', 'kwoo', 'kwoo', 'kwa', 'kwa',
+'kwaa', 'kwaa', 'kwaa', 'k', 'kw', 'keh', 'kih', 'koh', 'kah', 'ce', 'caai', 'ci', 'cii', 'co', 'coo', 'coo',
+'ca', 'caa', 'cwe', 'cwe', 'cwi', 'cwi', 'cwii', 'cwii', 'cwo', 'cwo', 'cwoo', 'cwoo', 'cwa', 'cwa', 'cwaa', 'cwaa',
+'cwaa', 'c', 'th', 'me', 'maai', 'mi', 'mii', 'mo', 'moo', 'moo', 'ma', 'maa', 'mwe', 'mwe', 'mwi', 'mwi',
+'mwii', 'mwii', 'mwo', 'mwo', 'mwoo', 'mwoo', 'mwa', 'mwa', 'mwaa', 'mwaa', 'mwaa', 'm', 'm', 'mh', 'm', 'm',
+'ne', 'naai', 'ni', 'nii', 'no', 'noo', 'noo', 'na', 'naa', 'nwe', 'nwe', 'nwa', 'nwa', 'nwaa', 'nwaa', 'nwaa',
+'n', 'ng', 'nh', 'le', 'laai', 'li', 'lii', 'lo', 'loo', 'loo', 'la', 'laa', 'lwe', 'lwe', 'lwi', 'lwi',
+'lwii', 'lwii', 'lwo', 'lwo', 'lwoo', 'lwoo', 'lwa', 'lwa', 'lwaa', 'lwaa', 'l', 'l', 'l', 'se', 'saai', 'si',
+'sii', 'so', 'soo', 'soo', 'sa', 'saa', 'swe', 'swe', 'swi', 'swi', 'swii', 'swii', 'swo', 'swo', 'swoo', 'swoo',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x15.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x15.php
new file mode 100644 (file)
index 0000000..ca7cde4
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x15] = array(
+'swa', 'swa', 'swaa', 'swaa', 'swaa', 's', 's', 'sw', 's', 'sk', 'skw', 'sW', 'spwa', 'stwa', 'skwa', 'scwa',
+'she', 'shi', 'shii', 'sho', 'shoo', 'sha', 'shaa', 'shwe', 'shwe', 'shwi', 'shwi', 'shwii', 'shwii', 'shwo', 'shwo', 'shwoo',
+'shwoo', 'shwa', 'shwa', 'shwaa', 'shwaa', 'sh', 'ye', 'yaai', 'yi', 'yii', 'yo', 'yoo', 'yoo', 'ya', 'yaa', 'ywe',
+'ywe', 'ywi', 'ywi', 'ywii', 'ywii', 'ywo', 'ywo', 'ywoo', 'ywoo', 'ywa', 'ywa', 'ywaa', 'ywaa', 'ywaa', 'y', 'y',
+'y', 'yi', 're', 're', 'le', 'raai', 'ri', 'rii', 'ro', 'roo', 'lo', 'ra', 'raa', 'la', 'rwaa', 'rwaa',
+'r', 'r', 'r', 'fe', 'faai', 'fi', 'fii', 'fo', 'foo', 'fa', 'faa', 'fwaa', 'fwaa', 'f', 'the', 'the',
+'thi', 'thi', 'thii', 'thii', 'tho', 'thoo', 'tha', 'thaa', 'thwaa', 'thwaa', 'th', 'tthe', 'tthi', 'ttho', 'ttha', 'tth',
+'tye', 'tyi', 'tyo', 'tya', 'he', 'hi', 'hii', 'ho', 'hoo', 'ha', 'haa', 'h', 'h', 'hk', 'qaai', 'qi',
+'qii', 'qo', 'qoo', 'qa', 'qaa', 'q', 'tlhe', 'tlhi', 'tlho', 'tlha', 're', 'ri', 'ro', 'ra', 'ngaai', 'ngi',
+'ngii', 'ngo', 'ngoo', 'nga', 'ngaa', 'ng', 'nng', 'she', 'shi', 'sho', 'sha', 'the', 'thi', 'tho', 'tha', 'th',
+'lhi', 'lhii', 'lho', 'lhoo', 'lha', 'lhaa', 'lh', 'the', 'thi', 'thii', 'tho', 'thoo', 'tha', 'thaa', 'th', 'b',
+'e', 'i', 'o', 'a', 'we', 'wi', 'wo', 'wa', 'ne', 'ni', 'no', 'na', 'ke', 'ki', 'ko', 'ka',
+'he', 'hi', 'ho', 'ha', 'ghu', 'gho', 'ghe', 'ghee', 'ghi', 'gha', 'ru', 'ro', 're', 'ree', 'ri', 'ra',
+'wu', 'wo', 'we', 'wee', 'wi', 'wa', 'hwu', 'hwo', 'hwe', 'hwee', 'hwi', 'hwa', 'thu', 'tho', 'the', 'thee',
+'thi', 'tha', 'ttu', 'tto', 'tte', 'ttee', 'tti', 'tta', 'pu', 'po', 'pe', 'pee', 'pi', 'pa', 'p', 'gu',
+'go', 'ge', 'gee', 'gi', 'ga', 'khu', 'kho', 'khe', 'khee', 'khi', 'kha', 'kku', 'kko', 'kke', 'kkee', 'kki',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x16.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x16.php
new file mode 100644 (file)
index 0000000..fc397e2
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x16] = array(
+'kka', 'kk', 'nu', 'no', 'ne', 'nee', 'ni', 'na', 'mu', 'mo', 'me', 'mee', 'mi', 'ma', 'yu', 'yo',
+'ye', 'yee', 'yi', 'ya', 'ju', 'ju', 'jo', 'je', 'jee', 'ji', 'ji', 'ja', 'jju', 'jjo', 'jje', 'jjee',
+'jji', 'jja', 'lu', 'lo', 'le', 'lee', 'li', 'la', 'dlu', 'dlo', 'dle', 'dlee', 'dli', 'dla', 'lhu', 'lho',
+'lhe', 'lhee', 'lhi', 'lha', 'tlhu', 'tlho', 'tlhe', 'tlhee', 'tlhi', 'tlha', 'tlu', 'tlo', 'tle', 'tlee', 'tli', 'tla',
+'zu', 'zo', 'ze', 'zee', 'zi', 'za', 'z', 'z', 'dzu', 'dzo', 'dze', 'dzee', 'dzi', 'dza', 'su', 'so',
+'se', 'see', 'si', 'sa', 'shu', 'sho', 'she', 'shee', 'shi', 'sha', 'sh', 'tsu', 'tso', 'tse', 'tsee', 'tsi',
+'tsa', 'chu', 'cho', 'che', 'chee', 'chi', 'cha', 'ttsu', 'ttso', 'ttse', 'ttsee', 'ttsi', 'ttsa', 'X', '.', 'qai',
+'ngai', 'nngi', 'nngii', 'nngo', 'nngoo', 'nnga', 'nngaa', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+' ', 'b', 'l', 'f', 's', 'n', 'h', 'd', 't', 'c', 'q', 'm', 'g', 'ng', 'z', 'r',
+'a', 'o', 'u', 'e', 'i', 'ch', 'th', 'ph', 'p', 'x', 'p', '<', '>', '[?]', '[?]', '[?]',
+'f', 'v', 'u', 'yr', 'y', 'w', 'th', 'th', 'a', 'o', 'ac', 'ae', 'o', 'o', 'o', 'oe',
+'on', 'r', 'k', 'c', 'k', 'g', 'ng', 'g', 'g', 'w', 'h', 'h', 'h', 'h', 'n', 'n',
+'n', 'i', 'e', 'j', 'g', 'ae', 'a', 'eo', 'p', 'z', 's', 's', 's', 'c', 'z', 't',
+'t', 'd', 'b', 'b', 'p', 'p', 'e', 'm', 'm', 'm', 'l', 'l', 'ng', 'ng', 'd', 'o',
+'ear', 'ior', 'qu', 'qu', 'qu', 's', 'yr', 'yr', 'yr', 'q', 'x', '.', ':', '+', '17', '18',
+'19', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x17.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x17.php
new file mode 100644 (file)
index 0000000..ebeba64
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x17] = array(
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'k', 'kh', 'g', 'gh', 'ng', 'c', 'ch', 'j', 'jh', 'ny', 't', 'tth', 'd', 'ddh', 'nn', 't',
+'th', 'd', 'dh', 'n', 'p', 'ph', 'b', 'bh', 'm', 'y', 'r', 'l', 'v', 'sh', 'ss', 's',
+'h', 'l', 'q', 'a', 'aa', 'i', 'ii', 'u', 'uk', 'uu', 'uuv', 'ry', 'ryy', 'ly', 'lyy', 'e',
+'ai', 'oo', 'oo', 'au', 'a', 'aa', 'aa', 'i', 'ii', 'y', 'yy', 'u', 'uu', 'ua', 'oe', 'ya',
+'ie', 'e', 'ae', 'ai', 'oo', 'au', 'M', 'H', 'a`', '', '', '', 'r', '', '!', '',
+'', '', '', '', '.', ' // ', ':', '+', '++', ' * ', ' /// ', 'KR', '\'', '[?]', '[?]', '[?]',
+'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x18.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x18.php
new file mode 100644 (file)
index 0000000..4abbb2c
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x18] = array(
+' @ ', ' ... ', ', ', '. ', ': ', ' // ', '', '-', ', ', '. ', '', '', '', '', '', '[?]',
+'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'a', 'e', 'i', 'o', 'u', 'O', 'U', 'ee', 'n', 'ng', 'b', 'p', 'q', 'g', 'm', 'l',
+'s', 'sh', 't', 'd', 'ch', 'j', 'y', 'r', 'w', 'f', 'k', 'kha', 'ts', 'z', 'h', 'zr',
+'lh', 'zh', 'ch', '-', 'e', 'i', 'o', 'u', 'O', 'U', 'ng', 'b', 'p', 'q', 'g', 'm',
+'t', 'd', 'ch', 'j', 'ts', 'y', 'w', 'k', 'g', 'h', 'jy', 'ny', 'dz', 'e', 'i', 'iy',
+'U', 'u', 'ng', 'k', 'g', 'h', 'p', 'sh', 't', 'd', 'j', 'f', 'g', 'h', 'ts', 'z',
+'r', 'ch', 'zh', 'i', 'k', 'r', 'f', 'zh', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', 'H', 'X', 'W', 'M', ' 3 ', ' 333 ', 'a', 'i', 'k', 'ng', 'c', 'tt', 'tth', 'dd', 'nn',
+'t', 'd', 'p', 'ph', 'ss', 'zh', 'z', 'a', 't', 'zh', 'gh', 'ng', 'c', 'jh', 'tta', 'ddh',
+'t', 'dh', 'ss', 'cy', 'zh', 'z', 'u', 'y', 'bh', '\'', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x1e.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x1e.php
new file mode 100644 (file)
index 0000000..ddb0ddd
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x1e] = array(
+'A', 'a', 'B', 'b', 'B', 'b', 'B', 'b', 'C', 'c', 'D', 'd', 'D', 'd', 'D', 'd',
+'D', 'd', 'D', 'd', 'E', 'e', 'E', 'e', 'E', 'e', 'E', 'e', 'E', 'e', 'F', 'f',
+'G', 'g', 'H', 'h', 'H', 'h', 'H', 'h', 'H', 'h', 'H', 'h', 'I', 'i', 'I', 'i',
+'K', 'k', 'K', 'k', 'K', 'k', 'L', 'l', 'L', 'l', 'L', 'l', 'L', 'l', 'M', 'm',
+'M', 'm', 'M', 'm', 'N', 'n', 'N', 'n', 'N', 'n', 'N', 'n', 'O', 'o', 'O', 'o',
+'O', 'o', 'O', 'o', 'P', 'p', 'P', 'p', 'R', 'r', 'R', 'r', 'R', 'r', 'R', 'r',
+'S', 's', 'S', 's', 'S', 's', 'S', 's', 'S', 's', 'T', 't', 'T', 't', 'T', 't',
+'T', 't', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', 'V', 'v', 'V', 'v',
+'W', 'w', 'W', 'w', 'W', 'w', 'W', 'w', 'W', 'w', 'X', 'x', 'X', 'x', 'Y', 'y',
+'Z', 'z', 'Z', 'z', 'Z', 'z', 'h', 't', 'w', 'y', 'a', 's', 's', 's', 'Ss', 'd',
+'A', 'a', 'A', 'a', 'A', 'a', 'A', 'a', 'A', 'a', 'A', 'a', 'A', 'a', 'A', 'a',
+'A', 'a', 'A', 'a', 'A', 'a', 'A', 'a', 'E', 'e', 'E', 'e', 'E', 'e', 'E', 'e',
+'E', 'e', 'E', 'e', 'E', 'e', 'E', 'e', 'I', 'i', 'I', 'i', 'O', 'o', 'O', 'o',
+'O', 'o', 'O', 'o', 'O', 'o', 'O', 'o', 'O', 'o', 'O', 'o', 'O', 'o', 'O', 'o',
+'O', 'o', 'O', 'o', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u',
+'U', 'u', 'Y', 'y', 'Y', 'y', 'Y', 'y', 'Y', 'y', '[?]', '[?]', '[?]', '[?]', '[?]',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x1f.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x1f.php
new file mode 100644 (file)
index 0000000..1514055
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x1f] = array(
+'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
+'e', 'e', 'e', 'e', 'e', 'e', '[?]', '[?]', 'E', 'E', 'E', 'E', 'E', 'E', '[?]', '[?]',
+'e', 'e', 'e', 'e', 'e', 'e', 'e', 'e', 'E', 'E', 'E', 'E', 'E', 'E', 'E', 'E',
+'i', 'i', 'i', 'i', 'i', 'i', 'i', 'i', 'I', 'I', 'I', 'I', 'I', 'I', 'I', 'I',
+'o', 'o', 'o', 'o', 'o', 'o', '[?]', '[?]', 'O', 'O', 'O', 'O', 'O', 'O', '[?]', '[?]',
+'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', '[?]', 'U', '[?]', 'U', '[?]', 'U', '[?]', 'U',
+'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O',
+'a', 'a', 'e', 'e', 'e', 'e', 'i', 'i', 'o', 'o', 'u', 'u', 'o', 'o', '[?]', '[?]',
+'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
+'e', 'e', 'e', 'e', 'e', 'e', 'e', 'e', 'E', 'E', 'E', 'E', 'E', 'E', 'E', 'E',
+'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O',
+'a', 'a', 'a', 'a', 'a', '[?]', 'a', 'a', 'A', 'A', 'A', 'A', 'A', '\'', 'i', '\'',
+'~', '"~', 'e', 'e', 'e', '[?]', 'e', 'e', 'E', 'E', 'E', 'E', 'E', '\'`', '\'\'', '\'~',
+'i', 'i', 'i', 'i', '[?]', '[?]', 'i', 'i', 'I', 'I', 'I', 'I', '[?]', '`\'', '`\'', '`~',
+'u', 'u', 'u', 'u', 'R', 'R', 'u', 'u', 'U', 'U', 'U', 'U', 'R', '"`', '"\'', '`',
+'[?]', '[?]', 'o', 'o', 'o', '[?]', 'o', 'o', 'O', 'O', 'O', 'O', 'O', '\'', '`',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x20.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x20.php
new file mode 100644 (file)
index 0000000..5572314
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x20] = array(
+' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '', '', '', '',
+'-', '-', '-', '-', '--', '--', '||', '_', '\'', '\'', ',', '\'', '"', '"', ',,', '"',
+'+', '++', '*', '*>', '.', '..', '...', '.', "\n", "\n\n", '', '', '', '', '', ' ',
+'%0', '%00', '\'', '\'\'', '\'\'\'', '`', '``', '```', '^', '<', '>', '*', '!!', '!?', '-', '_',
+'-', '^', '***', '--', '/', '-[', ']-', '[?]', '?!', '!?', '7', 'PP', '(]', '[)', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '', '', '', '', '', '',
+'0', '', '', '', '4', '5', '6', '7', '8', '9', '+', '-', '=', '(', ')', 'n',
+'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '-', '=', '(', ')', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'ECU', 'CL', 'Cr', 'FF', 'L', 'mil', 'N', 'Pts', 'Rs', 'W', 'NS', 'D', 'EUR', 'K', 'T', 'Dr',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x21.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x21.php
new file mode 100644 (file)
index 0000000..281989a
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x21] = array(
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', 'tm', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', ' 1/3 ', ' 2/3 ', ' 1/5 ', ' 2/5 ', ' 3/5 ', ' 4/5 ', ' 1/6 ', ' 5/6 ', ' 1/8 ', ' 3/8 ', ' 5/8 ', ' 7/8 ', ' 1/',
+'I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX', 'X', 'XI', 'XII', 'L', 'C', 'D', 'M',
+'i', 'ii', 'iii', 'iv', 'v', 'vi', 'vii', 'viii', 'ix', 'x', 'xi', 'xii', 'l', 'c', 'd', 'm',
+'(D', 'D)', '((|))', ')', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'-', '|', '-', '|', '-', '|', '\\', '/', '\\', '/', '-', '-', '~', '~', '-', '|',
+'-', '|', '-', '-', '-', '|', '-', '|', '|', '-', '-', '-', '-', '-', '-', '|',
+'|', '|', '|', '|', '|', '|', '^', 'V', '\\', '=', 'V', '^', '-', '-', '|', '|',
+'-', '-', '|', '|', '=', '|', '=', '=', '|', '=', '|', '=', '=', '=', '=', '=',
+'=', '|', '=', '|', '=', '|', '\\', '/', '\\', '/', '=', '=', '~', '~', '|', '|',
+'-', '|', '-', '|', '-', '-', '-', '|', '-', '|', '|', '|', '|', '|', '|', '|',
+'-', '\\', '\\', '|', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x24.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x24.php
new file mode 100644 (file)
index 0000000..55b0e0d
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x24] = array(
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'', '', '', '', '', '', '', '', '', '', '', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x25.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x25.php
new file mode 100644 (file)
index 0000000..7ff5120
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x25] = array(
+'-', '-', '|', '|', '-', '-', '|', '|', '-', '-', '|', '|', '+', '+', '+', '+',
+'+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
+'+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
+'+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
+'+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '-', '-', '|', '|',
+'-', '|', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
+'+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
+'+', '/', '\\', 'X', '-', '|', '-', '|', '-', '|', '-', '|', '-', '|', '-', '|',
+'#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#',
+'#', '#', '#', '#', '-', '|', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#',
+'#', '#', '^', '^', '^', '^', '>', '>', '>', '>', '>', '>', 'V', 'V', 'V', 'V',
+'<', '<', '<', '<', '<', '<', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*',
+'*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*',
+'*', '*', '*', '*', '*', '*', '*', '#', '#', '#', '#', '#', '^', '^', '^', 'O',
+'#', '#', '#', '#', '#', '#', '#', '#', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x26.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x26.php
new file mode 100644 (file)
index 0000000..a64a3ea
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x26] = array(
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '[?]', '[?]', '[?]', '[?]', '[?]', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x27.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x27.php
new file mode 100644 (file)
index 0000000..f99462d
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x27] = array(
+'[?]', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '[?]',
+'[?]', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'[?]', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x28.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x28.php
new file mode 100644 (file)
index 0000000..513ddb2
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x28] = array(
+' ', 'a', '1', 'b', '\'', 'k', '2', 'l', '@', 'c', 'i', 'f', '/', 'm', 's', 'p',
+'"', 'e', '3', 'h', '9', 'o', '6', 'r', '^', 'd', 'j', 'g', '>', 'n', 't', 'q',
+',', '*', '5', '<', '-', 'u', '8', 'v', '.', '%', '[', '$', '+', 'x', '!', '&',
+';', ':', '4', '\\', '0', 'z', '7', '(', '_', '?', 'w', ']', '#', 'y', ')', '=',
+'[d7]', '[d17]', '[d27]', '[d127]', '[d37]', '[d137]', '[d237]', '[d1237]', '[d47]', '[d147]', '[d247]', '[d1247]', '[d347]', '[d1347]', '[d2347]', '[d12347]',
+'[d57]', '[d157]', '[d257]', '[d1257]', '[d357]', '[d1357]', '[d2357]', '[d12357]', '[d457]', '[d1457]', '[d2457]', '[d12457]', '[d3457]', '[d13457]', '[d23457]', '[d123457]',
+'[d67]', '[d167]', '[d267]', '[d1267]', '[d367]', '[d1367]', '[d2367]', '[d12367]', '[d467]', '[d1467]', '[d2467]', '[d12467]', '[d3467]', '[d13467]', '[d23467]', '[d123467]',
+'[d567]', '[d1567]', '[d2567]', '[d12567]', '[d3567]', '[d13567]', '[d23567]', '[d123567]', '[d4567]', '[d14567]', '[d24567]', '[d124567]', '[d34567]', '[d134567]', '[d234567]', '[d1234567]',
+'[d8]', '[d18]', '[d28]', '[d128]', '[d38]', '[d138]', '[d238]', '[d1238]', '[d48]', '[d148]', '[d248]', '[d1248]', '[d348]', '[d1348]', '[d2348]', '[d12348]',
+'[d58]', '[d158]', '[d258]', '[d1258]', '[d358]', '[d1358]', '[d2358]', '[d12358]', '[d458]', '[d1458]', '[d2458]', '[d12458]', '[d3458]', '[d13458]', '[d23458]', '[d123458]',
+'[d68]', '[d168]', '[d268]', '[d1268]', '[d368]', '[d1368]', '[d2368]', '[d12368]', '[d468]', '[d1468]', '[d2468]', '[d12468]', '[d3468]', '[d13468]', '[d23468]', '[d123468]',
+'[d568]', '[d1568]', '[d2568]', '[d12568]', '[d3568]', '[d13568]', '[d23568]', '[d123568]', '[d4568]', '[d14568]', '[d24568]', '[d124568]', '[d34568]', '[d134568]', '[d234568]', '[d1234568]',
+'[d78]', '[d178]', '[d278]', '[d1278]', '[d378]', '[d1378]', '[d2378]', '[d12378]', '[d478]', '[d1478]', '[d2478]', '[d12478]', '[d3478]', '[d13478]', '[d23478]', '[d123478]',
+'[d578]', '[d1578]', '[d2578]', '[d12578]', '[d3578]', '[d13578]', '[d23578]', '[d123578]', '[d4578]', '[d14578]', '[d24578]', '[d124578]', '[d34578]', '[d134578]', '[d234578]', '[d1234578]',
+'[d678]', '[d1678]', '[d2678]', '[d12678]', '[d3678]', '[d13678]', '[d23678]', '[d123678]', '[d4678]', '[d14678]', '[d24678]', '[d124678]', '[d34678]', '[d134678]', '[d234678]', '[d1234678]',
+'[d5678]', '[d15678]', '[d25678]', '[d125678]', '[d35678]', '[d135678]', '[d235678]', '[d1235678]', '[d45678]', '[d145678]', '[d245678]', '[d1245678]', '[d345678]', '[d1345678]', '[d2345678]', '[d12345678]',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x30.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x30.php
new file mode 100644 (file)
index 0000000..86201c1
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x30] = array(
+' ', ', ', '. ', '"', '[JIS]', '"', '/', '0', '<', '> ', '<<', '>> ', '[', '] ', '{', '} ',
+'[(', ')] ', '@', 'X ', '[', '] ', '[[', ']] ', '((', ')) ', '[[', ']] ', '~ ', '``', '\'\'', ',,',
+'@', '1', '2', '3', '4', '5', '6', '7', '8', '9', '', '', '', '', '', '',
+'~', '+', '+', '+', '+', '', '@', ' // ', '+10+', '+20+', '+30+', '[?]', '[?]', '[?]', '', '',
+'[?]', 'a', 'a', 'i', 'i', 'u', 'u', 'e', 'e', 'o', 'o', 'ka', 'ga', 'ki', 'gi', 'ku',
+'gu', 'ke', 'ge', 'ko', 'go', 'sa', 'za', 'si', 'zi', 'su', 'zu', 'se', 'ze', 'so', 'zo', 'ta',
+'da', 'ti', 'di', 'tu', 'tu', 'du', 'te', 'de', 'to', 'do', 'na', 'ni', 'nu', 'ne', 'no', 'ha',
+'ba', 'pa', 'hi', 'bi', 'pi', 'hu', 'bu', 'pu', 'he', 'be', 'pe', 'ho', 'bo', 'po', 'ma', 'mi',
+'mu', 'me', 'mo', 'ya', 'ya', 'yu', 'yu', 'yo', 'yo', 'ra', 'ri', 'ru', 're', 'ro', 'wa', 'wa',
+'wi', 'we', 'wo', 'n', 'vu', '[?]', '[?]', '[?]', '[?]', '', '', '', '', '"', '"', '[?]',
+'[?]', 'a', 'a', 'i', 'i', 'u', 'u', 'e', 'e', 'o', 'o', 'ka', 'ga', 'ki', 'gi', 'ku',
+'gu', 'ke', 'ge', 'ko', 'go', 'sa', 'za', 'si', 'zi', 'su', 'zu', 'se', 'ze', 'so', 'zo', 'ta',
+'da', 'ti', 'di', 'tu', 'tu', 'du', 'te', 'de', 'to', 'do', 'na', 'ni', 'nu', 'ne', 'no', 'ha',
+'ba', 'pa', 'hi', 'bi', 'pi', 'hu', 'bu', 'pu', 'he', 'be', 'pe', 'ho', 'bo', 'po', 'ma', 'mi',
+'mu', 'me', 'mo', 'ya', 'ya', 'yu', 'yu', 'yo', 'yo', 'ra', 'ri', 'ru', 're', 'ro', 'wa', 'wa',
+'wi', 'we', 'wo', 'n', 'vu', 'ka', 'ke', 'va', 'vi', 've', 'vo', '', '', '"', '"',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x31.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x31.php
new file mode 100644 (file)
index 0000000..45c827e
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x31] = array(
+'[?]', '[?]', '[?]', '[?]', '[?]', 'B', 'P', 'M', 'F', 'D', 'T', 'N', 'L', 'G', 'K', 'H',
+'J', 'Q', 'X', 'ZH', 'CH', 'SH', 'R', 'Z', 'C', 'S', 'A', 'O', 'E', 'EH', 'AI', 'EI',
+'AU', 'OU', 'AN', 'EN', 'ANG', 'ENG', 'ER', 'I', 'U', 'IU', 'V', 'NG', 'GN', '[?]', '[?]', '[?]',
+'[?]', 'g', 'gg', 'gs', 'n', 'nj', 'nh', 'd', 'dd', 'r', 'lg', 'lm', 'lb', 'ls', 'lt', 'lp',
+'rh', 'm', 'b', 'bb', 'bs', 's', 'ss', '', 'j', 'jj', 'c', 'k', 't', 'p', 'h', 'a',
+'ae', 'ya', 'yae', 'eo', 'e', 'yeo', 'ye', 'o', 'wa', 'wae', 'oe', 'yo', 'u', 'weo', 'we', 'wi',
+'yu', 'eu', 'yi', 'i', '', 'nn', 'nd', 'ns', 'nZ', 'lgs', 'ld', 'lbs', 'lZ', 'lQ', 'mb', 'ms',
+'mZ', 'mN', 'bg', '', 'bsg', 'bst', 'bj', 'bt', 'bN', 'bbN', 'sg', 'sn', 'sd', 'sb', 'sj', 'Z',
+'', 'N', 'Ns', 'NZ', 'pN', 'hh', 'Q', 'yo-ya', 'yo-yae', 'yo-i', 'yu-yeo', 'yu-ye', 'yu-i', 'U', 'U-i', '[?]',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'BU', 'ZI', 'JI', 'GU', 'EE', 'ENN', 'OO', 'ONN', 'IR', 'ANN', 'INN', 'UNN', 'IM', 'NGG', 'AINN', 'AUNN',
+'AM', 'OM', 'ONG', 'INNN', 'P', 'T', 'K', 'H', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x32.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x32.php
new file mode 100644 (file)
index 0000000..567b92d
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x32] = array(
+'(g)', '(n)', '(d)', '(r)', '(m)', '(b)', '(s)', '()', '(j)', '(c)', '(k)', '(t)', '(p)', '(h)', '(ga)', '(na)',
+'(da)', '(ra)', '(ma)', '(ba)', '(sa)', '(a)', '(ja)', '(ca)', '(ka)', '(ta)', '(pa)', '(ha)', '(ju)', '[?]', '[?]', '[?]',
+'(1) ', '(2) ', '(3) ', '(4) ', '(5) ', '(6) ', '(7) ', '(8) ', '(9) ', '(10) ', '(Yue) ', '(Huo) ', '(Shui) ', '(Mu) ', '(Jin) ', '(Tu) ',
+'(Ri) ', '(Zhu) ', '(You) ', '(She) ', '(Ming) ', '(Te) ', '(Cai) ', '(Zhu) ', '(Lao) ', '(Dai) ', '(Hu) ', '(Xue) ', '(Jian) ', '(Qi) ', '(Zi) ', '(Xie) ',
+'(Ji) ', '(Xiu) ', '<<', '>>', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'(g)', '(n)', '(d)', '(r)', '(m)', '(b)', '(s)', '()', '(j)', '(c)', '(k)', '(t)', '(p)', '(h)', '(ga)', '(na)',
+'(da)', '(ra)', '(ma)', '(ba)', '(sa)', '(a)', '(ja)', '(ca)', '(ka)', '(ta)', '(pa)', '(ha)', '[?]', '[?]', '[?]', 'KIS ',
+'(1) ', '(2) ', '(3) ', '(4) ', '(5) ', '(6) ', '(7) ', '(8) ', '(9) ', '(10) ', '(Yue) ', '(Huo) ', '(Shui) ', '(Mu) ', '(Jin) ', '(Tu) ',
+'(Ri) ', '(Zhu) ', '(You) ', '(She) ', '(Ming) ', '(Te) ', '(Cai) ', '(Zhu) ', '(Lao) ', '(Mi) ', '(Nan) ', '(Nu) ', '(Shi) ', '(You) ', '(Yin) ', '(Zhu) ',
+'(Xiang) ', '(Xiu) ', '(Xie) ', '(Zheng) ', '(Shang) ', '(Zhong) ', '(Xia) ', '(Zuo) ', '(You) ', '(Yi) ', '(Zong) ', '(Xue) ', '(Jian) ', '(Qi) ', '(Zi) ', '(Xie) ',
+'(Ye) ', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'1M', '2M', '3M', '4M', '5M', '6M', '7M', '8M', '9M', '10M', '11M', '12M', '[?]', '[?]', '[?]', '[?]',
+'a', 'i', 'u', 'u', 'o', 'ka', 'ki', 'ku', 'ke', 'ko', 'sa', 'si', 'su', 'se', 'so', 'ta',
+'ti', 'tu', 'te', 'to', 'na', 'ni', 'nu', 'ne', 'no', 'ha', 'hi', 'hu', 'he', 'ho', 'ma', 'mi',
+'mu', 'me', 'mo', 'ya', 'yu', 'yo', 'ra', 'ri', 'ru', 're', 'ro', 'wa', 'wi', 'we', 'wo',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x33.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x33.php
new file mode 100644 (file)
index 0000000..15095c1
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x33] = array(
+'apartment', 'alpha', 'ampere', 'are', 'inning', 'inch', 'won', 'escudo', 'acre', 'ounce', 'ohm', 'kai-ri', 'carat', 'calorie', 'gallon', 'gamma',
+'giga', 'guinea', 'curie', 'guilder', 'kilo', 'kilogram', 'kilometer', 'kilowatt', 'gram', 'gram ton', 'cruzeiro', 'krone', 'case', 'koruna', 'co-op', 'cycle',
+'centime', 'shilling', 'centi', 'cent', 'dozen', 'desi', 'dollar', 'ton', 'nano', 'knot', 'heights', 'percent', 'parts', 'barrel', 'piaster', 'picul',
+'pico', 'building', 'farad', 'feet', 'bushel', 'franc', 'hectare', 'peso', 'pfennig', 'hertz', 'pence', 'page', 'beta', 'point', 'volt', 'hon',
+'pound', 'hall', 'horn', 'micro', 'mile', 'mach', 'mark', 'mansion', 'micron', 'milli', 'millibar', 'mega', 'megaton', 'meter', 'yard', 'yard',
+'yuan', 'liter', 'lira', 'rupee', 'ruble', 'rem', 'roentgen', 'watt', '0h', '1h', '2h', '3h', '4h', '5h', '6h', '7h',
+'8h', '9h', '10h', '11h', '12h', '13h', '14h', '15h', '16h', '17h', '18h', '19h', '20h', '21h', '22h', '23h',
+'24h', 'HPA', 'da', 'AU', 'bar', 'oV', 'pc', '[?]', '[?]', '[?]', '[?]', 'Heisei', 'Syouwa', 'Taisyou', 'Meiji', 'Inc.',
+'pA', 'nA', 'microamp', 'mA', 'kA', 'kB', 'MB', 'GB', 'cal', 'kcal', 'pF', 'nF', 'microFarad', 'microgram', 'mg', 'kg',
+'Hz', 'kHz', 'MHz', 'GHz', 'THz', 'microliter', 'ml', 'dl', 'kl', 'fm', 'nm', 'micrometer', 'mm', 'cm', 'km', 'mm^2',
+'cm^2', 'm^2', 'km^2', 'mm^4', 'cm^3', 'm^3', 'km^3', 'm/s', 'm/s^2', 'Pa', 'kPa', 'MPa', 'GPa', 'rad', 'rad/s', 'rad/s^2',
+'ps', 'ns', 'microsecond', 'ms', 'pV', 'nV', 'microvolt', 'mV', 'kV', 'MV', 'pW', 'nW', 'microwatt', 'mW', 'kW', 'MW',
+'kOhm', 'MOhm', 'a.m.', 'Bq', 'cc', 'cd', 'C/kg', 'Co.', 'dB', 'Gy', 'ha', 'HP', 'in', 'K.K.', 'KM', 'kt',
+'lm', 'ln', 'log', 'lx', 'mb', 'mil', 'mol', 'pH', 'p.m.', 'PPM', 'PR', 'sr', 'Sv', 'Wb', '[?]', '[?]',
+'1d', '2d', '3d', '4d', '5d', '6d', '7d', '8d', '9d', '10d', '11d', '12d', '13d', '14d', '15d', '16d',
+'17d', '18d', '19d', '20d', '21d', '22d', '23d', '24d', '25d', '26d', '27d', '28d', '29d', '30d', '31d',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x4e.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x4e.php
new file mode 100644 (file)
index 0000000..c5f3f36
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x4e] = array(
+'Yi ', 'Ding ', 'Kao ', 'Qi ', 'Shang ', 'Xia ', '[?]', 'Mo ', 'Zhang ', 'San ', 'Shang ', 'Xia ', 'Ji ', 'Bu ', 'Yu ', 'Mian ',
+'Gai ', 'Chou ', 'Chou ', 'Zhuan ', 'Qie ', 'Pi ', 'Shi ', 'Shi ', 'Qiu ', 'Bing ', 'Ye ', 'Cong ', 'Dong ', 'Si ', 'Cheng ', 'Diu ',
+'Qiu ', 'Liang ', 'Diu ', 'You ', 'Liang ', 'Yan ', 'Bing ', 'Sang ', 'Gun ', 'Jiu ', 'Ge ', 'Ya ', 'Qiang ', 'Zhong ', 'Ji ', 'Jie ',
+'Feng ', 'Guan ', 'Chuan ', 'Chan ', 'Lin ', 'Zhuo ', 'Zhu ', 'Ha ', 'Wan ', 'Dan ', 'Wei ', 'Zhu ', 'Jing ', 'Li ', 'Ju ', 'Pie ',
+'Fu ', 'Yi ', 'Yi ', 'Nai ', 'Shime ', 'Jiu ', 'Jiu ', 'Zhe ', 'Yao ', 'Yi ', '[?]', 'Zhi ', 'Wu ', 'Zha ', 'Hu ', 'Fa ',
+'Le ', 'Zhong ', 'Ping ', 'Pang ', 'Qiao ', 'Hu ', 'Guai ', 'Cheng ', 'Cheng ', 'Yi ', 'Yin ', '[?]', 'Mie ', 'Jiu ', 'Qi ', 'Ye ',
+'Xi ', 'Xiang ', 'Gai ', 'Diu ', 'Hal ', '[?]', 'Shu ', 'Twul ', 'Shi ', 'Ji ', 'Nang ', 'Jia ', 'Kel ', 'Shi ', '[?]', 'Ol ',
+'Mai ', 'Luan ', 'Cal ', 'Ru ', 'Xue ', 'Yan ', 'Fu ', 'Sha ', 'Na ', 'Gan ', 'Sol ', 'El ', 'Cwul ', '[?]', 'Gan ', 'Chi ',
+'Gui ', 'Gan ', 'Luan ', 'Lin ', 'Yi ', 'Jue ', 'Liao ', 'Ma ', 'Yu ', 'Zheng ', 'Shi ', 'Shi ', 'Er ', 'Chu ', 'Yu ', 'Yu ',
+'Yu ', 'Yun ', 'Hu ', 'Qi ', 'Wu ', 'Jing ', 'Si ', 'Sui ', 'Gen ', 'Gen ', 'Ya ', 'Xie ', 'Ya ', 'Qi ', 'Ya ', 'Ji ',
+'Tou ', 'Wang ', 'Kang ', 'Ta ', 'Jiao ', 'Hai ', 'Yi ', 'Chan ', 'Heng ', 'Mu ', '[?]', 'Xiang ', 'Jing ', 'Ting ', 'Liang ', 'Xiang ',
+'Jing ', 'Ye ', 'Qin ', 'Bo ', 'You ', 'Xie ', 'Dan ', 'Lian ', 'Duo ', 'Wei ', 'Ren ', 'Ren ', 'Ji ', 'La ', 'Wang ', 'Yi ',
+'Shi ', 'Ren ', 'Le ', 'Ding ', 'Ze ', 'Jin ', 'Pu ', 'Chou ', 'Ba ', 'Zhang ', 'Jin ', 'Jie ', 'Bing ', 'Reng ', 'Cong ', 'Fo ',
+'San ', 'Lun ', 'Sya ', 'Cang ', 'Zi ', 'Shi ', 'Ta ', 'Zhang ', 'Fu ', 'Xian ', 'Xian ', 'Tuo ', 'Hong ', 'Tong ', 'Ren ', 'Qian ',
+'Gan ', 'Yi ', 'Di ', 'Dai ', 'Ling ', 'Yi ', 'Chao ', 'Chang ', 'Sa ', '[?]', 'Yi ', 'Mu ', 'Men ', 'Ren ', 'Jia ', 'Chao ',
+'Yang ', 'Qian ', 'Zhong ', 'Pi ', 'Wan ', 'Wu ', 'Jian ', 'Jie ', 'Yao ', 'Feng ', 'Cang ', 'Ren ', 'Wang ', 'Fen ', 'Di ', 'Fang ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x4f.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x4f.php
new file mode 100644 (file)
index 0000000..4d3ce06
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x4f] = array(
+'Zhong ', 'Qi ', 'Pei ', 'Yu ', 'Diao ', 'Dun ', 'Wen ', 'Yi ', 'Xin ', 'Kang ', 'Yi ', 'Ji ', 'Ai ', 'Wu ', 'Ji ', 'Fu ',
+'Fa ', 'Xiu ', 'Jin ', 'Bei ', 'Dan ', 'Fu ', 'Tang ', 'Zhong ', 'You ', 'Huo ', 'Hui ', 'Yu ', 'Cui ', 'Chuan ', 'San ', 'Wei ',
+'Chuan ', 'Che ', 'Ya ', 'Xian ', 'Shang ', 'Chang ', 'Lun ', 'Cang ', 'Xun ', 'Xin ', 'Wei ', 'Zhu ', '[?]', 'Xuan ', 'Nu ', 'Bo ',
+'Gu ', 'Ni ', 'Ni ', 'Xie ', 'Ban ', 'Xu ', 'Ling ', 'Zhou ', 'Shen ', 'Qu ', 'Si ', 'Beng ', 'Si ', 'Jia ', 'Pi ', 'Yi ',
+'Si ', 'Ai ', 'Zheng ', 'Dian ', 'Han ', 'Mai ', 'Dan ', 'Zhu ', 'Bu ', 'Qu ', 'Bi ', 'Shao ', 'Ci ', 'Wei ', 'Di ', 'Zhu ',
+'Zuo ', 'You ', 'Yang ', 'Ti ', 'Zhan ', 'He ', 'Bi ', 'Tuo ', 'She ', 'Yu ', 'Yi ', 'Fo ', 'Zuo ', 'Kou ', 'Ning ', 'Tong ',
+'Ni ', 'Xuan ', 'Qu ', 'Yong ', 'Wa ', 'Qian ', '[?]', 'Ka ', '[?]', 'Pei ', 'Huai ', 'He ', 'Lao ', 'Xiang ', 'Ge ', 'Yang ',
+'Bai ', 'Fa ', 'Ming ', 'Jia ', 'Er ', 'Bing ', 'Ji ', 'Hen ', 'Huo ', 'Gui ', 'Quan ', 'Tiao ', 'Jiao ', 'Ci ', 'Yi ', 'Shi ',
+'Xing ', 'Shen ', 'Tuo ', 'Kan ', 'Zhi ', 'Gai ', 'Lai ', 'Yi ', 'Chi ', 'Kua ', 'Guang ', 'Li ', 'Yin ', 'Shi ', 'Mi ', 'Zhu ',
+'Xu ', 'You ', 'An ', 'Lu ', 'Mou ', 'Er ', 'Lun ', 'Tong ', 'Cha ', 'Chi ', 'Xun ', 'Gong ', 'Zhou ', 'Yi ', 'Ru ', 'Jian ',
+'Xia ', 'Jia ', 'Zai ', 'Lu ', 'Ko ', 'Jiao ', 'Zhen ', 'Ce ', 'Qiao ', 'Kuai ', 'Chai ', 'Ning ', 'Nong ', 'Jin ', 'Wu ', 'Hou ',
+'Jiong ', 'Cheng ', 'Zhen ', 'Zuo ', 'Chou ', 'Qin ', 'Lu ', 'Ju ', 'Shu ', 'Ting ', 'Shen ', 'Tuo ', 'Bo ', 'Nan ', 'Hao ', 'Bian ',
+'Tui ', 'Yu ', 'Xi ', 'Cu ', 'E ', 'Qiu ', 'Xu ', 'Kuang ', 'Ku ', 'Wu ', 'Jun ', 'Yi ', 'Fu ', 'Lang ', 'Zu ', 'Qiao ',
+'Li ', 'Yong ', 'Hun ', 'Jing ', 'Xian ', 'San ', 'Pai ', 'Su ', 'Fu ', 'Xi ', 'Li ', 'Fu ', 'Ping ', 'Bao ', 'Yu ', 'Si ',
+'Xia ', 'Xin ', 'Xiu ', 'Yu ', 'Ti ', 'Che ', 'Chou ', '[?]', 'Yan ', 'Lia ', 'Li ', 'Lai ', '[?]', 'Jian ', 'Xiu ', 'Fu ',
+'He ', 'Ju ', 'Xiao ', 'Pai ', 'Jian ', 'Biao ', 'Chu ', 'Fei ', 'Feng ', 'Ya ', 'An ', 'Bei ', 'Yu ', 'Xin ', 'Bi ', 'Jian ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x50.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x50.php
new file mode 100644 (file)
index 0000000..f561e43
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x50] = array(
+'Chang ', 'Chi ', 'Bing ', 'Zan ', 'Yao ', 'Cui ', 'Lia ', 'Wan ', 'Lai ', 'Cang ', 'Zong ', 'Ge ', 'Guan ', 'Bei ', 'Tian ', 'Shu ',
+'Shu ', 'Men ', 'Dao ', 'Tan ', 'Jue ', 'Chui ', 'Xing ', 'Peng ', 'Tang ', 'Hou ', 'Yi ', 'Qi ', 'Ti ', 'Gan ', 'Jing ', 'Jie ',
+'Sui ', 'Chang ', 'Jie ', 'Fang ', 'Zhi ', 'Kong ', 'Juan ', 'Zong ', 'Ju ', 'Qian ', 'Ni ', 'Lun ', 'Zhuo ', 'Wei ', 'Luo ', 'Song ',
+'Leng ', 'Hun ', 'Dong ', 'Zi ', 'Ben ', 'Wu ', 'Ju ', 'Nai ', 'Cai ', 'Jian ', 'Zhai ', 'Ye ', 'Zhi ', 'Sha ', 'Qing ', '[?]',
+'Ying ', 'Cheng ', 'Jian ', 'Yan ', 'Nuan ', 'Zhong ', 'Chun ', 'Jia ', 'Jie ', 'Wei ', 'Yu ', 'Bing ', 'Ruo ', 'Ti ', 'Wei ', 'Pian ',
+'Yan ', 'Feng ', 'Tang ', 'Wo ', 'E ', 'Xie ', 'Che ', 'Sheng ', 'Kan ', 'Di ', 'Zuo ', 'Cha ', 'Ting ', 'Bei ', 'Ye ', 'Huang ',
+'Yao ', 'Zhan ', 'Chou ', 'Yan ', 'You ', 'Jian ', 'Xu ', 'Zha ', 'Ci ', 'Fu ', 'Bi ', 'Zhi ', 'Zong ', 'Mian ', 'Ji ', 'Yi ',
+'Xie ', 'Xun ', 'Si ', 'Duan ', 'Ce ', 'Zhen ', 'Ou ', 'Tou ', 'Tou ', 'Bei ', 'Za ', 'Lu ', 'Jie ', 'Wei ', 'Fen ', 'Chang ',
+'Gui ', 'Sou ', 'Zhi ', 'Su ', 'Xia ', 'Fu ', 'Yuan ', 'Rong ', 'Li ', 'Ru ', 'Yun ', 'Gou ', 'Ma ', 'Bang ', 'Dian ', 'Tang ',
+'Hao ', 'Jie ', 'Xi ', 'Shan ', 'Qian ', 'Jue ', 'Cang ', 'Chu ', 'San ', 'Bei ', 'Xiao ', 'Yong ', 'Yao ', 'Tan ', 'Suo ', 'Yang ',
+'Fa ', 'Bing ', 'Jia ', 'Dai ', 'Zai ', 'Tang ', '[?]', 'Bin ', 'Chu ', 'Nuo ', 'Can ', 'Lei ', 'Cui ', 'Yong ', 'Zao ', 'Zong ',
+'Peng ', 'Song ', 'Ao ', 'Chuan ', 'Yu ', 'Zhai ', 'Cou ', 'Shang ', 'Qiang ', 'Jing ', 'Chi ', 'Sha ', 'Han ', 'Zhang ', 'Qing ', 'Yan ',
+'Di ', 'Xi ', 'Lu ', 'Bei ', 'Piao ', 'Jin ', 'Lian ', 'Lu ', 'Man ', 'Qian ', 'Xian ', 'Tan ', 'Ying ', 'Dong ', 'Zhuan ', 'Xiang ',
+'Shan ', 'Qiao ', 'Jiong ', 'Tui ', 'Zun ', 'Pu ', 'Xi ', 'Lao ', 'Chang ', 'Guang ', 'Liao ', 'Qi ', 'Deng ', 'Chan ', 'Wei ', 'Ji ',
+'Fan ', 'Hui ', 'Chuan ', 'Jian ', 'Dan ', 'Jiao ', 'Jiu ', 'Seng ', 'Fen ', 'Xian ', 'Jue ', 'E ', 'Jiao ', 'Jian ', 'Tong ', 'Lin ',
+'Bo ', 'Gu ', '[?]', 'Su ', 'Xian ', 'Jiang ', 'Min ', 'Ye ', 'Jin ', 'Jia ', 'Qiao ', 'Pi ', 'Feng ', 'Zhou ', 'Ai ', 'Sai ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x51.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x51.php
new file mode 100644 (file)
index 0000000..3ccfb4f
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x51] = array(
+'Yi ', 'Jun ', 'Nong ', 'Chan ', 'Yi ', 'Dang ', 'Jing ', 'Xuan ', 'Kuai ', 'Jian ', 'Chu ', 'Dan ', 'Jiao ', 'Sha ', 'Zai ', '[?]',
+'Bin ', 'An ', 'Ru ', 'Tai ', 'Chou ', 'Chai ', 'Lan ', 'Ni ', 'Jin ', 'Qian ', 'Meng ', 'Wu ', 'Ning ', 'Qiong ', 'Ni ', 'Chang ',
+'Lie ', 'Lei ', 'Lu ', 'Kuang ', 'Bao ', 'Du ', 'Biao ', 'Zan ', 'Zhi ', 'Si ', 'You ', 'Hao ', 'Chen ', 'Chen ', 'Li ', 'Teng ',
+'Wei ', 'Long ', 'Chu ', 'Chan ', 'Rang ', 'Shu ', 'Hui ', 'Li ', 'Luo ', 'Zan ', 'Nuo ', 'Tang ', 'Yan ', 'Lei ', 'Nang ', 'Er ',
+'Wu ', 'Yun ', 'Zan ', 'Yuan ', 'Xiong ', 'Chong ', 'Zhao ', 'Xiong ', 'Xian ', 'Guang ', 'Dui ', 'Ke ', 'Dui ', 'Mian ', 'Tu ', 'Chang ',
+'Er ', 'Dui ', 'Er ', 'Xin ', 'Tu ', 'Si ', 'Yan ', 'Yan ', 'Shi ', 'Shi ', 'Dang ', 'Qian ', 'Dou ', 'Fen ', 'Mao ', 'Shen ',
+'Dou ', 'Bai ', 'Jing ', 'Li ', 'Huang ', 'Ru ', 'Wang ', 'Nei ', 'Quan ', 'Liang ', 'Yu ', 'Ba ', 'Gong ', 'Liu ', 'Xi ', '[?]',
+'Lan ', 'Gong ', 'Tian ', 'Guan ', 'Xing ', 'Bing ', 'Qi ', 'Ju ', 'Dian ', 'Zi ', 'Ppwun ', 'Yang ', 'Jian ', 'Shou ', 'Ji ', 'Yi ',
+'Ji ', 'Chan ', 'Jiong ', 'Mao ', 'Ran ', 'Nei ', 'Yuan ', 'Mao ', 'Gang ', 'Ran ', 'Ce ', 'Jiong ', 'Ce ', 'Zai ', 'Gua ', 'Jiong ',
+'Mao ', 'Zhou ', 'Mou ', 'Gou ', 'Xu ', 'Mian ', 'Mi ', 'Rong ', 'Yin ', 'Xie ', 'Kan ', 'Jun ', 'Nong ', 'Yi ', 'Mi ', 'Shi ',
+'Guan ', 'Meng ', 'Zhong ', 'Ju ', 'Yuan ', 'Ming ', 'Kou ', 'Lam ', 'Fu ', 'Xie ', 'Mi ', 'Bing ', 'Dong ', 'Tai ', 'Gang ', 'Feng ',
+'Bing ', 'Hu ', 'Chong ', 'Jue ', 'Hu ', 'Kuang ', 'Ye ', 'Leng ', 'Pan ', 'Fu ', 'Min ', 'Dong ', 'Xian ', 'Lie ', 'Xia ', 'Jian ',
+'Jing ', 'Shu ', 'Mei ', 'Tu ', 'Qi ', 'Gu ', 'Zhun ', 'Song ', 'Jing ', 'Liang ', 'Qing ', 'Diao ', 'Ling ', 'Dong ', 'Gan ', 'Jian ',
+'Yin ', 'Cou ', 'Yi ', 'Li ', 'Cang ', 'Ming ', 'Zhuen ', 'Cui ', 'Si ', 'Duo ', 'Jin ', 'Lin ', 'Lin ', 'Ning ', 'Xi ', 'Du ',
+'Ji ', 'Fan ', 'Fan ', 'Fan ', 'Feng ', 'Ju ', 'Chu ', 'Tako ', 'Feng ', 'Mok ', 'Ci ', 'Fu ', 'Feng ', 'Ping ', 'Feng ', 'Kai ',
+'Huang ', 'Kai ', 'Gan ', 'Deng ', 'Ping ', 'Qu ', 'Xiong ', 'Kuai ', 'Tu ', 'Ao ', 'Chu ', 'Ji ', 'Dang ', 'Han ', 'Han ', 'Zao ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x52.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x52.php
new file mode 100644 (file)
index 0000000..cb36232
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x52] = array(
+'Dao ', 'Diao ', 'Dao ', 'Ren ', 'Ren ', 'Chuang ', 'Fen ', 'Qie ', 'Yi ', 'Ji ', 'Kan ', 'Qian ', 'Cun ', 'Chu ', 'Wen ', 'Ji ',
+'Dan ', 'Xing ', 'Hua ', 'Wan ', 'Jue ', 'Li ', 'Yue ', 'Lie ', 'Liu ', 'Ze ', 'Gang ', 'Chuang ', 'Fu ', 'Chu ', 'Qu ', 'Ju ',
+'Shan ', 'Min ', 'Ling ', 'Zhong ', 'Pan ', 'Bie ', 'Jie ', 'Jie ', 'Bao ', 'Li ', 'Shan ', 'Bie ', 'Chan ', 'Jing ', 'Gua ', 'Gen ',
+'Dao ', 'Chuang ', 'Kui ', 'Ku ', 'Duo ', 'Er ', 'Zhi ', 'Shua ', 'Quan ', 'Cha ', 'Ci ', 'Ke ', 'Jie ', 'Gui ', 'Ci ', 'Gui ',
+'Kai ', 'Duo ', 'Ji ', 'Ti ', 'Jing ', 'Lou ', 'Gen ', 'Ze ', 'Yuan ', 'Cuo ', 'Xue ', 'Ke ', 'La ', 'Qian ', 'Cha ', 'Chuang ',
+'Gua ', 'Jian ', 'Cuo ', 'Li ', 'Ti ', 'Fei ', 'Pou ', 'Chan ', 'Qi ', 'Chuang ', 'Zi ', 'Gang ', 'Wan ', 'Bo ', 'Ji ', 'Duo ',
+'Qing ', 'Yan ', 'Zhuo ', 'Jian ', 'Ji ', 'Bo ', 'Yan ', 'Ju ', 'Huo ', 'Sheng ', 'Jian ', 'Duo ', 'Duan ', 'Wu ', 'Gua ', 'Fu ',
+'Sheng ', 'Jian ', 'Ge ', 'Zha ', 'Kai ', 'Chuang ', 'Juan ', 'Chan ', 'Tuan ', 'Lu ', 'Li ', 'Fou ', 'Shan ', 'Piao ', 'Kou ', 'Jiao ',
+'Gua ', 'Qiao ', 'Jue ', 'Hua ', 'Zha ', 'Zhuo ', 'Lian ', 'Ju ', 'Pi ', 'Liu ', 'Gui ', 'Jiao ', 'Gui ', 'Jian ', 'Jian ', 'Tang ',
+'Huo ', 'Ji ', 'Jian ', 'Yi ', 'Jian ', 'Zhi ', 'Chan ', 'Cuan ', 'Mo ', 'Li ', 'Zhu ', 'Li ', 'Ya ', 'Quan ', 'Ban ', 'Gong ',
+'Jia ', 'Wu ', 'Mai ', 'Lie ', 'Jin ', 'Keng ', 'Xie ', 'Zhi ', 'Dong ', 'Zhu ', 'Nu ', 'Jie ', 'Qu ', 'Shao ', 'Yi ', 'Zhu ',
+'Miao ', 'Li ', 'Jing ', 'Lao ', 'Lao ', 'Juan ', 'Kou ', 'Yang ', 'Wa ', 'Xiao ', 'Mou ', 'Kuang ', 'Jie ', 'Lie ', 'He ', 'Shi ',
+'Ke ', 'Jing ', 'Hao ', 'Bo ', 'Min ', 'Chi ', 'Lang ', 'Yong ', 'Yong ', 'Mian ', 'Ke ', 'Xun ', 'Juan ', 'Qing ', 'Lu ', 'Pou ',
+'Meng ', 'Lai ', 'Le ', 'Kai ', 'Mian ', 'Dong ', 'Xu ', 'Xu ', 'Kan ', 'Wu ', 'Yi ', 'Xun ', 'Weng ', 'Sheng ', 'Lao ', 'Mu ',
+'Lu ', 'Piao ', 'Shi ', 'Ji ', 'Qin ', 'Qiang ', 'Jiao ', 'Quan ', 'Yang ', 'Yi ', 'Jue ', 'Fan ', 'Juan ', 'Tong ', 'Ju ', 'Dan ',
+'Xie ', 'Mai ', 'Xun ', 'Xun ', 'Lu ', 'Li ', 'Che ', 'Rang ', 'Quan ', 'Bao ', 'Shao ', 'Yun ', 'Jiu ', 'Bao ', 'Gou ', 'Wu ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x53.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x53.php
new file mode 100644 (file)
index 0000000..aa37183
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x53] = array(
+'Yun ', 'Mwun ', 'Nay ', 'Gai ', 'Gai ', 'Bao ', 'Cong ', '[?]', 'Xiong ', 'Peng ', 'Ju ', 'Tao ', 'Ge ', 'Pu ', 'An ', 'Pao ',
+'Fu ', 'Gong ', 'Da ', 'Jiu ', 'Qiong ', 'Bi ', 'Hua ', 'Bei ', 'Nao ', 'Chi ', 'Fang ', 'Jiu ', 'Yi ', 'Za ', 'Jiang ', 'Kang ',
+'Jiang ', 'Kuang ', 'Hu ', 'Xia ', 'Qu ', 'Bian ', 'Gui ', 'Qie ', 'Zang ', 'Kuang ', 'Fei ', 'Hu ', 'Tou ', 'Gui ', 'Gui ', 'Hui ',
+'Dan ', 'Gui ', 'Lian ', 'Lian ', 'Suan ', 'Du ', 'Jiu ', 'Qu ', 'Xi ', 'Pi ', 'Qu ', 'Yi ', 'Qia ', 'Yan ', 'Bian ', 'Ni ',
+'Qu ', 'Shi ', 'Xin ', 'Qian ', 'Nian ', 'Sa ', 'Zu ', 'Sheng ', 'Wu ', 'Hui ', 'Ban ', 'Shi ', 'Xi ', 'Wan ', 'Hua ', 'Xie ',
+'Wan ', 'Bei ', 'Zu ', 'Zhuo ', 'Xie ', 'Dan ', 'Mai ', 'Nan ', 'Dan ', 'Ji ', 'Bo ', 'Shuai ', 'Bu ', 'Kuang ', 'Bian ', 'Bu ',
+'Zhan ', 'Qia ', 'Lu ', 'You ', 'Lu ', 'Xi ', 'Gua ', 'Wo ', 'Xie ', 'Jie ', 'Jie ', 'Wei ', 'Ang ', 'Qiong ', 'Zhi ', 'Mao ',
+'Yin ', 'Wei ', 'Shao ', 'Ji ', 'Que ', 'Luan ', 'Shi ', 'Juan ', 'Xie ', 'Xu ', 'Jin ', 'Que ', 'Wu ', 'Ji ', 'E ', 'Qing ',
+'Xi ', '[?]', 'Han ', 'Zhan ', 'E ', 'Ting ', 'Li ', 'Zhe ', 'Han ', 'Li ', 'Ya ', 'Ya ', 'Yan ', 'She ', 'Zhi ', 'Zha ',
+'Pang ', '[?]', 'He ', 'Ya ', 'Zhi ', 'Ce ', 'Pang ', 'Ti ', 'Li ', 'She ', 'Hou ', 'Ting ', 'Zui ', 'Cuo ', 'Fei ', 'Yuan ',
+'Ce ', 'Yuan ', 'Xiang ', 'Yan ', 'Li ', 'Jue ', 'Sha ', 'Dian ', 'Chu ', 'Jiu ', 'Qin ', 'Ao ', 'Gui ', 'Yan ', 'Si ', 'Li ',
+'Chang ', 'Lan ', 'Li ', 'Yan ', 'Yan ', 'Yuan ', 'Si ', 'Gong ', 'Lin ', 'Qiu ', 'Qu ', 'Qu ', 'Uk ', 'Lei ', 'Du ', 'Xian ',
+'Zhuan ', 'San ', 'Can ', 'Can ', 'Can ', 'Can ', 'Ai ', 'Dai ', 'You ', 'Cha ', 'Ji ', 'You ', 'Shuang ', 'Fan ', 'Shou ', 'Guai ',
+'Ba ', 'Fa ', 'Ruo ', 'Shi ', 'Shu ', 'Zhuo ', 'Qu ', 'Shou ', 'Bian ', 'Xu ', 'Jia ', 'Pan ', 'Sou ', 'Gao ', 'Wei ', 'Sou ',
+'Die ', 'Rui ', 'Cong ', 'Kou ', 'Gu ', 'Ju ', 'Ling ', 'Gua ', 'Tao ', 'Kou ', 'Zhi ', 'Jiao ', 'Zhao ', 'Ba ', 'Ding ', 'Ke ',
+'Tai ', 'Chi ', 'Shi ', 'You ', 'Qiu ', 'Po ', 'Xie ', 'Hao ', 'Si ', 'Tan ', 'Chi ', 'Le ', 'Diao ', 'Ji ', '[?]', 'Hong ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x54.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x54.php
new file mode 100644 (file)
index 0000000..f830528
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x54] = array(
+'Mie ', 'Xu ', 'Mang ', 'Chi ', 'Ge ', 'Xuan ', 'Yao ', 'Zi ', 'He ', 'Ji ', 'Diao ', 'Cun ', 'Tong ', 'Ming ', 'Hou ', 'Li ',
+'Tu ', 'Xiang ', 'Zha ', 'Xia ', 'Ye ', 'Lu ', 'A ', 'Ma ', 'Ou ', 'Xue ', 'Yi ', 'Jun ', 'Chou ', 'Lin ', 'Tun ', 'Yin ',
+'Fei ', 'Bi ', 'Qin ', 'Qin ', 'Jie ', 'Bu ', 'Fou ', 'Ba ', 'Dun ', 'Fen ', 'E ', 'Han ', 'Ting ', 'Hang ', 'Shun ', 'Qi ',
+'Hong ', 'Zhi ', 'Shen ', 'Wu ', 'Wu ', 'Chao ', 'Ne ', 'Xue ', 'Xi ', 'Chui ', 'Dou ', 'Wen ', 'Hou ', 'Ou ', 'Wu ', 'Gao ',
+'Ya ', 'Jun ', 'Lu ', 'E ', 'Ge ', 'Mei ', 'Ai ', 'Qi ', 'Cheng ', 'Wu ', 'Gao ', 'Fu ', 'Jiao ', 'Hong ', 'Chi ', 'Sheng ',
+'Ne ', 'Tun ', 'Fu ', 'Yi ', 'Dai ', 'Ou ', 'Li ', 'Bai ', 'Yuan ', 'Kuai ', '[?]', 'Qiang ', 'Wu ', 'E ', 'Shi ', 'Quan ',
+'Pen ', 'Wen ', 'Ni ', 'M ', 'Ling ', 'Ran ', 'You ', 'Di ', 'Zhou ', 'Shi ', 'Zhou ', 'Tie ', 'Xi ', 'Yi ', 'Qi ', 'Ping ',
+'Zi ', 'Gu ', 'Zi ', 'Wei ', 'Xu ', 'He ', 'Nao ', 'Xia ', 'Pei ', 'Yi ', 'Xiao ', 'Shen ', 'Hu ', 'Ming ', 'Da ', 'Qu ',
+'Ju ', 'Gem ', 'Za ', 'Tuo ', 'Duo ', 'Pou ', 'Pao ', 'Bi ', 'Fu ', 'Yang ', 'He ', 'Zha ', 'He ', 'Hai ', 'Jiu ', 'Yong ',
+'Fu ', 'Que ', 'Zhou ', 'Wa ', 'Ka ', 'Gu ', 'Ka ', 'Zuo ', 'Bu ', 'Long ', 'Dong ', 'Ning ', 'Tha ', 'Si ', 'Xian ', 'Huo ',
+'Qi ', 'Er ', 'E ', 'Guang ', 'Zha ', 'Xi ', 'Yi ', 'Lie ', 'Zi ', 'Mie ', 'Mi ', 'Zhi ', 'Yao ', 'Ji ', 'Zhou ', 'Ge ',
+'Shuai ', 'Zan ', 'Xiao ', 'Ke ', 'Hui ', 'Kua ', 'Huai ', 'Tao ', 'Xian ', 'E ', 'Xuan ', 'Xiu ', 'Wai ', 'Yan ', 'Lao ', 'Yi ',
+'Ai ', 'Pin ', 'Shen ', 'Tong ', 'Hong ', 'Xiong ', 'Chi ', 'Wa ', 'Ha ', 'Zai ', 'Yu ', 'Di ', 'Pai ', 'Xiang ', 'Ai ', 'Hen ',
+'Kuang ', 'Ya ', 'Da ', 'Xiao ', 'Bi ', 'Yue ', '[?]', 'Hua ', 'Sasou ', 'Kuai ', 'Duo ', '[?]', 'Ji ', 'Nong ', 'Mou ', 'Yo ',
+'Hao ', 'Yuan ', 'Long ', 'Pou ', 'Mang ', 'Ge ', 'E ', 'Chi ', 'Shao ', 'Li ', 'Na ', 'Zu ', 'He ', 'Ku ', 'Xiao ', 'Xian ',
+'Lao ', 'Bo ', 'Zhe ', 'Zha ', 'Liang ', 'Ba ', 'Mie ', 'Le ', 'Sui ', 'Fou ', 'Bu ', 'Han ', 'Heng ', 'Geng ', 'Shuo ', 'Ge ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x55.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x55.php
new file mode 100644 (file)
index 0000000..4bda59c
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x55] = array(
+'You ', 'Yan ', 'Gu ', 'Gu ', 'Bai ', 'Han ', 'Suo ', 'Chun ', 'Yi ', 'Ai ', 'Jia ', 'Tu ', 'Xian ', 'Huan ', 'Li ', 'Xi ',
+'Tang ', 'Zuo ', 'Qiu ', 'Che ', 'Wu ', 'Zao ', 'Ya ', 'Dou ', 'Qi ', 'Di ', 'Qin ', 'Ma ', 'Mal ', 'Hong ', 'Dou ', 'Kes ',
+'Lao ', 'Liang ', 'Suo ', 'Zao ', 'Huan ', 'Lang ', 'Sha ', 'Ji ', 'Zuo ', 'Wo ', 'Feng ', 'Yin ', 'Hu ', 'Qi ', 'Shou ', 'Wei ',
+'Shua ', 'Chang ', 'Er ', 'Li ', 'Qiang ', 'An ', 'Jie ', 'Yo ', 'Nian ', 'Yu ', 'Tian ', 'Lai ', 'Sha ', 'Xi ', 'Tuo ', 'Hu ',
+'Ai ', 'Zhou ', 'Nou ', 'Ken ', 'Zhuo ', 'Zhuo ', 'Shang ', 'Di ', 'Heng ', 'Lan ', 'A ', 'Xiao ', 'Xiang ', 'Tun ', 'Wu ', 'Wen ',
+'Cui ', 'Sha ', 'Hu ', 'Qi ', 'Qi ', 'Tao ', 'Dan ', 'Dan ', 'Ye ', 'Zi ', 'Bi ', 'Cui ', 'Chuo ', 'He ', 'Ya ', 'Qi ',
+'Zhe ', 'Pei ', 'Liang ', 'Xian ', 'Pi ', 'Sha ', 'La ', 'Ze ', 'Qing ', 'Gua ', 'Pa ', 'Zhe ', 'Se ', 'Zhuan ', 'Nie ', 'Guo ',
+'Luo ', 'Yan ', 'Di ', 'Quan ', 'Tan ', 'Bo ', 'Ding ', 'Lang ', 'Xiao ', '[?]', 'Tang ', 'Chi ', 'Ti ', 'An ', 'Jiu ', 'Dan ',
+'Ke ', 'Yong ', 'Wei ', 'Nan ', 'Shan ', 'Yu ', 'Zhe ', 'La ', 'Jie ', 'Hou ', 'Han ', 'Die ', 'Zhou ', 'Chai ', 'Wai ', 'Re ',
+'Yu ', 'Yin ', 'Zan ', 'Yao ', 'Wo ', 'Mian ', 'Hu ', 'Yun ', 'Chuan ', 'Hui ', 'Huan ', 'Huan ', 'Xi ', 'He ', 'Ji ', 'Kui ',
+'Zhong ', 'Wei ', 'Sha ', 'Xu ', 'Huang ', 'Du ', 'Nie ', 'Xuan ', 'Liang ', 'Yu ', 'Sang ', 'Chi ', 'Qiao ', 'Yan ', 'Dan ', 'Pen ',
+'Can ', 'Li ', 'Yo ', 'Zha ', 'Wei ', 'Miao ', 'Ying ', 'Pen ', 'Phos ', 'Kui ', 'Xi ', 'Yu ', 'Jie ', 'Lou ', 'Ku ', 'Sao ',
+'Huo ', 'Ti ', 'Yao ', 'He ', 'A ', 'Xiu ', 'Qiang ', 'Se ', 'Yong ', 'Su ', 'Hong ', 'Xie ', 'Yi ', 'Suo ', 'Ma ', 'Cha ',
+'Hai ', 'Ke ', 'Ta ', 'Sang ', 'Tian ', 'Ru ', 'Sou ', 'Wa ', 'Ji ', 'Pang ', 'Wu ', 'Xian ', 'Shi ', 'Ge ', 'Zi ', 'Jie ',
+'Luo ', 'Weng ', 'Wa ', 'Si ', 'Chi ', 'Hao ', 'Suo ', 'Jia ', 'Hai ', 'Suo ', 'Qin ', 'Nie ', 'He ', 'Cis ', 'Sai ', 'Ng ',
+'Ge ', 'Na ', 'Dia ', 'Ai ', '[?]', 'Tong ', 'Bi ', 'Ao ', 'Ao ', 'Lian ', 'Cui ', 'Zhe ', 'Mo ', 'Sou ', 'Sou ', 'Tan ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x56.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x56.php
new file mode 100644 (file)
index 0000000..78735ec
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x56] = array(
+'Di ', 'Qi ', 'Jiao ', 'Chong ', 'Jiao ', 'Kai ', 'Tan ', 'San ', 'Cao ', 'Jia ', 'Ai ', 'Xiao ', 'Piao ', 'Lou ', 'Ga ', 'Gu ',
+'Xiao ', 'Hu ', 'Hui ', 'Guo ', 'Ou ', 'Xian ', 'Ze ', 'Chang ', 'Xu ', 'Po ', 'De ', 'Ma ', 'Ma ', 'Hu ', 'Lei ', 'Du ',
+'Ga ', 'Tang ', 'Ye ', 'Beng ', 'Ying ', 'Saai ', 'Jiao ', 'Mi ', 'Xiao ', 'Hua ', 'Mai ', 'Ran ', 'Zuo ', 'Peng ', 'Lao ', 'Xiao ',
+'Ji ', 'Zhu ', 'Chao ', 'Kui ', 'Zui ', 'Xiao ', 'Si ', 'Hao ', 'Fu ', 'Liao ', 'Qiao ', 'Xi ', 'Xiu ', 'Tan ', 'Tan ', 'Mo ',
+'Xun ', 'E ', 'Zun ', 'Fan ', 'Chi ', 'Hui ', 'Zan ', 'Chuang ', 'Cu ', 'Dan ', 'Yu ', 'Tun ', 'Cheng ', 'Jiao ', 'Ye ', 'Xi ',
+'Qi ', 'Hao ', 'Lian ', 'Xu ', 'Deng ', 'Hui ', 'Yin ', 'Pu ', 'Jue ', 'Qin ', 'Xun ', 'Nie ', 'Lu ', 'Si ', 'Yan ', 'Ying ',
+'Da ', 'Dan ', 'Yu ', 'Zhou ', 'Jin ', 'Nong ', 'Yue ', 'Hui ', 'Qi ', 'E ', 'Zao ', 'Yi ', 'Shi ', 'Jiao ', 'Yuan ', 'Ai ',
+'Yong ', 'Jue ', 'Kuai ', 'Yu ', 'Pen ', 'Dao ', 'Ge ', 'Xin ', 'Dun ', 'Dang ', 'Sin ', 'Sai ', 'Pi ', 'Pi ', 'Yin ', 'Zui ',
+'Ning ', 'Di ', 'Lan ', 'Ta ', 'Huo ', 'Ru ', 'Hao ', 'Xia ', 'Ya ', 'Duo ', 'Xi ', 'Chou ', 'Ji ', 'Jin ', 'Hao ', 'Ti ',
+'Chang ', '[?]', '[?]', 'Ca ', 'Ti ', 'Lu ', 'Hui ', 'Bo ', 'You ', 'Nie ', 'Yin ', 'Hu ', 'Mo ', 'Huang ', 'Zhe ', 'Li ',
+'Liu ', 'Haai ', 'Nang ', 'Xiao ', 'Mo ', 'Yan ', 'Li ', 'Lu ', 'Long ', 'Fu ', 'Dan ', 'Chen ', 'Pin ', 'Pi ', 'Xiang ', 'Huo ',
+'Mo ', 'Xi ', 'Duo ', 'Ku ', 'Yan ', 'Chan ', 'Ying ', 'Rang ', 'Dian ', 'La ', 'Ta ', 'Xiao ', 'Jiao ', 'Chuo ', 'Huan ', 'Huo ',
+'Zhuan ', 'Nie ', 'Xiao ', 'Ca ', 'Li ', 'Chan ', 'Chai ', 'Li ', 'Yi ', 'Luo ', 'Nang ', 'Zan ', 'Su ', 'Xi ', 'So ', 'Jian ',
+'Za ', 'Zhu ', 'Lan ', 'Nie ', 'Nang ', '[?]', '[?]', 'Wei ', 'Hui ', 'Yin ', 'Qiu ', 'Si ', 'Nin ', 'Jian ', 'Hui ', 'Xin ',
+'Yin ', 'Nan ', 'Tuan ', 'Tuan ', 'Dun ', 'Kang ', 'Yuan ', 'Jiong ', 'Pian ', 'Yun ', 'Cong ', 'Hu ', 'Hui ', 'Yuan ', 'You ', 'Guo ',
+'Kun ', 'Cong ', 'Wei ', 'Tu ', 'Wei ', 'Lun ', 'Guo ', 'Qun ', 'Ri ', 'Ling ', 'Gu ', 'Guo ', 'Tai ', 'Guo ', 'Tu ', 'You ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x57.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x57.php
new file mode 100644 (file)
index 0000000..610648a
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x57] = array(
+'Guo ', 'Yin ', 'Hun ', 'Pu ', 'Yu ', 'Han ', 'Yuan ', 'Lun ', 'Quan ', 'Yu ', 'Qing ', 'Guo ', 'Chuan ', 'Wei ', 'Yuan ', 'Quan ',
+'Ku ', 'Fu ', 'Yuan ', 'Yuan ', 'E ', 'Tu ', 'Tu ', 'Tu ', 'Tuan ', 'Lue ', 'Hui ', 'Yi ', 'Yuan ', 'Luan ', 'Luan ', 'Tu ',
+'Ya ', 'Tu ', 'Ting ', 'Sheng ', 'Pu ', 'Lu ', 'Iri ', 'Ya ', 'Zai ', 'Wei ', 'Ge ', 'Yu ', 'Wu ', 'Gui ', 'Pi ', 'Yi ',
+'Di ', 'Qian ', 'Qian ', 'Zhen ', 'Zhuo ', 'Dang ', 'Qia ', 'Akutsu ', 'Yama ', 'Kuang ', 'Chang ', 'Qi ', 'Nie ', 'Mo ', 'Ji ', 'Jia ',
+'Zhi ', 'Zhi ', 'Ban ', 'Xun ', 'Tou ', 'Qin ', 'Fen ', 'Jun ', 'Keng ', 'Tun ', 'Fang ', 'Fen ', 'Ben ', 'Tan ', 'Kan ', 'Pi ',
+'Zuo ', 'Keng ', 'Bi ', 'Xing ', 'Di ', 'Jing ', 'Ji ', 'Kuai ', 'Di ', 'Jing ', 'Jian ', 'Tan ', 'Li ', 'Ba ', 'Wu ', 'Fen ',
+'Zhui ', 'Po ', 'Pan ', 'Tang ', 'Kun ', 'Qu ', 'Tan ', 'Zhi ', 'Tuo ', 'Gan ', 'Ping ', 'Dian ', 'Gua ', 'Ni ', 'Tai ', 'Pi ',
+'Jiong ', 'Yang ', 'Fo ', 'Ao ', 'Liu ', 'Qiu ', 'Mu ', 'Ke ', 'Gou ', 'Xue ', 'Ba ', 'Chi ', 'Che ', 'Ling ', 'Zhu ', 'Fu ',
+'Hu ', 'Zhi ', 'Chui ', 'La ', 'Long ', 'Long ', 'Lu ', 'Ao ', 'Tay ', 'Pao ', '[?]', 'Xing ', 'Dong ', 'Ji ', 'Ke ', 'Lu ',
+'Ci ', 'Chi ', 'Lei ', 'Gai ', 'Yin ', 'Hou ', 'Dui ', 'Zhao ', 'Fu ', 'Guang ', 'Yao ', 'Duo ', 'Duo ', 'Gui ', 'Cha ', 'Yang ',
+'Yin ', 'Fa ', 'Gou ', 'Yuan ', 'Die ', 'Xie ', 'Ken ', 'Jiong ', 'Shou ', 'E ', 'Ha ', 'Dian ', 'Hong ', 'Wu ', 'Kua ', '[?]',
+'Tao ', 'Dang ', 'Kai ', 'Gake ', 'Nao ', 'An ', 'Xing ', 'Xian ', 'Huan ', 'Bang ', 'Pei ', 'Ba ', 'Yi ', 'Yin ', 'Han ', 'Xu ',
+'Chui ', 'Cen ', 'Geng ', 'Ai ', 'Peng ', 'Fang ', 'Que ', 'Yong ', 'Xun ', 'Jia ', 'Di ', 'Mai ', 'Lang ', 'Xuan ', 'Cheng ', 'Yan ',
+'Jin ', 'Zhe ', 'Lei ', 'Lie ', 'Bu ', 'Cheng ', 'Gomi ', 'Bu ', 'Shi ', 'Xun ', 'Guo ', 'Jiong ', 'Ye ', 'Nian ', 'Di ', 'Yu ',
+'Bu ', 'Ya ', 'Juan ', 'Sui ', 'Pi ', 'Cheng ', 'Wan ', 'Ju ', 'Lun ', 'Zheng ', 'Kong ', 'Chong ', 'Dong ', 'Dai ', 'Tan ', 'An ',
+'Cai ', 'Shu ', 'Beng ', 'Kan ', 'Zhi ', 'Duo ', 'Yi ', 'Zhi ', 'Yi ', 'Pei ', 'Ji ', 'Zhun ', 'Qi ', 'Sao ', 'Ju ', 'Ni ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x58.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x58.php
new file mode 100644 (file)
index 0000000..3d41da4
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x58] = array(
+'Ku ', 'Ke ', 'Tang ', 'Kun ', 'Ni ', 'Jian ', 'Dui ', 'Jin ', 'Gang ', 'Yu ', 'E ', 'Peng ', 'Gu ', 'Tu ', 'Leng ', '[?]',
+'Ya ', 'Qian ', '[?]', 'An ', '[?]', 'Duo ', 'Nao ', 'Tu ', 'Cheng ', 'Yin ', 'Hun ', 'Bi ', 'Lian ', 'Guo ', 'Die ', 'Zhuan ',
+'Hou ', 'Bao ', 'Bao ', 'Yu ', 'Di ', 'Mao ', 'Jie ', 'Ruan ', 'E ', 'Geng ', 'Kan ', 'Zong ', 'Yu ', 'Huang ', 'E ', 'Yao ',
+'Yan ', 'Bao ', 'Ji ', 'Mei ', 'Chang ', 'Du ', 'Tuo ', 'Yin ', 'Feng ', 'Zhong ', 'Jie ', 'Zhen ', 'Feng ', 'Gang ', 'Chuan ', 'Jian ',
+'Pyeng ', 'Toride ', 'Xiang ', 'Huang ', 'Leng ', 'Duan ', '[?]', 'Xuan ', 'Ji ', 'Ji ', 'Kuai ', 'Ying ', 'Ta ', 'Cheng ', 'Yong ', 'Kai ',
+'Su ', 'Su ', 'Shi ', 'Mi ', 'Ta ', 'Weng ', 'Cheng ', 'Tu ', 'Tang ', 'Que ', 'Zhong ', 'Li ', 'Peng ', 'Bang ', 'Sai ', 'Zang ',
+'Dui ', 'Tian ', 'Wu ', 'Cheng ', 'Xun ', 'Ge ', 'Zhen ', 'Ai ', 'Gong ', 'Yan ', 'Kan ', 'Tian ', 'Yuan ', 'Wen ', 'Xie ', 'Liu ',
+'Ama ', 'Lang ', 'Chang ', 'Peng ', 'Beng ', 'Chen ', 'Cu ', 'Lu ', 'Ou ', 'Qian ', 'Mei ', 'Mo ', 'Zhuan ', 'Shuang ', 'Shu ', 'Lou ',
+'Chi ', 'Man ', 'Biao ', 'Jing ', 'Qi ', 'Shu ', 'Di ', 'Zhang ', 'Kan ', 'Yong ', 'Dian ', 'Chen ', 'Zhi ', 'Xi ', 'Guo ', 'Qiang ',
+'Jin ', 'Di ', 'Shang ', 'Mu ', 'Cui ', 'Yan ', 'Ta ', 'Zeng ', 'Qi ', 'Qiang ', 'Liang ', '[?]', 'Zhui ', 'Qiao ', 'Zeng ', 'Xu ',
+'Shan ', 'Shan ', 'Ba ', 'Pu ', 'Kuai ', 'Dong ', 'Fan ', 'Que ', 'Mo ', 'Dun ', 'Dun ', 'Dun ', 'Di ', 'Sheng ', 'Duo ', 'Duo ',
+'Tan ', 'Deng ', 'Wu ', 'Fen ', 'Huang ', 'Tan ', 'Da ', 'Ye ', 'Sho ', 'Mama ', 'Yu ', 'Qiang ', 'Ji ', 'Qiao ', 'Ken ', 'Yi ',
+'Pi ', 'Bi ', 'Dian ', 'Jiang ', 'Ye ', 'Yong ', 'Bo ', 'Tan ', 'Lan ', 'Ju ', 'Huai ', 'Dang ', 'Rang ', 'Qian ', 'Xun ', 'Lan ',
+'Xi ', 'He ', 'Ai ', 'Ya ', 'Dao ', 'Hao ', 'Ruan ', 'Mama ', 'Lei ', 'Kuang ', 'Lu ', 'Yan ', 'Tan ', 'Wei ', 'Huai ', 'Long ',
+'Long ', 'Rui ', 'Li ', 'Lin ', 'Rang ', 'Ten ', 'Xun ', 'Yan ', 'Lei ', 'Ba ', '[?]', 'Shi ', 'Ren ', '[?]', 'Zhuang ', 'Zhuang ',
+'Sheng ', 'Yi ', 'Mai ', 'Ke ', 'Zhu ', 'Zhuang ', 'Hu ', 'Hu ', 'Kun ', 'Yi ', 'Hu ', 'Xu ', 'Kun ', 'Shou ', 'Mang ', 'Zun ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x59.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x59.php
new file mode 100644 (file)
index 0000000..8f057fb
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x59] = array(
+'Shou ', 'Yi ', 'Zhi ', 'Gu ', 'Chu ', 'Jiang ', 'Feng ', 'Bei ', 'Cay ', 'Bian ', 'Sui ', 'Qun ', 'Ling ', 'Fu ', 'Zuo ', 'Xia ',
+'Xiong ', '[?]', 'Nao ', 'Xia ', 'Kui ', 'Xi ', 'Wai ', 'Yuan ', 'Mao ', 'Su ', 'Duo ', 'Duo ', 'Ye ', 'Qing ', 'Uys ', 'Gou ',
+'Gou ', 'Qi ', 'Meng ', 'Meng ', 'Yin ', 'Huo ', 'Chen ', 'Da ', 'Ze ', 'Tian ', 'Tai ', 'Fu ', 'Guai ', 'Yao ', 'Yang ', 'Hang ',
+'Gao ', 'Shi ', 'Ben ', 'Tai ', 'Tou ', 'Yan ', 'Bi ', 'Yi ', 'Kua ', 'Jia ', 'Duo ', 'Kwu ', 'Kuang ', 'Yun ', 'Jia ', 'Pa ',
+'En ', 'Lian ', 'Huan ', 'Di ', 'Yan ', 'Pao ', 'Quan ', 'Qi ', 'Nai ', 'Feng ', 'Xie ', 'Fen ', 'Dian ', '[?]', 'Kui ', 'Zou ',
+'Huan ', 'Qi ', 'Kai ', 'Zha ', 'Ben ', 'Yi ', 'Jiang ', 'Tao ', 'Zang ', 'Ben ', 'Xi ', 'Xiang ', 'Fei ', 'Diao ', 'Xun ', 'Keng ',
+'Dian ', 'Ao ', 'She ', 'Weng ', 'Pan ', 'Ao ', 'Wu ', 'Ao ', 'Jiang ', 'Lian ', 'Duo ', 'Yun ', 'Jiang ', 'Shi ', 'Fen ', 'Huo ',
+'Bi ', 'Lian ', 'Duo ', 'Nu ', 'Nu ', 'Ding ', 'Nai ', 'Qian ', 'Jian ', 'Ta ', 'Jiu ', 'Nan ', 'Cha ', 'Hao ', 'Xian ', 'Fan ',
+'Ji ', 'Shuo ', 'Ru ', 'Fei ', 'Wang ', 'Hong ', 'Zhuang ', 'Fu ', 'Ma ', 'Dan ', 'Ren ', 'Fu ', 'Jing ', 'Yan ', 'Xie ', 'Wen ',
+'Zhong ', 'Pa ', 'Du ', 'Ji ', 'Keng ', 'Zhong ', 'Yao ', 'Jin ', 'Yun ', 'Miao ', 'Pei ', 'Shi ', 'Yue ', 'Zhuang ', 'Niu ', 'Yan ',
+'Na ', 'Xin ', 'Fen ', 'Bi ', 'Yu ', 'Tuo ', 'Feng ', 'Yuan ', 'Fang ', 'Wu ', 'Yu ', 'Gui ', 'Du ', 'Ba ', 'Ni ', 'Zhou ',
+'Zhuo ', 'Zhao ', 'Da ', 'Nai ', 'Yuan ', 'Tou ', 'Xuan ', 'Zhi ', 'E ', 'Mei ', 'Mo ', 'Qi ', 'Bi ', 'Shen ', 'Qie ', 'E ',
+'He ', 'Xu ', 'Fa ', 'Zheng ', 'Min ', 'Ban ', 'Mu ', 'Fu ', 'Ling ', 'Zi ', 'Zi ', 'Shi ', 'Ran ', 'Shan ', 'Yang ', 'Man ',
+'Jie ', 'Gu ', 'Si ', 'Xing ', 'Wei ', 'Zi ', 'Ju ', 'Shan ', 'Pin ', 'Ren ', 'Yao ', 'Tong ', 'Jiang ', 'Shu ', 'Ji ', 'Gai ',
+'Shang ', 'Kuo ', 'Juan ', 'Jiao ', 'Gou ', 'Mu ', 'Jian ', 'Jian ', 'Yi ', 'Nian ', 'Zhi ', 'Ji ', 'Ji ', 'Xian ', 'Heng ', 'Guang ',
+'Jun ', 'Kua ', 'Yan ', 'Ming ', 'Lie ', 'Pei ', 'Yan ', 'You ', 'Yan ', 'Cha ', 'Shen ', 'Yin ', 'Chi ', 'Gui ', 'Quan ', 'Zi ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x5a.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x5a.php
new file mode 100644 (file)
index 0000000..e338e23
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x5a] = array(
+'Song ', 'Wei ', 'Hong ', 'Wa ', 'Lou ', 'Ya ', 'Rao ', 'Jiao ', 'Luan ', 'Ping ', 'Xian ', 'Shao ', 'Li ', 'Cheng ', 'Xiao ', 'Mang ',
+'Fu ', 'Suo ', 'Wu ', 'Wei ', 'Ke ', 'Lai ', 'Chuo ', 'Ding ', 'Niang ', 'Xing ', 'Nan ', 'Yu ', 'Nuo ', 'Pei ', 'Nei ', 'Juan ',
+'Shen ', 'Zhi ', 'Han ', 'Di ', 'Zhuang ', 'E ', 'Pin ', 'Tui ', 'Han ', 'Mian ', 'Wu ', 'Yan ', 'Wu ', 'Xi ', 'Yan ', 'Yu ',
+'Si ', 'Yu ', 'Wa ', '[?]', 'Xian ', 'Ju ', 'Qu ', 'Shui ', 'Qi ', 'Xian ', 'Zhui ', 'Dong ', 'Chang ', 'Lu ', 'Ai ', 'E ',
+'E ', 'Lou ', 'Mian ', 'Cong ', 'Pou ', 'Ju ', 'Po ', 'Cai ', 'Ding ', 'Wan ', 'Biao ', 'Xiao ', 'Shu ', 'Qi ', 'Hui ', 'Fu ',
+'E ', 'Wo ', 'Tan ', 'Fei ', 'Wei ', 'Jie ', 'Tian ', 'Ni ', 'Quan ', 'Jing ', 'Hun ', 'Jing ', 'Qian ', 'Dian ', 'Xing ', 'Hu ',
+'Wa ', 'Lai ', 'Bi ', 'Yin ', 'Chou ', 'Chuo ', 'Fu ', 'Jing ', 'Lun ', 'Yan ', 'Lan ', 'Kun ', 'Yin ', 'Ya ', 'Ju ', 'Li ',
+'Dian ', 'Xian ', 'Hwa ', 'Hua ', 'Ying ', 'Chan ', 'Shen ', 'Ting ', 'Dang ', 'Yao ', 'Wu ', 'Nan ', 'Ruo ', 'Jia ', 'Tou ', 'Xu ',
+'Yu ', 'Wei ', 'Ti ', 'Rou ', 'Mei ', 'Dan ', 'Ruan ', 'Qin ', 'Hui ', 'Wu ', 'Qian ', 'Chun ', 'Mao ', 'Fu ', 'Jie ', 'Duan ',
+'Xi ', 'Zhong ', 'Mei ', 'Huang ', 'Mian ', 'An ', 'Ying ', 'Xuan ', 'Jie ', 'Wei ', 'Mei ', 'Yuan ', 'Zhen ', 'Qiu ', 'Ti ', 'Xie ',
+'Tuo ', 'Lian ', 'Mao ', 'Ran ', 'Si ', 'Pian ', 'Wei ', 'Wa ', 'Jiu ', 'Hu ', 'Ao ', '[?]', 'Bou ', 'Xu ', 'Tou ', 'Gui ',
+'Zou ', 'Yao ', 'Pi ', 'Xi ', 'Yuan ', 'Ying ', 'Rong ', 'Ru ', 'Chi ', 'Liu ', 'Mei ', 'Pan ', 'Ao ', 'Ma ', 'Gou ', 'Kui ',
+'Qin ', 'Jia ', 'Sao ', 'Zhen ', 'Yuan ', 'Cha ', 'Yong ', 'Ming ', 'Ying ', 'Ji ', 'Su ', 'Niao ', 'Xian ', 'Tao ', 'Pang ', 'Lang ',
+'Nao ', 'Bao ', 'Ai ', 'Pi ', 'Pin ', 'Yi ', 'Piao ', 'Yu ', 'Lei ', 'Xuan ', 'Man ', 'Yi ', 'Zhang ', 'Kang ', 'Yong ', 'Ni ',
+'Li ', 'Di ', 'Gui ', 'Yan ', 'Jin ', 'Zhuan ', 'Chang ', 'Ce ', 'Han ', 'Nen ', 'Lao ', 'Mo ', 'Zhe ', 'Hu ', 'Hu ', 'Ao ',
+'Nen ', 'Qiang ', 'Ma ', 'Pie ', 'Gu ', 'Wu ', 'Jiao ', 'Tuo ', 'Zhan ', 'Mao ', 'Xian ', 'Xian ', 'Mo ', 'Liao ', 'Lian ', 'Hua ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x5b.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x5b.php
new file mode 100644 (file)
index 0000000..0624099
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x5b] = array(
+'Gui ', 'Deng ', 'Zhi ', 'Xu ', 'Yi ', 'Hua ', 'Xi ', 'Hui ', 'Rao ', 'Xi ', 'Yan ', 'Chan ', 'Jiao ', 'Mei ', 'Fan ', 'Fan ',
+'Xian ', 'Yi ', 'Wei ', 'Jiao ', 'Fu ', 'Shi ', 'Bi ', 'Shan ', 'Sui ', 'Qiang ', 'Lian ', 'Huan ', 'Xin ', 'Niao ', 'Dong ', 'Yi ',
+'Can ', 'Ai ', 'Niang ', 'Neng ', 'Ma ', 'Tiao ', 'Chou ', 'Jin ', 'Ci ', 'Yu ', 'Pin ', 'Yong ', 'Xu ', 'Nai ', 'Yan ', 'Tai ',
+'Ying ', 'Can ', 'Niao ', 'Wo ', 'Ying ', 'Mian ', 'Kaka ', 'Ma ', 'Shen ', 'Xing ', 'Ni ', 'Du ', 'Liu ', 'Yuan ', 'Lan ', 'Yan ',
+'Shuang ', 'Ling ', 'Jiao ', 'Niang ', 'Lan ', 'Xian ', 'Ying ', 'Shuang ', 'Shuai ', 'Quan ', 'Mi ', 'Li ', 'Luan ', 'Yan ', 'Zhu ', 'Lan ',
+'Zi ', 'Jie ', 'Jue ', 'Jue ', 'Kong ', 'Yun ', 'Zi ', 'Zi ', 'Cun ', 'Sun ', 'Fu ', 'Bei ', 'Zi ', 'Xiao ', 'Xin ', 'Meng ',
+'Si ', 'Tai ', 'Bao ', 'Ji ', 'Gu ', 'Nu ', 'Xue ', '[?]', 'Zhuan ', 'Hai ', 'Luan ', 'Sun ', 'Huai ', 'Mie ', 'Cong ', 'Qian ',
+'Shu ', 'Chan ', 'Ya ', 'Zi ', 'Ni ', 'Fu ', 'Zi ', 'Li ', 'Xue ', 'Bo ', 'Ru ', 'Lai ', 'Nie ', 'Nie ', 'Ying ', 'Luan ',
+'Mian ', 'Zhu ', 'Rong ', 'Ta ', 'Gui ', 'Zhai ', 'Qiong ', 'Yu ', 'Shou ', 'An ', 'Tu ', 'Song ', 'Wan ', 'Rou ', 'Yao ', 'Hong ',
+'Yi ', 'Jing ', 'Zhun ', 'Mi ', 'Zhu ', 'Dang ', 'Hong ', 'Zong ', 'Guan ', 'Zhou ', 'Ding ', 'Wan ', 'Yi ', 'Bao ', 'Shi ', 'Shi ',
+'Chong ', 'Shen ', 'Ke ', 'Xuan ', 'Shi ', 'You ', 'Huan ', 'Yi ', 'Tiao ', 'Shi ', 'Xian ', 'Gong ', 'Cheng ', 'Qun ', 'Gong ', 'Xiao ',
+'Zai ', 'Zha ', 'Bao ', 'Hai ', 'Yan ', 'Xiao ', 'Jia ', 'Shen ', 'Chen ', 'Rong ', 'Huang ', 'Mi ', 'Kou ', 'Kuan ', 'Bin ', 'Su ',
+'Cai ', 'Zan ', 'Ji ', 'Yuan ', 'Ji ', 'Yin ', 'Mi ', 'Kou ', 'Qing ', 'Que ', 'Zhen ', 'Jian ', 'Fu ', 'Ning ', 'Bing ', 'Huan ',
+'Mei ', 'Qin ', 'Han ', 'Yu ', 'Shi ', 'Ning ', 'Qin ', 'Ning ', 'Zhi ', 'Yu ', 'Bao ', 'Kuan ', 'Ning ', 'Qin ', 'Mo ', 'Cha ',
+'Ju ', 'Gua ', 'Qin ', 'Hu ', 'Wu ', 'Liao ', 'Shi ', 'Zhu ', 'Zhai ', 'Shen ', 'Wei ', 'Xie ', 'Kuan ', 'Hui ', 'Liao ', 'Jun ',
+'Huan ', 'Yi ', 'Yi ', 'Bao ', 'Qin ', 'Chong ', 'Bao ', 'Feng ', 'Cun ', 'Dui ', 'Si ', 'Xun ', 'Dao ', 'Lu ', 'Dui ', 'Shou ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x5c.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x5c.php
new file mode 100644 (file)
index 0000000..24bc364
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x5c] = array(
+'Po ', 'Feng ', 'Zhuan ', 'Fu ', 'She ', 'Ke ', 'Jiang ', 'Jiang ', 'Zhuan ', 'Wei ', 'Zun ', 'Xun ', 'Shu ', 'Dui ', 'Dao ', 'Xiao ',
+'Ji ', 'Shao ', 'Er ', 'Er ', 'Er ', 'Ga ', 'Jian ', 'Shu ', 'Chen ', 'Shang ', 'Shang ', 'Mo ', 'Ga ', 'Chang ', 'Liao ', 'Xian ',
+'Xian ', '[?]', 'Wang ', 'Wang ', 'You ', 'Liao ', 'Liao ', 'Yao ', 'Mang ', 'Wang ', 'Wang ', 'Wang ', 'Ga ', 'Yao ', 'Duo ', 'Kui ',
+'Zhong ', 'Jiu ', 'Gan ', 'Gu ', 'Gan ', 'Tui ', 'Gan ', 'Gan ', 'Shi ', 'Yin ', 'Chi ', 'Kao ', 'Ni ', 'Jin ', 'Wei ', 'Niao ',
+'Ju ', 'Pi ', 'Ceng ', 'Xi ', 'Bi ', 'Ju ', 'Jie ', 'Tian ', 'Qu ', 'Ti ', 'Jie ', 'Wu ', 'Diao ', 'Shi ', 'Shi ', 'Ping ',
+'Ji ', 'Xie ', 'Chen ', 'Xi ', 'Ni ', 'Zhan ', 'Xi ', '[?]', 'Man ', 'E ', 'Lou ', 'Ping ', 'Ti ', 'Fei ', 'Shu ', 'Xie ',
+'Tu ', 'Lu ', 'Lu ', 'Xi ', 'Ceng ', 'Lu ', 'Ju ', 'Xie ', 'Ju ', 'Jue ', 'Liao ', 'Jue ', 'Shu ', 'Xi ', 'Che ', 'Tun ',
+'Ni ', 'Shan ', '[?]', 'Xian ', 'Li ', 'Xue ', 'Nata ', '[?]', 'Long ', 'Yi ', 'Qi ', 'Ren ', 'Wu ', 'Han ', 'Shen ', 'Yu ',
+'Chu ', 'Sui ', 'Qi ', '[?]', 'Yue ', 'Ban ', 'Yao ', 'Ang ', 'Ya ', 'Wu ', 'Jie ', 'E ', 'Ji ', 'Qian ', 'Fen ', 'Yuan ',
+'Qi ', 'Cen ', 'Qian ', 'Qi ', 'Cha ', 'Jie ', 'Qu ', 'Gang ', 'Xian ', 'Ao ', 'Lan ', 'Dao ', 'Ba ', 'Zuo ', 'Zuo ', 'Yang ',
+'Ju ', 'Gang ', 'Ke ', 'Gou ', 'Xue ', 'Bei ', 'Li ', 'Tiao ', 'Ju ', 'Yan ', 'Fu ', 'Xiu ', 'Jia ', 'Ling ', 'Tuo ', 'Pei ',
+'You ', 'Dai ', 'Kuang ', 'Yue ', 'Qu ', 'Hu ', 'Po ', 'Min ', 'An ', 'Tiao ', 'Ling ', 'Chi ', 'Yuri ', 'Dong ', 'Cem ', 'Kui ',
+'Xiu ', 'Mao ', 'Tong ', 'Xue ', 'Yi ', 'Kura ', 'He ', 'Ke ', 'Luo ', 'E ', 'Fu ', 'Xun ', 'Die ', 'Lu ', 'An ', 'Er ',
+'Gai ', 'Quan ', 'Tong ', 'Yi ', 'Mu ', 'Shi ', 'An ', 'Wei ', 'Hu ', 'Zhi ', 'Mi ', 'Li ', 'Ji ', 'Tong ', 'Wei ', 'You ',
+'Sang ', 'Xia ', 'Li ', 'Yao ', 'Jiao ', 'Zheng ', 'Luan ', 'Jiao ', 'E ', 'E ', 'Yu ', 'Ye ', 'Bu ', 'Qiao ', 'Qun ', 'Feng ',
+'Feng ', 'Nao ', 'Li ', 'You ', 'Xian ', 'Hong ', 'Dao ', 'Shen ', 'Cheng ', 'Tu ', 'Geng ', 'Jun ', 'Hao ', 'Xia ', 'Yin ', 'Yu ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x5d.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x5d.php
new file mode 100644 (file)
index 0000000..0bc8828
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x5d] = array(
+'Lang ', 'Kan ', 'Lao ', 'Lai ', 'Xian ', 'Que ', 'Kong ', 'Chong ', 'Chong ', 'Ta ', 'Lin ', 'Hua ', 'Ju ', 'Lai ', 'Qi ', 'Min ',
+'Kun ', 'Kun ', 'Zu ', 'Gu ', 'Cui ', 'Ya ', 'Ya ', 'Gang ', 'Lun ', 'Lun ', 'Leng ', 'Jue ', 'Duo ', 'Zheng ', 'Guo ', 'Yin ',
+'Dong ', 'Han ', 'Zheng ', 'Wei ', 'Yao ', 'Pi ', 'Yan ', 'Song ', 'Jie ', 'Beng ', 'Zu ', 'Jue ', 'Dong ', 'Zhan ', 'Gu ', 'Yin ',
+'[?]', 'Ze ', 'Huang ', 'Yu ', 'Wei ', 'Yang ', 'Feng ', 'Qiu ', 'Dun ', 'Ti ', 'Yi ', 'Zhi ', 'Shi ', 'Zai ', 'Yao ', 'E ',
+'Zhu ', 'Kan ', 'Lu ', 'Yan ', 'Mei ', 'Gan ', 'Ji ', 'Ji ', 'Huan ', 'Ting ', 'Sheng ', 'Mei ', 'Qian ', 'Wu ', 'Yu ', 'Zong ',
+'Lan ', 'Jue ', 'Yan ', 'Yan ', 'Wei ', 'Zong ', 'Cha ', 'Sui ', 'Rong ', 'Yamashina ', 'Qin ', 'Yu ', 'Kewashii ', 'Lou ', 'Tu ', 'Dui ',
+'Xi ', 'Weng ', 'Cang ', 'Dang ', 'Hong ', 'Jie ', 'Ai ', 'Liu ', 'Wu ', 'Song ', 'Qiao ', 'Zi ', 'Wei ', 'Beng ', 'Dian ', 'Cuo ',
+'Qian ', 'Yong ', 'Nie ', 'Cuo ', 'Ji ', '[?]', 'Tao ', 'Song ', 'Zong ', 'Jiang ', 'Liao ', 'Kang ', 'Chan ', 'Die ', 'Cen ', 'Ding ',
+'Tu ', 'Lou ', 'Zhang ', 'Zhan ', 'Zhan ', 'Ao ', 'Cao ', 'Qu ', 'Qiang ', 'Zui ', 'Zui ', 'Dao ', 'Dao ', 'Xi ', 'Yu ', 'Bo ',
+'Long ', 'Xiang ', 'Ceng ', 'Bo ', 'Qin ', 'Jiao ', 'Yan ', 'Lao ', 'Zhan ', 'Lin ', 'Liao ', 'Liao ', 'Jin ', 'Deng ', 'Duo ', 'Zun ',
+'Jiao ', 'Gui ', 'Yao ', 'Qiao ', 'Yao ', 'Jue ', 'Zhan ', 'Yi ', 'Xue ', 'Nao ', 'Ye ', 'Ye ', 'Yi ', 'E ', 'Xian ', 'Ji ',
+'Xie ', 'Ke ', 'Xi ', 'Di ', 'Ao ', 'Zui ', '[?]', 'Ni ', 'Rong ', 'Dao ', 'Ling ', 'Za ', 'Yu ', 'Yue ', 'Yin ', '[?]',
+'Jie ', 'Li ', 'Sui ', 'Long ', 'Long ', 'Dian ', 'Ying ', 'Xi ', 'Ju ', 'Chan ', 'Ying ', 'Kui ', 'Yan ', 'Wei ', 'Nao ', 'Quan ',
+'Chao ', 'Cuan ', 'Luan ', 'Dian ', 'Dian ', '[?]', 'Yan ', 'Yan ', 'Yan ', 'Nao ', 'Yan ', 'Chuan ', 'Gui ', 'Chuan ', 'Zhou ', 'Huang ',
+'Jing ', 'Xun ', 'Chao ', 'Chao ', 'Lie ', 'Gong ', 'Zuo ', 'Qiao ', 'Ju ', 'Gong ', 'Kek ', 'Wu ', 'Pwu ', 'Pwu ', 'Chai ', 'Qiu ',
+'Qiu ', 'Ji ', 'Yi ', 'Si ', 'Ba ', 'Zhi ', 'Zhao ', 'Xiang ', 'Yi ', 'Jin ', 'Xun ', 'Juan ', 'Phas ', 'Xun ', 'Jin ', 'Fu ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x5e.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x5e.php
new file mode 100644 (file)
index 0000000..cb925c7
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x5e] = array(
+'Za ', 'Bi ', 'Shi ', 'Bu ', 'Ding ', 'Shuai ', 'Fan ', 'Nie ', 'Shi ', 'Fen ', 'Pa ', 'Zhi ', 'Xi ', 'Hu ', 'Dan ', 'Wei ',
+'Zhang ', 'Tang ', 'Dai ', 'Ma ', 'Pei ', 'Pa ', 'Tie ', 'Fu ', 'Lian ', 'Zhi ', 'Zhou ', 'Bo ', 'Zhi ', 'Di ', 'Mo ', 'Yi ',
+'Yi ', 'Ping ', 'Qia ', 'Juan ', 'Ru ', 'Shuai ', 'Dai ', 'Zheng ', 'Shui ', 'Qiao ', 'Zhen ', 'Shi ', 'Qun ', 'Xi ', 'Bang ', 'Dai ',
+'Gui ', 'Chou ', 'Ping ', 'Zhang ', 'Sha ', 'Wan ', 'Dai ', 'Wei ', 'Chang ', 'Sha ', 'Qi ', 'Ze ', 'Guo ', 'Mao ', 'Du ', 'Hou ',
+'Zheng ', 'Xu ', 'Mi ', 'Wei ', 'Wo ', 'Fu ', 'Yi ', 'Bang ', 'Ping ', 'Tazuna ', 'Gong ', 'Pan ', 'Huang ', 'Dao ', 'Mi ', 'Jia ',
+'Teng ', 'Hui ', 'Zhong ', 'Shan ', 'Man ', 'Mu ', 'Biao ', 'Guo ', 'Ze ', 'Mu ', 'Bang ', 'Zhang ', 'Jiong ', 'Chan ', 'Fu ', 'Zhi ',
+'Hu ', 'Fan ', 'Chuang ', 'Bi ', 'Hei ', '[?]', 'Mi ', 'Qiao ', 'Chan ', 'Fen ', 'Meng ', 'Bang ', 'Chou ', 'Mie ', 'Chu ', 'Jie ',
+'Xian ', 'Lan ', 'Gan ', 'Ping ', 'Nian ', 'Qian ', 'Bing ', 'Bing ', 'Xing ', 'Gan ', 'Yao ', 'Huan ', 'You ', 'You ', 'Ji ', 'Yan ',
+'Pi ', 'Ting ', 'Ze ', 'Guang ', 'Zhuang ', 'Mo ', 'Qing ', 'Bi ', 'Qin ', 'Dun ', 'Chuang ', 'Gui ', 'Ya ', 'Bai ', 'Jie ', 'Xu ',
+'Lu ', 'Wu ', '[?]', 'Ku ', 'Ying ', 'Di ', 'Pao ', 'Dian ', 'Ya ', 'Miao ', 'Geng ', 'Ci ', 'Fu ', 'Tong ', 'Pang ', 'Fei ',
+'Xiang ', 'Yi ', 'Zhi ', 'Tiao ', 'Zhi ', 'Xiu ', 'Du ', 'Zuo ', 'Xiao ', 'Tu ', 'Gui ', 'Ku ', 'Pang ', 'Ting ', 'You ', 'Bu ',
+'Ding ', 'Cheng ', 'Lai ', 'Bei ', 'Ji ', 'An ', 'Shu ', 'Kang ', 'Yong ', 'Tuo ', 'Song ', 'Shu ', 'Qing ', 'Yu ', 'Yu ', 'Miao ',
+'Sou ', 'Ce ', 'Xiang ', 'Fei ', 'Jiu ', 'He ', 'Hui ', 'Liu ', 'Sha ', 'Lian ', 'Lang ', 'Sou ', 'Jian ', 'Pou ', 'Qing ', 'Jiu ',
+'Jiu ', 'Qin ', 'Ao ', 'Kuo ', 'Lou ', 'Yin ', 'Liao ', 'Dai ', 'Lu ', 'Yi ', 'Chu ', 'Chan ', 'Tu ', 'Si ', 'Xin ', 'Miao ',
+'Chang ', 'Wu ', 'Fei ', 'Guang ', 'Koc ', 'Kuai ', 'Bi ', 'Qiang ', 'Xie ', 'Lin ', 'Lin ', 'Liao ', 'Lu ', '[?]', 'Ying ', 'Xian ',
+'Ting ', 'Yong ', 'Li ', 'Ting ', 'Yin ', 'Xun ', 'Yan ', 'Ting ', 'Di ', 'Po ', 'Jian ', 'Hui ', 'Nai ', 'Hui ', 'Gong ', 'Nian ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x5f.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x5f.php
new file mode 100644 (file)
index 0000000..47233f8
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x5f] = array(
+'Kai ', 'Bian ', 'Yi ', 'Qi ', 'Nong ', 'Fen ', 'Ju ', 'Yan ', 'Yi ', 'Zang ', 'Bi ', 'Yi ', 'Yi ', 'Er ', 'San ', 'Shi ',
+'Er ', 'Shi ', 'Shi ', 'Gong ', 'Diao ', 'Yin ', 'Hu ', 'Fu ', 'Hong ', 'Wu ', 'Tui ', 'Chi ', 'Jiang ', 'Ba ', 'Shen ', 'Di ',
+'Zhang ', 'Jue ', 'Tao ', 'Fu ', 'Di ', 'Mi ', 'Xian ', 'Hu ', 'Chao ', 'Nu ', 'Jing ', 'Zhen ', 'Yi ', 'Mi ', 'Quan ', 'Wan ',
+'Shao ', 'Ruo ', 'Xuan ', 'Jing ', 'Dun ', 'Zhang ', 'Jiang ', 'Qiang ', 'Peng ', 'Dan ', 'Qiang ', 'Bi ', 'Bi ', 'She ', 'Dan ', 'Jian ',
+'Gou ', 'Sei ', 'Fa ', 'Bi ', 'Kou ', 'Nagi ', 'Bie ', 'Xiao ', 'Dan ', 'Kuo ', 'Qiang ', 'Hong ', 'Mi ', 'Kuo ', 'Wan ', 'Jue ',
+'Ji ', 'Ji ', 'Gui ', 'Dang ', 'Lu ', 'Lu ', 'Tuan ', 'Hui ', 'Zhi ', 'Hui ', 'Hui ', 'Yi ', 'Yi ', 'Yi ', 'Yi ', 'Huo ',
+'Huo ', 'Shan ', 'Xing ', 'Wen ', 'Tong ', 'Yan ', 'Yan ', 'Yu ', 'Chi ', 'Cai ', 'Biao ', 'Diao ', 'Bin ', 'Peng ', 'Yong ', 'Piao ',
+'Zhang ', 'Ying ', 'Chi ', 'Chi ', 'Zhuo ', 'Tuo ', 'Ji ', 'Pang ', 'Zhong ', 'Yi ', 'Wang ', 'Che ', 'Bi ', 'Chi ', 'Ling ', 'Fu ',
+'Wang ', 'Zheng ', 'Cu ', 'Wang ', 'Jing ', 'Dai ', 'Xi ', 'Xun ', 'Hen ', 'Yang ', 'Huai ', 'Lu ', 'Hou ', 'Wa ', 'Cheng ', 'Zhi ',
+'Xu ', 'Jing ', 'Tu ', 'Cong ', '[?]', 'Lai ', 'Cong ', 'De ', 'Pai ', 'Xi ', '[?]', 'Qi ', 'Chang ', 'Zhi ', 'Cong ', 'Zhou ',
+'Lai ', 'Yu ', 'Xie ', 'Jie ', 'Jian ', 'Chi ', 'Jia ', 'Bian ', 'Huang ', 'Fu ', 'Xun ', 'Wei ', 'Pang ', 'Yao ', 'Wei ', 'Xi ',
+'Zheng ', 'Piao ', 'Chi ', 'De ', 'Zheng ', 'Zheng ', 'Bie ', 'De ', 'Chong ', 'Che ', 'Jiao ', 'Wei ', 'Jiao ', 'Hui ', 'Mei ', 'Long ',
+'Xiang ', 'Bao ', 'Qu ', 'Xin ', 'Shu ', 'Bi ', 'Yi ', 'Le ', 'Ren ', 'Dao ', 'Ding ', 'Gai ', 'Ji ', 'Ren ', 'Ren ', 'Chan ',
+'Tan ', 'Te ', 'Te ', 'Gan ', 'Qi ', 'Shi ', 'Cun ', 'Zhi ', 'Wang ', 'Mang ', 'Xi ', 'Fan ', 'Ying ', 'Tian ', 'Min ', 'Min ',
+'Zhong ', 'Chong ', 'Wu ', 'Ji ', 'Wu ', 'Xi ', 'Ye ', 'You ', 'Wan ', 'Cong ', 'Zhong ', 'Kuai ', 'Yu ', 'Bian ', 'Zhi ', 'Qi ',
+'Cui ', 'Chen ', 'Tai ', 'Tun ', 'Qian ', 'Nian ', 'Hun ', 'Xiong ', 'Niu ', 'Wang ', 'Xian ', 'Xin ', 'Kang ', 'Hu ', 'Kai ', 'Fen ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x60.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x60.php
new file mode 100644 (file)
index 0000000..8c70316
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x60] = array(
+'Huai ', 'Tai ', 'Song ', 'Wu ', 'Ou ', 'Chang ', 'Chuang ', 'Ju ', 'Yi ', 'Bao ', 'Chao ', 'Min ', 'Pei ', 'Zuo ', 'Zen ', 'Yang ',
+'Kou ', 'Ban ', 'Nu ', 'Nao ', 'Zheng ', 'Pa ', 'Bu ', 'Tie ', 'Gu ', 'Hu ', 'Ju ', 'Da ', 'Lian ', 'Si ', 'Chou ', 'Di ',
+'Dai ', 'Yi ', 'Tu ', 'You ', 'Fu ', 'Ji ', 'Peng ', 'Xing ', 'Yuan ', 'Ni ', 'Guai ', 'Fu ', 'Xi ', 'Bi ', 'You ', 'Qie ',
+'Xuan ', 'Cong ', 'Bing ', 'Huang ', 'Xu ', 'Chu ', 'Pi ', 'Xi ', 'Xi ', 'Tan ', 'Koraeru ', 'Zong ', 'Dui ', '[?]', 'Ki ', 'Yi ',
+'Chi ', 'Ren ', 'Xun ', 'Shi ', 'Xi ', 'Lao ', 'Heng ', 'Kuang ', 'Mu ', 'Zhi ', 'Xie ', 'Lian ', 'Tiao ', 'Huang ', 'Die ', 'Hao ',
+'Kong ', 'Gui ', 'Heng ', 'Xi ', 'Xiao ', 'Shu ', 'S ', 'Kua ', 'Qiu ', 'Yang ', 'Hui ', 'Hui ', 'Chi ', 'Jia ', 'Yi ', 'Xiong ',
+'Guai ', 'Lin ', 'Hui ', 'Zi ', 'Xu ', 'Chi ', 'Xiang ', 'Nu ', 'Hen ', 'En ', 'Ke ', 'Tong ', 'Tian ', 'Gong ', 'Quan ', 'Xi ',
+'Qia ', 'Yue ', 'Peng ', 'Ken ', 'De ', 'Hui ', 'E ', 'Kyuu ', 'Tong ', 'Yan ', 'Kai ', 'Ce ', 'Nao ', 'Yun ', 'Mang ', 'Yong ',
+'Yong ', 'Yuan ', 'Pi ', 'Kun ', 'Qiao ', 'Yue ', 'Yu ', 'Yu ', 'Jie ', 'Xi ', 'Zhe ', 'Lin ', 'Ti ', 'Han ', 'Hao ', 'Qie ',
+'Ti ', 'Bu ', 'Yi ', 'Qian ', 'Hui ', 'Xi ', 'Bei ', 'Man ', 'Yi ', 'Heng ', 'Song ', 'Quan ', 'Cheng ', 'Hui ', 'Wu ', 'Wu ',
+'You ', 'Li ', 'Liang ', 'Huan ', 'Cong ', 'Yi ', 'Yue ', 'Li ', 'Nin ', 'Nao ', 'E ', 'Que ', 'Xuan ', 'Qian ', 'Wu ', 'Min ',
+'Cong ', 'Fei ', 'Bei ', 'Duo ', 'Cui ', 'Chang ', 'Men ', 'Li ', 'Ji ', 'Guan ', 'Guan ', 'Xing ', 'Dao ', 'Qi ', 'Kong ', 'Tian ',
+'Lun ', 'Xi ', 'Kan ', 'Kun ', 'Ni ', 'Qing ', 'Chou ', 'Dun ', 'Guo ', 'Chan ', 'Liang ', 'Wan ', 'Yuan ', 'Jin ', 'Ji ', 'Lin ',
+'Yu ', 'Huo ', 'He ', 'Quan ', 'Tan ', 'Ti ', 'Ti ', 'Nie ', 'Wang ', 'Chuo ', 'Bu ', 'Hun ', 'Xi ', 'Tang ', 'Xin ', 'Wei ',
+'Hui ', 'E ', 'Rui ', 'Zong ', 'Jian ', 'Yong ', 'Dian ', 'Ju ', 'Can ', 'Cheng ', 'De ', 'Bei ', 'Qie ', 'Can ', 'Dan ', 'Guan ',
+'Duo ', 'Nao ', 'Yun ', 'Xiang ', 'Zhui ', 'Die ', 'Huang ', 'Chun ', 'Qiong ', 'Re ', 'Xing ', 'Ce ', 'Bian ', 'Hun ', 'Zong ', 'Ti ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x61.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x61.php
new file mode 100644 (file)
index 0000000..117becf
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x61] = array(
+'Qiao ', 'Chou ', 'Bei ', 'Xuan ', 'Wei ', 'Ge ', 'Qian ', 'Wei ', 'Yu ', 'Yu ', 'Bi ', 'Xuan ', 'Huan ', 'Min ', 'Bi ', 'Yi ',
+'Mian ', 'Yong ', 'Kai ', 'Dang ', 'Yin ', 'E ', 'Chen ', 'Mou ', 'Ke ', 'Ke ', 'Yu ', 'Ai ', 'Qie ', 'Yan ', 'Nuo ', 'Gan ',
+'Yun ', 'Zong ', 'Sai ', 'Leng ', 'Fen ', '[?]', 'Kui ', 'Kui ', 'Que ', 'Gong ', 'Yun ', 'Su ', 'Su ', 'Qi ', 'Yao ', 'Song ',
+'Huang ', 'Ji ', 'Gu ', 'Ju ', 'Chuang ', 'Ni ', 'Xie ', 'Kai ', 'Zheng ', 'Yong ', 'Cao ', 'Sun ', 'Shen ', 'Bo ', 'Kai ', 'Yuan ',
+'Xie ', 'Hun ', 'Yong ', 'Yang ', 'Li ', 'Sao ', 'Tao ', 'Yin ', 'Ci ', 'Xu ', 'Qian ', 'Tai ', 'Huang ', 'Yun ', 'Shen ', 'Ming ',
+'[?]', 'She ', 'Cong ', 'Piao ', 'Mo ', 'Mu ', 'Guo ', 'Chi ', 'Can ', 'Can ', 'Can ', 'Cui ', 'Min ', 'Te ', 'Zhang ', 'Tong ',
+'Ao ', 'Shuang ', 'Man ', 'Guan ', 'Que ', 'Zao ', 'Jiu ', 'Hui ', 'Kai ', 'Lian ', 'Ou ', 'Song ', 'Jin ', 'Yin ', 'Lu ', 'Shang ',
+'Wei ', 'Tuan ', 'Man ', 'Qian ', 'She ', 'Yong ', 'Qing ', 'Kang ', 'Di ', 'Zhi ', 'Lou ', 'Juan ', 'Qi ', 'Qi ', 'Yu ', 'Ping ',
+'Liao ', 'Cong ', 'You ', 'Chong ', 'Zhi ', 'Tong ', 'Cheng ', 'Qi ', 'Qu ', 'Peng ', 'Bei ', 'Bie ', 'Chun ', 'Jiao ', 'Zeng ', 'Chi ',
+'Lian ', 'Ping ', 'Kui ', 'Hui ', 'Qiao ', 'Cheng ', 'Yin ', 'Yin ', 'Xi ', 'Xi ', 'Dan ', 'Tan ', 'Duo ', 'Dui ', 'Dui ', 'Su ',
+'Jue ', 'Ce ', 'Xiao ', 'Fan ', 'Fen ', 'Lao ', 'Lao ', 'Chong ', 'Han ', 'Qi ', 'Xian ', 'Min ', 'Jing ', 'Liao ', 'Wu ', 'Can ',
+'Jue ', 'Cu ', 'Xian ', 'Tan ', 'Sheng ', 'Pi ', 'Yi ', 'Chu ', 'Xian ', 'Nao ', 'Dan ', 'Tan ', 'Jing ', 'Song ', 'Han ', 'Jiao ',
+'Wai ', 'Huan ', 'Dong ', 'Qin ', 'Qin ', 'Qu ', 'Cao ', 'Ken ', 'Xie ', 'Ying ', 'Ao ', 'Mao ', 'Yi ', 'Lin ', 'Se ', 'Jun ',
+'Huai ', 'Men ', 'Lan ', 'Ai ', 'Lin ', 'Yan ', 'Gua ', 'Xia ', 'Chi ', 'Yu ', 'Yin ', 'Dai ', 'Meng ', 'Ai ', 'Meng ', 'Dui ',
+'Qi ', 'Mo ', 'Lan ', 'Men ', 'Chou ', 'Zhi ', 'Nuo ', 'Nuo ', 'Yan ', 'Yang ', 'Bo ', 'Zhi ', 'Kuang ', 'Kuang ', 'You ', 'Fu ',
+'Liu ', 'Mie ', 'Cheng ', '[?]', 'Chan ', 'Meng ', 'Lan ', 'Huai ', 'Xuan ', 'Rang ', 'Chan ', 'Ji ', 'Ju ', 'Huan ', 'She ', 'Yi ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x62.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x62.php
new file mode 100644 (file)
index 0000000..491cf96
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x62] = array(
+'Lian ', 'Nan ', 'Mi ', 'Tang ', 'Jue ', 'Gang ', 'Gang ', 'Gang ', 'Ge ', 'Yue ', 'Wu ', 'Jian ', 'Xu ', 'Shu ', 'Rong ', 'Xi ',
+'Cheng ', 'Wo ', 'Jie ', 'Ge ', 'Jian ', 'Qiang ', 'Huo ', 'Qiang ', 'Zhan ', 'Dong ', 'Qi ', 'Jia ', 'Die ', 'Zei ', 'Jia ', 'Ji ',
+'Shi ', 'Kan ', 'Ji ', 'Kui ', 'Gai ', 'Deng ', 'Zhan ', 'Chuang ', 'Ge ', 'Jian ', 'Jie ', 'Yu ', 'Jian ', 'Yan ', 'Lu ', 'Xi ',
+'Zhan ', 'Xi ', 'Xi ', 'Chuo ', 'Dai ', 'Qu ', 'Hu ', 'Hu ', 'Hu ', 'E ', 'Shi ', 'Li ', 'Mao ', 'Hu ', 'Li ', 'Fang ',
+'Suo ', 'Bian ', 'Dian ', 'Jiong ', 'Shang ', 'Yi ', 'Yi ', 'Shan ', 'Hu ', 'Fei ', 'Yan ', 'Shou ', 'T ', 'Cai ', 'Zha ', 'Qiu ',
+'Le ', 'Bu ', 'Ba ', 'Da ', 'Reng ', 'Fu ', 'Hameru ', 'Zai ', 'Tuo ', 'Zhang ', 'Diao ', 'Kang ', 'Yu ', 'Ku ', 'Han ', 'Shen ',
+'Cha ', 'Yi ', 'Gu ', 'Kou ', 'Wu ', 'Tuo ', 'Qian ', 'Zhi ', 'Ren ', 'Kuo ', 'Men ', 'Sao ', 'Yang ', 'Niu ', 'Ban ', 'Che ',
+'Rao ', 'Xi ', 'Qian ', 'Ban ', 'Jia ', 'Yu ', 'Fu ', 'Ao ', 'Xi ', 'Pi ', 'Zhi ', 'Zi ', 'E ', 'Dun ', 'Zhao ', 'Cheng ',
+'Ji ', 'Yan ', 'Kuang ', 'Bian ', 'Chao ', 'Ju ', 'Wen ', 'Hu ', 'Yue ', 'Jue ', 'Ba ', 'Qin ', 'Zhen ', 'Zheng ', 'Yun ', 'Wan ',
+'Nu ', 'Yi ', 'Shu ', 'Zhua ', 'Pou ', 'Tou ', 'Dou ', 'Kang ', 'Zhe ', 'Pou ', 'Fu ', 'Pao ', 'Ba ', 'Ao ', 'Ze ', 'Tuan ',
+'Kou ', 'Lun ', 'Qiang ', '[?]', 'Hu ', 'Bao ', 'Bing ', 'Zhi ', 'Peng ', 'Tan ', 'Pu ', 'Pi ', 'Tai ', 'Yao ', 'Zhen ', 'Zha ',
+'Yang ', 'Bao ', 'He ', 'Ni ', 'Yi ', 'Di ', 'Chi ', 'Pi ', 'Za ', 'Mo ', 'Mo ', 'Shen ', 'Ya ', 'Chou ', 'Qu ', 'Min ',
+'Chu ', 'Jia ', 'Fu ', 'Zhan ', 'Zhu ', 'Dan ', 'Chai ', 'Mu ', 'Nian ', 'La ', 'Fu ', 'Pao ', 'Ban ', 'Pai ', 'Ling ', 'Na ',
+'Guai ', 'Qian ', 'Ju ', 'Tuo ', 'Ba ', 'Tuo ', 'Tuo ', 'Ao ', 'Ju ', 'Zhuo ', 'Pan ', 'Zhao ', 'Bai ', 'Bai ', 'Di ', 'Ni ',
+'Ju ', 'Kuo ', 'Long ', 'Jian ', '[?]', 'Yong ', 'Lan ', 'Ning ', 'Bo ', 'Ze ', 'Qian ', 'Hen ', 'Gua ', 'Shi ', 'Jie ', 'Zheng ',
+'Nin ', 'Gong ', 'Gong ', 'Quan ', 'Shuan ', 'Cun ', 'Zan ', 'Kao ', 'Chi ', 'Xie ', 'Ce ', 'Hui ', 'Pin ', 'Zhuai ', 'Shi ', 'Na ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x63.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x63.php
new file mode 100644 (file)
index 0000000..8cc829f
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x63] = array(
+'Bo ', 'Chi ', 'Gua ', 'Zhi ', 'Kuo ', 'Duo ', 'Duo ', 'Zhi ', 'Qie ', 'An ', 'Nong ', 'Zhen ', 'Ge ', 'Jiao ', 'Ku ', 'Dong ',
+'Ru ', 'Tiao ', 'Lie ', 'Zha ', 'Lu ', 'Die ', 'Wa ', 'Jue ', 'Mushiru ', 'Ju ', 'Zhi ', 'Luan ', 'Ya ', 'Zhua ', 'Ta ', 'Xie ',
+'Nao ', 'Dang ', 'Jiao ', 'Zheng ', 'Ji ', 'Hui ', 'Xun ', 'Ku ', 'Ai ', 'Tuo ', 'Nuo ', 'Cuo ', 'Bo ', 'Geng ', 'Ti ', 'Zhen ',
+'Cheng ', 'Suo ', 'Suo ', 'Keng ', 'Mei ', 'Long ', 'Ju ', 'Peng ', 'Jian ', 'Yi ', 'Ting ', 'Shan ', 'Nuo ', 'Wan ', 'Xie ', 'Cha ',
+'Feng ', 'Jiao ', 'Wu ', 'Jun ', 'Jiu ', 'Tong ', 'Kun ', 'Huo ', 'Tu ', 'Zhuo ', 'Pou ', 'Le ', 'Ba ', 'Han ', 'Shao ', 'Nie ',
+'Juan ', 'Ze ', 'Song ', 'Ye ', 'Jue ', 'Bu ', 'Huan ', 'Bu ', 'Zun ', 'Yi ', 'Zhai ', 'Lu ', 'Sou ', 'Tuo ', 'Lao ', 'Sun ',
+'Bang ', 'Jian ', 'Huan ', 'Dao ', '[?]', 'Wan ', 'Qin ', 'Peng ', 'She ', 'Lie ', 'Min ', 'Men ', 'Fu ', 'Bai ', 'Ju ', 'Dao ',
+'Wo ', 'Ai ', 'Juan ', 'Yue ', 'Zong ', 'Chen ', 'Chui ', 'Jie ', 'Tu ', 'Ben ', 'Na ', 'Nian ', 'Nuo ', 'Zu ', 'Wo ', 'Xi ',
+'Xian ', 'Cheng ', 'Dian ', 'Sao ', 'Lun ', 'Qing ', 'Gang ', 'Duo ', 'Shou ', 'Diao ', 'Pou ', 'Di ', 'Zhang ', 'Gun ', 'Ji ', 'Tao ',
+'Qia ', 'Qi ', 'Pai ', 'Shu ', 'Qian ', 'Ling ', 'Yi ', 'Ya ', 'Jue ', 'Zheng ', 'Liang ', 'Gua ', 'Yi ', 'Huo ', 'Shan ', 'Zheng ',
+'Lue ', 'Cai ', 'Tan ', 'Che ', 'Bing ', 'Jie ', 'Ti ', 'Kong ', 'Tui ', 'Yan ', 'Cuo ', 'Zou ', 'Ju ', 'Tian ', 'Qian ', 'Ken ',
+'Bai ', 'Shou ', 'Jie ', 'Lu ', 'Guo ', 'Haba ', '[?]', 'Zhi ', 'Dan ', 'Mang ', 'Xian ', 'Sao ', 'Guan ', 'Peng ', 'Yuan ', 'Nuo ',
+'Jian ', 'Zhen ', 'Jiu ', 'Jian ', 'Yu ', 'Yan ', 'Kui ', 'Nan ', 'Hong ', 'Rou ', 'Pi ', 'Wei ', 'Sai ', 'Zou ', 'Xuan ', 'Miao ',
+'Ti ', 'Nie ', 'Cha ', 'Shi ', 'Zong ', 'Zhen ', 'Yi ', 'Shun ', 'Heng ', 'Bian ', 'Yang ', 'Huan ', 'Yan ', 'Zuan ', 'An ', 'Xu ',
+'Ya ', 'Wo ', 'Ke ', 'Chuai ', 'Ji ', 'Ti ', 'La ', 'La ', 'Cheng ', 'Kai ', 'Jiu ', 'Jiu ', 'Tu ', 'Jie ', 'Hui ', 'Geng ',
+'Chong ', 'Shuo ', 'She ', 'Xie ', 'Yuan ', 'Qian ', 'Ye ', 'Cha ', 'Zha ', 'Bei ', 'Yao ', '[?]', '[?]', 'Lan ', 'Wen ', 'Qin ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x64.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x64.php
new file mode 100644 (file)
index 0000000..00d8df9
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x64] = array(
+'Chan ', 'Ge ', 'Lou ', 'Zong ', 'Geng ', 'Jiao ', 'Gou ', 'Qin ', 'Yong ', 'Que ', 'Chou ', 'Chi ', 'Zhan ', 'Sun ', 'Sun ', 'Bo ',
+'Chu ', 'Rong ', 'Beng ', 'Cuo ', 'Sao ', 'Ke ', 'Yao ', 'Dao ', 'Zhi ', 'Nu ', 'Xie ', 'Jian ', 'Sou ', 'Qiu ', 'Gao ', 'Xian ',
+'Shuo ', 'Sang ', 'Jin ', 'Mie ', 'E ', 'Chui ', 'Nuo ', 'Shan ', 'Ta ', 'Jie ', 'Tang ', 'Pan ', 'Ban ', 'Da ', 'Li ', 'Tao ',
+'Hu ', 'Zhi ', 'Wa ', 'Xia ', 'Qian ', 'Wen ', 'Qiang ', 'Tian ', 'Zhen ', 'E ', 'Xi ', 'Nuo ', 'Quan ', 'Cha ', 'Zha ', 'Ge ',
+'Wu ', 'En ', 'She ', 'Kang ', 'She ', 'Shu ', 'Bai ', 'Yao ', 'Bin ', 'Sou ', 'Tan ', 'Sa ', 'Chan ', 'Suo ', 'Liao ', 'Chong ',
+'Chuang ', 'Guo ', 'Bing ', 'Feng ', 'Shuai ', 'Di ', 'Qi ', 'Sou ', 'Zhai ', 'Lian ', 'Tang ', 'Chi ', 'Guan ', 'Lu ', 'Luo ', 'Lou ',
+'Zong ', 'Gai ', 'Hu ', 'Zha ', 'Chuang ', 'Tang ', 'Hua ', 'Cui ', 'Nai ', 'Mo ', 'Jiang ', 'Gui ', 'Ying ', 'Zhi ', 'Ao ', 'Zhi ',
+'Nie ', 'Man ', 'Shan ', 'Kou ', 'Shu ', 'Suo ', 'Tuan ', 'Jiao ', 'Mo ', 'Mo ', 'Zhe ', 'Xian ', 'Keng ', 'Piao ', 'Jiang ', 'Yin ',
+'Gou ', 'Qian ', 'Lue ', 'Ji ', 'Ying ', 'Jue ', 'Pie ', 'Pie ', 'Lao ', 'Dun ', 'Xian ', 'Ruan ', 'Kui ', 'Zan ', 'Yi ', 'Xun ',
+'Cheng ', 'Cheng ', 'Sa ', 'Nao ', 'Heng ', 'Si ', 'Qian ', 'Huang ', 'Da ', 'Zun ', 'Nian ', 'Lin ', 'Zheng ', 'Hui ', 'Zhuang ', 'Jiao ',
+'Ji ', 'Cao ', 'Dan ', 'Dan ', 'Che ', 'Bo ', 'Che ', 'Jue ', 'Xiao ', 'Liao ', 'Ben ', 'Fu ', 'Qiao ', 'Bo ', 'Cuo ', 'Zhuo ',
+'Zhuan ', 'Tuo ', 'Pu ', 'Qin ', 'Dun ', 'Nian ', '[?]', 'Xie ', 'Lu ', 'Jiao ', 'Cuan ', 'Ta ', 'Han ', 'Qiao ', 'Zhua ', 'Jian ',
+'Gan ', 'Yong ', 'Lei ', 'Kuo ', 'Lu ', 'Shan ', 'Zhuo ', 'Ze ', 'Pu ', 'Chuo ', 'Ji ', 'Dang ', 'Suo ', 'Cao ', 'Qing ', 'Jing ',
+'Huan ', 'Jie ', 'Qin ', 'Kuai ', 'Dan ', 'Xi ', 'Ge ', 'Pi ', 'Bo ', 'Ao ', 'Ju ', 'Ye ', '[?]', 'Mang ', 'Sou ', 'Mi ',
+'Ji ', 'Tai ', 'Zhuo ', 'Dao ', 'Xing ', 'Lan ', 'Ca ', 'Ju ', 'Ye ', 'Ru ', 'Ye ', 'Ye ', 'Ni ', 'Hu ', 'Ji ', 'Bin ',
+'Ning ', 'Ge ', 'Zhi ', 'Jie ', 'Kuo ', 'Mo ', 'Jian ', 'Xie ', 'Lie ', 'Tan ', 'Bai ', 'Sou ', 'Lu ', 'Lue ', 'Rao ', 'Zhi ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x65.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x65.php
new file mode 100644 (file)
index 0000000..9f7f696
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x65] = array(
+'Pan ', 'Yang ', 'Lei ', 'Sa ', 'Shu ', 'Zan ', 'Nian ', 'Xian ', 'Jun ', 'Huo ', 'Li ', 'La ', 'Han ', 'Ying ', 'Lu ', 'Long ',
+'Qian ', 'Qian ', 'Zan ', 'Qian ', 'Lan ', 'San ', 'Ying ', 'Mei ', 'Rang ', 'Chan ', '[?]', 'Cuan ', 'Xi ', 'She ', 'Luo ', 'Jun ',
+'Mi ', 'Li ', 'Zan ', 'Luan ', 'Tan ', 'Zuan ', 'Li ', 'Dian ', 'Wa ', 'Dang ', 'Jiao ', 'Jue ', 'Lan ', 'Li ', 'Nang ', 'Zhi ',
+'Gui ', 'Gui ', 'Qi ', 'Xin ', 'Pu ', 'Sui ', 'Shou ', 'Kao ', 'You ', 'Gai ', 'Yi ', 'Gong ', 'Gan ', 'Ban ', 'Fang ', 'Zheng ',
+'Bo ', 'Dian ', 'Kou ', 'Min ', 'Wu ', 'Gu ', 'He ', 'Ce ', 'Xiao ', 'Mi ', 'Chu ', 'Ge ', 'Di ', 'Xu ', 'Jiao ', 'Min ',
+'Chen ', 'Jiu ', 'Zhen ', 'Duo ', 'Yu ', 'Chi ', 'Ao ', 'Bai ', 'Xu ', 'Jiao ', 'Duo ', 'Lian ', 'Nie ', 'Bi ', 'Chang ', 'Dian ',
+'Duo ', 'Yi ', 'Gan ', 'San ', 'Ke ', 'Yan ', 'Dun ', 'Qi ', 'Dou ', 'Xiao ', 'Duo ', 'Jiao ', 'Jing ', 'Yang ', 'Xia ', 'Min ',
+'Shu ', 'Ai ', 'Qiao ', 'Ai ', 'Zheng ', 'Di ', 'Zhen ', 'Fu ', 'Shu ', 'Liao ', 'Qu ', 'Xiong ', 'Xi ', 'Jiao ', 'Sen ', 'Jiao ',
+'Zhuo ', 'Yi ', 'Lian ', 'Bi ', 'Li ', 'Xiao ', 'Xiao ', 'Wen ', 'Xue ', 'Qi ', 'Qi ', 'Zhai ', 'Bin ', 'Jue ', 'Zhai ', '[?]',
+'Fei ', 'Ban ', 'Ban ', 'Lan ', 'Yu ', 'Lan ', 'Wei ', 'Dou ', 'Sheng ', 'Liao ', 'Jia ', 'Hu ', 'Xie ', 'Jia ', 'Yu ', 'Zhen ',
+'Jiao ', 'Wo ', 'Tou ', 'Chu ', 'Jin ', 'Chi ', 'Yin ', 'Fu ', 'Qiang ', 'Zhan ', 'Qu ', 'Zhuo ', 'Zhan ', 'Duan ', 'Zhuo ', 'Si ',
+'Xin ', 'Zhuo ', 'Zhuo ', 'Qin ', 'Lin ', 'Zhuo ', 'Chu ', 'Duan ', 'Zhu ', 'Fang ', 'Xie ', 'Hang ', 'Yu ', 'Shi ', 'Pei ', 'You ',
+'Mye ', 'Pang ', 'Qi ', 'Zhan ', 'Mao ', 'Lu ', 'Pei ', 'Pi ', 'Liu ', 'Fu ', 'Fang ', 'Xuan ', 'Jing ', 'Jing ', 'Ni ', 'Zu ',
+'Zhao ', 'Yi ', 'Liu ', 'Shao ', 'Jian ', 'Es ', 'Yi ', 'Qi ', 'Zhi ', 'Fan ', 'Piao ', 'Fan ', 'Zhan ', 'Guai ', 'Sui ', 'Yu ',
+'Wu ', 'Ji ', 'Ji ', 'Ji ', 'Huo ', 'Ri ', 'Dan ', 'Jiu ', 'Zhi ', 'Zao ', 'Xie ', 'Tiao ', 'Xun ', 'Xu ', 'Xu ', 'Xu ',
+'Gan ', 'Han ', 'Tai ', 'Di ', 'Xu ', 'Chan ', 'Shi ', 'Kuang ', 'Yang ', 'Shi ', 'Wang ', 'Min ', 'Min ', 'Tun ', 'Chun ', 'Wu ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x66.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x66.php
new file mode 100644 (file)
index 0000000..a4f2dae
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x66] = array(
+'Yun ', 'Bei ', 'Ang ', 'Ze ', 'Ban ', 'Jie ', 'Kun ', 'Sheng ', 'Hu ', 'Fang ', 'Hao ', 'Gui ', 'Chang ', 'Xuan ', 'Ming ', 'Hun ',
+'Fen ', 'Qin ', 'Hu ', 'Yi ', 'Xi ', 'Xin ', 'Yan ', 'Ze ', 'Fang ', 'Tan ', 'Shen ', 'Ju ', 'Yang ', 'Zan ', 'Bing ', 'Xing ',
+'Ying ', 'Xuan ', 'Pei ', 'Zhen ', 'Ling ', 'Chun ', 'Hao ', 'Mei ', 'Zuo ', 'Mo ', 'Bian ', 'Xu ', 'Hun ', 'Zhao ', 'Zong ', 'Shi ',
+'Shi ', 'Yu ', 'Fei ', 'Die ', 'Mao ', 'Ni ', 'Chang ', 'Wen ', 'Dong ', 'Ai ', 'Bing ', 'Ang ', 'Zhou ', 'Long ', 'Xian ', 'Kuang ',
+'Tiao ', 'Chao ', 'Shi ', 'Huang ', 'Huang ', 'Xuan ', 'Kui ', 'Xu ', 'Jiao ', 'Jin ', 'Zhi ', 'Jin ', 'Shang ', 'Tong ', 'Hong ', 'Yan ',
+'Gai ', 'Xiang ', 'Shai ', 'Xiao ', 'Ye ', 'Yun ', 'Hui ', 'Han ', 'Han ', 'Jun ', 'Wan ', 'Xian ', 'Kun ', 'Zhou ', 'Xi ', 'Cheng ',
+'Sheng ', 'Bu ', 'Zhe ', 'Zhe ', 'Wu ', 'Han ', 'Hui ', 'Hao ', 'Chen ', 'Wan ', 'Tian ', 'Zhuo ', 'Zui ', 'Zhou ', 'Pu ', 'Jing ',
+'Xi ', 'Shan ', 'Yi ', 'Xi ', 'Qing ', 'Qi ', 'Jing ', 'Gui ', 'Zhen ', 'Yi ', 'Zhi ', 'An ', 'Wan ', 'Lin ', 'Liang ', 'Chang ',
+'Wang ', 'Xiao ', 'Zan ', 'Hi ', 'Xuan ', 'Xuan ', 'Yi ', 'Xia ', 'Yun ', 'Hui ', 'Fu ', 'Min ', 'Kui ', 'He ', 'Ying ', 'Du ',
+'Wei ', 'Shu ', 'Qing ', 'Mao ', 'Nan ', 'Jian ', 'Nuan ', 'An ', 'Yang ', 'Chun ', 'Yao ', 'Suo ', 'Jin ', 'Ming ', 'Jiao ', 'Kai ',
+'Gao ', 'Weng ', 'Chang ', 'Qi ', 'Hao ', 'Yan ', 'Li ', 'Ai ', 'Ji ', 'Gui ', 'Men ', 'Zan ', 'Xie ', 'Hao ', 'Mu ', 'Mo ',
+'Cong ', 'Ni ', 'Zhang ', 'Hui ', 'Bao ', 'Han ', 'Xuan ', 'Chuan ', 'Liao ', 'Xian ', 'Dan ', 'Jing ', 'Pie ', 'Lin ', 'Tun ', 'Xi ',
+'Yi ', 'Ji ', 'Huang ', 'Tai ', 'Ye ', 'Ye ', 'Li ', 'Tan ', 'Tong ', 'Xiao ', 'Fei ', 'Qin ', 'Zhao ', 'Hao ', 'Yi ', 'Xiang ',
+'Xing ', 'Sen ', 'Jiao ', 'Bao ', 'Jing ', 'Yian ', 'Ai ', 'Ye ', 'Ru ', 'Shu ', 'Meng ', 'Xun ', 'Yao ', 'Pu ', 'Li ', 'Chen ',
+'Kuang ', 'Die ', '[?]', 'Yan ', 'Huo ', 'Lu ', 'Xi ', 'Rong ', 'Long ', 'Nang ', 'Luo ', 'Luan ', 'Shai ', 'Tang ', 'Yan ', 'Chu ',
+'Yue ', 'Yue ', 'Qu ', 'Yi ', 'Geng ', 'Ye ', 'Hu ', 'He ', 'Shu ', 'Cao ', 'Cao ', 'Noboru ', 'Man ', 'Ceng ', 'Ceng ', 'Ti ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x67.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x67.php
new file mode 100644 (file)
index 0000000..567831b
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x67] = array(
+'Zui ', 'Can ', 'Xu ', 'Hui ', 'Yin ', 'Qie ', 'Fen ', 'Pi ', 'Yue ', 'You ', 'Ruan ', 'Peng ', 'Ban ', 'Fu ', 'Ling ', 'Fei ',
+'Qu ', '[?]', 'Nu ', 'Tiao ', 'Shuo ', 'Zhen ', 'Lang ', 'Lang ', 'Juan ', 'Ming ', 'Huang ', 'Wang ', 'Tun ', 'Zhao ', 'Ji ', 'Qi ',
+'Ying ', 'Zong ', 'Wang ', 'Tong ', 'Lang ', '[?]', 'Meng ', 'Long ', 'Mu ', 'Deng ', 'Wei ', 'Mo ', 'Ben ', 'Zha ', 'Zhu ', 'Zhu ',
+'[?]', 'Zhu ', 'Ren ', 'Ba ', 'Po ', 'Duo ', 'Duo ', 'Dao ', 'Li ', 'Qiu ', 'Ji ', 'Jiu ', 'Bi ', 'Xiu ', 'Ting ', 'Ci ',
+'Sha ', 'Eburi ', 'Za ', 'Quan ', 'Qian ', 'Yu ', 'Gan ', 'Wu ', 'Cha ', 'Shan ', 'Xun ', 'Fan ', 'Wu ', 'Zi ', 'Li ', 'Xing ',
+'Cai ', 'Cun ', 'Ren ', 'Shao ', 'Tuo ', 'Di ', 'Zhang ', 'Mang ', 'Chi ', 'Yi ', 'Gu ', 'Gong ', 'Du ', 'Yi ', 'Qi ', 'Shu ',
+'Gang ', 'Tiao ', 'Moku ', 'Soma ', 'Tochi ', 'Lai ', 'Sugi ', 'Mang ', 'Yang ', 'Ma ', 'Miao ', 'Si ', 'Yuan ', 'Hang ', 'Fei ', 'Bei ',
+'Jie ', 'Dong ', 'Gao ', 'Yao ', 'Xian ', 'Chu ', 'Qun ', 'Pa ', 'Shu ', 'Hua ', 'Xin ', 'Chou ', 'Zhu ', 'Chou ', 'Song ', 'Ban ',
+'Song ', 'Ji ', 'Yue ', 'Jin ', 'Gou ', 'Ji ', 'Mao ', 'Pi ', 'Bi ', 'Wang ', 'Ang ', 'Fang ', 'Fen ', 'Yi ', 'Fu ', 'Nan ',
+'Xi ', 'Hu ', 'Ya ', 'Dou ', 'Xun ', 'Zhen ', 'Yao ', 'Lin ', 'Rui ', 'E ', 'Mei ', 'Zhao ', 'Guo ', 'Zhi ', 'Cong ', 'Yun ',
+'Waku ', 'Dou ', 'Shu ', 'Zao ', '[?]', 'Li ', 'Haze ', 'Jian ', 'Cheng ', 'Matsu ', 'Qiang ', 'Feng ', 'Nan ', 'Xiao ', 'Xian ', 'Ku ',
+'Ping ', 'Yi ', 'Xi ', 'Zhi ', 'Guai ', 'Xiao ', 'Jia ', 'Jia ', 'Gou ', 'Fu ', 'Mo ', 'Yi ', 'Ye ', 'Ye ', 'Shi ', 'Nie ',
+'Bi ', 'Duo ', 'Yi ', 'Ling ', 'Bing ', 'Ni ', 'La ', 'He ', 'Pan ', 'Fan ', 'Zhong ', 'Dai ', 'Ci ', 'Yang ', 'Fu ', 'Bo ',
+'Mou ', 'Gan ', 'Qi ', 'Ran ', 'Rou ', 'Mao ', 'Zhao ', 'Song ', 'Zhe ', 'Xia ', 'You ', 'Shen ', 'Ju ', 'Tuo ', 'Zuo ', 'Nan ',
+'Ning ', 'Yong ', 'Di ', 'Zhi ', 'Zha ', 'Cha ', 'Dan ', 'Gu ', 'Pu ', 'Jiu ', 'Ao ', 'Fu ', 'Jian ', 'Bo ', 'Duo ', 'Ke ',
+'Nai ', 'Zhu ', 'Bi ', 'Liu ', 'Chai ', 'Zha ', 'Si ', 'Zhu ', 'Pei ', 'Shi ', 'Guai ', 'Cha ', 'Yao ', 'Jue ', 'Jiu ', 'Shi ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x68.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x68.php
new file mode 100644 (file)
index 0000000..879ed78
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x68] = array(
+'Zhi ', 'Liu ', 'Mei ', 'Hoy ', 'Rong ', 'Zha ', '[?]', 'Biao ', 'Zhan ', 'Jie ', 'Long ', 'Dong ', 'Lu ', 'Sayng ', 'Li ', 'Lan ',
+'Yong ', 'Shu ', 'Xun ', 'Shuan ', 'Qi ', 'Zhen ', 'Qi ', 'Li ', 'Yi ', 'Xiang ', 'Zhen ', 'Li ', 'Su ', 'Gua ', 'Kan ', 'Bing ',
+'Ren ', 'Xiao ', 'Bo ', 'Ren ', 'Bing ', 'Zi ', 'Chou ', 'Yi ', 'Jie ', 'Xu ', 'Zhu ', 'Jian ', 'Zui ', 'Er ', 'Er ', 'You ',
+'Fa ', 'Gong ', 'Kao ', 'Lao ', 'Zhan ', 'Li ', 'Yin ', 'Yang ', 'He ', 'Gen ', 'Zhi ', 'Chi ', 'Ge ', 'Zai ', 'Luan ', 'Fu ',
+'Jie ', 'Hang ', 'Gui ', 'Tao ', 'Guang ', 'Wei ', 'Kuang ', 'Ru ', 'An ', 'An ', 'Juan ', 'Yi ', 'Zhuo ', 'Ku ', 'Zhi ', 'Qiong ',
+'Tong ', 'Sang ', 'Sang ', 'Huan ', 'Jie ', 'Jiu ', 'Xue ', 'Duo ', 'Zhui ', 'Yu ', 'Zan ', 'Kasei ', 'Ying ', 'Masu ', '[?]', 'Zhan ',
+'Ya ', 'Nao ', 'Zhen ', 'Dang ', 'Qi ', 'Qiao ', 'Hua ', 'Kuai ', 'Jiang ', 'Zhuang ', 'Xun ', 'Suo ', 'Sha ', 'Zhen ', 'Bei ', 'Ting ',
+'Gua ', 'Jing ', 'Bo ', 'Ben ', 'Fu ', 'Rui ', 'Tong ', 'Jue ', 'Xi ', 'Lang ', 'Liu ', 'Feng ', 'Qi ', 'Wen ', 'Jun ', 'Gan ',
+'Cu ', 'Liang ', 'Qiu ', 'Ting ', 'You ', 'Mei ', 'Bang ', 'Long ', 'Peng ', 'Zhuang ', 'Di ', 'Xuan ', 'Tu ', 'Zao ', 'Ao ', 'Gu ',
+'Bi ', 'Di ', 'Han ', 'Zi ', 'Zhi ', 'Ren ', 'Bei ', 'Geng ', 'Jian ', 'Huan ', 'Wan ', 'Nuo ', 'Jia ', 'Tiao ', 'Ji ', 'Xiao ',
+'Lu ', 'Huan ', 'Shao ', 'Cen ', 'Fen ', 'Song ', 'Meng ', 'Wu ', 'Li ', 'Li ', 'Dou ', 'Cen ', 'Ying ', 'Suo ', 'Ju ', 'Ti ',
+'Jie ', 'Kun ', 'Zhuo ', 'Shu ', 'Chan ', 'Fan ', 'Wei ', 'Jing ', 'Li ', 'Bing ', 'Fumoto ', 'Shikimi ', 'Tao ', 'Zhi ', 'Lai ', 'Lian ',
+'Jian ', 'Zhuo ', 'Ling ', 'Li ', 'Qi ', 'Bing ', 'Zhun ', 'Cong ', 'Qian ', 'Mian ', 'Qi ', 'Qi ', 'Cai ', 'Gun ', 'Chan ', 'Te ',
+'Fei ', 'Pai ', 'Bang ', 'Pou ', 'Hun ', 'Zong ', 'Cheng ', 'Zao ', 'Ji ', 'Li ', 'Peng ', 'Yu ', 'Yu ', 'Gu ', 'Hun ', 'Dong ',
+'Tang ', 'Gang ', 'Wang ', 'Di ', 'Xi ', 'Fan ', 'Cheng ', 'Zhan ', 'Qi ', 'Yuan ', 'Yan ', 'Yu ', 'Quan ', 'Yi ', 'Sen ', 'Ren ',
+'Chui ', 'Leng ', 'Qi ', 'Zhuo ', 'Fu ', 'Ke ', 'Lai ', 'Zou ', 'Zou ', 'Zhuo ', 'Guan ', 'Fen ', 'Fen ', 'Chen ', 'Qiong ', 'Nie ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x69.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x69.php
new file mode 100644 (file)
index 0000000..48c81e2
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x69] = array(
+'Wan ', 'Guo ', 'Lu ', 'Hao ', 'Jie ', 'Yi ', 'Chou ', 'Ju ', 'Ju ', 'Cheng ', 'Zuo ', 'Liang ', 'Qiang ', 'Zhi ', 'Zhui ', 'Ya ',
+'Ju ', 'Bei ', 'Jiao ', 'Zhuo ', 'Zi ', 'Bin ', 'Peng ', 'Ding ', 'Chu ', 'Chang ', 'Kunugi ', 'Momiji ', 'Jian ', 'Gui ', 'Xi ', 'Du ',
+'Qian ', 'Kunugi ', 'Soko ', 'Shide ', 'Luo ', 'Zhi ', 'Ken ', 'Myeng ', 'Tafu ', '[?]', 'Peng ', 'Zhan ', '[?]', 'Tuo ', 'Sen ', 'Duo ',
+'Ye ', 'Fou ', 'Wei ', 'Wei ', 'Duan ', 'Jia ', 'Zong ', 'Jian ', 'Yi ', 'Shen ', 'Xi ', 'Yan ', 'Yan ', 'Chuan ', 'Zhan ', 'Chun ',
+'Yu ', 'He ', 'Zha ', 'Wo ', 'Pian ', 'Bi ', 'Yao ', 'Huo ', 'Xu ', 'Ruo ', 'Yang ', 'La ', 'Yan ', 'Ben ', 'Hun ', 'Kui ',
+'Jie ', 'Kui ', 'Si ', 'Feng ', 'Xie ', 'Tuo ', 'Zhi ', 'Jian ', 'Mu ', 'Mao ', 'Chu ', 'Hu ', 'Hu ', 'Lian ', 'Leng ', 'Ting ',
+'Nan ', 'Yu ', 'You ', 'Mei ', 'Song ', 'Xuan ', 'Xuan ', 'Ying ', 'Zhen ', 'Pian ', 'Ye ', 'Ji ', 'Jie ', 'Ye ', 'Chu ', 'Shun ',
+'Yu ', 'Cou ', 'Wei ', 'Mei ', 'Di ', 'Ji ', 'Jie ', 'Kai ', 'Qiu ', 'Ying ', 'Rou ', 'Heng ', 'Lou ', 'Le ', 'Hazou ', 'Katsura ',
+'Pin ', 'Muro ', 'Gai ', 'Tan ', 'Lan ', 'Yun ', 'Yu ', 'Chen ', 'Lu ', 'Ju ', 'Sakaki ', '[?]', 'Pi ', 'Xie ', 'Jia ', 'Yi ',
+'Zhan ', 'Fu ', 'Nai ', 'Mi ', 'Lang ', 'Rong ', 'Gu ', 'Jian ', 'Ju ', 'Ta ', 'Yao ', 'Zhen ', 'Bang ', 'Sha ', 'Yuan ', 'Zi ',
+'Ming ', 'Su ', 'Jia ', 'Yao ', 'Jie ', 'Huang ', 'Gan ', 'Fei ', 'Zha ', 'Qian ', 'Ma ', 'Sun ', 'Yuan ', 'Xie ', 'Rong ', 'Shi ',
+'Zhi ', 'Cui ', 'Yun ', 'Ting ', 'Liu ', 'Rong ', 'Tang ', 'Que ', 'Zhai ', 'Si ', 'Sheng ', 'Ta ', 'Ke ', 'Xi ', 'Gu ', 'Qi ',
+'Kao ', 'Gao ', 'Sun ', 'Pan ', 'Tao ', 'Ge ', 'Xun ', 'Dian ', 'Nou ', 'Ji ', 'Shuo ', 'Gou ', 'Chui ', 'Qiang ', 'Cha ', 'Qian ',
+'Huai ', 'Mei ', 'Xu ', 'Gang ', 'Gao ', 'Zhuo ', 'Tuo ', 'Hashi ', 'Yang ', 'Dian ', 'Jia ', 'Jian ', 'Zui ', 'Kashi ', 'Ori ', 'Bin ',
+'Zhu ', '[?]', 'Xi ', 'Qi ', 'Lian ', 'Hui ', 'Yong ', 'Qian ', 'Guo ', 'Gai ', 'Gai ', 'Tuan ', 'Hua ', 'Cu ', 'Sen ', 'Cui ',
+'Beng ', 'You ', 'Hu ', 'Jiang ', 'Hu ', 'Huan ', 'Kui ', 'Yi ', 'Nie ', 'Gao ', 'Kang ', 'Gui ', 'Gui ', 'Cao ', 'Man ', 'Jin ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x6a.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x6a.php
new file mode 100644 (file)
index 0000000..9a0c4e3
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x6a] = array(
+'Di ', 'Zhuang ', 'Le ', 'Lang ', 'Chen ', 'Cong ', 'Li ', 'Xiu ', 'Qing ', 'Shuang ', 'Fan ', 'Tong ', 'Guan ', 'Ji ', 'Suo ', 'Lei ',
+'Lu ', 'Liang ', 'Mi ', 'Lou ', 'Chao ', 'Su ', 'Ke ', 'Shu ', 'Tang ', 'Biao ', 'Lu ', 'Jiu ', 'Shu ', 'Zha ', 'Shu ', 'Zhang ',
+'Men ', 'Mo ', 'Niao ', 'Yang ', 'Tiao ', 'Peng ', 'Zhu ', 'Sha ', 'Xi ', 'Quan ', 'Heng ', 'Jian ', 'Cong ', '[?]', 'Hokuso ', 'Qiang ',
+'Tara ', 'Ying ', 'Er ', 'Xin ', 'Zhi ', 'Qiao ', 'Zui ', 'Cong ', 'Pu ', 'Shu ', 'Hua ', 'Kui ', 'Zhen ', 'Zun ', 'Yue ', 'Zhan ',
+'Xi ', 'Xun ', 'Dian ', 'Fa ', 'Gan ', 'Mo ', 'Wu ', 'Qiao ', 'Nao ', 'Lin ', 'Liu ', 'Qiao ', 'Xian ', 'Run ', 'Fan ', 'Zhan ',
+'Tuo ', 'Lao ', 'Yun ', 'Shun ', 'Tui ', 'Cheng ', 'Tang ', 'Meng ', 'Ju ', 'Cheng ', 'Su ', 'Jue ', 'Jue ', 'Tan ', 'Hui ', 'Ji ',
+'Nuo ', 'Xiang ', 'Tuo ', 'Ning ', 'Rui ', 'Zhu ', 'Chuang ', 'Zeng ', 'Fen ', 'Qiong ', 'Ran ', 'Heng ', 'Cen ', 'Gu ', 'Liu ', 'Lao ',
+'Gao ', 'Chu ', 'Zusa ', 'Nude ', 'Ca ', 'San ', 'Ji ', 'Dou ', 'Shou ', 'Lu ', '[?]', '[?]', 'Yuan ', 'Ta ', 'Shu ', 'Jiang ',
+'Tan ', 'Lin ', 'Nong ', 'Yin ', 'Xi ', 'Sui ', 'Shan ', 'Zui ', 'Xuan ', 'Cheng ', 'Gan ', 'Ju ', 'Zui ', 'Yi ', 'Qin ', 'Pu ',
+'Yan ', 'Lei ', 'Feng ', 'Hui ', 'Dang ', 'Ji ', 'Sui ', 'Bo ', 'Bi ', 'Ding ', 'Chu ', 'Zhua ', 'Kuai ', 'Ji ', 'Jie ', 'Jia ',
+'Qing ', 'Zhe ', 'Jian ', 'Qiang ', 'Dao ', 'Yi ', 'Biao ', 'Song ', 'She ', 'Lin ', 'Kunugi ', 'Cha ', 'Meng ', 'Yin ', 'Tao ', 'Tai ',
+'Mian ', 'Qi ', 'Toan ', 'Bin ', 'Huo ', 'Ji ', 'Qian ', 'Mi ', 'Ning ', 'Yi ', 'Gao ', 'Jian ', 'Yin ', 'Er ', 'Qing ', 'Yan ',
+'Qi ', 'Mi ', 'Zhao ', 'Gui ', 'Chun ', 'Ji ', 'Kui ', 'Po ', 'Deng ', 'Chu ', '[?]', 'Mian ', 'You ', 'Zhi ', 'Guang ', 'Qian ',
+'Lei ', 'Lei ', 'Sa ', 'Lu ', 'Li ', 'Cuan ', 'Lu ', 'Mie ', 'Hui ', 'Ou ', 'Lu ', 'Jie ', 'Gao ', 'Du ', 'Yuan ', 'Li ',
+'Fei ', 'Zhuo ', 'Sou ', 'Lian ', 'Tamo ', 'Chu ', '[?]', 'Zhu ', 'Lu ', 'Yan ', 'Li ', 'Zhu ', 'Chen ', 'Jie ', 'E ', 'Su ',
+'Huai ', 'Nie ', 'Yu ', 'Long ', 'Lai ', '[?]', 'Xian ', 'Kwi ', 'Ju ', 'Xiao ', 'Ling ', 'Ying ', 'Jian ', 'Yin ', 'You ', 'Ying ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x6b.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x6b.php
new file mode 100644 (file)
index 0000000..26f97f2
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x6b] = array(
+'Xiang ', 'Nong ', 'Bo ', 'Chan ', 'Lan ', 'Ju ', 'Shuang ', 'She ', 'Wei ', 'Cong ', 'Quan ', 'Qu ', 'Cang ', '[?]', 'Yu ', 'Luo ',
+'Li ', 'Zan ', 'Luan ', 'Dang ', 'Jue ', 'Em ', 'Lan ', 'Lan ', 'Zhu ', 'Lei ', 'Li ', 'Ba ', 'Nang ', 'Yu ', 'Ling ', 'Tsuki ',
+'Qian ', 'Ci ', 'Huan ', 'Xin ', 'Yu ', 'Yu ', 'Qian ', 'Ou ', 'Xu ', 'Chao ', 'Chu ', 'Chi ', 'Kai ', 'Yi ', 'Jue ', 'Xi ',
+'Xu ', 'Xia ', 'Yu ', 'Kuai ', 'Lang ', 'Kuan ', 'Shuo ', 'Xi ', 'Ai ', 'Yi ', 'Qi ', 'Hu ', 'Chi ', 'Qin ', 'Kuan ', 'Kan ',
+'Kuan ', 'Kan ', 'Chuan ', 'Sha ', 'Gua ', 'Yin ', 'Xin ', 'Xie ', 'Yu ', 'Qian ', 'Xiao ', 'Yi ', 'Ge ', 'Wu ', 'Tan ', 'Jin ',
+'Ou ', 'Hu ', 'Ti ', 'Huan ', 'Xu ', 'Pen ', 'Xi ', 'Xiao ', 'Xu ', 'Xi ', 'Sen ', 'Lian ', 'Chu ', 'Yi ', 'Kan ', 'Yu ',
+'Chuo ', 'Huan ', 'Zhi ', 'Zheng ', 'Ci ', 'Bu ', 'Wu ', 'Qi ', 'Bu ', 'Bu ', 'Wai ', 'Ju ', 'Qian ', 'Chi ', 'Se ', 'Chi ',
+'Se ', 'Zhong ', 'Sui ', 'Sui ', 'Li ', 'Cuo ', 'Yu ', 'Li ', 'Gui ', 'Dai ', 'Dai ', 'Si ', 'Jian ', 'Zhe ', 'Mo ', 'Mo ',
+'Yao ', 'Mo ', 'Cu ', 'Yang ', 'Tian ', 'Sheng ', 'Dai ', 'Shang ', 'Xu ', 'Xun ', 'Shu ', 'Can ', 'Jue ', 'Piao ', 'Qia ', 'Qiu ',
+'Su ', 'Qing ', 'Yun ', 'Lian ', 'Yi ', 'Fou ', 'Zhi ', 'Ye ', 'Can ', 'Hun ', 'Dan ', 'Ji ', 'Ye ', 'Zhen ', 'Yun ', 'Wen ',
+'Chou ', 'Bin ', 'Ti ', 'Jin ', 'Shang ', 'Yin ', 'Diao ', 'Cu ', 'Hui ', 'Cuan ', 'Yi ', 'Dan ', 'Du ', 'Jiang ', 'Lian ', 'Bin ',
+'Du ', 'Tsukusu ', 'Jian ', 'Shu ', 'Ou ', 'Duan ', 'Zhu ', 'Yin ', 'Qing ', 'Yi ', 'Sha ', 'Que ', 'Ke ', 'Yao ', 'Jun ', 'Dian ',
+'Hui ', 'Hui ', 'Gu ', 'Que ', 'Ji ', 'Yi ', 'Ou ', 'Hui ', 'Duan ', 'Yi ', 'Xiao ', 'Wu ', 'Guan ', 'Mu ', 'Mei ', 'Mei ',
+'Ai ', 'Zuo ', 'Du ', 'Yu ', 'Bi ', 'Bi ', 'Bi ', 'Pi ', 'Pi ', 'Bi ', 'Chan ', 'Mao ', '[?]', '[?]', 'Pu ', 'Mushiru ',
+'Jia ', 'Zhan ', 'Sai ', 'Mu ', 'Tuo ', 'Xun ', 'Er ', 'Rong ', 'Xian ', 'Ju ', 'Mu ', 'Hao ', 'Qiu ', 'Dou ', 'Mushiru ', 'Tan ',
+'Pei ', 'Ju ', 'Duo ', 'Cui ', 'Bi ', 'San ', '[?]', 'Mao ', 'Sui ', 'Yu ', 'Yu ', 'Tuo ', 'He ', 'Jian ', 'Ta ', 'San ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x6c.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x6c.php
new file mode 100644 (file)
index 0000000..f4f756c
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x6c] = array(
+'Lu ', 'Mu ', 'Li ', 'Tong ', 'Rong ', 'Chang ', 'Pu ', 'Luo ', 'Zhan ', 'Sao ', 'Zhan ', 'Meng ', 'Luo ', 'Qu ', 'Die ', 'Shi ',
+'Di ', 'Min ', 'Jue ', 'Mang ', 'Qi ', 'Pie ', 'Nai ', 'Qi ', 'Dao ', 'Xian ', 'Chuan ', 'Fen ', 'Ri ', 'Nei ', '[?]', 'Fu ',
+'Shen ', 'Dong ', 'Qing ', 'Qi ', 'Yin ', 'Xi ', 'Hai ', 'Yang ', 'An ', 'Ya ', 'Ke ', 'Qing ', 'Ya ', 'Dong ', 'Dan ', 'Lu ',
+'Qing ', 'Yang ', 'Yun ', 'Yun ', 'Shui ', 'San ', 'Zheng ', 'Bing ', 'Yong ', 'Dang ', 'Shitamizu ', 'Le ', 'Ni ', 'Tun ', 'Fan ', 'Gui ',
+'Ting ', 'Zhi ', 'Qiu ', 'Bin ', 'Ze ', 'Mian ', 'Cuan ', 'Hui ', 'Diao ', 'Yi ', 'Cha ', 'Zhuo ', 'Chuan ', 'Wan ', 'Fan ', 'Dai ',
+'Xi ', 'Tuo ', 'Mang ', 'Qiu ', 'Qi ', 'Shan ', 'Pai ', 'Han ', 'Qian ', 'Wu ', 'Wu ', 'Xun ', 'Si ', 'Ru ', 'Gong ', 'Jiang ',
+'Chi ', 'Wu ', 'Tsuchi ', '[?]', 'Tang ', 'Zhi ', 'Chi ', 'Qian ', 'Mi ', 'Yu ', 'Wang ', 'Qing ', 'Jing ', 'Rui ', 'Jun ', 'Hong ',
+'Tai ', 'Quan ', 'Ji ', 'Bian ', 'Bian ', 'Gan ', 'Wen ', 'Zhong ', 'Fang ', 'Xiong ', 'Jue ', 'Hang ', 'Niou ', 'Qi ', 'Fen ', 'Xu ',
+'Xu ', 'Qin ', 'Yi ', 'Wo ', 'Yun ', 'Yuan ', 'Hang ', 'Yan ', 'Chen ', 'Chen ', 'Dan ', 'You ', 'Dun ', 'Hu ', 'Huo ', 'Qie ',
+'Mu ', 'Rou ', 'Mei ', 'Ta ', 'Mian ', 'Wu ', 'Chong ', 'Tian ', 'Bi ', 'Sha ', 'Zhi ', 'Pei ', 'Pan ', 'Zhui ', 'Za ', 'Gou ',
+'Liu ', 'Mei ', 'Ze ', 'Feng ', 'Ou ', 'Li ', 'Lun ', 'Cang ', 'Feng ', 'Wei ', 'Hu ', 'Mo ', 'Mei ', 'Shu ', 'Ju ', 'Zan ',
+'Tuo ', 'Tuo ', 'Tuo ', 'He ', 'Li ', 'Mi ', 'Yi ', 'Fa ', 'Fei ', 'You ', 'Tian ', 'Zhi ', 'Zhao ', 'Gu ', 'Zhan ', 'Yan ',
+'Si ', 'Kuang ', 'Jiong ', 'Ju ', 'Xie ', 'Qiu ', 'Yi ', 'Jia ', 'Zhong ', 'Quan ', 'Bo ', 'Hui ', 'Mi ', 'Ben ', 'Zhuo ', 'Chu ',
+'Le ', 'You ', 'Gu ', 'Hong ', 'Gan ', 'Fa ', 'Mao ', 'Si ', 'Hu ', 'Ping ', 'Ci ', 'Fan ', 'Chi ', 'Su ', 'Ning ', 'Cheng ',
+'Ling ', 'Pao ', 'Bo ', 'Qi ', 'Si ', 'Ni ', 'Ju ', 'Yue ', 'Zhu ', 'Sheng ', 'Lei ', 'Xuan ', 'Xue ', 'Fu ', 'Pan ', 'Min ',
+'Tai ', 'Yang ', 'Ji ', 'Yong ', 'Guan ', 'Beng ', 'Xue ', 'Long ', 'Lu ', '[?]', 'Bo ', 'Xie ', 'Po ', 'Ze ', 'Jing ', 'Yin ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x6d.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x6d.php
new file mode 100644 (file)
index 0000000..cb36b64
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x6d] = array(
+'Zhou ', 'Ji ', 'Yi ', 'Hui ', 'Hui ', 'Zui ', 'Cheng ', 'Yin ', 'Wei ', 'Hou ', 'Jian ', 'Yang ', 'Lie ', 'Si ', 'Ji ', 'Er ',
+'Xing ', 'Fu ', 'Sa ', 'Suo ', 'Zhi ', 'Yin ', 'Wu ', 'Xi ', 'Kao ', 'Zhu ', 'Jiang ', 'Luo ', '[?]', 'An ', 'Dong ', 'Yi ',
+'Mou ', 'Lei ', 'Yi ', 'Mi ', 'Quan ', 'Jin ', 'Mo ', 'Wei ', 'Xiao ', 'Xie ', 'Hong ', 'Xu ', 'Shuo ', 'Kuang ', 'Tao ', 'Qie ',
+'Ju ', 'Er ', 'Zhou ', 'Ru ', 'Ping ', 'Xun ', 'Xiong ', 'Zhi ', 'Guang ', 'Huan ', 'Ming ', 'Huo ', 'Wa ', 'Qia ', 'Pai ', 'Wu ',
+'Qu ', 'Liu ', 'Yi ', 'Jia ', 'Jing ', 'Qian ', 'Jiang ', 'Jiao ', 'Cheng ', 'Shi ', 'Zhuo ', 'Ce ', 'Pal ', 'Kuai ', 'Ji ', 'Liu ',
+'Chan ', 'Hun ', 'Hu ', 'Nong ', 'Xun ', 'Jin ', 'Lie ', 'Qiu ', 'Wei ', 'Zhe ', 'Jun ', 'Han ', 'Bang ', 'Mang ', 'Zhuo ', 'You ',
+'Xi ', 'Bo ', 'Dou ', 'Wan ', 'Hong ', 'Yi ', 'Pu ', 'Ying ', 'Lan ', 'Hao ', 'Lang ', 'Han ', 'Li ', 'Geng ', 'Fu ', 'Wu ',
+'Lian ', 'Chun ', 'Feng ', 'Yi ', 'Yu ', 'Tong ', 'Lao ', 'Hai ', 'Jin ', 'Jia ', 'Chong ', 'Weng ', 'Mei ', 'Sui ', 'Cheng ', 'Pei ',
+'Xian ', 'Shen ', 'Tu ', 'Kun ', 'Pin ', 'Nie ', 'Han ', 'Jing ', 'Xiao ', 'She ', 'Nian ', 'Tu ', 'Yong ', 'Xiao ', 'Xian ', 'Ting ',
+'E ', 'Su ', 'Tun ', 'Juan ', 'Cen ', 'Ti ', 'Li ', 'Shui ', 'Si ', 'Lei ', 'Shui ', 'Tao ', 'Du ', 'Lao ', 'Lai ', 'Lian ',
+'Wei ', 'Wo ', 'Yun ', 'Huan ', 'Di ', '[?]', 'Run ', 'Jian ', 'Zhang ', 'Se ', 'Fu ', 'Guan ', 'Xing ', 'Shou ', 'Shuan ', 'Ya ',
+'Chuo ', 'Zhang ', 'Ye ', 'Kong ', 'Wo ', 'Han ', 'Tuo ', 'Dong ', 'He ', 'Wo ', 'Ju ', 'Gan ', 'Liang ', 'Hun ', 'Ta ', 'Zhuo ',
+'Dian ', 'Qie ', 'De ', 'Juan ', 'Zi ', 'Xi ', 'Yao ', 'Qi ', 'Gu ', 'Guo ', 'Han ', 'Lin ', 'Tang ', 'Zhou ', 'Peng ', 'Hao ',
+'Chang ', 'Shu ', 'Qi ', 'Fang ', 'Chi ', 'Lu ', 'Nao ', 'Ju ', 'Tao ', 'Cong ', 'Lei ', 'Zhi ', 'Peng ', 'Fei ', 'Song ', 'Tian ',
+'Pi ', 'Dan ', 'Yu ', 'Ni ', 'Yu ', 'Lu ', 'Gan ', 'Mi ', 'Jing ', 'Ling ', 'Lun ', 'Yin ', 'Cui ', 'Qu ', 'Huai ', 'Yu ',
+'Nian ', 'Shen ', 'Piao ', 'Chun ', 'Wa ', 'Yuan ', 'Lai ', 'Hun ', 'Qing ', 'Yan ', 'Qian ', 'Tian ', 'Miao ', 'Zhi ', 'Yin ', 'Mi ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x6e.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x6e.php
new file mode 100644 (file)
index 0000000..7e50eb7
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x6e] = array(
+'Ben ', 'Yuan ', 'Wen ', 'Re ', 'Fei ', 'Qing ', 'Yuan ', 'Ke ', 'Ji ', 'She ', 'Yuan ', 'Shibui ', 'Lu ', 'Zi ', 'Du ', '[?]',
+'Jian ', 'Min ', 'Pi ', 'Tani ', 'Yu ', 'Yuan ', 'Shen ', 'Shen ', 'Rou ', 'Huan ', 'Zhu ', 'Jian ', 'Nuan ', 'Yu ', 'Qiu ', 'Ting ',
+'Qu ', 'Du ', 'Feng ', 'Zha ', 'Bo ', 'Wo ', 'Wo ', 'Di ', 'Wei ', 'Wen ', 'Ru ', 'Xie ', 'Ce ', 'Wei ', 'Ge ', 'Gang ',
+'Yan ', 'Hong ', 'Xuan ', 'Mi ', 'Ke ', 'Mao ', 'Ying ', 'Yan ', 'You ', 'Hong ', 'Miao ', 'Xing ', 'Mei ', 'Zai ', 'Hun ', 'Nai ',
+'Kui ', 'Shi ', 'E ', 'Pai ', 'Mei ', 'Lian ', 'Qi ', 'Qi ', 'Mei ', 'Tian ', 'Cou ', 'Wei ', 'Can ', 'Tuan ', 'Mian ', 'Hui ',
+'Mo ', 'Xu ', 'Ji ', 'Pen ', 'Jian ', 'Jian ', 'Hu ', 'Feng ', 'Xiang ', 'Yi ', 'Yin ', 'Zhan ', 'Shi ', 'Jie ', 'Cheng ', 'Huang ',
+'Tan ', 'Yu ', 'Bi ', 'Min ', 'Shi ', 'Tu ', 'Sheng ', 'Yong ', 'Qu ', 'Zhong ', 'Suei ', 'Jiu ', 'Jiao ', 'Qiou ', 'Yin ', 'Tang ',
+'Long ', 'Huo ', 'Yuan ', 'Nan ', 'Ban ', 'You ', 'Quan ', 'Chui ', 'Liang ', 'Chan ', 'Yan ', 'Chun ', 'Nie ', 'Zi ', 'Wan ', 'Shi ',
+'Man ', 'Ying ', 'Ratsu ', 'Kui ', '[?]', 'Jian ', 'Xu ', 'Lu ', 'Gui ', 'Gai ', '[?]', '[?]', 'Po ', 'Jin ', 'Gui ', 'Tang ',
+'Yuan ', 'Suo ', 'Yuan ', 'Lian ', 'Yao ', 'Meng ', 'Zhun ', 'Sheng ', 'Ke ', 'Tai ', 'Da ', 'Wa ', 'Liu ', 'Gou ', 'Sao ', 'Ming ',
+'Zha ', 'Shi ', 'Yi ', 'Lun ', 'Ma ', 'Pu ', 'Wei ', 'Li ', 'Cai ', 'Wu ', 'Xi ', 'Wen ', 'Qiang ', 'Ze ', 'Shi ', 'Su ',
+'Yi ', 'Zhen ', 'Sou ', 'Yun ', 'Xiu ', 'Yin ', 'Rong ', 'Hun ', 'Su ', 'Su ', 'Ni ', 'Ta ', 'Shi ', 'Ru ', 'Wei ', 'Pan ',
+'Chu ', 'Chu ', 'Pang ', 'Weng ', 'Cang ', 'Mie ', 'He ', 'Dian ', 'Hao ', 'Huang ', 'Xi ', 'Zi ', 'Di ', 'Zhi ', 'Ying ', 'Fu ',
+'Jie ', 'Hua ', 'Ge ', 'Zi ', 'Tao ', 'Teng ', 'Sui ', 'Bi ', 'Jiao ', 'Hui ', 'Gun ', 'Yin ', 'Gao ', 'Long ', 'Zhi ', 'Yan ',
+'She ', 'Man ', 'Ying ', 'Chun ', 'Lu ', 'Lan ', 'Luan ', '[?]', 'Bin ', 'Tan ', 'Yu ', 'Sou ', 'Hu ', 'Bi ', 'Biao ', 'Zhi ',
+'Jiang ', 'Kou ', 'Shen ', 'Shang ', 'Di ', 'Mi ', 'Ao ', 'Lu ', 'Hu ', 'Hu ', 'You ', 'Chan ', 'Fan ', 'Yong ', 'Gun ', 'Man ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x6f.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x6f.php
new file mode 100644 (file)
index 0000000..a610acf
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x6f] = array(
+'Qing ', 'Yu ', 'Piao ', 'Ji ', 'Ya ', 'Jiao ', 'Qi ', 'Xi ', 'Ji ', 'Lu ', 'Lu ', 'Long ', 'Jin ', 'Guo ', 'Cong ', 'Lou ',
+'Zhi ', 'Gai ', 'Qiang ', 'Li ', 'Yan ', 'Cao ', 'Jiao ', 'Cong ', 'Qun ', 'Tuan ', 'Ou ', 'Teng ', 'Ye ', 'Xi ', 'Mi ', 'Tang ',
+'Mo ', 'Shang ', 'Han ', 'Lian ', 'Lan ', 'Wa ', 'Li ', 'Qian ', 'Feng ', 'Xuan ', 'Yi ', 'Man ', 'Zi ', 'Mang ', 'Kang ', 'Lei ',
+'Peng ', 'Shu ', 'Zhang ', 'Zhang ', 'Chong ', 'Xu ', 'Huan ', 'Kuo ', 'Jian ', 'Yan ', 'Chuang ', 'Liao ', 'Cui ', 'Ti ', 'Yang ', 'Jiang ',
+'Cong ', 'Ying ', 'Hong ', 'Xun ', 'Shu ', 'Guan ', 'Ying ', 'Xiao ', '[?]', '[?]', 'Xu ', 'Lian ', 'Zhi ', 'Wei ', 'Pi ', 'Jue ',
+'Jiao ', 'Po ', 'Dang ', 'Hui ', 'Jie ', 'Wu ', 'Pa ', 'Ji ', 'Pan ', 'Gui ', 'Xiao ', 'Qian ', 'Qian ', 'Xi ', 'Lu ', 'Xi ',
+'Xuan ', 'Dun ', 'Huang ', 'Min ', 'Run ', 'Su ', 'Liao ', 'Zhen ', 'Zhong ', 'Yi ', 'Di ', 'Wan ', 'Dan ', 'Tan ', 'Chao ', 'Xun ',
+'Kui ', 'Yie ', 'Shao ', 'Tu ', 'Zhu ', 'San ', 'Hei ', 'Bi ', 'Shan ', 'Chan ', 'Chan ', 'Shu ', 'Tong ', 'Pu ', 'Lin ', 'Wei ',
+'Se ', 'Se ', 'Cheng ', 'Jiong ', 'Cheng ', 'Hua ', 'Jiao ', 'Lao ', 'Che ', 'Gan ', 'Cun ', 'Heng ', 'Si ', 'Shu ', 'Peng ', 'Han ',
+'Yun ', 'Liu ', 'Hong ', 'Fu ', 'Hao ', 'He ', 'Xian ', 'Jian ', 'Shan ', 'Xi ', 'Oki ', '[?]', 'Lan ', '[?]', 'Yu ', 'Lin ',
+'Min ', 'Zao ', 'Dang ', 'Wan ', 'Ze ', 'Xie ', 'Yu ', 'Li ', 'Shi ', 'Xue ', 'Ling ', 'Man ', 'Zi ', 'Yong ', 'Kuai ', 'Can ',
+'Lian ', 'Dian ', 'Ye ', 'Ao ', 'Huan ', 'Zhen ', 'Chan ', 'Man ', 'Dan ', 'Dan ', 'Yi ', 'Sui ', 'Pi ', 'Ju ', 'Ta ', 'Qin ',
+'Ji ', 'Zhuo ', 'Lian ', 'Nong ', 'Guo ', 'Jin ', 'Fen ', 'Se ', 'Ji ', 'Sui ', 'Hui ', 'Chu ', 'Ta ', 'Song ', 'Ding ', '[?]',
+'Zhu ', 'Lai ', 'Bin ', 'Lian ', 'Mi ', 'Shi ', 'Shu ', 'Mi ', 'Ning ', 'Ying ', 'Ying ', 'Meng ', 'Jin ', 'Qi ', 'Pi ', 'Ji ',
+'Hao ', 'Ru ', 'Zui ', 'Wo ', 'Tao ', 'Yin ', 'Yin ', 'Dui ', 'Ci ', 'Huo ', 'Jing ', 'Lan ', 'Jun ', 'Ai ', 'Pu ', 'Zhuo ',
+'Wei ', 'Bin ', 'Gu ', 'Qian ', 'Xing ', 'Hama ', 'Kuo ', 'Fei ', '[?]', 'Boku ', 'Jian ', 'Wei ', 'Luo ', 'Zan ', 'Lu ', 'Li ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x70.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x70.php
new file mode 100644 (file)
index 0000000..87ea68a
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x70] = array(
+'You ', 'Yang ', 'Lu ', 'Si ', 'Jie ', 'Ying ', 'Du ', 'Wang ', 'Hui ', 'Xie ', 'Pan ', 'Shen ', 'Biao ', 'Chan ', 'Mo ', 'Liu ',
+'Jian ', 'Pu ', 'Se ', 'Cheng ', 'Gu ', 'Bin ', 'Huo ', 'Xian ', 'Lu ', 'Qin ', 'Han ', 'Ying ', 'Yong ', 'Li ', 'Jing ', 'Xiao ',
+'Ying ', 'Sui ', 'Wei ', 'Xie ', 'Huai ', 'Hao ', 'Zhu ', 'Long ', 'Lai ', 'Dui ', 'Fan ', 'Hu ', 'Lai ', '[?]', '[?]', 'Ying ',
+'Mi ', 'Ji ', 'Lian ', 'Jian ', 'Ying ', 'Fen ', 'Lin ', 'Yi ', 'Jian ', 'Yue ', 'Chan ', 'Dai ', 'Rang ', 'Jian ', 'Lan ', 'Fan ',
+'Shuang ', 'Yuan ', 'Zhuo ', 'Feng ', 'She ', 'Lei ', 'Lan ', 'Cong ', 'Qu ', 'Yong ', 'Qian ', 'Fa ', 'Guan ', 'Que ', 'Yan ', 'Hao ',
+'Hyeng ', 'Sa ', 'Zan ', 'Luan ', 'Yan ', 'Li ', 'Mi ', 'Shan ', 'Tan ', 'Dang ', 'Jiao ', 'Chan ', '[?]', 'Hao ', 'Ba ', 'Zhu ',
+'Lan ', 'Lan ', 'Nang ', 'Wan ', 'Luan ', 'Xun ', 'Xian ', 'Yan ', 'Gan ', 'Yan ', 'Yu ', 'Huo ', 'Si ', 'Mie ', 'Guang ', 'Deng ',
+'Hui ', 'Xiao ', 'Xiao ', 'Hu ', 'Hong ', 'Ling ', 'Zao ', 'Zhuan ', 'Jiu ', 'Zha ', 'Xie ', 'Chi ', 'Zhuo ', 'Zai ', 'Zai ', 'Can ',
+'Yang ', 'Qi ', 'Zhong ', 'Fen ', 'Niu ', 'Jiong ', 'Wen ', 'Po ', 'Yi ', 'Lu ', 'Chui ', 'Pi ', 'Kai ', 'Pan ', 'Yan ', 'Kai ',
+'Pang ', 'Mu ', 'Chao ', 'Liao ', 'Gui ', 'Kang ', 'Tun ', 'Guang ', 'Xin ', 'Zhi ', 'Guang ', 'Guang ', 'Wei ', 'Qiang ', '[?]', 'Da ',
+'Xia ', 'Zheng ', 'Zhu ', 'Ke ', 'Zhao ', 'Fu ', 'Ba ', 'Duo ', 'Duo ', 'Ling ', 'Zhuo ', 'Xuan ', 'Ju ', 'Tan ', 'Pao ', 'Jiong ',
+'Pao ', 'Tai ', 'Tai ', 'Bing ', 'Yang ', 'Tong ', 'Han ', 'Zhu ', 'Zha ', 'Dian ', 'Wei ', 'Shi ', 'Lian ', 'Chi ', 'Huang ', '[?]',
+'Hu ', 'Shuo ', 'Lan ', 'Jing ', 'Jiao ', 'Xu ', 'Xing ', 'Quan ', 'Lie ', 'Huan ', 'Yang ', 'Xiao ', 'Xiu ', 'Xian ', 'Yin ', 'Wu ',
+'Zhou ', 'Yao ', 'Shi ', 'Wei ', 'Tong ', 'Xue ', 'Zai ', 'Kai ', 'Hong ', 'Luo ', 'Xia ', 'Zhu ', 'Xuan ', 'Zheng ', 'Po ', 'Yan ',
+'Hui ', 'Guang ', 'Zhe ', 'Hui ', 'Kao ', '[?]', 'Fan ', 'Shao ', 'Ye ', 'Hui ', '[?]', 'Tang ', 'Jin ', 'Re ', '[?]', 'Xi ',
+'Fu ', 'Jiong ', 'Che ', 'Pu ', 'Jing ', 'Zhuo ', 'Ting ', 'Wan ', 'Hai ', 'Peng ', 'Lang ', 'Shan ', 'Hu ', 'Feng ', 'Chi ', 'Rong ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x71.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x71.php
new file mode 100644 (file)
index 0000000..77e5766
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x71] = array(
+'Hu ', 'Xi ', 'Shu ', 'He ', 'Xun ', 'Ku ', 'Jue ', 'Xiao ', 'Xi ', 'Yan ', 'Han ', 'Zhuang ', 'Jun ', 'Di ', 'Xie ', 'Ji ',
+'Wu ', '[?]', '[?]', 'Han ', 'Yan ', 'Huan ', 'Men ', 'Ju ', 'Chou ', 'Bei ', 'Fen ', 'Lin ', 'Kun ', 'Hun ', 'Tun ', 'Xi ',
+'Cui ', 'Wu ', 'Hong ', 'Ju ', 'Fu ', 'Wo ', 'Jiao ', 'Cong ', 'Feng ', 'Ping ', 'Qiong ', 'Ruo ', 'Xi ', 'Qiong ', 'Xin ', 'Zhuo ',
+'Yan ', 'Yan ', 'Yi ', 'Jue ', 'Yu ', 'Gang ', 'Ran ', 'Pi ', 'Gu ', '[?]', 'Sheng ', 'Chang ', 'Shao ', '[?]', '[?]', '[?]',
+'[?]', 'Chen ', 'He ', 'Kui ', 'Zhong ', 'Duan ', 'Xia ', 'Hui ', 'Feng ', 'Lian ', 'Xuan ', 'Xing ', 'Huang ', 'Jiao ', 'Jian ', 'Bi ',
+'Ying ', 'Zhu ', 'Wei ', 'Tuan ', 'Tian ', 'Xi ', 'Nuan ', 'Nuan ', 'Chan ', 'Yan ', 'Jiong ', 'Jiong ', 'Yu ', 'Mei ', 'Sha ', 'Wei ',
+'Ye ', 'Xin ', 'Qiong ', 'Rou ', 'Mei ', 'Huan ', 'Xu ', 'Zhao ', 'Wei ', 'Fan ', 'Qiu ', 'Sui ', 'Yang ', 'Lie ', 'Zhu ', 'Jie ',
+'Gao ', 'Gua ', 'Bao ', 'Hu ', 'Yun ', 'Xia ', '[?]', '[?]', 'Bian ', 'Gou ', 'Tui ', 'Tang ', 'Chao ', 'Shan ', 'N ', 'Bo ',
+'Huang ', 'Xie ', 'Xi ', 'Wu ', 'Xi ', 'Yun ', 'He ', 'He ', 'Xi ', 'Yun ', 'Xiong ', 'Nai ', 'Shan ', 'Qiong ', 'Yao ', 'Xun ',
+'Mi ', 'Lian ', 'Ying ', 'Wen ', 'Rong ', 'Oozutsu ', '[?]', 'Qiang ', 'Liu ', 'Xi ', 'Bi ', 'Biao ', 'Zong ', 'Lu ', 'Jian ', 'Shou ',
+'Yi ', 'Lou ', 'Feng ', 'Sui ', 'Yi ', 'Tong ', 'Jue ', 'Zong ', 'Yun ', 'Hu ', 'Yi ', 'Zhi ', 'Ao ', 'Wei ', 'Liao ', 'Han ',
+'Ou ', 'Re ', 'Jiong ', 'Man ', '[?]', 'Shang ', 'Cuan ', 'Zeng ', 'Jian ', 'Xi ', 'Xi ', 'Xi ', 'Yi ', 'Xiao ', 'Chi ', 'Huang ',
+'Chan ', 'Ye ', 'Qian ', 'Ran ', 'Yan ', 'Xian ', 'Qiao ', 'Zun ', 'Deng ', 'Dun ', 'Shen ', 'Jiao ', 'Fen ', 'Si ', 'Liao ', 'Yu ',
+'Lin ', 'Tong ', 'Shao ', 'Fen ', 'Fan ', 'Yan ', 'Xun ', 'Lan ', 'Mei ', 'Tang ', 'Yi ', 'Jing ', 'Men ', '[?]', '[?]', 'Ying ',
+'Yu ', 'Yi ', 'Xue ', 'Lan ', 'Tai ', 'Zao ', 'Can ', 'Sui ', 'Xi ', 'Que ', 'Cong ', 'Lian ', 'Hui ', 'Zhu ', 'Xie ', 'Ling ',
+'Wei ', 'Yi ', 'Xie ', 'Zhao ', 'Hui ', 'Tatsu ', 'Nung ', 'Lan ', 'Ru ', 'Xian ', 'Kao ', 'Xun ', 'Jin ', 'Chou ', 'Chou ', 'Yao ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x72.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x72.php
new file mode 100644 (file)
index 0000000..d279fa2
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x72] = array(
+'He ', 'Lan ', 'Biao ', 'Rong ', 'Li ', 'Mo ', 'Bao ', 'Ruo ', 'Lu ', 'La ', 'Ao ', 'Xun ', 'Kuang ', 'Shuo ', '[?]', 'Li ',
+'Lu ', 'Jue ', 'Liao ', 'Yan ', 'Xi ', 'Xie ', 'Long ', 'Ye ', '[?]', 'Rang ', 'Yue ', 'Lan ', 'Cong ', 'Jue ', 'Tong ', 'Guan ',
+'[?]', 'Che ', 'Mi ', 'Tang ', 'Lan ', 'Zhu ', '[?]', 'Ling ', 'Cuan ', 'Yu ', 'Zhua ', 'Tsumekanmuri ', 'Pa ', 'Zheng ', 'Pao ', 'Cheng ',
+'Yuan ', 'Ai ', 'Wei ', '[?]', 'Jue ', 'Jue ', 'Fu ', 'Ye ', 'Ba ', 'Die ', 'Ye ', 'Yao ', 'Zu ', 'Shuang ', 'Er ', 'Qiang ',
+'Chuang ', 'Ge ', 'Zang ', 'Die ', 'Qiang ', 'Yong ', 'Qiang ', 'Pian ', 'Ban ', 'Pan ', 'Shao ', 'Jian ', 'Pai ', 'Du ', 'Chuang ', 'Tou ',
+'Zha ', 'Bian ', 'Die ', 'Bang ', 'Bo ', 'Chuang ', 'You ', '[?]', 'Du ', 'Ya ', 'Cheng ', 'Niu ', 'Ushihen ', 'Pin ', 'Jiu ', 'Mou ',
+'Tuo ', 'Mu ', 'Lao ', 'Ren ', 'Mang ', 'Fang ', 'Mao ', 'Mu ', 'Gang ', 'Wu ', 'Yan ', 'Ge ', 'Bei ', 'Si ', 'Jian ', 'Gu ',
+'You ', 'Ge ', 'Sheng ', 'Mu ', 'Di ', 'Qian ', 'Quan ', 'Quan ', 'Zi ', 'Te ', 'Xi ', 'Mang ', 'Keng ', 'Qian ', 'Wu ', 'Gu ',
+'Xi ', 'Li ', 'Li ', 'Pou ', 'Ji ', 'Gang ', 'Zhi ', 'Ben ', 'Quan ', 'Run ', 'Du ', 'Ju ', 'Jia ', 'Jian ', 'Feng ', 'Pian ',
+'Ke ', 'Ju ', 'Kao ', 'Chu ', 'Xi ', 'Bei ', 'Luo ', 'Jie ', 'Ma ', 'San ', 'Wei ', 'Li ', 'Dun ', 'Tong ', '[?]', 'Jiang ',
+'Ikenie ', 'Li ', 'Du ', 'Lie ', 'Pi ', 'Piao ', 'Bao ', 'Xi ', 'Chou ', 'Wei ', 'Kui ', 'Chou ', 'Quan ', 'Fan ', 'Ba ', 'Fan ',
+'Qiu ', 'Ji ', 'Cai ', 'Chuo ', 'An ', 'Jie ', 'Zhuang ', 'Guang ', 'Ma ', 'You ', 'Kang ', 'Bo ', 'Hou ', 'Ya ', 'Yin ', 'Huan ',
+'Zhuang ', 'Yun ', 'Kuang ', 'Niu ', 'Di ', 'Qing ', 'Zhong ', 'Mu ', 'Bei ', 'Pi ', 'Ju ', 'Ni ', 'Sheng ', 'Pao ', 'Xia ', 'Tuo ',
+'Hu ', 'Ling ', 'Fei ', 'Pi ', 'Ni ', 'Ao ', 'You ', 'Gou ', 'Yue ', 'Ju ', 'Dan ', 'Po ', 'Gu ', 'Xian ', 'Ning ', 'Huan ',
+'Hen ', 'Jiao ', 'He ', 'Zhao ', 'Ji ', 'Xun ', 'Shan ', 'Ta ', 'Rong ', 'Shou ', 'Tong ', 'Lao ', 'Du ', 'Xia ', 'Shi ', 'Hua ',
+'Zheng ', 'Yu ', 'Sun ', 'Yu ', 'Bi ', 'Mang ', 'Xi ', 'Juan ', 'Li ', 'Xia ', 'Yin ', 'Suan ', 'Lang ', 'Bei ', 'Zhi ', 'Yan ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x73.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x73.php
new file mode 100644 (file)
index 0000000..9219abc
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x73] = array(
+'Sha ', 'Li ', 'Han ', 'Xian ', 'Jing ', 'Pai ', 'Fei ', 'Yao ', 'Ba ', 'Qi ', 'Ni ', 'Biao ', 'Yin ', 'Lai ', 'Xi ', 'Jian ',
+'Qiang ', 'Kun ', 'Yan ', 'Guo ', 'Zong ', 'Mi ', 'Chang ', 'Yi ', 'Zhi ', 'Zheng ', 'Ya ', 'Meng ', 'Cai ', 'Cu ', 'She ', 'Kari ',
+'Cen ', 'Luo ', 'Hu ', 'Zong ', 'Ji ', 'Wei ', 'Feng ', 'Wo ', 'Yuan ', 'Xing ', 'Zhu ', 'Mao ', 'Wei ', 'Yuan ', 'Xian ', 'Tuan ',
+'Ya ', 'Nao ', 'Xie ', 'Jia ', 'Hou ', 'Bian ', 'You ', 'You ', 'Mei ', 'Zha ', 'Yao ', 'Sun ', 'Bo ', 'Ming ', 'Hua ', 'Yuan ',
+'Sou ', 'Ma ', 'Yuan ', 'Dai ', 'Yu ', 'Shi ', 'Hao ', '[?]', 'Yi ', 'Zhen ', 'Chuang ', 'Hao ', 'Man ', 'Jing ', 'Jiang ', 'Mu ',
+'Zhang ', 'Chan ', 'Ao ', 'Ao ', 'Hao ', 'Cui ', 'Fen ', 'Jue ', 'Bi ', 'Bi ', 'Huang ', 'Pu ', 'Lin ', 'Yu ', 'Tong ', 'Yao ',
+'Liao ', 'Shuo ', 'Xiao ', 'Swu ', 'Ton ', 'Xi ', 'Ge ', 'Juan ', 'Du ', 'Hui ', 'Kuai ', 'Xian ', 'Xie ', 'Ta ', 'Xian ', 'Xun ',
+'Ning ', 'Pin ', 'Huo ', 'Nou ', 'Meng ', 'Lie ', 'Nao ', 'Guang ', 'Shou ', 'Lu ', 'Ta ', 'Xian ', 'Mi ', 'Rang ', 'Huan ', 'Nao ',
+'Luo ', 'Xian ', 'Qi ', 'Jue ', 'Xuan ', 'Miao ', 'Zi ', 'Lu ', 'Lu ', 'Yu ', 'Su ', 'Wang ', 'Qiu ', 'Ga ', 'Ding ', 'Le ',
+'Ba ', 'Ji ', 'Hong ', 'Di ', 'Quan ', 'Gan ', 'Jiu ', 'Yu ', 'Ji ', 'Yu ', 'Yang ', 'Ma ', 'Gong ', 'Wu ', 'Fu ', 'Wen ',
+'Jie ', 'Ya ', 'Fen ', 'Bian ', 'Beng ', 'Yue ', 'Jue ', 'Yun ', 'Jue ', 'Wan ', 'Jian ', 'Mei ', 'Dan ', 'Pi ', 'Wei ', 'Huan ',
+'Xian ', 'Qiang ', 'Ling ', 'Dai ', 'Yi ', 'An ', 'Ping ', 'Dian ', 'Fu ', 'Xuan ', 'Xi ', 'Bo ', 'Ci ', 'Gou ', 'Jia ', 'Shao ',
+'Po ', 'Ci ', 'Ke ', 'Ran ', 'Sheng ', 'Shen ', 'Yi ', 'Zu ', 'Jia ', 'Min ', 'Shan ', 'Liu ', 'Bi ', 'Zhen ', 'Zhen ', 'Jue ',
+'Fa ', 'Long ', 'Jin ', 'Jiao ', 'Jian ', 'Li ', 'Guang ', 'Xian ', 'Zhou ', 'Gong ', 'Yan ', 'Xiu ', 'Yang ', 'Xu ', 'Luo ', 'Su ',
+'Zhu ', 'Qin ', 'Ken ', 'Xun ', 'Bao ', 'Er ', 'Xiang ', 'Yao ', 'Xia ', 'Heng ', 'Gui ', 'Chong ', 'Xu ', 'Ban ', 'Pei ', '[?]',
+'Dang ', 'Ei ', 'Hun ', 'Wen ', 'E ', 'Cheng ', 'Ti ', 'Wu ', 'Wu ', 'Cheng ', 'Jun ', 'Mei ', 'Bei ', 'Ting ', 'Xian ', 'Chuo ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x74.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x74.php
new file mode 100644 (file)
index 0000000..288aec1
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x74] = array(
+'Han ', 'Xuan ', 'Yan ', 'Qiu ', 'Quan ', 'Lang ', 'Li ', 'Xiu ', 'Fu ', 'Liu ', 'Ye ', 'Xi ', 'Ling ', 'Li ', 'Jin ', 'Lian ',
+'Suo ', 'Chiisai ', '[?]', 'Wan ', 'Dian ', 'Pin ', 'Zhan ', 'Cui ', 'Min ', 'Yu ', 'Ju ', 'Chen ', 'Lai ', 'Wen ', 'Sheng ', 'Wei ',
+'Dian ', 'Chu ', 'Zhuo ', 'Pei ', 'Cheng ', 'Hu ', 'Qi ', 'E ', 'Kun ', 'Chang ', 'Qi ', 'Beng ', 'Wan ', 'Lu ', 'Cong ', 'Guan ',
+'Yan ', 'Diao ', 'Bei ', 'Lin ', 'Qin ', 'Pi ', 'Pa ', 'Que ', 'Zhuo ', 'Qin ', 'Fa ', '[?]', 'Qiong ', 'Du ', 'Jie ', 'Hun ',
+'Yu ', 'Mao ', 'Mei ', 'Chun ', 'Xuan ', 'Ti ', 'Xing ', 'Dai ', 'Rou ', 'Min ', 'Zhen ', 'Wei ', 'Ruan ', 'Huan ', 'Jie ', 'Chuan ',
+'Jian ', 'Zhuan ', 'Yang ', 'Lian ', 'Quan ', 'Xia ', 'Duan ', 'Yuan ', 'Ye ', 'Nao ', 'Hu ', 'Ying ', 'Yu ', 'Huang ', 'Rui ', 'Se ',
+'Liu ', 'Shi ', 'Rong ', 'Suo ', 'Yao ', 'Wen ', 'Wu ', 'Jin ', 'Jin ', 'Ying ', 'Ma ', 'Tao ', 'Liu ', 'Tang ', 'Li ', 'Lang ',
+'Gui ', 'Zhen ', 'Qiang ', 'Cuo ', 'Jue ', 'Zhao ', 'Yao ', 'Ai ', 'Bin ', 'Tu ', 'Chang ', 'Kun ', 'Zhuan ', 'Cong ', 'Jin ', 'Yi ',
+'Cui ', 'Cong ', 'Qi ', 'Li ', 'Ying ', 'Suo ', 'Qiu ', 'Xuan ', 'Ao ', 'Lian ', 'Man ', 'Zhang ', 'Yin ', '[?]', 'Ying ', 'Zhi ',
+'Lu ', 'Wu ', 'Deng ', 'Xiou ', 'Zeng ', 'Xun ', 'Qu ', 'Dang ', 'Lin ', 'Liao ', 'Qiong ', 'Su ', 'Huang ', 'Gui ', 'Pu ', 'Jing ',
+'Fan ', 'Jin ', 'Liu ', 'Ji ', '[?]', 'Jing ', 'Ai ', 'Bi ', 'Can ', 'Qu ', 'Zao ', 'Dang ', 'Jiao ', 'Gun ', 'Tan ', 'Hui ',
+'Huan ', 'Se ', 'Sui ', 'Tian ', '[?]', 'Yu ', 'Jin ', 'Lu ', 'Bin ', 'Shou ', 'Wen ', 'Zui ', 'Lan ', 'Xi ', 'Ji ', 'Xuan ',
+'Ruan ', 'Huo ', 'Gai ', 'Lei ', 'Du ', 'Li ', 'Zhi ', 'Rou ', 'Li ', 'Zan ', 'Qiong ', 'Zhe ', 'Gui ', 'Sui ', 'La ', 'Long ',
+'Lu ', 'Li ', 'Zan ', 'Lan ', 'Ying ', 'Mi ', 'Xiang ', 'Xi ', 'Guan ', 'Dao ', 'Zan ', 'Huan ', 'Gua ', 'Bo ', 'Die ', 'Bao ',
+'Hu ', 'Zhi ', 'Piao ', 'Ban ', 'Rang ', 'Li ', 'Wa ', 'Dekaguramu ', 'Jiang ', 'Qian ', 'Fan ', 'Pen ', 'Fang ', 'Dan ', 'Weng ', 'Ou ',
+'Deshiguramu ', 'Miriguramu ', 'Thon ', 'Hu ', 'Ling ', 'Yi ', 'Ping ', 'Ci ', 'Hekutogura ', 'Juan ', 'Chang ', 'Chi ', 'Sarake ', 'Dang ', 'Meng ', 'Pou ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x75.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x75.php
new file mode 100644 (file)
index 0000000..b13b4a3
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x75] = array(
+'Zhui ', 'Ping ', 'Bian ', 'Zhou ', 'Zhen ', 'Senchigura ', 'Ci ', 'Ying ', 'Qi ', 'Xian ', 'Lou ', 'Di ', 'Ou ', 'Meng ', 'Zhuan ', 'Peng ',
+'Lin ', 'Zeng ', 'Wu ', 'Pi ', 'Dan ', 'Weng ', 'Ying ', 'Yan ', 'Gan ', 'Dai ', 'Shen ', 'Tian ', 'Tian ', 'Han ', 'Chang ', 'Sheng ',
+'Qing ', 'Sheng ', 'Chan ', 'Chan ', 'Rui ', 'Sheng ', 'Su ', 'Sen ', 'Yong ', 'Shuai ', 'Lu ', 'Fu ', 'Yong ', 'Beng ', 'Feng ', 'Ning ',
+'Tian ', 'You ', 'Jia ', 'Shen ', 'Zha ', 'Dian ', 'Fu ', 'Nan ', 'Dian ', 'Ping ', 'Ting ', 'Hua ', 'Ting ', 'Quan ', 'Zi ', 'Meng ',
+'Bi ', 'Qi ', 'Liu ', 'Xun ', 'Liu ', 'Chang ', 'Mu ', 'Yun ', 'Fan ', 'Fu ', 'Geng ', 'Tian ', 'Jie ', 'Jie ', 'Quan ', 'Wei ',
+'Fu ', 'Tian ', 'Mu ', 'Tap ', 'Pan ', 'Jiang ', 'Wa ', 'Da ', 'Nan ', 'Liu ', 'Ben ', 'Zhen ', 'Chu ', 'Mu ', 'Mu ', 'Ce ',
+'Cen ', 'Gai ', 'Bi ', 'Da ', 'Zhi ', 'Lue ', 'Qi ', 'Lue ', 'Pan ', 'Kesa ', 'Fan ', 'Hua ', 'Yu ', 'Yu ', 'Mu ', 'Jun ',
+'Yi ', 'Liu ', 'Yu ', 'Die ', 'Chou ', 'Hua ', 'Dang ', 'Chuo ', 'Ji ', 'Wan ', 'Jiang ', 'Sheng ', 'Chang ', 'Tuan ', 'Lei ', 'Ji ',
+'Cha ', 'Liu ', 'Tatamu ', 'Tuan ', 'Lin ', 'Jiang ', 'Jiang ', 'Chou ', 'Bo ', 'Die ', 'Die ', 'Pi ', 'Nie ', 'Dan ', 'Shu ', 'Shu ',
+'Zhi ', 'Yi ', 'Chuang ', 'Nai ', 'Ding ', 'Bi ', 'Jie ', 'Liao ', 'Gong ', 'Ge ', 'Jiu ', 'Zhou ', 'Xia ', 'Shan ', 'Xu ', 'Nue ',
+'Li ', 'Yang ', 'Chen ', 'You ', 'Ba ', 'Jie ', 'Jue ', 'Zhi ', 'Xia ', 'Cui ', 'Bi ', 'Yi ', 'Li ', 'Zong ', 'Chuang ', 'Feng ',
+'Zhu ', 'Pao ', 'Pi ', 'Gan ', 'Ke ', 'Ci ', 'Xie ', 'Qi ', 'Dan ', 'Zhen ', 'Fa ', 'Zhi ', 'Teng ', 'Ju ', 'Ji ', 'Fei ',
+'Qu ', 'Dian ', 'Jia ', 'Xian ', 'Cha ', 'Bing ', 'Ni ', 'Zheng ', 'Yong ', 'Jing ', 'Quan ', 'Chong ', 'Tong ', 'Yi ', 'Kai ', 'Wei ',
+'Hui ', 'Duo ', 'Yang ', 'Chi ', 'Zhi ', 'Hen ', 'Ya ', 'Mei ', 'Dou ', 'Jing ', 'Xiao ', 'Tong ', 'Tu ', 'Mang ', 'Pi ', 'Xiao ',
+'Suan ', 'Pu ', 'Li ', 'Zhi ', 'Cuo ', 'Duo ', 'Wu ', 'Sha ', 'Lao ', 'Shou ', 'Huan ', 'Xian ', 'Yi ', 'Peng ', 'Zhang ', 'Guan ',
+'Tan ', 'Fei ', 'Ma ', 'Lin ', 'Chi ', 'Ji ', 'Dian ', 'An ', 'Chi ', 'Bi ', 'Bei ', 'Min ', 'Gu ', 'Dui ', 'E ', 'Wei ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x76.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x76.php
new file mode 100644 (file)
index 0000000..6a8178f
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x76] = array(
+'Yu ', 'Cui ', 'Ya ', 'Zhu ', 'Cu ', 'Dan ', 'Shen ', 'Zhung ', 'Ji ', 'Yu ', 'Hou ', 'Feng ', 'La ', 'Yang ', 'Shen ', 'Tu ',
+'Yu ', 'Gua ', 'Wen ', 'Huan ', 'Ku ', 'Jia ', 'Yin ', 'Yi ', 'Lu ', 'Sao ', 'Jue ', 'Chi ', 'Xi ', 'Guan ', 'Yi ', 'Wen ',
+'Ji ', 'Chuang ', 'Ban ', 'Lei ', 'Liu ', 'Chai ', 'Shou ', 'Nue ', 'Dian ', 'Da ', 'Pie ', 'Tan ', 'Zhang ', 'Biao ', 'Shen ', 'Cu ',
+'Luo ', 'Yi ', 'Zong ', 'Chou ', 'Zhang ', 'Zhai ', 'Sou ', 'Suo ', 'Que ', 'Diao ', 'Lou ', 'Lu ', 'Mo ', 'Jin ', 'Yin ', 'Ying ',
+'Huang ', 'Fu ', 'Liao ', 'Long ', 'Qiao ', 'Liu ', 'Lao ', 'Xian ', 'Fei ', 'Dan ', 'Yin ', 'He ', 'Yan ', 'Ban ', 'Xian ', 'Guan ',
+'Guai ', 'Nong ', 'Yu ', 'Wei ', 'Yi ', 'Yong ', 'Pi ', 'Lei ', 'Li ', 'Shu ', 'Dan ', 'Lin ', 'Dian ', 'Lin ', 'Lai ', 'Pie ',
+'Ji ', 'Chi ', 'Yang ', 'Xian ', 'Jie ', 'Zheng ', '[?]', 'Li ', 'Huo ', 'Lai ', 'Shaku ', 'Dian ', 'Xian ', 'Ying ', 'Yin ', 'Qu ',
+'Yong ', 'Tan ', 'Dian ', 'Luo ', 'Luan ', 'Luan ', 'Bo ', '[?]', 'Gui ', 'Po ', 'Fa ', 'Deng ', 'Fa ', 'Bai ', 'Bai ', 'Qie ',
+'Bi ', 'Zao ', 'Zao ', 'Mao ', 'De ', 'Pa ', 'Jie ', 'Huang ', 'Gui ', 'Ci ', 'Ling ', 'Gao ', 'Mo ', 'Ji ', 'Jiao ', 'Peng ',
+'Gao ', 'Ai ', 'E ', 'Hao ', 'Han ', 'Bi ', 'Wan ', 'Chou ', 'Qian ', 'Xi ', 'Ai ', 'Jiong ', 'Hao ', 'Huang ', 'Hao ', 'Ze ',
+'Cui ', 'Hao ', 'Xiao ', 'Ye ', 'Po ', 'Hao ', 'Jiao ', 'Ai ', 'Xing ', 'Huang ', 'Li ', 'Piao ', 'He ', 'Jiao ', 'Pi ', 'Gan ',
+'Pao ', 'Zhou ', 'Jun ', 'Qiu ', 'Cun ', 'Que ', 'Zha ', 'Gu ', 'Jun ', 'Jun ', 'Zhou ', 'Zha ', 'Gu ', 'Zhan ', 'Du ', 'Min ',
+'Qi ', 'Ying ', 'Yu ', 'Bei ', 'Zhao ', 'Zhong ', 'Pen ', 'He ', 'Ying ', 'He ', 'Yi ', 'Bo ', 'Wan ', 'He ', 'Ang ', 'Zhan ',
+'Yan ', 'Jian ', 'He ', 'Yu ', 'Kui ', 'Fan ', 'Gai ', 'Dao ', 'Pan ', 'Fu ', 'Qiu ', 'Sheng ', 'Dao ', 'Lu ', 'Zhan ', 'Meng ',
+'Li ', 'Jin ', 'Xu ', 'Jian ', 'Pan ', 'Guan ', 'An ', 'Lu ', 'Shu ', 'Zhou ', 'Dang ', 'An ', 'Gu ', 'Li ', 'Mu ', 'Cheng ',
+'Gan ', 'Xu ', 'Mang ', 'Mang ', 'Zhi ', 'Qi ', 'Ruan ', 'Tian ', 'Xiang ', 'Dun ', 'Xin ', 'Xi ', 'Pan ', 'Feng ', 'Dun ', 'Min ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x77.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x77.php
new file mode 100644 (file)
index 0000000..d5dc1dd
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x77] = array(
+'Ming ', 'Sheng ', 'Shi ', 'Yun ', 'Mian ', 'Pan ', 'Fang ', 'Miao ', 'Dan ', 'Mei ', 'Mao ', 'Kan ', 'Xian ', 'Ou ', 'Shi ', 'Yang ',
+'Zheng ', 'Yao ', 'Shen ', 'Huo ', 'Da ', 'Zhen ', 'Kuang ', 'Ju ', 'Shen ', 'Chi ', 'Sheng ', 'Mei ', 'Mo ', 'Zhu ', 'Zhen ', 'Zhen ',
+'Mian ', 'Di ', 'Yuan ', 'Die ', 'Yi ', 'Zi ', 'Zi ', 'Chao ', 'Zha ', 'Xuan ', 'Bing ', 'Mi ', 'Long ', 'Sui ', 'Dong ', 'Mi ',
+'Die ', 'Yi ', 'Er ', 'Ming ', 'Xuan ', 'Chi ', 'Kuang ', 'Juan ', 'Mou ', 'Zhen ', 'Tiao ', 'Yang ', 'Yan ', 'Mo ', 'Zhong ', 'Mai ',
+'Zhao ', 'Zheng ', 'Mei ', 'Jun ', 'Shao ', 'Han ', 'Huan ', 'Di ', 'Cheng ', 'Cuo ', 'Juan ', 'E ', 'Wan ', 'Xian ', 'Xi ', 'Kun ',
+'Lai ', 'Jian ', 'Shan ', 'Tian ', 'Hun ', 'Wan ', 'Ling ', 'Shi ', 'Qiong ', 'Lie ', 'Yai ', 'Jing ', 'Zheng ', 'Li ', 'Lai ', 'Sui ',
+'Juan ', 'Shui ', 'Sui ', 'Du ', 'Bi ', 'Bi ', 'Mu ', 'Hun ', 'Ni ', 'Lu ', 'Yi ', 'Jie ', 'Cai ', 'Zhou ', 'Yu ', 'Hun ',
+'Ma ', 'Xia ', 'Xing ', 'Xi ', 'Gun ', 'Cai ', 'Chun ', 'Jian ', 'Mei ', 'Du ', 'Hou ', 'Xuan ', 'Ti ', 'Kui ', 'Gao ', 'Rui ',
+'Mou ', 'Xu ', 'Fa ', 'Wen ', 'Miao ', 'Chou ', 'Kui ', 'Mi ', 'Weng ', 'Kou ', 'Dang ', 'Chen ', 'Ke ', 'Sou ', 'Xia ', 'Qiong ',
+'Mao ', 'Ming ', 'Man ', 'Shui ', 'Ze ', 'Zhang ', 'Yi ', 'Diao ', 'Ou ', 'Mo ', 'Shun ', 'Cong ', 'Lou ', 'Chi ', 'Man ', 'Piao ',
+'Cheng ', 'Ji ', 'Meng ', '[?]', 'Run ', 'Pie ', 'Xi ', 'Qiao ', 'Pu ', 'Zhu ', 'Deng ', 'Shen ', 'Shun ', 'Liao ', 'Che ', 'Xian ',
+'Kan ', 'Ye ', 'Xu ', 'Tong ', 'Mou ', 'Lin ', 'Kui ', 'Xian ', 'Ye ', 'Ai ', 'Hui ', 'Zhan ', 'Jian ', 'Gu ', 'Zhao ', 'Qu ',
+'Wei ', 'Chou ', 'Sao ', 'Ning ', 'Xun ', 'Yao ', 'Huo ', 'Meng ', 'Mian ', 'Bin ', 'Mian ', 'Li ', 'Kuang ', 'Jue ', 'Xuan ', 'Mian ',
+'Huo ', 'Lu ', 'Meng ', 'Long ', 'Guan ', 'Man ', 'Xi ', 'Chu ', 'Tang ', 'Kan ', 'Zhu ', 'Mao ', 'Jin ', 'Lin ', 'Yu ', 'Shuo ',
+'Ce ', 'Jue ', 'Shi ', 'Yi ', 'Shen ', 'Zhi ', 'Hou ', 'Shen ', 'Ying ', 'Ju ', 'Zhou ', 'Jiao ', 'Cuo ', 'Duan ', 'Ai ', 'Jiao ',
+'Zeng ', 'Huo ', 'Bai ', 'Shi ', 'Ding ', 'Qi ', 'Ji ', 'Zi ', 'Gan ', 'Wu ', 'Tuo ', 'Ku ', 'Qiang ', 'Xi ', 'Fan ', 'Kuang ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x78.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x78.php
new file mode 100644 (file)
index 0000000..93f6072
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x78] = array(
+'Dang ', 'Ma ', 'Sha ', 'Dan ', 'Jue ', 'Li ', 'Fu ', 'Min ', 'Nuo ', 'Huo ', 'Kang ', 'Zhi ', 'Qi ', 'Kan ', 'Jie ', 'Fen ',
+'E ', 'Ya ', 'Pi ', 'Zhe ', 'Yan ', 'Sui ', 'Zhuan ', 'Che ', 'Dun ', 'Pan ', 'Yan ', '[?]', 'Feng ', 'Fa ', 'Mo ', 'Zha ',
+'Qu ', 'Yu ', 'Luo ', 'Tuo ', 'Tuo ', 'Di ', 'Zhai ', 'Zhen ', 'Ai ', 'Fei ', 'Mu ', 'Zhu ', 'Li ', 'Bian ', 'Nu ', 'Ping ',
+'Peng ', 'Ling ', 'Pao ', 'Le ', 'Po ', 'Bo ', 'Po ', 'Shen ', 'Za ', 'Nuo ', 'Li ', 'Long ', 'Tong ', '[?]', 'Li ', 'Aragane ',
+'Chu ', 'Keng ', 'Quan ', 'Zhu ', 'Kuang ', 'Huo ', 'E ', 'Nao ', 'Jia ', 'Lu ', 'Wei ', 'Ai ', 'Luo ', 'Ken ', 'Xing ', 'Yan ',
+'Tong ', 'Peng ', 'Xi ', '[?]', 'Hong ', 'Shuo ', 'Xia ', 'Qiao ', '[?]', 'Wei ', 'Qiao ', '[?]', 'Keng ', 'Xiao ', 'Que ', 'Chan ',
+'Lang ', 'Hong ', 'Yu ', 'Xiao ', 'Xia ', 'Mang ', 'Long ', 'Iong ', 'Che ', 'Che ', 'E ', 'Liu ', 'Ying ', 'Mang ', 'Que ', 'Yan ',
+'Sha ', 'Kun ', 'Yu ', '[?]', 'Kaki ', 'Lu ', 'Chen ', 'Jian ', 'Nue ', 'Song ', 'Zhuo ', 'Keng ', 'Peng ', 'Yan ', 'Zhui ', 'Kong ',
+'Ceng ', 'Qi ', 'Zong ', 'Qing ', 'Lin ', 'Jun ', 'Bo ', 'Ding ', 'Min ', 'Diao ', 'Jian ', 'He ', 'Lu ', 'Ai ', 'Sui ', 'Que ',
+'Ling ', 'Bei ', 'Yin ', 'Dui ', 'Wu ', 'Qi ', 'Lun ', 'Wan ', 'Dian ', 'Gang ', 'Pei ', 'Qi ', 'Chen ', 'Ruan ', 'Yan ', 'Die ',
+'Ding ', 'Du ', 'Tuo ', 'Jie ', 'Ying ', 'Bian ', 'Ke ', 'Bi ', 'Wei ', 'Shuo ', 'Zhen ', 'Duan ', 'Xia ', 'Dang ', 'Ti ', 'Nao ',
+'Peng ', 'Jian ', 'Di ', 'Tan ', 'Cha ', 'Seki ', 'Qi ', '[?]', 'Feng ', 'Xuan ', 'Que ', 'Que ', 'Ma ', 'Gong ', 'Nian ', 'Su ',
+'E ', 'Ci ', 'Liu ', 'Si ', 'Tang ', 'Bang ', 'Hua ', 'Pi ', 'Wei ', 'Sang ', 'Lei ', 'Cuo ', 'Zhen ', 'Xia ', 'Qi ', 'Lian ',
+'Pan ', 'Wei ', 'Yun ', 'Dui ', 'Zhe ', 'Ke ', 'La ', '[?]', 'Qing ', 'Gun ', 'Zhuan ', 'Chan ', 'Qi ', 'Ao ', 'Peng ', 'Lu ',
+'Lu ', 'Kan ', 'Qiang ', 'Chen ', 'Yin ', 'Lei ', 'Biao ', 'Qi ', 'Mo ', 'Qi ', 'Cui ', 'Zong ', 'Qing ', 'Chuo ', '[?]', 'Ji ',
+'Shan ', 'Lao ', 'Qu ', 'Zeng ', 'Deng ', 'Jian ', 'Xi ', 'Lin ', 'Ding ', 'Dian ', 'Huang ', 'Pan ', 'Za ', 'Qiao ', 'Di ', 'Li ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x79.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x79.php
new file mode 100644 (file)
index 0000000..bf392ac
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x79] = array(
+'Tani ', 'Jiao ', '[?]', 'Zhang ', 'Qiao ', 'Dun ', 'Xian ', 'Yu ', 'Zhui ', 'He ', 'Huo ', 'Zhai ', 'Lei ', 'Ke ', 'Chu ', 'Ji ',
+'Que ', 'Dang ', 'Yi ', 'Jiang ', 'Pi ', 'Pi ', 'Yu ', 'Pin ', 'Qi ', 'Ai ', 'Kai ', 'Jian ', 'Yu ', 'Ruan ', 'Meng ', 'Pao ',
+'Ci ', '[?]', '[?]', 'Mie ', 'Ca ', 'Xian ', 'Kuang ', 'Lei ', 'Lei ', 'Zhi ', 'Li ', 'Li ', 'Fan ', 'Que ', 'Pao ', 'Ying ',
+'Li ', 'Long ', 'Long ', 'Mo ', 'Bo ', 'Shuang ', 'Guan ', 'Lan ', 'Zan ', 'Yan ', 'Shi ', 'Shi ', 'Li ', 'Reng ', 'She ', 'Yue ',
+'Si ', 'Qi ', 'Ta ', 'Ma ', 'Xie ', 'Xian ', 'Xian ', 'Zhi ', 'Qi ', 'Zhi ', 'Beng ', 'Dui ', 'Zhong ', '[?]', 'Yi ', 'Shi ',
+'You ', 'Zhi ', 'Tiao ', 'Fu ', 'Fu ', 'Mi ', 'Zu ', 'Zhi ', 'Suan ', 'Mei ', 'Zuo ', 'Qu ', 'Hu ', 'Zhu ', 'Shen ', 'Sui ',
+'Ci ', 'Chai ', 'Mi ', 'Lu ', 'Yu ', 'Xiang ', 'Wu ', 'Tiao ', 'Piao ', 'Zhu ', 'Gui ', 'Xia ', 'Zhi ', 'Ji ', 'Gao ', 'Zhen ',
+'Gao ', 'Shui ', 'Jin ', 'Chen ', 'Gai ', 'Kun ', 'Di ', 'Dao ', 'Huo ', 'Tao ', 'Qi ', 'Gu ', 'Guan ', 'Zui ', 'Ling ', 'Lu ',
+'Bing ', 'Jin ', 'Dao ', 'Zhi ', 'Lu ', 'Shan ', 'Bei ', 'Zhe ', 'Hui ', 'You ', 'Xi ', 'Yin ', 'Zi ', 'Huo ', 'Zhen ', 'Fu ',
+'Yuan ', 'Wu ', 'Xian ', 'Yang ', 'Ti ', 'Yi ', 'Mei ', 'Si ', 'Di ', '[?]', 'Zhuo ', 'Zhen ', 'Yong ', 'Ji ', 'Gao ', 'Tang ',
+'Si ', 'Ma ', 'Ta ', '[?]', 'Xuan ', 'Qi ', 'Yu ', 'Xi ', 'Ji ', 'Si ', 'Chan ', 'Tan ', 'Kuai ', 'Sui ', 'Li ', 'Nong ',
+'Ni ', 'Dao ', 'Li ', 'Rang ', 'Yue ', 'Ti ', 'Zan ', 'Lei ', 'Rou ', 'Yu ', 'Yu ', 'Chi ', 'Xie ', 'Qin ', 'He ', 'Tu ',
+'Xiu ', 'Si ', 'Ren ', 'Tu ', 'Zi ', 'Cha ', 'Gan ', 'Yi ', 'Xian ', 'Bing ', 'Nian ', 'Qiu ', 'Qiu ', 'Chong ', 'Fen ', 'Hao ',
+'Yun ', 'Ke ', 'Miao ', 'Zhi ', 'Geng ', 'Bi ', 'Zhi ', 'Yu ', 'Mi ', 'Ku ', 'Ban ', 'Pi ', 'Ni ', 'Li ', 'You ', 'Zu ',
+'Pi ', 'Ba ', 'Ling ', 'Mo ', 'Cheng ', 'Nian ', 'Qin ', 'Yang ', 'Zuo ', 'Zhi ', 'Zhi ', 'Shu ', 'Ju ', 'Zi ', 'Huo ', 'Ji ',
+'Cheng ', 'Tong ', 'Zhi ', 'Huo ', 'He ', 'Yin ', 'Zi ', 'Zhi ', 'Jie ', 'Ren ', 'Du ', 'Yi ', 'Zhu ', 'Hui ', 'Nong ', 'Fu ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x7a.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x7a.php
new file mode 100644 (file)
index 0000000..70bcfb7
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x7a] = array(
+'Xi ', 'Kao ', 'Lang ', 'Fu ', 'Ze ', 'Shui ', 'Lu ', 'Kun ', 'Gan ', 'Geng ', 'Ti ', 'Cheng ', 'Tu ', 'Shao ', 'Shui ', 'Ya ',
+'Lun ', 'Lu ', 'Gu ', 'Zuo ', 'Ren ', 'Zhun ', 'Bang ', 'Bai ', 'Ji ', 'Zhi ', 'Zhi ', 'Kun ', 'Leng ', 'Peng ', 'Ke ', 'Bing ',
+'Chou ', 'Zu ', 'Yu ', 'Su ', 'Lue ', '[?]', 'Yi ', 'Xi ', 'Bian ', 'Ji ', 'Fu ', 'Bi ', 'Nuo ', 'Jie ', 'Zhong ', 'Zong ',
+'Xu ', 'Cheng ', 'Dao ', 'Wen ', 'Lian ', 'Zi ', 'Yu ', 'Ji ', 'Xu ', 'Zhen ', 'Zhi ', 'Dao ', 'Jia ', 'Ji ', 'Gao ', 'Gao ',
+'Gu ', 'Rong ', 'Sui ', 'You ', 'Ji ', 'Kang ', 'Mu ', 'Shan ', 'Men ', 'Zhi ', 'Ji ', 'Lu ', 'Su ', 'Ji ', 'Ying ', 'Wen ',
+'Qiu ', 'Se ', '[?]', 'Yi ', 'Huang ', 'Qie ', 'Ji ', 'Sui ', 'Xiao ', 'Pu ', 'Jiao ', 'Zhuo ', 'Tong ', 'Sai ', 'Lu ', 'Sui ',
+'Nong ', 'Se ', 'Hui ', 'Rang ', 'Nuo ', 'Yu ', 'Bin ', 'Ji ', 'Tui ', 'Wen ', 'Cheng ', 'Huo ', 'Gong ', 'Lu ', 'Biao ', '[?]',
+'Rang ', 'Zhuo ', 'Li ', 'Zan ', 'Xue ', 'Wa ', 'Jiu ', 'Qiong ', 'Xi ', 'Qiong ', 'Kong ', 'Yu ', 'Sen ', 'Jing ', 'Yao ', 'Chuan ',
+'Zhun ', 'Tu ', 'Lao ', 'Qie ', 'Zhai ', 'Yao ', 'Bian ', 'Bao ', 'Yao ', 'Bing ', 'Wa ', 'Zhu ', 'Jiao ', 'Qiao ', 'Diao ', 'Wu ',
+'Gui ', 'Yao ', 'Zhi ', 'Chuang ', 'Yao ', 'Tiao ', 'Jiao ', 'Chuang ', 'Jiong ', 'Xiao ', 'Cheng ', 'Kou ', 'Cuan ', 'Wo ', 'Dan ', 'Ku ',
+'Ke ', 'Zhui ', 'Xu ', 'Su ', 'Guan ', 'Kui ', 'Dou ', '[?]', 'Yin ', 'Wo ', 'Wa ', 'Ya ', 'Yu ', 'Ju ', 'Qiong ', 'Yao ',
+'Yao ', 'Tiao ', 'Chao ', 'Yu ', 'Tian ', 'Diao ', 'Ju ', 'Liao ', 'Xi ', 'Wu ', 'Kui ', 'Chuang ', 'Zhao ', '[?]', 'Kuan ', 'Long ',
+'Cheng ', 'Cui ', 'Piao ', 'Zao ', 'Cuan ', 'Qiao ', 'Qiong ', 'Dou ', 'Zao ', 'Long ', 'Qie ', 'Li ', 'Chu ', 'Shi ', 'Fou ', 'Qian ',
+'Chu ', 'Hong ', 'Qi ', 'Qian ', 'Gong ', 'Shi ', 'Shu ', 'Miao ', 'Ju ', 'Zhan ', 'Zhu ', 'Ling ', 'Long ', 'Bing ', 'Jing ', 'Jing ',
+'Zhang ', 'Yi ', 'Si ', 'Jun ', 'Hong ', 'Tong ', 'Song ', 'Jing ', 'Diao ', 'Yi ', 'Shu ', 'Jing ', 'Qu ', 'Jie ', 'Ping ', 'Duan ',
+'Shao ', 'Zhuan ', 'Ceng ', 'Deng ', 'Cui ', 'Huai ', 'Jing ', 'Kan ', 'Jing ', 'Zhu ', 'Zhu ', 'Le ', 'Peng ', 'Yu ', 'Chi ', 'Gan ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x7b.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x7b.php
new file mode 100644 (file)
index 0000000..61de9c6
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x7b] = array(
+'Mang ', 'Zhu ', 'Utsubo ', 'Du ', 'Ji ', 'Xiao ', 'Ba ', 'Suan ', 'Ji ', 'Zhen ', 'Zhao ', 'Sun ', 'Ya ', 'Zhui ', 'Yuan ', 'Hu ',
+'Gang ', 'Xiao ', 'Cen ', 'Pi ', 'Bi ', 'Jian ', 'Yi ', 'Dong ', 'Shan ', 'Sheng ', 'Xia ', 'Di ', 'Zhu ', 'Na ', 'Chi ', 'Gu ',
+'Li ', 'Qie ', 'Min ', 'Bao ', 'Tiao ', 'Si ', 'Fu ', 'Ce ', 'Ben ', 'Pei ', 'Da ', 'Zi ', 'Di ', 'Ling ', 'Ze ', 'Nu ',
+'Fu ', 'Gou ', 'Fan ', 'Jia ', 'Ge ', 'Fan ', 'Shi ', 'Mao ', 'Po ', 'Sey ', 'Jian ', 'Qiong ', 'Long ', 'Souke ', 'Bian ', 'Luo ',
+'Gui ', 'Qu ', 'Chi ', 'Yin ', 'Yao ', 'Xian ', 'Bi ', 'Qiong ', 'Gua ', 'Deng ', 'Jiao ', 'Jin ', 'Quan ', 'Sun ', 'Ru ', 'Fa ',
+'Kuang ', 'Zhu ', 'Tong ', 'Ji ', 'Da ', 'Xing ', 'Ce ', 'Zhong ', 'Kou ', 'Lai ', 'Bi ', 'Shai ', 'Dang ', 'Zheng ', 'Ce ', 'Fu ',
+'Yun ', 'Tu ', 'Pa ', 'Li ', 'Lang ', 'Ju ', 'Guan ', 'Jian ', 'Han ', 'Tong ', 'Xia ', 'Zhi ', 'Cheng ', 'Suan ', 'Shi ', 'Zhu ',
+'Zuo ', 'Xiao ', 'Shao ', 'Ting ', 'Ce ', 'Yan ', 'Gao ', 'Kuai ', 'Gan ', 'Chou ', 'Kago ', 'Gang ', 'Yun ', 'O ', 'Qian ', 'Xiao ',
+'Jian ', 'Pu ', 'Lai ', 'Zou ', 'Bi ', 'Bi ', 'Bi ', 'Ge ', 'Chi ', 'Guai ', 'Yu ', 'Jian ', 'Zhao ', 'Gu ', 'Chi ', 'Zheng ',
+'Jing ', 'Sha ', 'Zhou ', 'Lu ', 'Bo ', 'Ji ', 'Lin ', 'Suan ', 'Jun ', 'Fu ', 'Zha ', 'Gu ', 'Kong ', 'Qian ', 'Quan ', 'Jun ',
+'Chui ', 'Guan ', 'Yuan ', 'Ce ', 'Ju ', 'Bo ', 'Ze ', 'Qie ', 'Tuo ', 'Luo ', 'Dan ', 'Xiao ', 'Ruo ', 'Jian ', 'Xuan ', 'Bian ',
+'Sun ', 'Xiang ', 'Xian ', 'Ping ', 'Zhen ', 'Sheng ', 'Hu ', 'Shi ', 'Zhu ', 'Yue ', 'Chun ', 'Lu ', 'Wu ', 'Dong ', 'Xiao ', 'Ji ',
+'Jie ', 'Huang ', 'Xing ', 'Mei ', 'Fan ', 'Chui ', 'Zhuan ', 'Pian ', 'Feng ', 'Zhu ', 'Hong ', 'Qie ', 'Hou ', 'Qiu ', 'Miao ', 'Qian ',
+'[?]', 'Kui ', 'Sik ', 'Lou ', 'Yun ', 'He ', 'Tang ', 'Yue ', 'Chou ', 'Gao ', 'Fei ', 'Ruo ', 'Zheng ', 'Gou ', 'Nie ', 'Qian ',
+'Xiao ', 'Cuan ', 'Gong ', 'Pang ', 'Du ', 'Li ', 'Bi ', 'Zhuo ', 'Chu ', 'Shai ', 'Chi ', 'Zhu ', 'Qiang ', 'Long ', 'Lan ', 'Jian ',
+'Bu ', 'Li ', 'Hui ', 'Bi ', 'Di ', 'Cong ', 'Yan ', 'Peng ', 'Sen ', 'Zhuan ', 'Pai ', 'Piao ', 'Dou ', 'Yu ', 'Mie ', 'Zhuan ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x7c.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x7c.php
new file mode 100644 (file)
index 0000000..abe1ca2
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x7c] = array(
+'Ze ', 'Xi ', 'Guo ', 'Yi ', 'Hu ', 'Chan ', 'Kou ', 'Cu ', 'Ping ', 'Chou ', 'Ji ', 'Gui ', 'Su ', 'Lou ', 'Zha ', 'Lu ',
+'Nian ', 'Suo ', 'Cuan ', 'Sasara ', 'Suo ', 'Le ', 'Duan ', 'Yana ', 'Xiao ', 'Bo ', 'Mi ', 'Si ', 'Dang ', 'Liao ', 'Dan ', 'Dian ',
+'Fu ', 'Jian ', 'Min ', 'Kui ', 'Dai ', 'Qiao ', 'Deng ', 'Huang ', 'Sun ', 'Lao ', 'Zan ', 'Xiao ', 'Du ', 'Shi ', 'Zan ', '[?]',
+'Pai ', 'Hata ', 'Pai ', 'Gan ', 'Ju ', 'Du ', 'Lu ', 'Yan ', 'Bo ', 'Dang ', 'Sai ', 'Ke ', 'Long ', 'Qian ', 'Lian ', 'Bo ',
+'Zhou ', 'Lai ', '[?]', 'Lan ', 'Kui ', 'Yu ', 'Yue ', 'Hao ', 'Zhen ', 'Tai ', 'Ti ', 'Mi ', 'Chou ', 'Ji ', '[?]', 'Hata ',
+'Teng ', 'Zhuan ', 'Zhou ', 'Fan ', 'Sou ', 'Zhou ', 'Kuji ', 'Zhuo ', 'Teng ', 'Lu ', 'Lu ', 'Jian ', 'Tuo ', 'Ying ', 'Yu ', 'Lai ',
+'Long ', 'Shinshi ', 'Lian ', 'Lan ', 'Qian ', 'Yue ', 'Zhong ', 'Qu ', 'Lian ', 'Bian ', 'Duan ', 'Zuan ', 'Li ', 'Si ', 'Luo ', 'Ying ',
+'Yue ', 'Zhuo ', 'Xu ', 'Mi ', 'Di ', 'Fan ', 'Shen ', 'Zhe ', 'Shen ', 'Nu ', 'Xie ', 'Lei ', 'Xian ', 'Zi ', 'Ni ', 'Cun ',
+'[?]', 'Qian ', 'Kume ', 'Bi ', 'Ban ', 'Wu ', 'Sha ', 'Kang ', 'Rou ', 'Fen ', 'Bi ', 'Cui ', '[?]', 'Li ', 'Chi ', 'Nukamiso ',
+'Ro ', 'Ba ', 'Li ', 'Gan ', 'Ju ', 'Po ', 'Mo ', 'Cu ', 'Nian ', 'Zhou ', 'Li ', 'Su ', 'Tiao ', 'Li ', 'Qi ', 'Su ',
+'Hong ', 'Tong ', 'Zi ', 'Ce ', 'Yue ', 'Zhou ', 'Lin ', 'Zhuang ', 'Bai ', '[?]', 'Fen ', 'Ji ', '[?]', 'Sukumo ', 'Liang ', 'Xian ',
+'Fu ', 'Liang ', 'Can ', 'Geng ', 'Li ', 'Yue ', 'Lu ', 'Ju ', 'Qi ', 'Cui ', 'Bai ', 'Zhang ', 'Lin ', 'Zong ', 'Jing ', 'Guo ',
+'Kouji ', 'San ', 'San ', 'Tang ', 'Bian ', 'Rou ', 'Mian ', 'Hou ', 'Xu ', 'Zong ', 'Hu ', 'Jian ', 'Zan ', 'Ci ', 'Li ', 'Xie ',
+'Fu ', 'Ni ', 'Bei ', 'Gu ', 'Xiu ', 'Gao ', 'Tang ', 'Qiu ', 'Sukumo ', 'Cao ', 'Zhuang ', 'Tang ', 'Mi ', 'San ', 'Fen ', 'Zao ',
+'Kang ', 'Jiang ', 'Mo ', 'San ', 'San ', 'Nuo ', 'Xi ', 'Liang ', 'Jiang ', 'Kuai ', 'Bo ', 'Huan ', '[?]', 'Zong ', 'Xian ', 'Nuo ',
+'Tuan ', 'Nie ', 'Li ', 'Zuo ', 'Di ', 'Nie ', 'Tiao ', 'Lan ', 'Mi ', 'Jiao ', 'Jiu ', 'Xi ', 'Gong ', 'Zheng ', 'Jiu ', 'You ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x7d.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x7d.php
new file mode 100644 (file)
index 0000000..4223cb7
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x7d] = array(
+'Ji ', 'Cha ', 'Zhou ', 'Xun ', 'Yue ', 'Hong ', 'Yu ', 'He ', 'Wan ', 'Ren ', 'Wen ', 'Wen ', 'Qiu ', 'Na ', 'Zi ', 'Tou ',
+'Niu ', 'Fou ', 'Jie ', 'Shu ', 'Chun ', 'Pi ', 'Yin ', 'Sha ', 'Hong ', 'Zhi ', 'Ji ', 'Fen ', 'Yun ', 'Ren ', 'Dan ', 'Jin ',
+'Su ', 'Fang ', 'Suo ', 'Cui ', 'Jiu ', 'Zha ', 'Kinu ', 'Jin ', 'Fu ', 'Zhi ', 'Ci ', 'Zi ', 'Chou ', 'Hong ', 'Zha ', 'Lei ',
+'Xi ', 'Fu ', 'Xie ', 'Shen ', 'Bei ', 'Zhu ', 'Qu ', 'Ling ', 'Zhu ', 'Shao ', 'Gan ', 'Yang ', 'Fu ', 'Tuo ', 'Zhen ', 'Dai ',
+'Zhuo ', 'Shi ', 'Zhong ', 'Xian ', 'Zu ', 'Jiong ', 'Ban ', 'Ju ', 'Mo ', 'Shu ', 'Zui ', 'Wata ', 'Jing ', 'Ren ', 'Heng ', 'Xie ',
+'Jie ', 'Zhu ', 'Chou ', 'Gua ', 'Bai ', 'Jue ', 'Kuang ', 'Hu ', 'Ci ', 'Geng ', 'Geng ', 'Tao ', 'Xie ', 'Ku ', 'Jiao ', 'Quan ',
+'Gai ', 'Luo ', 'Xuan ', 'Bing ', 'Xian ', 'Fu ', 'Gei ', 'Tong ', 'Rong ', 'Tiao ', 'Yin ', 'Lei ', 'Xie ', 'Quan ', 'Xu ', 'Lun ',
+'Die ', 'Tong ', 'Si ', 'Jiang ', 'Xiang ', 'Hui ', 'Jue ', 'Zhi ', 'Jian ', 'Juan ', 'Chi ', 'Mian ', 'Zhen ', 'Lu ', 'Cheng ', 'Qiu ',
+'Shu ', 'Bang ', 'Tong ', 'Xiao ', 'Wan ', 'Qin ', 'Geng ', 'Xiu ', 'Ti ', 'Xiu ', 'Xie ', 'Hong ', 'Xi ', 'Fu ', 'Ting ', 'Sui ',
+'Dui ', 'Kun ', 'Fu ', 'Jing ', 'Hu ', 'Zhi ', 'Yan ', 'Jiong ', 'Feng ', 'Ji ', 'Sok ', 'Kase ', 'Zong ', 'Lin ', 'Duo ', 'Li ',
+'Lu ', 'Liang ', 'Chou ', 'Quan ', 'Shao ', 'Qi ', 'Qi ', 'Zhun ', 'Qi ', 'Wan ', 'Qian ', 'Xian ', 'Shou ', 'Wei ', 'Qi ', 'Tao ',
+'Wan ', 'Gang ', 'Wang ', 'Beng ', 'Zhui ', 'Cai ', 'Guo ', 'Cui ', 'Lun ', 'Liu ', 'Qi ', 'Zhan ', 'Bei ', 'Chuo ', 'Ling ', 'Mian ',
+'Qi ', 'Qie ', 'Tan ', 'Zong ', 'Gun ', 'Zou ', 'Yi ', 'Zi ', 'Xing ', 'Liang ', 'Jin ', 'Fei ', 'Rui ', 'Min ', 'Yu ', 'Zong ',
+'Fan ', 'Lu ', 'Xu ', 'Yingl ', 'Zhang ', 'Kasuri ', 'Xu ', 'Xiang ', 'Jian ', 'Ke ', 'Xian ', 'Ruan ', 'Mian ', 'Qi ', 'Duan ', 'Zhong ',
+'Di ', 'Min ', 'Miao ', 'Yuan ', 'Xie ', 'Bao ', 'Si ', 'Qiu ', 'Bian ', 'Huan ', 'Geng ', 'Cong ', 'Mian ', 'Wei ', 'Fu ', 'Wei ',
+'Yu ', 'Gou ', 'Miao ', 'Xie ', 'Lian ', 'Zong ', 'Bian ', 'Yun ', 'Yin ', 'Ti ', 'Gua ', 'Zhi ', 'Yun ', 'Cheng ', 'Chan ', 'Dai ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x7e.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x7e.php
new file mode 100644 (file)
index 0000000..4b22ad7
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x7e] = array(
+'Xia ', 'Yuan ', 'Zong ', 'Xu ', 'Nawa ', 'Odoshi ', 'Geng ', 'Sen ', 'Ying ', 'Jin ', 'Yi ', 'Zhui ', 'Ni ', 'Bang ', 'Gu ', 'Pan ',
+'Zhou ', 'Jian ', 'Cuo ', 'Quan ', 'Shuang ', 'Yun ', 'Xia ', 'Shuai ', 'Xi ', 'Rong ', 'Tao ', 'Fu ', 'Yun ', 'Zhen ', 'Gao ', 'Ru ',
+'Hu ', 'Zai ', 'Teng ', 'Xian ', 'Su ', 'Zhen ', 'Zong ', 'Tao ', 'Horo ', 'Cai ', 'Bi ', 'Feng ', 'Cu ', 'Li ', 'Suo ', 'Yin ',
+'Xi ', 'Zong ', 'Lei ', 'Zhuan ', 'Qian ', 'Man ', 'Zhi ', 'Lu ', 'Mo ', 'Piao ', 'Lian ', 'Mi ', 'Xuan ', 'Zong ', 'Ji ', 'Shan ',
+'Sui ', 'Fan ', 'Shuai ', 'Beng ', 'Yi ', 'Sao ', 'Mou ', 'Zhou ', 'Qiang ', 'Hun ', 'Sem ', 'Xi ', 'Jung ', 'Xiu ', 'Ran ', 'Xuan ',
+'Hui ', 'Qiao ', 'Zeng ', 'Zuo ', 'Zhi ', 'Shan ', 'San ', 'Lin ', 'Yu ', 'Fan ', 'Liao ', 'Chuo ', 'Zun ', 'Jian ', 'Rao ', 'Chan ',
+'Rui ', 'Xiu ', 'Hui ', 'Hua ', 'Zuan ', 'Xi ', 'Qiang ', 'Un ', 'Da ', 'Sheng ', 'Hui ', 'Xi ', 'Se ', 'Jian ', 'Jiang ', 'Huan ',
+'Zao ', 'Cong ', 'Jie ', 'Jiao ', 'Bo ', 'Chan ', 'Yi ', 'Nao ', 'Sui ', 'Yi ', 'Shai ', 'Xu ', 'Ji ', 'Bin ', 'Qian ', 'Lan ',
+'Pu ', 'Xun ', 'Zuan ', 'Qi ', 'Peng ', 'Li ', 'Mo ', 'Lei ', 'Xie ', 'Zuan ', 'Kuang ', 'You ', 'Xu ', 'Lei ', 'Xian ', 'Chan ',
+'Kou ', 'Lu ', 'Chan ', 'Ying ', 'Cai ', 'Xiang ', 'Xian ', 'Zui ', 'Zuan ', 'Luo ', 'Xi ', 'Dao ', 'Lan ', 'Lei ', 'Lian ', 'Si ',
+'Jiu ', 'Yu ', 'Hong ', 'Zhou ', 'Xian ', 'He ', 'Yue ', 'Ji ', 'Wan ', 'Kuang ', 'Ji ', 'Ren ', 'Wei ', 'Yun ', 'Hong ', 'Chun ',
+'Pi ', 'Sha ', 'Gang ', 'Na ', 'Ren ', 'Zong ', 'Lun ', 'Fen ', 'Zhi ', 'Wen ', 'Fang ', 'Zhu ', 'Yin ', 'Niu ', 'Shu ', 'Xian ',
+'Gan ', 'Xie ', 'Fu ', 'Lian ', 'Zu ', 'Shen ', 'Xi ', 'Zhi ', 'Zhong ', 'Zhou ', 'Ban ', 'Fu ', 'Zhuo ', 'Shao ', 'Yi ', 'Jing ',
+'Dai ', 'Bang ', 'Rong ', 'Jie ', 'Ku ', 'Rao ', 'Die ', 'Heng ', 'Hui ', 'Gei ', 'Xuan ', 'Jiang ', 'Luo ', 'Jue ', 'Jiao ', 'Tong ',
+'Geng ', 'Xiao ', 'Juan ', 'Xiu ', 'Xi ', 'Sui ', 'Tao ', 'Ji ', 'Ti ', 'Ji ', 'Xu ', 'Ling ', '[?]', 'Xu ', 'Qi ', 'Fei ',
+'Chuo ', 'Zhang ', 'Gun ', 'Sheng ', 'Wei ', 'Mian ', 'Shou ', 'Beng ', 'Chou ', 'Tao ', 'Liu ', 'Quan ', 'Zong ', 'Zhan ', 'Wan ', 'Lu ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x7f.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x7f.php
new file mode 100644 (file)
index 0000000..3fc4b25
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x7f] = array(
+'Zhui ', 'Zi ', 'Ke ', 'Xiang ', 'Jian ', 'Mian ', 'Lan ', 'Ti ', 'Miao ', 'Qi ', 'Yun ', 'Hui ', 'Si ', 'Duo ', 'Duan ', 'Bian ',
+'Xian ', 'Gou ', 'Zhui ', 'Huan ', 'Di ', 'Lu ', 'Bian ', 'Min ', 'Yuan ', 'Jin ', 'Fu ', 'Ru ', 'Zhen ', 'Feng ', 'Shuai ', 'Gao ',
+'Chan ', 'Li ', 'Yi ', 'Jian ', 'Bin ', 'Piao ', 'Man ', 'Lei ', 'Ying ', 'Suo ', 'Mou ', 'Sao ', 'Xie ', 'Liao ', 'Shan ', 'Zeng ',
+'Jiang ', 'Qian ', 'Zao ', 'Huan ', 'Jiao ', 'Zuan ', 'Fou ', 'Xie ', 'Gang ', 'Fou ', 'Que ', 'Fou ', 'Kaakeru ', 'Bo ', 'Ping ', 'Hou ',
+'[?]', 'Gang ', 'Ying ', 'Ying ', 'Qing ', 'Xia ', 'Guan ', 'Zun ', 'Tan ', 'Chang ', 'Qi ', 'Weng ', 'Ying ', 'Lei ', 'Tan ', 'Lu ',
+'Guan ', 'Wang ', 'Wang ', 'Gang ', 'Wang ', 'Han ', '[?]', 'Luo ', 'Fu ', 'Mi ', 'Fa ', 'Gu ', 'Zhu ', 'Ju ', 'Mao ', 'Gu ',
+'Min ', 'Gang ', 'Ba ', 'Gua ', 'Ti ', 'Juan ', 'Fu ', 'Lin ', 'Yan ', 'Zhao ', 'Zui ', 'Gua ', 'Zhuo ', 'Yu ', 'Zhi ', 'An ',
+'Fa ', 'Nan ', 'Shu ', 'Si ', 'Pi ', 'Ma ', 'Liu ', 'Ba ', 'Fa ', 'Li ', 'Chao ', 'Wei ', 'Bi ', 'Ji ', 'Zeng ', 'Tong ',
+'Liu ', 'Ji ', 'Juan ', 'Mi ', 'Zhao ', 'Luo ', 'Pi ', 'Ji ', 'Ji ', 'Luan ', 'Yang ', 'Mie ', 'Qiang ', 'Ta ', 'Mei ', 'Yang ',
+'You ', 'You ', 'Fen ', 'Ba ', 'Gao ', 'Yang ', 'Gu ', 'Qiang ', 'Zang ', 'Gao ', 'Ling ', 'Yi ', 'Zhu ', 'Di ', 'Xiu ', 'Qian ',
+'Yi ', 'Xian ', 'Rong ', 'Qun ', 'Qun ', 'Qian ', 'Huan ', 'Zui ', 'Xian ', 'Yi ', 'Yashinau ', 'Qiang ', 'Xian ', 'Yu ', 'Geng ', 'Jie ',
+'Tang ', 'Yuan ', 'Xi ', 'Fan ', 'Shan ', 'Fen ', 'Shan ', 'Lian ', 'Lei ', 'Geng ', 'Nou ', 'Qiang ', 'Chan ', 'Yu ', 'Gong ', 'Yi ',
+'Chong ', 'Weng ', 'Fen ', 'Hong ', 'Chi ', 'Chi ', 'Cui ', 'Fu ', 'Xia ', 'Pen ', 'Yi ', 'La ', 'Yi ', 'Pi ', 'Ling ', 'Liu ',
+'Zhi ', 'Qu ', 'Xi ', 'Xie ', 'Xiang ', 'Xi ', 'Xi ', 'Qi ', 'Qiao ', 'Hui ', 'Hui ', 'Xiao ', 'Se ', 'Hong ', 'Jiang ', 'Di ',
+'Cui ', 'Fei ', 'Tao ', 'Sha ', 'Chi ', 'Zhu ', 'Jian ', 'Xuan ', 'Shi ', 'Pian ', 'Zong ', 'Wan ', 'Hui ', 'Hou ', 'He ', 'He ',
+'Han ', 'Ao ', 'Piao ', 'Yi ', 'Lian ', 'Qu ', '[?]', 'Lin ', 'Pen ', 'Qiao ', 'Ao ', 'Fan ', 'Yi ', 'Hui ', 'Xuan ', 'Dao ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x80.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x80.php
new file mode 100644 (file)
index 0000000..0ba36d9
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x80] = array(
+'Yao ', 'Lao ', '[?]', 'Kao ', 'Mao ', 'Zhe ', 'Qi ', 'Gou ', 'Gou ', 'Gou ', 'Die ', 'Die ', 'Er ', 'Shua ', 'Ruan ', 'Er ',
+'Nai ', 'Zhuan ', 'Lei ', 'Ting ', 'Zi ', 'Geng ', 'Chao ', 'Hao ', 'Yun ', 'Pa ', 'Pi ', 'Chi ', 'Si ', 'Chu ', 'Jia ', 'Ju ',
+'He ', 'Chu ', 'Lao ', 'Lun ', 'Ji ', 'Tang ', 'Ou ', 'Lou ', 'Nou ', 'Gou ', 'Pang ', 'Ze ', 'Lou ', 'Ji ', 'Lao ', 'Huo ',
+'You ', 'Mo ', 'Huai ', 'Er ', 'Zhe ', 'Ting ', 'Ye ', 'Da ', 'Song ', 'Qin ', 'Yun ', 'Chi ', 'Dan ', 'Dan ', 'Hong ', 'Geng ',
+'Zhi ', '[?]', 'Nie ', 'Dan ', 'Zhen ', 'Che ', 'Ling ', 'Zheng ', 'You ', 'Wa ', 'Liao ', 'Long ', 'Zhi ', 'Ning ', 'Tiao ', 'Er ',
+'Ya ', 'Die ', 'Gua ', '[?]', 'Lian ', 'Hao ', 'Sheng ', 'Lie ', 'Pin ', 'Jing ', 'Ju ', 'Bi ', 'Di ', 'Guo ', 'Wen ', 'Xu ',
+'Ping ', 'Cong ', 'Shikato ', '[?]', 'Ting ', 'Yu ', 'Cong ', 'Kui ', 'Tsuraneru ', 'Kui ', 'Cong ', 'Lian ', 'Weng ', 'Kui ', 'Lian ', 'Lian ',
+'Cong ', 'Ao ', 'Sheng ', 'Song ', 'Ting ', 'Kui ', 'Nie ', 'Zhi ', 'Dan ', 'Ning ', 'Qie ', 'Ji ', 'Ting ', 'Ting ', 'Long ', 'Yu ',
+'Yu ', 'Zhao ', 'Si ', 'Su ', 'Yi ', 'Su ', 'Si ', 'Zhao ', 'Zhao ', 'Rou ', 'Yi ', 'Le ', 'Ji ', 'Qiu ', 'Ken ', 'Cao ',
+'Ge ', 'Di ', 'Huan ', 'Huang ', 'Yi ', 'Ren ', 'Xiao ', 'Ru ', 'Zhou ', 'Yuan ', 'Du ', 'Gang ', 'Rong ', 'Gan ', 'Cha ', 'Wo ',
+'Chang ', 'Gu ', 'Zhi ', 'Han ', 'Fu ', 'Fei ', 'Fen ', 'Pei ', 'Pang ', 'Jian ', 'Fang ', 'Zhun ', 'You ', 'Na ', 'Hang ', 'Ken ',
+'Ran ', 'Gong ', 'Yu ', 'Wen ', 'Yao ', 'Jin ', 'Pi ', 'Qian ', 'Xi ', 'Xi ', 'Fei ', 'Ken ', 'Jing ', 'Tai ', 'Shen ', 'Zhong ',
+'Zhang ', 'Xie ', 'Shen ', 'Wei ', 'Zhou ', 'Die ', 'Dan ', 'Fei ', 'Ba ', 'Bo ', 'Qu ', 'Tian ', 'Bei ', 'Gua ', 'Tai ', 'Zi ',
+'Ku ', 'Zhi ', 'Ni ', 'Ping ', 'Zi ', 'Fu ', 'Pang ', 'Zhen ', 'Xian ', 'Zuo ', 'Pei ', 'Jia ', 'Sheng ', 'Zhi ', 'Bao ', 'Mu ',
+'Qu ', 'Hu ', 'Ke ', 'Yi ', 'Yin ', 'Xu ', 'Yang ', 'Long ', 'Dong ', 'Ka ', 'Lu ', 'Jing ', 'Nu ', 'Yan ', 'Pang ', 'Kua ',
+'Yi ', 'Guang ', 'Gai ', 'Ge ', 'Dong ', 'Zhi ', 'Xiao ', 'Xiong ', 'Xiong ', 'Er ', 'E ', 'Xing ', 'Pian ', 'Neng ', 'Zi ', 'Gui ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x81.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x81.php
new file mode 100644 (file)
index 0000000..9c5c045
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x81] = array(
+'Cheng ', 'Tiao ', 'Zhi ', 'Cui ', 'Mei ', 'Xie ', 'Cui ', 'Xie ', 'Mo ', 'Mai ', 'Ji ', 'Obiyaakasu ', '[?]', 'Kuai ', 'Sa ', 'Zang ',
+'Qi ', 'Nao ', 'Mi ', 'Nong ', 'Luan ', 'Wan ', 'Bo ', 'Wen ', 'Guan ', 'Qiu ', 'Jiao ', 'Jing ', 'Rou ', 'Heng ', 'Cuo ', 'Lie ',
+'Shan ', 'Ting ', 'Mei ', 'Chun ', 'Shen ', 'Xie ', 'De ', 'Zui ', 'Cu ', 'Xiu ', 'Xin ', 'Tuo ', 'Pao ', 'Cheng ', 'Nei ', 'Fu ',
+'Dou ', 'Tuo ', 'Niao ', 'Noy ', 'Pi ', 'Gu ', 'Gua ', 'Li ', 'Lian ', 'Zhang ', 'Cui ', 'Jie ', 'Liang ', 'Zhou ', 'Pi ', 'Biao ',
+'Lun ', 'Pian ', 'Guo ', 'Kui ', 'Chui ', 'Dan ', 'Tian ', 'Nei ', 'Jing ', 'Jie ', 'La ', 'Yi ', 'An ', 'Ren ', 'Shen ', 'Chuo ',
+'Fu ', 'Fu ', 'Ju ', 'Fei ', 'Qiang ', 'Wan ', 'Dong ', 'Pi ', 'Guo ', 'Zong ', 'Ding ', 'Wu ', 'Mei ', 'Ruan ', 'Zhuan ', 'Zhi ',
+'Cou ', 'Gua ', 'Ou ', 'Di ', 'An ', 'Xing ', 'Nao ', 'Yu ', 'Chuan ', 'Nan ', 'Yun ', 'Zhong ', 'Rou ', 'E ', 'Sai ', 'Tu ',
+'Yao ', 'Jian ', 'Wei ', 'Jiao ', 'Yu ', 'Jia ', 'Duan ', 'Bi ', 'Chang ', 'Fu ', 'Xian ', 'Ni ', 'Mian ', 'Wa ', 'Teng ', 'Tui ',
+'Bang ', 'Qian ', 'Lu ', 'Wa ', 'Sou ', 'Tang ', 'Su ', 'Zhui ', 'Ge ', 'Yi ', 'Bo ', 'Liao ', 'Ji ', 'Pi ', 'Xie ', 'Gao ',
+'Lu ', 'Bin ', 'Ou ', 'Chang ', 'Lu ', 'Guo ', 'Pang ', 'Chuai ', 'Piao ', 'Jiang ', 'Fu ', 'Tang ', 'Mo ', 'Xi ', 'Zhuan ', 'Lu ',
+'Jiao ', 'Ying ', 'Lu ', 'Zhi ', 'Tara ', 'Chun ', 'Lian ', 'Tong ', 'Peng ', 'Ni ', 'Zha ', 'Liao ', 'Cui ', 'Gui ', 'Xiao ', 'Teng ',
+'Fan ', 'Zhi ', 'Jiao ', 'Shan ', 'Wu ', 'Cui ', 'Run ', 'Xiang ', 'Sui ', 'Fen ', 'Ying ', 'Tan ', 'Zhua ', 'Dan ', 'Kuai ', 'Nong ',
+'Tun ', 'Lian ', 'Bi ', 'Yong ', 'Jue ', 'Chu ', 'Yi ', 'Juan ', 'La ', 'Lian ', 'Sao ', 'Tun ', 'Gu ', 'Qi ', 'Cui ', 'Bin ',
+'Xun ', 'Ru ', 'Huo ', 'Zang ', 'Xian ', 'Biao ', 'Xing ', 'Kuan ', 'La ', 'Yan ', 'Lu ', 'Huo ', 'Zang ', 'Luo ', 'Qu ', 'Zang ',
+'Luan ', 'Ni ', 'Zang ', 'Chen ', 'Qian ', 'Wo ', 'Guang ', 'Zang ', 'Lin ', 'Guang ', 'Zi ', 'Jiao ', 'Nie ', 'Chou ', 'Ji ', 'Gao ',
+'Chou ', 'Mian ', 'Nie ', 'Zhi ', 'Zhi ', 'Ge ', 'Jian ', 'Die ', 'Zhi ', 'Xiu ', 'Tai ', 'Zhen ', 'Jiu ', 'Xian ', 'Yu ', 'Cha ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x82.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x82.php
new file mode 100644 (file)
index 0000000..f287f81
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x82] = array(
+'Yao ', 'Yu ', 'Chong ', 'Xi ', 'Xi ', 'Jiu ', 'Yu ', 'Yu ', 'Xing ', 'Ju ', 'Jiu ', 'Xin ', 'She ', 'She ', 'Yadoru ', 'Jiu ',
+'Shi ', 'Tan ', 'Shu ', 'Shi ', 'Tian ', 'Dan ', 'Pu ', 'Pu ', 'Guan ', 'Hua ', 'Tan ', 'Chuan ', 'Shun ', 'Xia ', 'Wu ', 'Zhou ',
+'Dao ', 'Gang ', 'Shan ', 'Yi ', '[?]', 'Pa ', 'Tai ', 'Fan ', 'Ban ', 'Chuan ', 'Hang ', 'Fang ', 'Ban ', 'Que ', 'Hesaki ', 'Zhong ',
+'Jian ', 'Cang ', 'Ling ', 'Zhu ', 'Ze ', 'Duo ', 'Bo ', 'Xian ', 'Ge ', 'Chuan ', 'Jia ', 'Lu ', 'Hong ', 'Pang ', 'Xi ', '[?]',
+'Fu ', 'Zao ', 'Feng ', 'Li ', 'Shao ', 'Yu ', 'Lang ', 'Ting ', '[?]', 'Wei ', 'Bo ', 'Meng ', 'Nian ', 'Ju ', 'Huang ', 'Shou ',
+'Zong ', 'Bian ', 'Mao ', 'Die ', '[?]', 'Bang ', 'Cha ', 'Yi ', 'Sao ', 'Cang ', 'Cao ', 'Lou ', 'Dai ', 'Sori ', 'Yao ', 'Tong ',
+'Yofune ', 'Dang ', 'Tan ', 'Lu ', 'Yi ', 'Jie ', 'Jian ', 'Huo ', 'Meng ', 'Qi ', 'Lu ', 'Lu ', 'Chan ', 'Shuang ', 'Gen ', 'Liang ',
+'Jian ', 'Jian ', 'Se ', 'Yan ', 'Fu ', 'Ping ', 'Yan ', 'Yan ', 'Cao ', 'Cao ', 'Yi ', 'Le ', 'Ting ', 'Qiu ', 'Ai ', 'Nai ',
+'Tiao ', 'Jiao ', 'Jie ', 'Peng ', 'Wan ', 'Yi ', 'Chai ', 'Mian ', 'Mie ', 'Gan ', 'Qian ', 'Yu ', 'Yu ', 'Shuo ', 'Qiong ', 'Tu ',
+'Xia ', 'Qi ', 'Mang ', 'Zi ', 'Hui ', 'Sui ', 'Zhi ', 'Xiang ', 'Bi ', 'Fu ', 'Tun ', 'Wei ', 'Wu ', 'Zhi ', 'Qi ', 'Shan ',
+'Wen ', 'Qian ', 'Ren ', 'Fou ', 'Kou ', 'Jie ', 'Lu ', 'Xu ', 'Ji ', 'Qin ', 'Qi ', 'Yuan ', 'Fen ', 'Ba ', 'Rui ', 'Xin ',
+'Ji ', 'Hua ', 'Hua ', 'Fang ', 'Wu ', 'Jue ', 'Gou ', 'Zhi ', 'Yun ', 'Qin ', 'Ao ', 'Chu ', 'Mao ', 'Ya ', 'Fei ', 'Reng ',
+'Hang ', 'Cong ', 'Yin ', 'You ', 'Bian ', 'Yi ', 'Susa ', 'Wei ', 'Li ', 'Pi ', 'E ', 'Xian ', 'Chang ', 'Cang ', 'Meng ', 'Su ',
+'Yi ', 'Yuan ', 'Ran ', 'Ling ', 'Tai ', 'Tiao ', 'Di ', 'Miao ', 'Qiong ', 'Li ', 'Yong ', 'Ke ', 'Mu ', 'Pei ', 'Bao ', 'Gou ',
+'Min ', 'Yi ', 'Yi ', 'Ju ', 'Pi ', 'Ruo ', 'Ku ', 'Zhu ', 'Ni ', 'Bo ', 'Bing ', 'Shan ', 'Qiu ', 'Yao ', 'Xian ', 'Ben ',
+'Hong ', 'Ying ', 'Zha ', 'Dong ', 'Ju ', 'Die ', 'Nie ', 'Gan ', 'Hu ', 'Ping ', 'Mei ', 'Fu ', 'Sheng ', 'Gu ', 'Bi ', 'Wei ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x83.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x83.php
new file mode 100644 (file)
index 0000000..8ae2507
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x83] = array(
+'Fu ', 'Zhuo ', 'Mao ', 'Fan ', 'Qie ', 'Mao ', 'Mao ', 'Ba ', 'Zi ', 'Mo ', 'Zi ', 'Di ', 'Chi ', 'Ji ', 'Jing ', 'Long ',
+'[?]', 'Niao ', '[?]', 'Xue ', 'Ying ', 'Qiong ', 'Ge ', 'Ming ', 'Li ', 'Rong ', 'Yin ', 'Gen ', 'Qian ', 'Chai ', 'Chen ', 'Yu ',
+'Xiu ', 'Zi ', 'Lie ', 'Wu ', 'Ji ', 'Kui ', 'Ce ', 'Chong ', 'Ci ', 'Gou ', 'Guang ', 'Mang ', 'Chi ', 'Jiao ', 'Jiao ', 'Fu ',
+'Yu ', 'Zhu ', 'Zi ', 'Jiang ', 'Hui ', 'Yin ', 'Cha ', 'Fa ', 'Rong ', 'Ru ', 'Chong ', 'Mang ', 'Tong ', 'Zhong ', '[?]', 'Zhu ',
+'Xun ', 'Huan ', 'Kua ', 'Quan ', 'Gai ', 'Da ', 'Jing ', 'Xing ', 'Quan ', 'Cao ', 'Jing ', 'Er ', 'An ', 'Shou ', 'Chi ', 'Ren ',
+'Jian ', 'Ti ', 'Huang ', 'Ping ', 'Li ', 'Jin ', 'Lao ', 'Shu ', 'Zhuang ', 'Da ', 'Jia ', 'Rao ', 'Bi ', 'Ze ', 'Qiao ', 'Hui ',
+'Qi ', 'Dang ', '[?]', 'Rong ', 'Hun ', 'Ying ', 'Luo ', 'Ying ', 'Xun ', 'Jin ', 'Sun ', 'Yin ', 'Mai ', 'Hong ', 'Zhou ', 'Yao ',
+'Du ', 'Wei ', 'Chu ', 'Dou ', 'Fu ', 'Ren ', 'Yin ', 'He ', 'Bi ', 'Bu ', 'Yun ', 'Di ', 'Tu ', 'Sui ', 'Sui ', 'Cheng ',
+'Chen ', 'Wu ', 'Bie ', 'Xi ', 'Geng ', 'Li ', 'Fu ', 'Zhu ', 'Mo ', 'Li ', 'Zhuang ', 'Ji ', 'Duo ', 'Qiu ', 'Sha ', 'Suo ',
+'Chen ', 'Feng ', 'Ju ', 'Mei ', 'Meng ', 'Xing ', 'Jing ', 'Che ', 'Xin ', 'Jun ', 'Yan ', 'Ting ', 'Diao ', 'Cuo ', 'Wan ', 'Han ',
+'You ', 'Cuo ', 'Jia ', 'Wang ', 'You ', 'Niu ', 'Shao ', 'Xian ', 'Lang ', 'Fu ', 'E ', 'Mo ', 'Wen ', 'Jie ', 'Nan ', 'Mu ',
+'Kan ', 'Lai ', 'Lian ', 'Shi ', 'Wo ', 'Usagi ', 'Lian ', 'Huo ', 'You ', 'Ying ', 'Ying ', 'Nuc ', 'Chun ', 'Mang ', 'Mang ', 'Ci ',
+'Wan ', 'Jing ', 'Di ', 'Qu ', 'Dong ', 'Jian ', 'Zou ', 'Gu ', 'La ', 'Lu ', 'Ju ', 'Wei ', 'Jun ', 'Nie ', 'Kun ', 'He ',
+'Pu ', 'Zi ', 'Gao ', 'Guo ', 'Fu ', 'Lun ', 'Chang ', 'Chou ', 'Song ', 'Chui ', 'Zhan ', 'Men ', 'Cai ', 'Ba ', 'Li ', 'Tu ',
+'Bo ', 'Han ', 'Bao ', 'Qin ', 'Juan ', 'Xi ', 'Qin ', 'Di ', 'Jie ', 'Pu ', 'Dang ', 'Jin ', 'Zhao ', 'Tai ', 'Geng ', 'Hua ',
+'Gu ', 'Ling ', 'Fei ', 'Jin ', 'An ', 'Wang ', 'Beng ', 'Zhou ', 'Yan ', 'Ju ', 'Jian ', 'Lin ', 'Tan ', 'Shu ', 'Tian ', 'Dao ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x84.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x84.php
new file mode 100644 (file)
index 0000000..58e9586
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x84] = array(
+'Hu ', 'Qi ', 'He ', 'Cui ', 'Tao ', 'Chun ', 'Bei ', 'Chang ', 'Huan ', 'Fei ', 'Lai ', 'Qi ', 'Meng ', 'Ping ', 'Wei ', 'Dan ',
+'Sha ', 'Huan ', 'Yan ', 'Yi ', 'Tiao ', 'Qi ', 'Wan ', 'Ce ', 'Nai ', 'Kutabireru ', 'Tuo ', 'Jiu ', 'Tie ', 'Luo ', '[?]', '[?]',
+'Meng ', '[?]', 'Yaji ', '[?]', 'Ying ', 'Ying ', 'Ying ', 'Xiao ', 'Sa ', 'Qiu ', 'Ke ', 'Xiang ', 'Wan ', 'Yu ', 'Yu ', 'Fu ',
+'Lian ', 'Xuan ', 'Yuan ', 'Nan ', 'Ze ', 'Wo ', 'Chun ', 'Xiao ', 'Yu ', 'Pian ', 'Mao ', 'An ', 'E ', 'Luo ', 'Ying ', 'Huo ',
+'Gua ', 'Jiang ', 'Mian ', 'Zuo ', 'Zuo ', 'Ju ', 'Bao ', 'Rou ', 'Xi ', 'Xie ', 'An ', 'Qu ', 'Jian ', 'Fu ', 'Lu ', 'Jing ',
+'Pen ', 'Feng ', 'Hong ', 'Hong ', 'Hou ', 'Yan ', 'Tu ', 'Zhu ', 'Zi ', 'Xiang ', 'Shen ', 'Ge ', 'Jie ', 'Jing ', 'Mi ', 'Huang ',
+'Shen ', 'Pu ', 'Gai ', 'Dong ', 'Zhou ', 'Qian ', 'Wei ', 'Bo ', 'Wei ', 'Pa ', 'Ji ', 'Hu ', 'Zang ', 'Jia ', 'Duan ', 'Yao ',
+'Jun ', 'Cong ', 'Quan ', 'Wei ', 'Xian ', 'Kui ', 'Ting ', 'Hun ', 'Xi ', 'Shi ', 'Qi ', 'Lan ', 'Zong ', 'Yao ', 'Yuan ', 'Mei ',
+'Yun ', 'Shu ', 'Di ', 'Zhuan ', 'Guan ', 'Sukumo ', 'Xue ', 'Chan ', 'Kai ', 'Kui ', '[?]', 'Jiang ', 'Lou ', 'Wei ', 'Pai ', '[?]',
+'Sou ', 'Yin ', 'Shi ', 'Chun ', 'Shi ', 'Yun ', 'Zhen ', 'Lang ', 'Nu ', 'Meng ', 'He ', 'Que ', 'Suan ', 'Yuan ', 'Li ', 'Ju ',
+'Xi ', 'Pang ', 'Chu ', 'Xu ', 'Tu ', 'Liu ', 'Wo ', 'Zhen ', 'Qian ', 'Zu ', 'Po ', 'Cuo ', 'Yuan ', 'Chu ', 'Yu ', 'Kuai ',
+'Pan ', 'Pu ', 'Pu ', 'Na ', 'Shuo ', 'Xi ', 'Fen ', 'Yun ', 'Zheng ', 'Jian ', 'Ji ', 'Ruo ', 'Cang ', 'En ', 'Mi ', 'Hao ',
+'Sun ', 'Zhen ', 'Ming ', 'Sou ', 'Xu ', 'Liu ', 'Xi ', 'Gu ', 'Lang ', 'Rong ', 'Weng ', 'Gai ', 'Cuo ', 'Shi ', 'Tang ', 'Luo ',
+'Ru ', 'Suo ', 'Xian ', 'Bei ', 'Yao ', 'Gui ', 'Bi ', 'Zong ', 'Gun ', 'Za ', 'Xiu ', 'Ce ', 'Hai ', 'Lan ', '[?]', 'Ji ',
+'Li ', 'Can ', 'Lang ', 'Yu ', '[?]', 'Ying ', 'Mo ', 'Diao ', 'Tiao ', 'Mao ', 'Tong ', 'Zhu ', 'Peng ', 'An ', 'Lian ', 'Cong ',
+'Xi ', 'Ping ', 'Qiu ', 'Jin ', 'Chun ', 'Jie ', 'Wei ', 'Tui ', 'Cao ', 'Yu ', 'Yi ', 'Ji ', 'Liao ', 'Bi ', 'Lu ', 'Su ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x85.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x85.php
new file mode 100644 (file)
index 0000000..2abfe05
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x85] = array(
+'Bu ', 'Zhang ', 'Luo ', 'Jiang ', 'Man ', 'Yan ', 'Ling ', 'Ji ', 'Piao ', 'Gun ', 'Han ', 'Di ', 'Su ', 'Lu ', 'She ', 'Shang ',
+'Di ', 'Mie ', 'Xun ', 'Man ', 'Bo ', 'Di ', 'Cuo ', 'Zhe ', 'Sen ', 'Xuan ', 'Wei ', 'Hu ', 'Ao ', 'Mi ', 'Lou ', 'Cu ',
+'Zhong ', 'Cai ', 'Po ', 'Jiang ', 'Mi ', 'Cong ', 'Niao ', 'Hui ', 'Jun ', 'Yin ', 'Jian ', 'Yan ', 'Shu ', 'Yin ', 'Kui ', 'Chen ',
+'Hu ', 'Sha ', 'Kou ', 'Qian ', 'Ma ', 'Zang ', 'Sonoko ', 'Qiang ', 'Dou ', 'Lian ', 'Lin ', 'Kou ', 'Ai ', 'Bi ', 'Li ', 'Wei ',
+'Ji ', 'Xun ', 'Sheng ', 'Fan ', 'Meng ', 'Ou ', 'Chan ', 'Dian ', 'Xun ', 'Jiao ', 'Rui ', 'Rui ', 'Lei ', 'Yu ', 'Qiao ', 'Chu ',
+'Hua ', 'Jian ', 'Mai ', 'Yun ', 'Bao ', 'You ', 'Qu ', 'Lu ', 'Rao ', 'Hui ', 'E ', 'Teng ', 'Fei ', 'Jue ', 'Zui ', 'Fa ',
+'Ru ', 'Fen ', 'Kui ', 'Shun ', 'Rui ', 'Ya ', 'Xu ', 'Fu ', 'Jue ', 'Dang ', 'Wu ', 'Tong ', 'Si ', 'Xiao ', 'Xi ', 'Long ',
+'Yun ', '[?]', 'Qi ', 'Jian ', 'Yun ', 'Sun ', 'Ling ', 'Yu ', 'Xia ', 'Yong ', 'Ji ', 'Hong ', 'Si ', 'Nong ', 'Lei ', 'Xuan ',
+'Yun ', 'Yu ', 'Xi ', 'Hao ', 'Bo ', 'Hao ', 'Ai ', 'Wei ', 'Hui ', 'Wei ', 'Ji ', 'Ci ', 'Xiang ', 'Luan ', 'Mie ', 'Yi ',
+'Leng ', 'Jiang ', 'Can ', 'Shen ', 'Qiang ', 'Lian ', 'Ke ', 'Yuan ', 'Da ', 'Ti ', 'Tang ', 'Xie ', 'Bi ', 'Zhan ', 'Sun ', 'Lian ',
+'Fan ', 'Ding ', 'Jie ', 'Gu ', 'Xie ', 'Shu ', 'Jian ', 'Kao ', 'Hong ', 'Sa ', 'Xin ', 'Xun ', 'Yao ', 'Hie ', 'Sou ', 'Shu ',
+'Xun ', 'Dui ', 'Pin ', 'Wei ', 'Neng ', 'Chou ', 'Mai ', 'Ru ', 'Piao ', 'Tai ', 'Qi ', 'Zao ', 'Chen ', 'Zhen ', 'Er ', 'Ni ',
+'Ying ', 'Gao ', 'Cong ', 'Xiao ', 'Qi ', 'Fa ', 'Jian ', 'Xu ', 'Kui ', 'Jie ', 'Bian ', 'Diao ', 'Mi ', 'Lan ', 'Jin ', 'Cang ',
+'Miao ', 'Qiong ', 'Qie ', 'Xian ', '[?]', 'Ou ', 'Xian ', 'Su ', 'Lu ', 'Yi ', 'Xu ', 'Xie ', 'Li ', 'Yi ', 'La ', 'Lei ',
+'Xiao ', 'Di ', 'Zhi ', 'Bei ', 'Teng ', 'Yao ', 'Mo ', 'Huan ', 'Piao ', 'Fan ', 'Sou ', 'Tan ', 'Tui ', 'Qiong ', 'Qiao ', 'Wei ',
+'Liu ', 'Hui ', '[?]', 'Gao ', 'Yun ', '[?]', 'Li ', 'Shu ', 'Chu ', 'Ai ', 'Lin ', 'Zao ', 'Xuan ', 'Chen ', 'Lai ', 'Huo ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x86.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x86.php
new file mode 100644 (file)
index 0000000..6101b36
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x86] = array(
+'Tuo ', 'Wu ', 'Rui ', 'Rui ', 'Qi ', 'Heng ', 'Lu ', 'Su ', 'Tui ', 'Mang ', 'Yun ', 'Pin ', 'Yu ', 'Xun ', 'Ji ', 'Jiong ',
+'Xian ', 'Mo ', 'Hagi ', 'Su ', 'Jiong ', '[?]', 'Nie ', 'Bo ', 'Rang ', 'Yi ', 'Xian ', 'Yu ', 'Ju ', 'Lian ', 'Lian ', 'Yin ',
+'Qiang ', 'Ying ', 'Long ', 'Tong ', 'Wei ', 'Yue ', 'Ling ', 'Qu ', 'Yao ', 'Fan ', 'Mi ', 'Lan ', 'Kui ', 'Lan ', 'Ji ', 'Dang ',
+'Katsura ', 'Lei ', 'Lei ', 'Hua ', 'Feng ', 'Zhi ', 'Wei ', 'Kui ', 'Zhan ', 'Huai ', 'Li ', 'Ji ', 'Mi ', 'Lei ', 'Huai ', 'Luo ',
+'Ji ', 'Kui ', 'Lu ', 'Jian ', 'San ', '[?]', 'Lei ', 'Quan ', 'Xiao ', 'Yi ', 'Luan ', 'Men ', 'Bie ', 'Hu ', 'Hu ', 'Lu ',
+'Nue ', 'Lu ', 'Si ', 'Xiao ', 'Qian ', 'Chu ', 'Hu ', 'Xu ', 'Cuo ', 'Fu ', 'Xu ', 'Xu ', 'Lu ', 'Hu ', 'Yu ', 'Hao ',
+'Jiao ', 'Ju ', 'Guo ', 'Bao ', 'Yan ', 'Zhan ', 'Zhan ', 'Kui ', 'Ban ', 'Xi ', 'Shu ', 'Chong ', 'Qiu ', 'Diao ', 'Ji ', 'Qiu ',
+'Cheng ', 'Shi ', '[?]', 'Di ', 'Zhe ', 'She ', 'Yu ', 'Gan ', 'Zi ', 'Hong ', 'Hui ', 'Meng ', 'Ge ', 'Sui ', 'Xia ', 'Chai ',
+'Shi ', 'Yi ', 'Ma ', 'Xiang ', 'Fang ', 'E ', 'Pa ', 'Chi ', 'Qian ', 'Wen ', 'Wen ', 'Rui ', 'Bang ', 'Bi ', 'Yue ', 'Yue ',
+'Jun ', 'Qi ', 'Ran ', 'Yin ', 'Qi ', 'Tian ', 'Yuan ', 'Jue ', 'Hui ', 'Qin ', 'Qi ', 'Zhong ', 'Ya ', 'Ci ', 'Mu ', 'Wang ',
+'Fen ', 'Fen ', 'Hang ', 'Gong ', 'Zao ', 'Fu ', 'Ran ', 'Jie ', 'Fu ', 'Chi ', 'Dou ', 'Piao ', 'Xian ', 'Ni ', 'Te ', 'Qiu ',
+'You ', 'Zha ', 'Ping ', 'Chi ', 'You ', 'He ', 'Han ', 'Ju ', 'Li ', 'Fu ', 'Ran ', 'Zha ', 'Gou ', 'Pi ', 'Bo ', 'Xian ',
+'Zhu ', 'Diao ', 'Bie ', 'Bing ', 'Gu ', 'Ran ', 'Qu ', 'She ', 'Tie ', 'Ling ', 'Gu ', 'Dan ', 'Gu ', 'Ying ', 'Li ', 'Cheng ',
+'Qu ', 'Mou ', 'Ge ', 'Ci ', 'Hui ', 'Hui ', 'Mang ', 'Fu ', 'Yang ', 'Wa ', 'Lie ', 'Zhu ', 'Yi ', 'Xian ', 'Kuo ', 'Jiao ',
+'Li ', 'Yi ', 'Ping ', 'Ji ', 'Ha ', 'She ', 'Yi ', 'Wang ', 'Mo ', 'Qiong ', 'Qie ', 'Gui ', 'Gong ', 'Zhi ', 'Man ', 'Ebi ',
+'Zhi ', 'Jia ', 'Rao ', 'Si ', 'Qi ', 'Xing ', 'Lie ', 'Qiu ', 'Shao ', 'Yong ', 'Jia ', 'Shui ', 'Che ', 'Bai ', 'E ', 'Han ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x87.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x87.php
new file mode 100644 (file)
index 0000000..7256272
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x87] = array(
+'Shu ', 'Xuan ', 'Feng ', 'Shen ', 'Zhen ', 'Fu ', 'Xian ', 'Zhe ', 'Wu ', 'Fu ', 'Li ', 'Lang ', 'Bi ', 'Chu ', 'Yuan ', 'You ',
+'Jie ', 'Dan ', 'Yan ', 'Ting ', 'Dian ', 'Shui ', 'Hui ', 'Gua ', 'Zhi ', 'Song ', 'Fei ', 'Ju ', 'Mi ', 'Qi ', 'Qi ', 'Yu ',
+'Jun ', 'Zha ', 'Meng ', 'Qiang ', 'Si ', 'Xi ', 'Lun ', 'Li ', 'Die ', 'Tiao ', 'Tao ', 'Kun ', 'Gan ', 'Han ', 'Yu ', 'Bang ',
+'Fei ', 'Pi ', 'Wei ', 'Dun ', 'Yi ', 'Yuan ', 'Su ', 'Quan ', 'Qian ', 'Rui ', 'Ni ', 'Qing ', 'Wei ', 'Liang ', 'Guo ', 'Wan ',
+'Dong ', 'E ', 'Ban ', 'Di ', 'Wang ', 'Can ', 'Yang ', 'Ying ', 'Guo ', 'Chan ', '[?]', 'La ', 'Ke ', 'Ji ', 'He ', 'Ting ',
+'Mai ', 'Xu ', 'Mian ', 'Yu ', 'Jie ', 'Shi ', 'Xuan ', 'Huang ', 'Yan ', 'Bian ', 'Rou ', 'Wei ', 'Fu ', 'Yuan ', 'Mei ', 'Wei ',
+'Fu ', 'Ruan ', 'Xie ', 'You ', 'Qiu ', 'Mao ', 'Xia ', 'Ying ', 'Shi ', 'Chong ', 'Tang ', 'Zhu ', 'Zong ', 'Ti ', 'Fu ', 'Yuan ',
+'Hui ', 'Meng ', 'La ', 'Du ', 'Hu ', 'Qiu ', 'Die ', 'Li ', 'Gua ', 'Yun ', 'Ju ', 'Nan ', 'Lou ', 'Qun ', 'Rong ', 'Ying ',
+'Jiang ', '[?]', 'Lang ', 'Pang ', 'Si ', 'Xi ', 'Ci ', 'Xi ', 'Yuan ', 'Weng ', 'Lian ', 'Sou ', 'Ban ', 'Rong ', 'Rong ', 'Ji ',
+'Wu ', 'Qiu ', 'Han ', 'Qin ', 'Yi ', 'Bi ', 'Hua ', 'Tang ', 'Yi ', 'Du ', 'Nai ', 'He ', 'Hu ', 'Hui ', 'Ma ', 'Ming ',
+'Yi ', 'Wen ', 'Ying ', 'Teng ', 'Yu ', 'Cang ', 'So ', 'Ebi ', 'Man ', '[?]', 'Shang ', 'Zhe ', 'Cao ', 'Chi ', 'Di ', 'Ao ',
+'Lu ', 'Wei ', 'Zhi ', 'Tang ', 'Chen ', 'Piao ', 'Qu ', 'Pi ', 'Yu ', 'Jian ', 'Luo ', 'Lou ', 'Qin ', 'Zhong ', 'Yin ', 'Jiang ',
+'Shuai ', 'Wen ', 'Jiao ', 'Wan ', 'Zhi ', 'Zhe ', 'Ma ', 'Ma ', 'Guo ', 'Liu ', 'Mao ', 'Xi ', 'Cong ', 'Li ', 'Man ', 'Xiao ',
+'Kamakiri ', 'Zhang ', 'Mang ', 'Xiang ', 'Mo ', 'Zui ', 'Si ', 'Qiu ', 'Te ', 'Zhi ', 'Peng ', 'Peng ', 'Jiao ', 'Qu ', 'Bie ', 'Liao ',
+'Pan ', 'Gui ', 'Xi ', 'Ji ', 'Zhuan ', 'Huang ', 'Fei ', 'Lao ', 'Jue ', 'Jue ', 'Hui ', 'Yin ', 'Chan ', 'Jiao ', 'Shan ', 'Rao ',
+'Xiao ', 'Mou ', 'Chong ', 'Xun ', 'Si ', '[?]', 'Cheng ', 'Dang ', 'Li ', 'Xie ', 'Shan ', 'Yi ', 'Jing ', 'Da ', 'Chan ', 'Qi ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x88.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x88.php
new file mode 100644 (file)
index 0000000..ac13d30
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x88] = array(
+'Ci ', 'Xiang ', 'She ', 'Luo ', 'Qin ', 'Ying ', 'Chai ', 'Li ', 'Ze ', 'Xuan ', 'Lian ', 'Zhu ', 'Ze ', 'Xie ', 'Mang ', 'Xie ',
+'Qi ', 'Rong ', 'Jian ', 'Meng ', 'Hao ', 'Ruan ', 'Huo ', 'Zhuo ', 'Jie ', 'Bin ', 'He ', 'Mie ', 'Fan ', 'Lei ', 'Jie ', 'La ',
+'Mi ', 'Li ', 'Chun ', 'Li ', 'Qiu ', 'Nie ', 'Lu ', 'Du ', 'Xiao ', 'Zhu ', 'Long ', 'Li ', 'Long ', 'Feng ', 'Ye ', 'Beng ',
+'Shang ', 'Gu ', 'Juan ', 'Ying ', '[?]', 'Xi ', 'Can ', 'Qu ', 'Quan ', 'Du ', 'Can ', 'Man ', 'Jue ', 'Jie ', 'Zhu ', 'Zha ',
+'Xie ', 'Huang ', 'Niu ', 'Pei ', 'Nu ', 'Xin ', 'Zhong ', 'Mo ', 'Er ', 'Ke ', 'Mie ', 'Xi ', 'Xing ', 'Yan ', 'Kan ', 'Yuan ',
+'[?]', 'Ling ', 'Xuan ', 'Shu ', 'Xian ', 'Tong ', 'Long ', 'Jie ', 'Xian ', 'Ya ', 'Hu ', 'Wei ', 'Dao ', 'Chong ', 'Wei ', 'Dao ',
+'Zhun ', 'Heng ', 'Qu ', 'Yi ', 'Yi ', 'Bu ', 'Gan ', 'Yu ', 'Biao ', 'Cha ', 'Yi ', 'Shan ', 'Chen ', 'Fu ', 'Gun ', 'Fen ',
+'Shuai ', 'Jie ', 'Na ', 'Zhong ', 'Dan ', 'Ri ', 'Zhong ', 'Zhong ', 'Xie ', 'Qi ', 'Xie ', 'Ran ', 'Zhi ', 'Ren ', 'Qin ', 'Jin ',
+'Jun ', 'Yuan ', 'Mei ', 'Chai ', 'Ao ', 'Niao ', 'Hui ', 'Ran ', 'Jia ', 'Tuo ', 'Ling ', 'Dai ', 'Bao ', 'Pao ', 'Yao ', 'Zuo ',
+'Bi ', 'Shao ', 'Tan ', 'Ju ', 'He ', 'Shu ', 'Xiu ', 'Zhen ', 'Yi ', 'Pa ', 'Bo ', 'Di ', 'Wa ', 'Fu ', 'Gun ', 'Zhi ',
+'Zhi ', 'Ran ', 'Pan ', 'Yi ', 'Mao ', 'Tuo ', 'Na ', 'Kou ', 'Xian ', 'Chan ', 'Qu ', 'Bei ', 'Gun ', 'Xi ', 'Ne ', 'Bo ',
+'Horo ', 'Fu ', 'Yi ', 'Chi ', 'Ku ', 'Ren ', 'Jiang ', 'Jia ', 'Cun ', 'Mo ', 'Jie ', 'Er ', 'Luo ', 'Ru ', 'Zhu ', 'Gui ',
+'Yin ', 'Cai ', 'Lie ', 'Kamishimo ', 'Yuki ', 'Zhuang ', 'Dang ', '[?]', 'Kun ', 'Ken ', 'Niao ', 'Shu ', 'Jia ', 'Kun ', 'Cheng ', 'Li ',
+'Juan ', 'Shen ', 'Pou ', 'Ge ', 'Yi ', 'Yu ', 'Zhen ', 'Liu ', 'Qiu ', 'Qun ', 'Ji ', 'Yi ', 'Bu ', 'Zhuang ', 'Shui ', 'Sha ',
+'Qun ', 'Li ', 'Lian ', 'Lian ', 'Ku ', 'Jian ', 'Fou ', 'Chan ', 'Bi ', 'Gun ', 'Tao ', 'Yuan ', 'Ling ', 'Chi ', 'Chang ', 'Chou ',
+'Duo ', 'Biao ', 'Liang ', 'Chang ', 'Pei ', 'Pei ', 'Fei ', 'Yuan ', 'Luo ', 'Guo ', 'Yan ', 'Du ', 'Xi ', 'Zhi ', 'Ju ', 'Qi ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x89.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x89.php
new file mode 100644 (file)
index 0000000..733142a
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x89] = array(
+'Ji ', 'Zhi ', 'Gua ', 'Ken ', 'Che ', 'Ti ', 'Ti ', 'Fu ', 'Chong ', 'Xie ', 'Bian ', 'Die ', 'Kun ', 'Duan ', 'Xiu ', 'Xiu ',
+'He ', 'Yuan ', 'Bao ', 'Bao ', 'Fu ', 'Yu ', 'Tuan ', 'Yan ', 'Hui ', 'Bei ', 'Chu ', 'Lu ', 'Ena ', 'Hitoe ', 'Yun ', 'Da ',
+'Gou ', 'Da ', 'Huai ', 'Rong ', 'Yuan ', 'Ru ', 'Nai ', 'Jiong ', 'Suo ', 'Ban ', 'Tun ', 'Chi ', 'Sang ', 'Niao ', 'Ying ', 'Jie ',
+'Qian ', 'Huai ', 'Ku ', 'Lian ', 'Bao ', 'Li ', 'Zhe ', 'Shi ', 'Lu ', 'Yi ', 'Die ', 'Xie ', 'Xian ', 'Wei ', 'Biao ', 'Cao ',
+'Ji ', 'Jiang ', 'Sen ', 'Bao ', 'Xiang ', 'Chihaya ', 'Pu ', 'Jian ', 'Zhuan ', 'Jian ', 'Zui ', 'Ji ', 'Dan ', 'Za ', 'Fan ', 'Bo ',
+'Xiang ', 'Xin ', 'Bie ', 'Rao ', 'Man ', 'Lan ', 'Ao ', 'Duo ', 'Gui ', 'Cao ', 'Sui ', 'Nong ', 'Chan ', 'Lian ', 'Bi ', 'Jin ',
+'Dang ', 'Shu ', 'Tan ', 'Bi ', 'Lan ', 'Pu ', 'Ru ', 'Zhi ', '[?]', 'Shu ', 'Wa ', 'Shi ', 'Bai ', 'Xie ', 'Bo ', 'Chen ',
+'Lai ', 'Long ', 'Xi ', 'Xian ', 'Lan ', 'Zhe ', 'Dai ', 'Tasuki ', 'Zan ', 'Shi ', 'Jian ', 'Pan ', 'Yi ', 'Ran ', 'Ya ', 'Xi ',
+'Xi ', 'Yao ', 'Feng ', 'Tan ', '[?]', 'Biao ', 'Fu ', 'Ba ', 'He ', 'Ji ', 'Ji ', 'Jian ', 'Guan ', 'Bian ', 'Yan ', 'Gui ',
+'Jue ', 'Pian ', 'Mao ', 'Mi ', 'Mi ', 'Mie ', 'Shi ', 'Si ', 'Zhan ', 'Luo ', 'Jue ', 'Mi ', 'Tiao ', 'Lian ', 'Yao ', 'Zhi ',
+'Jun ', 'Xi ', 'Shan ', 'Wei ', 'Xi ', 'Tian ', 'Yu ', 'Lan ', 'E ', 'Du ', 'Qin ', 'Pang ', 'Ji ', 'Ming ', 'Ying ', 'Gou ',
+'Qu ', 'Zhan ', 'Jin ', 'Guan ', 'Deng ', 'Jian ', 'Luo ', 'Qu ', 'Jian ', 'Wei ', 'Jue ', 'Qu ', 'Luo ', 'Lan ', 'Shen ', 'Di ',
+'Guan ', 'Jian ', 'Guan ', 'Yan ', 'Gui ', 'Mi ', 'Shi ', 'Zhan ', 'Lan ', 'Jue ', 'Ji ', 'Xi ', 'Di ', 'Tian ', 'Yu ', 'Gou ',
+'Jin ', 'Qu ', 'Jiao ', 'Jiu ', 'Jin ', 'Cu ', 'Jue ', 'Zhi ', 'Chao ', 'Ji ', 'Gu ', 'Dan ', 'Zui ', 'Di ', 'Shang ', 'Hua ',
+'Quan ', 'Ge ', 'Chi ', 'Jie ', 'Gui ', 'Gong ', 'Hong ', 'Jie ', 'Hun ', 'Qiu ', 'Xing ', 'Su ', 'Ni ', 'Ji ', 'Lu ', 'Zhi ',
+'Zha ', 'Bi ', 'Xing ', 'Hu ', 'Shang ', 'Gong ', 'Zhi ', 'Xue ', 'Chu ', 'Xi ', 'Yi ', 'Lu ', 'Jue ', 'Xi ', 'Yan ', 'Xi ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x8a.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x8a.php
new file mode 100644 (file)
index 0000000..b9d89bf
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x8a] = array(
+'Yan ', 'Yan ', 'Ding ', 'Fu ', 'Qiu ', 'Qiu ', 'Jiao ', 'Hong ', 'Ji ', 'Fan ', 'Xun ', 'Diao ', 'Hong ', 'Cha ', 'Tao ', 'Xu ',
+'Jie ', 'Yi ', 'Ren ', 'Xun ', 'Yin ', 'Shan ', 'Qi ', 'Tuo ', 'Ji ', 'Xun ', 'Yin ', 'E ', 'Fen ', 'Ya ', 'Yao ', 'Song ',
+'Shen ', 'Yin ', 'Xin ', 'Jue ', 'Xiao ', 'Ne ', 'Chen ', 'You ', 'Zhi ', 'Xiong ', 'Fang ', 'Xin ', 'Chao ', 'She ', 'Xian ', 'Sha ',
+'Tun ', 'Xu ', 'Yi ', 'Yi ', 'Su ', 'Chi ', 'He ', 'Shen ', 'He ', 'Xu ', 'Zhen ', 'Zhu ', 'Zheng ', 'Gou ', 'Zi ', 'Zi ',
+'Zhan ', 'Gu ', 'Fu ', 'Quan ', 'Die ', 'Ling ', 'Di ', 'Yang ', 'Li ', 'Nao ', 'Pan ', 'Zhou ', 'Gan ', 'Yi ', 'Ju ', 'Ao ',
+'Zha ', 'Tuo ', 'Yi ', 'Qu ', 'Zhao ', 'Ping ', 'Bi ', 'Xiong ', 'Qu ', 'Ba ', 'Da ', 'Zu ', 'Tao ', 'Zhu ', 'Ci ', 'Zhe ',
+'Yong ', 'Xu ', 'Xun ', 'Yi ', 'Huang ', 'He ', 'Shi ', 'Cha ', 'Jiao ', 'Shi ', 'Hen ', 'Cha ', 'Gou ', 'Gui ', 'Quan ', 'Hui ',
+'Jie ', 'Hua ', 'Gai ', 'Xiang ', 'Wei ', 'Shen ', 'Chou ', 'Tong ', 'Mi ', 'Zhan ', 'Ming ', 'E ', 'Hui ', 'Yan ', 'Xiong ', 'Gua ',
+'Er ', 'Beng ', 'Tiao ', 'Chi ', 'Lei ', 'Zhu ', 'Kuang ', 'Kua ', 'Wu ', 'Yu ', 'Teng ', 'Ji ', 'Zhi ', 'Ren ', 'Su ', 'Lang ',
+'E ', 'Kuang ', 'E ', 'Shi ', 'Ting ', 'Dan ', 'Bo ', 'Chan ', 'You ', 'Heng ', 'Qiao ', 'Qin ', 'Shua ', 'An ', 'Yu ', 'Xiao ',
+'Cheng ', 'Jie ', 'Xian ', 'Wu ', 'Wu ', 'Gao ', 'Song ', 'Pu ', 'Hui ', 'Jing ', 'Shuo ', 'Zhen ', 'Shuo ', 'Du ', 'Yasashi ', 'Chang ',
+'Shui ', 'Jie ', 'Ke ', 'Qu ', 'Cong ', 'Xiao ', 'Sui ', 'Wang ', 'Xuan ', 'Fei ', 'Chi ', 'Ta ', 'Yi ', 'Na ', 'Yin ', 'Diao ',
+'Pi ', 'Chuo ', 'Chan ', 'Chen ', 'Zhun ', 'Ji ', 'Qi ', 'Tan ', 'Zhui ', 'Wei ', 'Ju ', 'Qing ', 'Jian ', 'Zheng ', 'Ze ', 'Zou ',
+'Qian ', 'Zhuo ', 'Liang ', 'Jian ', 'Zhu ', 'Hao ', 'Lun ', 'Shen ', 'Biao ', 'Huai ', 'Pian ', 'Yu ', 'Die ', 'Xu ', 'Pian ', 'Shi ',
+'Xuan ', 'Shi ', 'Hun ', 'Hua ', 'E ', 'Zhong ', 'Di ', 'Xie ', 'Fu ', 'Pu ', 'Ting ', 'Jian ', 'Qi ', 'Yu ', 'Zi ', 'Chuan ',
+'Xi ', 'Hui ', 'Yin ', 'An ', 'Xian ', 'Nan ', 'Chen ', 'Feng ', 'Zhu ', 'Yang ', 'Yan ', 'Heng ', 'Xuan ', 'Ge ', 'Nuo ', 'Qi ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x8b.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x8b.php
new file mode 100644 (file)
index 0000000..576d716
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x8b] = array(
+'Mou ', 'Ye ', 'Wei ', '[?]', 'Teng ', 'Zou ', 'Shan ', 'Jian ', 'Bo ', 'Ku ', 'Huang ', 'Huo ', 'Ge ', 'Ying ', 'Mi ', 'Xiao ',
+'Mi ', 'Xi ', 'Qiang ', 'Chen ', 'Nue ', 'Ti ', 'Su ', 'Bang ', 'Chi ', 'Qian ', 'Shi ', 'Jiang ', 'Yuan ', 'Xie ', 'Xue ', 'Tao ',
+'Yao ', 'Yao ', '[?]', 'Yu ', 'Biao ', 'Cong ', 'Qing ', 'Li ', 'Mo ', 'Mo ', 'Shang ', 'Zhe ', 'Miu ', 'Jian ', 'Ze ', 'Jie ',
+'Lian ', 'Lou ', 'Can ', 'Ou ', 'Guan ', 'Xi ', 'Zhuo ', 'Ao ', 'Ao ', 'Jin ', 'Zhe ', 'Yi ', 'Hu ', 'Jiang ', 'Man ', 'Chao ',
+'Han ', 'Hua ', 'Chan ', 'Xu ', 'Zeng ', 'Se ', 'Xi ', 'She ', 'Dui ', 'Zheng ', 'Nao ', 'Lan ', 'E ', 'Ying ', 'Jue ', 'Ji ',
+'Zun ', 'Jiao ', 'Bo ', 'Hui ', 'Zhuan ', 'Mu ', 'Zen ', 'Zha ', 'Shi ', 'Qiao ', 'Tan ', 'Zen ', 'Pu ', 'Sheng ', 'Xuan ', 'Zao ',
+'Tan ', 'Dang ', 'Sui ', 'Qian ', 'Ji ', 'Jiao ', 'Jing ', 'Lian ', 'Nou ', 'Yi ', 'Ai ', 'Zhan ', 'Pi ', 'Hui ', 'Hua ', 'Yi ',
+'Yi ', 'Shan ', 'Rang ', 'Nou ', 'Qian ', 'Zhui ', 'Ta ', 'Hu ', 'Zhou ', 'Hao ', 'Ye ', 'Ying ', 'Jian ', 'Yu ', 'Jian ', 'Hui ',
+'Du ', 'Zhe ', 'Xuan ', 'Zan ', 'Lei ', 'Shen ', 'Wei ', 'Chan ', 'Li ', 'Yi ', 'Bian ', 'Zhe ', 'Yan ', 'E ', 'Chou ', 'Wei ',
+'Chou ', 'Yao ', 'Chan ', 'Rang ', 'Yin ', 'Lan ', 'Chen ', 'Huo ', 'Zhe ', 'Huan ', 'Zan ', 'Yi ', 'Dang ', 'Zhan ', 'Yan ', 'Du ',
+'Yan ', 'Ji ', 'Ding ', 'Fu ', 'Ren ', 'Ji ', 'Jie ', 'Hong ', 'Tao ', 'Rang ', 'Shan ', 'Qi ', 'Tuo ', 'Xun ', 'Yi ', 'Xun ',
+'Ji ', 'Ren ', 'Jiang ', 'Hui ', 'Ou ', 'Ju ', 'Ya ', 'Ne ', 'Xu ', 'E ', 'Lun ', 'Xiong ', 'Song ', 'Feng ', 'She ', 'Fang ',
+'Jue ', 'Zheng ', 'Gu ', 'He ', 'Ping ', 'Zu ', 'Shi ', 'Xiong ', 'Zha ', 'Su ', 'Zhen ', 'Di ', 'Zou ', 'Ci ', 'Qu ', 'Zhao ',
+'Bi ', 'Yi ', 'Yi ', 'Kuang ', 'Lei ', 'Shi ', 'Gua ', 'Shi ', 'Jie ', 'Hui ', 'Cheng ', 'Zhu ', 'Shen ', 'Hua ', 'Dan ', 'Gou ',
+'Quan ', 'Gui ', 'Xun ', 'Yi ', 'Zheng ', 'Gai ', 'Xiang ', 'Cha ', 'Hun ', 'Xu ', 'Zhou ', 'Jie ', 'Wu ', 'Yu ', 'Qiao ', 'Wu ',
+'Gao ', 'You ', 'Hui ', 'Kuang ', 'Shuo ', 'Song ', 'Ai ', 'Qing ', 'Zhu ', 'Zou ', 'Nuo ', 'Du ', 'Zhuo ', 'Fei ', 'Ke ', 'Wei ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x8c.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x8c.php
new file mode 100644 (file)
index 0000000..231af4a
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x8c] = array(
+'Yu ', 'Shui ', 'Shen ', 'Diao ', 'Chan ', 'Liang ', 'Zhun ', 'Sui ', 'Tan ', 'Shen ', 'Yi ', 'Mou ', 'Chen ', 'Die ', 'Huang ', 'Jian ',
+'Xie ', 'Nue ', 'Ye ', 'Wei ', 'E ', 'Yu ', 'Xuan ', 'Chan ', 'Zi ', 'An ', 'Yan ', 'Di ', 'Mi ', 'Pian ', 'Xu ', 'Mo ',
+'Dang ', 'Su ', 'Xie ', 'Yao ', 'Bang ', 'Shi ', 'Qian ', 'Mi ', 'Jin ', 'Man ', 'Zhe ', 'Jian ', 'Miu ', 'Tan ', 'Zen ', 'Qiao ',
+'Lan ', 'Pu ', 'Jue ', 'Yan ', 'Qian ', 'Zhan ', 'Chen ', 'Gu ', 'Qian ', 'Hong ', 'Xia ', 'Jue ', 'Hong ', 'Han ', 'Hong ', 'Xi ',
+'Xi ', 'Huo ', 'Liao ', 'Han ', 'Du ', 'Long ', 'Dou ', 'Jiang ', 'Qi ', 'Shi ', 'Li ', 'Deng ', 'Wan ', 'Bi ', 'Shu ', 'Xian ',
+'Feng ', 'Zhi ', 'Zhi ', 'Yan ', 'Yan ', 'Shi ', 'Chu ', 'Hui ', 'Tun ', 'Yi ', 'Tun ', 'Yi ', 'Jian ', 'Ba ', 'Hou ', 'E ',
+'Cu ', 'Xiang ', 'Huan ', 'Jian ', 'Ken ', 'Gai ', 'Qu ', 'Fu ', 'Xi ', 'Bin ', 'Hao ', 'Yu ', 'Zhu ', 'Jia ', '[?]', 'Xi ',
+'Bo ', 'Wen ', 'Huan ', 'Bin ', 'Di ', 'Zong ', 'Fen ', 'Yi ', 'Zhi ', 'Bao ', 'Chai ', 'Han ', 'Pi ', 'Na ', 'Pi ', 'Gou ',
+'Na ', 'You ', 'Diao ', 'Mo ', 'Si ', 'Xiu ', 'Huan ', 'Kun ', 'He ', 'He ', 'Mo ', 'Han ', 'Mao ', 'Li ', 'Ni ', 'Bi ',
+'Yu ', 'Jia ', 'Tuan ', 'Mao ', 'Pi ', 'Xi ', 'E ', 'Ju ', 'Mo ', 'Chu ', 'Tan ', 'Huan ', 'Jue ', 'Bei ', 'Zhen ', 'Yuan ',
+'Fu ', 'Cai ', 'Gong ', 'Te ', 'Yi ', 'Hang ', 'Wan ', 'Pin ', 'Huo ', 'Fan ', 'Tan ', 'Guan ', 'Ze ', 'Zhi ', 'Er ', 'Zhu ',
+'Shi ', 'Bi ', 'Zi ', 'Er ', 'Gui ', 'Pian ', 'Bian ', 'Mai ', 'Dai ', 'Sheng ', 'Kuang ', 'Fei ', 'Tie ', 'Yi ', 'Chi ', 'Mao ',
+'He ', 'Bi ', 'Lu ', 'Ren ', 'Hui ', 'Gai ', 'Pian ', 'Zi ', 'Jia ', 'Xu ', 'Zei ', 'Jiao ', 'Gai ', 'Zang ', 'Jian ', 'Ying ',
+'Xun ', 'Zhen ', 'She ', 'Bin ', 'Bin ', 'Qiu ', 'She ', 'Chuan ', 'Zang ', 'Zhou ', 'Lai ', 'Zan ', 'Si ', 'Chen ', 'Shang ', 'Tian ',
+'Pei ', 'Geng ', 'Xian ', 'Mai ', 'Jian ', 'Sui ', 'Fu ', 'Tan ', 'Cong ', 'Cong ', 'Zhi ', 'Ji ', 'Zhang ', 'Du ', 'Jin ', 'Xiong ',
+'Shun ', 'Yun ', 'Bao ', 'Zai ', 'Lai ', 'Feng ', 'Cang ', 'Ji ', 'Sheng ', 'Ai ', 'Zhuan ', 'Fu ', 'Gou ', 'Sai ', 'Ze ', 'Liao ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x8d.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x8d.php
new file mode 100644 (file)
index 0000000..b025551
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x8d] = array(
+'Wei ', 'Bai ', 'Chen ', 'Zhuan ', 'Zhi ', 'Zhui ', 'Biao ', 'Yun ', 'Zeng ', 'Tan ', 'Zan ', 'Yan ', '[?]', 'Shan ', 'Wan ', 'Ying ',
+'Jin ', 'Gan ', 'Xian ', 'Zang ', 'Bi ', 'Du ', 'Shu ', 'Yan ', '[?]', 'Xuan ', 'Long ', 'Gan ', 'Zang ', 'Bei ', 'Zhen ', 'Fu ',
+'Yuan ', 'Gong ', 'Cai ', 'Ze ', 'Xian ', 'Bai ', 'Zhang ', 'Huo ', 'Zhi ', 'Fan ', 'Tan ', 'Pin ', 'Bian ', 'Gou ', 'Zhu ', 'Guan ',
+'Er ', 'Jian ', 'Bi ', 'Shi ', 'Tie ', 'Gui ', 'Kuang ', 'Dai ', 'Mao ', 'Fei ', 'He ', 'Yi ', 'Zei ', 'Zhi ', 'Jia ', 'Hui ',
+'Zi ', 'Ren ', 'Lu ', 'Zang ', 'Zi ', 'Gai ', 'Jin ', 'Qiu ', 'Zhen ', 'Lai ', 'She ', 'Fu ', 'Du ', 'Ji ', 'Shu ', 'Shang ',
+'Si ', 'Bi ', 'Zhou ', 'Geng ', 'Pei ', 'Tan ', 'Lai ', 'Feng ', 'Zhui ', 'Fu ', 'Zhuan ', 'Sai ', 'Ze ', 'Yan ', 'Zan ', 'Yun ',
+'Zeng ', 'Shan ', 'Ying ', 'Gan ', 'Chi ', 'Xi ', 'She ', 'Nan ', 'Xiong ', 'Xi ', 'Cheng ', 'He ', 'Cheng ', 'Zhe ', 'Xia ', 'Tang ',
+'Zou ', 'Zou ', 'Li ', 'Jiu ', 'Fu ', 'Zhao ', 'Gan ', 'Qi ', 'Shan ', 'Qiong ', 'Qin ', 'Xian ', 'Ci ', 'Jue ', 'Qin ', 'Chi ',
+'Ci ', 'Chen ', 'Chen ', 'Die ', 'Ju ', 'Chao ', 'Di ', 'Se ', 'Zhan ', 'Zhu ', 'Yue ', 'Qu ', 'Jie ', 'Chi ', 'Chu ', 'Gua ',
+'Xue ', 'Ci ', 'Tiao ', 'Duo ', 'Lie ', 'Gan ', 'Suo ', 'Cu ', 'Xi ', 'Zhao ', 'Su ', 'Yin ', 'Ju ', 'Jian ', 'Que ', 'Tang ',
+'Chuo ', 'Cui ', 'Lu ', 'Qu ', 'Dang ', 'Qiu ', 'Zi ', 'Ti ', 'Qu ', 'Chi ', 'Huang ', 'Qiao ', 'Qiao ', 'Yao ', 'Zao ', 'Ti ',
+'[?]', 'Zan ', 'Zan ', 'Zu ', 'Pa ', 'Bao ', 'Ku ', 'Ke ', 'Dun ', 'Jue ', 'Fu ', 'Chen ', 'Jian ', 'Fang ', 'Zhi ', 'Sa ',
+'Yue ', 'Pa ', 'Qi ', 'Yue ', 'Qiang ', 'Tuo ', 'Tai ', 'Yi ', 'Nian ', 'Ling ', 'Mei ', 'Ba ', 'Die ', 'Ku ', 'Tuo ', 'Jia ',
+'Ci ', 'Pao ', 'Qia ', 'Zhu ', 'Ju ', 'Die ', 'Zhi ', 'Fu ', 'Pan ', 'Ju ', 'Shan ', 'Bo ', 'Ni ', 'Ju ', 'Li ', 'Gen ',
+'Yi ', 'Ji ', 'Dai ', 'Xian ', 'Jiao ', 'Duo ', 'Zhu ', 'Zhuan ', 'Kua ', 'Zhuai ', 'Gui ', 'Qiong ', 'Kui ', 'Xiang ', 'Chi ', 'Lu ',
+'Beng ', 'Zhi ', 'Jia ', 'Tiao ', 'Cai ', 'Jian ', 'Ta ', 'Qiao ', 'Bi ', 'Xian ', 'Duo ', 'Ji ', 'Ju ', 'Ji ', 'Shu ', 'Tu ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x8e.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x8e.php
new file mode 100644 (file)
index 0000000..d6cfc18
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x8e] = array(
+'Chu ', 'Jing ', 'Nie ', 'Xiao ', 'Bo ', 'Chi ', 'Qun ', 'Mou ', 'Shu ', 'Lang ', 'Yong ', 'Jiao ', 'Chou ', 'Qiao ', '[?]', 'Ta ',
+'Jian ', 'Qi ', 'Wo ', 'Wei ', 'Zhuo ', 'Jie ', 'Ji ', 'Nie ', 'Ju ', 'Ju ', 'Lun ', 'Lu ', 'Leng ', 'Huai ', 'Ju ', 'Chi ',
+'Wan ', 'Quan ', 'Ti ', 'Bo ', 'Zu ', 'Qie ', 'Ji ', 'Cu ', 'Zong ', 'Cai ', 'Zong ', 'Peng ', 'Zhi ', 'Zheng ', 'Dian ', 'Zhi ',
+'Yu ', 'Duo ', 'Dun ', 'Chun ', 'Yong ', 'Zhong ', 'Di ', 'Zhe ', 'Chen ', 'Chuai ', 'Jian ', 'Gua ', 'Tang ', 'Ju ', 'Fu ', 'Zu ',
+'Die ', 'Pian ', 'Rou ', 'Nuo ', 'Ti ', 'Cha ', 'Tui ', 'Jian ', 'Dao ', 'Cuo ', 'Xi ', 'Ta ', 'Qiang ', 'Zhan ', 'Dian ', 'Ti ',
+'Ji ', 'Nie ', 'Man ', 'Liu ', 'Zhan ', 'Bi ', 'Chong ', 'Lu ', 'Liao ', 'Cu ', 'Tang ', 'Dai ', 'Suo ', 'Xi ', 'Kui ', 'Ji ',
+'Zhi ', 'Qiang ', 'Di ', 'Man ', 'Zong ', 'Lian ', 'Beng ', 'Zao ', 'Nian ', 'Bie ', 'Tui ', 'Ju ', 'Deng ', 'Ceng ', 'Xian ', 'Fan ',
+'Chu ', 'Zhong ', 'Dun ', 'Bo ', 'Cu ', 'Zu ', 'Jue ', 'Jue ', 'Lin ', 'Ta ', 'Qiao ', 'Qiao ', 'Pu ', 'Liao ', 'Dun ', 'Cuan ',
+'Kuang ', 'Zao ', 'Ta ', 'Bi ', 'Bi ', 'Zhu ', 'Ju ', 'Chu ', 'Qiao ', 'Dun ', 'Chou ', 'Ji ', 'Wu ', 'Yue ', 'Nian ', 'Lin ',
+'Lie ', 'Zhi ', 'Li ', 'Zhi ', 'Chan ', 'Chu ', 'Duan ', 'Wei ', 'Long ', 'Lin ', 'Xian ', 'Wei ', 'Zuan ', 'Lan ', 'Xie ', 'Rang ',
+'Xie ', 'Nie ', 'Ta ', 'Qu ', 'Jie ', 'Cuan ', 'Zuan ', 'Xi ', 'Kui ', 'Jue ', 'Lin ', 'Shen ', 'Gong ', 'Dan ', 'Segare ', 'Qu ',
+'Ti ', 'Duo ', 'Duo ', 'Gong ', 'Lang ', 'Nerau ', 'Luo ', 'Ai ', 'Ji ', 'Ju ', 'Tang ', 'Utsuke ', '[?]', 'Yan ', 'Shitsuke ', 'Kang ',
+'Qu ', 'Lou ', 'Lao ', 'Tuo ', 'Zhi ', 'Yagate ', 'Ti ', 'Dao ', 'Yagate ', 'Yu ', 'Che ', 'Ya ', 'Gui ', 'Jun ', 'Wei ', 'Yue ',
+'Xin ', 'Di ', 'Xuan ', 'Fan ', 'Ren ', 'Shan ', 'Qiang ', 'Shu ', 'Tun ', 'Chen ', 'Dai ', 'E ', 'Na ', 'Qi ', 'Mao ', 'Ruan ',
+'Ren ', 'Fan ', 'Zhuan ', 'Hong ', 'Hu ', 'Qu ', 'Huang ', 'Di ', 'Ling ', 'Dai ', 'Ao ', 'Zhen ', 'Fan ', 'Kuang ', 'Ang ', 'Peng ',
+'Bei ', 'Gu ', 'Ku ', 'Pao ', 'Zhu ', 'Rong ', 'E ', 'Ba ', 'Zhou ', 'Zhi ', 'Yao ', 'Ke ', 'Yi ', 'Qing ', 'Shi ', 'Ping ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x8f.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x8f.php
new file mode 100644 (file)
index 0000000..62f5ca0
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x8f] = array(
+'Er ', 'Qiong ', 'Ju ', 'Jiao ', 'Guang ', 'Lu ', 'Kai ', 'Quan ', 'Zhou ', 'Zai ', 'Zhi ', 'She ', 'Liang ', 'Yu ', 'Shao ', 'You ',
+'Huan ', 'Yun ', 'Zhe ', 'Wan ', 'Fu ', 'Qing ', 'Zhou ', 'Ni ', 'Ling ', 'Zhe ', 'Zhan ', 'Liang ', 'Zi ', 'Hui ', 'Wang ', 'Chuo ',
+'Guo ', 'Kan ', 'Yi ', 'Peng ', 'Qian ', 'Gun ', 'Nian ', 'Pian ', 'Guan ', 'Bei ', 'Lun ', 'Pai ', 'Liang ', 'Ruan ', 'Rou ', 'Ji ',
+'Yang ', 'Xian ', 'Chuan ', 'Cou ', 'Qun ', 'Ge ', 'You ', 'Hong ', 'Shu ', 'Fu ', 'Zi ', 'Fu ', 'Wen ', 'Ben ', 'Zhan ', 'Yu ',
+'Wen ', 'Tao ', 'Gu ', 'Zhen ', 'Xia ', 'Yuan ', 'Lu ', 'Jiu ', 'Chao ', 'Zhuan ', 'Wei ', 'Hun ', 'Sori ', 'Che ', 'Jiao ', 'Zhan ',
+'Pu ', 'Lao ', 'Fen ', 'Fan ', 'Lin ', 'Ge ', 'Se ', 'Kan ', 'Huan ', 'Yi ', 'Ji ', 'Dui ', 'Er ', 'Yu ', 'Xian ', 'Hong ',
+'Lei ', 'Pei ', 'Li ', 'Li ', 'Lu ', 'Lin ', 'Che ', 'Ya ', 'Gui ', 'Xuan ', 'Di ', 'Ren ', 'Zhuan ', 'E ', 'Lun ', 'Ruan ',
+'Hong ', 'Ku ', 'Ke ', 'Lu ', 'Zhou ', 'Zhi ', 'Yi ', 'Hu ', 'Zhen ', 'Li ', 'Yao ', 'Qing ', 'Shi ', 'Zai ', 'Zhi ', 'Jiao ',
+'Zhou ', 'Quan ', 'Lu ', 'Jiao ', 'Zhe ', 'Fu ', 'Liang ', 'Nian ', 'Bei ', 'Hui ', 'Gun ', 'Wang ', 'Liang ', 'Chuo ', 'Zi ', 'Cou ',
+'Fu ', 'Ji ', 'Wen ', 'Shu ', 'Pei ', 'Yuan ', 'Xia ', 'Zhan ', 'Lu ', 'Che ', 'Lin ', 'Xin ', 'Gu ', 'Ci ', 'Ci ', 'Pi ',
+'Zui ', 'Bian ', 'La ', 'La ', 'Ci ', 'Xue ', 'Ban ', 'Bian ', 'Bian ', 'Bian ', '[?]', 'Bian ', 'Ban ', 'Ci ', 'Bian ', 'Bian ',
+'Chen ', 'Ru ', 'Nong ', 'Nong ', 'Zhen ', 'Chuo ', 'Chuo ', 'Suberu ', 'Reng ', 'Bian ', 'Bian ', 'Sip ', 'Ip ', 'Liao ', 'Da ', 'Chan ',
+'Gan ', 'Qian ', 'Yu ', 'Yu ', 'Qi ', 'Xun ', 'Yi ', 'Guo ', 'Mai ', 'Qi ', 'Za ', 'Wang ', 'Jia ', 'Zhun ', 'Ying ', 'Ti ',
+'Yun ', 'Jin ', 'Hang ', 'Ya ', 'Fan ', 'Wu ', 'Da ', 'E ', 'Huan ', 'Zhe ', 'Totemo ', 'Jin ', 'Yuan ', 'Wei ', 'Lian ', 'Chi ',
+'Che ', 'Ni ', 'Tiao ', 'Zhi ', 'Yi ', 'Jiong ', 'Jia ', 'Chen ', 'Dai ', 'Er ', 'Di ', 'Po ', 'Wang ', 'Die ', 'Ze ', 'Tao ',
+'Shu ', 'Tuo ', 'Kep ', 'Jing ', 'Hui ', 'Tong ', 'You ', 'Mi ', 'Beng ', 'Ji ', 'Nai ', 'Yi ', 'Jie ', 'Zhui ', 'Lie ', 'Xun ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x90.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x90.php
new file mode 100644 (file)
index 0000000..61840bf
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x90] = array(
+'Tui ', 'Song ', 'Gua ', 'Tao ', 'Pang ', 'Hou ', 'Ni ', 'Dun ', 'Jiong ', 'Xuan ', 'Xun ', 'Bu ', 'You ', 'Xiao ', 'Qiu ', 'Tou ',
+'Zhu ', 'Qiu ', 'Di ', 'Di ', 'Tu ', 'Jing ', 'Ti ', 'Dou ', 'Yi ', 'Zhe ', 'Tong ', 'Guang ', 'Wu ', 'Shi ', 'Cheng ', 'Su ',
+'Zao ', 'Qun ', 'Feng ', 'Lian ', 'Suo ', 'Hui ', 'Li ', 'Sako ', 'Lai ', 'Ben ', 'Cuo ', 'Jue ', 'Beng ', 'Huan ', 'Dai ', 'Lu ',
+'You ', 'Zhou ', 'Jin ', 'Yu ', 'Chuo ', 'Kui ', 'Wei ', 'Ti ', 'Yi ', 'Da ', 'Yuan ', 'Luo ', 'Bi ', 'Nuo ', 'Yu ', 'Dang ',
+'Sui ', 'Dun ', 'Sui ', 'Yan ', 'Chuan ', 'Chi ', 'Ti ', 'Yu ', 'Shi ', 'Zhen ', 'You ', 'Yun ', 'E ', 'Bian ', 'Guo ', 'E ',
+'Xia ', 'Huang ', 'Qiu ', 'Dao ', 'Da ', 'Wei ', 'Appare ', 'Yi ', 'Gou ', 'Yao ', 'Chu ', 'Liu ', 'Xun ', 'Ta ', 'Di ', 'Chi ',
+'Yuan ', 'Su ', 'Ta ', 'Qian ', '[?]', 'Yao ', 'Guan ', 'Zhang ', 'Ao ', 'Shi ', 'Ce ', 'Chi ', 'Su ', 'Zao ', 'Zhe ', 'Dun ',
+'Di ', 'Lou ', 'Chi ', 'Cuo ', 'Lin ', 'Zun ', 'Rao ', 'Qian ', 'Xuan ', 'Yu ', 'Yi ', 'Wu ', 'Liao ', 'Ju ', 'Shi ', 'Bi ',
+'Yao ', 'Mai ', 'Xie ', 'Sui ', 'Huan ', 'Zhan ', 'Teng ', 'Er ', 'Miao ', 'Bian ', 'Bian ', 'La ', 'Li ', 'Yuan ', 'Yao ', 'Luo ',
+'Li ', 'Yi ', 'Ting ', 'Deng ', 'Qi ', 'Yong ', 'Shan ', 'Han ', 'Yu ', 'Mang ', 'Ru ', 'Qiong ', '[?]', 'Kuang ', 'Fu ', 'Kang ',
+'Bin ', 'Fang ', 'Xing ', 'Na ', 'Xin ', 'Shen ', 'Bang ', 'Yuan ', 'Cun ', 'Huo ', 'Xie ', 'Bang ', 'Wu ', 'Ju ', 'You ', 'Han ',
+'Tai ', 'Qiu ', 'Bi ', 'Pei ', 'Bing ', 'Shao ', 'Bei ', 'Wa ', 'Di ', 'Zou ', 'Ye ', 'Lin ', 'Kuang ', 'Gui ', 'Zhu ', 'Shi ',
+'Ku ', 'Yu ', 'Gai ', 'Ge ', 'Xi ', 'Zhi ', 'Ji ', 'Xun ', 'Hou ', 'Xing ', 'Jiao ', 'Xi ', 'Gui ', 'Nuo ', 'Lang ', 'Jia ',
+'Kuai ', 'Zheng ', 'Otoko ', 'Yun ', 'Yan ', 'Cheng ', 'Dou ', 'Chi ', 'Lu ', 'Fu ', 'Wu ', 'Fu ', 'Gao ', 'Hao ', 'Lang ', 'Jia ',
+'Geng ', 'Jun ', 'Ying ', 'Bo ', 'Xi ', 'Bei ', 'Li ', 'Yun ', 'Bu ', 'Xiao ', 'Qi ', 'Pi ', 'Qing ', 'Guo ', 'Zhou ', 'Tan ',
+'Zou ', 'Ping ', 'Lai ', 'Ni ', 'Chen ', 'You ', 'Bu ', 'Xiang ', 'Dan ', 'Ju ', 'Yong ', 'Qiao ', 'Yi ', 'Du ', 'Yan ', 'Mei ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x91.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x91.php
new file mode 100644 (file)
index 0000000..e4dbcb7
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x91] = array(
+'Ruo ', 'Bei ', 'E ', 'Yu ', 'Juan ', 'Yu ', 'Yun ', 'Hou ', 'Kui ', 'Xiang ', 'Xiang ', 'Sou ', 'Tang ', 'Ming ', 'Xi ', 'Ru ',
+'Chu ', 'Zi ', 'Zou ', 'Ju ', 'Wu ', 'Xiang ', 'Yun ', 'Hao ', 'Yong ', 'Bi ', 'Mo ', 'Chao ', 'Fu ', 'Liao ', 'Yin ', 'Zhuan ',
+'Hu ', 'Qiao ', 'Yan ', 'Zhang ', 'Fan ', 'Qiao ', 'Xu ', 'Deng ', 'Bi ', 'Xin ', 'Bi ', 'Ceng ', 'Wei ', 'Zheng ', 'Mao ', 'Shan ',
+'Lin ', 'Po ', 'Dan ', 'Meng ', 'Ye ', 'Cao ', 'Kuai ', 'Feng ', 'Meng ', 'Zou ', 'Kuang ', 'Lian ', 'Zan ', 'Chan ', 'You ', 'Qi ',
+'Yan ', 'Chan ', 'Zan ', 'Ling ', 'Huan ', 'Xi ', 'Feng ', 'Zan ', 'Li ', 'You ', 'Ding ', 'Qiu ', 'Zhuo ', 'Pei ', 'Zhou ', 'Yi ',
+'Hang ', 'Yu ', 'Jiu ', 'Yan ', 'Zui ', 'Mao ', 'Dan ', 'Xu ', 'Tou ', 'Zhen ', 'Fen ', 'Sakenomoto ', '[?]', 'Yun ', 'Tai ', 'Tian ',
+'Qia ', 'Tuo ', 'Zuo ', 'Han ', 'Gu ', 'Su ', 'Po ', 'Chou ', 'Zai ', 'Ming ', 'Luo ', 'Chuo ', 'Chou ', 'You ', 'Tong ', 'Zhi ',
+'Xian ', 'Jiang ', 'Cheng ', 'Yin ', 'Tu ', 'Xiao ', 'Mei ', 'Ku ', 'Suan ', 'Lei ', 'Pu ', 'Zui ', 'Hai ', 'Yan ', 'Xi ', 'Niang ',
+'Wei ', 'Lu ', 'Lan ', 'Yan ', 'Tao ', 'Pei ', 'Zhan ', 'Chun ', 'Tan ', 'Zui ', 'Chuo ', 'Cu ', 'Kun ', 'Ti ', 'Mian ', 'Du ',
+'Hu ', 'Xu ', 'Xing ', 'Tan ', 'Jiu ', 'Chun ', 'Yun ', 'Po ', 'Ke ', 'Sou ', 'Mi ', 'Quan ', 'Chou ', 'Cuo ', 'Yun ', 'Yong ',
+'Ang ', 'Zha ', 'Hai ', 'Tang ', 'Jiang ', 'Piao ', 'Shan ', 'Yu ', 'Li ', 'Zao ', 'Lao ', 'Yi ', 'Jiang ', 'Pu ', 'Jiao ', 'Xi ',
+'Tan ', 'Po ', 'Nong ', 'Yi ', 'Li ', 'Ju ', 'Jiao ', 'Yi ', 'Niang ', 'Ru ', 'Xun ', 'Chou ', 'Yan ', 'Ling ', 'Mi ', 'Mi ',
+'Niang ', 'Xin ', 'Jiao ', 'Xi ', 'Mi ', 'Yan ', 'Bian ', 'Cai ', 'Shi ', 'You ', 'Shi ', 'Shi ', 'Li ', 'Zhong ', 'Ye ', 'Liang ',
+'Li ', 'Jin ', 'Jin ', 'Qiu ', 'Yi ', 'Diao ', 'Dao ', 'Zhao ', 'Ding ', 'Po ', 'Qiu ', 'He ', 'Fu ', 'Zhen ', 'Zhi ', 'Ba ',
+'Luan ', 'Fu ', 'Nai ', 'Diao ', 'Shan ', 'Qiao ', 'Kou ', 'Chuan ', 'Zi ', 'Fan ', 'Yu ', 'Hua ', 'Han ', 'Gong ', 'Qi ', 'Mang ',
+'Ri ', 'Di ', 'Si ', 'Xi ', 'Yi ', 'Chai ', 'Shi ', 'Tu ', 'Xi ', 'Nu ', 'Qian ', 'Ishiyumi ', 'Jian ', 'Pi ', 'Ye ', 'Yin ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x92.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x92.php
new file mode 100644 (file)
index 0000000..2715ade
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x92] = array(
+'Ba ', 'Fang ', 'Chen ', 'Xing ', 'Tou ', 'Yue ', 'Yan ', 'Fu ', 'Pi ', 'Na ', 'Xin ', 'E ', 'Jue ', 'Dun ', 'Gou ', 'Yin ',
+'Qian ', 'Ban ', 'Ji ', 'Ren ', 'Chao ', 'Niu ', 'Fen ', 'Yun ', 'Ji ', 'Qin ', 'Pi ', 'Guo ', 'Hong ', 'Yin ', 'Jun ', 'Shi ',
+'Yi ', 'Zhong ', 'Nie ', 'Gai ', 'Ri ', 'Huo ', 'Tai ', 'Kang ', 'Habaki ', 'Irori ', 'Ngaak ', '[?]', 'Duo ', 'Zi ', 'Ni ', 'Tu ',
+'Shi ', 'Min ', 'Gu ', 'E ', 'Ling ', 'Bing ', 'Yi ', 'Gu ', 'Ba ', 'Pi ', 'Yu ', 'Si ', 'Zuo ', 'Bu ', 'You ', 'Dian ',
+'Jia ', 'Zhen ', 'Shi ', 'Shi ', 'Tie ', 'Ju ', 'Zhan ', 'Shi ', 'She ', 'Xuan ', 'Zhao ', 'Bao ', 'He ', 'Bi ', 'Sheng ', 'Chu ',
+'Shi ', 'Bo ', 'Zhu ', 'Chi ', 'Za ', 'Po ', 'Tong ', 'Qian ', 'Fu ', 'Zhai ', 'Liu ', 'Qian ', 'Fu ', 'Li ', 'Yue ', 'Pi ',
+'Yang ', 'Ban ', 'Bo ', 'Jie ', 'Gou ', 'Shu ', 'Zheng ', 'Mu ', 'Ni ', 'Nie ', 'Di ', 'Jia ', 'Mu ', 'Dan ', 'Shen ', 'Yi ',
+'Si ', 'Kuang ', 'Ka ', 'Bei ', 'Jian ', 'Tong ', 'Xing ', 'Hong ', 'Jiao ', 'Chi ', 'Er ', 'Ge ', 'Bing ', 'Shi ', 'Mou ', 'Jia ',
+'Yin ', 'Jun ', 'Zhou ', 'Chong ', 'Shang ', 'Tong ', 'Mo ', 'Lei ', 'Ji ', 'Yu ', 'Xu ', 'Ren ', 'Zun ', 'Zhi ', 'Qiong ', 'Shan ',
+'Chi ', 'Xian ', 'Xing ', 'Quan ', 'Pi ', 'Tie ', 'Zhu ', 'Hou ', 'Ming ', 'Kua ', 'Yao ', 'Xian ', 'Xian ', 'Xiu ', 'Jun ', 'Cha ',
+'Lao ', 'Ji ', 'Pi ', 'Ru ', 'Mi ', 'Yi ', 'Yin ', 'Guang ', 'An ', 'Diou ', 'You ', 'Se ', 'Kao ', 'Qian ', 'Luan ', 'Kasugai ',
+'Ai ', 'Diao ', 'Han ', 'Rui ', 'Shi ', 'Keng ', 'Qiu ', 'Xiao ', 'Zhe ', 'Xiu ', 'Zang ', 'Ti ', 'Cuo ', 'Gua ', 'Gong ', 'Zhong ',
+'Dou ', 'Lu ', 'Mei ', 'Lang ', 'Wan ', 'Xin ', 'Yun ', 'Bei ', 'Wu ', 'Su ', 'Yu ', 'Chan ', 'Ting ', 'Bo ', 'Han ', 'Jia ',
+'Hong ', 'Cuan ', 'Feng ', 'Chan ', 'Wan ', 'Zhi ', 'Si ', 'Xuan ', 'Wu ', 'Wu ', 'Tiao ', 'Gong ', 'Zhuo ', 'Lue ', 'Xing ', 'Qian ',
+'Shen ', 'Han ', 'Lue ', 'Xie ', 'Chu ', 'Zheng ', 'Ju ', 'Xian ', 'Tie ', 'Mang ', 'Pu ', 'Li ', 'Pan ', 'Rui ', 'Cheng ', 'Gao ',
+'Li ', 'Te ', 'Pyeng ', 'Zhu ', '[?]', 'Tu ', 'Liu ', 'Zui ', 'Ju ', 'Chang ', 'Yuan ', 'Jian ', 'Gang ', 'Diao ', 'Tao ', 'Chang ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x93.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x93.php
new file mode 100644 (file)
index 0000000..124a1fa
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x93] = array(
+'Lun ', 'Kua ', 'Ling ', 'Bei ', 'Lu ', 'Li ', 'Qiang ', 'Pou ', 'Juan ', 'Min ', 'Zui ', 'Peng ', 'An ', 'Pi ', 'Xian ', 'Ya ',
+'Zhui ', 'Lei ', 'A ', 'Kong ', 'Ta ', 'Kun ', 'Du ', 'Wei ', 'Chui ', 'Zi ', 'Zheng ', 'Ben ', 'Nie ', 'Cong ', 'Qun ', 'Tan ',
+'Ding ', 'Qi ', 'Qian ', 'Zhuo ', 'Qi ', 'Yu ', 'Jin ', 'Guan ', 'Mao ', 'Chang ', 'Tian ', 'Xi ', 'Lian ', 'Tao ', 'Gu ', 'Cuo ',
+'Shu ', 'Zhen ', 'Lu ', 'Meng ', 'Lu ', 'Hua ', 'Biao ', 'Ga ', 'Lai ', 'Ken ', 'Kazari ', 'Bu ', 'Nai ', 'Wan ', 'Zan ', '[?]',
+'De ', 'Xian ', '[?]', 'Huo ', 'Liang ', '[?]', 'Men ', 'Kai ', 'Ying ', 'Di ', 'Lian ', 'Guo ', 'Xian ', 'Du ', 'Tu ', 'Wei ',
+'Cong ', 'Fu ', 'Rou ', 'Ji ', 'E ', 'Rou ', 'Chen ', 'Ti ', 'Zha ', 'Hong ', 'Yang ', 'Duan ', 'Xia ', 'Yu ', 'Keng ', 'Xing ',
+'Huang ', 'Wei ', 'Fu ', 'Zhao ', 'Cha ', 'Qie ', 'She ', 'Hong ', 'Kui ', 'Tian ', 'Mou ', 'Qiao ', 'Qiao ', 'Hou ', 'Tou ', 'Cong ',
+'Huan ', 'Ye ', 'Min ', 'Jian ', 'Duan ', 'Jian ', 'Song ', 'Kui ', 'Hu ', 'Xuan ', 'Duo ', 'Jie ', 'Zhen ', 'Bian ', 'Zhong ', 'Zi ',
+'Xiu ', 'Ye ', 'Mei ', 'Pai ', 'Ai ', 'Jie ', '[?]', 'Mei ', 'Chuo ', 'Ta ', 'Bang ', 'Xia ', 'Lian ', 'Suo ', 'Xi ', 'Liu ',
+'Zu ', 'Ye ', 'Nou ', 'Weng ', 'Rong ', 'Tang ', 'Suo ', 'Qiang ', 'Ge ', 'Shuo ', 'Chui ', 'Bo ', 'Pan ', 'Sa ', 'Bi ', 'Sang ',
+'Gang ', 'Zi ', 'Wu ', 'Ying ', 'Huang ', 'Tiao ', 'Liu ', 'Kai ', 'Sun ', 'Sha ', 'Sou ', 'Wan ', 'Hao ', 'Zhen ', 'Zhen ', 'Luo ',
+'Yi ', 'Yuan ', 'Tang ', 'Nie ', 'Xi ', 'Jia ', 'Ge ', 'Ma ', 'Juan ', 'Kasugai ', 'Habaki ', 'Suo ', '[?]', '[?]', '[?]', 'Na ',
+'Lu ', 'Suo ', 'Ou ', 'Zu ', 'Tuan ', 'Xiu ', 'Guan ', 'Xuan ', 'Lian ', 'Shou ', 'Ao ', 'Man ', 'Mo ', 'Luo ', 'Bi ', 'Wei ',
+'Liu ', 'Di ', 'Qiao ', 'Cong ', 'Yi ', 'Lu ', 'Ao ', 'Keng ', 'Qiang ', 'Cui ', 'Qi ', 'Chang ', 'Tang ', 'Man ', 'Yong ', 'Chan ',
+'Feng ', 'Jing ', 'Biao ', 'Shu ', 'Lou ', 'Xiu ', 'Cong ', 'Long ', 'Zan ', 'Jian ', 'Cao ', 'Li ', 'Xia ', 'Xi ', 'Kang ', '[?]',
+'Beng ', '[?]', '[?]', 'Zheng ', 'Lu ', 'Hua ', 'Ji ', 'Pu ', 'Hui ', 'Qiang ', 'Po ', 'Lin ', 'Suo ', 'Xiu ', 'San ', 'Cheng ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x94.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x94.php
new file mode 100644 (file)
index 0000000..edd5f83
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x94] = array(
+'Kui ', 'Si ', 'Liu ', 'Nao ', 'Heng ', 'Pie ', 'Sui ', 'Fan ', 'Qiao ', 'Quan ', 'Yang ', 'Tang ', 'Xiang ', 'Jue ', 'Jiao ', 'Zun ',
+'Liao ', 'Jie ', 'Lao ', 'Dui ', 'Tan ', 'Zan ', 'Ji ', 'Jian ', 'Zhong ', 'Deng ', 'Ya ', 'Ying ', 'Dui ', 'Jue ', 'Nou ', 'Ti ',
+'Pu ', 'Tie ', '[?]', '[?]', 'Ding ', 'Shan ', 'Kai ', 'Jian ', 'Fei ', 'Sui ', 'Lu ', 'Juan ', 'Hui ', 'Yu ', 'Lian ', 'Zhuo ',
+'Qiao ', 'Qian ', 'Zhuo ', 'Lei ', 'Bi ', 'Tie ', 'Huan ', 'Ye ', 'Duo ', 'Guo ', 'Dang ', 'Ju ', 'Fen ', 'Da ', 'Bei ', 'Yi ',
+'Ai ', 'Zong ', 'Xun ', 'Diao ', 'Zhu ', 'Heng ', 'Zhui ', 'Ji ', 'Nie ', 'Ta ', 'Huo ', 'Qing ', 'Bin ', 'Ying ', 'Kui ', 'Ning ',
+'Xu ', 'Jian ', 'Jian ', 'Yari ', 'Cha ', 'Zhi ', 'Mie ', 'Li ', 'Lei ', 'Ji ', 'Zuan ', 'Kuang ', 'Shang ', 'Peng ', 'La ', 'Du ',
+'Shuo ', 'Chuo ', 'Lu ', 'Biao ', 'Bao ', 'Lu ', '[?]', '[?]', 'Long ', 'E ', 'Lu ', 'Xin ', 'Jian ', 'Lan ', 'Bo ', 'Jian ',
+'Yao ', 'Chan ', 'Xiang ', 'Jian ', 'Xi ', 'Guan ', 'Cang ', 'Nie ', 'Lei ', 'Cuan ', 'Qu ', 'Pan ', 'Luo ', 'Zuan ', 'Luan ', 'Zao ',
+'Nie ', 'Jue ', 'Tang ', 'Shu ', 'Lan ', 'Jin ', 'Qiu ', 'Yi ', 'Zhen ', 'Ding ', 'Zhao ', 'Po ', 'Diao ', 'Tu ', 'Qian ', 'Chuan ',
+'Shan ', 'Ji ', 'Fan ', 'Diao ', 'Men ', 'Nu ', 'Xi ', 'Chai ', 'Xing ', 'Gai ', 'Bu ', 'Tai ', 'Ju ', 'Dun ', 'Chao ', 'Zhong ',
+'Na ', 'Bei ', 'Gang ', 'Ban ', 'Qian ', 'Yao ', 'Qin ', 'Jun ', 'Wu ', 'Gou ', 'Kang ', 'Fang ', 'Huo ', 'Tou ', 'Niu ', 'Ba ',
+'Yu ', 'Qian ', 'Zheng ', 'Qian ', 'Gu ', 'Bo ', 'E ', 'Po ', 'Bu ', 'Ba ', 'Yue ', 'Zuan ', 'Mu ', 'Dan ', 'Jia ', 'Dian ',
+'You ', 'Tie ', 'Bo ', 'Ling ', 'Shuo ', 'Qian ', 'Liu ', 'Bao ', 'Shi ', 'Xuan ', 'She ', 'Bi ', 'Ni ', 'Pi ', 'Duo ', 'Xing ',
+'Kao ', 'Lao ', 'Er ', 'Mang ', 'Ya ', 'You ', 'Cheng ', 'Jia ', 'Ye ', 'Nao ', 'Zhi ', 'Dang ', 'Tong ', 'Lu ', 'Diao ', 'Yin ',
+'Kai ', 'Zha ', 'Zhu ', 'Xian ', 'Ting ', 'Diu ', 'Xian ', 'Hua ', 'Quan ', 'Sha ', 'Jia ', 'Yao ', 'Ge ', 'Ming ', 'Zheng ', 'Se ',
+'Jiao ', 'Yi ', 'Chan ', 'Chong ', 'Tang ', 'An ', 'Yin ', 'Ru ', 'Zhu ', 'Lao ', 'Pu ', 'Wu ', 'Lai ', 'Te ', 'Lian ', 'Keng ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x95.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x95.php
new file mode 100644 (file)
index 0000000..1f87df6
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x95] = array(
+'Xiao ', 'Suo ', 'Li ', 'Zheng ', 'Chu ', 'Guo ', 'Gao ', 'Tie ', 'Xiu ', 'Cuo ', 'Lue ', 'Feng ', 'Xin ', 'Liu ', 'Kai ', 'Jian ',
+'Rui ', 'Ti ', 'Lang ', 'Qian ', 'Ju ', 'A ', 'Qiang ', 'Duo ', 'Tian ', 'Cuo ', 'Mao ', 'Ben ', 'Qi ', 'De ', 'Kua ', 'Kun ',
+'Chang ', 'Xi ', 'Gu ', 'Luo ', 'Chui ', 'Zhui ', 'Jin ', 'Zhi ', 'Xian ', 'Juan ', 'Huo ', 'Pou ', 'Tan ', 'Ding ', 'Jian ', 'Ju ',
+'Meng ', 'Zi ', 'Qie ', 'Ying ', 'Kai ', 'Qiang ', 'Song ', 'E ', 'Cha ', 'Qiao ', 'Zhong ', 'Duan ', 'Sou ', 'Huang ', 'Huan ', 'Ai ',
+'Du ', 'Mei ', 'Lou ', 'Zi ', 'Fei ', 'Mei ', 'Mo ', 'Zhen ', 'Bo ', 'Ge ', 'Nie ', 'Tang ', 'Juan ', 'Nie ', 'Na ', 'Liu ',
+'Hao ', 'Bang ', 'Yi ', 'Jia ', 'Bin ', 'Rong ', 'Biao ', 'Tang ', 'Man ', 'Luo ', 'Beng ', 'Yong ', 'Jing ', 'Di ', 'Zu ', 'Xuan ',
+'Liu ', 'Tan ', 'Jue ', 'Liao ', 'Pu ', 'Lu ', 'Dui ', 'Lan ', 'Pu ', 'Cuan ', 'Qiang ', 'Deng ', 'Huo ', 'Lei ', 'Huan ', 'Zhuo ',
+'Lian ', 'Yi ', 'Cha ', 'Biao ', 'La ', 'Chan ', 'Xiang ', 'Chang ', 'Chang ', 'Jiu ', 'Ao ', 'Die ', 'Qu ', 'Liao ', 'Mi ', 'Chang ',
+'Men ', 'Ma ', 'Shuan ', 'Shan ', 'Huo ', 'Men ', 'Yan ', 'Bi ', 'Han ', 'Bi ', 'San ', 'Kai ', 'Kang ', 'Beng ', 'Hong ', 'Run ',
+'San ', 'Xian ', 'Xian ', 'Jian ', 'Min ', 'Xia ', 'Yuru ', 'Dou ', 'Zha ', 'Nao ', 'Jian ', 'Peng ', 'Xia ', 'Ling ', 'Bian ', 'Bi ',
+'Run ', 'He ', 'Guan ', 'Ge ', 'Ge ', 'Fa ', 'Chu ', 'Hong ', 'Gui ', 'Min ', 'Se ', 'Kun ', 'Lang ', 'Lu ', 'Ting ', 'Sha ',
+'Ju ', 'Yue ', 'Yue ', 'Chan ', 'Qu ', 'Lin ', 'Chang ', 'Shai ', 'Kun ', 'Yan ', 'Min ', 'Yan ', 'E ', 'Hun ', 'Yu ', 'Wen ',
+'Xiang ', 'Bao ', 'Xiang ', 'Qu ', 'Yao ', 'Wen ', 'Ban ', 'An ', 'Wei ', 'Yin ', 'Kuo ', 'Que ', 'Lan ', 'Du ', '[?]', 'Phwung ',
+'Tian ', 'Nie ', 'Ta ', 'Kai ', 'He ', 'Que ', 'Chuang ', 'Guan ', 'Dou ', 'Qi ', 'Kui ', 'Tang ', 'Guan ', 'Piao ', 'Kan ', 'Xi ',
+'Hui ', 'Chan ', 'Pi ', 'Dang ', 'Huan ', 'Ta ', 'Wen ', '[?]', 'Men ', 'Shuan ', 'Shan ', 'Yan ', 'Han ', 'Bi ', 'Wen ', 'Chuang ',
+'Run ', 'Wei ', 'Xian ', 'Hong ', 'Jian ', 'Min ', 'Kang ', 'Men ', 'Zha ', 'Nao ', 'Gui ', 'Wen ', 'Ta ', 'Min ', 'Lu ', 'Kai ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x96.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x96.php
new file mode 100644 (file)
index 0000000..6d8fac2
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x96] = array(
+'Fa ', 'Ge ', 'He ', 'Kun ', 'Jiu ', 'Yue ', 'Lang ', 'Du ', 'Yu ', 'Yan ', 'Chang ', 'Xi ', 'Wen ', 'Hun ', 'Yan ', 'E ',
+'Chan ', 'Lan ', 'Qu ', 'Hui ', 'Kuo ', 'Que ', 'Ge ', 'Tian ', 'Ta ', 'Que ', 'Kan ', 'Huan ', 'Fu ', 'Fu ', 'Le ', 'Dui ',
+'Xin ', 'Qian ', 'Wu ', 'Yi ', 'Tuo ', 'Yin ', 'Yang ', 'Dou ', 'E ', 'Sheng ', 'Ban ', 'Pei ', 'Keng ', 'Yun ', 'Ruan ', 'Zhi ',
+'Pi ', 'Jing ', 'Fang ', 'Yang ', 'Yin ', 'Zhen ', 'Jie ', 'Cheng ', 'E ', 'Qu ', 'Di ', 'Zu ', 'Zuo ', 'Dian ', 'Ling ', 'A ',
+'Tuo ', 'Tuo ', 'Po ', 'Bing ', 'Fu ', 'Ji ', 'Lu ', 'Long ', 'Chen ', 'Xing ', 'Duo ', 'Lou ', 'Mo ', 'Jiang ', 'Shu ', 'Duo ',
+'Xian ', 'Er ', 'Gui ', 'Yu ', 'Gai ', 'Shan ', 'Xun ', 'Qiao ', 'Xing ', 'Chun ', 'Fu ', 'Bi ', 'Xia ', 'Shan ', 'Sheng ', 'Zhi ',
+'Pu ', 'Dou ', 'Yuan ', 'Zhen ', 'Chu ', 'Xian ', 'Tou ', 'Nie ', 'Yun ', 'Xian ', 'Pei ', 'Pei ', 'Zou ', 'Yi ', 'Dui ', 'Lun ',
+'Yin ', 'Ju ', 'Chui ', 'Chen ', 'Pi ', 'Ling ', 'Tao ', 'Xian ', 'Lu ', 'Sheng ', 'Xian ', 'Yin ', 'Zhu ', 'Yang ', 'Reng ', 'Shan ',
+'Chong ', 'Yan ', 'Yin ', 'Yu ', 'Ti ', 'Yu ', 'Long ', 'Wei ', 'Wei ', 'Nie ', 'Dui ', 'Sui ', 'An ', 'Huang ', 'Jie ', 'Sui ',
+'Yin ', 'Gai ', 'Yan ', 'Hui ', 'Ge ', 'Yun ', 'Wu ', 'Wei ', 'Ai ', 'Xi ', 'Tang ', 'Ji ', 'Zhang ', 'Dao ', 'Ao ', 'Xi ',
+'Yin ', '[?]', 'Rao ', 'Lin ', 'Tui ', 'Deng ', 'Pi ', 'Sui ', 'Sui ', 'Yu ', 'Xian ', 'Fen ', 'Ni ', 'Er ', 'Ji ', 'Dao ',
+'Xi ', 'Yin ', 'E ', 'Hui ', 'Long ', 'Xi ', 'Li ', 'Li ', 'Li ', 'Zhui ', 'He ', 'Zhi ', 'Zhun ', 'Jun ', 'Nan ', 'Yi ',
+'Que ', 'Yan ', 'Qian ', 'Ya ', 'Xiong ', 'Ya ', 'Ji ', 'Gu ', 'Huan ', 'Zhi ', 'Gou ', 'Jun ', 'Ci ', 'Yong ', 'Ju ', 'Chu ',
+'Hu ', 'Za ', 'Luo ', 'Yu ', 'Chou ', 'Diao ', 'Sui ', 'Han ', 'Huo ', 'Shuang ', 'Guan ', 'Chu ', 'Za ', 'Yong ', 'Ji ', 'Xi ',
+'Chou ', 'Liu ', 'Li ', 'Nan ', 'Xue ', 'Za ', 'Ji ', 'Ji ', 'Yu ', 'Yu ', 'Xue ', 'Na ', 'Fou ', 'Se ', 'Mu ', 'Wen ',
+'Fen ', 'Pang ', 'Yun ', 'Li ', 'Li ', 'Ang ', 'Ling ', 'Lei ', 'An ', 'Bao ', 'Meng ', 'Dian ', 'Dang ', 'Xing ', 'Wu ', 'Zhao ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x97.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x97.php
new file mode 100644 (file)
index 0000000..b09dca9
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x97] = array(
+'Xu ', 'Ji ', 'Mu ', 'Chen ', 'Xiao ', 'Zha ', 'Ting ', 'Zhen ', 'Pei ', 'Mei ', 'Ling ', 'Qi ', 'Chou ', 'Huo ', 'Sha ', 'Fei ',
+'Weng ', 'Zhan ', 'Yin ', 'Ni ', 'Chou ', 'Tun ', 'Lin ', '[?]', 'Dong ', 'Ying ', 'Wu ', 'Ling ', 'Shuang ', 'Ling ', 'Xia ', 'Hong ',
+'Yin ', 'Mo ', 'Mai ', 'Yun ', 'Liu ', 'Meng ', 'Bin ', 'Wu ', 'Wei ', 'Huo ', 'Yin ', 'Xi ', 'Yi ', 'Ai ', 'Dan ', 'Deng ',
+'Xian ', 'Yu ', 'Lu ', 'Long ', 'Dai ', 'Ji ', 'Pang ', 'Yang ', 'Ba ', 'Pi ', 'Wei ', '[?]', 'Xi ', 'Ji ', 'Mai ', 'Meng ',
+'Meng ', 'Lei ', 'Li ', 'Huo ', 'Ai ', 'Fei ', 'Dai ', 'Long ', 'Ling ', 'Ai ', 'Feng ', 'Li ', 'Bao ', '[?]', 'He ', 'He ',
+'Bing ', 'Qing ', 'Qing ', 'Jing ', 'Tian ', 'Zhen ', 'Jing ', 'Cheng ', 'Qing ', 'Jing ', 'Jing ', 'Dian ', 'Jing ', 'Tian ', 'Fei ', 'Fei ',
+'Kao ', 'Mi ', 'Mian ', 'Mian ', 'Pao ', 'Ye ', 'Tian ', 'Hui ', 'Ye ', 'Ge ', 'Ding ', 'Cha ', 'Jian ', 'Ren ', 'Di ', 'Du ',
+'Wu ', 'Ren ', 'Qin ', 'Jin ', 'Xue ', 'Niu ', 'Ba ', 'Yin ', 'Sa ', 'Na ', 'Mo ', 'Zu ', 'Da ', 'Ban ', 'Yi ', 'Yao ',
+'Tao ', 'Tuo ', 'Jia ', 'Hong ', 'Pao ', 'Yang ', 'Tomo ', 'Yin ', 'Jia ', 'Tao ', 'Ji ', 'Xie ', 'An ', 'An ', 'Hen ', 'Gong ',
+'Kohaze ', 'Da ', 'Qiao ', 'Ting ', 'Wan ', 'Ying ', 'Sui ', 'Tiao ', 'Qiao ', 'Xuan ', 'Kong ', 'Beng ', 'Ta ', 'Zhang ', 'Bing ', 'Kuo ',
+'Ju ', 'La ', 'Xie ', 'Rou ', 'Bang ', 'Yi ', 'Qiu ', 'Qiu ', 'He ', 'Xiao ', 'Mu ', 'Ju ', 'Jian ', 'Bian ', 'Di ', 'Jian ',
+'On ', 'Tao ', 'Gou ', 'Ta ', 'Bei ', 'Xie ', 'Pan ', 'Ge ', 'Bi ', 'Kuo ', 'Tang ', 'Lou ', 'Gui ', 'Qiao ', 'Xue ', 'Ji ',
+'Jian ', 'Jiang ', 'Chan ', 'Da ', 'Huo ', 'Xian ', 'Qian ', 'Du ', 'Wa ', 'Jian ', 'Lan ', 'Wei ', 'Ren ', 'Fu ', 'Mei ', 'Juan ',
+'Ge ', 'Wei ', 'Qiao ', 'Han ', 'Chang ', '[?]', 'Rou ', 'Xun ', 'She ', 'Wei ', 'Ge ', 'Bei ', 'Tao ', 'Gou ', 'Yun ', '[?]',
+'Bi ', 'Wei ', 'Hui ', 'Du ', 'Wa ', 'Du ', 'Wei ', 'Ren ', 'Fu ', 'Han ', 'Wei ', 'Yun ', 'Tao ', 'Jiu ', 'Jiu ', 'Xian ',
+'Xie ', 'Xian ', 'Ji ', 'Yin ', 'Za ', 'Yun ', 'Shao ', 'Le ', 'Peng ', 'Heng ', 'Ying ', 'Yun ', 'Peng ', 'Yin ', 'Yin ', 'Xiang ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x98.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x98.php
new file mode 100644 (file)
index 0000000..54d1a1a
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x98] = array(
+'Hu ', 'Ye ', 'Ding ', 'Qing ', 'Pan ', 'Xiang ', 'Shun ', 'Han ', 'Xu ', 'Yi ', 'Xu ', 'Gu ', 'Song ', 'Kui ', 'Qi ', 'Hang ',
+'Yu ', 'Wan ', 'Ban ', 'Dun ', 'Di ', 'Dan ', 'Pan ', 'Po ', 'Ling ', 'Ce ', 'Jing ', 'Lei ', 'He ', 'Qiao ', 'E ', 'E ',
+'Wei ', 'Jie ', 'Gua ', 'Shen ', 'Yi ', 'Shen ', 'Hai ', 'Dui ', 'Pian ', 'Ping ', 'Lei ', 'Fu ', 'Jia ', 'Tou ', 'Hui ', 'Kui ',
+'Jia ', 'Le ', 'Tian ', 'Cheng ', 'Ying ', 'Jun ', 'Hu ', 'Han ', 'Jing ', 'Tui ', 'Tui ', 'Pin ', 'Lai ', 'Tui ', 'Zi ', 'Zi ',
+'Chui ', 'Ding ', 'Lai ', 'Yan ', 'Han ', 'Jian ', 'Ke ', 'Cui ', 'Jiong ', 'Qin ', 'Yi ', 'Sai ', 'Ti ', 'E ', 'E ', 'Yan ',
+'Hun ', 'Kan ', 'Yong ', 'Zhuan ', 'Yan ', 'Xian ', 'Xin ', 'Yi ', 'Yuan ', 'Sang ', 'Dian ', 'Dian ', 'Jiang ', 'Ku ', 'Lei ', 'Liao ',
+'Piao ', 'Yi ', 'Man ', 'Qi ', 'Rao ', 'Hao ', 'Qiao ', 'Gu ', 'Xun ', 'Qian ', 'Hui ', 'Zhan ', 'Ru ', 'Hong ', 'Bin ', 'Xian ',
+'Pin ', 'Lu ', 'Lan ', 'Nie ', 'Quan ', 'Ye ', 'Ding ', 'Qing ', 'Han ', 'Xiang ', 'Shun ', 'Xu ', 'Xu ', 'Wan ', 'Gu ', 'Dun ',
+'Qi ', 'Ban ', 'Song ', 'Hang ', 'Yu ', 'Lu ', 'Ling ', 'Po ', 'Jing ', 'Jie ', 'Jia ', 'Tian ', 'Han ', 'Ying ', 'Jiong ', 'Hai ',
+'Yi ', 'Pin ', 'Hui ', 'Tui ', 'Han ', 'Ying ', 'Ying ', 'Ke ', 'Ti ', 'Yong ', 'E ', 'Zhuan ', 'Yan ', 'E ', 'Nie ', 'Man ',
+'Dian ', 'Sang ', 'Hao ', 'Lei ', 'Zhan ', 'Ru ', 'Pin ', 'Quan ', 'Feng ', 'Biao ', 'Oroshi ', 'Fu ', 'Xia ', 'Zhan ', 'Biao ', 'Sa ',
+'Ba ', 'Tai ', 'Lie ', 'Gua ', 'Xuan ', 'Shao ', 'Ju ', 'Bi ', 'Si ', 'Wei ', 'Yang ', 'Yao ', 'Sou ', 'Kai ', 'Sao ', 'Fan ',
+'Liu ', 'Xi ', 'Liao ', 'Piao ', 'Piao ', 'Liu ', 'Biao ', 'Biao ', 'Biao ', 'Liao ', '[?]', 'Se ', 'Feng ', 'Biao ', 'Feng ', 'Yang ',
+'Zhan ', 'Biao ', 'Sa ', 'Ju ', 'Si ', 'Sou ', 'Yao ', 'Liu ', 'Piao ', 'Biao ', 'Biao ', 'Fei ', 'Fan ', 'Fei ', 'Fei ', 'Shi ',
+'Shi ', 'Can ', 'Ji ', 'Ding ', 'Si ', 'Tuo ', 'Zhan ', 'Sun ', 'Xiang ', 'Tun ', 'Ren ', 'Yu ', 'Juan ', 'Chi ', 'Yin ', 'Fan ',
+'Fan ', 'Sun ', 'Yin ', 'Zhu ', 'Yi ', 'Zhai ', 'Bi ', 'Jie ', 'Tao ', 'Liu ', 'Ci ', 'Tie ', 'Si ', 'Bao ', 'Shi ', 'Duo ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x99.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x99.php
new file mode 100644 (file)
index 0000000..6863736
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x99] = array(
+'Hai ', 'Ren ', 'Tian ', 'Jiao ', 'Jia ', 'Bing ', 'Yao ', 'Tong ', 'Ci ', 'Xiang ', 'Yang ', 'Yang ', 'Er ', 'Yan ', 'Le ', 'Yi ',
+'Can ', 'Bo ', 'Nei ', 'E ', 'Bu ', 'Jun ', 'Dou ', 'Su ', 'Yu ', 'Shi ', 'Yao ', 'Hun ', 'Guo ', 'Shi ', 'Jian ', 'Zhui ',
+'Bing ', 'Xian ', 'Bu ', 'Ye ', 'Tan ', 'Fei ', 'Zhang ', 'Wei ', 'Guan ', 'E ', 'Nuan ', 'Hun ', 'Hu ', 'Huang ', 'Tie ', 'Hui ',
+'Jian ', 'Hou ', 'He ', 'Xing ', 'Fen ', 'Wei ', 'Gu ', 'Cha ', 'Song ', 'Tang ', 'Bo ', 'Gao ', 'Xi ', 'Kui ', 'Liu ', 'Sou ',
+'Tao ', 'Ye ', 'Yun ', 'Mo ', 'Tang ', 'Man ', 'Bi ', 'Yu ', 'Xiu ', 'Jin ', 'San ', 'Kui ', 'Zhuan ', 'Shan ', 'Chi ', 'Dan ',
+'Yi ', 'Ji ', 'Rao ', 'Cheng ', 'Yong ', 'Tao ', 'Hui ', 'Xiang ', 'Zhan ', 'Fen ', 'Hai ', 'Meng ', 'Yan ', 'Mo ', 'Chan ', 'Xiang ',
+'Luo ', 'Zuan ', 'Nang ', 'Shi ', 'Ding ', 'Ji ', 'Tuo ', 'Xing ', 'Tun ', 'Xi ', 'Ren ', 'Yu ', 'Chi ', 'Fan ', 'Yin ', 'Jian ',
+'Shi ', 'Bao ', 'Si ', 'Duo ', 'Yi ', 'Er ', 'Rao ', 'Xiang ', 'Jia ', 'Le ', 'Jiao ', 'Yi ', 'Bing ', 'Bo ', 'Dou ', 'E ',
+'Yu ', 'Nei ', 'Jun ', 'Guo ', 'Hun ', 'Xian ', 'Guan ', 'Cha ', 'Kui ', 'Gu ', 'Sou ', 'Chan ', 'Ye ', 'Mo ', 'Bo ', 'Liu ',
+'Xiu ', 'Jin ', 'Man ', 'San ', 'Zhuan ', 'Nang ', 'Shou ', 'Kui ', 'Guo ', 'Xiang ', 'Fen ', 'Ba ', 'Ni ', 'Bi ', 'Bo ', 'Tu ',
+'Han ', 'Fei ', 'Jian ', 'An ', 'Ai ', 'Fu ', 'Xian ', 'Wen ', 'Xin ', 'Fen ', 'Bin ', 'Xing ', 'Ma ', 'Yu ', 'Feng ', 'Han ',
+'Di ', 'Tuo ', 'Tuo ', 'Chi ', 'Xun ', 'Zhu ', 'Zhi ', 'Pei ', 'Xin ', 'Ri ', 'Sa ', 'Yin ', 'Wen ', 'Zhi ', 'Dan ', 'Lu ',
+'You ', 'Bo ', 'Bao ', 'Kuai ', 'Tuo ', 'Yi ', 'Qu ', '[?]', 'Qu ', 'Jiong ', 'Bo ', 'Zhao ', 'Yuan ', 'Peng ', 'Zhou ', 'Ju ',
+'Zhu ', 'Nu ', 'Ju ', 'Pi ', 'Zang ', 'Jia ', 'Ling ', 'Zhen ', 'Tai ', 'Fu ', 'Yang ', 'Shi ', 'Bi ', 'Tuo ', 'Tuo ', 'Si ',
+'Liu ', 'Ma ', 'Pian ', 'Tao ', 'Zhi ', 'Rong ', 'Teng ', 'Dong ', 'Xun ', 'Quan ', 'Shen ', 'Jiong ', 'Er ', 'Hai ', 'Bo ', 'Zhu ',
+'Yin ', 'Luo ', 'Shuu ', 'Dan ', 'Xie ', 'Liu ', 'Ju ', 'Song ', 'Qin ', 'Mang ', 'Liang ', 'Han ', 'Tu ', 'Xuan ', 'Tui ', 'Jun ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x9a.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x9a.php
new file mode 100644 (file)
index 0000000..5597b9a
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x9a] = array(
+'E ', 'Cheng ', 'Xin ', 'Ai ', 'Lu ', 'Zhui ', 'Zhou ', 'She ', 'Pian ', 'Kun ', 'Tao ', 'Lai ', 'Zong ', 'Ke ', 'Qi ', 'Qi ',
+'Yan ', 'Fei ', 'Sao ', 'Yan ', 'Jie ', 'Yao ', 'Wu ', 'Pian ', 'Cong ', 'Pian ', 'Qian ', 'Fei ', 'Huang ', 'Jian ', 'Huo ', 'Yu ',
+'Ti ', 'Quan ', 'Xia ', 'Zong ', 'Kui ', 'Rou ', 'Si ', 'Gua ', 'Tuo ', 'Kui ', 'Sou ', 'Qian ', 'Cheng ', 'Zhi ', 'Liu ', 'Pang ',
+'Teng ', 'Xi ', 'Cao ', 'Du ', 'Yan ', 'Yuan ', 'Zou ', 'Sao ', 'Shan ', 'Li ', 'Zhi ', 'Shuang ', 'Lu ', 'Xi ', 'Luo ', 'Zhang ',
+'Mo ', 'Ao ', 'Can ', 'Piao ', 'Cong ', 'Qu ', 'Bi ', 'Zhi ', 'Yu ', 'Xu ', 'Hua ', 'Bo ', 'Su ', 'Xiao ', 'Lin ', 'Chan ',
+'Dun ', 'Liu ', 'Tuo ', 'Zeng ', 'Tan ', 'Jiao ', 'Tie ', 'Yan ', 'Luo ', 'Zhan ', 'Jing ', 'Yi ', 'Ye ', 'Tuo ', 'Bin ', 'Zou ',
+'Yan ', 'Peng ', 'Lu ', 'Teng ', 'Xiang ', 'Ji ', 'Shuang ', 'Ju ', 'Xi ', 'Huan ', 'Li ', 'Biao ', 'Ma ', 'Yu ', 'Tuo ', 'Xun ',
+'Chi ', 'Qu ', 'Ri ', 'Bo ', 'Lu ', 'Zang ', 'Shi ', 'Si ', 'Fu ', 'Ju ', 'Zou ', 'Zhu ', 'Tuo ', 'Nu ', 'Jia ', 'Yi ',
+'Tai ', 'Xiao ', 'Ma ', 'Yin ', 'Jiao ', 'Hua ', 'Luo ', 'Hai ', 'Pian ', 'Biao ', 'Li ', 'Cheng ', 'Yan ', 'Xin ', 'Qin ', 'Jun ',
+'Qi ', 'Qi ', 'Ke ', 'Zhui ', 'Zong ', 'Su ', 'Can ', 'Pian ', 'Zhi ', 'Kui ', 'Sao ', 'Wu ', 'Ao ', 'Liu ', 'Qian ', 'Shan ',
+'Piao ', 'Luo ', 'Cong ', 'Chan ', 'Zou ', 'Ji ', 'Shuang ', 'Xiang ', 'Gu ', 'Wei ', 'Wei ', 'Wei ', 'Yu ', 'Gan ', 'Yi ', 'Ang ',
+'Tou ', 'Xie ', 'Bao ', 'Bi ', 'Chi ', 'Ti ', 'Di ', 'Ku ', 'Hai ', 'Qiao ', 'Gou ', 'Kua ', 'Ge ', 'Tui ', 'Geng ', 'Pian ',
+'Bi ', 'Ke ', 'Ka ', 'Yu ', 'Sui ', 'Lou ', 'Bo ', 'Xiao ', 'Pang ', 'Bo ', 'Ci ', 'Kuan ', 'Bin ', 'Mo ', 'Liao ', 'Lou ',
+'Nao ', 'Du ', 'Zang ', 'Sui ', 'Ti ', 'Bin ', 'Kuan ', 'Lu ', 'Gao ', 'Gao ', 'Qiao ', 'Kao ', 'Qiao ', 'Lao ', 'Zao ', 'Biao ',
+'Kun ', 'Kun ', 'Ti ', 'Fang ', 'Xiu ', 'Ran ', 'Mao ', 'Dan ', 'Kun ', 'Bin ', 'Fa ', 'Tiao ', 'Peng ', 'Zi ', 'Fa ', 'Ran ',
+'Ti ', 'Pao ', 'Pi ', 'Mao ', 'Fu ', 'Er ', 'Rong ', 'Qu ', 'Gong ', 'Xiu ', 'Gua ', 'Ji ', 'Peng ', 'Zhua ', 'Shao ', 'Sha ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x9b.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x9b.php
new file mode 100644 (file)
index 0000000..2659f06
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x9b] = array(
+'Ti ', 'Li ', 'Bin ', 'Zong ', 'Ti ', 'Peng ', 'Song ', 'Zheng ', 'Quan ', 'Zong ', 'Shun ', 'Jian ', 'Duo ', 'Hu ', 'La ', 'Jiu ',
+'Qi ', 'Lian ', 'Zhen ', 'Bin ', 'Peng ', 'Mo ', 'San ', 'Man ', 'Man ', 'Seng ', 'Xu ', 'Lie ', 'Qian ', 'Qian ', 'Nong ', 'Huan ',
+'Kuai ', 'Ning ', 'Bin ', 'Lie ', 'Rang ', 'Dou ', 'Dou ', 'Nao ', 'Hong ', 'Xi ', 'Dou ', 'Han ', 'Dou ', 'Dou ', 'Jiu ', 'Chang ',
+'Yu ', 'Yu ', 'Li ', 'Juan ', 'Fu ', 'Qian ', 'Gui ', 'Zong ', 'Liu ', 'Gui ', 'Shang ', 'Yu ', 'Gui ', 'Mei ', 'Ji ', 'Qi ',
+'Jie ', 'Kui ', 'Hun ', 'Ba ', 'Po ', 'Mei ', 'Xu ', 'Yan ', 'Xiao ', 'Liang ', 'Yu ', 'Tui ', 'Qi ', 'Wang ', 'Liang ', 'Wei ',
+'Jian ', 'Chi ', 'Piao ', 'Bi ', 'Mo ', 'Ji ', 'Xu ', 'Chou ', 'Yan ', 'Zhan ', 'Yu ', 'Dao ', 'Ren ', 'Ji ', 'Eri ', 'Gong ',
+'Tuo ', 'Diao ', 'Ji ', 'Xu ', 'E ', 'E ', 'Sha ', 'Hang ', 'Tun ', 'Mo ', 'Jie ', 'Shen ', 'Fan ', 'Yuan ', 'Bi ', 'Lu ',
+'Wen ', 'Hu ', 'Lu ', 'Za ', 'Fang ', 'Fen ', 'Na ', 'You ', 'Namazu ', 'Todo ', 'He ', 'Xia ', 'Qu ', 'Han ', 'Pi ', 'Ling ',
+'Tuo ', 'Bo ', 'Qiu ', 'Ping ', 'Fu ', 'Bi ', 'Ji ', 'Wei ', 'Ju ', 'Diao ', 'Bo ', 'You ', 'Gun ', 'Pi ', 'Nian ', 'Xing ',
+'Tai ', 'Bao ', 'Fu ', 'Zha ', 'Ju ', 'Gu ', 'Kajika ', 'Tong ', '[?]', 'Ta ', 'Jie ', 'Shu ', 'Hou ', 'Xiang ', 'Er ', 'An ',
+'Wei ', 'Tiao ', 'Zhu ', 'Yin ', 'Lie ', 'Luo ', 'Tong ', 'Yi ', 'Qi ', 'Bing ', 'Wei ', 'Jiao ', 'Bu ', 'Gui ', 'Xian ', 'Ge ',
+'Hui ', 'Bora ', 'Mate ', 'Kao ', 'Gori ', 'Duo ', 'Jun ', 'Ti ', 'Man ', 'Xiao ', 'Za ', 'Sha ', 'Qin ', 'Yu ', 'Nei ', 'Zhe ',
+'Gun ', 'Geng ', 'Su ', 'Wu ', 'Qiu ', 'Ting ', 'Fu ', 'Wan ', 'You ', 'Li ', 'Sha ', 'Sha ', 'Gao ', 'Meng ', 'Ugui ', 'Asari ',
+'Subashiri ', 'Kazunoko ', 'Yong ', 'Ni ', 'Zi ', 'Qi ', 'Qing ', 'Xiang ', 'Nei ', 'Chun ', 'Ji ', 'Diao ', 'Qie ', 'Gu ', 'Zhou ', 'Dong ',
+'Lai ', 'Fei ', 'Ni ', 'Yi ', 'Kun ', 'Lu ', 'Jiu ', 'Chang ', 'Jing ', 'Lun ', 'Ling ', 'Zou ', 'Li ', 'Meng ', 'Zong ', 'Zhi ',
+'Nian ', 'Shachi ', 'Dojou ', 'Sukesou ', 'Shi ', 'Shen ', 'Hun ', 'Shi ', 'Hou ', 'Xing ', 'Zhu ', 'La ', 'Zong ', 'Ji ', 'Bian ', 'Bian ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x9c.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x9c.php
new file mode 100644 (file)
index 0000000..c458ea7
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x9c] = array(
+'Huan ', 'Quan ', 'Ze ', 'Wei ', 'Wei ', 'Yu ', 'Qun ', 'Rou ', 'Die ', 'Huang ', 'Lian ', 'Yan ', 'Qiu ', 'Qiu ', 'Jian ', 'Bi ',
+'E ', 'Yang ', 'Fu ', 'Sai ', 'Jian ', 'Xia ', 'Tuo ', 'Hu ', 'Muroaji ', 'Ruo ', 'Haraka ', 'Wen ', 'Jian ', 'Hao ', 'Wu ', 'Fang ',
+'Sao ', 'Liu ', 'Ma ', 'Shi ', 'Shi ', 'Yin ', 'Z ', 'Teng ', 'Ta ', 'Yao ', 'Ge ', 'Rong ', 'Qian ', 'Qi ', 'Wen ', 'Ruo ',
+'Hatahata ', 'Lian ', 'Ao ', 'Le ', 'Hui ', 'Min ', 'Ji ', 'Tiao ', 'Qu ', 'Jian ', 'Sao ', 'Man ', 'Xi ', 'Qiu ', 'Biao ', 'Ji ',
+'Ji ', 'Zhu ', 'Jiang ', 'Qiu ', 'Zhuan ', 'Yong ', 'Zhang ', 'Kang ', 'Xue ', 'Bie ', 'Jue ', 'Qu ', 'Xiang ', 'Bo ', 'Jiao ', 'Xun ',
+'Su ', 'Huang ', 'Zun ', 'Shan ', 'Shan ', 'Fan ', 'Jue ', 'Lin ', 'Xun ', 'Miao ', 'Xi ', 'Eso ', 'Kyou ', 'Fen ', 'Guan ', 'Hou ',
+'Kuai ', 'Zei ', 'Sao ', 'Zhan ', 'Gan ', 'Gui ', 'Sheng ', 'Li ', 'Chang ', 'Hatahata ', 'Shiira ', 'Mutsu ', 'Ru ', 'Ji ', 'Xu ', 'Huo ',
+'Shiira ', 'Li ', 'Lie ', 'Li ', 'Mie ', 'Zhen ', 'Xiang ', 'E ', 'Lu ', 'Guan ', 'Li ', 'Xian ', 'Yu ', 'Dao ', 'Ji ', 'You ',
+'Tun ', 'Lu ', 'Fang ', 'Ba ', 'He ', 'Bo ', 'Ping ', 'Nian ', 'Lu ', 'You ', 'Zha ', 'Fu ', 'Bo ', 'Bao ', 'Hou ', 'Pi ',
+'Tai ', 'Gui ', 'Jie ', 'Kao ', 'Wei ', 'Er ', 'Tong ', 'Ze ', 'Hou ', 'Kuai ', 'Ji ', 'Jiao ', 'Xian ', 'Za ', 'Xiang ', 'Xun ',
+'Geng ', 'Li ', 'Lian ', 'Jian ', 'Li ', 'Shi ', 'Tiao ', 'Gun ', 'Sha ', 'Wan ', 'Jun ', 'Ji ', 'Yong ', 'Qing ', 'Ling ', 'Qi ',
+'Zou ', 'Fei ', 'Kun ', 'Chang ', 'Gu ', 'Ni ', 'Nian ', 'Diao ', 'Jing ', 'Shen ', 'Shi ', 'Zi ', 'Fen ', 'Die ', 'Bi ', 'Chang ',
+'Shi ', 'Wen ', 'Wei ', 'Sai ', 'E ', 'Qiu ', 'Fu ', 'Huang ', 'Quan ', 'Jiang ', 'Bian ', 'Sao ', 'Ao ', 'Qi ', 'Ta ', 'Yin ',
+'Yao ', 'Fang ', 'Jian ', 'Le ', 'Biao ', 'Xue ', 'Bie ', 'Man ', 'Min ', 'Yong ', 'Wei ', 'Xi ', 'Jue ', 'Shan ', 'Lin ', 'Zun ',
+'Huo ', 'Gan ', 'Li ', 'Zhan ', 'Guan ', 'Niao ', 'Yi ', 'Fu ', 'Li ', 'Jiu ', 'Bu ', 'Yan ', 'Fu ', 'Diao ', 'Ji ', 'Feng ',
+'Nio ', 'Gan ', 'Shi ', 'Feng ', 'Ming ', 'Bao ', 'Yuan ', 'Zhi ', 'Hu ', 'Qin ', 'Fu ', 'Fen ', 'Wen ', 'Jian ', 'Shi ', 'Yu ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x9d.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x9d.php
new file mode 100644 (file)
index 0000000..7e733e5
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x9d] = array(
+'Fou ', 'Yiao ', 'Jue ', 'Jue ', 'Pi ', 'Huan ', 'Zhen ', 'Bao ', 'Yan ', 'Ya ', 'Zheng ', 'Fang ', 'Feng ', 'Wen ', 'Ou ', 'Te ',
+'Jia ', 'Nu ', 'Ling ', 'Mie ', 'Fu ', 'Tuo ', 'Wen ', 'Li ', 'Bian ', 'Zhi ', 'Ge ', 'Yuan ', 'Zi ', 'Qu ', 'Xiao ', 'Zhi ',
+'Dan ', 'Ju ', 'You ', 'Gu ', 'Zhong ', 'Yu ', 'Yang ', 'Rong ', 'Ya ', 'Tie ', 'Yu ', 'Shigi ', 'Ying ', 'Zhui ', 'Wu ', 'Er ',
+'Gua ', 'Ai ', 'Zhi ', 'Yan ', 'Heng ', 'Jiao ', 'Ji ', 'Lie ', 'Zhu ', 'Ren ', 'Yi ', 'Hong ', 'Luo ', 'Ru ', 'Mou ', 'Ge ',
+'Ren ', 'Jiao ', 'Xiu ', 'Zhou ', 'Zhi ', 'Luo ', 'Chidori ', 'Toki ', 'Ten ', 'Luan ', 'Jia ', 'Ji ', 'Yu ', 'Huan ', 'Tuo ', 'Bu ',
+'Wu ', 'Juan ', 'Yu ', 'Bo ', 'Xun ', 'Xun ', 'Bi ', 'Xi ', 'Jun ', 'Ju ', 'Tu ', 'Jing ', 'Ti ', 'E ', 'E ', 'Kuang ',
+'Hu ', 'Wu ', 'Shen ', 'Lai ', 'Ikaruga ', 'Kakesu ', 'Lu ', 'Ping ', 'Shu ', 'Fu ', 'An ', 'Zhao ', 'Peng ', 'Qin ', 'Qian ', 'Bei ',
+'Diao ', 'Lu ', 'Que ', 'Jian ', 'Ju ', 'Tu ', 'Ya ', 'Yuan ', 'Qi ', 'Li ', 'Ye ', 'Zhui ', 'Kong ', 'Zhui ', 'Kun ', 'Sheng ',
+'Qi ', 'Jing ', 'Yi ', 'Yi ', 'Jing ', 'Zi ', 'Lai ', 'Dong ', 'Qi ', 'Chun ', 'Geng ', 'Ju ', 'Qu ', 'Isuka ', 'Kikuitadaki ', 'Ji ',
+'Shu ', '[?]', 'Chi ', 'Miao ', 'Rou ', 'An ', 'Qiu ', 'Ti ', 'Hu ', 'Ti ', 'E ', 'Jie ', 'Mao ', 'Fu ', 'Chun ', 'Tu ',
+'Yan ', 'He ', 'Yuan ', 'Pian ', 'Yun ', 'Mei ', 'Hu ', 'Ying ', 'Dun ', 'Mu ', 'Ju ', 'Tsugumi ', 'Cang ', 'Fang ', 'Gu ', 'Ying ',
+'Yuan ', 'Xuan ', 'Weng ', 'Shi ', 'He ', 'Chu ', 'Tang ', 'Xia ', 'Ruo ', 'Liu ', 'Ji ', 'Gu ', 'Jian ', 'Zhun ', 'Han ', 'Zi ',
+'Zi ', 'Ni ', 'Yao ', 'Yan ', 'Ji ', 'Li ', 'Tian ', 'Kou ', 'Ti ', 'Ti ', 'Ni ', 'Tu ', 'Ma ', 'Jiao ', 'Gao ', 'Tian ',
+'Chen ', 'Li ', 'Zhuan ', 'Zhe ', 'Ao ', 'Yao ', 'Yi ', 'Ou ', 'Chi ', 'Zhi ', 'Liao ', 'Rong ', 'Lou ', 'Bi ', 'Shuang ', 'Zhuo ',
+'Yu ', 'Wu ', 'Jue ', 'Yin ', 'Quan ', 'Si ', 'Jiao ', 'Yi ', 'Hua ', 'Bi ', 'Ying ', 'Su ', 'Huang ', 'Fan ', 'Jiao ', 'Liao ',
+'Yan ', 'Kao ', 'Jiu ', 'Xian ', 'Xian ', 'Tu ', 'Mai ', 'Zun ', 'Yu ', 'Ying ', 'Lu ', 'Tuan ', 'Xian ', 'Xue ', 'Yi ', 'Pi ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x9e.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x9e.php
new file mode 100644 (file)
index 0000000..2c32db9
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x9e] = array(
+'Shu ', 'Luo ', 'Qi ', 'Yi ', 'Ji ', 'Zhe ', 'Yu ', 'Zhan ', 'Ye ', 'Yang ', 'Pi ', 'Ning ', 'Huo ', 'Mi ', 'Ying ', 'Meng ',
+'Di ', 'Yue ', 'Yu ', 'Lei ', 'Bao ', 'Lu ', 'He ', 'Long ', 'Shuang ', 'Yue ', 'Ying ', 'Guan ', 'Qu ', 'Li ', 'Luan ', 'Niao ',
+'Jiu ', 'Ji ', 'Yuan ', 'Ming ', 'Shi ', 'Ou ', 'Ya ', 'Cang ', 'Bao ', 'Zhen ', 'Gu ', 'Dong ', 'Lu ', 'Ya ', 'Xiao ', 'Yang ',
+'Ling ', 'Zhi ', 'Qu ', 'Yuan ', 'Xue ', 'Tuo ', 'Si ', 'Zhi ', 'Er ', 'Gua ', 'Xiu ', 'Heng ', 'Zhou ', 'Ge ', 'Luan ', 'Hong ',
+'Wu ', 'Bo ', 'Li ', 'Juan ', 'Hu ', 'E ', 'Yu ', 'Xian ', 'Ti ', 'Wu ', 'Que ', 'Miao ', 'An ', 'Kun ', 'Bei ', 'Peng ',
+'Qian ', 'Chun ', 'Geng ', 'Yuan ', 'Su ', 'Hu ', 'He ', 'E ', 'Gu ', 'Qiu ', 'Zi ', 'Mei ', 'Mu ', 'Ni ', 'Yao ', 'Weng ',
+'Liu ', 'Ji ', 'Ni ', 'Jian ', 'He ', 'Yi ', 'Ying ', 'Zhe ', 'Liao ', 'Liao ', 'Jiao ', 'Jiu ', 'Yu ', 'Lu ', 'Xuan ', 'Zhan ',
+'Ying ', 'Huo ', 'Meng ', 'Guan ', 'Shuang ', 'Lu ', 'Jin ', 'Ling ', 'Jian ', 'Xian ', 'Cuo ', 'Jian ', 'Jian ', 'Yan ', 'Cuo ', 'Lu ',
+'You ', 'Cu ', 'Ji ', 'Biao ', 'Cu ', 'Biao ', 'Zhu ', 'Jun ', 'Zhu ', 'Jian ', 'Mi ', 'Mi ', 'Wu ', 'Liu ', 'Chen ', 'Jun ',
+'Lin ', 'Ni ', 'Qi ', 'Lu ', 'Jiu ', 'Jun ', 'Jing ', 'Li ', 'Xiang ', 'Yan ', 'Jia ', 'Mi ', 'Li ', 'She ', 'Zhang ', 'Lin ',
+'Jing ', 'Ji ', 'Ling ', 'Yan ', 'Cu ', 'Mai ', 'Mai ', 'Ge ', 'Chao ', 'Fu ', 'Mian ', 'Mian ', 'Fu ', 'Pao ', 'Qu ', 'Qu ',
+'Mou ', 'Fu ', 'Xian ', 'Lai ', 'Qu ', 'Mian ', '[?]', 'Feng ', 'Fu ', 'Qu ', 'Mian ', 'Ma ', 'Mo ', 'Mo ', 'Hui ', 'Ma ',
+'Zou ', 'Nen ', 'Fen ', 'Huang ', 'Huang ', 'Jin ', 'Guang ', 'Tian ', 'Tou ', 'Heng ', 'Xi ', 'Kuang ', 'Heng ', 'Shu ', 'Li ', 'Nian ',
+'Chi ', 'Hei ', 'Hei ', 'Yi ', 'Qian ', 'Dan ', 'Xi ', 'Tuan ', 'Mo ', 'Mo ', 'Qian ', 'Dai ', 'Chu ', 'You ', 'Dian ', 'Yi ',
+'Xia ', 'Yan ', 'Qu ', 'Mei ', 'Yan ', 'Jing ', 'Yu ', 'Li ', 'Dang ', 'Du ', 'Can ', 'Yin ', 'An ', 'Yan ', 'Tan ', 'An ',
+'Zhen ', 'Dai ', 'Can ', 'Yi ', 'Mei ', 'Dan ', 'Yan ', 'Du ', 'Lu ', 'Zhi ', 'Fen ', 'Fu ', 'Fu ', 'Min ', 'Min ', 'Yuan ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/x9f.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/x9f.php
new file mode 100644 (file)
index 0000000..5a909ff
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0x9f] = array(
+'Cu ', 'Qu ', 'Chao ', 'Wa ', 'Zhu ', 'Zhi ', 'Mang ', 'Ao ', 'Bie ', 'Tuo ', 'Bi ', 'Yuan ', 'Chao ', 'Tuo ', 'Ding ', 'Mi ',
+'Nai ', 'Ding ', 'Zi ', 'Gu ', 'Gu ', 'Dong ', 'Fen ', 'Tao ', 'Yuan ', 'Pi ', 'Chang ', 'Gao ', 'Qi ', 'Yuan ', 'Tang ', 'Teng ',
+'Shu ', 'Shu ', 'Fen ', 'Fei ', 'Wen ', 'Ba ', 'Diao ', 'Tuo ', 'Tong ', 'Qu ', 'Sheng ', 'Shi ', 'You ', 'Shi ', 'Ting ', 'Wu ',
+'Nian ', 'Jing ', 'Hun ', 'Ju ', 'Yan ', 'Tu ', 'Ti ', 'Xi ', 'Xian ', 'Yan ', 'Lei ', 'Bi ', 'Yao ', 'Qiu ', 'Han ', 'Wu ',
+'Wu ', 'Hou ', 'Xi ', 'Ge ', 'Zha ', 'Xiu ', 'Weng ', 'Zha ', 'Nong ', 'Nang ', 'Qi ', 'Zhai ', 'Ji ', 'Zi ', 'Ji ', 'Ji ',
+'Qi ', 'Ji ', 'Chi ', 'Chen ', 'Chen ', 'He ', 'Ya ', 'Ken ', 'Xie ', 'Pao ', 'Cuo ', 'Shi ', 'Zi ', 'Chi ', 'Nian ', 'Ju ',
+'Tiao ', 'Ling ', 'Ling ', 'Chu ', 'Quan ', 'Xie ', 'Ken ', 'Nie ', 'Jiu ', 'Yao ', 'Chuo ', 'Kun ', 'Yu ', 'Chu ', 'Yi ', 'Ni ',
+'Cuo ', 'Zou ', 'Qu ', 'Nen ', 'Xian ', 'Ou ', 'E ', 'Wo ', 'Yi ', 'Chuo ', 'Zou ', 'Dian ', 'Chu ', 'Jin ', 'Ya ', 'Chi ',
+'Chen ', 'He ', 'Ken ', 'Ju ', 'Ling ', 'Pao ', 'Tiao ', 'Zi ', 'Ken ', 'Yu ', 'Chuo ', 'Qu ', 'Wo ', 'Long ', 'Pang ', 'Gong ',
+'Pang ', 'Yan ', 'Long ', 'Long ', 'Gong ', 'Kan ', 'Ta ', 'Ling ', 'Ta ', 'Long ', 'Gong ', 'Kan ', 'Gui ', 'Qiu ', 'Bie ', 'Gui ',
+'Yue ', 'Chui ', 'He ', 'Jue ', 'Xie ', 'Yu ', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/xa0.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/xa0.php
new file mode 100644 (file)
index 0000000..0959bd7
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0xa0] = array(
+'it', 'ix', 'i', 'ip', 'iet', 'iex', 'ie', 'iep', 'at', 'ax', 'a', 'ap', 'uox', 'uo', 'uop', 'ot',
+'ox', 'o', 'op', 'ex', 'e', 'wu', 'bit', 'bix', 'bi', 'bip', 'biet', 'biex', 'bie', 'biep', 'bat', 'bax',
+'ba', 'bap', 'buox', 'buo', 'buop', 'bot', 'box', 'bo', 'bop', 'bex', 'be', 'bep', 'but', 'bux', 'bu', 'bup',
+'burx', 'bur', 'byt', 'byx', 'by', 'byp', 'byrx', 'byr', 'pit', 'pix', 'pi', 'pip', 'piex', 'pie', 'piep', 'pat',
+'pax', 'pa', 'pap', 'puox', 'puo', 'puop', 'pot', 'pox', 'po', 'pop', 'put', 'pux', 'pu', 'pup', 'purx', 'pur',
+'pyt', 'pyx', 'py', 'pyp', 'pyrx', 'pyr', 'bbit', 'bbix', 'bbi', 'bbip', 'bbiet', 'bbiex', 'bbie', 'bbiep', 'bbat', 'bbax',
+'bba', 'bbap', 'bbuox', 'bbuo', 'bbuop', 'bbot', 'bbox', 'bbo', 'bbop', 'bbex', 'bbe', 'bbep', 'bbut', 'bbux', 'bbu', 'bbup',
+'bburx', 'bbur', 'bbyt', 'bbyx', 'bby', 'bbyp', 'nbit', 'nbix', 'nbi', 'nbip', 'nbiex', 'nbie', 'nbiep', 'nbat', 'nbax', 'nba',
+'nbap', 'nbot', 'nbox', 'nbo', 'nbop', 'nbut', 'nbux', 'nbu', 'nbup', 'nburx', 'nbur', 'nbyt', 'nbyx', 'nby', 'nbyp', 'nbyrx',
+'nbyr', 'hmit', 'hmix', 'hmi', 'hmip', 'hmiex', 'hmie', 'hmiep', 'hmat', 'hmax', 'hma', 'hmap', 'hmuox', 'hmuo', 'hmuop', 'hmot',
+'hmox', 'hmo', 'hmop', 'hmut', 'hmux', 'hmu', 'hmup', 'hmurx', 'hmur', 'hmyx', 'hmy', 'hmyp', 'hmyrx', 'hmyr', 'mit', 'mix',
+'mi', 'mip', 'miex', 'mie', 'miep', 'mat', 'max', 'ma', 'map', 'muot', 'muox', 'muo', 'muop', 'mot', 'mox', 'mo',
+'mop', 'mex', 'me', 'mut', 'mux', 'mu', 'mup', 'murx', 'mur', 'myt', 'myx', 'my', 'myp', 'fit', 'fix', 'fi',
+'fip', 'fat', 'fax', 'fa', 'fap', 'fox', 'fo', 'fop', 'fut', 'fux', 'fu', 'fup', 'furx', 'fur', 'fyt', 'fyx',
+'fy', 'fyp', 'vit', 'vix', 'vi', 'vip', 'viet', 'viex', 'vie', 'viep', 'vat', 'vax', 'va', 'vap', 'vot', 'vox',
+'vo', 'vop', 'vex', 'vep', 'vut', 'vux', 'vu', 'vup', 'vurx', 'vur', 'vyt', 'vyx', 'vy', 'vyp', 'vyrx', 'vyr',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/xa1.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/xa1.php
new file mode 100644 (file)
index 0000000..ba66197
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0xa1] = array(
+'dit', 'dix', 'di', 'dip', 'diex', 'die', 'diep', 'dat', 'dax', 'da', 'dap', 'duox', 'duo', 'dot', 'dox', 'do',
+'dop', 'dex', 'de', 'dep', 'dut', 'dux', 'du', 'dup', 'durx', 'dur', 'tit', 'tix', 'ti', 'tip', 'tiex', 'tie',
+'tiep', 'tat', 'tax', 'ta', 'tap', 'tuot', 'tuox', 'tuo', 'tuop', 'tot', 'tox', 'to', 'top', 'tex', 'te', 'tep',
+'tut', 'tux', 'tu', 'tup', 'turx', 'tur', 'ddit', 'ddix', 'ddi', 'ddip', 'ddiex', 'ddie', 'ddiep', 'ddat', 'ddax', 'dda',
+'ddap', 'dduox', 'dduo', 'dduop', 'ddot', 'ddox', 'ddo', 'ddop', 'ddex', 'dde', 'ddep', 'ddut', 'ddux', 'ddu', 'ddup', 'ddurx',
+'ddur', 'ndit', 'ndix', 'ndi', 'ndip', 'ndiex', 'ndie', 'ndat', 'ndax', 'nda', 'ndap', 'ndot', 'ndox', 'ndo', 'ndop', 'ndex',
+'nde', 'ndep', 'ndut', 'ndux', 'ndu', 'ndup', 'ndurx', 'ndur', 'hnit', 'hnix', 'hni', 'hnip', 'hniet', 'hniex', 'hnie', 'hniep',
+'hnat', 'hnax', 'hna', 'hnap', 'hnuox', 'hnuo', 'hnot', 'hnox', 'hnop', 'hnex', 'hne', 'hnep', 'hnut', 'nit', 'nix', 'ni',
+'nip', 'niex', 'nie', 'niep', 'nax', 'na', 'nap', 'nuox', 'nuo', 'nuop', 'not', 'nox', 'no', 'nop', 'nex', 'ne',
+'nep', 'nut', 'nux', 'nu', 'nup', 'nurx', 'nur', 'hlit', 'hlix', 'hli', 'hlip', 'hliex', 'hlie', 'hliep', 'hlat', 'hlax',
+'hla', 'hlap', 'hluox', 'hluo', 'hluop', 'hlox', 'hlo', 'hlop', 'hlex', 'hle', 'hlep', 'hlut', 'hlux', 'hlu', 'hlup', 'hlurx',
+'hlur', 'hlyt', 'hlyx', 'hly', 'hlyp', 'hlyrx', 'hlyr', 'lit', 'lix', 'li', 'lip', 'liet', 'liex', 'lie', 'liep', 'lat',
+'lax', 'la', 'lap', 'luot', 'luox', 'luo', 'luop', 'lot', 'lox', 'lo', 'lop', 'lex', 'le', 'lep', 'lut', 'lux',
+'lu', 'lup', 'lurx', 'lur', 'lyt', 'lyx', 'ly', 'lyp', 'lyrx', 'lyr', 'git', 'gix', 'gi', 'gip', 'giet', 'giex',
+'gie', 'giep', 'gat', 'gax', 'ga', 'gap', 'guot', 'guox', 'guo', 'guop', 'got', 'gox', 'go', 'gop', 'get', 'gex',
+'ge', 'gep', 'gut', 'gux', 'gu', 'gup', 'gurx', 'gur', 'kit', 'kix', 'ki', 'kip', 'kiex', 'kie', 'kiep', 'kat',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/xa2.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/xa2.php
new file mode 100644 (file)
index 0000000..394a679
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0xa2] = array(
+'kax', 'ka', 'kap', 'kuox', 'kuo', 'kuop', 'kot', 'kox', 'ko', 'kop', 'ket', 'kex', 'ke', 'kep', 'kut', 'kux',
+'ku', 'kup', 'kurx', 'kur', 'ggit', 'ggix', 'ggi', 'ggiex', 'ggie', 'ggiep', 'ggat', 'ggax', 'gga', 'ggap', 'gguot', 'gguox',
+'gguo', 'gguop', 'ggot', 'ggox', 'ggo', 'ggop', 'gget', 'ggex', 'gge', 'ggep', 'ggut', 'ggux', 'ggu', 'ggup', 'ggurx', 'ggur',
+'mgiex', 'mgie', 'mgat', 'mgax', 'mga', 'mgap', 'mguox', 'mguo', 'mguop', 'mgot', 'mgox', 'mgo', 'mgop', 'mgex', 'mge', 'mgep',
+'mgut', 'mgux', 'mgu', 'mgup', 'mgurx', 'mgur', 'hxit', 'hxix', 'hxi', 'hxip', 'hxiet', 'hxiex', 'hxie', 'hxiep', 'hxat', 'hxax',
+'hxa', 'hxap', 'hxuot', 'hxuox', 'hxuo', 'hxuop', 'hxot', 'hxox', 'hxo', 'hxop', 'hxex', 'hxe', 'hxep', 'ngiex', 'ngie', 'ngiep',
+'ngat', 'ngax', 'nga', 'ngap', 'nguot', 'nguox', 'nguo', 'ngot', 'ngox', 'ngo', 'ngop', 'ngex', 'nge', 'ngep', 'hit', 'hiex',
+'hie', 'hat', 'hax', 'ha', 'hap', 'huot', 'huox', 'huo', 'huop', 'hot', 'hox', 'ho', 'hop', 'hex', 'he', 'hep',
+'wat', 'wax', 'wa', 'wap', 'wuox', 'wuo', 'wuop', 'wox', 'wo', 'wop', 'wex', 'we', 'wep', 'zit', 'zix', 'zi',
+'zip', 'ziex', 'zie', 'ziep', 'zat', 'zax', 'za', 'zap', 'zuox', 'zuo', 'zuop', 'zot', 'zox', 'zo', 'zop', 'zex',
+'ze', 'zep', 'zut', 'zux', 'zu', 'zup', 'zurx', 'zur', 'zyt', 'zyx', 'zy', 'zyp', 'zyrx', 'zyr', 'cit', 'cix',
+'ci', 'cip', 'ciet', 'ciex', 'cie', 'ciep', 'cat', 'cax', 'ca', 'cap', 'cuox', 'cuo', 'cuop', 'cot', 'cox', 'co',
+'cop', 'cex', 'ce', 'cep', 'cut', 'cux', 'cu', 'cup', 'curx', 'cur', 'cyt', 'cyx', 'cy', 'cyp', 'cyrx', 'cyr',
+'zzit', 'zzix', 'zzi', 'zzip', 'zziet', 'zziex', 'zzie', 'zziep', 'zzat', 'zzax', 'zza', 'zzap', 'zzox', 'zzo', 'zzop', 'zzex',
+'zze', 'zzep', 'zzux', 'zzu', 'zzup', 'zzurx', 'zzur', 'zzyt', 'zzyx', 'zzy', 'zzyp', 'zzyrx', 'zzyr', 'nzit', 'nzix', 'nzi',
+'nzip', 'nziex', 'nzie', 'nziep', 'nzat', 'nzax', 'nza', 'nzap', 'nzuox', 'nzuo', 'nzox', 'nzop', 'nzex', 'nze', 'nzux', 'nzu',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/xa3.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/xa3.php
new file mode 100644 (file)
index 0000000..af0f3a4
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0xa3] = array(
+'nzup', 'nzurx', 'nzur', 'nzyt', 'nzyx', 'nzy', 'nzyp', 'nzyrx', 'nzyr', 'sit', 'six', 'si', 'sip', 'siex', 'sie', 'siep',
+'sat', 'sax', 'sa', 'sap', 'suox', 'suo', 'suop', 'sot', 'sox', 'so', 'sop', 'sex', 'se', 'sep', 'sut', 'sux',
+'su', 'sup', 'surx', 'sur', 'syt', 'syx', 'sy', 'syp', 'syrx', 'syr', 'ssit', 'ssix', 'ssi', 'ssip', 'ssiex', 'ssie',
+'ssiep', 'ssat', 'ssax', 'ssa', 'ssap', 'ssot', 'ssox', 'sso', 'ssop', 'ssex', 'sse', 'ssep', 'ssut', 'ssux', 'ssu', 'ssup',
+'ssyt', 'ssyx', 'ssy', 'ssyp', 'ssyrx', 'ssyr', 'zhat', 'zhax', 'zha', 'zhap', 'zhuox', 'zhuo', 'zhuop', 'zhot', 'zhox', 'zho',
+'zhop', 'zhet', 'zhex', 'zhe', 'zhep', 'zhut', 'zhux', 'zhu', 'zhup', 'zhurx', 'zhur', 'zhyt', 'zhyx', 'zhy', 'zhyp', 'zhyrx',
+'zhyr', 'chat', 'chax', 'cha', 'chap', 'chuot', 'chuox', 'chuo', 'chuop', 'chot', 'chox', 'cho', 'chop', 'chet', 'chex', 'che',
+'chep', 'chux', 'chu', 'chup', 'churx', 'chur', 'chyt', 'chyx', 'chy', 'chyp', 'chyrx', 'chyr', 'rrax', 'rra', 'rruox', 'rruo',
+'rrot', 'rrox', 'rro', 'rrop', 'rret', 'rrex', 'rre', 'rrep', 'rrut', 'rrux', 'rru', 'rrup', 'rrurx', 'rrur', 'rryt', 'rryx',
+'rry', 'rryp', 'rryrx', 'rryr', 'nrat', 'nrax', 'nra', 'nrap', 'nrox', 'nro', 'nrop', 'nret', 'nrex', 'nre', 'nrep', 'nrut',
+'nrux', 'nru', 'nrup', 'nrurx', 'nrur', 'nryt', 'nryx', 'nry', 'nryp', 'nryrx', 'nryr', 'shat', 'shax', 'sha', 'shap', 'shuox',
+'shuo', 'shuop', 'shot', 'shox', 'sho', 'shop', 'shet', 'shex', 'she', 'shep', 'shut', 'shux', 'shu', 'shup', 'shurx', 'shur',
+'shyt', 'shyx', 'shy', 'shyp', 'shyrx', 'shyr', 'rat', 'rax', 'ra', 'rap', 'ruox', 'ruo', 'ruop', 'rot', 'rox', 'ro',
+'rop', 'rex', 're', 'rep', 'rut', 'rux', 'ru', 'rup', 'rurx', 'rur', 'ryt', 'ryx', 'ry', 'ryp', 'ryrx', 'ryr',
+'jit', 'jix', 'ji', 'jip', 'jiet', 'jiex', 'jie', 'jiep', 'juot', 'juox', 'juo', 'juop', 'jot', 'jox', 'jo', 'jop',
+'jut', 'jux', 'ju', 'jup', 'jurx', 'jur', 'jyt', 'jyx', 'jy', 'jyp', 'jyrx', 'jyr', 'qit', 'qix', 'qi', 'qip',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/xa4.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/xa4.php
new file mode 100644 (file)
index 0000000..1c0ee13
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0xa4] = array(
+'qiet', 'qiex', 'qie', 'qiep', 'quot', 'quox', 'quo', 'quop', 'qot', 'qox', 'qo', 'qop', 'qut', 'qux', 'qu', 'qup',
+'qurx', 'qur', 'qyt', 'qyx', 'qy', 'qyp', 'qyrx', 'qyr', 'jjit', 'jjix', 'jji', 'jjip', 'jjiet', 'jjiex', 'jjie', 'jjiep',
+'jjuox', 'jjuo', 'jjuop', 'jjot', 'jjox', 'jjo', 'jjop', 'jjut', 'jjux', 'jju', 'jjup', 'jjurx', 'jjur', 'jjyt', 'jjyx', 'jjy',
+'jjyp', 'njit', 'njix', 'nji', 'njip', 'njiet', 'njiex', 'njie', 'njiep', 'njuox', 'njuo', 'njot', 'njox', 'njo', 'njop', 'njux',
+'nju', 'njup', 'njurx', 'njur', 'njyt', 'njyx', 'njy', 'njyp', 'njyrx', 'njyr', 'nyit', 'nyix', 'nyi', 'nyip', 'nyiet', 'nyiex',
+'nyie', 'nyiep', 'nyuox', 'nyuo', 'nyuop', 'nyot', 'nyox', 'nyo', 'nyop', 'nyut', 'nyux', 'nyu', 'nyup', 'xit', 'xix', 'xi',
+'xip', 'xiet', 'xiex', 'xie', 'xiep', 'xuox', 'xuo', 'xot', 'xox', 'xo', 'xop', 'xyt', 'xyx', 'xy', 'xyp', 'xyrx',
+'xyr', 'yit', 'yix', 'yi', 'yip', 'yiet', 'yiex', 'yie', 'yiep', 'yuot', 'yuox', 'yuo', 'yuop', 'yot', 'yox', 'yo',
+'yop', 'yut', 'yux', 'yu', 'yup', 'yurx', 'yur', 'yyt', 'yyx', 'yy', 'yyp', 'yyrx', 'yyr', '[?]', '[?]', '[?]',
+'Qot', 'Li', 'Kit', 'Nyip', 'Cyp', 'Ssi', 'Ggop', 'Gep', 'Mi', 'Hxit', 'Lyr', 'Bbut', 'Mop', 'Yo', 'Put', 'Hxuo',
+'Tat', 'Ga', '[?]', '[?]', 'Ddur', 'Bur', 'Gguo', 'Nyop', 'Tu', 'Op', 'Jjut', 'Zot', 'Pyt', 'Hmo', 'Yit', 'Vur',
+'Shy', 'Vep', 'Za', 'Jo', '[?]', 'Jjy', 'Got', 'Jjie', 'Wo', 'Du', 'Shur', 'Lie', 'Cy', 'Cuop', 'Cip', 'Hxop',
+'Shat', '[?]', 'Shop', 'Che', 'Zziet', '[?]', 'Ke', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/xac.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/xac.php
new file mode 100644 (file)
index 0000000..894dcce
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0xac] = array(
+'ga', 'gag', 'gagg', 'gags', 'gan', 'ganj', 'ganh', 'gad', 'gal', 'galg', 'galm', 'galb', 'gals', 'galt', 'galp', 'galh',
+'gam', 'gab', 'gabs', 'gas', 'gass', 'gang', 'gaj', 'gac', 'gak', 'gat', 'gap', 'gah', 'gae', 'gaeg', 'gaegg', 'gaegs',
+'gaen', 'gaenj', 'gaenh', 'gaed', 'gael', 'gaelg', 'gaelm', 'gaelb', 'gaels', 'gaelt', 'gaelp', 'gaelh', 'gaem', 'gaeb', 'gaebs', 'gaes',
+'gaess', 'gaeng', 'gaej', 'gaec', 'gaek', 'gaet', 'gaep', 'gaeh', 'gya', 'gyag', 'gyagg', 'gyags', 'gyan', 'gyanj', 'gyanh', 'gyad',
+'gyal', 'gyalg', 'gyalm', 'gyalb', 'gyals', 'gyalt', 'gyalp', 'gyalh', 'gyam', 'gyab', 'gyabs', 'gyas', 'gyass', 'gyang', 'gyaj', 'gyac',
+'gyak', 'gyat', 'gyap', 'gyah', 'gyae', 'gyaeg', 'gyaegg', 'gyaegs', 'gyaen', 'gyaenj', 'gyaenh', 'gyaed', 'gyael', 'gyaelg', 'gyaelm', 'gyaelb',
+'gyaels', 'gyaelt', 'gyaelp', 'gyaelh', 'gyaem', 'gyaeb', 'gyaebs', 'gyaes', 'gyaess', 'gyaeng', 'gyaej', 'gyaec', 'gyaek', 'gyaet', 'gyaep', 'gyaeh',
+'geo', 'geog', 'geogg', 'geogs', 'geon', 'geonj', 'geonh', 'geod', 'geol', 'geolg', 'geolm', 'geolb', 'geols', 'geolt', 'geolp', 'geolh',
+'geom', 'geob', 'geobs', 'geos', 'geoss', 'geong', 'geoj', 'geoc', 'geok', 'geot', 'geop', 'geoh', 'ge', 'geg', 'gegg', 'gegs',
+'gen', 'genj', 'genh', 'ged', 'gel', 'gelg', 'gelm', 'gelb', 'gels', 'gelt', 'gelp', 'gelh', 'gem', 'geb', 'gebs', 'ges',
+'gess', 'geng', 'gej', 'gec', 'gek', 'get', 'gep', 'geh', 'gyeo', 'gyeog', 'gyeogg', 'gyeogs', 'gyeon', 'gyeonj', 'gyeonh', 'gyeod',
+'gyeol', 'gyeolg', 'gyeolm', 'gyeolb', 'gyeols', 'gyeolt', 'gyeolp', 'gyeolh', 'gyeom', 'gyeob', 'gyeobs', 'gyeos', 'gyeoss', 'gyeong', 'gyeoj', 'gyeoc',
+'gyeok', 'gyeot', 'gyeop', 'gyeoh', 'gye', 'gyeg', 'gyegg', 'gyegs', 'gyen', 'gyenj', 'gyenh', 'gyed', 'gyel', 'gyelg', 'gyelm', 'gyelb',
+'gyels', 'gyelt', 'gyelp', 'gyelh', 'gyem', 'gyeb', 'gyebs', 'gyes', 'gyess', 'gyeng', 'gyej', 'gyec', 'gyek', 'gyet', 'gyep', 'gyeh',
+'go', 'gog', 'gogg', 'gogs', 'gon', 'gonj', 'gonh', 'god', 'gol', 'golg', 'golm', 'golb', 'gols', 'golt', 'golp', 'golh',
+'gom', 'gob', 'gobs', 'gos', 'goss', 'gong', 'goj', 'goc', 'gok', 'got', 'gop', 'goh', 'gwa', 'gwag', 'gwagg', 'gwags',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/xad.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/xad.php
new file mode 100644 (file)
index 0000000..945bf05
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0xad] = array(
+'gwan', 'gwanj', 'gwanh', 'gwad', 'gwal', 'gwalg', 'gwalm', 'gwalb', 'gwals', 'gwalt', 'gwalp', 'gwalh', 'gwam', 'gwab', 'gwabs', 'gwas',
+'gwass', 'gwang', 'gwaj', 'gwac', 'gwak', 'gwat', 'gwap', 'gwah', 'gwae', 'gwaeg', 'gwaegg', 'gwaegs', 'gwaen', 'gwaenj', 'gwaenh', 'gwaed',
+'gwael', 'gwaelg', 'gwaelm', 'gwaelb', 'gwaels', 'gwaelt', 'gwaelp', 'gwaelh', 'gwaem', 'gwaeb', 'gwaebs', 'gwaes', 'gwaess', 'gwaeng', 'gwaej', 'gwaec',
+'gwaek', 'gwaet', 'gwaep', 'gwaeh', 'goe', 'goeg', 'goegg', 'goegs', 'goen', 'goenj', 'goenh', 'goed', 'goel', 'goelg', 'goelm', 'goelb',
+'goels', 'goelt', 'goelp', 'goelh', 'goem', 'goeb', 'goebs', 'goes', 'goess', 'goeng', 'goej', 'goec', 'goek', 'goet', 'goep', 'goeh',
+'gyo', 'gyog', 'gyogg', 'gyogs', 'gyon', 'gyonj', 'gyonh', 'gyod', 'gyol', 'gyolg', 'gyolm', 'gyolb', 'gyols', 'gyolt', 'gyolp', 'gyolh',
+'gyom', 'gyob', 'gyobs', 'gyos', 'gyoss', 'gyong', 'gyoj', 'gyoc', 'gyok', 'gyot', 'gyop', 'gyoh', 'gu', 'gug', 'gugg', 'gugs',
+'gun', 'gunj', 'gunh', 'gud', 'gul', 'gulg', 'gulm', 'gulb', 'guls', 'gult', 'gulp', 'gulh', 'gum', 'gub', 'gubs', 'gus',
+'guss', 'gung', 'guj', 'guc', 'guk', 'gut', 'gup', 'guh', 'gweo', 'gweog', 'gweogg', 'gweogs', 'gweon', 'gweonj', 'gweonh', 'gweod',
+'gweol', 'gweolg', 'gweolm', 'gweolb', 'gweols', 'gweolt', 'gweolp', 'gweolh', 'gweom', 'gweob', 'gweobs', 'gweos', 'gweoss', 'gweong', 'gweoj', 'gweoc',
+'gweok', 'gweot', 'gweop', 'gweoh', 'gwe', 'gweg', 'gwegg', 'gwegs', 'gwen', 'gwenj', 'gwenh', 'gwed', 'gwel', 'gwelg', 'gwelm', 'gwelb',
+'gwels', 'gwelt', 'gwelp', 'gwelh', 'gwem', 'gweb', 'gwebs', 'gwes', 'gwess', 'gweng', 'gwej', 'gwec', 'gwek', 'gwet', 'gwep', 'gweh',
+'gwi', 'gwig', 'gwigg', 'gwigs', 'gwin', 'gwinj', 'gwinh', 'gwid', 'gwil', 'gwilg', 'gwilm', 'gwilb', 'gwils', 'gwilt', 'gwilp', 'gwilh',
+'gwim', 'gwib', 'gwibs', 'gwis', 'gwiss', 'gwing', 'gwij', 'gwic', 'gwik', 'gwit', 'gwip', 'gwih', 'gyu', 'gyug', 'gyugg', 'gyugs',
+'gyun', 'gyunj', 'gyunh', 'gyud', 'gyul', 'gyulg', 'gyulm', 'gyulb', 'gyuls', 'gyult', 'gyulp', 'gyulh', 'gyum', 'gyub', 'gyubs', 'gyus',
+'gyuss', 'gyung', 'gyuj', 'gyuc', 'gyuk', 'gyut', 'gyup', 'gyuh', 'geu', 'geug', 'geugg', 'geugs', 'geun', 'geunj', 'geunh', 'geud',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/xae.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/xae.php
new file mode 100644 (file)
index 0000000..ea2332c
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0xae] = array(
+'geul', 'geulg', 'geulm', 'geulb', 'geuls', 'geult', 'geulp', 'geulh', 'geum', 'geub', 'geubs', 'geus', 'geuss', 'geung', 'geuj', 'geuc',
+'geuk', 'geut', 'geup', 'geuh', 'gyi', 'gyig', 'gyigg', 'gyigs', 'gyin', 'gyinj', 'gyinh', 'gyid', 'gyil', 'gyilg', 'gyilm', 'gyilb',
+'gyils', 'gyilt', 'gyilp', 'gyilh', 'gyim', 'gyib', 'gyibs', 'gyis', 'gyiss', 'gying', 'gyij', 'gyic', 'gyik', 'gyit', 'gyip', 'gyih',
+'gi', 'gig', 'gigg', 'gigs', 'gin', 'ginj', 'ginh', 'gid', 'gil', 'gilg', 'gilm', 'gilb', 'gils', 'gilt', 'gilp', 'gilh',
+'gim', 'gib', 'gibs', 'gis', 'giss', 'ging', 'gij', 'gic', 'gik', 'git', 'gip', 'gih', 'gga', 'ggag', 'ggagg', 'ggags',
+'ggan', 'gganj', 'gganh', 'ggad', 'ggal', 'ggalg', 'ggalm', 'ggalb', 'ggals', 'ggalt', 'ggalp', 'ggalh', 'ggam', 'ggab', 'ggabs', 'ggas',
+'ggass', 'ggang', 'ggaj', 'ggac', 'ggak', 'ggat', 'ggap', 'ggah', 'ggae', 'ggaeg', 'ggaegg', 'ggaegs', 'ggaen', 'ggaenj', 'ggaenh', 'ggaed',
+'ggael', 'ggaelg', 'ggaelm', 'ggaelb', 'ggaels', 'ggaelt', 'ggaelp', 'ggaelh', 'ggaem', 'ggaeb', 'ggaebs', 'ggaes', 'ggaess', 'ggaeng', 'ggaej', 'ggaec',
+'ggaek', 'ggaet', 'ggaep', 'ggaeh', 'ggya', 'ggyag', 'ggyagg', 'ggyags', 'ggyan', 'ggyanj', 'ggyanh', 'ggyad', 'ggyal', 'ggyalg', 'ggyalm', 'ggyalb',
+'ggyals', 'ggyalt', 'ggyalp', 'ggyalh', 'ggyam', 'ggyab', 'ggyabs', 'ggyas', 'ggyass', 'ggyang', 'ggyaj', 'ggyac', 'ggyak', 'ggyat', 'ggyap', 'ggyah',
+'ggyae', 'ggyaeg', 'ggyaegg', 'ggyaegs', 'ggyaen', 'ggyaenj', 'ggyaenh', 'ggyaed', 'ggyael', 'ggyaelg', 'ggyaelm', 'ggyaelb', 'ggyaels', 'ggyaelt', 'ggyaelp', 'ggyaelh',
+'ggyaem', 'ggyaeb', 'ggyaebs', 'ggyaes', 'ggyaess', 'ggyaeng', 'ggyaej', 'ggyaec', 'ggyaek', 'ggyaet', 'ggyaep', 'ggyaeh', 'ggeo', 'ggeog', 'ggeogg', 'ggeogs',
+'ggeon', 'ggeonj', 'ggeonh', 'ggeod', 'ggeol', 'ggeolg', 'ggeolm', 'ggeolb', 'ggeols', 'ggeolt', 'ggeolp', 'ggeolh', 'ggeom', 'ggeob', 'ggeobs', 'ggeos',
+'ggeoss', 'ggeong', 'ggeoj', 'ggeoc', 'ggeok', 'ggeot', 'ggeop', 'ggeoh', 'gge', 'ggeg', 'ggegg', 'ggegs', 'ggen', 'ggenj', 'ggenh', 'gged',
+'ggel', 'ggelg', 'ggelm', 'ggelb', 'ggels', 'ggelt', 'ggelp', 'ggelh', 'ggem', 'ggeb', 'ggebs', 'gges', 'ggess', 'ggeng', 'ggej', 'ggec',
+'ggek', 'gget', 'ggep', 'ggeh', 'ggyeo', 'ggyeog', 'ggyeogg', 'ggyeogs', 'ggyeon', 'ggyeonj', 'ggyeonh', 'ggyeod', 'ggyeol', 'ggyeolg', 'ggyeolm', 'ggyeolb',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/xaf.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/xaf.php
new file mode 100644 (file)
index 0000000..ae02bd0
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0xaf] = array(
+'ggyeols', 'ggyeolt', 'ggyeolp', 'ggyeolh', 'ggyeom', 'ggyeob', 'ggyeobs', 'ggyeos', 'ggyeoss', 'ggyeong', 'ggyeoj', 'ggyeoc', 'ggyeok', 'ggyeot', 'ggyeop', 'ggyeoh',
+'ggye', 'ggyeg', 'ggyegg', 'ggyegs', 'ggyen', 'ggyenj', 'ggyenh', 'ggyed', 'ggyel', 'ggyelg', 'ggyelm', 'ggyelb', 'ggyels', 'ggyelt', 'ggyelp', 'ggyelh',
+'ggyem', 'ggyeb', 'ggyebs', 'ggyes', 'ggyess', 'ggyeng', 'ggyej', 'ggyec', 'ggyek', 'ggyet', 'ggyep', 'ggyeh', 'ggo', 'ggog', 'ggogg', 'ggogs',
+'ggon', 'ggonj', 'ggonh', 'ggod', 'ggol', 'ggolg', 'ggolm', 'ggolb', 'ggols', 'ggolt', 'ggolp', 'ggolh', 'ggom', 'ggob', 'ggobs', 'ggos',
+'ggoss', 'ggong', 'ggoj', 'ggoc', 'ggok', 'ggot', 'ggop', 'ggoh', 'ggwa', 'ggwag', 'ggwagg', 'ggwags', 'ggwan', 'ggwanj', 'ggwanh', 'ggwad',
+'ggwal', 'ggwalg', 'ggwalm', 'ggwalb', 'ggwals', 'ggwalt', 'ggwalp', 'ggwalh', 'ggwam', 'ggwab', 'ggwabs', 'ggwas', 'ggwass', 'ggwang', 'ggwaj', 'ggwac',
+'ggwak', 'ggwat', 'ggwap', 'ggwah', 'ggwae', 'ggwaeg', 'ggwaegg', 'ggwaegs', 'ggwaen', 'ggwaenj', 'ggwaenh', 'ggwaed', 'ggwael', 'ggwaelg', 'ggwaelm', 'ggwaelb',
+'ggwaels', 'ggwaelt', 'ggwaelp', 'ggwaelh', 'ggwaem', 'ggwaeb', 'ggwaebs', 'ggwaes', 'ggwaess', 'ggwaeng', 'ggwaej', 'ggwaec', 'ggwaek', 'ggwaet', 'ggwaep', 'ggwaeh',
+'ggoe', 'ggoeg', 'ggoegg', 'ggoegs', 'ggoen', 'ggoenj', 'ggoenh', 'ggoed', 'ggoel', 'ggoelg', 'ggoelm', 'ggoelb', 'ggoels', 'ggoelt', 'ggoelp', 'ggoelh',
+'ggoem', 'ggoeb', 'ggoebs', 'ggoes', 'ggoess', 'ggoeng', 'ggoej', 'ggoec', 'ggoek', 'ggoet', 'ggoep', 'ggoeh', 'ggyo', 'ggyog', 'ggyogg', 'ggyogs',
+'ggyon', 'ggyonj', 'ggyonh', 'ggyod', 'ggyol', 'ggyolg', 'ggyolm', 'ggyolb', 'ggyols', 'ggyolt', 'ggyolp', 'ggyolh', 'ggyom', 'ggyob', 'ggyobs', 'ggyos',
+'ggyoss', 'ggyong', 'ggyoj', 'ggyoc', 'ggyok', 'ggyot', 'ggyop', 'ggyoh', 'ggu', 'ggug', 'ggugg', 'ggugs', 'ggun', 'ggunj', 'ggunh', 'ggud',
+'ggul', 'ggulg', 'ggulm', 'ggulb', 'gguls', 'ggult', 'ggulp', 'ggulh', 'ggum', 'ggub', 'ggubs', 'ggus', 'gguss', 'ggung', 'gguj', 'gguc',
+'gguk', 'ggut', 'ggup', 'gguh', 'ggweo', 'ggweog', 'ggweogg', 'ggweogs', 'ggweon', 'ggweonj', 'ggweonh', 'ggweod', 'ggweol', 'ggweolg', 'ggweolm', 'ggweolb',
+'ggweols', 'ggweolt', 'ggweolp', 'ggweolh', 'ggweom', 'ggweob', 'ggweobs', 'ggweos', 'ggweoss', 'ggweong', 'ggweoj', 'ggweoc', 'ggweok', 'ggweot', 'ggweop', 'ggweoh',
+'ggwe', 'ggweg', 'ggwegg', 'ggwegs', 'ggwen', 'ggwenj', 'ggwenh', 'ggwed', 'ggwel', 'ggwelg', 'ggwelm', 'ggwelb', 'ggwels', 'ggwelt', 'ggwelp', 'ggwelh',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/xb0.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/xb0.php
new file mode 100644 (file)
index 0000000..48348ac
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0xb0] = array(
+'ggwem', 'ggweb', 'ggwebs', 'ggwes', 'ggwess', 'ggweng', 'ggwej', 'ggwec', 'ggwek', 'ggwet', 'ggwep', 'ggweh', 'ggwi', 'ggwig', 'ggwigg', 'ggwigs',
+'ggwin', 'ggwinj', 'ggwinh', 'ggwid', 'ggwil', 'ggwilg', 'ggwilm', 'ggwilb', 'ggwils', 'ggwilt', 'ggwilp', 'ggwilh', 'ggwim', 'ggwib', 'ggwibs', 'ggwis',
+'ggwiss', 'ggwing', 'ggwij', 'ggwic', 'ggwik', 'ggwit', 'ggwip', 'ggwih', 'ggyu', 'ggyug', 'ggyugg', 'ggyugs', 'ggyun', 'ggyunj', 'ggyunh', 'ggyud',
+'ggyul', 'ggyulg', 'ggyulm', 'ggyulb', 'ggyuls', 'ggyult', 'ggyulp', 'ggyulh', 'ggyum', 'ggyub', 'ggyubs', 'ggyus', 'ggyuss', 'ggyung', 'ggyuj', 'ggyuc',
+'ggyuk', 'ggyut', 'ggyup', 'ggyuh', 'ggeu', 'ggeug', 'ggeugg', 'ggeugs', 'ggeun', 'ggeunj', 'ggeunh', 'ggeud', 'ggeul', 'ggeulg', 'ggeulm', 'ggeulb',
+'ggeuls', 'ggeult', 'ggeulp', 'ggeulh', 'ggeum', 'ggeub', 'ggeubs', 'ggeus', 'ggeuss', 'ggeung', 'ggeuj', 'ggeuc', 'ggeuk', 'ggeut', 'ggeup', 'ggeuh',
+'ggyi', 'ggyig', 'ggyigg', 'ggyigs', 'ggyin', 'ggyinj', 'ggyinh', 'ggyid', 'ggyil', 'ggyilg', 'ggyilm', 'ggyilb', 'ggyils', 'ggyilt', 'ggyilp', 'ggyilh',
+'ggyim', 'ggyib', 'ggyibs', 'ggyis', 'ggyiss', 'ggying', 'ggyij', 'ggyic', 'ggyik', 'ggyit', 'ggyip', 'ggyih', 'ggi', 'ggig', 'ggigg', 'ggigs',
+'ggin', 'gginj', 'gginh', 'ggid', 'ggil', 'ggilg', 'ggilm', 'ggilb', 'ggils', 'ggilt', 'ggilp', 'ggilh', 'ggim', 'ggib', 'ggibs', 'ggis',
+'ggiss', 'gging', 'ggij', 'ggic', 'ggik', 'ggit', 'ggip', 'ggih', 'na', 'nag', 'nagg', 'nags', 'nan', 'nanj', 'nanh', 'nad',
+'nal', 'nalg', 'nalm', 'nalb', 'nals', 'nalt', 'nalp', 'nalh', 'nam', 'nab', 'nabs', 'nas', 'nass', 'nang', 'naj', 'nac',
+'nak', 'nat', 'nap', 'nah', 'nae', 'naeg', 'naegg', 'naegs', 'naen', 'naenj', 'naenh', 'naed', 'nael', 'naelg', 'naelm', 'naelb',
+'naels', 'naelt', 'naelp', 'naelh', 'naem', 'naeb', 'naebs', 'naes', 'naess', 'naeng', 'naej', 'naec', 'naek', 'naet', 'naep', 'naeh',
+'nya', 'nyag', 'nyagg', 'nyags', 'nyan', 'nyanj', 'nyanh', 'nyad', 'nyal', 'nyalg', 'nyalm', 'nyalb', 'nyals', 'nyalt', 'nyalp', 'nyalh',
+'nyam', 'nyab', 'nyabs', 'nyas', 'nyass', 'nyang', 'nyaj', 'nyac', 'nyak', 'nyat', 'nyap', 'nyah', 'nyae', 'nyaeg', 'nyaegg', 'nyaegs',
+'nyaen', 'nyaenj', 'nyaenh', 'nyaed', 'nyael', 'nyaelg', 'nyaelm', 'nyaelb', 'nyaels', 'nyaelt', 'nyaelp', 'nyaelh', 'nyaem', 'nyaeb', 'nyaebs', 'nyaes',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/xb1.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/xb1.php
new file mode 100644 (file)
index 0000000..78df71f
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0xb1] = array(
+'nyaess', 'nyaeng', 'nyaej', 'nyaec', 'nyaek', 'nyaet', 'nyaep', 'nyaeh', 'neo', 'neog', 'neogg', 'neogs', 'neon', 'neonj', 'neonh', 'neod',
+'neol', 'neolg', 'neolm', 'neolb', 'neols', 'neolt', 'neolp', 'neolh', 'neom', 'neob', 'neobs', 'neos', 'neoss', 'neong', 'neoj', 'neoc',
+'neok', 'neot', 'neop', 'neoh', 'ne', 'neg', 'negg', 'negs', 'nen', 'nenj', 'nenh', 'ned', 'nel', 'nelg', 'nelm', 'nelb',
+'nels', 'nelt', 'nelp', 'nelh', 'nem', 'neb', 'nebs', 'nes', 'ness', 'neng', 'nej', 'nec', 'nek', 'net', 'nep', 'neh',
+'nyeo', 'nyeog', 'nyeogg', 'nyeogs', 'nyeon', 'nyeonj', 'nyeonh', 'nyeod', 'nyeol', 'nyeolg', 'nyeolm', 'nyeolb', 'nyeols', 'nyeolt', 'nyeolp', 'nyeolh',
+'nyeom', 'nyeob', 'nyeobs', 'nyeos', 'nyeoss', 'nyeong', 'nyeoj', 'nyeoc', 'nyeok', 'nyeot', 'nyeop', 'nyeoh', 'nye', 'nyeg', 'nyegg', 'nyegs',
+'nyen', 'nyenj', 'nyenh', 'nyed', 'nyel', 'nyelg', 'nyelm', 'nyelb', 'nyels', 'nyelt', 'nyelp', 'nyelh', 'nyem', 'nyeb', 'nyebs', 'nyes',
+'nyess', 'nyeng', 'nyej', 'nyec', 'nyek', 'nyet', 'nyep', 'nyeh', 'no', 'nog', 'nogg', 'nogs', 'non', 'nonj', 'nonh', 'nod',
+'nol', 'nolg', 'nolm', 'nolb', 'nols', 'nolt', 'nolp', 'nolh', 'nom', 'nob', 'nobs', 'nos', 'noss', 'nong', 'noj', 'noc',
+'nok', 'not', 'nop', 'noh', 'nwa', 'nwag', 'nwagg', 'nwags', 'nwan', 'nwanj', 'nwanh', 'nwad', 'nwal', 'nwalg', 'nwalm', 'nwalb',
+'nwals', 'nwalt', 'nwalp', 'nwalh', 'nwam', 'nwab', 'nwabs', 'nwas', 'nwass', 'nwang', 'nwaj', 'nwac', 'nwak', 'nwat', 'nwap', 'nwah',
+'nwae', 'nwaeg', 'nwaegg', 'nwaegs', 'nwaen', 'nwaenj', 'nwaenh', 'nwaed', 'nwael', 'nwaelg', 'nwaelm', 'nwaelb', 'nwaels', 'nwaelt', 'nwaelp', 'nwaelh',
+'nwaem', 'nwaeb', 'nwaebs', 'nwaes', 'nwaess', 'nwaeng', 'nwaej', 'nwaec', 'nwaek', 'nwaet', 'nwaep', 'nwaeh', 'noe', 'noeg', 'noegg', 'noegs',
+'noen', 'noenj', 'noenh', 'noed', 'noel', 'noelg', 'noelm', 'noelb', 'noels', 'noelt', 'noelp', 'noelh', 'noem', 'noeb', 'noebs', 'noes',
+'noess', 'noeng', 'noej', 'noec', 'noek', 'noet', 'noep', 'noeh', 'nyo', 'nyog', 'nyogg', 'nyogs', 'nyon', 'nyonj', 'nyonh', 'nyod',
+'nyol', 'nyolg', 'nyolm', 'nyolb', 'nyols', 'nyolt', 'nyolp', 'nyolh', 'nyom', 'nyob', 'nyobs', 'nyos', 'nyoss', 'nyong', 'nyoj', 'nyoc',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/xb2.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/xb2.php
new file mode 100644 (file)
index 0000000..89bb25f
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0xb2] = array(
+'nyok', 'nyot', 'nyop', 'nyoh', 'nu', 'nug', 'nugg', 'nugs', 'nun', 'nunj', 'nunh', 'nud', 'nul', 'nulg', 'nulm', 'nulb',
+'nuls', 'nult', 'nulp', 'nulh', 'num', 'nub', 'nubs', 'nus', 'nuss', 'nung', 'nuj', 'nuc', 'nuk', 'nut', 'nup', 'nuh',
+'nweo', 'nweog', 'nweogg', 'nweogs', 'nweon', 'nweonj', 'nweonh', 'nweod', 'nweol', 'nweolg', 'nweolm', 'nweolb', 'nweols', 'nweolt', 'nweolp', 'nweolh',
+'nweom', 'nweob', 'nweobs', 'nweos', 'nweoss', 'nweong', 'nweoj', 'nweoc', 'nweok', 'nweot', 'nweop', 'nweoh', 'nwe', 'nweg', 'nwegg', 'nwegs',
+'nwen', 'nwenj', 'nwenh', 'nwed', 'nwel', 'nwelg', 'nwelm', 'nwelb', 'nwels', 'nwelt', 'nwelp', 'nwelh', 'nwem', 'nweb', 'nwebs', 'nwes',
+'nwess', 'nweng', 'nwej', 'nwec', 'nwek', 'nwet', 'nwep', 'nweh', 'nwi', 'nwig', 'nwigg', 'nwigs', 'nwin', 'nwinj', 'nwinh', 'nwid',
+'nwil', 'nwilg', 'nwilm', 'nwilb', 'nwils', 'nwilt', 'nwilp', 'nwilh', 'nwim', 'nwib', 'nwibs', 'nwis', 'nwiss', 'nwing', 'nwij', 'nwic',
+'nwik', 'nwit', 'nwip', 'nwih', 'nyu', 'nyug', 'nyugg', 'nyugs', 'nyun', 'nyunj', 'nyunh', 'nyud', 'nyul', 'nyulg', 'nyulm', 'nyulb',
+'nyuls', 'nyult', 'nyulp', 'nyulh', 'nyum', 'nyub', 'nyubs', 'nyus', 'nyuss', 'nyung', 'nyuj', 'nyuc', 'nyuk', 'nyut', 'nyup', 'nyuh',
+'neu', 'neug', 'neugg', 'neugs', 'neun', 'neunj', 'neunh', 'neud', 'neul', 'neulg', 'neulm', 'neulb', 'neuls', 'neult', 'neulp', 'neulh',
+'neum', 'neub', 'neubs', 'neus', 'neuss', 'neung', 'neuj', 'neuc', 'neuk', 'neut', 'neup', 'neuh', 'nyi', 'nyig', 'nyigg', 'nyigs',
+'nyin', 'nyinj', 'nyinh', 'nyid', 'nyil', 'nyilg', 'nyilm', 'nyilb', 'nyils', 'nyilt', 'nyilp', 'nyilh', 'nyim', 'nyib', 'nyibs', 'nyis',
+'nyiss', 'nying', 'nyij', 'nyic', 'nyik', 'nyit', 'nyip', 'nyih', 'ni', 'nig', 'nigg', 'nigs', 'nin', 'ninj', 'ninh', 'nid',
+'nil', 'nilg', 'nilm', 'nilb', 'nils', 'nilt', 'nilp', 'nilh', 'nim', 'nib', 'nibs', 'nis', 'niss', 'ning', 'nij', 'nic',
+'nik', 'nit', 'nip', 'nih', 'da', 'dag', 'dagg', 'dags', 'dan', 'danj', 'danh', 'dad', 'dal', 'dalg', 'dalm', 'dalb',
+'dals', 'dalt', 'dalp', 'dalh', 'dam', 'dab', 'dabs', 'das', 'dass', 'dang', 'daj', 'dac', 'dak', 'dat', 'dap', 'dah',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/xb3.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/xb3.php
new file mode 100644 (file)
index 0000000..2a28f2e
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0xb3] = array(
+'dae', 'daeg', 'daegg', 'daegs', 'daen', 'daenj', 'daenh', 'daed', 'dael', 'daelg', 'daelm', 'daelb', 'daels', 'daelt', 'daelp', 'daelh',
+'daem', 'daeb', 'daebs', 'daes', 'daess', 'daeng', 'daej', 'daec', 'daek', 'daet', 'daep', 'daeh', 'dya', 'dyag', 'dyagg', 'dyags',
+'dyan', 'dyanj', 'dyanh', 'dyad', 'dyal', 'dyalg', 'dyalm', 'dyalb', 'dyals', 'dyalt', 'dyalp', 'dyalh', 'dyam', 'dyab', 'dyabs', 'dyas',
+'dyass', 'dyang', 'dyaj', 'dyac', 'dyak', 'dyat', 'dyap', 'dyah', 'dyae', 'dyaeg', 'dyaegg', 'dyaegs', 'dyaen', 'dyaenj', 'dyaenh', 'dyaed',
+'dyael', 'dyaelg', 'dyaelm', 'dyaelb', 'dyaels', 'dyaelt', 'dyaelp', 'dyaelh', 'dyaem', 'dyaeb', 'dyaebs', 'dyaes', 'dyaess', 'dyaeng', 'dyaej', 'dyaec',
+'dyaek', 'dyaet', 'dyaep', 'dyaeh', 'deo', 'deog', 'deogg', 'deogs', 'deon', 'deonj', 'deonh', 'deod', 'deol', 'deolg', 'deolm', 'deolb',
+'deols', 'deolt', 'deolp', 'deolh', 'deom', 'deob', 'deobs', 'deos', 'deoss', 'deong', 'deoj', 'deoc', 'deok', 'deot', 'deop', 'deoh',
+'de', 'deg', 'degg', 'degs', 'den', 'denj', 'denh', 'ded', 'del', 'delg', 'delm', 'delb', 'dels', 'delt', 'delp', 'delh',
+'dem', 'deb', 'debs', 'des', 'dess', 'deng', 'dej', 'dec', 'dek', 'det', 'dep', 'deh', 'dyeo', 'dyeog', 'dyeogg', 'dyeogs',
+'dyeon', 'dyeonj', 'dyeonh', 'dyeod', 'dyeol', 'dyeolg', 'dyeolm', 'dyeolb', 'dyeols', 'dyeolt', 'dyeolp', 'dyeolh', 'dyeom', 'dyeob', 'dyeobs', 'dyeos',
+'dyeoss', 'dyeong', 'dyeoj', 'dyeoc', 'dyeok', 'dyeot', 'dyeop', 'dyeoh', 'dye', 'dyeg', 'dyegg', 'dyegs', 'dyen', 'dyenj', 'dyenh', 'dyed',
+'dyel', 'dyelg', 'dyelm', 'dyelb', 'dyels', 'dyelt', 'dyelp', 'dyelh', 'dyem', 'dyeb', 'dyebs', 'dyes', 'dyess', 'dyeng', 'dyej', 'dyec',
+'dyek', 'dyet', 'dyep', 'dyeh', 'do', 'dog', 'dogg', 'dogs', 'don', 'donj', 'donh', 'dod', 'dol', 'dolg', 'dolm', 'dolb',
+'dols', 'dolt', 'dolp', 'dolh', 'dom', 'dob', 'dobs', 'dos', 'doss', 'dong', 'doj', 'doc', 'dok', 'dot', 'dop', 'doh',
+'dwa', 'dwag', 'dwagg', 'dwags', 'dwan', 'dwanj', 'dwanh', 'dwad', 'dwal', 'dwalg', 'dwalm', 'dwalb', 'dwals', 'dwalt', 'dwalp', 'dwalh',
+'dwam', 'dwab', 'dwabs', 'dwas', 'dwass', 'dwang', 'dwaj', 'dwac', 'dwak', 'dwat', 'dwap', 'dwah', 'dwae', 'dwaeg', 'dwaegg', 'dwaegs',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/xb4.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/xb4.php
new file mode 100644 (file)
index 0000000..6aca4bb
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0xb4] = array(
+'dwaen', 'dwaenj', 'dwaenh', 'dwaed', 'dwael', 'dwaelg', 'dwaelm', 'dwaelb', 'dwaels', 'dwaelt', 'dwaelp', 'dwaelh', 'dwaem', 'dwaeb', 'dwaebs', 'dwaes',
+'dwaess', 'dwaeng', 'dwaej', 'dwaec', 'dwaek', 'dwaet', 'dwaep', 'dwaeh', 'doe', 'doeg', 'doegg', 'doegs', 'doen', 'doenj', 'doenh', 'doed',
+'doel', 'doelg', 'doelm', 'doelb', 'doels', 'doelt', 'doelp', 'doelh', 'doem', 'doeb', 'doebs', 'does', 'doess', 'doeng', 'doej', 'doec',
+'doek', 'doet', 'doep', 'doeh', 'dyo', 'dyog', 'dyogg', 'dyogs', 'dyon', 'dyonj', 'dyonh', 'dyod', 'dyol', 'dyolg', 'dyolm', 'dyolb',
+'dyols', 'dyolt', 'dyolp', 'dyolh', 'dyom', 'dyob', 'dyobs', 'dyos', 'dyoss', 'dyong', 'dyoj', 'dyoc', 'dyok', 'dyot', 'dyop', 'dyoh',
+'du', 'dug', 'dugg', 'dugs', 'dun', 'dunj', 'dunh', 'dud', 'dul', 'dulg', 'dulm', 'dulb', 'duls', 'dult', 'dulp', 'dulh',
+'dum', 'dub', 'dubs', 'dus', 'duss', 'dung', 'duj', 'duc', 'duk', 'dut', 'dup', 'duh', 'dweo', 'dweog', 'dweogg', 'dweogs',
+'dweon', 'dweonj', 'dweonh', 'dweod', 'dweol', 'dweolg', 'dweolm', 'dweolb', 'dweols', 'dweolt', 'dweolp', 'dweolh', 'dweom', 'dweob', 'dweobs', 'dweos',
+'dweoss', 'dweong', 'dweoj', 'dweoc', 'dweok', 'dweot', 'dweop', 'dweoh', 'dwe', 'dweg', 'dwegg', 'dwegs', 'dwen', 'dwenj', 'dwenh', 'dwed',
+'dwel', 'dwelg', 'dwelm', 'dwelb', 'dwels', 'dwelt', 'dwelp', 'dwelh', 'dwem', 'dweb', 'dwebs', 'dwes', 'dwess', 'dweng', 'dwej', 'dwec',
+'dwek', 'dwet', 'dwep', 'dweh', 'dwi', 'dwig', 'dwigg', 'dwigs', 'dwin', 'dwinj', 'dwinh', 'dwid', 'dwil', 'dwilg', 'dwilm', 'dwilb',
+'dwils', 'dwilt', 'dwilp', 'dwilh', 'dwim', 'dwib', 'dwibs', 'dwis', 'dwiss', 'dwing', 'dwij', 'dwic', 'dwik', 'dwit', 'dwip', 'dwih',
+'dyu', 'dyug', 'dyugg', 'dyugs', 'dyun', 'dyunj', 'dyunh', 'dyud', 'dyul', 'dyulg', 'dyulm', 'dyulb', 'dyuls', 'dyult', 'dyulp', 'dyulh',
+'dyum', 'dyub', 'dyubs', 'dyus', 'dyuss', 'dyung', 'dyuj', 'dyuc', 'dyuk', 'dyut', 'dyup', 'dyuh', 'deu', 'deug', 'deugg', 'deugs',
+'deun', 'deunj', 'deunh', 'deud', 'deul', 'deulg', 'deulm', 'deulb', 'deuls', 'deult', 'deulp', 'deulh', 'deum', 'deub', 'deubs', 'deus',
+'deuss', 'deung', 'deuj', 'deuc', 'deuk', 'deut', 'deup', 'deuh', 'dyi', 'dyig', 'dyigg', 'dyigs', 'dyin', 'dyinj', 'dyinh', 'dyid',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/xb5.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/xb5.php
new file mode 100644 (file)
index 0000000..f083bd0
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0xb5] = array(
+'dyil', 'dyilg', 'dyilm', 'dyilb', 'dyils', 'dyilt', 'dyilp', 'dyilh', 'dyim', 'dyib', 'dyibs', 'dyis', 'dyiss', 'dying', 'dyij', 'dyic',
+'dyik', 'dyit', 'dyip', 'dyih', 'di', 'dig', 'digg', 'digs', 'din', 'dinj', 'dinh', 'did', 'dil', 'dilg', 'dilm', 'dilb',
+'dils', 'dilt', 'dilp', 'dilh', 'dim', 'dib', 'dibs', 'dis', 'diss', 'ding', 'dij', 'dic', 'dik', 'dit', 'dip', 'dih',
+'dda', 'ddag', 'ddagg', 'ddags', 'ddan', 'ddanj', 'ddanh', 'ddad', 'ddal', 'ddalg', 'ddalm', 'ddalb', 'ddals', 'ddalt', 'ddalp', 'ddalh',
+'ddam', 'ddab', 'ddabs', 'ddas', 'ddass', 'ddang', 'ddaj', 'ddac', 'ddak', 'ddat', 'ddap', 'ddah', 'ddae', 'ddaeg', 'ddaegg', 'ddaegs',
+'ddaen', 'ddaenj', 'ddaenh', 'ddaed', 'ddael', 'ddaelg', 'ddaelm', 'ddaelb', 'ddaels', 'ddaelt', 'ddaelp', 'ddaelh', 'ddaem', 'ddaeb', 'ddaebs', 'ddaes',
+'ddaess', 'ddaeng', 'ddaej', 'ddaec', 'ddaek', 'ddaet', 'ddaep', 'ddaeh', 'ddya', 'ddyag', 'ddyagg', 'ddyags', 'ddyan', 'ddyanj', 'ddyanh', 'ddyad',
+'ddyal', 'ddyalg', 'ddyalm', 'ddyalb', 'ddyals', 'ddyalt', 'ddyalp', 'ddyalh', 'ddyam', 'ddyab', 'ddyabs', 'ddyas', 'ddyass', 'ddyang', 'ddyaj', 'ddyac',
+'ddyak', 'ddyat', 'ddyap', 'ddyah', 'ddyae', 'ddyaeg', 'ddyaegg', 'ddyaegs', 'ddyaen', 'ddyaenj', 'ddyaenh', 'ddyaed', 'ddyael', 'ddyaelg', 'ddyaelm', 'ddyaelb',
+'ddyaels', 'ddyaelt', 'ddyaelp', 'ddyaelh', 'ddyaem', 'ddyaeb', 'ddyaebs', 'ddyaes', 'ddyaess', 'ddyaeng', 'ddyaej', 'ddyaec', 'ddyaek', 'ddyaet', 'ddyaep', 'ddyaeh',
+'ddeo', 'ddeog', 'ddeogg', 'ddeogs', 'ddeon', 'ddeonj', 'ddeonh', 'ddeod', 'ddeol', 'ddeolg', 'ddeolm', 'ddeolb', 'ddeols', 'ddeolt', 'ddeolp', 'ddeolh',
+'ddeom', 'ddeob', 'ddeobs', 'ddeos', 'ddeoss', 'ddeong', 'ddeoj', 'ddeoc', 'ddeok', 'ddeot', 'ddeop', 'ddeoh', 'dde', 'ddeg', 'ddegg', 'ddegs',
+'dden', 'ddenj', 'ddenh', 'dded', 'ddel', 'ddelg', 'ddelm', 'ddelb', 'ddels', 'ddelt', 'ddelp', 'ddelh', 'ddem', 'ddeb', 'ddebs', 'ddes',
+'ddess', 'ddeng', 'ddej', 'ddec', 'ddek', 'ddet', 'ddep', 'ddeh', 'ddyeo', 'ddyeog', 'ddyeogg', 'ddyeogs', 'ddyeon', 'ddyeonj', 'ddyeonh', 'ddyeod',
+'ddyeol', 'ddyeolg', 'ddyeolm', 'ddyeolb', 'ddyeols', 'ddyeolt', 'ddyeolp', 'ddyeolh', 'ddyeom', 'ddyeob', 'ddyeobs', 'ddyeos', 'ddyeoss', 'ddyeong', 'ddyeoj', 'ddyeoc',
+'ddyeok', 'ddyeot', 'ddyeop', 'ddyeoh', 'ddye', 'ddyeg', 'ddyegg', 'ddyegs', 'ddyen', 'ddyenj', 'ddyenh', 'ddyed', 'ddyel', 'ddyelg', 'ddyelm', 'ddyelb',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/xb6.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/xb6.php
new file mode 100644 (file)
index 0000000..f1a64f9
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0xb6] = array(
+'ddyels', 'ddyelt', 'ddyelp', 'ddyelh', 'ddyem', 'ddyeb', 'ddyebs', 'ddyes', 'ddyess', 'ddyeng', 'ddyej', 'ddyec', 'ddyek', 'ddyet', 'ddyep', 'ddyeh',
+'ddo', 'ddog', 'ddogg', 'ddogs', 'ddon', 'ddonj', 'ddonh', 'ddod', 'ddol', 'ddolg', 'ddolm', 'ddolb', 'ddols', 'ddolt', 'ddolp', 'ddolh',
+'ddom', 'ddob', 'ddobs', 'ddos', 'ddoss', 'ddong', 'ddoj', 'ddoc', 'ddok', 'ddot', 'ddop', 'ddoh', 'ddwa', 'ddwag', 'ddwagg', 'ddwags',
+'ddwan', 'ddwanj', 'ddwanh', 'ddwad', 'ddwal', 'ddwalg', 'ddwalm', 'ddwalb', 'ddwals', 'ddwalt', 'ddwalp', 'ddwalh', 'ddwam', 'ddwab', 'ddwabs', 'ddwas',
+'ddwass', 'ddwang', 'ddwaj', 'ddwac', 'ddwak', 'ddwat', 'ddwap', 'ddwah', 'ddwae', 'ddwaeg', 'ddwaegg', 'ddwaegs', 'ddwaen', 'ddwaenj', 'ddwaenh', 'ddwaed',
+'ddwael', 'ddwaelg', 'ddwaelm', 'ddwaelb', 'ddwaels', 'ddwaelt', 'ddwaelp', 'ddwaelh', 'ddwaem', 'ddwaeb', 'ddwaebs', 'ddwaes', 'ddwaess', 'ddwaeng', 'ddwaej', 'ddwaec',
+'ddwaek', 'ddwaet', 'ddwaep', 'ddwaeh', 'ddoe', 'ddoeg', 'ddoegg', 'ddoegs', 'ddoen', 'ddoenj', 'ddoenh', 'ddoed', 'ddoel', 'ddoelg', 'ddoelm', 'ddoelb',
+'ddoels', 'ddoelt', 'ddoelp', 'ddoelh', 'ddoem', 'ddoeb', 'ddoebs', 'ddoes', 'ddoess', 'ddoeng', 'ddoej', 'ddoec', 'ddoek', 'ddoet', 'ddoep', 'ddoeh',
+'ddyo', 'ddyog', 'ddyogg', 'ddyogs', 'ddyon', 'ddyonj', 'ddyonh', 'ddyod', 'ddyol', 'ddyolg', 'ddyolm', 'ddyolb', 'ddyols', 'ddyolt', 'ddyolp', 'ddyolh',
+'ddyom', 'ddyob', 'ddyobs', 'ddyos', 'ddyoss', 'ddyong', 'ddyoj', 'ddyoc', 'ddyok', 'ddyot', 'ddyop', 'ddyoh', 'ddu', 'ddug', 'ddugg', 'ddugs',
+'ddun', 'ddunj', 'ddunh', 'ddud', 'ddul', 'ddulg', 'ddulm', 'ddulb', 'dduls', 'ddult', 'ddulp', 'ddulh', 'ddum', 'ddub', 'ddubs', 'ddus',
+'dduss', 'ddung', 'dduj', 'dduc', 'dduk', 'ddut', 'ddup', 'dduh', 'ddweo', 'ddweog', 'ddweogg', 'ddweogs', 'ddweon', 'ddweonj', 'ddweonh', 'ddweod',
+'ddweol', 'ddweolg', 'ddweolm', 'ddweolb', 'ddweols', 'ddweolt', 'ddweolp', 'ddweolh', 'ddweom', 'ddweob', 'ddweobs', 'ddweos', 'ddweoss', 'ddweong', 'ddweoj', 'ddweoc',
+'ddweok', 'ddweot', 'ddweop', 'ddweoh', 'ddwe', 'ddweg', 'ddwegg', 'ddwegs', 'ddwen', 'ddwenj', 'ddwenh', 'ddwed', 'ddwel', 'ddwelg', 'ddwelm', 'ddwelb',
+'ddwels', 'ddwelt', 'ddwelp', 'ddwelh', 'ddwem', 'ddweb', 'ddwebs', 'ddwes', 'ddwess', 'ddweng', 'ddwej', 'ddwec', 'ddwek', 'ddwet', 'ddwep', 'ddweh',
+'ddwi', 'ddwig', 'ddwigg', 'ddwigs', 'ddwin', 'ddwinj', 'ddwinh', 'ddwid', 'ddwil', 'ddwilg', 'ddwilm', 'ddwilb', 'ddwils', 'ddwilt', 'ddwilp', 'ddwilh',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/xb7.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/xb7.php
new file mode 100644 (file)
index 0000000..c66b9e0
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0xb7] = array(
+'ddwim', 'ddwib', 'ddwibs', 'ddwis', 'ddwiss', 'ddwing', 'ddwij', 'ddwic', 'ddwik', 'ddwit', 'ddwip', 'ddwih', 'ddyu', 'ddyug', 'ddyugg', 'ddyugs',
+'ddyun', 'ddyunj', 'ddyunh', 'ddyud', 'ddyul', 'ddyulg', 'ddyulm', 'ddyulb', 'ddyuls', 'ddyult', 'ddyulp', 'ddyulh', 'ddyum', 'ddyub', 'ddyubs', 'ddyus',
+'ddyuss', 'ddyung', 'ddyuj', 'ddyuc', 'ddyuk', 'ddyut', 'ddyup', 'ddyuh', 'ddeu', 'ddeug', 'ddeugg', 'ddeugs', 'ddeun', 'ddeunj', 'ddeunh', 'ddeud',
+'ddeul', 'ddeulg', 'ddeulm', 'ddeulb', 'ddeuls', 'ddeult', 'ddeulp', 'ddeulh', 'ddeum', 'ddeub', 'ddeubs', 'ddeus', 'ddeuss', 'ddeung', 'ddeuj', 'ddeuc',
+'ddeuk', 'ddeut', 'ddeup', 'ddeuh', 'ddyi', 'ddyig', 'ddyigg', 'ddyigs', 'ddyin', 'ddyinj', 'ddyinh', 'ddyid', 'ddyil', 'ddyilg', 'ddyilm', 'ddyilb',
+'ddyils', 'ddyilt', 'ddyilp', 'ddyilh', 'ddyim', 'ddyib', 'ddyibs', 'ddyis', 'ddyiss', 'ddying', 'ddyij', 'ddyic', 'ddyik', 'ddyit', 'ddyip', 'ddyih',
+'ddi', 'ddig', 'ddigg', 'ddigs', 'ddin', 'ddinj', 'ddinh', 'ddid', 'ddil', 'ddilg', 'ddilm', 'ddilb', 'ddils', 'ddilt', 'ddilp', 'ddilh',
+'ddim', 'ddib', 'ddibs', 'ddis', 'ddiss', 'dding', 'ddij', 'ddic', 'ddik', 'ddit', 'ddip', 'ddih', 'ra', 'rag', 'ragg', 'rags',
+'ran', 'ranj', 'ranh', 'rad', 'ral', 'ralg', 'ralm', 'ralb', 'rals', 'ralt', 'ralp', 'ralh', 'ram', 'rab', 'rabs', 'ras',
+'rass', 'rang', 'raj', 'rac', 'rak', 'rat', 'rap', 'rah', 'rae', 'raeg', 'raegg', 'raegs', 'raen', 'raenj', 'raenh', 'raed',
+'rael', 'raelg', 'raelm', 'raelb', 'raels', 'raelt', 'raelp', 'raelh', 'raem', 'raeb', 'raebs', 'raes', 'raess', 'raeng', 'raej', 'raec',
+'raek', 'raet', 'raep', 'raeh', 'rya', 'ryag', 'ryagg', 'ryags', 'ryan', 'ryanj', 'ryanh', 'ryad', 'ryal', 'ryalg', 'ryalm', 'ryalb',
+'ryals', 'ryalt', 'ryalp', 'ryalh', 'ryam', 'ryab', 'ryabs', 'ryas', 'ryass', 'ryang', 'ryaj', 'ryac', 'ryak', 'ryat', 'ryap', 'ryah',
+'ryae', 'ryaeg', 'ryaegg', 'ryaegs', 'ryaen', 'ryaenj', 'ryaenh', 'ryaed', 'ryael', 'ryaelg', 'ryaelm', 'ryaelb', 'ryaels', 'ryaelt', 'ryaelp', 'ryaelh',
+'ryaem', 'ryaeb', 'ryaebs', 'ryaes', 'ryaess', 'ryaeng', 'ryaej', 'ryaec', 'ryaek', 'ryaet', 'ryaep', 'ryaeh', 'reo', 'reog', 'reogg', 'reogs',
+'reon', 'reonj', 'reonh', 'reod', 'reol', 'reolg', 'reolm', 'reolb', 'reols', 'reolt', 'reolp', 'reolh', 'reom', 'reob', 'reobs', 'reos',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/xb8.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/xb8.php
new file mode 100644 (file)
index 0000000..9878e9b
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0xb8] = array(
+'reoss', 'reong', 'reoj', 'reoc', 'reok', 'reot', 'reop', 'reoh', 're', 'reg', 'regg', 'regs', 'ren', 'renj', 'renh', 'red',
+'rel', 'relg', 'relm', 'relb', 'rels', 'relt', 'relp', 'relh', 'rem', 'reb', 'rebs', 'res', 'ress', 'reng', 'rej', 'rec',
+'rek', 'ret', 'rep', 'reh', 'ryeo', 'ryeog', 'ryeogg', 'ryeogs', 'ryeon', 'ryeonj', 'ryeonh', 'ryeod', 'ryeol', 'ryeolg', 'ryeolm', 'ryeolb',
+'ryeols', 'ryeolt', 'ryeolp', 'ryeolh', 'ryeom', 'ryeob', 'ryeobs', 'ryeos', 'ryeoss', 'ryeong', 'ryeoj', 'ryeoc', 'ryeok', 'ryeot', 'ryeop', 'ryeoh',
+'rye', 'ryeg', 'ryegg', 'ryegs', 'ryen', 'ryenj', 'ryenh', 'ryed', 'ryel', 'ryelg', 'ryelm', 'ryelb', 'ryels', 'ryelt', 'ryelp', 'ryelh',
+'ryem', 'ryeb', 'ryebs', 'ryes', 'ryess', 'ryeng', 'ryej', 'ryec', 'ryek', 'ryet', 'ryep', 'ryeh', 'ro', 'rog', 'rogg', 'rogs',
+'ron', 'ronj', 'ronh', 'rod', 'rol', 'rolg', 'rolm', 'rolb', 'rols', 'rolt', 'rolp', 'rolh', 'rom', 'rob', 'robs', 'ros',
+'ross', 'rong', 'roj', 'roc', 'rok', 'rot', 'rop', 'roh', 'rwa', 'rwag', 'rwagg', 'rwags', 'rwan', 'rwanj', 'rwanh', 'rwad',
+'rwal', 'rwalg', 'rwalm', 'rwalb', 'rwals', 'rwalt', 'rwalp', 'rwalh', 'rwam', 'rwab', 'rwabs', 'rwas', 'rwass', 'rwang', 'rwaj', 'rwac',
+'rwak', 'rwat', 'rwap', 'rwah', 'rwae', 'rwaeg', 'rwaegg', 'rwaegs', 'rwaen', 'rwaenj', 'rwaenh', 'rwaed', 'rwael', 'rwaelg', 'rwaelm', 'rwaelb',
+'rwaels', 'rwaelt', 'rwaelp', 'rwaelh', 'rwaem', 'rwaeb', 'rwaebs', 'rwaes', 'rwaess', 'rwaeng', 'rwaej', 'rwaec', 'rwaek', 'rwaet', 'rwaep', 'rwaeh',
+'roe', 'roeg', 'roegg', 'roegs', 'roen', 'roenj', 'roenh', 'roed', 'roel', 'roelg', 'roelm', 'roelb', 'roels', 'roelt', 'roelp', 'roelh',
+'roem', 'roeb', 'roebs', 'roes', 'roess', 'roeng', 'roej', 'roec', 'roek', 'roet', 'roep', 'roeh', 'ryo', 'ryog', 'ryogg', 'ryogs',
+'ryon', 'ryonj', 'ryonh', 'ryod', 'ryol', 'ryolg', 'ryolm', 'ryolb', 'ryols', 'ryolt', 'ryolp', 'ryolh', 'ryom', 'ryob', 'ryobs', 'ryos',
+'ryoss', 'ryong', 'ryoj', 'ryoc', 'ryok', 'ryot', 'ryop', 'ryoh', 'ru', 'rug', 'rugg', 'rugs', 'run', 'runj', 'runh', 'rud',
+'rul', 'rulg', 'rulm', 'rulb', 'ruls', 'rult', 'rulp', 'rulh', 'rum', 'rub', 'rubs', 'rus', 'russ', 'rung', 'ruj', 'ruc',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/xb9.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/xb9.php
new file mode 100644 (file)
index 0000000..098eefe
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0xb9] = array(
+'ruk', 'rut', 'rup', 'ruh', 'rweo', 'rweog', 'rweogg', 'rweogs', 'rweon', 'rweonj', 'rweonh', 'rweod', 'rweol', 'rweolg', 'rweolm', 'rweolb',
+'rweols', 'rweolt', 'rweolp', 'rweolh', 'rweom', 'rweob', 'rweobs', 'rweos', 'rweoss', 'rweong', 'rweoj', 'rweoc', 'rweok', 'rweot', 'rweop', 'rweoh',
+'rwe', 'rweg', 'rwegg', 'rwegs', 'rwen', 'rwenj', 'rwenh', 'rwed', 'rwel', 'rwelg', 'rwelm', 'rwelb', 'rwels', 'rwelt', 'rwelp', 'rwelh',
+'rwem', 'rweb', 'rwebs', 'rwes', 'rwess', 'rweng', 'rwej', 'rwec', 'rwek', 'rwet', 'rwep', 'rweh', 'rwi', 'rwig', 'rwigg', 'rwigs',
+'rwin', 'rwinj', 'rwinh', 'rwid', 'rwil', 'rwilg', 'rwilm', 'rwilb', 'rwils', 'rwilt', 'rwilp', 'rwilh', 'rwim', 'rwib', 'rwibs', 'rwis',
+'rwiss', 'rwing', 'rwij', 'rwic', 'rwik', 'rwit', 'rwip', 'rwih', 'ryu', 'ryug', 'ryugg', 'ryugs', 'ryun', 'ryunj', 'ryunh', 'ryud',
+'ryul', 'ryulg', 'ryulm', 'ryulb', 'ryuls', 'ryult', 'ryulp', 'ryulh', 'ryum', 'ryub', 'ryubs', 'ryus', 'ryuss', 'ryung', 'ryuj', 'ryuc',
+'ryuk', 'ryut', 'ryup', 'ryuh', 'reu', 'reug', 'reugg', 'reugs', 'reun', 'reunj', 'reunh', 'reud', 'reul', 'reulg', 'reulm', 'reulb',
+'reuls', 'reult', 'reulp', 'reulh', 'reum', 'reub', 'reubs', 'reus', 'reuss', 'reung', 'reuj', 'reuc', 'reuk', 'reut', 'reup', 'reuh',
+'ryi', 'ryig', 'ryigg', 'ryigs', 'ryin', 'ryinj', 'ryinh', 'ryid', 'ryil', 'ryilg', 'ryilm', 'ryilb', 'ryils', 'ryilt', 'ryilp', 'ryilh',
+'ryim', 'ryib', 'ryibs', 'ryis', 'ryiss', 'rying', 'ryij', 'ryic', 'ryik', 'ryit', 'ryip', 'ryih', 'ri', 'rig', 'rigg', 'rigs',
+'rin', 'rinj', 'rinh', 'rid', 'ril', 'rilg', 'rilm', 'rilb', 'rils', 'rilt', 'rilp', 'rilh', 'rim', 'rib', 'ribs', 'ris',
+'riss', 'ring', 'rij', 'ric', 'rik', 'rit', 'rip', 'rih', 'ma', 'mag', 'magg', 'mags', 'man', 'manj', 'manh', 'mad',
+'mal', 'malg', 'malm', 'malb', 'mals', 'malt', 'malp', 'malh', 'mam', 'mab', 'mabs', 'mas', 'mass', 'mang', 'maj', 'mac',
+'mak', 'mat', 'map', 'mah', 'mae', 'maeg', 'maegg', 'maegs', 'maen', 'maenj', 'maenh', 'maed', 'mael', 'maelg', 'maelm', 'maelb',
+'maels', 'maelt', 'maelp', 'maelh', 'maem', 'maeb', 'maebs', 'maes', 'maess', 'maeng', 'maej', 'maec', 'maek', 'maet', 'maep', 'maeh',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/xba.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/xba.php
new file mode 100644 (file)
index 0000000..b807cc9
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0xba] = array(
+'mya', 'myag', 'myagg', 'myags', 'myan', 'myanj', 'myanh', 'myad', 'myal', 'myalg', 'myalm', 'myalb', 'myals', 'myalt', 'myalp', 'myalh',
+'myam', 'myab', 'myabs', 'myas', 'myass', 'myang', 'myaj', 'myac', 'myak', 'myat', 'myap', 'myah', 'myae', 'myaeg', 'myaegg', 'myaegs',
+'myaen', 'myaenj', 'myaenh', 'myaed', 'myael', 'myaelg', 'myaelm', 'myaelb', 'myaels', 'myaelt', 'myaelp', 'myaelh', 'myaem', 'myaeb', 'myaebs', 'myaes',
+'myaess', 'myaeng', 'myaej', 'myaec', 'myaek', 'myaet', 'myaep', 'myaeh', 'meo', 'meog', 'meogg', 'meogs', 'meon', 'meonj', 'meonh', 'meod',
+'meol', 'meolg', 'meolm', 'meolb', 'meols', 'meolt', 'meolp', 'meolh', 'meom', 'meob', 'meobs', 'meos', 'meoss', 'meong', 'meoj', 'meoc',
+'meok', 'meot', 'meop', 'meoh', 'me', 'meg', 'megg', 'megs', 'men', 'menj', 'menh', 'med', 'mel', 'melg', 'melm', 'melb',
+'mels', 'melt', 'melp', 'melh', 'mem', 'meb', 'mebs', 'mes', 'mess', 'meng', 'mej', 'mec', 'mek', 'met', 'mep', 'meh',
+'myeo', 'myeog', 'myeogg', 'myeogs', 'myeon', 'myeonj', 'myeonh', 'myeod', 'myeol', 'myeolg', 'myeolm', 'myeolb', 'myeols', 'myeolt', 'myeolp', 'myeolh',
+'myeom', 'myeob', 'myeobs', 'myeos', 'myeoss', 'myeong', 'myeoj', 'myeoc', 'myeok', 'myeot', 'myeop', 'myeoh', 'mye', 'myeg', 'myegg', 'myegs',
+'myen', 'myenj', 'myenh', 'myed', 'myel', 'myelg', 'myelm', 'myelb', 'myels', 'myelt', 'myelp', 'myelh', 'myem', 'myeb', 'myebs', 'myes',
+'myess', 'myeng', 'myej', 'myec', 'myek', 'myet', 'myep', 'myeh', 'mo', 'mog', 'mogg', 'mogs', 'mon', 'monj', 'monh', 'mod',
+'mol', 'molg', 'molm', 'molb', 'mols', 'molt', 'molp', 'molh', 'mom', 'mob', 'mobs', 'mos', 'moss', 'mong', 'moj', 'moc',
+'mok', 'mot', 'mop', 'moh', 'mwa', 'mwag', 'mwagg', 'mwags', 'mwan', 'mwanj', 'mwanh', 'mwad', 'mwal', 'mwalg', 'mwalm', 'mwalb',
+'mwals', 'mwalt', 'mwalp', 'mwalh', 'mwam', 'mwab', 'mwabs', 'mwas', 'mwass', 'mwang', 'mwaj', 'mwac', 'mwak', 'mwat', 'mwap', 'mwah',
+'mwae', 'mwaeg', 'mwaegg', 'mwaegs', 'mwaen', 'mwaenj', 'mwaenh', 'mwaed', 'mwael', 'mwaelg', 'mwaelm', 'mwaelb', 'mwaels', 'mwaelt', 'mwaelp', 'mwaelh',
+'mwaem', 'mwaeb', 'mwaebs', 'mwaes', 'mwaess', 'mwaeng', 'mwaej', 'mwaec', 'mwaek', 'mwaet', 'mwaep', 'mwaeh', 'moe', 'moeg', 'moegg', 'moegs',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/xbb.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/xbb.php
new file mode 100644 (file)
index 0000000..85b906b
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0xbb] = array(
+'moen', 'moenj', 'moenh', 'moed', 'moel', 'moelg', 'moelm', 'moelb', 'moels', 'moelt', 'moelp', 'moelh', 'moem', 'moeb', 'moebs', 'moes',
+'moess', 'moeng', 'moej', 'moec', 'moek', 'moet', 'moep', 'moeh', 'myo', 'myog', 'myogg', 'myogs', 'myon', 'myonj', 'myonh', 'myod',
+'myol', 'myolg', 'myolm', 'myolb', 'myols', 'myolt', 'myolp', 'myolh', 'myom', 'myob', 'myobs', 'myos', 'myoss', 'myong', 'myoj', 'myoc',
+'myok', 'myot', 'myop', 'myoh', 'mu', 'mug', 'mugg', 'mugs', 'mun', 'munj', 'munh', 'mud', 'mul', 'mulg', 'mulm', 'mulb',
+'muls', 'mult', 'mulp', 'mulh', 'mum', 'mub', 'mubs', 'mus', 'muss', 'mung', 'muj', 'muc', 'muk', 'mut', 'mup', 'muh',
+'mweo', 'mweog', 'mweogg', 'mweogs', 'mweon', 'mweonj', 'mweonh', 'mweod', 'mweol', 'mweolg', 'mweolm', 'mweolb', 'mweols', 'mweolt', 'mweolp', 'mweolh',
+'mweom', 'mweob', 'mweobs', 'mweos', 'mweoss', 'mweong', 'mweoj', 'mweoc', 'mweok', 'mweot', 'mweop', 'mweoh', 'mwe', 'mweg', 'mwegg', 'mwegs',
+'mwen', 'mwenj', 'mwenh', 'mwed', 'mwel', 'mwelg', 'mwelm', 'mwelb', 'mwels', 'mwelt', 'mwelp', 'mwelh', 'mwem', 'mweb', 'mwebs', 'mwes',
+'mwess', 'mweng', 'mwej', 'mwec', 'mwek', 'mwet', 'mwep', 'mweh', 'mwi', 'mwig', 'mwigg', 'mwigs', 'mwin', 'mwinj', 'mwinh', 'mwid',
+'mwil', 'mwilg', 'mwilm', 'mwilb', 'mwils', 'mwilt', 'mwilp', 'mwilh', 'mwim', 'mwib', 'mwibs', 'mwis', 'mwiss', 'mwing', 'mwij', 'mwic',
+'mwik', 'mwit', 'mwip', 'mwih', 'myu', 'myug', 'myugg', 'myugs', 'myun', 'myunj', 'myunh', 'myud', 'myul', 'myulg', 'myulm', 'myulb',
+'myuls', 'myult', 'myulp', 'myulh', 'myum', 'myub', 'myubs', 'myus', 'myuss', 'myung', 'myuj', 'myuc', 'myuk', 'myut', 'myup', 'myuh',
+'meu', 'meug', 'meugg', 'meugs', 'meun', 'meunj', 'meunh', 'meud', 'meul', 'meulg', 'meulm', 'meulb', 'meuls', 'meult', 'meulp', 'meulh',
+'meum', 'meub', 'meubs', 'meus', 'meuss', 'meung', 'meuj', 'meuc', 'meuk', 'meut', 'meup', 'meuh', 'myi', 'myig', 'myigg', 'myigs',
+'myin', 'myinj', 'myinh', 'myid', 'myil', 'myilg', 'myilm', 'myilb', 'myils', 'myilt', 'myilp', 'myilh', 'myim', 'myib', 'myibs', 'myis',
+'myiss', 'mying', 'myij', 'myic', 'myik', 'myit', 'myip', 'myih', 'mi', 'mig', 'migg', 'migs', 'min', 'minj', 'minh', 'mid',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/xbc.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/xbc.php
new file mode 100644 (file)
index 0000000..30298aa
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0xbc] = array(
+'mil', 'milg', 'milm', 'milb', 'mils', 'milt', 'milp', 'milh', 'mim', 'mib', 'mibs', 'mis', 'miss', 'ming', 'mij', 'mic',
+'mik', 'mit', 'mip', 'mih', 'ba', 'bag', 'bagg', 'bags', 'ban', 'banj', 'banh', 'bad', 'bal', 'balg', 'balm', 'balb',
+'bals', 'balt', 'balp', 'balh', 'bam', 'bab', 'babs', 'bas', 'bass', 'bang', 'baj', 'bac', 'bak', 'bat', 'bap', 'bah',
+'bae', 'baeg', 'baegg', 'baegs', 'baen', 'baenj', 'baenh', 'baed', 'bael', 'baelg', 'baelm', 'baelb', 'baels', 'baelt', 'baelp', 'baelh',
+'baem', 'baeb', 'baebs', 'baes', 'baess', 'baeng', 'baej', 'baec', 'baek', 'baet', 'baep', 'baeh', 'bya', 'byag', 'byagg', 'byags',
+'byan', 'byanj', 'byanh', 'byad', 'byal', 'byalg', 'byalm', 'byalb', 'byals', 'byalt', 'byalp', 'byalh', 'byam', 'byab', 'byabs', 'byas',
+'byass', 'byang', 'byaj', 'byac', 'byak', 'byat', 'byap', 'byah', 'byae', 'byaeg', 'byaegg', 'byaegs', 'byaen', 'byaenj', 'byaenh', 'byaed',
+'byael', 'byaelg', 'byaelm', 'byaelb', 'byaels', 'byaelt', 'byaelp', 'byaelh', 'byaem', 'byaeb', 'byaebs', 'byaes', 'byaess', 'byaeng', 'byaej', 'byaec',
+'byaek', 'byaet', 'byaep', 'byaeh', 'beo', 'beog', 'beogg', 'beogs', 'beon', 'beonj', 'beonh', 'beod', 'beol', 'beolg', 'beolm', 'beolb',
+'beols', 'beolt', 'beolp', 'beolh', 'beom', 'beob', 'beobs', 'beos', 'beoss', 'beong', 'beoj', 'beoc', 'beok', 'beot', 'beop', 'beoh',
+'be', 'beg', 'begg', 'begs', 'ben', 'benj', 'benh', 'bed', 'bel', 'belg', 'belm', 'belb', 'bels', 'belt', 'belp', 'belh',
+'bem', 'beb', 'bebs', 'bes', 'bess', 'beng', 'bej', 'bec', 'bek', 'bet', 'bep', 'beh', 'byeo', 'byeog', 'byeogg', 'byeogs',
+'byeon', 'byeonj', 'byeonh', 'byeod', 'byeol', 'byeolg', 'byeolm', 'byeolb', 'byeols', 'byeolt', 'byeolp', 'byeolh', 'byeom', 'byeob', 'byeobs', 'byeos',
+'byeoss', 'byeong', 'byeoj', 'byeoc', 'byeok', 'byeot', 'byeop', 'byeoh', 'bye', 'byeg', 'byegg', 'byegs', 'byen', 'byenj', 'byenh', 'byed',
+'byel', 'byelg', 'byelm', 'byelb', 'byels', 'byelt', 'byelp', 'byelh', 'byem', 'byeb', 'byebs', 'byes', 'byess', 'byeng', 'byej', 'byec',
+'byek', 'byet', 'byep', 'byeh', 'bo', 'bog', 'bogg', 'bogs', 'bon', 'bonj', 'bonh', 'bod', 'bol', 'bolg', 'bolm', 'bolb',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/xbd.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/xbd.php
new file mode 100644 (file)
index 0000000..9d02cc5
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0xbd] = array(
+'bols', 'bolt', 'bolp', 'bolh', 'bom', 'bob', 'bobs', 'bos', 'boss', 'bong', 'boj', 'boc', 'bok', 'bot', 'bop', 'boh',
+'bwa', 'bwag', 'bwagg', 'bwags', 'bwan', 'bwanj', 'bwanh', 'bwad', 'bwal', 'bwalg', 'bwalm', 'bwalb', 'bwals', 'bwalt', 'bwalp', 'bwalh',
+'bwam', 'bwab', 'bwabs', 'bwas', 'bwass', 'bwang', 'bwaj', 'bwac', 'bwak', 'bwat', 'bwap', 'bwah', 'bwae', 'bwaeg', 'bwaegg', 'bwaegs',
+'bwaen', 'bwaenj', 'bwaenh', 'bwaed', 'bwael', 'bwaelg', 'bwaelm', 'bwaelb', 'bwaels', 'bwaelt', 'bwaelp', 'bwaelh', 'bwaem', 'bwaeb', 'bwaebs', 'bwaes',
+'bwaess', 'bwaeng', 'bwaej', 'bwaec', 'bwaek', 'bwaet', 'bwaep', 'bwaeh', 'boe', 'boeg', 'boegg', 'boegs', 'boen', 'boenj', 'boenh', 'boed',
+'boel', 'boelg', 'boelm', 'boelb', 'boels', 'boelt', 'boelp', 'boelh', 'boem', 'boeb', 'boebs', 'boes', 'boess', 'boeng', 'boej', 'boec',
+'boek', 'boet', 'boep', 'boeh', 'byo', 'byog', 'byogg', 'byogs', 'byon', 'byonj', 'byonh', 'byod', 'byol', 'byolg', 'byolm', 'byolb',
+'byols', 'byolt', 'byolp', 'byolh', 'byom', 'byob', 'byobs', 'byos', 'byoss', 'byong', 'byoj', 'byoc', 'byok', 'byot', 'byop', 'byoh',
+'bu', 'bug', 'bugg', 'bugs', 'bun', 'bunj', 'bunh', 'bud', 'bul', 'bulg', 'bulm', 'bulb', 'buls', 'bult', 'bulp', 'bulh',
+'bum', 'bub', 'bubs', 'bus', 'buss', 'bung', 'buj', 'buc', 'buk', 'but', 'bup', 'buh', 'bweo', 'bweog', 'bweogg', 'bweogs',
+'bweon', 'bweonj', 'bweonh', 'bweod', 'bweol', 'bweolg', 'bweolm', 'bweolb', 'bweols', 'bweolt', 'bweolp', 'bweolh', 'bweom', 'bweob', 'bweobs', 'bweos',
+'bweoss', 'bweong', 'bweoj', 'bweoc', 'bweok', 'bweot', 'bweop', 'bweoh', 'bwe', 'bweg', 'bwegg', 'bwegs', 'bwen', 'bwenj', 'bwenh', 'bwed',
+'bwel', 'bwelg', 'bwelm', 'bwelb', 'bwels', 'bwelt', 'bwelp', 'bwelh', 'bwem', 'bweb', 'bwebs', 'bwes', 'bwess', 'bweng', 'bwej', 'bwec',
+'bwek', 'bwet', 'bwep', 'bweh', 'bwi', 'bwig', 'bwigg', 'bwigs', 'bwin', 'bwinj', 'bwinh', 'bwid', 'bwil', 'bwilg', 'bwilm', 'bwilb',
+'bwils', 'bwilt', 'bwilp', 'bwilh', 'bwim', 'bwib', 'bwibs', 'bwis', 'bwiss', 'bwing', 'bwij', 'bwic', 'bwik', 'bwit', 'bwip', 'bwih',
+'byu', 'byug', 'byugg', 'byugs', 'byun', 'byunj', 'byunh', 'byud', 'byul', 'byulg', 'byulm', 'byulb', 'byuls', 'byult', 'byulp', 'byulh',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/xbe.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/xbe.php
new file mode 100644 (file)
index 0000000..4a29ef8
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0xbe] = array(
+'byum', 'byub', 'byubs', 'byus', 'byuss', 'byung', 'byuj', 'byuc', 'byuk', 'byut', 'byup', 'byuh', 'beu', 'beug', 'beugg', 'beugs',
+'beun', 'beunj', 'beunh', 'beud', 'beul', 'beulg', 'beulm', 'beulb', 'beuls', 'beult', 'beulp', 'beulh', 'beum', 'beub', 'beubs', 'beus',
+'beuss', 'beung', 'beuj', 'beuc', 'beuk', 'beut', 'beup', 'beuh', 'byi', 'byig', 'byigg', 'byigs', 'byin', 'byinj', 'byinh', 'byid',
+'byil', 'byilg', 'byilm', 'byilb', 'byils', 'byilt', 'byilp', 'byilh', 'byim', 'byib', 'byibs', 'byis', 'byiss', 'bying', 'byij', 'byic',
+'byik', 'byit', 'byip', 'byih', 'bi', 'big', 'bigg', 'bigs', 'bin', 'binj', 'binh', 'bid', 'bil', 'bilg', 'bilm', 'bilb',
+'bils', 'bilt', 'bilp', 'bilh', 'bim', 'bib', 'bibs', 'bis', 'biss', 'bing', 'bij', 'bic', 'bik', 'bit', 'bip', 'bih',
+'bba', 'bbag', 'bbagg', 'bbags', 'bban', 'bbanj', 'bbanh', 'bbad', 'bbal', 'bbalg', 'bbalm', 'bbalb', 'bbals', 'bbalt', 'bbalp', 'bbalh',
+'bbam', 'bbab', 'bbabs', 'bbas', 'bbass', 'bbang', 'bbaj', 'bbac', 'bbak', 'bbat', 'bbap', 'bbah', 'bbae', 'bbaeg', 'bbaegg', 'bbaegs',
+'bbaen', 'bbaenj', 'bbaenh', 'bbaed', 'bbael', 'bbaelg', 'bbaelm', 'bbaelb', 'bbaels', 'bbaelt', 'bbaelp', 'bbaelh', 'bbaem', 'bbaeb', 'bbaebs', 'bbaes',
+'bbaess', 'bbaeng', 'bbaej', 'bbaec', 'bbaek', 'bbaet', 'bbaep', 'bbaeh', 'bbya', 'bbyag', 'bbyagg', 'bbyags', 'bbyan', 'bbyanj', 'bbyanh', 'bbyad',
+'bbyal', 'bbyalg', 'bbyalm', 'bbyalb', 'bbyals', 'bbyalt', 'bbyalp', 'bbyalh', 'bbyam', 'bbyab', 'bbyabs', 'bbyas', 'bbyass', 'bbyang', 'bbyaj', 'bbyac',
+'bbyak', 'bbyat', 'bbyap', 'bbyah', 'bbyae', 'bbyaeg', 'bbyaegg', 'bbyaegs', 'bbyaen', 'bbyaenj', 'bbyaenh', 'bbyaed', 'bbyael', 'bbyaelg', 'bbyaelm', 'bbyaelb',
+'bbyaels', 'bbyaelt', 'bbyaelp', 'bbyaelh', 'bbyaem', 'bbyaeb', 'bbyaebs', 'bbyaes', 'bbyaess', 'bbyaeng', 'bbyaej', 'bbyaec', 'bbyaek', 'bbyaet', 'bbyaep', 'bbyaeh',
+'bbeo', 'bbeog', 'bbeogg', 'bbeogs', 'bbeon', 'bbeonj', 'bbeonh', 'bbeod', 'bbeol', 'bbeolg', 'bbeolm', 'bbeolb', 'bbeols', 'bbeolt', 'bbeolp', 'bbeolh',
+'bbeom', 'bbeob', 'bbeobs', 'bbeos', 'bbeoss', 'bbeong', 'bbeoj', 'bbeoc', 'bbeok', 'bbeot', 'bbeop', 'bbeoh', 'bbe', 'bbeg', 'bbegg', 'bbegs',
+'bben', 'bbenj', 'bbenh', 'bbed', 'bbel', 'bbelg', 'bbelm', 'bbelb', 'bbels', 'bbelt', 'bbelp', 'bbelh', 'bbem', 'bbeb', 'bbebs', 'bbes',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/xbf.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/xbf.php
new file mode 100644 (file)
index 0000000..edb8074
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0xbf] = array(
+'bbess', 'bbeng', 'bbej', 'bbec', 'bbek', 'bbet', 'bbep', 'bbeh', 'bbyeo', 'bbyeog', 'bbyeogg', 'bbyeogs', 'bbyeon', 'bbyeonj', 'bbyeonh', 'bbyeod',
+'bbyeol', 'bbyeolg', 'bbyeolm', 'bbyeolb', 'bbyeols', 'bbyeolt', 'bbyeolp', 'bbyeolh', 'bbyeom', 'bbyeob', 'bbyeobs', 'bbyeos', 'bbyeoss', 'bbyeong', 'bbyeoj', 'bbyeoc',
+'bbyeok', 'bbyeot', 'bbyeop', 'bbyeoh', 'bbye', 'bbyeg', 'bbyegg', 'bbyegs', 'bbyen', 'bbyenj', 'bbyenh', 'bbyed', 'bbyel', 'bbyelg', 'bbyelm', 'bbyelb',
+'bbyels', 'bbyelt', 'bbyelp', 'bbyelh', 'bbyem', 'bbyeb', 'bbyebs', 'bbyes', 'bbyess', 'bbyeng', 'bbyej', 'bbyec', 'bbyek', 'bbyet', 'bbyep', 'bbyeh',
+'bbo', 'bbog', 'bbogg', 'bbogs', 'bbon', 'bbonj', 'bbonh', 'bbod', 'bbol', 'bbolg', 'bbolm', 'bbolb', 'bbols', 'bbolt', 'bbolp', 'bbolh',
+'bbom', 'bbob', 'bbobs', 'bbos', 'bboss', 'bbong', 'bboj', 'bboc', 'bbok', 'bbot', 'bbop', 'bboh', 'bbwa', 'bbwag', 'bbwagg', 'bbwags',
+'bbwan', 'bbwanj', 'bbwanh', 'bbwad', 'bbwal', 'bbwalg', 'bbwalm', 'bbwalb', 'bbwals', 'bbwalt', 'bbwalp', 'bbwalh', 'bbwam', 'bbwab', 'bbwabs', 'bbwas',
+'bbwass', 'bbwang', 'bbwaj', 'bbwac', 'bbwak', 'bbwat', 'bbwap', 'bbwah', 'bbwae', 'bbwaeg', 'bbwaegg', 'bbwaegs', 'bbwaen', 'bbwaenj', 'bbwaenh', 'bbwaed',
+'bbwael', 'bbwaelg', 'bbwaelm', 'bbwaelb', 'bbwaels', 'bbwaelt', 'bbwaelp', 'bbwaelh', 'bbwaem', 'bbwaeb', 'bbwaebs', 'bbwaes', 'bbwaess', 'bbwaeng', 'bbwaej', 'bbwaec',
+'bbwaek', 'bbwaet', 'bbwaep', 'bbwaeh', 'bboe', 'bboeg', 'bboegg', 'bboegs', 'bboen', 'bboenj', 'bboenh', 'bboed', 'bboel', 'bboelg', 'bboelm', 'bboelb',
+'bboels', 'bboelt', 'bboelp', 'bboelh', 'bboem', 'bboeb', 'bboebs', 'bboes', 'bboess', 'bboeng', 'bboej', 'bboec', 'bboek', 'bboet', 'bboep', 'bboeh',
+'bbyo', 'bbyog', 'bbyogg', 'bbyogs', 'bbyon', 'bbyonj', 'bbyonh', 'bbyod', 'bbyol', 'bbyolg', 'bbyolm', 'bbyolb', 'bbyols', 'bbyolt', 'bbyolp', 'bbyolh',
+'bbyom', 'bbyob', 'bbyobs', 'bbyos', 'bbyoss', 'bbyong', 'bbyoj', 'bbyoc', 'bbyok', 'bbyot', 'bbyop', 'bbyoh', 'bbu', 'bbug', 'bbugg', 'bbugs',
+'bbun', 'bbunj', 'bbunh', 'bbud', 'bbul', 'bbulg', 'bbulm', 'bbulb', 'bbuls', 'bbult', 'bbulp', 'bbulh', 'bbum', 'bbub', 'bbubs', 'bbus',
+'bbuss', 'bbung', 'bbuj', 'bbuc', 'bbuk', 'bbut', 'bbup', 'bbuh', 'bbweo', 'bbweog', 'bbweogg', 'bbweogs', 'bbweon', 'bbweonj', 'bbweonh', 'bbweod',
+'bbweol', 'bbweolg', 'bbweolm', 'bbweolb', 'bbweols', 'bbweolt', 'bbweolp', 'bbweolh', 'bbweom', 'bbweob', 'bbweobs', 'bbweos', 'bbweoss', 'bbweong', 'bbweoj', 'bbweoc',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/xc0.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/xc0.php
new file mode 100644 (file)
index 0000000..4dc359c
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0xc0] = array(
+'bbweok', 'bbweot', 'bbweop', 'bbweoh', 'bbwe', 'bbweg', 'bbwegg', 'bbwegs', 'bbwen', 'bbwenj', 'bbwenh', 'bbwed', 'bbwel', 'bbwelg', 'bbwelm', 'bbwelb',
+'bbwels', 'bbwelt', 'bbwelp', 'bbwelh', 'bbwem', 'bbweb', 'bbwebs', 'bbwes', 'bbwess', 'bbweng', 'bbwej', 'bbwec', 'bbwek', 'bbwet', 'bbwep', 'bbweh',
+'bbwi', 'bbwig', 'bbwigg', 'bbwigs', 'bbwin', 'bbwinj', 'bbwinh', 'bbwid', 'bbwil', 'bbwilg', 'bbwilm', 'bbwilb', 'bbwils', 'bbwilt', 'bbwilp', 'bbwilh',
+'bbwim', 'bbwib', 'bbwibs', 'bbwis', 'bbwiss', 'bbwing', 'bbwij', 'bbwic', 'bbwik', 'bbwit', 'bbwip', 'bbwih', 'bbyu', 'bbyug', 'bbyugg', 'bbyugs',
+'bbyun', 'bbyunj', 'bbyunh', 'bbyud', 'bbyul', 'bbyulg', 'bbyulm', 'bbyulb', 'bbyuls', 'bbyult', 'bbyulp', 'bbyulh', 'bbyum', 'bbyub', 'bbyubs', 'bbyus',
+'bbyuss', 'bbyung', 'bbyuj', 'bbyuc', 'bbyuk', 'bbyut', 'bbyup', 'bbyuh', 'bbeu', 'bbeug', 'bbeugg', 'bbeugs', 'bbeun', 'bbeunj', 'bbeunh', 'bbeud',
+'bbeul', 'bbeulg', 'bbeulm', 'bbeulb', 'bbeuls', 'bbeult', 'bbeulp', 'bbeulh', 'bbeum', 'bbeub', 'bbeubs', 'bbeus', 'bbeuss', 'bbeung', 'bbeuj', 'bbeuc',
+'bbeuk', 'bbeut', 'bbeup', 'bbeuh', 'bbyi', 'bbyig', 'bbyigg', 'bbyigs', 'bbyin', 'bbyinj', 'bbyinh', 'bbyid', 'bbyil', 'bbyilg', 'bbyilm', 'bbyilb',
+'bbyils', 'bbyilt', 'bbyilp', 'bbyilh', 'bbyim', 'bbyib', 'bbyibs', 'bbyis', 'bbyiss', 'bbying', 'bbyij', 'bbyic', 'bbyik', 'bbyit', 'bbyip', 'bbyih',
+'bbi', 'bbig', 'bbigg', 'bbigs', 'bbin', 'bbinj', 'bbinh', 'bbid', 'bbil', 'bbilg', 'bbilm', 'bbilb', 'bbils', 'bbilt', 'bbilp', 'bbilh',
+'bbim', 'bbib', 'bbibs', 'bbis', 'bbiss', 'bbing', 'bbij', 'bbic', 'bbik', 'bbit', 'bbip', 'bbih', 'sa', 'sag', 'sagg', 'sags',
+'san', 'sanj', 'sanh', 'sad', 'sal', 'salg', 'salm', 'salb', 'sals', 'salt', 'salp', 'salh', 'sam', 'sab', 'sabs', 'sas',
+'sass', 'sang', 'saj', 'sac', 'sak', 'sat', 'sap', 'sah', 'sae', 'saeg', 'saegg', 'saegs', 'saen', 'saenj', 'saenh', 'saed',
+'sael', 'saelg', 'saelm', 'saelb', 'saels', 'saelt', 'saelp', 'saelh', 'saem', 'saeb', 'saebs', 'saes', 'saess', 'saeng', 'saej', 'saec',
+'saek', 'saet', 'saep', 'saeh', 'sya', 'syag', 'syagg', 'syags', 'syan', 'syanj', 'syanh', 'syad', 'syal', 'syalg', 'syalm', 'syalb',
+'syals', 'syalt', 'syalp', 'syalh', 'syam', 'syab', 'syabs', 'syas', 'syass', 'syang', 'syaj', 'syac', 'syak', 'syat', 'syap', 'syah',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/xc1.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/xc1.php
new file mode 100644 (file)
index 0000000..d47dc2f
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0xc1] = array(
+'syae', 'syaeg', 'syaegg', 'syaegs', 'syaen', 'syaenj', 'syaenh', 'syaed', 'syael', 'syaelg', 'syaelm', 'syaelb', 'syaels', 'syaelt', 'syaelp', 'syaelh',
+'syaem', 'syaeb', 'syaebs', 'syaes', 'syaess', 'syaeng', 'syaej', 'syaec', 'syaek', 'syaet', 'syaep', 'syaeh', 'seo', 'seog', 'seogg', 'seogs',
+'seon', 'seonj', 'seonh', 'seod', 'seol', 'seolg', 'seolm', 'seolb', 'seols', 'seolt', 'seolp', 'seolh', 'seom', 'seob', 'seobs', 'seos',
+'seoss', 'seong', 'seoj', 'seoc', 'seok', 'seot', 'seop', 'seoh', 'se', 'seg', 'segg', 'segs', 'sen', 'senj', 'senh', 'sed',
+'sel', 'selg', 'selm', 'selb', 'sels', 'selt', 'selp', 'selh', 'sem', 'seb', 'sebs', 'ses', 'sess', 'seng', 'sej', 'sec',
+'sek', 'set', 'sep', 'seh', 'syeo', 'syeog', 'syeogg', 'syeogs', 'syeon', 'syeonj', 'syeonh', 'syeod', 'syeol', 'syeolg', 'syeolm', 'syeolb',
+'syeols', 'syeolt', 'syeolp', 'syeolh', 'syeom', 'syeob', 'syeobs', 'syeos', 'syeoss', 'syeong', 'syeoj', 'syeoc', 'syeok', 'syeot', 'syeop', 'syeoh',
+'sye', 'syeg', 'syegg', 'syegs', 'syen', 'syenj', 'syenh', 'syed', 'syel', 'syelg', 'syelm', 'syelb', 'syels', 'syelt', 'syelp', 'syelh',
+'syem', 'syeb', 'syebs', 'syes', 'syess', 'syeng', 'syej', 'syec', 'syek', 'syet', 'syep', 'syeh', 'so', 'sog', 'sogg', 'sogs',
+'son', 'sonj', 'sonh', 'sod', 'sol', 'solg', 'solm', 'solb', 'sols', 'solt', 'solp', 'solh', 'som', 'sob', 'sobs', 'sos',
+'soss', 'song', 'soj', 'soc', 'sok', 'sot', 'sop', 'soh', 'swa', 'swag', 'swagg', 'swags', 'swan', 'swanj', 'swanh', 'swad',
+'swal', 'swalg', 'swalm', 'swalb', 'swals', 'swalt', 'swalp', 'swalh', 'swam', 'swab', 'swabs', 'swas', 'swass', 'swang', 'swaj', 'swac',
+'swak', 'swat', 'swap', 'swah', 'swae', 'swaeg', 'swaegg', 'swaegs', 'swaen', 'swaenj', 'swaenh', 'swaed', 'swael', 'swaelg', 'swaelm', 'swaelb',
+'swaels', 'swaelt', 'swaelp', 'swaelh', 'swaem', 'swaeb', 'swaebs', 'swaes', 'swaess', 'swaeng', 'swaej', 'swaec', 'swaek', 'swaet', 'swaep', 'swaeh',
+'soe', 'soeg', 'soegg', 'soegs', 'soen', 'soenj', 'soenh', 'soed', 'soel', 'soelg', 'soelm', 'soelb', 'soels', 'soelt', 'soelp', 'soelh',
+'soem', 'soeb', 'soebs', 'soes', 'soess', 'soeng', 'soej', 'soec', 'soek', 'soet', 'soep', 'soeh', 'syo', 'syog', 'syogg', 'syogs',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/xc2.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/xc2.php
new file mode 100644 (file)
index 0000000..b584b76
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0xc2] = array(
+'syon', 'syonj', 'syonh', 'syod', 'syol', 'syolg', 'syolm', 'syolb', 'syols', 'syolt', 'syolp', 'syolh', 'syom', 'syob', 'syobs', 'syos',
+'syoss', 'syong', 'syoj', 'syoc', 'syok', 'syot', 'syop', 'syoh', 'su', 'sug', 'sugg', 'sugs', 'sun', 'sunj', 'sunh', 'sud',
+'sul', 'sulg', 'sulm', 'sulb', 'suls', 'sult', 'sulp', 'sulh', 'sum', 'sub', 'subs', 'sus', 'suss', 'sung', 'suj', 'suc',
+'suk', 'sut', 'sup', 'suh', 'sweo', 'sweog', 'sweogg', 'sweogs', 'sweon', 'sweonj', 'sweonh', 'sweod', 'sweol', 'sweolg', 'sweolm', 'sweolb',
+'sweols', 'sweolt', 'sweolp', 'sweolh', 'sweom', 'sweob', 'sweobs', 'sweos', 'sweoss', 'sweong', 'sweoj', 'sweoc', 'sweok', 'sweot', 'sweop', 'sweoh',
+'swe', 'sweg', 'swegg', 'swegs', 'swen', 'swenj', 'swenh', 'swed', 'swel', 'swelg', 'swelm', 'swelb', 'swels', 'swelt', 'swelp', 'swelh',
+'swem', 'sweb', 'swebs', 'swes', 'swess', 'sweng', 'swej', 'swec', 'swek', 'swet', 'swep', 'sweh', 'swi', 'swig', 'swigg', 'swigs',
+'swin', 'swinj', 'swinh', 'swid', 'swil', 'swilg', 'swilm', 'swilb', 'swils', 'swilt', 'swilp', 'swilh', 'swim', 'swib', 'swibs', 'swis',
+'swiss', 'swing', 'swij', 'swic', 'swik', 'swit', 'swip', 'swih', 'syu', 'syug', 'syugg', 'syugs', 'syun', 'syunj', 'syunh', 'syud',
+'syul', 'syulg', 'syulm', 'syulb', 'syuls', 'syult', 'syulp', 'syulh', 'syum', 'syub', 'syubs', 'syus', 'syuss', 'syung', 'syuj', 'syuc',
+'syuk', 'syut', 'syup', 'syuh', 'seu', 'seug', 'seugg', 'seugs', 'seun', 'seunj', 'seunh', 'seud', 'seul', 'seulg', 'seulm', 'seulb',
+'seuls', 'seult', 'seulp', 'seulh', 'seum', 'seub', 'seubs', 'seus', 'seuss', 'seung', 'seuj', 'seuc', 'seuk', 'seut', 'seup', 'seuh',
+'syi', 'syig', 'syigg', 'syigs', 'syin', 'syinj', 'syinh', 'syid', 'syil', 'syilg', 'syilm', 'syilb', 'syils', 'syilt', 'syilp', 'syilh',
+'syim', 'syib', 'syibs', 'syis', 'syiss', 'sying', 'syij', 'syic', 'syik', 'syit', 'syip', 'syih', 'si', 'sig', 'sigg', 'sigs',
+'sin', 'sinj', 'sinh', 'sid', 'sil', 'silg', 'silm', 'silb', 'sils', 'silt', 'silp', 'silh', 'sim', 'sib', 'sibs', 'sis',
+'siss', 'sing', 'sij', 'sic', 'sik', 'sit', 'sip', 'sih', 'ssa', 'ssag', 'ssagg', 'ssags', 'ssan', 'ssanj', 'ssanh', 'ssad',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/xc3.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/xc3.php
new file mode 100644 (file)
index 0000000..0944d44
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0xc3] = array(
+'ssal', 'ssalg', 'ssalm', 'ssalb', 'ssals', 'ssalt', 'ssalp', 'ssalh', 'ssam', 'ssab', 'ssabs', 'ssas', 'ssass', 'ssang', 'ssaj', 'ssac',
+'ssak', 'ssat', 'ssap', 'ssah', 'ssae', 'ssaeg', 'ssaegg', 'ssaegs', 'ssaen', 'ssaenj', 'ssaenh', 'ssaed', 'ssael', 'ssaelg', 'ssaelm', 'ssaelb',
+'ssaels', 'ssaelt', 'ssaelp', 'ssaelh', 'ssaem', 'ssaeb', 'ssaebs', 'ssaes', 'ssaess', 'ssaeng', 'ssaej', 'ssaec', 'ssaek', 'ssaet', 'ssaep', 'ssaeh',
+'ssya', 'ssyag', 'ssyagg', 'ssyags', 'ssyan', 'ssyanj', 'ssyanh', 'ssyad', 'ssyal', 'ssyalg', 'ssyalm', 'ssyalb', 'ssyals', 'ssyalt', 'ssyalp', 'ssyalh',
+'ssyam', 'ssyab', 'ssyabs', 'ssyas', 'ssyass', 'ssyang', 'ssyaj', 'ssyac', 'ssyak', 'ssyat', 'ssyap', 'ssyah', 'ssyae', 'ssyaeg', 'ssyaegg', 'ssyaegs',
+'ssyaen', 'ssyaenj', 'ssyaenh', 'ssyaed', 'ssyael', 'ssyaelg', 'ssyaelm', 'ssyaelb', 'ssyaels', 'ssyaelt', 'ssyaelp', 'ssyaelh', 'ssyaem', 'ssyaeb', 'ssyaebs', 'ssyaes',
+'ssyaess', 'ssyaeng', 'ssyaej', 'ssyaec', 'ssyaek', 'ssyaet', 'ssyaep', 'ssyaeh', 'sseo', 'sseog', 'sseogg', 'sseogs', 'sseon', 'sseonj', 'sseonh', 'sseod',
+'sseol', 'sseolg', 'sseolm', 'sseolb', 'sseols', 'sseolt', 'sseolp', 'sseolh', 'sseom', 'sseob', 'sseobs', 'sseos', 'sseoss', 'sseong', 'sseoj', 'sseoc',
+'sseok', 'sseot', 'sseop', 'sseoh', 'sse', 'sseg', 'ssegg', 'ssegs', 'ssen', 'ssenj', 'ssenh', 'ssed', 'ssel', 'sselg', 'sselm', 'sselb',
+'ssels', 'sselt', 'sselp', 'sselh', 'ssem', 'sseb', 'ssebs', 'sses', 'ssess', 'sseng', 'ssej', 'ssec', 'ssek', 'sset', 'ssep', 'sseh',
+'ssyeo', 'ssyeog', 'ssyeogg', 'ssyeogs', 'ssyeon', 'ssyeonj', 'ssyeonh', 'ssyeod', 'ssyeol', 'ssyeolg', 'ssyeolm', 'ssyeolb', 'ssyeols', 'ssyeolt', 'ssyeolp', 'ssyeolh',
+'ssyeom', 'ssyeob', 'ssyeobs', 'ssyeos', 'ssyeoss', 'ssyeong', 'ssyeoj', 'ssyeoc', 'ssyeok', 'ssyeot', 'ssyeop', 'ssyeoh', 'ssye', 'ssyeg', 'ssyegg', 'ssyegs',
+'ssyen', 'ssyenj', 'ssyenh', 'ssyed', 'ssyel', 'ssyelg', 'ssyelm', 'ssyelb', 'ssyels', 'ssyelt', 'ssyelp', 'ssyelh', 'ssyem', 'ssyeb', 'ssyebs', 'ssyes',
+'ssyess', 'ssyeng', 'ssyej', 'ssyec', 'ssyek', 'ssyet', 'ssyep', 'ssyeh', 'sso', 'ssog', 'ssogg', 'ssogs', 'sson', 'ssonj', 'ssonh', 'ssod',
+'ssol', 'ssolg', 'ssolm', 'ssolb', 'ssols', 'ssolt', 'ssolp', 'ssolh', 'ssom', 'ssob', 'ssobs', 'ssos', 'ssoss', 'ssong', 'ssoj', 'ssoc',
+'ssok', 'ssot', 'ssop', 'ssoh', 'sswa', 'sswag', 'sswagg', 'sswags', 'sswan', 'sswanj', 'sswanh', 'sswad', 'sswal', 'sswalg', 'sswalm', 'sswalb',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/xc4.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/xc4.php
new file mode 100644 (file)
index 0000000..959195d
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0xc4] = array(
+'sswals', 'sswalt', 'sswalp', 'sswalh', 'sswam', 'sswab', 'sswabs', 'sswas', 'sswass', 'sswang', 'sswaj', 'sswac', 'sswak', 'sswat', 'sswap', 'sswah',
+'sswae', 'sswaeg', 'sswaegg', 'sswaegs', 'sswaen', 'sswaenj', 'sswaenh', 'sswaed', 'sswael', 'sswaelg', 'sswaelm', 'sswaelb', 'sswaels', 'sswaelt', 'sswaelp', 'sswaelh',
+'sswaem', 'sswaeb', 'sswaebs', 'sswaes', 'sswaess', 'sswaeng', 'sswaej', 'sswaec', 'sswaek', 'sswaet', 'sswaep', 'sswaeh', 'ssoe', 'ssoeg', 'ssoegg', 'ssoegs',
+'ssoen', 'ssoenj', 'ssoenh', 'ssoed', 'ssoel', 'ssoelg', 'ssoelm', 'ssoelb', 'ssoels', 'ssoelt', 'ssoelp', 'ssoelh', 'ssoem', 'ssoeb', 'ssoebs', 'ssoes',
+'ssoess', 'ssoeng', 'ssoej', 'ssoec', 'ssoek', 'ssoet', 'ssoep', 'ssoeh', 'ssyo', 'ssyog', 'ssyogg', 'ssyogs', 'ssyon', 'ssyonj', 'ssyonh', 'ssyod',
+'ssyol', 'ssyolg', 'ssyolm', 'ssyolb', 'ssyols', 'ssyolt', 'ssyolp', 'ssyolh', 'ssyom', 'ssyob', 'ssyobs', 'ssyos', 'ssyoss', 'ssyong', 'ssyoj', 'ssyoc',
+'ssyok', 'ssyot', 'ssyop', 'ssyoh', 'ssu', 'ssug', 'ssugg', 'ssugs', 'ssun', 'ssunj', 'ssunh', 'ssud', 'ssul', 'ssulg', 'ssulm', 'ssulb',
+'ssuls', 'ssult', 'ssulp', 'ssulh', 'ssum', 'ssub', 'ssubs', 'ssus', 'ssuss', 'ssung', 'ssuj', 'ssuc', 'ssuk', 'ssut', 'ssup', 'ssuh',
+'ssweo', 'ssweog', 'ssweogg', 'ssweogs', 'ssweon', 'ssweonj', 'ssweonh', 'ssweod', 'ssweol', 'ssweolg', 'ssweolm', 'ssweolb', 'ssweols', 'ssweolt', 'ssweolp', 'ssweolh',
+'ssweom', 'ssweob', 'ssweobs', 'ssweos', 'ssweoss', 'ssweong', 'ssweoj', 'ssweoc', 'ssweok', 'ssweot', 'ssweop', 'ssweoh', 'sswe', 'ssweg', 'sswegg', 'sswegs',
+'sswen', 'sswenj', 'sswenh', 'sswed', 'sswel', 'sswelg', 'sswelm', 'sswelb', 'sswels', 'sswelt', 'sswelp', 'sswelh', 'sswem', 'ssweb', 'sswebs', 'sswes',
+'sswess', 'ssweng', 'sswej', 'sswec', 'sswek', 'sswet', 'sswep', 'ssweh', 'sswi', 'sswig', 'sswigg', 'sswigs', 'sswin', 'sswinj', 'sswinh', 'sswid',
+'sswil', 'sswilg', 'sswilm', 'sswilb', 'sswils', 'sswilt', 'sswilp', 'sswilh', 'sswim', 'sswib', 'sswibs', 'sswis', 'sswiss', 'sswing', 'sswij', 'sswic',
+'sswik', 'sswit', 'sswip', 'sswih', 'ssyu', 'ssyug', 'ssyugg', 'ssyugs', 'ssyun', 'ssyunj', 'ssyunh', 'ssyud', 'ssyul', 'ssyulg', 'ssyulm', 'ssyulb',
+'ssyuls', 'ssyult', 'ssyulp', 'ssyulh', 'ssyum', 'ssyub', 'ssyubs', 'ssyus', 'ssyuss', 'ssyung', 'ssyuj', 'ssyuc', 'ssyuk', 'ssyut', 'ssyup', 'ssyuh',
+'sseu', 'sseug', 'sseugg', 'sseugs', 'sseun', 'sseunj', 'sseunh', 'sseud', 'sseul', 'sseulg', 'sseulm', 'sseulb', 'sseuls', 'sseult', 'sseulp', 'sseulh',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/xc5.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/xc5.php
new file mode 100644 (file)
index 0000000..574194d
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0xc5] = array(
+'sseum', 'sseub', 'sseubs', 'sseus', 'sseuss', 'sseung', 'sseuj', 'sseuc', 'sseuk', 'sseut', 'sseup', 'sseuh', 'ssyi', 'ssyig', 'ssyigg', 'ssyigs',
+'ssyin', 'ssyinj', 'ssyinh', 'ssyid', 'ssyil', 'ssyilg', 'ssyilm', 'ssyilb', 'ssyils', 'ssyilt', 'ssyilp', 'ssyilh', 'ssyim', 'ssyib', 'ssyibs', 'ssyis',
+'ssyiss', 'ssying', 'ssyij', 'ssyic', 'ssyik', 'ssyit', 'ssyip', 'ssyih', 'ssi', 'ssig', 'ssigg', 'ssigs', 'ssin', 'ssinj', 'ssinh', 'ssid',
+'ssil', 'ssilg', 'ssilm', 'ssilb', 'ssils', 'ssilt', 'ssilp', 'ssilh', 'ssim', 'ssib', 'ssibs', 'ssis', 'ssiss', 'ssing', 'ssij', 'ssic',
+'ssik', 'ssit', 'ssip', 'ssih', 'a', 'ag', 'agg', 'ags', 'an', 'anj', 'anh', 'ad', 'al', 'alg', 'alm', 'alb',
+'als', 'alt', 'alp', 'alh', 'am', 'ab', 'abs', 'as', 'ass', 'ang', 'aj', 'ac', 'ak', 'at', 'ap', 'ah',
+'ae', 'aeg', 'aegg', 'aegs', 'aen', 'aenj', 'aenh', 'aed', 'ael', 'aelg', 'aelm', 'aelb', 'aels', 'aelt', 'aelp', 'aelh',
+'aem', 'aeb', 'aebs', 'aes', 'aess', 'aeng', 'aej', 'aec', 'aek', 'aet', 'aep', 'aeh', 'ya', 'yag', 'yagg', 'yags',
+'yan', 'yanj', 'yanh', 'yad', 'yal', 'yalg', 'yalm', 'yalb', 'yals', 'yalt', 'yalp', 'yalh', 'yam', 'yab', 'yabs', 'yas',
+'yass', 'yang', 'yaj', 'yac', 'yak', 'yat', 'yap', 'yah', 'yae', 'yaeg', 'yaegg', 'yaegs', 'yaen', 'yaenj', 'yaenh', 'yaed',
+'yael', 'yaelg', 'yaelm', 'yaelb', 'yaels', 'yaelt', 'yaelp', 'yaelh', 'yaem', 'yaeb', 'yaebs', 'yaes', 'yaess', 'yaeng', 'yaej', 'yaec',
+'yaek', 'yaet', 'yaep', 'yaeh', 'eo', 'eog', 'eogg', 'eogs', 'eon', 'eonj', 'eonh', 'eod', 'eol', 'eolg', 'eolm', 'eolb',
+'eols', 'eolt', 'eolp', 'eolh', 'eom', 'eob', 'eobs', 'eos', 'eoss', 'eong', 'eoj', 'eoc', 'eok', 'eot', 'eop', 'eoh',
+'e', 'eg', 'egg', 'egs', 'en', 'enj', 'enh', 'ed', 'el', 'elg', 'elm', 'elb', 'els', 'elt', 'elp', 'elh',
+'em', 'eb', 'ebs', 'es', 'ess', 'eng', 'ej', 'ec', 'ek', 'et', 'ep', 'eh', 'yeo', 'yeog', 'yeogg', 'yeogs',
+'yeon', 'yeonj', 'yeonh', 'yeod', 'yeol', 'yeolg', 'yeolm', 'yeolb', 'yeols', 'yeolt', 'yeolp', 'yeolh', 'yeom', 'yeob', 'yeobs', 'yeos',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/xc6.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/xc6.php
new file mode 100644 (file)
index 0000000..6a15c38
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0xc6] = array(
+'yeoss', 'yeong', 'yeoj', 'yeoc', 'yeok', 'yeot', 'yeop', 'yeoh', 'ye', 'yeg', 'yegg', 'yegs', 'yen', 'yenj', 'yenh', 'yed',
+'yel', 'yelg', 'yelm', 'yelb', 'yels', 'yelt', 'yelp', 'yelh', 'yem', 'yeb', 'yebs', 'yes', 'yess', 'yeng', 'yej', 'yec',
+'yek', 'yet', 'yep', 'yeh', 'o', 'og', 'ogg', 'ogs', 'on', 'onj', 'onh', 'od', 'ol', 'olg', 'olm', 'olb',
+'ols', 'olt', 'olp', 'olh', 'om', 'ob', 'obs', 'os', 'oss', 'ong', 'oj', 'oc', 'ok', 'ot', 'op', 'oh',
+'wa', 'wag', 'wagg', 'wags', 'wan', 'wanj', 'wanh', 'wad', 'wal', 'walg', 'walm', 'walb', 'wals', 'walt', 'walp', 'walh',
+'wam', 'wab', 'wabs', 'was', 'wass', 'wang', 'waj', 'wac', 'wak', 'wat', 'wap', 'wah', 'wae', 'waeg', 'waegg', 'waegs',
+'waen', 'waenj', 'waenh', 'waed', 'wael', 'waelg', 'waelm', 'waelb', 'waels', 'waelt', 'waelp', 'waelh', 'waem', 'waeb', 'waebs', 'waes',
+'waess', 'waeng', 'waej', 'waec', 'waek', 'waet', 'waep', 'waeh', 'oe', 'oeg', 'oegg', 'oegs', 'oen', 'oenj', 'oenh', 'oed',
+'oel', 'oelg', 'oelm', 'oelb', 'oels', 'oelt', 'oelp', 'oelh', 'oem', 'oeb', 'oebs', 'oes', 'oess', 'oeng', 'oej', 'oec',
+'oek', 'oet', 'oep', 'oeh', 'yo', 'yog', 'yogg', 'yogs', 'yon', 'yonj', 'yonh', 'yod', 'yol', 'yolg', 'yolm', 'yolb',
+'yols', 'yolt', 'yolp', 'yolh', 'yom', 'yob', 'yobs', 'yos', 'yoss', 'yong', 'yoj', 'yoc', 'yok', 'yot', 'yop', 'yoh',
+'u', 'ug', 'ugg', 'ugs', 'un', 'unj', 'unh', 'ud', 'ul', 'ulg', 'ulm', 'ulb', 'uls', 'ult', 'ulp', 'ulh',
+'um', 'ub', 'ubs', 'us', 'uss', 'ung', 'uj', 'uc', 'uk', 'ut', 'up', 'uh', 'weo', 'weog', 'weogg', 'weogs',
+'weon', 'weonj', 'weonh', 'weod', 'weol', 'weolg', 'weolm', 'weolb', 'weols', 'weolt', 'weolp', 'weolh', 'weom', 'weob', 'weobs', 'weos',
+'weoss', 'weong', 'weoj', 'weoc', 'weok', 'weot', 'weop', 'weoh', 'we', 'weg', 'wegg', 'wegs', 'wen', 'wenj', 'wenh', 'wed',
+'wel', 'welg', 'welm', 'welb', 'wels', 'welt', 'welp', 'welh', 'wem', 'web', 'webs', 'wes', 'wess', 'weng', 'wej', 'wec',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/xc7.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/xc7.php
new file mode 100644 (file)
index 0000000..215d302
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0xc7] = array(
+'wek', 'wet', 'wep', 'weh', 'wi', 'wig', 'wigg', 'wigs', 'win', 'winj', 'winh', 'wid', 'wil', 'wilg', 'wilm', 'wilb',
+'wils', 'wilt', 'wilp', 'wilh', 'wim', 'wib', 'wibs', 'wis', 'wiss', 'wing', 'wij', 'wic', 'wik', 'wit', 'wip', 'wih',
+'yu', 'yug', 'yugg', 'yugs', 'yun', 'yunj', 'yunh', 'yud', 'yul', 'yulg', 'yulm', 'yulb', 'yuls', 'yult', 'yulp', 'yulh',
+'yum', 'yub', 'yubs', 'yus', 'yuss', 'yung', 'yuj', 'yuc', 'yuk', 'yut', 'yup', 'yuh', 'eu', 'eug', 'eugg', 'eugs',
+'eun', 'eunj', 'eunh', 'eud', 'eul', 'eulg', 'eulm', 'eulb', 'euls', 'eult', 'eulp', 'eulh', 'eum', 'eub', 'eubs', 'eus',
+'euss', 'eung', 'euj', 'euc', 'euk', 'eut', 'eup', 'euh', 'yi', 'yig', 'yigg', 'yigs', 'yin', 'yinj', 'yinh', 'yid',
+'yil', 'yilg', 'yilm', 'yilb', 'yils', 'yilt', 'yilp', 'yilh', 'yim', 'yib', 'yibs', 'yis', 'yiss', 'ying', 'yij', 'yic',
+'yik', 'yit', 'yip', 'yih', 'i', 'ig', 'igg', 'igs', 'in', 'inj', 'inh', 'id', 'il', 'ilg', 'ilm', 'ilb',
+'ils', 'ilt', 'ilp', 'ilh', 'im', 'ib', 'ibs', 'is', 'iss', 'ing', 'ij', 'ic', 'ik', 'it', 'ip', 'ih',
+'ja', 'jag', 'jagg', 'jags', 'jan', 'janj', 'janh', 'jad', 'jal', 'jalg', 'jalm', 'jalb', 'jals', 'jalt', 'jalp', 'jalh',
+'jam', 'jab', 'jabs', 'jas', 'jass', 'jang', 'jaj', 'jac', 'jak', 'jat', 'jap', 'jah', 'jae', 'jaeg', 'jaegg', 'jaegs',
+'jaen', 'jaenj', 'jaenh', 'jaed', 'jael', 'jaelg', 'jaelm', 'jaelb', 'jaels', 'jaelt', 'jaelp', 'jaelh', 'jaem', 'jaeb', 'jaebs', 'jaes',
+'jaess', 'jaeng', 'jaej', 'jaec', 'jaek', 'jaet', 'jaep', 'jaeh', 'jya', 'jyag', 'jyagg', 'jyags', 'jyan', 'jyanj', 'jyanh', 'jyad',
+'jyal', 'jyalg', 'jyalm', 'jyalb', 'jyals', 'jyalt', 'jyalp', 'jyalh', 'jyam', 'jyab', 'jyabs', 'jyas', 'jyass', 'jyang', 'jyaj', 'jyac',
+'jyak', 'jyat', 'jyap', 'jyah', 'jyae', 'jyaeg', 'jyaegg', 'jyaegs', 'jyaen', 'jyaenj', 'jyaenh', 'jyaed', 'jyael', 'jyaelg', 'jyaelm', 'jyaelb',
+'jyaels', 'jyaelt', 'jyaelp', 'jyaelh', 'jyaem', 'jyaeb', 'jyaebs', 'jyaes', 'jyaess', 'jyaeng', 'jyaej', 'jyaec', 'jyaek', 'jyaet', 'jyaep', 'jyaeh',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/xc8.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/xc8.php
new file mode 100644 (file)
index 0000000..1b7ce9a
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0xc8] = array(
+'jeo', 'jeog', 'jeogg', 'jeogs', 'jeon', 'jeonj', 'jeonh', 'jeod', 'jeol', 'jeolg', 'jeolm', 'jeolb', 'jeols', 'jeolt', 'jeolp', 'jeolh',
+'jeom', 'jeob', 'jeobs', 'jeos', 'jeoss', 'jeong', 'jeoj', 'jeoc', 'jeok', 'jeot', 'jeop', 'jeoh', 'je', 'jeg', 'jegg', 'jegs',
+'jen', 'jenj', 'jenh', 'jed', 'jel', 'jelg', 'jelm', 'jelb', 'jels', 'jelt', 'jelp', 'jelh', 'jem', 'jeb', 'jebs', 'jes',
+'jess', 'jeng', 'jej', 'jec', 'jek', 'jet', 'jep', 'jeh', 'jyeo', 'jyeog', 'jyeogg', 'jyeogs', 'jyeon', 'jyeonj', 'jyeonh', 'jyeod',
+'jyeol', 'jyeolg', 'jyeolm', 'jyeolb', 'jyeols', 'jyeolt', 'jyeolp', 'jyeolh', 'jyeom', 'jyeob', 'jyeobs', 'jyeos', 'jyeoss', 'jyeong', 'jyeoj', 'jyeoc',
+'jyeok', 'jyeot', 'jyeop', 'jyeoh', 'jye', 'jyeg', 'jyegg', 'jyegs', 'jyen', 'jyenj', 'jyenh', 'jyed', 'jyel', 'jyelg', 'jyelm', 'jyelb',
+'jyels', 'jyelt', 'jyelp', 'jyelh', 'jyem', 'jyeb', 'jyebs', 'jyes', 'jyess', 'jyeng', 'jyej', 'jyec', 'jyek', 'jyet', 'jyep', 'jyeh',
+'jo', 'jog', 'jogg', 'jogs', 'jon', 'jonj', 'jonh', 'jod', 'jol', 'jolg', 'jolm', 'jolb', 'jols', 'jolt', 'jolp', 'jolh',
+'jom', 'job', 'jobs', 'jos', 'joss', 'jong', 'joj', 'joc', 'jok', 'jot', 'jop', 'joh', 'jwa', 'jwag', 'jwagg', 'jwags',
+'jwan', 'jwanj', 'jwanh', 'jwad', 'jwal', 'jwalg', 'jwalm', 'jwalb', 'jwals', 'jwalt', 'jwalp', 'jwalh', 'jwam', 'jwab', 'jwabs', 'jwas',
+'jwass', 'jwang', 'jwaj', 'jwac', 'jwak', 'jwat', 'jwap', 'jwah', 'jwae', 'jwaeg', 'jwaegg', 'jwaegs', 'jwaen', 'jwaenj', 'jwaenh', 'jwaed',
+'jwael', 'jwaelg', 'jwaelm', 'jwaelb', 'jwaels', 'jwaelt', 'jwaelp', 'jwaelh', 'jwaem', 'jwaeb', 'jwaebs', 'jwaes', 'jwaess', 'jwaeng', 'jwaej', 'jwaec',
+'jwaek', 'jwaet', 'jwaep', 'jwaeh', 'joe', 'joeg', 'joegg', 'joegs', 'joen', 'joenj', 'joenh', 'joed', 'joel', 'joelg', 'joelm', 'joelb',
+'joels', 'joelt', 'joelp', 'joelh', 'joem', 'joeb', 'joebs', 'joes', 'joess', 'joeng', 'joej', 'joec', 'joek', 'joet', 'joep', 'joeh',
+'jyo', 'jyog', 'jyogg', 'jyogs', 'jyon', 'jyonj', 'jyonh', 'jyod', 'jyol', 'jyolg', 'jyolm', 'jyolb', 'jyols', 'jyolt', 'jyolp', 'jyolh',
+'jyom', 'jyob', 'jyobs', 'jyos', 'jyoss', 'jyong', 'jyoj', 'jyoc', 'jyok', 'jyot', 'jyop', 'jyoh', 'ju', 'jug', 'jugg', 'jugs',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/xc9.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/xc9.php
new file mode 100644 (file)
index 0000000..01b149e
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0xc9] = array(
+'jun', 'junj', 'junh', 'jud', 'jul', 'julg', 'julm', 'julb', 'juls', 'jult', 'julp', 'julh', 'jum', 'jub', 'jubs', 'jus',
+'juss', 'jung', 'juj', 'juc', 'juk', 'jut', 'jup', 'juh', 'jweo', 'jweog', 'jweogg', 'jweogs', 'jweon', 'jweonj', 'jweonh', 'jweod',
+'jweol', 'jweolg', 'jweolm', 'jweolb', 'jweols', 'jweolt', 'jweolp', 'jweolh', 'jweom', 'jweob', 'jweobs', 'jweos', 'jweoss', 'jweong', 'jweoj', 'jweoc',
+'jweok', 'jweot', 'jweop', 'jweoh', 'jwe', 'jweg', 'jwegg', 'jwegs', 'jwen', 'jwenj', 'jwenh', 'jwed', 'jwel', 'jwelg', 'jwelm', 'jwelb',
+'jwels', 'jwelt', 'jwelp', 'jwelh', 'jwem', 'jweb', 'jwebs', 'jwes', 'jwess', 'jweng', 'jwej', 'jwec', 'jwek', 'jwet', 'jwep', 'jweh',
+'jwi', 'jwig', 'jwigg', 'jwigs', 'jwin', 'jwinj', 'jwinh', 'jwid', 'jwil', 'jwilg', 'jwilm', 'jwilb', 'jwils', 'jwilt', 'jwilp', 'jwilh',
+'jwim', 'jwib', 'jwibs', 'jwis', 'jwiss', 'jwing', 'jwij', 'jwic', 'jwik', 'jwit', 'jwip', 'jwih', 'jyu', 'jyug', 'jyugg', 'jyugs',
+'jyun', 'jyunj', 'jyunh', 'jyud', 'jyul', 'jyulg', 'jyulm', 'jyulb', 'jyuls', 'jyult', 'jyulp', 'jyulh', 'jyum', 'jyub', 'jyubs', 'jyus',
+'jyuss', 'jyung', 'jyuj', 'jyuc', 'jyuk', 'jyut', 'jyup', 'jyuh', 'jeu', 'jeug', 'jeugg', 'jeugs', 'jeun', 'jeunj', 'jeunh', 'jeud',
+'jeul', 'jeulg', 'jeulm', 'jeulb', 'jeuls', 'jeult', 'jeulp', 'jeulh', 'jeum', 'jeub', 'jeubs', 'jeus', 'jeuss', 'jeung', 'jeuj', 'jeuc',
+'jeuk', 'jeut', 'jeup', 'jeuh', 'jyi', 'jyig', 'jyigg', 'jyigs', 'jyin', 'jyinj', 'jyinh', 'jyid', 'jyil', 'jyilg', 'jyilm', 'jyilb',
+'jyils', 'jyilt', 'jyilp', 'jyilh', 'jyim', 'jyib', 'jyibs', 'jyis', 'jyiss', 'jying', 'jyij', 'jyic', 'jyik', 'jyit', 'jyip', 'jyih',
+'ji', 'jig', 'jigg', 'jigs', 'jin', 'jinj', 'jinh', 'jid', 'jil', 'jilg', 'jilm', 'jilb', 'jils', 'jilt', 'jilp', 'jilh',
+'jim', 'jib', 'jibs', 'jis', 'jiss', 'jing', 'jij', 'jic', 'jik', 'jit', 'jip', 'jih', 'jja', 'jjag', 'jjagg', 'jjags',
+'jjan', 'jjanj', 'jjanh', 'jjad', 'jjal', 'jjalg', 'jjalm', 'jjalb', 'jjals', 'jjalt', 'jjalp', 'jjalh', 'jjam', 'jjab', 'jjabs', 'jjas',
+'jjass', 'jjang', 'jjaj', 'jjac', 'jjak', 'jjat', 'jjap', 'jjah', 'jjae', 'jjaeg', 'jjaegg', 'jjaegs', 'jjaen', 'jjaenj', 'jjaenh', 'jjaed',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/xca.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/xca.php
new file mode 100644 (file)
index 0000000..94a1f84
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0xca] = array(
+'jjael', 'jjaelg', 'jjaelm', 'jjaelb', 'jjaels', 'jjaelt', 'jjaelp', 'jjaelh', 'jjaem', 'jjaeb', 'jjaebs', 'jjaes', 'jjaess', 'jjaeng', 'jjaej', 'jjaec',
+'jjaek', 'jjaet', 'jjaep', 'jjaeh', 'jjya', 'jjyag', 'jjyagg', 'jjyags', 'jjyan', 'jjyanj', 'jjyanh', 'jjyad', 'jjyal', 'jjyalg', 'jjyalm', 'jjyalb',
+'jjyals', 'jjyalt', 'jjyalp', 'jjyalh', 'jjyam', 'jjyab', 'jjyabs', 'jjyas', 'jjyass', 'jjyang', 'jjyaj', 'jjyac', 'jjyak', 'jjyat', 'jjyap', 'jjyah',
+'jjyae', 'jjyaeg', 'jjyaegg', 'jjyaegs', 'jjyaen', 'jjyaenj', 'jjyaenh', 'jjyaed', 'jjyael', 'jjyaelg', 'jjyaelm', 'jjyaelb', 'jjyaels', 'jjyaelt', 'jjyaelp', 'jjyaelh',
+'jjyaem', 'jjyaeb', 'jjyaebs', 'jjyaes', 'jjyaess', 'jjyaeng', 'jjyaej', 'jjyaec', 'jjyaek', 'jjyaet', 'jjyaep', 'jjyaeh', 'jjeo', 'jjeog', 'jjeogg', 'jjeogs',
+'jjeon', 'jjeonj', 'jjeonh', 'jjeod', 'jjeol', 'jjeolg', 'jjeolm', 'jjeolb', 'jjeols', 'jjeolt', 'jjeolp', 'jjeolh', 'jjeom', 'jjeob', 'jjeobs', 'jjeos',
+'jjeoss', 'jjeong', 'jjeoj', 'jjeoc', 'jjeok', 'jjeot', 'jjeop', 'jjeoh', 'jje', 'jjeg', 'jjegg', 'jjegs', 'jjen', 'jjenj', 'jjenh', 'jjed',
+'jjel', 'jjelg', 'jjelm', 'jjelb', 'jjels', 'jjelt', 'jjelp', 'jjelh', 'jjem', 'jjeb', 'jjebs', 'jjes', 'jjess', 'jjeng', 'jjej', 'jjec',
+'jjek', 'jjet', 'jjep', 'jjeh', 'jjyeo', 'jjyeog', 'jjyeogg', 'jjyeogs', 'jjyeon', 'jjyeonj', 'jjyeonh', 'jjyeod', 'jjyeol', 'jjyeolg', 'jjyeolm', 'jjyeolb',
+'jjyeols', 'jjyeolt', 'jjyeolp', 'jjyeolh', 'jjyeom', 'jjyeob', 'jjyeobs', 'jjyeos', 'jjyeoss', 'jjyeong', 'jjyeoj', 'jjyeoc', 'jjyeok', 'jjyeot', 'jjyeop', 'jjyeoh',
+'jjye', 'jjyeg', 'jjyegg', 'jjyegs', 'jjyen', 'jjyenj', 'jjyenh', 'jjyed', 'jjyel', 'jjyelg', 'jjyelm', 'jjyelb', 'jjyels', 'jjyelt', 'jjyelp', 'jjyelh',
+'jjyem', 'jjyeb', 'jjyebs', 'jjyes', 'jjyess', 'jjyeng', 'jjyej', 'jjyec', 'jjyek', 'jjyet', 'jjyep', 'jjyeh', 'jjo', 'jjog', 'jjogg', 'jjogs',
+'jjon', 'jjonj', 'jjonh', 'jjod', 'jjol', 'jjolg', 'jjolm', 'jjolb', 'jjols', 'jjolt', 'jjolp', 'jjolh', 'jjom', 'jjob', 'jjobs', 'jjos',
+'jjoss', 'jjong', 'jjoj', 'jjoc', 'jjok', 'jjot', 'jjop', 'jjoh', 'jjwa', 'jjwag', 'jjwagg', 'jjwags', 'jjwan', 'jjwanj', 'jjwanh', 'jjwad',
+'jjwal', 'jjwalg', 'jjwalm', 'jjwalb', 'jjwals', 'jjwalt', 'jjwalp', 'jjwalh', 'jjwam', 'jjwab', 'jjwabs', 'jjwas', 'jjwass', 'jjwang', 'jjwaj', 'jjwac',
+'jjwak', 'jjwat', 'jjwap', 'jjwah', 'jjwae', 'jjwaeg', 'jjwaegg', 'jjwaegs', 'jjwaen', 'jjwaenj', 'jjwaenh', 'jjwaed', 'jjwael', 'jjwaelg', 'jjwaelm', 'jjwaelb',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/xcb.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/xcb.php
new file mode 100644 (file)
index 0000000..74d3309
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0xcb] = array(
+'jjwaels', 'jjwaelt', 'jjwaelp', 'jjwaelh', 'jjwaem', 'jjwaeb', 'jjwaebs', 'jjwaes', 'jjwaess', 'jjwaeng', 'jjwaej', 'jjwaec', 'jjwaek', 'jjwaet', 'jjwaep', 'jjwaeh',
+'jjoe', 'jjoeg', 'jjoegg', 'jjoegs', 'jjoen', 'jjoenj', 'jjoenh', 'jjoed', 'jjoel', 'jjoelg', 'jjoelm', 'jjoelb', 'jjoels', 'jjoelt', 'jjoelp', 'jjoelh',
+'jjoem', 'jjoeb', 'jjoebs', 'jjoes', 'jjoess', 'jjoeng', 'jjoej', 'jjoec', 'jjoek', 'jjoet', 'jjoep', 'jjoeh', 'jjyo', 'jjyog', 'jjyogg', 'jjyogs',
+'jjyon', 'jjyonj', 'jjyonh', 'jjyod', 'jjyol', 'jjyolg', 'jjyolm', 'jjyolb', 'jjyols', 'jjyolt', 'jjyolp', 'jjyolh', 'jjyom', 'jjyob', 'jjyobs', 'jjyos',
+'jjyoss', 'jjyong', 'jjyoj', 'jjyoc', 'jjyok', 'jjyot', 'jjyop', 'jjyoh', 'jju', 'jjug', 'jjugg', 'jjugs', 'jjun', 'jjunj', 'jjunh', 'jjud',
+'jjul', 'jjulg', 'jjulm', 'jjulb', 'jjuls', 'jjult', 'jjulp', 'jjulh', 'jjum', 'jjub', 'jjubs', 'jjus', 'jjuss', 'jjung', 'jjuj', 'jjuc',
+'jjuk', 'jjut', 'jjup', 'jjuh', 'jjweo', 'jjweog', 'jjweogg', 'jjweogs', 'jjweon', 'jjweonj', 'jjweonh', 'jjweod', 'jjweol', 'jjweolg', 'jjweolm', 'jjweolb',
+'jjweols', 'jjweolt', 'jjweolp', 'jjweolh', 'jjweom', 'jjweob', 'jjweobs', 'jjweos', 'jjweoss', 'jjweong', 'jjweoj', 'jjweoc', 'jjweok', 'jjweot', 'jjweop', 'jjweoh',
+'jjwe', 'jjweg', 'jjwegg', 'jjwegs', 'jjwen', 'jjwenj', 'jjwenh', 'jjwed', 'jjwel', 'jjwelg', 'jjwelm', 'jjwelb', 'jjwels', 'jjwelt', 'jjwelp', 'jjwelh',
+'jjwem', 'jjweb', 'jjwebs', 'jjwes', 'jjwess', 'jjweng', 'jjwej', 'jjwec', 'jjwek', 'jjwet', 'jjwep', 'jjweh', 'jjwi', 'jjwig', 'jjwigg', 'jjwigs',
+'jjwin', 'jjwinj', 'jjwinh', 'jjwid', 'jjwil', 'jjwilg', 'jjwilm', 'jjwilb', 'jjwils', 'jjwilt', 'jjwilp', 'jjwilh', 'jjwim', 'jjwib', 'jjwibs', 'jjwis',
+'jjwiss', 'jjwing', 'jjwij', 'jjwic', 'jjwik', 'jjwit', 'jjwip', 'jjwih', 'jjyu', 'jjyug', 'jjyugg', 'jjyugs', 'jjyun', 'jjyunj', 'jjyunh', 'jjyud',
+'jjyul', 'jjyulg', 'jjyulm', 'jjyulb', 'jjyuls', 'jjyult', 'jjyulp', 'jjyulh', 'jjyum', 'jjyub', 'jjyubs', 'jjyus', 'jjyuss', 'jjyung', 'jjyuj', 'jjyuc',
+'jjyuk', 'jjyut', 'jjyup', 'jjyuh', 'jjeu', 'jjeug', 'jjeugg', 'jjeugs', 'jjeun', 'jjeunj', 'jjeunh', 'jjeud', 'jjeul', 'jjeulg', 'jjeulm', 'jjeulb',
+'jjeuls', 'jjeult', 'jjeulp', 'jjeulh', 'jjeum', 'jjeub', 'jjeubs', 'jjeus', 'jjeuss', 'jjeung', 'jjeuj', 'jjeuc', 'jjeuk', 'jjeut', 'jjeup', 'jjeuh',
+'jjyi', 'jjyig', 'jjyigg', 'jjyigs', 'jjyin', 'jjyinj', 'jjyinh', 'jjyid', 'jjyil', 'jjyilg', 'jjyilm', 'jjyilb', 'jjyils', 'jjyilt', 'jjyilp', 'jjyilh',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/xcc.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/xcc.php
new file mode 100644 (file)
index 0000000..56bd516
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0xcc] = array(
+'jjyim', 'jjyib', 'jjyibs', 'jjyis', 'jjyiss', 'jjying', 'jjyij', 'jjyic', 'jjyik', 'jjyit', 'jjyip', 'jjyih', 'jji', 'jjig', 'jjigg', 'jjigs',
+'jjin', 'jjinj', 'jjinh', 'jjid', 'jjil', 'jjilg', 'jjilm', 'jjilb', 'jjils', 'jjilt', 'jjilp', 'jjilh', 'jjim', 'jjib', 'jjibs', 'jjis',
+'jjiss', 'jjing', 'jjij', 'jjic', 'jjik', 'jjit', 'jjip', 'jjih', 'ca', 'cag', 'cagg', 'cags', 'can', 'canj', 'canh', 'cad',
+'cal', 'calg', 'calm', 'calb', 'cals', 'calt', 'calp', 'calh', 'cam', 'cab', 'cabs', 'cas', 'cass', 'cang', 'caj', 'cac',
+'cak', 'cat', 'cap', 'cah', 'cae', 'caeg', 'caegg', 'caegs', 'caen', 'caenj', 'caenh', 'caed', 'cael', 'caelg', 'caelm', 'caelb',
+'caels', 'caelt', 'caelp', 'caelh', 'caem', 'caeb', 'caebs', 'caes', 'caess', 'caeng', 'caej', 'caec', 'caek', 'caet', 'caep', 'caeh',
+'cya', 'cyag', 'cyagg', 'cyags', 'cyan', 'cyanj', 'cyanh', 'cyad', 'cyal', 'cyalg', 'cyalm', 'cyalb', 'cyals', 'cyalt', 'cyalp', 'cyalh',
+'cyam', 'cyab', 'cyabs', 'cyas', 'cyass', 'cyang', 'cyaj', 'cyac', 'cyak', 'cyat', 'cyap', 'cyah', 'cyae', 'cyaeg', 'cyaegg', 'cyaegs',
+'cyaen', 'cyaenj', 'cyaenh', 'cyaed', 'cyael', 'cyaelg', 'cyaelm', 'cyaelb', 'cyaels', 'cyaelt', 'cyaelp', 'cyaelh', 'cyaem', 'cyaeb', 'cyaebs', 'cyaes',
+'cyaess', 'cyaeng', 'cyaej', 'cyaec', 'cyaek', 'cyaet', 'cyaep', 'cyaeh', 'ceo', 'ceog', 'ceogg', 'ceogs', 'ceon', 'ceonj', 'ceonh', 'ceod',
+'ceol', 'ceolg', 'ceolm', 'ceolb', 'ceols', 'ceolt', 'ceolp', 'ceolh', 'ceom', 'ceob', 'ceobs', 'ceos', 'ceoss', 'ceong', 'ceoj', 'ceoc',
+'ceok', 'ceot', 'ceop', 'ceoh', 'ce', 'ceg', 'cegg', 'cegs', 'cen', 'cenj', 'cenh', 'ced', 'cel', 'celg', 'celm', 'celb',
+'cels', 'celt', 'celp', 'celh', 'cem', 'ceb', 'cebs', 'ces', 'cess', 'ceng', 'cej', 'cec', 'cek', 'cet', 'cep', 'ceh',
+'cyeo', 'cyeog', 'cyeogg', 'cyeogs', 'cyeon', 'cyeonj', 'cyeonh', 'cyeod', 'cyeol', 'cyeolg', 'cyeolm', 'cyeolb', 'cyeols', 'cyeolt', 'cyeolp', 'cyeolh',
+'cyeom', 'cyeob', 'cyeobs', 'cyeos', 'cyeoss', 'cyeong', 'cyeoj', 'cyeoc', 'cyeok', 'cyeot', 'cyeop', 'cyeoh', 'cye', 'cyeg', 'cyegg', 'cyegs',
+'cyen', 'cyenj', 'cyenh', 'cyed', 'cyel', 'cyelg', 'cyelm', 'cyelb', 'cyels', 'cyelt', 'cyelp', 'cyelh', 'cyem', 'cyeb', 'cyebs', 'cyes',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/xcd.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/xcd.php
new file mode 100644 (file)
index 0000000..c0a098c
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0xcd] = array(
+'cyess', 'cyeng', 'cyej', 'cyec', 'cyek', 'cyet', 'cyep', 'cyeh', 'co', 'cog', 'cogg', 'cogs', 'con', 'conj', 'conh', 'cod',
+'col', 'colg', 'colm', 'colb', 'cols', 'colt', 'colp', 'colh', 'com', 'cob', 'cobs', 'cos', 'coss', 'cong', 'coj', 'coc',
+'cok', 'cot', 'cop', 'coh', 'cwa', 'cwag', 'cwagg', 'cwags', 'cwan', 'cwanj', 'cwanh', 'cwad', 'cwal', 'cwalg', 'cwalm', 'cwalb',
+'cwals', 'cwalt', 'cwalp', 'cwalh', 'cwam', 'cwab', 'cwabs', 'cwas', 'cwass', 'cwang', 'cwaj', 'cwac', 'cwak', 'cwat', 'cwap', 'cwah',
+'cwae', 'cwaeg', 'cwaegg', 'cwaegs', 'cwaen', 'cwaenj', 'cwaenh', 'cwaed', 'cwael', 'cwaelg', 'cwaelm', 'cwaelb', 'cwaels', 'cwaelt', 'cwaelp', 'cwaelh',
+'cwaem', 'cwaeb', 'cwaebs', 'cwaes', 'cwaess', 'cwaeng', 'cwaej', 'cwaec', 'cwaek', 'cwaet', 'cwaep', 'cwaeh', 'coe', 'coeg', 'coegg', 'coegs',
+'coen', 'coenj', 'coenh', 'coed', 'coel', 'coelg', 'coelm', 'coelb', 'coels', 'coelt', 'coelp', 'coelh', 'coem', 'coeb', 'coebs', 'coes',
+'coess', 'coeng', 'coej', 'coec', 'coek', 'coet', 'coep', 'coeh', 'cyo', 'cyog', 'cyogg', 'cyogs', 'cyon', 'cyonj', 'cyonh', 'cyod',
+'cyol', 'cyolg', 'cyolm', 'cyolb', 'cyols', 'cyolt', 'cyolp', 'cyolh', 'cyom', 'cyob', 'cyobs', 'cyos', 'cyoss', 'cyong', 'cyoj', 'cyoc',
+'cyok', 'cyot', 'cyop', 'cyoh', 'cu', 'cug', 'cugg', 'cugs', 'cun', 'cunj', 'cunh', 'cud', 'cul', 'culg', 'culm', 'culb',
+'culs', 'cult', 'culp', 'culh', 'cum', 'cub', 'cubs', 'cus', 'cuss', 'cung', 'cuj', 'cuc', 'cuk', 'cut', 'cup', 'cuh',
+'cweo', 'cweog', 'cweogg', 'cweogs', 'cweon', 'cweonj', 'cweonh', 'cweod', 'cweol', 'cweolg', 'cweolm', 'cweolb', 'cweols', 'cweolt', 'cweolp', 'cweolh',
+'cweom', 'cweob', 'cweobs', 'cweos', 'cweoss', 'cweong', 'cweoj', 'cweoc', 'cweok', 'cweot', 'cweop', 'cweoh', 'cwe', 'cweg', 'cwegg', 'cwegs',
+'cwen', 'cwenj', 'cwenh', 'cwed', 'cwel', 'cwelg', 'cwelm', 'cwelb', 'cwels', 'cwelt', 'cwelp', 'cwelh', 'cwem', 'cweb', 'cwebs', 'cwes',
+'cwess', 'cweng', 'cwej', 'cwec', 'cwek', 'cwet', 'cwep', 'cweh', 'cwi', 'cwig', 'cwigg', 'cwigs', 'cwin', 'cwinj', 'cwinh', 'cwid',
+'cwil', 'cwilg', 'cwilm', 'cwilb', 'cwils', 'cwilt', 'cwilp', 'cwilh', 'cwim', 'cwib', 'cwibs', 'cwis', 'cwiss', 'cwing', 'cwij', 'cwic',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/xce.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/xce.php
new file mode 100644 (file)
index 0000000..0fbd401
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0xce] = array(
+'cwik', 'cwit', 'cwip', 'cwih', 'cyu', 'cyug', 'cyugg', 'cyugs', 'cyun', 'cyunj', 'cyunh', 'cyud', 'cyul', 'cyulg', 'cyulm', 'cyulb',
+'cyuls', 'cyult', 'cyulp', 'cyulh', 'cyum', 'cyub', 'cyubs', 'cyus', 'cyuss', 'cyung', 'cyuj', 'cyuc', 'cyuk', 'cyut', 'cyup', 'cyuh',
+'ceu', 'ceug', 'ceugg', 'ceugs', 'ceun', 'ceunj', 'ceunh', 'ceud', 'ceul', 'ceulg', 'ceulm', 'ceulb', 'ceuls', 'ceult', 'ceulp', 'ceulh',
+'ceum', 'ceub', 'ceubs', 'ceus', 'ceuss', 'ceung', 'ceuj', 'ceuc', 'ceuk', 'ceut', 'ceup', 'ceuh', 'cyi', 'cyig', 'cyigg', 'cyigs',
+'cyin', 'cyinj', 'cyinh', 'cyid', 'cyil', 'cyilg', 'cyilm', 'cyilb', 'cyils', 'cyilt', 'cyilp', 'cyilh', 'cyim', 'cyib', 'cyibs', 'cyis',
+'cyiss', 'cying', 'cyij', 'cyic', 'cyik', 'cyit', 'cyip', 'cyih', 'ci', 'cig', 'cigg', 'cigs', 'cin', 'cinj', 'cinh', 'cid',
+'cil', 'cilg', 'cilm', 'cilb', 'cils', 'cilt', 'cilp', 'cilh', 'cim', 'cib', 'cibs', 'cis', 'ciss', 'cing', 'cij', 'cic',
+'cik', 'cit', 'cip', 'cih', 'ka', 'kag', 'kagg', 'kags', 'kan', 'kanj', 'kanh', 'kad', 'kal', 'kalg', 'kalm', 'kalb',
+'kals', 'kalt', 'kalp', 'kalh', 'kam', 'kab', 'kabs', 'kas', 'kass', 'kang', 'kaj', 'kac', 'kak', 'kat', 'kap', 'kah',
+'kae', 'kaeg', 'kaegg', 'kaegs', 'kaen', 'kaenj', 'kaenh', 'kaed', 'kael', 'kaelg', 'kaelm', 'kaelb', 'kaels', 'kaelt', 'kaelp', 'kaelh',
+'kaem', 'kaeb', 'kaebs', 'kaes', 'kaess', 'kaeng', 'kaej', 'kaec', 'kaek', 'kaet', 'kaep', 'kaeh', 'kya', 'kyag', 'kyagg', 'kyags',
+'kyan', 'kyanj', 'kyanh', 'kyad', 'kyal', 'kyalg', 'kyalm', 'kyalb', 'kyals', 'kyalt', 'kyalp', 'kyalh', 'kyam', 'kyab', 'kyabs', 'kyas',
+'kyass', 'kyang', 'kyaj', 'kyac', 'kyak', 'kyat', 'kyap', 'kyah', 'kyae', 'kyaeg', 'kyaegg', 'kyaegs', 'kyaen', 'kyaenj', 'kyaenh', 'kyaed',
+'kyael', 'kyaelg', 'kyaelm', 'kyaelb', 'kyaels', 'kyaelt', 'kyaelp', 'kyaelh', 'kyaem', 'kyaeb', 'kyaebs', 'kyaes', 'kyaess', 'kyaeng', 'kyaej', 'kyaec',
+'kyaek', 'kyaet', 'kyaep', 'kyaeh', 'keo', 'keog', 'keogg', 'keogs', 'keon', 'keonj', 'keonh', 'keod', 'keol', 'keolg', 'keolm', 'keolb',
+'keols', 'keolt', 'keolp', 'keolh', 'keom', 'keob', 'keobs', 'keos', 'keoss', 'keong', 'keoj', 'keoc', 'keok', 'keot', 'keop', 'keoh',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/xcf.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/xcf.php
new file mode 100644 (file)
index 0000000..cf3ce71
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0xcf] = array(
+'ke', 'keg', 'kegg', 'kegs', 'ken', 'kenj', 'kenh', 'ked', 'kel', 'kelg', 'kelm', 'kelb', 'kels', 'kelt', 'kelp', 'kelh',
+'kem', 'keb', 'kebs', 'kes', 'kess', 'keng', 'kej', 'kec', 'kek', 'ket', 'kep', 'keh', 'kyeo', 'kyeog', 'kyeogg', 'kyeogs',
+'kyeon', 'kyeonj', 'kyeonh', 'kyeod', 'kyeol', 'kyeolg', 'kyeolm', 'kyeolb', 'kyeols', 'kyeolt', 'kyeolp', 'kyeolh', 'kyeom', 'kyeob', 'kyeobs', 'kyeos',
+'kyeoss', 'kyeong', 'kyeoj', 'kyeoc', 'kyeok', 'kyeot', 'kyeop', 'kyeoh', 'kye', 'kyeg', 'kyegg', 'kyegs', 'kyen', 'kyenj', 'kyenh', 'kyed',
+'kyel', 'kyelg', 'kyelm', 'kyelb', 'kyels', 'kyelt', 'kyelp', 'kyelh', 'kyem', 'kyeb', 'kyebs', 'kyes', 'kyess', 'kyeng', 'kyej', 'kyec',
+'kyek', 'kyet', 'kyep', 'kyeh', 'ko', 'kog', 'kogg', 'kogs', 'kon', 'konj', 'konh', 'kod', 'kol', 'kolg', 'kolm', 'kolb',
+'kols', 'kolt', 'kolp', 'kolh', 'kom', 'kob', 'kobs', 'kos', 'koss', 'kong', 'koj', 'koc', 'kok', 'kot', 'kop', 'koh',
+'kwa', 'kwag', 'kwagg', 'kwags', 'kwan', 'kwanj', 'kwanh', 'kwad', 'kwal', 'kwalg', 'kwalm', 'kwalb', 'kwals', 'kwalt', 'kwalp', 'kwalh',
+'kwam', 'kwab', 'kwabs', 'kwas', 'kwass', 'kwang', 'kwaj', 'kwac', 'kwak', 'kwat', 'kwap', 'kwah', 'kwae', 'kwaeg', 'kwaegg', 'kwaegs',
+'kwaen', 'kwaenj', 'kwaenh', 'kwaed', 'kwael', 'kwaelg', 'kwaelm', 'kwaelb', 'kwaels', 'kwaelt', 'kwaelp', 'kwaelh', 'kwaem', 'kwaeb', 'kwaebs', 'kwaes',
+'kwaess', 'kwaeng', 'kwaej', 'kwaec', 'kwaek', 'kwaet', 'kwaep', 'kwaeh', 'koe', 'koeg', 'koegg', 'koegs', 'koen', 'koenj', 'koenh', 'koed',
+'koel', 'koelg', 'koelm', 'koelb', 'koels', 'koelt', 'koelp', 'koelh', 'koem', 'koeb', 'koebs', 'koes', 'koess', 'koeng', 'koej', 'koec',
+'koek', 'koet', 'koep', 'koeh', 'kyo', 'kyog', 'kyogg', 'kyogs', 'kyon', 'kyonj', 'kyonh', 'kyod', 'kyol', 'kyolg', 'kyolm', 'kyolb',
+'kyols', 'kyolt', 'kyolp', 'kyolh', 'kyom', 'kyob', 'kyobs', 'kyos', 'kyoss', 'kyong', 'kyoj', 'kyoc', 'kyok', 'kyot', 'kyop', 'kyoh',
+'ku', 'kug', 'kugg', 'kugs', 'kun', 'kunj', 'kunh', 'kud', 'kul', 'kulg', 'kulm', 'kulb', 'kuls', 'kult', 'kulp', 'kulh',
+'kum', 'kub', 'kubs', 'kus', 'kuss', 'kung', 'kuj', 'kuc', 'kuk', 'kut', 'kup', 'kuh', 'kweo', 'kweog', 'kweogg', 'kweogs',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/xd0.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/xd0.php
new file mode 100644 (file)
index 0000000..c2ab053
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0xd0] = array(
+'kweon', 'kweonj', 'kweonh', 'kweod', 'kweol', 'kweolg', 'kweolm', 'kweolb', 'kweols', 'kweolt', 'kweolp', 'kweolh', 'kweom', 'kweob', 'kweobs', 'kweos',
+'kweoss', 'kweong', 'kweoj', 'kweoc', 'kweok', 'kweot', 'kweop', 'kweoh', 'kwe', 'kweg', 'kwegg', 'kwegs', 'kwen', 'kwenj', 'kwenh', 'kwed',
+'kwel', 'kwelg', 'kwelm', 'kwelb', 'kwels', 'kwelt', 'kwelp', 'kwelh', 'kwem', 'kweb', 'kwebs', 'kwes', 'kwess', 'kweng', 'kwej', 'kwec',
+'kwek', 'kwet', 'kwep', 'kweh', 'kwi', 'kwig', 'kwigg', 'kwigs', 'kwin', 'kwinj', 'kwinh', 'kwid', 'kwil', 'kwilg', 'kwilm', 'kwilb',
+'kwils', 'kwilt', 'kwilp', 'kwilh', 'kwim', 'kwib', 'kwibs', 'kwis', 'kwiss', 'kwing', 'kwij', 'kwic', 'kwik', 'kwit', 'kwip', 'kwih',
+'kyu', 'kyug', 'kyugg', 'kyugs', 'kyun', 'kyunj', 'kyunh', 'kyud', 'kyul', 'kyulg', 'kyulm', 'kyulb', 'kyuls', 'kyult', 'kyulp', 'kyulh',
+'kyum', 'kyub', 'kyubs', 'kyus', 'kyuss', 'kyung', 'kyuj', 'kyuc', 'kyuk', 'kyut', 'kyup', 'kyuh', 'keu', 'keug', 'keugg', 'keugs',
+'keun', 'keunj', 'keunh', 'keud', 'keul', 'keulg', 'keulm', 'keulb', 'keuls', 'keult', 'keulp', 'keulh', 'keum', 'keub', 'keubs', 'keus',
+'keuss', 'keung', 'keuj', 'keuc', 'keuk', 'keut', 'keup', 'keuh', 'kyi', 'kyig', 'kyigg', 'kyigs', 'kyin', 'kyinj', 'kyinh', 'kyid',
+'kyil', 'kyilg', 'kyilm', 'kyilb', 'kyils', 'kyilt', 'kyilp', 'kyilh', 'kyim', 'kyib', 'kyibs', 'kyis', 'kyiss', 'kying', 'kyij', 'kyic',
+'kyik', 'kyit', 'kyip', 'kyih', 'ki', 'kig', 'kigg', 'kigs', 'kin', 'kinj', 'kinh', 'kid', 'kil', 'kilg', 'kilm', 'kilb',
+'kils', 'kilt', 'kilp', 'kilh', 'kim', 'kib', 'kibs', 'kis', 'kiss', 'king', 'kij', 'kic', 'kik', 'kit', 'kip', 'kih',
+'ta', 'tag', 'tagg', 'tags', 'tan', 'tanj', 'tanh', 'tad', 'tal', 'talg', 'talm', 'talb', 'tals', 'talt', 'talp', 'talh',
+'tam', 'tab', 'tabs', 'tas', 'tass', 'tang', 'taj', 'tac', 'tak', 'tat', 'tap', 'tah', 'tae', 'taeg', 'taegg', 'taegs',
+'taen', 'taenj', 'taenh', 'taed', 'tael', 'taelg', 'taelm', 'taelb', 'taels', 'taelt', 'taelp', 'taelh', 'taem', 'taeb', 'taebs', 'taes',
+'taess', 'taeng', 'taej', 'taec', 'taek', 'taet', 'taep', 'taeh', 'tya', 'tyag', 'tyagg', 'tyags', 'tyan', 'tyanj', 'tyanh', 'tyad',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/xd1.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/xd1.php
new file mode 100644 (file)
index 0000000..ad50eab
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0xd1] = array(
+'tyal', 'tyalg', 'tyalm', 'tyalb', 'tyals', 'tyalt', 'tyalp', 'tyalh', 'tyam', 'tyab', 'tyabs', 'tyas', 'tyass', 'tyang', 'tyaj', 'tyac',
+'tyak', 'tyat', 'tyap', 'tyah', 'tyae', 'tyaeg', 'tyaegg', 'tyaegs', 'tyaen', 'tyaenj', 'tyaenh', 'tyaed', 'tyael', 'tyaelg', 'tyaelm', 'tyaelb',
+'tyaels', 'tyaelt', 'tyaelp', 'tyaelh', 'tyaem', 'tyaeb', 'tyaebs', 'tyaes', 'tyaess', 'tyaeng', 'tyaej', 'tyaec', 'tyaek', 'tyaet', 'tyaep', 'tyaeh',
+'teo', 'teog', 'teogg', 'teogs', 'teon', 'teonj', 'teonh', 'teod', 'teol', 'teolg', 'teolm', 'teolb', 'teols', 'teolt', 'teolp', 'teolh',
+'teom', 'teob', 'teobs', 'teos', 'teoss', 'teong', 'teoj', 'teoc', 'teok', 'teot', 'teop', 'teoh', 'te', 'teg', 'tegg', 'tegs',
+'ten', 'tenj', 'tenh', 'ted', 'tel', 'telg', 'telm', 'telb', 'tels', 'telt', 'telp', 'telh', 'tem', 'teb', 'tebs', 'tes',
+'tess', 'teng', 'tej', 'tec', 'tek', 'tet', 'tep', 'teh', 'tyeo', 'tyeog', 'tyeogg', 'tyeogs', 'tyeon', 'tyeonj', 'tyeonh', 'tyeod',
+'tyeol', 'tyeolg', 'tyeolm', 'tyeolb', 'tyeols', 'tyeolt', 'tyeolp', 'tyeolh', 'tyeom', 'tyeob', 'tyeobs', 'tyeos', 'tyeoss', 'tyeong', 'tyeoj', 'tyeoc',
+'tyeok', 'tyeot', 'tyeop', 'tyeoh', 'tye', 'tyeg', 'tyegg', 'tyegs', 'tyen', 'tyenj', 'tyenh', 'tyed', 'tyel', 'tyelg', 'tyelm', 'tyelb',
+'tyels', 'tyelt', 'tyelp', 'tyelh', 'tyem', 'tyeb', 'tyebs', 'tyes', 'tyess', 'tyeng', 'tyej', 'tyec', 'tyek', 'tyet', 'tyep', 'tyeh',
+'to', 'tog', 'togg', 'togs', 'ton', 'tonj', 'tonh', 'tod', 'tol', 'tolg', 'tolm', 'tolb', 'tols', 'tolt', 'tolp', 'tolh',
+'tom', 'tob', 'tobs', 'tos', 'toss', 'tong', 'toj', 'toc', 'tok', 'tot', 'top', 'toh', 'twa', 'twag', 'twagg', 'twags',
+'twan', 'twanj', 'twanh', 'twad', 'twal', 'twalg', 'twalm', 'twalb', 'twals', 'twalt', 'twalp', 'twalh', 'twam', 'twab', 'twabs', 'twas',
+'twass', 'twang', 'twaj', 'twac', 'twak', 'twat', 'twap', 'twah', 'twae', 'twaeg', 'twaegg', 'twaegs', 'twaen', 'twaenj', 'twaenh', 'twaed',
+'twael', 'twaelg', 'twaelm', 'twaelb', 'twaels', 'twaelt', 'twaelp', 'twaelh', 'twaem', 'twaeb', 'twaebs', 'twaes', 'twaess', 'twaeng', 'twaej', 'twaec',
+'twaek', 'twaet', 'twaep', 'twaeh', 'toe', 'toeg', 'toegg', 'toegs', 'toen', 'toenj', 'toenh', 'toed', 'toel', 'toelg', 'toelm', 'toelb',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/xd2.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/xd2.php
new file mode 100644 (file)
index 0000000..39ed453
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0xd2] = array(
+'toels', 'toelt', 'toelp', 'toelh', 'toem', 'toeb', 'toebs', 'toes', 'toess', 'toeng', 'toej', 'toec', 'toek', 'toet', 'toep', 'toeh',
+'tyo', 'tyog', 'tyogg', 'tyogs', 'tyon', 'tyonj', 'tyonh', 'tyod', 'tyol', 'tyolg', 'tyolm', 'tyolb', 'tyols', 'tyolt', 'tyolp', 'tyolh',
+'tyom', 'tyob', 'tyobs', 'tyos', 'tyoss', 'tyong', 'tyoj', 'tyoc', 'tyok', 'tyot', 'tyop', 'tyoh', 'tu', 'tug', 'tugg', 'tugs',
+'tun', 'tunj', 'tunh', 'tud', 'tul', 'tulg', 'tulm', 'tulb', 'tuls', 'tult', 'tulp', 'tulh', 'tum', 'tub', 'tubs', 'tus',
+'tuss', 'tung', 'tuj', 'tuc', 'tuk', 'tut', 'tup', 'tuh', 'tweo', 'tweog', 'tweogg', 'tweogs', 'tweon', 'tweonj', 'tweonh', 'tweod',
+'tweol', 'tweolg', 'tweolm', 'tweolb', 'tweols', 'tweolt', 'tweolp', 'tweolh', 'tweom', 'tweob', 'tweobs', 'tweos', 'tweoss', 'tweong', 'tweoj', 'tweoc',
+'tweok', 'tweot', 'tweop', 'tweoh', 'twe', 'tweg', 'twegg', 'twegs', 'twen', 'twenj', 'twenh', 'twed', 'twel', 'twelg', 'twelm', 'twelb',
+'twels', 'twelt', 'twelp', 'twelh', 'twem', 'tweb', 'twebs', 'twes', 'twess', 'tweng', 'twej', 'twec', 'twek', 'twet', 'twep', 'tweh',
+'twi', 'twig', 'twigg', 'twigs', 'twin', 'twinj', 'twinh', 'twid', 'twil', 'twilg', 'twilm', 'twilb', 'twils', 'twilt', 'twilp', 'twilh',
+'twim', 'twib', 'twibs', 'twis', 'twiss', 'twing', 'twij', 'twic', 'twik', 'twit', 'twip', 'twih', 'tyu', 'tyug', 'tyugg', 'tyugs',
+'tyun', 'tyunj', 'tyunh', 'tyud', 'tyul', 'tyulg', 'tyulm', 'tyulb', 'tyuls', 'tyult', 'tyulp', 'tyulh', 'tyum', 'tyub', 'tyubs', 'tyus',
+'tyuss', 'tyung', 'tyuj', 'tyuc', 'tyuk', 'tyut', 'tyup', 'tyuh', 'teu', 'teug', 'teugg', 'teugs', 'teun', 'teunj', 'teunh', 'teud',
+'teul', 'teulg', 'teulm', 'teulb', 'teuls', 'teult', 'teulp', 'teulh', 'teum', 'teub', 'teubs', 'teus', 'teuss', 'teung', 'teuj', 'teuc',
+'teuk', 'teut', 'teup', 'teuh', 'tyi', 'tyig', 'tyigg', 'tyigs', 'tyin', 'tyinj', 'tyinh', 'tyid', 'tyil', 'tyilg', 'tyilm', 'tyilb',
+'tyils', 'tyilt', 'tyilp', 'tyilh', 'tyim', 'tyib', 'tyibs', 'tyis', 'tyiss', 'tying', 'tyij', 'tyic', 'tyik', 'tyit', 'tyip', 'tyih',
+'ti', 'tig', 'tigg', 'tigs', 'tin', 'tinj', 'tinh', 'tid', 'til', 'tilg', 'tilm', 'tilb', 'tils', 'tilt', 'tilp', 'tilh',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/xd3.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/xd3.php
new file mode 100644 (file)
index 0000000..16a461e
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0xd3] = array(
+'tim', 'tib', 'tibs', 'tis', 'tiss', 'ting', 'tij', 'tic', 'tik', 'tit', 'tip', 'tih', 'pa', 'pag', 'pagg', 'pags',
+'pan', 'panj', 'panh', 'pad', 'pal', 'palg', 'palm', 'palb', 'pals', 'palt', 'palp', 'palh', 'pam', 'pab', 'pabs', 'pas',
+'pass', 'pang', 'paj', 'pac', 'pak', 'pat', 'pap', 'pah', 'pae', 'paeg', 'paegg', 'paegs', 'paen', 'paenj', 'paenh', 'paed',
+'pael', 'paelg', 'paelm', 'paelb', 'paels', 'paelt', 'paelp', 'paelh', 'paem', 'paeb', 'paebs', 'paes', 'paess', 'paeng', 'paej', 'paec',
+'paek', 'paet', 'paep', 'paeh', 'pya', 'pyag', 'pyagg', 'pyags', 'pyan', 'pyanj', 'pyanh', 'pyad', 'pyal', 'pyalg', 'pyalm', 'pyalb',
+'pyals', 'pyalt', 'pyalp', 'pyalh', 'pyam', 'pyab', 'pyabs', 'pyas', 'pyass', 'pyang', 'pyaj', 'pyac', 'pyak', 'pyat', 'pyap', 'pyah',
+'pyae', 'pyaeg', 'pyaegg', 'pyaegs', 'pyaen', 'pyaenj', 'pyaenh', 'pyaed', 'pyael', 'pyaelg', 'pyaelm', 'pyaelb', 'pyaels', 'pyaelt', 'pyaelp', 'pyaelh',
+'pyaem', 'pyaeb', 'pyaebs', 'pyaes', 'pyaess', 'pyaeng', 'pyaej', 'pyaec', 'pyaek', 'pyaet', 'pyaep', 'pyaeh', 'peo', 'peog', 'peogg', 'peogs',
+'peon', 'peonj', 'peonh', 'peod', 'peol', 'peolg', 'peolm', 'peolb', 'peols', 'peolt', 'peolp', 'peolh', 'peom', 'peob', 'peobs', 'peos',
+'peoss', 'peong', 'peoj', 'peoc', 'peok', 'peot', 'peop', 'peoh', 'pe', 'peg', 'pegg', 'pegs', 'pen', 'penj', 'penh', 'ped',
+'pel', 'pelg', 'pelm', 'pelb', 'pels', 'pelt', 'pelp', 'pelh', 'pem', 'peb', 'pebs', 'pes', 'pess', 'peng', 'pej', 'pec',
+'pek', 'pet', 'pep', 'peh', 'pyeo', 'pyeog', 'pyeogg', 'pyeogs', 'pyeon', 'pyeonj', 'pyeonh', 'pyeod', 'pyeol', 'pyeolg', 'pyeolm', 'pyeolb',
+'pyeols', 'pyeolt', 'pyeolp', 'pyeolh', 'pyeom', 'pyeob', 'pyeobs', 'pyeos', 'pyeoss', 'pyeong', 'pyeoj', 'pyeoc', 'pyeok', 'pyeot', 'pyeop', 'pyeoh',
+'pye', 'pyeg', 'pyegg', 'pyegs', 'pyen', 'pyenj', 'pyenh', 'pyed', 'pyel', 'pyelg', 'pyelm', 'pyelb', 'pyels', 'pyelt', 'pyelp', 'pyelh',
+'pyem', 'pyeb', 'pyebs', 'pyes', 'pyess', 'pyeng', 'pyej', 'pyec', 'pyek', 'pyet', 'pyep', 'pyeh', 'po', 'pog', 'pogg', 'pogs',
+'pon', 'ponj', 'ponh', 'pod', 'pol', 'polg', 'polm', 'polb', 'pols', 'polt', 'polp', 'polh', 'pom', 'pob', 'pobs', 'pos',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/xd4.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/xd4.php
new file mode 100644 (file)
index 0000000..36e4f50
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0xd4] = array(
+'poss', 'pong', 'poj', 'poc', 'pok', 'pot', 'pop', 'poh', 'pwa', 'pwag', 'pwagg', 'pwags', 'pwan', 'pwanj', 'pwanh', 'pwad',
+'pwal', 'pwalg', 'pwalm', 'pwalb', 'pwals', 'pwalt', 'pwalp', 'pwalh', 'pwam', 'pwab', 'pwabs', 'pwas', 'pwass', 'pwang', 'pwaj', 'pwac',
+'pwak', 'pwat', 'pwap', 'pwah', 'pwae', 'pwaeg', 'pwaegg', 'pwaegs', 'pwaen', 'pwaenj', 'pwaenh', 'pwaed', 'pwael', 'pwaelg', 'pwaelm', 'pwaelb',
+'pwaels', 'pwaelt', 'pwaelp', 'pwaelh', 'pwaem', 'pwaeb', 'pwaebs', 'pwaes', 'pwaess', 'pwaeng', 'pwaej', 'pwaec', 'pwaek', 'pwaet', 'pwaep', 'pwaeh',
+'poe', 'poeg', 'poegg', 'poegs', 'poen', 'poenj', 'poenh', 'poed', 'poel', 'poelg', 'poelm', 'poelb', 'poels', 'poelt', 'poelp', 'poelh',
+'poem', 'poeb', 'poebs', 'poes', 'poess', 'poeng', 'poej', 'poec', 'poek', 'poet', 'poep', 'poeh', 'pyo', 'pyog', 'pyogg', 'pyogs',
+'pyon', 'pyonj', 'pyonh', 'pyod', 'pyol', 'pyolg', 'pyolm', 'pyolb', 'pyols', 'pyolt', 'pyolp', 'pyolh', 'pyom', 'pyob', 'pyobs', 'pyos',
+'pyoss', 'pyong', 'pyoj', 'pyoc', 'pyok', 'pyot', 'pyop', 'pyoh', 'pu', 'pug', 'pugg', 'pugs', 'pun', 'punj', 'punh', 'pud',
+'pul', 'pulg', 'pulm', 'pulb', 'puls', 'pult', 'pulp', 'pulh', 'pum', 'pub', 'pubs', 'pus', 'puss', 'pung', 'puj', 'puc',
+'puk', 'put', 'pup', 'puh', 'pweo', 'pweog', 'pweogg', 'pweogs', 'pweon', 'pweonj', 'pweonh', 'pweod', 'pweol', 'pweolg', 'pweolm', 'pweolb',
+'pweols', 'pweolt', 'pweolp', 'pweolh', 'pweom', 'pweob', 'pweobs', 'pweos', 'pweoss', 'pweong', 'pweoj', 'pweoc', 'pweok', 'pweot', 'pweop', 'pweoh',
+'pwe', 'pweg', 'pwegg', 'pwegs', 'pwen', 'pwenj', 'pwenh', 'pwed', 'pwel', 'pwelg', 'pwelm', 'pwelb', 'pwels', 'pwelt', 'pwelp', 'pwelh',
+'pwem', 'pweb', 'pwebs', 'pwes', 'pwess', 'pweng', 'pwej', 'pwec', 'pwek', 'pwet', 'pwep', 'pweh', 'pwi', 'pwig', 'pwigg', 'pwigs',
+'pwin', 'pwinj', 'pwinh', 'pwid', 'pwil', 'pwilg', 'pwilm', 'pwilb', 'pwils', 'pwilt', 'pwilp', 'pwilh', 'pwim', 'pwib', 'pwibs', 'pwis',
+'pwiss', 'pwing', 'pwij', 'pwic', 'pwik', 'pwit', 'pwip', 'pwih', 'pyu', 'pyug', 'pyugg', 'pyugs', 'pyun', 'pyunj', 'pyunh', 'pyud',
+'pyul', 'pyulg', 'pyulm', 'pyulb', 'pyuls', 'pyult', 'pyulp', 'pyulh', 'pyum', 'pyub', 'pyubs', 'pyus', 'pyuss', 'pyung', 'pyuj', 'pyuc',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/xd5.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/xd5.php
new file mode 100644 (file)
index 0000000..fa21446
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0xd5] = array(
+'pyuk', 'pyut', 'pyup', 'pyuh', 'peu', 'peug', 'peugg', 'peugs', 'peun', 'peunj', 'peunh', 'peud', 'peul', 'peulg', 'peulm', 'peulb',
+'peuls', 'peult', 'peulp', 'peulh', 'peum', 'peub', 'peubs', 'peus', 'peuss', 'peung', 'peuj', 'peuc', 'peuk', 'peut', 'peup', 'peuh',
+'pyi', 'pyig', 'pyigg', 'pyigs', 'pyin', 'pyinj', 'pyinh', 'pyid', 'pyil', 'pyilg', 'pyilm', 'pyilb', 'pyils', 'pyilt', 'pyilp', 'pyilh',
+'pyim', 'pyib', 'pyibs', 'pyis', 'pyiss', 'pying', 'pyij', 'pyic', 'pyik', 'pyit', 'pyip', 'pyih', 'pi', 'pig', 'pigg', 'pigs',
+'pin', 'pinj', 'pinh', 'pid', 'pil', 'pilg', 'pilm', 'pilb', 'pils', 'pilt', 'pilp', 'pilh', 'pim', 'pib', 'pibs', 'pis',
+'piss', 'ping', 'pij', 'pic', 'pik', 'pit', 'pip', 'pih', 'ha', 'hag', 'hagg', 'hags', 'han', 'hanj', 'hanh', 'had',
+'hal', 'halg', 'halm', 'halb', 'hals', 'halt', 'halp', 'halh', 'ham', 'hab', 'habs', 'has', 'hass', 'hang', 'haj', 'hac',
+'hak', 'hat', 'hap', 'hah', 'hae', 'haeg', 'haegg', 'haegs', 'haen', 'haenj', 'haenh', 'haed', 'hael', 'haelg', 'haelm', 'haelb',
+'haels', 'haelt', 'haelp', 'haelh', 'haem', 'haeb', 'haebs', 'haes', 'haess', 'haeng', 'haej', 'haec', 'haek', 'haet', 'haep', 'haeh',
+'hya', 'hyag', 'hyagg', 'hyags', 'hyan', 'hyanj', 'hyanh', 'hyad', 'hyal', 'hyalg', 'hyalm', 'hyalb', 'hyals', 'hyalt', 'hyalp', 'hyalh',
+'hyam', 'hyab', 'hyabs', 'hyas', 'hyass', 'hyang', 'hyaj', 'hyac', 'hyak', 'hyat', 'hyap', 'hyah', 'hyae', 'hyaeg', 'hyaegg', 'hyaegs',
+'hyaen', 'hyaenj', 'hyaenh', 'hyaed', 'hyael', 'hyaelg', 'hyaelm', 'hyaelb', 'hyaels', 'hyaelt', 'hyaelp', 'hyaelh', 'hyaem', 'hyaeb', 'hyaebs', 'hyaes',
+'hyaess', 'hyaeng', 'hyaej', 'hyaec', 'hyaek', 'hyaet', 'hyaep', 'hyaeh', 'heo', 'heog', 'heogg', 'heogs', 'heon', 'heonj', 'heonh', 'heod',
+'heol', 'heolg', 'heolm', 'heolb', 'heols', 'heolt', 'heolp', 'heolh', 'heom', 'heob', 'heobs', 'heos', 'heoss', 'heong', 'heoj', 'heoc',
+'heok', 'heot', 'heop', 'heoh', 'he', 'heg', 'hegg', 'hegs', 'hen', 'henj', 'henh', 'hed', 'hel', 'helg', 'helm', 'helb',
+'hels', 'helt', 'help', 'helh', 'hem', 'heb', 'hebs', 'hes', 'hess', 'heng', 'hej', 'hec', 'hek', 'het', 'hep', 'heh',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/xd6.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/xd6.php
new file mode 100644 (file)
index 0000000..53dfec2
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0xd6] = array(
+'hyeo', 'hyeog', 'hyeogg', 'hyeogs', 'hyeon', 'hyeonj', 'hyeonh', 'hyeod', 'hyeol', 'hyeolg', 'hyeolm', 'hyeolb', 'hyeols', 'hyeolt', 'hyeolp', 'hyeolh',
+'hyeom', 'hyeob', 'hyeobs', 'hyeos', 'hyeoss', 'hyeong', 'hyeoj', 'hyeoc', 'hyeok', 'hyeot', 'hyeop', 'hyeoh', 'hye', 'hyeg', 'hyegg', 'hyegs',
+'hyen', 'hyenj', 'hyenh', 'hyed', 'hyel', 'hyelg', 'hyelm', 'hyelb', 'hyels', 'hyelt', 'hyelp', 'hyelh', 'hyem', 'hyeb', 'hyebs', 'hyes',
+'hyess', 'hyeng', 'hyej', 'hyec', 'hyek', 'hyet', 'hyep', 'hyeh', 'ho', 'hog', 'hogg', 'hogs', 'hon', 'honj', 'honh', 'hod',
+'hol', 'holg', 'holm', 'holb', 'hols', 'holt', 'holp', 'holh', 'hom', 'hob', 'hobs', 'hos', 'hoss', 'hong', 'hoj', 'hoc',
+'hok', 'hot', 'hop', 'hoh', 'hwa', 'hwag', 'hwagg', 'hwags', 'hwan', 'hwanj', 'hwanh', 'hwad', 'hwal', 'hwalg', 'hwalm', 'hwalb',
+'hwals', 'hwalt', 'hwalp', 'hwalh', 'hwam', 'hwab', 'hwabs', 'hwas', 'hwass', 'hwang', 'hwaj', 'hwac', 'hwak', 'hwat', 'hwap', 'hwah',
+'hwae', 'hwaeg', 'hwaegg', 'hwaegs', 'hwaen', 'hwaenj', 'hwaenh', 'hwaed', 'hwael', 'hwaelg', 'hwaelm', 'hwaelb', 'hwaels', 'hwaelt', 'hwaelp', 'hwaelh',
+'hwaem', 'hwaeb', 'hwaebs', 'hwaes', 'hwaess', 'hwaeng', 'hwaej', 'hwaec', 'hwaek', 'hwaet', 'hwaep', 'hwaeh', 'hoe', 'hoeg', 'hoegg', 'hoegs',
+'hoen', 'hoenj', 'hoenh', 'hoed', 'hoel', 'hoelg', 'hoelm', 'hoelb', 'hoels', 'hoelt', 'hoelp', 'hoelh', 'hoem', 'hoeb', 'hoebs', 'hoes',
+'hoess', 'hoeng', 'hoej', 'hoec', 'hoek', 'hoet', 'hoep', 'hoeh', 'hyo', 'hyog', 'hyogg', 'hyogs', 'hyon', 'hyonj', 'hyonh', 'hyod',
+'hyol', 'hyolg', 'hyolm', 'hyolb', 'hyols', 'hyolt', 'hyolp', 'hyolh', 'hyom', 'hyob', 'hyobs', 'hyos', 'hyoss', 'hyong', 'hyoj', 'hyoc',
+'hyok', 'hyot', 'hyop', 'hyoh', 'hu', 'hug', 'hugg', 'hugs', 'hun', 'hunj', 'hunh', 'hud', 'hul', 'hulg', 'hulm', 'hulb',
+'huls', 'hult', 'hulp', 'hulh', 'hum', 'hub', 'hubs', 'hus', 'huss', 'hung', 'huj', 'huc', 'huk', 'hut', 'hup', 'huh',
+'hweo', 'hweog', 'hweogg', 'hweogs', 'hweon', 'hweonj', 'hweonh', 'hweod', 'hweol', 'hweolg', 'hweolm', 'hweolb', 'hweols', 'hweolt', 'hweolp', 'hweolh',
+'hweom', 'hweob', 'hweobs', 'hweos', 'hweoss', 'hweong', 'hweoj', 'hweoc', 'hweok', 'hweot', 'hweop', 'hweoh', 'hwe', 'hweg', 'hwegg', 'hwegs',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/xd7.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/xd7.php
new file mode 100644 (file)
index 0000000..32735ec
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0xd7] = array(
+'hwen', 'hwenj', 'hwenh', 'hwed', 'hwel', 'hwelg', 'hwelm', 'hwelb', 'hwels', 'hwelt', 'hwelp', 'hwelh', 'hwem', 'hweb', 'hwebs', 'hwes',
+'hwess', 'hweng', 'hwej', 'hwec', 'hwek', 'hwet', 'hwep', 'hweh', 'hwi', 'hwig', 'hwigg', 'hwigs', 'hwin', 'hwinj', 'hwinh', 'hwid',
+'hwil', 'hwilg', 'hwilm', 'hwilb', 'hwils', 'hwilt', 'hwilp', 'hwilh', 'hwim', 'hwib', 'hwibs', 'hwis', 'hwiss', 'hwing', 'hwij', 'hwic',
+'hwik', 'hwit', 'hwip', 'hwih', 'hyu', 'hyug', 'hyugg', 'hyugs', 'hyun', 'hyunj', 'hyunh', 'hyud', 'hyul', 'hyulg', 'hyulm', 'hyulb',
+'hyuls', 'hyult', 'hyulp', 'hyulh', 'hyum', 'hyub', 'hyubs', 'hyus', 'hyuss', 'hyung', 'hyuj', 'hyuc', 'hyuk', 'hyut', 'hyup', 'hyuh',
+'heu', 'heug', 'heugg', 'heugs', 'heun', 'heunj', 'heunh', 'heud', 'heul', 'heulg', 'heulm', 'heulb', 'heuls', 'heult', 'heulp', 'heulh',
+'heum', 'heub', 'heubs', 'heus', 'heuss', 'heung', 'heuj', 'heuc', 'heuk', 'heut', 'heup', 'heuh', 'hyi', 'hyig', 'hyigg', 'hyigs',
+'hyin', 'hyinj', 'hyinh', 'hyid', 'hyil', 'hyilg', 'hyilm', 'hyilb', 'hyils', 'hyilt', 'hyilp', 'hyilh', 'hyim', 'hyib', 'hyibs', 'hyis',
+'hyiss', 'hying', 'hyij', 'hyic', 'hyik', 'hyit', 'hyip', 'hyih', 'hi', 'hig', 'higg', 'higs', 'hin', 'hinj', 'hinh', 'hid',
+'hil', 'hilg', 'hilm', 'hilb', 'hils', 'hilt', 'hilp', 'hilh', 'him', 'hib', 'hibs', 'his', 'hiss', 'hing', 'hij', 'hic',
+'hik', 'hit', 'hip', 'hih', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/xf9.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/xf9.php
new file mode 100644 (file)
index 0000000..c3196ba
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0xf9] = array(
+'Kay ', 'Kayng ', 'Ke ', 'Ko ', 'Kol ', 'Koc ', 'Kwi ', 'Kwi ', 'Kyun ', 'Kul ', 'Kum ', 'Na ', 'Na ', 'Na ', 'La ', 'Na ',
+'Na ', 'Na ', 'Na ', 'Na ', 'Nak ', 'Nak ', 'Nak ', 'Nak ', 'Nak ', 'Nak ', 'Nak ', 'Nan ', 'Nan ', 'Nan ', 'Nan ', 'Nan ',
+'Nan ', 'Nam ', 'Nam ', 'Nam ', 'Nam ', 'Nap ', 'Nap ', 'Nap ', 'Nang ', 'Nang ', 'Nang ', 'Nang ', 'Nang ', 'Nay ', 'Nayng ', 'No ',
+'No ', 'No ', 'No ', 'No ', 'No ', 'No ', 'No ', 'No ', 'No ', 'No ', 'No ', 'Nok ', 'Nok ', 'Nok ', 'Nok ', 'Nok ',
+'Nok ', 'Non ', 'Nong ', 'Nong ', 'Nong ', 'Nong ', 'Noy ', 'Noy ', 'Noy ', 'Noy ', 'Nwu ', 'Nwu ', 'Nwu ', 'Nwu ', 'Nwu ', 'Nwu ',
+'Nwu ', 'Nwu ', 'Nuk ', 'Nuk ', 'Num ', 'Nung ', 'Nung ', 'Nung ', 'Nung ', 'Nung ', 'Twu ', 'La ', 'Lak ', 'Lak ', 'Lan ', 'Lyeng ',
+'Lo ', 'Lyul ', 'Li ', 'Pey ', 'Pen ', 'Pyen ', 'Pwu ', 'Pwul ', 'Pi ', 'Sak ', 'Sak ', 'Sam ', 'Sayk ', 'Sayng ', 'Sep ', 'Sey ',
+'Sway ', 'Sin ', 'Sim ', 'Sip ', 'Ya ', 'Yak ', 'Yak ', 'Yang ', 'Yang ', 'Yang ', 'Yang ', 'Yang ', 'Yang ', 'Yang ', 'Yang ', 'Ye ',
+'Ye ', 'Ye ', 'Ye ', 'Ye ', 'Ye ', 'Ye ', 'Ye ', 'Ye ', 'Ye ', 'Ye ', 'Yek ', 'Yek ', 'Yek ', 'Yek ', 'Yen ', 'Yen ',
+'Yen ', 'Yen ', 'Yen ', 'Yen ', 'Yen ', 'Yen ', 'Yen ', 'Yen ', 'Yen ', 'Yen ', 'Yen ', 'Yen ', 'Yel ', 'Yel ', 'Yel ', 'Yel ',
+'Yel ', 'Yel ', 'Yem ', 'Yem ', 'Yem ', 'Yem ', 'Yem ', 'Yep ', 'Yeng ', 'Yeng ', 'Yeng ', 'Yeng ', 'Yeng ', 'Yeng ', 'Yeng ', 'Yeng ',
+'Yeng ', 'Yeng ', 'Yeng ', 'Yeng ', 'Yeng ', 'Yey ', 'Yey ', 'Yey ', 'Yey ', 'O ', 'Yo ', 'Yo ', 'Yo ', 'Yo ', 'Yo ', 'Yo ',
+'Yo ', 'Yo ', 'Yo ', 'Yo ', 'Yong ', 'Wun ', 'Wen ', 'Yu ', 'Yu ', 'Yu ', 'Yu ', 'Yu ', 'Yu ', 'Yu ', 'Yu ', 'Yu ',
+'Yu ', 'Yuk ', 'Yuk ', 'Yuk ', 'Yun ', 'Yun ', 'Yun ', 'Yun ', 'Yul ', 'Yul ', 'Yul ', 'Yul ', 'Yung ', 'I ', 'I ', 'I ',
+'I ', 'I ', 'I ', 'I ', 'I ', 'I ', 'I ', 'I ', 'I ', 'I ', 'I ', 'Ik ', 'Ik ', 'In ', 'In ', 'In ',
+'In ', 'In ', 'In ', 'In ', 'Im ', 'Im ', 'Im ', 'Ip ', 'Ip ', 'Ip ', 'Cang ', 'Cek ', 'Ci ', 'Cip ', 'Cha ', 'Chek ',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/xfa.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/xfa.php
new file mode 100644 (file)
index 0000000..b500f6c
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0xfa] = array(
+'Chey ', 'Thak ', 'Thak ', 'Thang ', 'Thayk ', 'Thong ', 'Pho ', 'Phok ', 'Hang ', 'Hang ', 'Hyen ', 'Hwak ', 'Wu ', 'Huo ', '[?]', '[?]',
+'Zhong ', '[?]', 'Qing ', '[?]', '[?]', 'Xi ', 'Zhu ', 'Yi ', 'Li ', 'Shen ', 'Xiang ', 'Fu ', 'Jing ', 'Jing ', 'Yu ', '[?]',
+'Hagi ', '[?]', 'Zhu ', '[?]', '[?]', 'Yi ', 'Du ', '[?]', '[?]', '[?]', 'Fan ', 'Si ', 'Guan ', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/xfb.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/xfb.php
new file mode 100644 (file)
index 0000000..a8aec9a
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0xfb] = array(
+'ff', 'fi', 'fl', 'ffi', 'ffl', 'st', 'st', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', 'mn', 'me', 'mi', 'vn', 'mkh', '[?]', '[?]', '[?]', '[?]', '[?]', 'yi', '', 'ay',
+'`', '', 'd', 'h', 'k', 'l', 'm', 'm', 't', '+', 'sh', 's', 'sh', 's', 'a', 'a',
+'', 'b', 'g', 'd', 'h', 'v', 'z', '[?]', 't', 'y', 'k', 'k', 'l', '[?]', 'l', '[?]',
+'n', 'n', '[?]', 'p', 'p', '[?]', 'ts', 'ts', 'r', 'sh', 't', 'vo', 'b', 'k', 'p', 'l',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/xfc.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/xfc.php
new file mode 100644 (file)
index 0000000..cef2b30
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0xfc] = array(
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/xfd.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/xfd.php
new file mode 100644 (file)
index 0000000..ee0fca9
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0xfd] = array(
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'[?]', '[?]', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'', '', '', '', '', '', '', '', '', '', '', '', '[?]', '[?]', '[?]',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/xfe.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/xfe.php
new file mode 100644 (file)
index 0000000..6d60c84
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0xfe] = array(
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'', '', '', '~', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]',
+'..', '--', '-', '_', '_', '(', ') ', '{', '} ', '[', '] ', '[(', ')] ', '<<', '>> ', '<',
+'> ', '[', '] ', '{', '}', '[?]', '[?]', '[?]', '[?]', '', '', '', '', '', '', '',
+',', ',', '.', '', ';', ':', '?', '!', '-', '(', ')', '{', '}', '{', '}', '#',
+'&', '*', '+', '-', '<', '>', '=', '', '\\', '$', '%', '@', '[?]', '[?]', '[?]', '[?]',
+'', '', '', '[?]', '', '[?]', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+'', '', '', '', '', '', '', '', '', '', '', '', '', '[?]', '[?]', '',
+);
diff --git a/vendor/behat/transliterator/src/Behat/Transliterator/data/xff.php b/vendor/behat/transliterator/src/Behat/Transliterator/data/xff.php
new file mode 100644 (file)
index 0000000..b415a06
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+$UTF8_TO_ASCII[0xff] = array(
+'[?]', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/',
+'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?',
+'@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
+'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^', '_',
+'`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
+'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', '[?]',
+'[?]', '.', '[', ']', ',', '*', 'wo', 'a', 'i', 'u', 'e', 'o', 'ya', 'yu', 'yo', 'tu',
+'+', 'a', 'i', 'u', 'e', 'o', 'ka', 'ki', 'ku', 'ke', 'ko', 'sa', 'si', 'su', 'se', 'so',
+'ta', 'ti', 'tu', 'te', 'to', 'na', 'ni', 'nu', 'ne', 'no', 'ha', 'hi', 'hu', 'he', 'ho', 'ma',
+'mi', 'mu', 'me', 'mo', 'ya', 'yu', 'yo', 'ra', 'ri', 'ru', 're', 'ro', 'wa', 'n', ':', ';',
+'', 'g', 'gg', 'gs', 'n', 'nj', 'nh', 'd', 'dd', 'r', 'lg', 'lm', 'lb', 'ls', 'lt', 'lp',
+'rh', 'm', 'b', 'bb', 'bs', 's', 'ss', '', 'j', 'jj', 'c', 'k', 't', 'p', 'h', '[?]',
+'[?]', '[?]', 'a', 'ae', 'ya', 'yae', 'eo', 'e', '[?]', '[?]', 'yeo', 'ye', 'o', 'wa', 'wae', 'oe',
+'[?]', '[?]', 'yo', 'u', 'weo', 'we', 'wi', 'yu', '[?]', '[?]', 'eu', 'yi', 'i', '[?]', '[?]', '[?]',
+'/C', 'PS', '!', '-', '|', 'Y=', 'W=', '[?]', '|', '-', '|', '-', '|', '#', 'O', '[?]',
+'[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '{', '|', '}', '', '', '', '',
+);
diff --git a/vendor/bin/behat b/vendor/bin/behat
new file mode 120000 (symlink)
index 0000000..090aac1
--- /dev/null
@@ -0,0 +1 @@
+../behat/behat/bin/behat
\ No newline at end of file
index 5dd3efe8c797af479328cb4525654ad8bb81908c..9838ed7419a2a62659418e9028565dfb9799977c 100644 (file)
@@ -8,6 +8,7 @@ $baseDir = dirname($vendorDir);
 return array(
     'phpDocumentor' => array($vendorDir . '/phpdocumentor/reflection-docblock/src'),
     'org\\bovigo\\vfs\\' => array($vendorDir . '/mikey179/vfsStream/src/main/php'),
+    'WebDriver' => array($vendorDir . '/instaclick/php-webdriver/lib'),
     'Twig_' => array($vendorDir . '/twig/twig/lib'),
     'Sunra\\PhpSimple\\HtmlDomParser' => array($vendorDir . '/sunra/php-simple-html-dom-parser/Src'),
     'Stack' => array($vendorDir . '/stack/builder/src'),
@@ -19,6 +20,12 @@ return array(
     'Egulias\\' => array($vendorDir . '/egulias/email-validator/src'),
     'EasyRdf_' => array($vendorDir . '/easyrdf/easyrdf/lib'),
     'Drush' => array($vendorDir . '/drush/config-extra/lib', $vendorDir . '/drush/drush/lib'),
+    'Drupal\\Tests\\Driver' => array($vendorDir . '/drupal/drupal-driver/tests'),
+    'Drupal\\Exception' => array($vendorDir . '/drupal/drupal-extension/src'),
+    'Drupal\\DrupalExtension' => array($vendorDir . '/drupal/drupal-extension/src'),
+    'Drupal\\Drupal' => array($vendorDir . '/drupal/drupal-extension/src'),
+    'Drupal\\Driver' => array($vendorDir . '/drupal/drupal-driver/src'),
+    'Drupal\\Component' => array($vendorDir . '/drupal/drupal-driver/src'),
     'Doctrine\\Common\\Lexer\\' => array($vendorDir . '/doctrine/lexer/lib'),
     'Doctrine\\Common\\Inflector\\' => array($vendorDir . '/doctrine/inflector/lib'),
     'Doctrine\\Common\\Collections\\' => array($vendorDir . '/doctrine/collections/lib'),
@@ -28,4 +35,9 @@ return array(
     'Dflydev\\DotAccessConfiguration' => array($vendorDir . '/dflydev/dot-access-configuration/src'),
     'Consolidation' => array($vendorDir . '/drush/drush/lib'),
     'Caxy\\HtmlDiff' => array($vendorDir . '/caxy/php-htmldiff/lib'),
+    'Behat\\Transliterator' => array($vendorDir . '/behat/transliterator/src'),
+    'Behat\\Testwork' => array($vendorDir . '/behat/behat/src'),
+    'Behat\\MinkExtension' => array($vendorDir . '/behat/mink-extension/src'),
+    'Behat\\Gherkin' => array($vendorDir . '/behat/gherkin/src'),
+    'Behat\\Behat' => array($vendorDir . '/behat/behat/src'),
 );
index 25c9d24e7ea383832300674e8f8cc95926431e26..484ba4a00b52138c6a0fd69142d4e86a321604ee 100644 (file)
@@ -50,9 +50,12 @@ return array(
     'Psy\\' => array($vendorDir . '/psy/psysh/src/Psy'),
     'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'),
     'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-message/src'),
+    'Psr\\Container\\' => array($vendorDir . '/psr/container/src'),
     'PhpParser\\' => array($vendorDir . '/nikic/php-parser/lib/PhpParser'),
     'Pharborist\\' => array($vendorDir . '/grom358/pharborist/src'),
+    'PermissionsByTerm\\' => array($baseDir . '/web/modules/contrib/permissions_by_term/tests/src/Behat/Context'),
     'Masterminds\\' => array($vendorDir . '/masterminds/html5/src'),
+    'Interop\\Container\\' => array($vendorDir . '/container-interop/container-interop/src/Interop/Container'),
     'GuzzleHttp\\Psr7\\' => array($vendorDir . '/guzzlehttp/psr7/src'),
     'GuzzleHttp\\Promise\\' => array($vendorDir . '/guzzlehttp/promises/src'),
     'GuzzleHttp\\' => array($vendorDir . '/guzzlehttp/guzzle/src'),
@@ -72,7 +75,7 @@ return array(
     'Consolidation\\AnnotatedCommand\\' => array($vendorDir . '/consolidation/annotated-command/src'),
     'Composer\\Semver\\' => array($vendorDir . '/composer/semver/src'),
     'Composer\\Installers\\' => array($vendorDir . '/composer/installers/src/Composer/Installers'),
-    'Behat\\Mink\\Driver\\' => array($vendorDir . '/behat/mink-browserkit-driver/src', $vendorDir . '/behat/mink-goutte-driver/src'),
+    'Behat\\Mink\\Driver\\' => array($vendorDir . '/behat/mink-browserkit-driver/src', $vendorDir . '/behat/mink-goutte-driver/src', $vendorDir . '/behat/mink-selenium2-driver/src'),
     'Behat\\Mink\\' => array($vendorDir . '/behat/mink/src'),
     'Asm89\\Stack\\' => array($vendorDir . '/asm89/stack-cors/src/Asm89/Stack'),
     'Alchemy\\Zippy\\' => array($vendorDir . '/alchemy/zippy/src'),
index 0be8f5f6fca99da70708c8a00e58ad41de5d6bac..335450508f4a18a1487451b6ac4d0e1baa4f0cf6 100644 (file)
@@ -93,13 +93,19 @@ class ComposerStaticInit045d6a3105edf51cf91c16e965235549
             'Psy\\' => 4,
             'Psr\\Log\\' => 8,
             'Psr\\Http\\Message\\' => 17,
+            'Psr\\Container\\' => 14,
             'PhpParser\\' => 10,
             'Pharborist\\' => 11,
+            'PermissionsByTerm\\' => 18,
         ),
         'M' => 
         array (
             'Masterminds\\' => 12,
         ),
+        'I' => 
+        array (
+            'Interop\\Container\\' => 18,
+        ),
         'G' => 
         array (
             'GuzzleHttp\\Psr7\\' => 16,
@@ -318,6 +324,10 @@ class ComposerStaticInit045d6a3105edf51cf91c16e965235549
         array (
             0 => __DIR__ . '/..' . '/psr/http-message/src',
         ),
+        'Psr\\Container\\' => 
+        array (
+            0 => __DIR__ . '/..' . '/psr/container/src',
+        ),
         'PhpParser\\' => 
         array (
             0 => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser',
@@ -326,10 +336,18 @@ class ComposerStaticInit045d6a3105edf51cf91c16e965235549
         array (
             0 => __DIR__ . '/..' . '/grom358/pharborist/src',
         ),
+        'PermissionsByTerm\\' => 
+        array (
+            0 => __DIR__ . '/../..' . '/web/modules/contrib/permissions_by_term/tests/src/Behat/Context',
+        ),
         'Masterminds\\' => 
         array (
             0 => __DIR__ . '/..' . '/masterminds/html5/src',
         ),
+        'Interop\\Container\\' => 
+        array (
+            0 => __DIR__ . '/..' . '/container-interop/container-interop/src/Interop/Container',
+        ),
         'GuzzleHttp\\Psr7\\' => 
         array (
             0 => __DIR__ . '/..' . '/guzzlehttp/psr7/src',
@@ -410,6 +428,7 @@ class ComposerStaticInit045d6a3105edf51cf91c16e965235549
         array (
             0 => __DIR__ . '/..' . '/behat/mink-browserkit-driver/src',
             1 => __DIR__ . '/..' . '/behat/mink-goutte-driver/src',
+            2 => __DIR__ . '/..' . '/behat/mink-selenium2-driver/src',
         ),
         'Behat\\Mink\\' => 
         array (
@@ -444,6 +463,13 @@ class ComposerStaticInit045d6a3105edf51cf91c16e965235549
                 0 => __DIR__ . '/..' . '/mikey179/vfsStream/src/main/php',
             ),
         ),
+        'W' => 
+        array (
+            'WebDriver' => 
+            array (
+                0 => __DIR__ . '/..' . '/instaclick/php-webdriver/lib',
+            ),
+        ),
         'T' => 
         array (
             'Twig_' => 
@@ -512,6 +538,30 @@ class ComposerStaticInit045d6a3105edf51cf91c16e965235549
                 0 => __DIR__ . '/..' . '/drush/config-extra/lib',
                 1 => __DIR__ . '/..' . '/drush/drush/lib',
             ),
+            'Drupal\\Tests\\Driver' => 
+            array (
+                0 => __DIR__ . '/..' . '/drupal/drupal-driver/tests',
+            ),
+            'Drupal\\Exception' => 
+            array (
+                0 => __DIR__ . '/..' . '/drupal/drupal-extension/src',
+            ),
+            'Drupal\\DrupalExtension' => 
+            array (
+                0 => __DIR__ . '/..' . '/drupal/drupal-extension/src',
+            ),
+            'Drupal\\Drupal' => 
+            array (
+                0 => __DIR__ . '/..' . '/drupal/drupal-extension/src',
+            ),
+            'Drupal\\Driver' => 
+            array (
+                0 => __DIR__ . '/..' . '/drupal/drupal-driver/src',
+            ),
+            'Drupal\\Component' => 
+            array (
+                0 => __DIR__ . '/..' . '/drupal/drupal-driver/src',
+            ),
             'Doctrine\\Common\\Lexer\\' => 
             array (
                 0 => __DIR__ . '/..' . '/doctrine/lexer/lib',
@@ -552,6 +602,29 @@ class ComposerStaticInit045d6a3105edf51cf91c16e965235549
                 0 => __DIR__ . '/..' . '/caxy/php-htmldiff/lib',
             ),
         ),
+        'B' => 
+        array (
+            'Behat\\Transliterator' => 
+            array (
+                0 => __DIR__ . '/..' . '/behat/transliterator/src',
+            ),
+            'Behat\\Testwork' => 
+            array (
+                0 => __DIR__ . '/..' . '/behat/behat/src',
+            ),
+            'Behat\\MinkExtension' => 
+            array (
+                0 => __DIR__ . '/..' . '/behat/mink-extension/src',
+            ),
+            'Behat\\Gherkin' => 
+            array (
+                0 => __DIR__ . '/..' . '/behat/gherkin/src',
+            ),
+            'Behat\\Behat' => 
+            array (
+                0 => __DIR__ . '/..' . '/behat/behat/src',
+            ),
+        ),
     );
 
     public static $classMap = array (
index 6e357d5ee83eb789582ecb43266dd795d2a31992..1d8aa4480207f9703380808d28842b2e25679e54 100644 (file)
             "source": "http://cgit.drupalcode.org/hacked"
         }
     },
-    {
-        "name": "drupal/permissions_by_term",
-        "version": "1.19.0",
-        "version_normalized": "1.19.0.0",
-        "source": {
-            "type": "git",
-            "url": "https://git.drupal.org/project/permissions_by_term",
-            "reference": "8.x-1.19"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://ftp.drupal.org/files/projects/permissions_by_term-8.x-1.19.zip",
-            "reference": "8.x-1.19",
-            "shasum": "87ecf60dda39138f648ee57fe4e3ce334b187100"
-        },
-        "require": {
-            "drupal/core": "*"
-        },
-        "type": "drupal-module",
-        "extra": {
-            "branch-alias": {
-                "dev-1.x": "1.x-dev"
-            },
-            "drupal": {
-                "version": "8.x-1.19",
-                "datestamp": "1494360188"
-            }
-        },
-        "installation-source": "dist",
-        "notification-url": "https://packages.drupal.org/8/downloads",
-        "license": [
-            "GPL-2.0+"
-        ],
-        "authors": [
-            {
-                "name": "Peter Majmesku",
-                "homepage": "https://www.drupal.org/user/786132"
-            }
-        ],
-        "description": "Limits the selection of specific taxonomy terms by users or roles. Prevents users to display nodes and nodes on views pages, for which which they do not have access by taxonomy term restriction.",
-        "homepage": "https://www.drupal.org/project/permissions_by_term",
-        "support": {
-            "source": "http://cgit.drupalcode.org/permissions_by_term"
-        }
-    },
     {
         "name": "drupal/linkit",
         "version": "4.3.0",
             "GPL-2.0+"
         ],
         "description": "Drupal is an open source content management platform powering millions of websites and applications."
+    },
+    {
+        "name": "instaclick/php-webdriver",
+        "version": "1.4.5",
+        "version_normalized": "1.4.5.0",
+        "source": {
+            "type": "git",
+            "url": "https://github.com/instaclick/php-webdriver.git",
+            "reference": "6fa959452e774dcaed543faad3a9d1a37d803327"
+        },
+        "dist": {
+            "type": "zip",
+            "url": "https://api.github.com/repos/instaclick/php-webdriver/zipball/6fa959452e774dcaed543faad3a9d1a37d803327",
+            "reference": "6fa959452e774dcaed543faad3a9d1a37d803327",
+            "shasum": ""
+        },
+        "require": {
+            "ext-curl": "*",
+            "php": ">=5.3.2"
+        },
+        "require-dev": {
+            "phpunit/phpunit": "^4.8",
+            "satooshi/php-coveralls": "^1.0||^2.0"
+        },
+        "time": "2017-06-30T04:02:48+00:00",
+        "type": "library",
+        "extra": {
+            "branch-alias": {
+                "dev-master": "1.4.x-dev"
+            }
+        },
+        "installation-source": "dist",
+        "autoload": {
+            "psr-0": {
+                "WebDriver": "lib/"
+            }
+        },
+        "notification-url": "https://packagist.org/downloads/",
+        "license": [
+            "Apache-2.0"
+        ],
+        "authors": [
+            {
+                "name": "Justin Bishop",
+                "email": "jubishop@gmail.com",
+                "role": "Developer"
+            },
+            {
+                "name": "Anthon Pang",
+                "email": "apang@softwaredevelopment.ca",
+                "role": "Fork Maintainer"
+            }
+        ],
+        "description": "PHP WebDriver for Selenium 2",
+        "homepage": "http://instaclick.com/",
+        "keywords": [
+            "browser",
+            "selenium",
+            "webdriver",
+            "webtest"
+        ]
+    },
+    {
+        "name": "behat/mink-selenium2-driver",
+        "version": "v1.3.1",
+        "version_normalized": "1.3.1.0",
+        "source": {
+            "type": "git",
+            "url": "https://github.com/minkphp/MinkSelenium2Driver.git",
+            "reference": "473a9f3ebe0c134ee1e623ce8a9c852832020288"
+        },
+        "dist": {
+            "type": "zip",
+            "url": "https://api.github.com/repos/minkphp/MinkSelenium2Driver/zipball/473a9f3ebe0c134ee1e623ce8a9c852832020288",
+            "reference": "473a9f3ebe0c134ee1e623ce8a9c852832020288",
+            "shasum": ""
+        },
+        "require": {
+            "behat/mink": "~1.7@dev",
+            "instaclick/php-webdriver": "~1.1",
+            "php": ">=5.3.1"
+        },
+        "require-dev": {
+            "symfony/phpunit-bridge": "~2.7"
+        },
+        "time": "2016-03-05T09:10:18+00:00",
+        "type": "mink-driver",
+        "extra": {
+            "branch-alias": {
+                "dev-master": "1.3.x-dev"
+            }
+        },
+        "installation-source": "dist",
+        "autoload": {
+            "psr-4": {
+                "Behat\\Mink\\Driver\\": "src/"
+            }
+        },
+        "notification-url": "https://packagist.org/downloads/",
+        "license": [
+            "MIT"
+        ],
+        "authors": [
+            {
+                "name": "Konstantin Kudryashov",
+                "email": "ever.zet@gmail.com",
+                "homepage": "http://everzet.com"
+            },
+            {
+                "name": "Pete Otaqui",
+                "email": "pete@otaqui.com",
+                "homepage": "https://github.com/pete-otaqui"
+            }
+        ],
+        "description": "Selenium2 (WebDriver) driver for Mink framework",
+        "homepage": "http://mink.behat.org/",
+        "keywords": [
+            "ajax",
+            "browser",
+            "javascript",
+            "selenium",
+            "testing",
+            "webdriver"
+        ]
+    },
+    {
+        "name": "psr/container",
+        "version": "1.0.0",
+        "version_normalized": "1.0.0.0",
+        "source": {
+            "type": "git",
+            "url": "https://github.com/php-fig/container.git",
+            "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f"
+        },
+        "dist": {
+            "type": "zip",
+            "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
+            "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
+            "shasum": ""
+        },
+        "require": {
+            "php": ">=5.3.0"
+        },
+        "time": "2017-02-14T16:28:37+00:00",
+        "type": "library",
+        "extra": {
+            "branch-alias": {
+                "dev-master": "1.0.x-dev"
+            }
+        },
+        "installation-source": "dist",
+        "autoload": {
+            "psr-4": {
+                "Psr\\Container\\": "src/"
+            }
+        },
+        "notification-url": "https://packagist.org/downloads/",
+        "license": [
+            "MIT"
+        ],
+        "authors": [
+            {
+                "name": "PHP-FIG",
+                "homepage": "http://www.php-fig.org/"
+            }
+        ],
+        "description": "Common Container Interface (PHP FIG PSR-11)",
+        "homepage": "https://github.com/php-fig/container",
+        "keywords": [
+            "PSR-11",
+            "container",
+            "container-interface",
+            "container-interop",
+            "psr"
+        ]
+    },
+    {
+        "name": "container-interop/container-interop",
+        "version": "1.2.0",
+        "version_normalized": "1.2.0.0",
+        "source": {
+            "type": "git",
+            "url": "https://github.com/container-interop/container-interop.git",
+            "reference": "79cbf1341c22ec75643d841642dd5d6acd83bdb8"
+        },
+        "dist": {
+            "type": "zip",
+            "url": "https://api.github.com/repos/container-interop/container-interop/zipball/79cbf1341c22ec75643d841642dd5d6acd83bdb8",
+            "reference": "79cbf1341c22ec75643d841642dd5d6acd83bdb8",
+            "shasum": ""
+        },
+        "require": {
+            "psr/container": "^1.0"
+        },
+        "time": "2017-02-14T19:40:03+00:00",
+        "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.)",
+        "homepage": "https://github.com/container-interop/container-interop"
+    },
+    {
+        "name": "behat/transliterator",
+        "version": "v1.2.0",
+        "version_normalized": "1.2.0.0",
+        "source": {
+            "type": "git",
+            "url": "https://github.com/Behat/Transliterator.git",
+            "reference": "826ce7e9c2a6664c0d1f381cbb38b1fb80a7ee2c"
+        },
+        "dist": {
+            "type": "zip",
+            "url": "https://api.github.com/repos/Behat/Transliterator/zipball/826ce7e9c2a6664c0d1f381cbb38b1fb80a7ee2c",
+            "reference": "826ce7e9c2a6664c0d1f381cbb38b1fb80a7ee2c",
+            "shasum": ""
+        },
+        "require": {
+            "php": ">=5.3.3"
+        },
+        "require-dev": {
+            "chuyskywalker/rolling-curl": "^3.1",
+            "php-yaoi/php-yaoi": "^1.0"
+        },
+        "time": "2017-04-04T11:38:05+00:00",
+        "type": "library",
+        "extra": {
+            "branch-alias": {
+                "dev-master": "1.2-dev"
+            }
+        },
+        "installation-source": "dist",
+        "autoload": {
+            "psr-0": {
+                "Behat\\Transliterator": "src/"
+            }
+        },
+        "notification-url": "https://packagist.org/downloads/",
+        "license": [
+            "Artistic-1.0"
+        ],
+        "description": "String transliterator",
+        "keywords": [
+            "i18n",
+            "slug",
+            "transliterator"
+        ]
+    },
+    {
+        "name": "behat/gherkin",
+        "version": "v4.5.1",
+        "version_normalized": "4.5.1.0",
+        "source": {
+            "type": "git",
+            "url": "https://github.com/Behat/Gherkin.git",
+            "reference": "74ac03d52c5e23ad8abd5c5cce4ab0e8dc1b530a"
+        },
+        "dist": {
+            "type": "zip",
+            "url": "https://api.github.com/repos/Behat/Gherkin/zipball/74ac03d52c5e23ad8abd5c5cce4ab0e8dc1b530a",
+            "reference": "74ac03d52c5e23ad8abd5c5cce4ab0e8dc1b530a",
+            "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"
+        },
+        "time": "2017-08-30T11:04:43+00:00",
+        "type": "library",
+        "extra": {
+            "branch-alias": {
+                "dev-master": "4.4-dev"
+            }
+        },
+        "installation-source": "dist",
+        "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"
+        ]
+    },
+    {
+        "name": "behat/behat",
+        "version": "v3.4.1",
+        "version_normalized": "3.4.1.0",
+        "source": {
+            "type": "git",
+            "url": "https://github.com/Behat/Behat.git",
+            "reference": "cb51d4b0b11ea6d3897f3589a871a63a33632692"
+        },
+        "dist": {
+            "type": "zip",
+            "url": "https://api.github.com/repos/Behat/Behat/zipball/cb51d4b0b11ea6d3897f3589a871a63a33632692",
+            "reference": "cb51d4b0b11ea6d3897f3589a871a63a33632692",
+            "shasum": ""
+        },
+        "require": {
+            "behat/gherkin": "^4.5.1",
+            "behat/transliterator": "^1.2",
+            "container-interop/container-interop": "^1.2",
+            "ext-mbstring": "*",
+            "php": ">=5.3.3",
+            "psr/container": "^1.0",
+            "symfony/class-loader": "~2.1||~3.0",
+            "symfony/config": "~2.3||~3.0",
+            "symfony/console": "~2.5||~3.0",
+            "symfony/dependency-injection": "~2.1||~3.0",
+            "symfony/event-dispatcher": "~2.1||~3.0",
+            "symfony/translation": "~2.3||~3.0",
+            "symfony/yaml": "~2.1||~3.0"
+        },
+        "require-dev": {
+            "herrera-io/box": "~1.6.1",
+            "phpunit/phpunit": "~4.5",
+            "symfony/process": "~2.5|~3.0"
+        },
+        "suggest": {
+            "behat/mink-extension": "for integration with Mink testing framework",
+            "behat/symfony2-extension": "for integration with Symfony2 web framework",
+            "behat/yii-extension": "for integration with Yii web framework"
+        },
+        "time": "2017-09-18T11:10:28+00:00",
+        "bin": [
+            "bin/behat"
+        ],
+        "type": "library",
+        "extra": {
+            "branch-alias": {
+                "dev-master": "3.2.x-dev"
+            }
+        },
+        "installation-source": "dist",
+        "autoload": {
+            "psr-0": {
+                "Behat\\Behat": "src/",
+                "Behat\\Testwork": "src/"
+            }
+        },
+        "notification-url": "https://packagist.org/downloads/",
+        "license": [
+            "MIT"
+        ],
+        "authors": [
+            {
+                "name": "Konstantin Kudryashov",
+                "email": "ever.zet@gmail.com",
+                "homepage": "http://everzet.com"
+            }
+        ],
+        "description": "Scenario-oriented BDD framework for PHP 5.3",
+        "homepage": "http://behat.org/",
+        "keywords": [
+            "Agile",
+            "BDD",
+            "ScenarioBDD",
+            "Scrum",
+            "StoryBDD",
+            "User story",
+            "business",
+            "development",
+            "documentation",
+            "examples",
+            "symfony",
+            "testing"
+        ]
+    },
+    {
+        "name": "behat/mink-extension",
+        "version": "v2.2",
+        "version_normalized": "2.2.0.0",
+        "source": {
+            "type": "git",
+            "url": "https://github.com/Behat/MinkExtension.git",
+            "reference": "5b4bda64ff456104564317e212c823e45cad9d59"
+        },
+        "dist": {
+            "type": "zip",
+            "url": "https://api.github.com/repos/Behat/MinkExtension/zipball/5b4bda64ff456104564317e212c823e45cad9d59",
+            "reference": "5b4bda64ff456104564317e212c823e45cad9d59",
+            "shasum": ""
+        },
+        "require": {
+            "behat/behat": "~3.0,>=3.0.5",
+            "behat/mink": "~1.5",
+            "php": ">=5.3.2",
+            "symfony/config": "~2.2|~3.0"
+        },
+        "require-dev": {
+            "behat/mink-goutte-driver": "~1.1",
+            "phpspec/phpspec": "~2.0"
+        },
+        "time": "2016-02-15T07:55:18+00:00",
+        "type": "behat-extension",
+        "extra": {
+            "branch-alias": {
+                "dev-master": "2.1.x-dev"
+            }
+        },
+        "installation-source": "dist",
+        "autoload": {
+            "psr-0": {
+                "Behat\\MinkExtension": "src/"
+            }
+        },
+        "notification-url": "https://packagist.org/downloads/",
+        "license": [
+            "MIT"
+        ],
+        "authors": [
+            {
+                "name": "Christophe Coevoet",
+                "email": "stof@notk.org"
+            },
+            {
+                "name": "Konstantin Kudryashov",
+                "email": "ever.zet@gmail.com"
+            }
+        ],
+        "description": "Mink extension for Behat",
+        "homepage": "http://extensions.behat.org/mink",
+        "keywords": [
+            "browser",
+            "gui",
+            "test",
+            "web"
+        ]
+    },
+    {
+        "name": "drupal/drupal-driver",
+        "version": "v1.2.1",
+        "version_normalized": "1.2.1.0",
+        "source": {
+            "type": "git",
+            "url": "https://github.com/jhedstrom/DrupalDriver.git",
+            "reference": "125d39918c97f7a08e3110d456a0a1db864dae46"
+        },
+        "dist": {
+            "type": "zip",
+            "url": "https://api.github.com/repos/jhedstrom/DrupalDriver/zipball/125d39918c97f7a08e3110d456a0a1db864dae46",
+            "reference": "125d39918c97f7a08e3110d456a0a1db864dae46",
+            "shasum": ""
+        },
+        "require": {
+            "symfony/dependency-injection": "~2.6|~3.0",
+            "symfony/process": "~2.5|~3.0"
+        },
+        "require-dev": {
+            "drupal/coder": "~8.2.0",
+            "drush-ops/behat-drush-endpoint": "*",
+            "mockery/mockery": "0.9.4",
+            "phpspec/phpspec": "~2.0",
+            "phpunit/phpunit": "~4.0"
+        },
+        "time": "2016-06-20T16:29:51+00:00",
+        "type": "library",
+        "extra": {
+            "branch-alias": {
+                "dev-master": "1.2.x-dev"
+            }
+        },
+        "installation-source": "dist",
+        "autoload": {
+            "psr-0": {
+                "Drupal\\Component": "src/",
+                "Drupal\\Driver": "src/",
+                "Drupal\\Tests\\Driver": "tests/"
+            }
+        },
+        "notification-url": "https://packagist.org/downloads/",
+        "license": [
+            "GPL-2.0+"
+        ],
+        "authors": [
+            {
+                "name": "Jonathan Hedstrom",
+                "email": "jhedstrom@gmail.com"
+            }
+        ],
+        "description": "A collection of reusable Drupal drivers",
+        "homepage": "http://github.com/jhedstrom/DrupalDriver",
+        "keywords": [
+            "drupal",
+            "test",
+            "web"
+        ]
+    },
+    {
+        "name": "drupal/drupal-extension",
+        "version": "v3.3.1",
+        "version_normalized": "3.3.1.0",
+        "source": {
+            "type": "git",
+            "url": "https://github.com/jhedstrom/drupalextension.git",
+            "reference": "2a858760208856391f7e5e4d269fba2c1df110a4"
+        },
+        "dist": {
+            "type": "zip",
+            "url": "https://api.github.com/repos/jhedstrom/drupalextension/zipball/2a858760208856391f7e5e4d269fba2c1df110a4",
+            "reference": "2a858760208856391f7e5e4d269fba2c1df110a4",
+            "shasum": ""
+        },
+        "require": {
+            "behat/behat": "~3.2",
+            "behat/mink": "~1.5",
+            "behat/mink-extension": "~2.0",
+            "behat/mink-goutte-driver": "~1.0",
+            "behat/mink-selenium2-driver": "~1.1",
+            "drupal/drupal-driver": "~1.2",
+            "symfony/dependency-injection": "~2.7|~3.0",
+            "symfony/event-dispatcher": "~2.7|~3.0"
+        },
+        "require-dev": {
+            "behat/mink-zombie-driver": "^1.2",
+            "phpspec/phpspec": "~2.0",
+            "phpunit/phpunit": "3.7.*"
+        },
+        "time": "2017-09-13T19:54:23+00:00",
+        "type": "behat-extension",
+        "extra": {
+            "branch-alias": {
+                "dev-master": "3.2.x-dev"
+            }
+        },
+        "installation-source": "dist",
+        "autoload": {
+            "psr-0": {
+                "Drupal\\Drupal": "src/",
+                "Drupal\\Exception": "src/",
+                "Drupal\\DrupalExtension": "src/"
+            }
+        },
+        "notification-url": "https://packagist.org/downloads/",
+        "license": [
+            "GPL-2.0+"
+        ],
+        "authors": [
+            {
+                "name": "Jonathan Hedstrom",
+                "email": "jhedstrom@gmail.com"
+            }
+        ],
+        "description": "Drupal extension for Behat",
+        "homepage": "http://drupal.org/project/drupalextension",
+        "keywords": [
+            "drupal",
+            "test",
+            "web"
+        ]
+    },
+    {
+        "name": "drupal/permissions_by_term",
+        "version": "1.35.0",
+        "version_normalized": "1.35.0.0",
+        "source": {
+            "type": "git",
+            "url": "https://git.drupal.org/project/permissions_by_term",
+            "reference": "8.x-1.35"
+        },
+        "dist": {
+            "type": "zip",
+            "url": "https://ftp.drupal.org/files/projects/permissions_by_term-8.x-1.35.zip",
+            "reference": "8.x-1.35",
+            "shasum": "4f9a7406a81a2e03f90e278fd6921f8fc962f07b"
+        },
+        "require": {
+            "behat/behat": "^3.1",
+            "behat/mink": "^1.7",
+            "behat/mink-extension": "^2.2",
+            "behat/mink-goutte-driver": "^1.2",
+            "behat/mink-selenium2-driver": "^1.3",
+            "drupal/core": "*",
+            "drupal/drupal-driver": "~1.0",
+            "drupal/drupal-extension": "~3.0",
+            "guzzlehttp/guzzle": "^6.0@dev"
+        },
+        "type": "drupal-module",
+        "extra": {
+            "branch-alias": {
+                "dev-1.x": "1.x-dev"
+            },
+            "drupal": {
+                "version": "8.x-1.35",
+                "datestamp": "1509945000",
+                "security-coverage": {
+                    "status": "covered",
+                    "message": "Covered by Drupal's security advisory policy"
+                }
+            }
+        },
+        "installation-source": "dist",
+        "autoload": {
+            "psr-4": {
+                "PermissionsByTerm\\": "tests/src/Behat/Context/"
+            }
+        },
+        "notification-url": "https://packages.drupal.org/8/downloads",
+        "license": [
+            "GPL-2.0+"
+        ],
+        "authors": [
+            {
+                "name": "Peter Majmesku",
+                "homepage": "https://www.drupal.org/user/786132",
+                "email": "p.majmesku@gmail.com"
+            },
+            {
+                "name": "dakku",
+                "homepage": "https://www.drupal.org/user/97634"
+            },
+            {
+                "name": "rackberg",
+                "homepage": "https://www.drupal.org/user/2806873"
+            }
+        ],
+        "description": "Restricts access to nodes by taxonomy terms in relation to users and their roles.",
+        "homepage": "https://www.drupal.org/project/permissions_by_term",
+        "support": {
+            "source": "http://cgit.drupalcode.org/permissions_by_term"
+        }
     }
 ]
diff --git a/vendor/container-interop/container-interop/.gitignore b/vendor/container-interop/container-interop/.gitignore
new file mode 100644 (file)
index 0000000..b2395aa
--- /dev/null
@@ -0,0 +1,3 @@
+composer.lock
+composer.phar
+/vendor/
diff --git a/vendor/container-interop/container-interop/LICENSE b/vendor/container-interop/container-interop/LICENSE
new file mode 100644 (file)
index 0000000..7671d90
--- /dev/null
@@ -0,0 +1,20 @@
+The MIT License (MIT)
+
+Copyright (c) 2013 container-interop
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/vendor/container-interop/container-interop/README.md b/vendor/container-interop/container-interop/README.md
new file mode 100644 (file)
index 0000000..cdd7a44
--- /dev/null
@@ -0,0 +1,148 @@
+# Container Interoperability
+
+[![Latest Stable Version](https://poser.pugx.org/container-interop/container-interop/v/stable.png)](https://packagist.org/packages/container-interop/container-interop)
+[![Total Downloads](https://poser.pugx.org/container-interop/container-interop/downloads.svg)](https://packagist.org/packages/container-interop/container-interop)
+
+## Deprecation warning!
+
+Starting Feb. 13th 2017, container-interop is officially deprecated in favor of [PSR-11](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-11-container.md).
+Container-interop has been the test-bed of PSR-11. From v1.2, container-interop directly extends PSR-11 interfaces.
+Therefore, all containers implementing container-interop are now *de-facto* compatible with PSR-11.
+
+- Projects implementing container-interop interfaces are encouraged to directly implement PSR-11 interfaces instead.
+- Projects consuming container-interop interfaces are very strongly encouraged to directly type-hint on PSR-11 interfaces, in order to be compatible with PSR-11 containers that are not compatible with container-interop.
+
+Regarding the delegate lookup feature, that is present in container-interop and not in PSR-11, the feature is actually a design pattern. It is therefore not deprecated. Documentation regarding this design pattern will be migrated from this repository into a separate website in the future.
+
+## About
+
+*container-interop* tries to identify and standardize features in *container* objects (service locators,
+dependency injection containers, etc.) to achieve interoperability.
+
+Through discussions and trials, we try to create a standard, made of common interfaces but also recommendations.
+
+If PHP projects that provide container implementations begin to adopt these common standards, then PHP
+applications and projects that use containers can depend on the common interfaces instead of specific
+implementations. This facilitates a high-level of interoperability and flexibility that allows users to consume
+*any* container implementation that can be adapted to these interfaces.
+
+The work done in this project is not officially endorsed by the [PHP-FIG](http://www.php-fig.org/), but it is being
+worked on by members of PHP-FIG and other good developers. We adhere to the spirit and ideals of PHP-FIG, and hope
+this project will pave the way for one or more future PSRs.
+
+
+## Installation
+
+You can install this package through Composer:
+
+```json
+composer require container-interop/container-interop
+```
+
+The packages adheres to the [SemVer](http://semver.org/) specification, and there will be full backward compatibility
+between minor versions.
+
+## Standards
+
+### Available
+
+- [`ContainerInterface`](src/Interop/Container/ContainerInterface.php).
+[Description](docs/ContainerInterface.md) [Meta Document](docs/ContainerInterface-meta.md).
+Describes the interface of a container that exposes methods to read its entries.
+- [*Delegate lookup feature*](docs/Delegate-lookup.md).
+[Meta Document](docs/Delegate-lookup-meta.md).
+Describes the ability for a container to delegate the lookup of its dependencies to a third-party container. This
+feature lets several containers work together in a single application.
+
+### Proposed
+
+View open [request for comments](https://github.com/container-interop/container-interop/labels/RFC)
+
+## Compatible projects
+
+### Projects implementing `ContainerInterface`
+
+- [Acclimate](https://github.com/jeremeamia/acclimate-container): Adapters for
+  Aura.Di, Laravel, Nette DI, Pimple, Symfony DI, ZF2 Service manager, ZF2
+  Dependency injection and any container using `ArrayAccess`
+- [Aura.Di](https://github.com/auraphp/Aura.Di)
+- [auryn-container-interop](https://github.com/elazar/auryn-container-interop)
+- [Burlap](https://github.com/codeeverything/burlap)
+- [Chernozem](https://github.com/pyrsmk/Chernozem)
+- [Data Manager](https://github.com/chrismichaels84/data-manager)
+- [Disco](https://github.com/bitexpert/disco)
+- [InDI](https://github.com/idealogica/indi)
+- [League/Container](http://container.thephpleague.com/)
+- [Mouf](http://mouf-php.com)
+- [Njasm Container](https://github.com/njasm/container)
+- [PHP-DI](http://php-di.org)
+- [Picotainer](https://github.com/thecodingmachine/picotainer)
+- [PimpleInterop](https://github.com/moufmouf/pimple-interop)
+- [Pimple3-ContainerInterop](https://github.com/Sam-Burns/pimple3-containerinterop) (using Pimple v3)
+- [SitePoint Container](https://github.com/sitepoint/Container)
+- [Thruster Container](https://github.com/ThrusterIO/container) (PHP7 only)
+- [Ultra-Lite Container](https://github.com/ultra-lite/container)
+- [Unbox](https://github.com/mindplay-dk/unbox)
+- [XStatic](https://github.com/jeremeamia/xstatic)
+- [Zend\ServiceManager](https://github.com/zendframework/zend-servicemanager)
+- [Zit](https://github.com/inxilpro/Zit)
+
+### Projects implementing the *delegate lookup* feature
+
+- [Aura.Di](https://github.com/auraphp/Aura.Di)
+- [Burlap](https://github.com/codeeverything/burlap)
+- [Chernozem](https://github.com/pyrsmk/Chernozem)
+- [InDI](https://github.com/idealogica/indi)
+- [League/Container](http://container.thephpleague.com/)
+- [Mouf](http://mouf-php.com)
+- [Picotainer](https://github.com/thecodingmachine/picotainer)
+- [PHP-DI](http://php-di.org)
+- [PimpleInterop](https://github.com/moufmouf/pimple-interop)
+- [Ultra-Lite Container](https://github.com/ultra-lite/container)
+
+### Middlewares implementing `ContainerInterface`
+
+- [Alias-Container](https://github.com/thecodingmachine/alias-container): add
+  aliases support to any container
+- [Prefixer-Container](https://github.com/thecodingmachine/prefixer-container):
+  dynamically prefix identifiers
+- [Lazy-Container](https://github.com/snapshotpl/lazy-container): lazy services
+
+### Projects using `ContainerInterface`
+
+The list below contains only a sample of all the projects consuming `ContainerInterface`. For a more complete list have a look [here](http://packanalyst.com/class?q=Interop%5CContainer%5CContainerInterface).
+
+| | Downloads |
+| --- | --- |
+| [Adroit](https://github.com/bitexpert/adroit) | ![](https://img.shields.io/packagist/dt/bitexpert/adroit.svg) |
+| [Behat](https://github.com/Behat/Behat/pull/974) | ![](https://img.shields.io/packagist/dt/behat/behat.svg) |
+| [blast-facades](https://github.com/phpthinktank/blast-facades): Minimize complexity and represent dependencies as facades. | ![](https://img.shields.io/packagist/dt/blast/facades.svg) |
+| [interop.silex.di](https://github.com/thecodingmachine/interop.silex.di): an extension to [Silex](http://silex.sensiolabs.org/) that adds support for any *container-interop* compatible container | ![](https://img.shields.io/packagist/dt/mouf/interop.silex.di.svg) |
+| [mindplay/walkway](https://github.com/mindplay-dk/walkway): a modular request router | ![](https://img.shields.io/packagist/dt/mindplay/walkway.svg) |
+| [mindplay/middleman](https://github.com/mindplay-dk/middleman): minimalist PSR-7 middleware dispatcher | ![](https://img.shields.io/packagist/dt/mindplay/middleman.svg) |
+| [PHP-DI/Invoker](https://github.com/PHP-DI/Invoker): extensible and configurable invoker/dispatcher | ![](https://img.shields.io/packagist/dt/php-di/invoker.svg) |
+| [Prophiler](https://github.com/fabfuel/prophiler) | ![](https://img.shields.io/packagist/dt/fabfuel/prophiler.svg) |
+| [Silly](https://github.com/mnapoli/silly): CLI micro-framework | ![](https://img.shields.io/packagist/dt/mnapoli/silly.svg) |
+| [Slim v3](https://github.com/slimphp/Slim) | ![](https://img.shields.io/packagist/dt/slim/slim.svg) |
+| [Splash](http://mouf-php.com/packages/mouf/mvc.splash-common/version/8.0-dev/README.md) | ![](https://img.shields.io/packagist/dt/mouf/mvc.splash-common.svg) |
+| [Woohoo Labs. Harmony](https://github.com/woohoolabs/harmony): a flexible micro-framework | ![](https://img.shields.io/packagist/dt/woohoolabs/harmony.svg) |
+| [zend-expressive](https://github.com/zendframework/zend-expressive) | ![](https://img.shields.io/packagist/dt/zendframework/zend-expressive.svg) |
+
+
+## Workflow
+
+Everyone is welcome to join and contribute.
+
+The general workflow looks like this:
+
+1. Someone opens a discussion (GitHub issue) to suggest an interface
+1. Feedback is gathered
+1. The interface is added to a development branch
+1. We release alpha versions so that the interface can be experimented with
+1. Discussions and edits ensue until the interface is deemed stable by a general consensus
+1. A new minor version of the package is released
+
+We try to not break BC by creating new interfaces instead of editing existing ones.
+
+While we currently work on interfaces, we are open to anything that might help towards interoperability, may that
+be code, best practices, etc.
diff --git a/vendor/container-interop/container-interop/composer.json b/vendor/container-interop/container-interop/composer.json
new file mode 100644 (file)
index 0000000..855f766
--- /dev/null
@@ -0,0 +1,15 @@
+{
+    "name": "container-interop/container-interop",
+    "type": "library",
+    "description": "Promoting the interoperability of container objects (DIC, SL, etc.)",
+    "homepage": "https://github.com/container-interop/container-interop",
+    "license": "MIT",
+    "autoload": {
+        "psr-4": {
+            "Interop\\Container\\": "src/Interop/Container/"
+        }
+    },
+    "require": {
+        "psr/container": "^1.0"
+    }
+}
diff --git a/vendor/container-interop/container-interop/docs/ContainerInterface-meta.md b/vendor/container-interop/container-interop/docs/ContainerInterface-meta.md
new file mode 100644 (file)
index 0000000..59f3d55
--- /dev/null
@@ -0,0 +1,114 @@
+# ContainerInterface Meta Document
+
+## Introduction
+
+This document describes the process and discussions that lead to the `ContainerInterface`.
+Its goal is to explain the reasons behind each decision.
+
+## Goal
+
+The goal set by `ContainerInterface` is to standardize how frameworks and libraries make use of a
+container to obtain objects and parameters.
+
+By standardizing such a behavior, frameworks and libraries using the `ContainerInterface`
+could work with any compatible container.
+That would allow end users to choose their own container based on their own preferences.
+
+It is important to distinguish the two usages of a container:
+
+- configuring entries
+- fetching entries
+
+Most of the time, those two sides are not used by the same party.
+While it is often end users who tend to configure entries, it is generally the framework that fetch
+entries to build the application.
+
+This is why this interface focuses only on how entries can be fetched from a container.
+
+## Interface name
+
+The interface name has been thoroughly discussed and was decided by a vote.
+
+The list of options considered with their respective votes are:
+
+- `ContainerInterface`: +8
+- `ProviderInterface`: +2
+- `LocatorInterface`: 0
+- `ReadableContainerInterface`: -5
+- `ServiceLocatorInterface`: -6
+- `ObjectFactory`: -6
+- `ObjectStore`: -8
+- `ConsumerInterface`: -9
+
+[Full results of the vote](https://github.com/container-interop/container-interop/wiki/%231-interface-name:-Vote)
+
+The complete discussion can be read in [the issue #1](https://github.com/container-interop/container-interop/issues/1).
+
+## Interface methods
+
+The choice of which methods the interface would contain was made after a statistical analysis of existing containers.
+The results of this analysis are available [in this document](https://gist.github.com/mnapoli/6159681).
+
+The summary of the analysis showed that:
+
+- all containers offer a method to get an entry by its id
+- a large majority name such method `get()`
+- for all containers, the `get()` method has 1 mandatory parameter of type string
+- some containers have an optional additional argument for `get()`, but it doesn't have the same purpose between containers
+- a large majority of the containers offer a method to test if it can return an entry by its id
+- a majority name such method `has()`
+- for all containers offering `has()`, the method has exactly 1 parameter of type string
+- a large majority of the containers throw an exception rather than returning null when an entry is not found in `get()`
+- a large majority of the containers don't implement `ArrayAccess`
+
+The question of whether to include methods to define entries has been discussed in
+[issue #1](https://github.com/container-interop/container-interop/issues/1).
+It has been judged that such methods do not belong in the interface described here because it is out of its scope
+(see the "Goal" section).
+
+As a result, the `ContainerInterface` contains two methods:
+
+- `get()`, returning anything, with one mandatory string parameter. Should throw an exception if the entry is not found.
+- `has()`, returning a boolean, with one mandatory string parameter.
+
+### Number of parameters in `get()` method
+
+While `ContainerInterface` only defines one mandatory parameter in `get()`, it is not incompatible with
+existing containers that have additional optional parameters. PHP allows an implementation to offer more parameters
+as long as they are optional, because the implementation *does* satisfy the interface.
+
+This issue has been discussed in [issue #6](https://github.com/container-interop/container-interop/issues/6).
+
+### Type of the `$id` parameter
+
+The type of the `$id` parameter in `get()` and `has()` has been discussed in
+[issue #6](https://github.com/container-interop/container-interop/issues/6).
+While `string` is used in all the containers that were analyzed, it was suggested that allowing
+anything (such as objects) could allow containers to offer a more advanced query API.
+
+An example given was to use the container as an object builder. The `$id` parameter would then be an
+object that would describe how to create an instance.
+
+The conclusion of the discussion was that this was beyond the scope of getting entries from a container without
+knowing how the container provided them, and it was more fit for a factory.
+
+## Contributors
+
+Are listed here all people that contributed in the discussions or votes, by alphabetical order:
+
+- [Amy Stephen](https://github.com/AmyStephen)
+- [David Négrier](https://github.com/moufmouf)
+- [Don Gilbert](https://github.com/dongilbert)
+- [Jason Judge](https://github.com/judgej)
+- [Jeremy Lindblom](https://github.com/jeremeamia)
+- [Marco Pivetta](https://github.com/Ocramius)
+- [Matthieu Napoli](https://github.com/mnapoli)
+- [Paul M. Jones](https://github.com/pmjones)
+- [Stephan Hochdörfer](https://github.com/shochdoerfer)
+- [Taylor Otwell](https://github.com/taylorotwell)
+
+## Relevant links
+
+- [`ContainerInterface.php`](https://github.com/container-interop/container-interop/blob/master/src/Interop/Container/ContainerInterface.php)
+- [List of all issues](https://github.com/container-interop/container-interop/issues?labels=ContainerInterface&milestone=&page=1&state=closed)
+- [Vote for the interface name](https://github.com/container-interop/container-interop/wiki/%231-interface-name:-Vote)
diff --git a/vendor/container-interop/container-interop/docs/ContainerInterface.md b/vendor/container-interop/container-interop/docs/ContainerInterface.md
new file mode 100644 (file)
index 0000000..bda973d
--- /dev/null
@@ -0,0 +1,158 @@
+Container interface
+===================
+
+This document describes a common interface for dependency injection containers.
+
+The goal set by `ContainerInterface` is to standardize how frameworks and libraries make use of a
+container to obtain objects and parameters (called *entries* in the rest of this document).
+
+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 `ContainerInterface` in a dependency injection-related library or framework.
+Users of dependency injections containers (DIC) are referred to as `user`.
+
+[RFC 2119]: http://tools.ietf.org/html/rfc2119
+
+1. Specification
+-----------------
+
+### 1.1 Basics
+
+- The `Interop\Container\ContainerInterface` exposes two methods : `get` and `has`.
+
+- `get` takes one mandatory parameter: an entry identifier. It MUST be a string.
+  A call to `get` can return anything (a *mixed* value), or throws an exception if the identifier
+  is not known to the container. Two successive calls to `get` with the same
+  identifier SHOULD return the same value. However, depending on the `implementor`
+  design and/or `user` configuration, different values might be returned, so
+  `user` SHOULD NOT rely on getting the same value on 2 successive calls.
+  While `ContainerInterface` only defines one mandatory parameter in `get()`, implementations
+  MAY accept additional optional parameters.
+
+- `has` takes one unique parameter: an entry identifier. It MUST return `true`
+  if an entry identifier is known to the container and `false` if it is not.
+  `has($id)` returning true does not mean that `get($id)` will not throw an exception.
+  It does however mean that `get($id)` will not throw a `NotFoundException`.
+
+### 1.2 Exceptions
+
+Exceptions directly thrown by the container MUST implement the
+[`Interop\Container\Exception\ContainerException`](../src/Interop/Container/Exception/ContainerException.php).
+
+A call to the `get` method with a non-existing id SHOULD throw a
+[`Interop\Container\Exception\NotFoundException`](../src/Interop/Container/Exception/NotFoundException.php).
+
+### 1.3 Additional features
+
+This section describes additional features that MAY be added to a container. Containers are not
+required to implement these features to respect the ContainerInterface.
+
+#### 1.3.1 Delegate lookup feature
+
+The goal of 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.
+
+A container implementing this feature:
+
+- MUST implement the `ContainerInterface`
+- 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`.
+
+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`).
+- 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 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.
+
+2. Package
+----------
+
+The interfaces and classes described as well as relevant exception are provided as part of the
+[container-interop/container-interop](https://packagist.org/packages/container-interop/container-interop) package.
+
+3. `Interop\Container\ContainerInterface`
+-----------------------------------------
+
+```php
+<?php
+namespace Interop\Container;
+
+use Interop\Container\Exception\ContainerException;
+use Interop\Container\Exception\NotFoundException;
+
+/**
+ * Describes the interface of a container that exposes methods to read its entries.
+ */
+interface ContainerInterface
+{
+    /**
+     * Finds an entry of the container by its identifier and returns it.
+     *
+     * @param string $id Identifier of the entry to look for.
+     *
+     * @throws NotFoundException  No entry was found for this identifier.
+     * @throws ContainerException Error while retrieving the entry.
+     *
+     * @return mixed Entry.
+     */
+    public function get($id);
+
+    /**
+     * Returns true if the container can return an entry for the given identifier.
+     * Returns false otherwise.
+     *
+     * `has($id)` returning true does not mean that `get($id)` will not throw an exception.
+     * It does however mean that `get($id)` will not throw a `NotFoundException`.
+     *
+     * @param string $id Identifier of the entry to look for.
+     *
+     * @return boolean
+     */
+    public function has($id);
+}
+```
+
+4. `Interop\Container\Exception\ContainerException`
+---------------------------------------------------
+
+```php
+<?php
+namespace Interop\Container\Exception;
+
+/**
+ * Base interface representing a generic exception in a container.
+ */
+interface ContainerException
+{
+}
+```
+
+5. `Interop\Container\Exception\NotFoundException`
+---------------------------------------------------
+
+```php
+<?php
+namespace Interop\Container\Exception;
+
+/**
+ * No entry was found in the container.
+ */
+interface NotFoundException extends ContainerException
+{
+}
+```
diff --git a/vendor/container-interop/container-interop/docs/Delegate-lookup-meta.md b/vendor/container-interop/container-interop/docs/Delegate-lookup-meta.md
new file mode 100644 (file)
index 0000000..6048b73
--- /dev/null
@@ -0,0 +1,259 @@
+Delegate lookup feature Meta Document
+=====================================
+
+1. Summary
+----------
+
+This document describes the *delegate lookup feature*.
+Containers are not required to implement this feature to respect the `ContainerInterface`.
+However, containers implementing this feature will offer a greater lever of interoperability
+with other containers, allowing multiple containers to share entries in the same application.
+Implementation of this feature is therefore recommanded.
+
+2. Why Bother?
+--------------
+
+The [`ContainerInterface`](../src/Interop/Container/ContainerInterface.php) ([meta doc](ContainerInterface.md))
+standardizes how frameworks and libraries make use of a container to obtain objects and parameters.
+
+By standardizing such a behavior, frameworks and libraries relying on the `ContainerInterface`
+could work with any compatible container.
+That would allow end users to choose their own container based on their own preferences.
+
+The `ContainerInterface` is also enough if we want to have several containers side-by-side in the same
+application. For instance, this is what the [CompositeContainer](https://github.com/jeremeamia/acclimate-container/blob/master/src/CompositeContainer.php) 
+class of [Acclimate](https://github.com/jeremeamia/acclimate-container) is designed for:
+
+![Side by side containers](images/side_by_side_containers.png)
+
+However, an instance in container 1 cannot reference an instance in container 2.
+
+It would be better if an instance of container 1 could reference an instance in container 2,
+and the opposite should be true. 
+
+![Interoperating containers](images/interoperating_containers.png)
+
+In the sample above, entry 1 in container 1 is referencing entry 3 in container 2.
+
+3. Scope
+--------
+
+### 3.1 Goals
+
+The goal of the *delegate lookup* feature is to allow several containers to share entries.
+
+4. Approaches
+-------------
+
+### 4.1 Chosen Approach
+
+Containers implementing this feature can perform dependency lookups in other containers.
+
+A container implementing this feature:
+
+- must implement the `ContainerInterface`
+- 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`.
+
+When a *delegate container* is configured on a container:
+
+- 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 required in the `ContainerInterface`).
+- 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.
+ - Finally, the important part: if the entry we are fetching has dependencies,
+**instead** of perfoming the dependency lookup in the container, the lookup is performed on the *delegate container*.
+
+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.
+
+### 4.2 Typical usage
+
+The *delegate container* will usually be a composite container. A composite container is a container that
+contains several other containers. When performing a lookup on a composite container, the inner containers are 
+queried until one container returns an entry.
+An inner container implementing the *delegate lookup feature* will return entries it contains, but if these
+entries have dependencies, the dependencies lookup calls will be performed on the composite container, giving
+a chance to all containers to answer.
+
+Interestingly enough, the order in which containers are added in the composite container matters. Indeed,
+the first containers to be added in the composite container can "override" the entries of containers with
+lower priority.
+
+![Containers priority](images/priority.png)
+
+In the example above, "container 2" contains a controller "myController" and the controller is referencing an 
+"entityManager" entry. "Container 1" contains also an entry named "entityManager".
+Without the *delegate lookup* feature, when requesting the "myController" instance to container 2, it would take 
+in charge the instanciation of both entries.
+
+However, using the *delegate lookup* feature, here is what happens when we ask the composite container for the 
+"myController" instance:
+
+- The composite container asks container 1 if if contains the "myController" instance. The answer is no.
+- The composite container asks container 2 if if contains the "myController" instance. The answer is yes.
+- The composite container performs a `get` call on container 2 for the "myController" instance.
+- Container 2 sees that "myController" has a dependency on "entityManager".
+- Container 2 delegates the lookup of "entityManager" to the composite container.
+- The composite container asks container 1 if if contains the "entityManager" instance. The answer is yes.
+- The composite container performs a `get` call on container 1 for the "entityManager" instance.
+
+In the end, we get a controller instanciated by container 2 that references an entityManager instanciated
+by container 1.
+
+### 4.3 Alternative: the fallback strategy
+
+The first proposed approach we tried was to perform all the lookups in the "local" container,
+and if a lookup fails in the container, to use the delegate container. In this scenario, the
+delegate container is used in "fallback" mode.
+
+This strategy has been described in @moufmouf blog post: http://mouf-php.com/container-interop-whats-next (solution 1).
+It was also discussed [here](https://github.com/container-interop/container-interop/pull/8#issuecomment-33570697) and
+[here](https://github.com/container-interop/container-interop/pull/20#issuecomment-56599631).
+
+Problems with this strategy:
+
+- Heavy problem regarding infinite loops
+- Unable to overload a container entry with the delegate container entry
+
+### 4.4 Alternative: force implementing an interface
+
+The first proposed approach was to develop a `ParentAwareContainerInterface` interface.
+It was proposed here: https://github.com/container-interop/container-interop/pull/8
+
+The interface would have had the behaviour of the delegate lookup feature but would have forced the addition of
+a `setParentContainter` method:
+
+```php
+interface ParentAwareContainerInterface extends ReadableContainerInterface {
+    /**
+     * Sets the parent container associated to that container. This container will call
+     * the parent container to fetch dependencies.
+     *
+     * @param ContainerInterface $container
+     */
+    public function setParentContainer(ContainerInterface $container);
+}
+```
+
+The interface idea was first questioned by @Ocramius [here](https://github.com/container-interop/container-interop/pull/8#issuecomment-51721777).
+@Ocramius expressed the idea that an interface should not contain setters, otherwise, it is forcing implementation
+details on the class implementing the interface. 
+Then @mnapoli made a proposal for a "convention" [here](https://github.com/container-interop/container-interop/pull/8#issuecomment-51841079),
+this idea was further discussed until all participants in the discussion agreed to remove the interface idea
+and replace it with a "standard" feature.
+
+**Pros:**
+
+If we had had an interface, we could have delegated the registration of the delegate/composite container to the
+the delegate/composite container itself.
+For instance:
+
+```php
+$containerA = new ContainerA();
+$containerB = new ContainerB();
+
+$compositeContainer = new CompositeContainer([$containerA, $containerB]);
+
+// The call to 'setParentContainer' is delegated to the CompositeContainer
+// It is not the responsibility of the user anymore.
+class CompositeContainer {
+       ...
+       
+       public function __construct($containers) {
+               foreach ($containers as $container) {
+                       if ($container instanceof ParentAwareContainerInterface) {
+                               $container->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/vendor/container-interop/container-interop/docs/Delegate-lookup.md b/vendor/container-interop/container-interop/docs/Delegate-lookup.md
new file mode 100644 (file)
index 0000000..f64a8f7
--- /dev/null
@@ -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 referred 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/vendor/container-interop/container-interop/docs/images/interoperating_containers.png b/vendor/container-interop/container-interop/docs/images/interoperating_containers.png
new file mode 100644 (file)
index 0000000..1d3fdd0
Binary files /dev/null and b/vendor/container-interop/container-interop/docs/images/interoperating_containers.png differ
diff --git a/vendor/container-interop/container-interop/docs/images/priority.png b/vendor/container-interop/container-interop/docs/images/priority.png
new file mode 100644 (file)
index 0000000..d02cb7d
Binary files /dev/null and b/vendor/container-interop/container-interop/docs/images/priority.png differ
diff --git a/vendor/container-interop/container-interop/docs/images/side_by_side_containers.png b/vendor/container-interop/container-interop/docs/images/side_by_side_containers.png
new file mode 100644 (file)
index 0000000..87884bc
Binary files /dev/null and b/vendor/container-interop/container-interop/docs/images/side_by_side_containers.png differ
diff --git a/vendor/container-interop/container-interop/src/Interop/Container/ContainerInterface.php b/vendor/container-interop/container-interop/src/Interop/Container/ContainerInterface.php
new file mode 100644 (file)
index 0000000..a75468f
--- /dev/null
@@ -0,0 +1,15 @@
+<?php
+/**
+ * @license http://www.opensource.org/licenses/mit-license.php MIT (see the LICENSE file)
+ */
+
+namespace Interop\Container;
+
+use Psr\Container\ContainerInterface as PsrContainerInterface;
+
+/**
+ * Describes the interface of a container that exposes methods to read its entries.
+ */
+interface ContainerInterface extends PsrContainerInterface
+{
+}
diff --git a/vendor/container-interop/container-interop/src/Interop/Container/Exception/ContainerException.php b/vendor/container-interop/container-interop/src/Interop/Container/Exception/ContainerException.php
new file mode 100644 (file)
index 0000000..3964061
--- /dev/null
@@ -0,0 +1,15 @@
+<?php
+/**
+ * @license http://www.opensource.org/licenses/mit-license.php MIT (see the LICENSE file)
+ */
+
+namespace Interop\Container\Exception;
+
+use Psr\Container\ContainerExceptionInterface as PsrContainerException;
+
+/**
+ * Base interface representing a generic exception in a container.
+ */
+interface ContainerException extends PsrContainerException
+{
+}
diff --git a/vendor/container-interop/container-interop/src/Interop/Container/Exception/NotFoundException.php b/vendor/container-interop/container-interop/src/Interop/Container/Exception/NotFoundException.php
new file mode 100644 (file)
index 0000000..031b3ab
--- /dev/null
@@ -0,0 +1,15 @@
+<?php
+/**
+ * @license http://www.opensource.org/licenses/mit-license.php MIT (see the LICENSE file)
+ */
+
+namespace Interop\Container\Exception;
+
+use Psr\Container\NotFoundExceptionInterface as PsrNotFoundException;
+
+/**
+ * No entry was found in the container.
+ */
+interface NotFoundException extends ContainerException, PsrNotFoundException
+{
+}
diff --git a/vendor/drupal/drupal-driver/.gitignore b/vendor/drupal/drupal-driver/.gitignore
new file mode 100644 (file)
index 0000000..204844e
--- /dev/null
@@ -0,0 +1,5 @@
+*.tgz
+*.phar
+composer.lock
+vendor
+drush
diff --git a/vendor/drupal/drupal-driver/.travis.yml b/vendor/drupal/drupal-driver/.travis.yml
new file mode 100644 (file)
index 0000000..9dd1ee8
--- /dev/null
@@ -0,0 +1,22 @@
+language: php
+
+php:
+  - 5.3
+  - 5.4
+  - 5.5
+  - 5.6
+  - 7.0
+  - hhvm
+
+install:
+  - composer install --dev --prefer-source
+
+script:
+  - find ./src -name "*.php" -print0 | xargs -0 -n1 -P8 php -l
+  - phpunit
+  - vendor/bin/phpspec run -f pretty --no-interaction
+  # Don't test coding on php 5.3.
+  - test ${TRAVIS_PHP_VERSION} == "5.3" || ./vendor/bin/phpcs --standard=./phpcs-ruleset.xml --ignore=./vendor --ignore=./doc --ignore=./spec --ignore=./drush .
+
+# Enable Travis containers.
+sudo: false
diff --git a/vendor/drupal/drupal-driver/LICENSE b/vendor/drupal/drupal-driver/LICENSE
new file mode 100644 (file)
index 0000000..d159169
--- /dev/null
@@ -0,0 +1,339 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                            NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --git a/vendor/drupal/drupal-driver/README.md b/vendor/drupal/drupal-driver/README.md
new file mode 100644 (file)
index 0000000..5116aa1
--- /dev/null
@@ -0,0 +1,61 @@
+[![Build Status](https://travis-ci.org/jhedstrom/DrupalDriver.svg?branch=master)](https://travis-ci.org/jhedstrom/DrupalDriver)
+
+Provides a collection of light-weight drivers with a common interface for interacting with [Drupal](http://drupal.org). These are generally intended for testing, and are not meant to be API-complete.
+
+[Read the full documentation](http://drupal-drivers.readthedocs.org)
+
+[![Latest Stable Version](https://poser.pugx.org/drupal/drupal-driver/v/stable.svg)](https://packagist.org/packages/drupal/drupal-driver) [![Total Downloads](https://poser.pugx.org/drupal/drupal-driver/downloads.svg)](https://packagist.org/packages/drupal/drupal-driver) [![License](https://poser.pugx.org/drupal/drupal-driver/license.svg)](https://packagist.org/packages/drupal/drupal-driver) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/jhedstrom/DrupalDriver/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/jhedstrom/DrupalDriver/?branch=master)
+
+### Drivers
+
+These drivers support Drupal versions 7 and 8.
+
+* Blackbox
+* Direct Drupal API bootstrap
+* Drush
+
+### Installation
+
+``` json
+{
+  "require": {
+    "drupal/drupal-driver": "~1.0"
+  }
+}
+```
+
+``` bash
+$> curl -sS http://getcomposer.org/installer | php
+$> php composer.phar install
+```
+
+### Usage
+
+``` php
+<?php
+
+use Drupal\Driver\DrupalDriver;
+use Drupal\Driver\Cores\Drupal8;
+
+require 'vendor/autoload.php';
+
+// Path to Drupal.
+$path = './drupal-8';
+
+// Host.
+$uri = 'http://d8.devl';
+
+$driver = new DrupalDriver($path, $uri);
+$driver->setCoreFromVersion();
+
+// Bootstrap Drupal.
+$driver->bootstrap();
+
+// Create a node.
+$node = (object) array(
+  'type' => 'article',
+  'uid' => 1,
+  'title' => $driver->getRandom()->name(),
+);
+$driver->createNode($node);
+```
diff --git a/vendor/drupal/drupal-driver/composer.json b/vendor/drupal/drupal-driver/composer.json
new file mode 100644 (file)
index 0000000..7f5922c
--- /dev/null
@@ -0,0 +1,37 @@
+{
+  "name": "drupal/drupal-driver",
+  "type": "library",
+  "description": "A collection of reusable Drupal drivers",
+  "keywords": ["drupal", "web", "test"],
+  "homepage": "http://github.com/jhedstrom/DrupalDriver",
+  "license": "GPL-2.0+",
+  "authors": [
+     {
+       "name": "Jonathan Hedstrom",
+       "email": "jhedstrom@gmail.com"
+     }
+  ],
+  "require": {
+    "symfony/process": "~2.5|~3.0",
+    "symfony/dependency-injection": "~2.6|~3.0"
+  },
+  "require-dev": {
+    "drupal/coder": "~8.2.0",
+    "phpspec/phpspec": "~2.0",
+    "phpunit/phpunit": "~4.0",
+    "mockery/mockery": "0.9.4",
+    "drush-ops/behat-drush-endpoint": "*"
+  },
+  "autoload": {
+    "psr-0": {
+      "Drupal\\Component": "src/",
+      "Drupal\\Driver": "src/",
+      "Drupal\\Tests\\Driver" : "tests/"
+    }
+  },
+  "extra": {
+    "branch-alias": {
+      "dev-master": "1.2.x-dev"
+    }
+  }
+}
diff --git a/vendor/drupal/drupal-driver/doc/.gitignore b/vendor/drupal/drupal-driver/doc/.gitignore
new file mode 100644 (file)
index 0000000..a485625
--- /dev/null
@@ -0,0 +1 @@
+/_build
diff --git a/vendor/drupal/drupal-driver/doc/Makefile b/vendor/drupal/drupal-driver/doc/Makefile
new file mode 100644 (file)
index 0000000..cc5ae9b
--- /dev/null
@@ -0,0 +1,177 @@
+# Makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS    =
+SPHINXBUILD   = sphinx-build
+PAPER         =
+BUILDDIR      = _build
+
+# User-friendly check for sphinx-build
+ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
+$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)
+endif
+
+# Internal variables.
+PAPEROPT_a4     = -D latex_paper_size=a4
+PAPEROPT_letter = -D latex_paper_size=letter
+ALLSPHINXOPTS   = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+# the i18n builder cannot share the environment and doctrees with the others
+I18NSPHINXOPTS  = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+
+.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
+
+help:
+       @echo "Please use \`make <target>' where <target> is one of"
+       @echo "  html       to make standalone HTML files"
+       @echo "  dirhtml    to make HTML files named index.html in directories"
+       @echo "  singlehtml to make a single large HTML file"
+       @echo "  pickle     to make pickle files"
+       @echo "  json       to make JSON files"
+       @echo "  htmlhelp   to make HTML files and a HTML help project"
+       @echo "  qthelp     to make HTML files and a qthelp project"
+       @echo "  devhelp    to make HTML files and a Devhelp project"
+       @echo "  epub       to make an epub"
+       @echo "  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+       @echo "  latexpdf   to make LaTeX files and run them through pdflatex"
+       @echo "  latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
+       @echo "  text       to make text files"
+       @echo "  man        to make manual pages"
+       @echo "  texinfo    to make Texinfo files"
+       @echo "  info       to make Texinfo files and run them through makeinfo"
+       @echo "  gettext    to make PO message catalogs"
+       @echo "  changes    to make an overview of all changed/added/deprecated items"
+       @echo "  xml        to make Docutils-native XML files"
+       @echo "  pseudoxml  to make pseudoxml-XML files for display purposes"
+       @echo "  linkcheck  to check all external links for integrity"
+       @echo "  doctest    to run all doctests embedded in the documentation (if enabled)"
+
+clean:
+       rm -rf $(BUILDDIR)/*
+
+html:
+       $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
+       @echo
+       @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
+
+dirhtml:
+       $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
+       @echo
+       @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
+
+singlehtml:
+       $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
+       @echo
+       @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
+
+pickle:
+       $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
+       @echo
+       @echo "Build finished; now you can process the pickle files."
+
+json:
+       $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
+       @echo
+       @echo "Build finished; now you can process the JSON files."
+
+htmlhelp:
+       $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
+       @echo
+       @echo "Build finished; now you can run HTML Help Workshop with the" \
+             ".hhp project file in $(BUILDDIR)/htmlhelp."
+
+qthelp:
+       $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
+       @echo
+       @echo "Build finished; now you can run "qcollectiongenerator" with the" \
+             ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
+       @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/DrupalDrivers.qhcp"
+       @echo "To view the help file:"
+       @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/DrupalDrivers.qhc"
+
+devhelp:
+       $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
+       @echo
+       @echo "Build finished."
+       @echo "To view the help file:"
+       @echo "# mkdir -p $$HOME/.local/share/devhelp/DrupalDrivers"
+       @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/DrupalDrivers"
+       @echo "# devhelp"
+
+epub:
+       $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
+       @echo
+       @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
+
+latex:
+       $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+       @echo
+       @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
+       @echo "Run \`make' in that directory to run these through (pdf)latex" \
+             "(use \`make latexpdf' here to do that automatically)."
+
+latexpdf:
+       $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+       @echo "Running LaTeX files through pdflatex..."
+       $(MAKE) -C $(BUILDDIR)/latex all-pdf
+       @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
+
+latexpdfja:
+       $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+       @echo "Running LaTeX files through platex and dvipdfmx..."
+       $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
+       @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
+
+text:
+       $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
+       @echo
+       @echo "Build finished. The text files are in $(BUILDDIR)/text."
+
+man:
+       $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
+       @echo
+       @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
+
+texinfo:
+       $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
+       @echo
+       @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
+       @echo "Run \`make' in that directory to run these through makeinfo" \
+             "(use \`make info' here to do that automatically)."
+
+info:
+       $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
+       @echo "Running Texinfo files through makeinfo..."
+       make -C $(BUILDDIR)/texinfo info
+       @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
+
+gettext:
+       $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
+       @echo
+       @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
+
+changes:
+       $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
+       @echo
+       @echo "The overview file is in $(BUILDDIR)/changes."
+
+linkcheck:
+       $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
+       @echo
+       @echo "Link check complete; look for any errors in the above output " \
+             "or in $(BUILDDIR)/linkcheck/output.txt."
+
+doctest:
+       $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
+       @echo "Testing of doctests in the sources finished, look at the " \
+             "results in $(BUILDDIR)/doctest/output.txt."
+
+xml:
+       $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
+       @echo
+       @echo "Build finished. The XML files are in $(BUILDDIR)/xml."
+
+pseudoxml:
+       $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
+       @echo
+       @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
diff --git a/vendor/drupal/drupal-driver/doc/_static/snippets/composer.bash b/vendor/drupal/drupal-driver/doc/_static/snippets/composer.bash
new file mode 100644 (file)
index 0000000..e31b3f2
--- /dev/null
@@ -0,0 +1,2 @@
+$> curl -sS http://getcomposer.org/installer | php
+$> php composer.phar install
diff --git a/vendor/drupal/drupal-driver/doc/_static/snippets/composer.json b/vendor/drupal/drupal-driver/doc/_static/snippets/composer.json
new file mode 100644 (file)
index 0000000..b81cc88
--- /dev/null
@@ -0,0 +1,5 @@
+{
+  "require": {
+    "drupal/drupal-driver": "~1.0"
+  }
+}
diff --git a/vendor/drupal/drupal-driver/doc/_static/snippets/phpunit-composer.json b/vendor/drupal/drupal-driver/doc/_static/snippets/phpunit-composer.json
new file mode 100644 (file)
index 0000000..0e8b0d4
--- /dev/null
@@ -0,0 +1,6 @@
+{
+    "require": {
+        "aik099/phpunit-mink": "~2.0",
+        "drupal/drupal-driver": "~1.0"
+    }
+}
diff --git a/vendor/drupal/drupal-driver/doc/_static/snippets/phpunitDrupalDriver.php b/vendor/drupal/drupal-driver/doc/_static/snippets/phpunitDrupalDriver.php
new file mode 100644 (file)
index 0000000..3c70068
--- /dev/null
@@ -0,0 +1,72 @@
+<?php
+
+use aik099\PHPUnit\BrowserTestCase;
+
+use Drupal\Driver\DrupalDriver;
+
+class GeneralTest extends BrowserTestCase
+{
+
+    /**
+     * @var \Drupal\Driver\DriverInterface
+     */
+     protected static $driver;
+
+    // Path to a Drupal install. This example assumes the directory is in the same one as the `composer.json` file.
+    protected static $drupalRoot = './drupal';
+
+    // Url to the homepage of the Drupal install.
+    protected static $uri = 'http://d8.devl';
+
+    public static $browsers = array(
+        // Selenium info.
+        array(
+            'host' => 'localhost',
+            'port' => 4444,
+            'browserName' => 'firefox',
+            'baseUrl' => 'http://d8.devl',
+        ),
+    );
+
+     public static function setUpBeforeClass() {
+        self::$driver = new DrupalDriver(static::$drupalRoot, static::$uri);
+        self::$driver->setCoreFromVersion();
+        self::$driver->bootstrap();
+    }
+
+    public function testUsingSession()
+    {
+        // This is Mink's Session.
+        $session = $this->getSession();
+
+        // Go to a page.
+        $session->visit(static::$uri);
+
+        // Validate text presence on a page.
+        $this->assertTrue($session->getPage()->hasContent('Site-Install'));
+    }
+
+    public function testUsingBrowser()
+    {
+        // Prints the name of used browser.
+        echo sprintf(
+            "I'm executed using '%s' browser",
+            $this->getBrowser()->getBrowserName()
+        );
+    }
+
+    public function testNodeCreate() {
+        $drupal = self::$driver;
+        $node = (object) [
+            'title' => $drupal->getRandom()->string(),
+            'type' => 'article',
+        ];
+        $drupal->createNode($node);
+
+        $session = $this->getSession();
+        $session->visit(static::$uri . '/node/' . $node->nid);
+
+        $this->assertTrue($session->getPage()->hasContent($node->title));
+    }
+
+}
diff --git a/vendor/drupal/drupal-driver/doc/_static/snippets/usage-blackbox.php b/vendor/drupal/drupal-driver/doc/_static/snippets/usage-blackbox.php
new file mode 100644 (file)
index 0000000..f3dc5bd
--- /dev/null
@@ -0,0 +1,22 @@
+<?php
+
+use Drupal\Driver\BlackboxDriver;
+use Drupal\Driver\Exception\UnsupportedDriverActionException;
+
+...
+
+$driver = new BlackboxDriver($alias);
+
+try {
+  // Create a node.
+  $node = (object) array(
+    'type' => 'article',
+    'uid' => 1,
+    'title' => $driver->getRandom()->name(),
+  );
+  $driver->createNode($node);
+}
+catch (UnsupportedDriverActionException $e) {
+  // Mark test as skipped.
+}
+
diff --git a/vendor/drupal/drupal-driver/doc/_static/snippets/usage-drupal.php b/vendor/drupal/drupal-driver/doc/_static/snippets/usage-drupal.php
new file mode 100644 (file)
index 0000000..e7ae9e2
--- /dev/null
@@ -0,0 +1,26 @@
+<?php
+
+use Drupal\Driver\DrupalDriver;
+use Drupal\Driver\Cores\Drupal8;
+
+require 'vendor/autoload.php';
+
+// Path to Drupal.
+$path = './drupal-8';
+
+// Host.
+$uri = 'http://d8.devl';
+
+$driver = new DrupalDriver($path, $uri);
+$driver->setCoreFromVersion();
+
+// Bootstrap Drupal.
+$driver->bootstrap();
+
+// Create a node.
+$node = (object) array(
+  'type' => 'article',
+  'uid' => 1,
+  'title' => $driver->getRandom()->name(),
+);
+$driver->createNode($node);
diff --git a/vendor/drupal/drupal-driver/doc/_static/snippets/usage-drush.php b/vendor/drupal/drupal-driver/doc/_static/snippets/usage-drush.php
new file mode 100644 (file)
index 0000000..555be1c
--- /dev/null
@@ -0,0 +1,10 @@
+<?php
+
+use Drupal\Driver\DrushDriver;
+
+...
+
+$alias = '@mysite';
+$driver = new DrushDriver($alias);
+
+...
diff --git a/vendor/drupal/drupal-driver/doc/conf.py b/vendor/drupal/drupal-driver/doc/conf.py
new file mode 100644 (file)
index 0000000..e488b36
--- /dev/null
@@ -0,0 +1,267 @@
+# -*- coding: utf-8 -*-
+#
+# Drupal Drivers documentation build configuration file, created by
+# sphinx-quickstart on Thu Oct 30 12:57:48 2014.
+#
+# This file is execfile()d with the current directory set to its
+# containing dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+import sys, os
+
+# Check if this build is on readthedocs.org
+on_rtd = os.environ.get('READTHEDOCS', None) == 'True'
+if not on_rtd:
+  import sphinx_rtd_theme
+  html_theme = "sphinx_rtd_theme"
+  html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#sys.path.insert(0, os.path.abspath('.'))
+
+# -- General configuration ------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+#needs_sphinx = '1.0'
+
+# Add any Sphinx extension module names here, as strings. They can be
+# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
+# ones.
+extensions = []
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The suffix of source filenames.
+source_suffix = '.rst'
+
+# The encoding of source files.
+#source_encoding = 'utf-8-sig'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = u'Drupal Drivers'
+copyright = u'2014, Jonathan Hedstrom'
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The short X.Y version.
+version = '1.0'
+# The full version, including alpha/beta/rc tags.
+release = '1.0'
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#language = None
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+#today_fmt = '%B %d, %Y'
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+exclude_patterns = ['_build']
+
+# The reST default role (used for this markup: `text`) to use for all
+# documents.
+#default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# A list of ignored prefixes for module index sorting.
+#modindex_common_prefix = []
+
+# If true, keep warnings as "system message" paragraphs in the built documents.
+#keep_warnings = False
+
+
+# -- Options for HTML output ----------------------------------------------
+
+# The theme to use for HTML and HTML Help pages.  See the documentation for
+# a list of builtin themes.
+#html_theme = 'default'
+#html_sidebars = {
+#  '**':['globaltoc.html','searchbox.html'],
+#  'using/windows': ['windowssidebar.html', 'searchbox.html'],
+#}
+# Theme options are theme-specific and customize the look and feel of a theme
+# further.  For a list of options available for each theme, see the
+# documentation.
+#html_theme_options = {}
+
+# Add any paths that contain custom themes here, relative to this directory.
+#html_theme_path = []
+
+# The name for this set of Sphinx documents.  If None, it defaults to
+# "<project> v<release> documentation".
+#html_title = None
+
+# A shorter title for the navigation bar.  Default is the same as html_title.
+#html_short_title = None
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+#html_logo = None
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+#html_favicon = None
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['_static']
+
+# Add any extra paths that contain custom files (such as robots.txt or
+# .htaccess) here, relative to this directory. These files are copied
+# directly to the root of the documentation.
+#html_extra_path = []
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+#html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+#html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#html_additional_pages = {}
+
+# If false, no module index is generated.
+#html_domain_indices = True
+
+# If false, no index is generated.
+#html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+#html_split_index = False
+
+# If true, links to the reST sources are added to the pages.
+#html_show_sourcelink = True
+
+# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
+#html_show_sphinx = True
+
+# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
+#html_show_copyright = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a <link> tag referring to it.  The value of this option must be the
+# base URL from which the finished HTML is served.
+#html_use_opensearch = ''
+
+# This is the file name suffix for HTML files (e.g. ".xhtml").
+#html_file_suffix = None
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'DrupalDriversdoc'
+
+
+# -- Options for LaTeX output ---------------------------------------------
+
+latex_elements = {
+# The paper size ('letterpaper' or 'a4paper').
+#'papersize': 'letterpaper',
+
+# The font size ('10pt', '11pt' or '12pt').
+#'pointsize': '10pt',
+
+# Additional stuff for the LaTeX preamble.
+#'preamble': '',
+}
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title,
+#  author, documentclass [howto, manual, or own class]).
+latex_documents = [
+  ('index', 'DrupalDrivers.tex', u'Drupal Drivers Documentation',
+   u'Jonathan Hedstrom', 'manual'),
+]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+#latex_logo = None
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+#latex_use_parts = False
+
+# If true, show page references after internal links.
+#latex_show_pagerefs = False
+
+# If true, show URL addresses after external links.
+#latex_show_urls = False
+
+# Documents to append as an appendix to all manuals.
+#latex_appendices = []
+
+# If false, no module index is generated.
+#latex_domain_indices = True
+
+
+# -- Options for manual page output ---------------------------------------
+
+# One entry per manual page. List of tuples
+# (source start file, name, description, authors, manual section).
+man_pages = [
+    ('index', 'drupaldrivers', u'Drupal Drivers Documentation',
+     [u'Jonathan Hedstrom'], 1)
+]
+
+# If true, show URL addresses after external links.
+#man_show_urls = False
+
+
+# -- Options for Texinfo output -------------------------------------------
+
+# Grouping the document tree into Texinfo files. List of tuples
+# (source start file, target name, title, author,
+#  dir menu entry, description, category)
+texinfo_documents = [
+  ('index', 'DrupalDrivers', u'Drupal Drivers Documentation',
+   u'Jonathan Hedstrom', 'DrupalDrivers', 'One line description of project.',
+   'Miscellaneous'),
+]
+
+# Documents to append as an appendix to all manuals.
+#texinfo_appendices = []
+
+# If false, no module index is generated.
+#texinfo_domain_indices = True
+
+# How to display URL addresses: 'footnote', 'no', or 'inline'.
+#texinfo_show_urls = 'footnote'
+
+# If true, do not generate a @detailmenu in the "Top" node's menu.
+#texinfo_no_detailmenu = False
diff --git a/vendor/drupal/drupal-driver/doc/drivers.rst b/vendor/drupal/drupal-driver/doc/drivers.rst
new file mode 100644 (file)
index 0000000..53b9c53
--- /dev/null
@@ -0,0 +1,23 @@
+Comparison of Drivers
+=====================
+
+The available drivers for interacting with your site, which are
+compatible with Drupal 7, and 8. Each driver has its own limitiations.
+
++-----------------------+----------+-------+------------+
+| Feature               | Blackbox | Drush | Drupal API |
++=======================+==========+=======+============+
+| Create users          | No       | Yes   | Yes        |
++-----------------------+----------+-------+------------+
+| Create nodes          | No       | [*]   | Yes        |
++-----------------------+----------+-------+------------+
+| Create vocabularies   | No       | No    | Yes        |
++-----------------------+----------+-------+------------+
+| Create taxonomy terms | No       | [*]   | Yes        |
++-----------------------+----------+-------+------------+
+| Run tests and site    |          |       |            |
+| on different servers  | Yes      | Yes   | No         |
++-----------------------+----------+-------+------------+
+
+[*] Possible if behat.d7.drush.inc or behat.d8.drush.inc,
+    as appropriate, is installed in the target Drupal site.
diff --git a/vendor/drupal/drupal-driver/doc/index.rst b/vendor/drupal/drupal-driver/doc/index.rst
new file mode 100644 (file)
index 0000000..b9a85c9
--- /dev/null
@@ -0,0 +1,21 @@
+.. Drupal Drivers documentation master file, created by
+   sphinx-quickstart on Thu Oct 30 12:57:48 2014.
+   You can adapt this file completely to your liking, but it should at least
+   contain the root `toctree` directive.
+
+Welcome to Drupal Driver' documentation!
+========================================
+
+The `Drupal Drivers`_ are a collection of light-weight drivers with a common interface for interacting with Drupal_. These are generally intended for testing, and are not meant to be API-complete.
+
+Contents:
+
+.. toctree::
+   :maxdepth: 1
+
+   install
+   drivers
+   usage
+
+.. _Drupal: http://drupal.org
+.. _`Drupal Drivers`: https://github.com/jhedstrom/DrupalDriver
diff --git a/vendor/drupal/drupal-driver/doc/install.rst b/vendor/drupal/drupal-driver/doc/install.rst
new file mode 100644 (file)
index 0000000..60636fd
--- /dev/null
@@ -0,0 +1,29 @@
+Installation
+============
+
+To utilize the Drupal Drivers in your own project, they are installed via composer_.
+
+.. literalinclude:: _static/snippets/composer.json
+   :language: json
+
+and then install and run composer
+
+.. literalinclude:: _static/snippets/composer.bash
+   :language: bash
+
+.. _composer: https://getcomposer.org/
+
+If you plan on using the Drush driver, then you need to ensure
+that the behat-drush-endpoint is available in the target Drupal
+site.  There are two ways to do this:
+
+1. Copy the files manually.  The project can be found at:
+
+https://github.com/drush-ops/behat-drush-endpoint
+
+2. Use Composer.
+
+If you are using Composer to manage your Drupal site, then
+you only need to require drupal/drupal-driver and
+composer/installers, and the behat-drush-endpoint files
+will be copied to the correct location.
diff --git a/vendor/drupal/drupal-driver/doc/make.bat b/vendor/drupal/drupal-driver/doc/make.bat
new file mode 100644 (file)
index 0000000..1e14cd1
--- /dev/null
@@ -0,0 +1,242 @@
+@ECHO OFF\r
+\r
+REM Command file for Sphinx documentation\r
+\r
+if "%SPHINXBUILD%" == "" (\r
+       set SPHINXBUILD=sphinx-build\r
+)\r
+set BUILDDIR=_build\r
+set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .\r
+set I18NSPHINXOPTS=%SPHINXOPTS% .\r
+if NOT "%PAPER%" == "" (\r
+       set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%\r
+       set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%\r
+)\r
+\r
+if "%1" == "" goto help\r
+\r
+if "%1" == "help" (\r
+       :help\r
+       echo.Please use `make ^<target^>` where ^<target^> is one of\r
+       echo.  html       to make standalone HTML files\r
+       echo.  dirhtml    to make HTML files named index.html in directories\r
+       echo.  singlehtml to make a single large HTML file\r
+       echo.  pickle     to make pickle files\r
+       echo.  json       to make JSON files\r
+       echo.  htmlhelp   to make HTML files and a HTML help project\r
+       echo.  qthelp     to make HTML files and a qthelp project\r
+       echo.  devhelp    to make HTML files and a Devhelp project\r
+       echo.  epub       to make an epub\r
+       echo.  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter\r
+       echo.  text       to make text files\r
+       echo.  man        to make manual pages\r
+       echo.  texinfo    to make Texinfo files\r
+       echo.  gettext    to make PO message catalogs\r
+       echo.  changes    to make an overview over all changed/added/deprecated items\r
+       echo.  xml        to make Docutils-native XML files\r
+       echo.  pseudoxml  to make pseudoxml-XML files for display purposes\r
+       echo.  linkcheck  to check all external links for integrity\r
+       echo.  doctest    to run all doctests embedded in the documentation if enabled\r
+       goto end\r
+)\r
+\r
+if "%1" == "clean" (\r
+       for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i\r
+       del /q /s %BUILDDIR%\*\r
+       goto end\r
+)\r
+\r
+\r
+%SPHINXBUILD% 2> nul\r
+if errorlevel 9009 (\r
+       echo.\r
+       echo.The 'sphinx-build' command was not found. Make sure you have Sphinx\r
+       echo.installed, then set the SPHINXBUILD environment variable to point\r
+       echo.to the full path of the 'sphinx-build' executable. Alternatively you\r
+       echo.may add the Sphinx directory to PATH.\r
+       echo.\r
+       echo.If you don't have Sphinx installed, grab it from\r
+       echo.http://sphinx-doc.org/\r
+       exit /b 1\r
+)\r
+\r
+if "%1" == "html" (\r
+       %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html\r
+       if errorlevel 1 exit /b 1\r
+       echo.\r
+       echo.Build finished. The HTML pages are in %BUILDDIR%/html.\r
+       goto end\r
+)\r
+\r
+if "%1" == "dirhtml" (\r
+       %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml\r
+       if errorlevel 1 exit /b 1\r
+       echo.\r
+       echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.\r
+       goto end\r
+)\r
+\r
+if "%1" == "singlehtml" (\r
+       %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml\r
+       if errorlevel 1 exit /b 1\r
+       echo.\r
+       echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.\r
+       goto end\r
+)\r
+\r
+if "%1" == "pickle" (\r
+       %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle\r
+       if errorlevel 1 exit /b 1\r
+       echo.\r
+       echo.Build finished; now you can process the pickle files.\r
+       goto end\r
+)\r
+\r
+if "%1" == "json" (\r
+       %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json\r
+       if errorlevel 1 exit /b 1\r
+       echo.\r
+       echo.Build finished; now you can process the JSON files.\r
+       goto end\r
+)\r
+\r
+if "%1" == "htmlhelp" (\r
+       %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp\r
+       if errorlevel 1 exit /b 1\r
+       echo.\r
+       echo.Build finished; now you can run HTML Help Workshop with the ^\r
+.hhp project file in %BUILDDIR%/htmlhelp.\r
+       goto end\r
+)\r
+\r
+if "%1" == "qthelp" (\r
+       %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp\r
+       if errorlevel 1 exit /b 1\r
+       echo.\r
+       echo.Build finished; now you can run "qcollectiongenerator" with the ^\r
+.qhcp project file in %BUILDDIR%/qthelp, like this:\r
+       echo.^> qcollectiongenerator %BUILDDIR%\qthelp\DrupalDrivers.qhcp\r
+       echo.To view the help file:\r
+       echo.^> assistant -collectionFile %BUILDDIR%\qthelp\DrupalDrivers.ghc\r
+       goto end\r
+)\r
+\r
+if "%1" == "devhelp" (\r
+       %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp\r
+       if errorlevel 1 exit /b 1\r
+       echo.\r
+       echo.Build finished.\r
+       goto end\r
+)\r
+\r
+if "%1" == "epub" (\r
+       %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub\r
+       if errorlevel 1 exit /b 1\r
+       echo.\r
+       echo.Build finished. The epub file is in %BUILDDIR%/epub.\r
+       goto end\r
+)\r
+\r
+if "%1" == "latex" (\r
+       %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex\r
+       if errorlevel 1 exit /b 1\r
+       echo.\r
+       echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.\r
+       goto end\r
+)\r
+\r
+if "%1" == "latexpdf" (\r
+       %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex\r
+       cd %BUILDDIR%/latex\r
+       make all-pdf\r
+       cd %BUILDDIR%/..\r
+       echo.\r
+       echo.Build finished; the PDF files are in %BUILDDIR%/latex.\r
+       goto end\r
+)\r
+\r
+if "%1" == "latexpdfja" (\r
+       %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex\r
+       cd %BUILDDIR%/latex\r
+       make all-pdf-ja\r
+       cd %BUILDDIR%/..\r
+       echo.\r
+       echo.Build finished; the PDF files are in %BUILDDIR%/latex.\r
+       goto end\r
+)\r
+\r
+if "%1" == "text" (\r
+       %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text\r
+       if errorlevel 1 exit /b 1\r
+       echo.\r
+       echo.Build finished. The text files are in %BUILDDIR%/text.\r
+       goto end\r
+)\r
+\r
+if "%1" == "man" (\r
+       %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man\r
+       if errorlevel 1 exit /b 1\r
+       echo.\r
+       echo.Build finished. The manual pages are in %BUILDDIR%/man.\r
+       goto end\r
+)\r
+\r
+if "%1" == "texinfo" (\r
+       %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo\r
+       if errorlevel 1 exit /b 1\r
+       echo.\r
+       echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.\r
+       goto end\r
+)\r
+\r
+if "%1" == "gettext" (\r
+       %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale\r
+       if errorlevel 1 exit /b 1\r
+       echo.\r
+       echo.Build finished. The message catalogs are in %BUILDDIR%/locale.\r
+       goto end\r
+)\r
+\r
+if "%1" == "changes" (\r
+       %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes\r
+       if errorlevel 1 exit /b 1\r
+       echo.\r
+       echo.The overview file is in %BUILDDIR%/changes.\r
+       goto end\r
+)\r
+\r
+if "%1" == "linkcheck" (\r
+       %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck\r
+       if errorlevel 1 exit /b 1\r
+       echo.\r
+       echo.Link check complete; look for any errors in the above output ^\r
+or in %BUILDDIR%/linkcheck/output.txt.\r
+       goto end\r
+)\r
+\r
+if "%1" == "doctest" (\r
+       %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest\r
+       if errorlevel 1 exit /b 1\r
+       echo.\r
+       echo.Testing of doctests in the sources finished, look at the ^\r
+results in %BUILDDIR%/doctest/output.txt.\r
+       goto end\r
+)\r
+\r
+if "%1" == "xml" (\r
+       %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml\r
+       if errorlevel 1 exit /b 1\r
+       echo.\r
+       echo.Build finished. The XML files are in %BUILDDIR%/xml.\r
+       goto end\r
+)\r
+\r
+if "%1" == "pseudoxml" (\r
+       %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml\r
+       if errorlevel 1 exit /b 1\r
+       echo.\r
+       echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml.\r
+       goto end\r
+)\r
+\r
+:end\r
diff --git a/vendor/drupal/drupal-driver/doc/usage.rst b/vendor/drupal/drupal-driver/doc/usage.rst
new file mode 100644 (file)
index 0000000..1563634
--- /dev/null
@@ -0,0 +1,47 @@
+Usage
+=====
+
+Drupal API driver
+-----------------
+
+.. literalinclude:: _static/snippets/usage-drupal.php
+   :language: php
+   :linenos:
+   :emphasize-lines: 14-15
+
+Drush driver
+------------
+
+.. literalinclude:: _static/snippets/usage-drush.php
+   :language: php
+   :linenos:
+   :emphasize-lines: 7-8
+
+Blackbox
+--------
+
+Note, the blackbox driver has no ability to control Drupal, and is provided as a fallback for when some tests can run without such access.
+
+Any testing application should catch unsupported driver exceptions.
+
+.. literalinclude:: _static/snippets/usage-blackbox.php
+   :language: php
+   :linenos:
+   :emphasize-lines: 8,19
+
+Practical example with PHPUnit
+------------------------------
+
+By using the phpunit/mink project in conjunction with the Drupal Driver, one can use PHPUnit to drive browser sessions and control Drupal.
+
+To install:
+
+.. literalinclude:: _static/snippets/phpunit-composer.json
+   :language: json
+   :linenos:
+
+and then, in the tests directory, a sample test:
+
+.. literalinclude:: _static/snippets/phpunitDrupalDriver.php
+   :language: php
+   :linenos:
diff --git a/vendor/drupal/drupal-driver/phpcs-ruleset.xml b/vendor/drupal/drupal-driver/phpcs-ruleset.xml
new file mode 100644 (file)
index 0000000..7f07a3f
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+<!-- PHP_CodeSniffer standard -->
+<!-- See https://github.com/squizlabs/PHP_CodeSniffer/wiki/Annotated-ruleset.xml -->
+<ruleset name="Invoicing">
+    <description>DrupalDriver coding standard</description>
+
+    <rule ref="./vendor/drupal/coder/coder_sniffer/Drupal">
+    </rule>
+
+    <!-- Core drivers need to set a server's remote address. -->
+    <rule ref="Drupal.Semantics.RemoteAddress.RemoteAddress">
+        <exclude-pattern>src/Drupal/Driver/Cores/*.php</exclude-pattern>
+    </rule>
+
+</ruleset>
diff --git a/vendor/drupal/drupal-driver/phpunit.xml.dist b/vendor/drupal/drupal-driver/phpunit.xml.dist
new file mode 100644 (file)
index 0000000..dcd41f4
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<phpunit colors="true" bootstrap="vendor/autoload.php">
+    <testsuites>
+        <testsuite name="Drupal Driver test suite">
+            <directory>./tests/Drupal/</directory>
+        </testsuite>
+    </testsuites>
+
+    <filter>
+        <whitelist>
+            <directory>./src/Drupal/</directory>
+        </whitelist>
+    </filter>
+</phpunit>
diff --git a/vendor/drupal/drupal-driver/spec/Drupal/Driver/BlackboxDriverSpec.php b/vendor/drupal/drupal-driver/spec/Drupal/Driver/BlackboxDriverSpec.php
new file mode 100644 (file)
index 0000000..13b30ec
--- /dev/null
@@ -0,0 +1,32 @@
+<?php
+
+namespace spec\Drupal\Driver;
+
+use PhpSpec\ObjectBehavior;
+use Prophecy\Argument;
+
+class BlackboxDriverSpec extends ObjectBehavior
+{
+    function it_is_initializable()
+    {
+        $this->shouldHaveType('Drupal\Driver\BlackboxDriver');
+    }
+
+    function it_is_always_bootstrapped()
+    {
+        $this->isBootStrapped()->shouldReturn(TRUE);
+    }
+
+    function it_should_not_allow_api_methods()
+    {
+        $user = $node = $term = new \stdClass();
+        $this->shouldThrow('Drupal\Driver\Exception\UnsupportedDriverActionException')->duringUserCreate($user);
+        $this->shouldThrow('Drupal\Driver\Exception\UnsupportedDriverActionException')->duringCreateNode($node);
+        $this->shouldThrow('Drupal\Driver\Exception\UnsupportedDriverActionException')->duringCreateTerm($term);
+    }
+
+    function it_should_not_have_a_random_generator()
+    {
+        $this->shouldThrow('Drupal\Driver\Exception\UnsupportedDriverActionException')->duringGetRandom();
+    }
+}
diff --git a/vendor/drupal/drupal-driver/spec/Drupal/Driver/Cores/Drupal6Spec.php b/vendor/drupal/drupal-driver/spec/Drupal/Driver/Cores/Drupal6Spec.php
new file mode 100644 (file)
index 0000000..79eed1a
--- /dev/null
@@ -0,0 +1,26 @@
+<?php
+
+namespace spec\Drupal\Driver\Cores;
+
+use Drupal\Component\Utility\Random;
+
+use PhpSpec\ObjectBehavior;
+use Prophecy\Argument;
+
+class Drupal6Spec extends ObjectBehavior
+{
+    function let(Random $random)
+    {
+        $this->beConstructedWith('path', 'http://www.example.com', $random);
+    }
+
+    function it_is_initializable()
+    {
+        $this->shouldHaveType('Drupal\Driver\Cores\Drupal6');
+    }
+
+    function it_should_return_a_random_generator()
+    {
+        $this->getRandom()->shouldBeAnInstanceOf('Drupal\Component\Utility\Random');
+    }
+}
diff --git a/vendor/drupal/drupal-driver/spec/Drupal/Driver/Cores/Drupal7Spec.php b/vendor/drupal/drupal-driver/spec/Drupal/Driver/Cores/Drupal7Spec.php
new file mode 100644 (file)
index 0000000..9ee3ae4
--- /dev/null
@@ -0,0 +1,26 @@
+<?php
+
+namespace spec\Drupal\Driver\Cores;
+
+use Drupal\Component\Utility\Random;
+
+use PhpSpec\ObjectBehavior;
+use Prophecy\Argument;
+
+class Drupal7Spec extends ObjectBehavior
+{
+    function let(Random $random)
+    {
+        $this->beConstructedWith('path', 'http://www.example.com', $random);
+    }
+
+    function it_is_initializable()
+    {
+        $this->shouldHaveType('Drupal\Driver\Cores\Drupal7');
+    }
+
+    function it_should_return_a_random_generator()
+    {
+        $this->getRandom()->shouldBeAnInstanceOf('Drupal\Component\Utility\Random');
+    }
+}
diff --git a/vendor/drupal/drupal-driver/spec/Drupal/Driver/Cores/Drupal8Spec.php b/vendor/drupal/drupal-driver/spec/Drupal/Driver/Cores/Drupal8Spec.php
new file mode 100644 (file)
index 0000000..a73162e
--- /dev/null
@@ -0,0 +1,26 @@
+<?php
+
+namespace spec\Drupal\Driver\Cores;
+
+use Drupal\Component\Utility\Random;
+
+use PhpSpec\ObjectBehavior;
+use Prophecy\Argument;
+
+class Drupal8Spec extends ObjectBehavior
+{
+    function let(Random $random)
+    {
+        $this->beConstructedWith('path', 'http://www.example.com', $random);
+    }
+
+    function it_is_initializable()
+    {
+        $this->shouldHaveType('Drupal\Driver\Cores\Drupal8');
+    }
+
+    function it_should_return_a_random_generator()
+    {
+        $this->getRandom()->shouldBeAnInstanceOf('Drupal\Component\Utility\Random');
+    }
+}
diff --git a/vendor/drupal/drupal-driver/spec/Drupal/Driver/Exception/BootstrapExceptionSpec.php b/vendor/drupal/drupal-driver/spec/Drupal/Driver/Exception/BootstrapExceptionSpec.php
new file mode 100644 (file)
index 0000000..c18721d
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+
+namespace spec\Drupal\Driver\Exception;
+
+use PhpSpec\ObjectBehavior;
+use Prophecy\Argument;
+
+class BootstrapExceptionSpec extends ObjectBehavior
+{
+    function let()
+    {
+        $this->beConstructedWith('Failed to bootstrap!');
+    }
+
+    function it_is_initializable()
+    {
+        $this->shouldHaveType('Drupal\Driver\Exception\BootstrapException');
+    }
+}
diff --git a/vendor/drupal/drupal-driver/spec/Drupal/Driver/Exception/UnsupportedDriverActionExceptionSpec.php b/vendor/drupal/drupal-driver/spec/Drupal/Driver/Exception/UnsupportedDriverActionExceptionSpec.php
new file mode 100644 (file)
index 0000000..84a465e
--- /dev/null
@@ -0,0 +1,26 @@
+<?php
+
+namespace spec\Drupal\Driver\Exception;
+
+use PhpSpec\ObjectBehavior;
+use Prophecy\Argument;
+
+use Drupal\Driver\DriverInterface;
+
+class UnsupportedDriverActionExceptionSpec extends ObjectBehavior
+{
+    function let(DriverInterface $driver)
+    {
+        $this->beConstructedWith('Unsupported action in %s driver!', $driver);
+    }
+
+    function it_is_initializable()
+    {
+        $this->shouldHaveType('Drupal\Driver\Exception\UnsupportedDriverActionException');
+    }
+
+    function it_should_get_the_driver()
+    {
+        $this->getDriver()->shouldBeAnInstanceOf('Drupal\Driver\DriverInterface');
+    }
+}
diff --git a/vendor/drupal/drupal-driver/src/Drupal/Component/Utility/Random.php b/vendor/drupal/drupal-driver/src/Drupal/Component/Utility/Random.php
new file mode 100644 (file)
index 0000000..fb87641
--- /dev/null
@@ -0,0 +1,151 @@
+<?php
+
+namespace Drupal\Component\Utility;
+
+/**
+ * Defines a utility class for creating random data.
+ */
+class Random {
+
+  /**
+   * The maximum number of times name() and string() can loop.
+   *
+   * This prevents infinite loops if the length of the random value is very
+   * small.
+   *
+   * @see \Drupal\Tests\Component\Utility\RandomTest
+   */
+  const MAXIMUM_TRIES = 100;
+
+  /**
+   * A list of unique strings generated by string().
+   *
+   * @var array
+   */
+  protected $strings = array();
+
+  /**
+   * A list of unique names generated by name().
+   *
+   * @var array
+   */
+  protected $names = array();
+
+  /**
+   * Generates a random string of ASCII characters of codes 32 to 126.
+   *
+   * The generated string includes alpha-numeric characters and common
+   * miscellaneous characters. Use this method when testing general input
+   * where the content is not restricted.
+   *
+   * @param int $length
+   *   Length of random string to generate.
+   * @param bool $unique
+   *   (optional) If TRUE ensures that the random string returned is unique.
+   *   Defaults to FALSE.
+   * @param callable $validator
+   *   (optional) A callable to validate the the string. Defaults to NULL.
+   *
+   * @return string
+   *   Randomly generated string.
+   *
+   * @see \Drupal\Component\Utility\Random::name()
+   */
+  public function string($length = 8, $unique = FALSE, callable $validator = NULL) {
+    $counter = 0;
+
+    // Continue to loop if $unique is TRUE and the generated string is not
+    // unique or if $validator is a callable that returns FALSE. To generate a
+    // random string this loop must be carried out at least once.
+    do {
+      if ($counter == static::MAXIMUM_TRIES) {
+        throw new \RuntimeException('Unable to generate a unique random name');
+      }
+      $str = '';
+      for ($i = 0; $i < $length; $i++) {
+        $str .= chr(mt_rand(32, 126));
+      }
+      $counter++;
+
+      $continue = FALSE;
+      if ($unique) {
+        $continue = isset($this->strings[$str]);
+      }
+      if (!$continue && is_callable($validator)) {
+        // If the validator callback returns FALSE generate another random
+        // string.
+        $continue = !call_user_func($validator, $str);
+      }
+    } while ($continue);
+
+    if ($unique) {
+      $this->strings[$str] = TRUE;
+    }
+
+    return $str;
+  }
+
+  /**
+   * Generates a random string containing letters and numbers.
+   *
+   * The string will always start with a letter. The letters may be upper or
+   * lower case. This method is better for restricted inputs that do not
+   * accept certain characters. For example, when testing input fields that
+   * require machine readable values (i.e. without spaces and non-standard
+   * characters) this method is best.
+   *
+   * @param int $length
+   *   Length of random string to generate.
+   * @param bool $unique
+   *   (optional) If TRUE ensures that the random string returned is unique.
+   *   Defaults to FALSE.
+   *
+   * @return string
+   *   Randomly generated string.
+   *
+   * @see \Drupal\Component\Utility\Random::string()
+   */
+  public function name($length = 8, $unique = FALSE) {
+    $values = array_merge(range(65, 90), range(97, 122), range(48, 57));
+    $max = count($values) - 1;
+    $counter = 0;
+
+    do {
+      if ($counter == static::MAXIMUM_TRIES) {
+        throw new \RuntimeException('Unable to generate a unique random name');
+      }
+      $str = chr(mt_rand(97, 122));
+      for ($i = 1; $i < $length; $i++) {
+        $str .= chr($values[mt_rand(0, $max)]);
+      }
+      $counter++;
+    } while ($unique && isset($this->names[$str]));
+
+    if ($unique) {
+      $this->names[$str] = TRUE;
+    }
+
+    return $str;
+  }
+
+  /**
+   * Generates a random PHP object.
+   *
+   * @param int $size
+   *   The number of random keys to add to the object.
+   *
+   * @return \stdClass
+   *   The generated object, with the specified number of random keys. Each key
+   *   has a random string value.
+   */
+  public function object($size = 4) {
+    $object = new \stdClass();
+    for ($i = 0; $i < $size; $i++) {
+      $random_key = $this->name();
+      $random_value = $this->string();
+      $object->{$random_key} = $random_value;
+    }
+    return $object;
+  }
+
+}
diff --git a/vendor/drupal/drupal-driver/src/Drupal/Driver/BaseDriver.php b/vendor/drupal/drupal-driver/src/Drupal/Driver/BaseDriver.php
new file mode 100644 (file)
index 0000000..7e6d5d0
--- /dev/null
@@ -0,0 +1,163 @@
+<?php
+
+namespace Drupal\Driver;
+
+use Drupal\Driver\Exception\UnsupportedDriverActionException;
+
+/**
+ * Implements DriverInterface.
+ */
+abstract class BaseDriver implements DriverInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getRandom() {
+    throw new UnsupportedDriverActionException($this->errorString('generate random'), $this);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function bootstrap() {
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isBootstrapped() {
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function userCreate(\stdClass $user) {
+    throw new UnsupportedDriverActionException($this->errorString('create users'), $this);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function userDelete(\stdClass $user) {
+    throw new UnsupportedDriverActionException($this->errorString('delete users'), $this);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function processBatch() {
+    throw new UnsupportedDriverActionException($this->errorString('process batch actions'), $this);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function userAddRole(\stdClass $user, $role) {
+    throw new UnsupportedDriverActionException($this->errorString('add roles'), $this);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function fetchWatchdog($count = 10, $type = NULL, $severity = NULL) {
+    throw new UnsupportedDriverActionException($this->errorString('access watchdog entries'), $this);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function clearCache($type = NULL) {
+    throw new UnsupportedDriverActionException($this->errorString('clear Drupal caches'), $this);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function clearStaticCaches() {
+    throw new UnsupportedDriverActionException($this->errorString('clear static caches'), $this);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function createNode($node) {
+    throw new UnsupportedDriverActionException($this->errorString('create nodes'), $this);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function nodeDelete($node) {
+    throw new UnsupportedDriverActionException($this->errorString('delete nodes'), $this);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function runCron() {
+    throw new UnsupportedDriverActionException($this->errorString('run cron'), $this);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function createTerm(\stdClass $term) {
+    throw new UnsupportedDriverActionException($this->errorString('create terms'), $this);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function termDelete(\stdClass $term) {
+    throw new UnsupportedDriverActionException($this->errorString('delete terms'), $this);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function roleCreate(array $permissions) {
+    throw new UnsupportedDriverActionException($this->errorString('create roles'), $this);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function roleDelete($rid) {
+    throw new UnsupportedDriverActionException($this->errorString('delete roles'), $this);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isField($entity_type, $field_name) {
+    return FALSE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function configGet($name, $key) {
+    throw new UnsupportedDriverActionException($this->errorString('config get'), $this);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function configSet($name, $key, $value) {
+    throw new UnsupportedDriverActionException($this->errorString('config set'), $this);
+  }
+
+  /**
+   * Error printing exception.
+   *
+   * @param string $error
+   *   The term, node, user or permission.
+   *
+   * @return string
+   *   A formatted string reminding people to use an API driver.
+   */
+  private function errorString($error) {
+    return sprintf('No ability to %s in %%s. Put `@api` into your feature and add an API driver (ex: `api_driver: drupal`) in behat.yml.', $error);
+  }
+
+}
diff --git a/vendor/drupal/drupal-driver/src/Drupal/Driver/BlackboxDriver.php b/vendor/drupal/drupal-driver/src/Drupal/Driver/BlackboxDriver.php
new file mode 100644 (file)
index 0000000..c4577de
--- /dev/null
@@ -0,0 +1,18 @@
+<?php
+
+namespace Drupal\Driver;
+
+/**
+ * Implements DriverInterface.
+ */
+class BlackboxDriver extends BaseDriver {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isBootstrapped() {
+    // Assume the blackbox is always bootstrapped.
+    return TRUE;
+  }
+
+}
diff --git a/vendor/drupal/drupal-driver/src/Drupal/Driver/Cores/AbstractCore.php b/vendor/drupal/drupal-driver/src/Drupal/Driver/Cores/AbstractCore.php
new file mode 100644 (file)
index 0000000..0265418
--- /dev/null
@@ -0,0 +1,91 @@
+<?php
+
+namespace Drupal\Driver\Cores;
+
+use Drupal\Component\Utility\Random;
+use Symfony\Component\DependencyInjection\Container;
+
+/**
+ * Base class for core drivers.
+ */
+abstract class AbstractCore implements CoreInterface {
+
+  /**
+   * System path to the Drupal installation.
+   *
+   * @var string
+   */
+  protected $drupalRoot;
+
+  /**
+   * URI for the Drupal installation.
+   *
+   * @var string
+   */
+  protected $uri;
+
+  /**
+   * Random generator.
+   *
+   * @var \Drupal\Component\Utility\Random
+   */
+  protected $random;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function __construct($drupal_root, $uri = 'default', Random $random = NULL) {
+    $this->drupalRoot = realpath($drupal_root);
+    $this->uri = $uri;
+    if (!isset($random)) {
+      $random = new Random();
+    }
+    $this->random = $random;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getRandom() {
+    return $this->random;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getFieldHandler($entity, $entity_type, $field_name) {
+    $reflection = new \ReflectionClass($this);
+    $core_namespace = $reflection->getShortName();
+    $field_types = $this->getEntityFieldTypes($entity_type);
+    $camelized_type = Container::camelize($field_types[$field_name]);
+    $default_class = sprintf('\Drupal\Driver\Fields\%s\DefaultHandler', $core_namespace);
+    $class_name = sprintf('\Drupal\Driver\Fields\%s\%sHandler', $core_namespace, $camelized_type);
+    if (class_exists($class_name)) {
+      return new $class_name($entity, $entity_type, $field_name);
+    }
+    return new $default_class($entity, $entity_type, $field_name);
+  }
+
+  /**
+   * Expands properties on the given entity object to the expected structure.
+   *
+   * @param \stdClass $entity
+   *   Entity object.
+   */
+  protected function expandEntityFields($entity_type, \stdClass $entity) {
+    $field_types = $this->getEntityFieldTypes($entity_type);
+    foreach ($field_types as $field_name => $type) {
+      if (isset($entity->$field_name)) {
+        $entity->$field_name = $this->getFieldHandler($entity, $entity_type, $field_name)
+          ->expand($entity->$field_name);
+      }
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function clearStaticCaches() {
+  }
+
+}
diff --git a/vendor/drupal/drupal-driver/src/Drupal/Driver/Cores/CoreInterface.php b/vendor/drupal/drupal-driver/src/Drupal/Driver/Cores/CoreInterface.php
new file mode 100644 (file)
index 0000000..7c78658
--- /dev/null
@@ -0,0 +1,219 @@
+<?php
+
+namespace Drupal\Driver\Cores;
+
+use Drupal\Component\Utility\Random;
+
+/**
+ * Drupal core interface.
+ */
+interface CoreInterface {
+
+  /**
+   * Instantiate the core interface.
+   *
+   * @param string $drupal_root
+   *   The path to the Drupal root folder.
+   * @param string $uri
+   *   URI that is accessing Drupal. Defaults to 'default'.
+   * @param \Drupal\Component\Utility\Random $random
+   *   Random string generator.
+   */
+  public function __construct($drupal_root, $uri = 'default', Random $random = NULL);
+
+  /**
+   * Return random generator.
+   */
+  public function getRandom();
+
+  /**
+   * Bootstrap Drupal.
+   */
+  public function bootstrap();
+
+  /**
+   * Get module list.
+   */
+  public function getModuleList();
+
+  /**
+   * Returns a list of all extension absolute paths.
+   *
+   * @return array
+   *   An array of absolute paths to enabled extensions.
+   */
+  public function getExtensionPathList();
+
+  /**
+   * Clear caches.
+   */
+  public function clearCache();
+
+  /**
+   * Run cron.
+   *
+   * @return bool
+   *   True if cron runs, otherwise false.
+   */
+  public function runCron();
+
+  /**
+   * Create a node.
+   */
+  public function nodeCreate($node);
+
+  /**
+   * Delete a node.
+   */
+  public function nodeDelete($node);
+
+  /**
+   * Create a user.
+   */
+  public function userCreate(\stdClass $user);
+
+  /**
+   * Delete a user.
+   */
+  public function userDelete(\stdClass $user);
+
+  /**
+   * Add a role to a user.
+   *
+   * @param \stdClass $user
+   *   The Drupal user object.
+   * @param string $role_name
+   *   The role name.
+   */
+  public function userAddRole(\stdClass $user, $role_name);
+
+  /**
+   * Validate, and prepare environment for Drupal bootstrap.
+   *
+   * @throws \Drupal\Driver\Exception\BootstrapException
+   *   Thrown when the Drupal site cannot be bootstrapped.
+   *
+   * @see _drush_bootstrap_drupal_site_validate()
+   */
+  public function validateDrupalSite();
+
+  /**
+   * Processes a batch of actions.
+   */
+  public function processBatch();
+
+  /**
+   * Create a taxonomy term.
+   */
+  public function termCreate(\stdClass $term);
+
+  /**
+   * Deletes a taxonomy term.
+   */
+  public function termDelete(\stdClass $term);
+
+  /**
+   * Creates a role.
+   *
+   * @param array $permissions
+   *   An array of permissions to create the role with.
+   *
+   * @return int
+   *   The created role name.
+   */
+  public function roleCreate(array $permissions);
+
+  /**
+   * Deletes a role.
+   *
+   * @param string $role_name
+   *   A role name to delete.
+   */
+  public function roleDelete($role_name);
+
+  /**
+   * Get FieldHandler class.
+   *
+   * @param string $entity_type
+   *   Entity type machine name.
+   * @param string $field_name
+   *   Field machine name.
+   *
+   * @return \Drupal\Driver\Fields\FieldHandlerInterface
+   *   The field handler.
+   */
+  public function getFieldHandler($entity, $entity_type, $field_name);
+
+  /**
+   * Check if the specified field is an actual Drupal field.
+   *
+   * @param string $entity_type
+   *   The entity type to check.
+   * @param string $field_name
+   *   The field name to check.
+   *
+   * @return bool
+   *   TRUE if the given field is a Drupal field, FALSE otherwise.
+   */
+  public function isField($entity_type, $field_name);
+
+  /**
+   * Returns array of field types for the specified entity.
+   *
+   * @param string $entity_type
+   *   The entity type for which to return the field types.
+   *
+   * @return array
+   *   An associative array of field types, keyed by field name.
+   */
+  public function getEntityFieldTypes($entity_type);
+
+  /**
+   * Creates a language.
+   *
+   * @param \stdClass $language
+   *   An object with the following properties:
+   *   - langcode: the langcode of the language to create.
+   */
+  public function languageCreate(\stdClass $language);
+
+  /**
+   * Deletes a language.
+   *
+   * @param \stdClass $language
+   *   An object with the following properties:
+   *   - langcode: the langcode of the language to delete.
+   */
+  public function languageDelete(\stdClass $language);
+
+  /**
+   * Clears the static caches.
+   */
+  public function clearStaticCaches();
+
+  /**
+   * Returns a configuration item.
+   *
+   * @param string $name
+   *   The name of the configuration object to retrieve.
+   * @param string $key
+   *   A string that maps to a key within the configuration data.
+   *
+   * @return mixed
+   *   The data that was requested.
+   */
+  public function configGet($name, $key = '');
+
+  /**
+   * Sets a value in a configuration object.
+   *
+   * @param string $name
+   *   The name of the configuration object.
+   * @param string $key
+   *   Identifier to store value in configuration.
+   * @param mixed $value
+   *   Value to associate with identifier.
+   */
+  public function configSet($name, $key, $value);
+
+}
diff --git a/vendor/drupal/drupal-driver/src/Drupal/Driver/Cores/Drupal6.php b/vendor/drupal/drupal-driver/src/Drupal/Driver/Cores/Drupal6.php
new file mode 100644 (file)
index 0000000..f004bae
--- /dev/null
@@ -0,0 +1,509 @@
+<?php
+
+namespace Drupal\Driver\Cores;
+
+use Drupal\Driver\Exception\BootstrapException;
+
+/**
+ * Drupal 6 core.
+ */
+class Drupal6 extends AbstractCore {
+
+  /**
+   * The available permissions.
+   *
+   * @var array
+   */
+  protected $availablePermissons;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function bootstrap() {
+    // Validate, and prepare environment for Drupal bootstrap.
+    if (!defined('DRUPAL_ROOT')) {
+      define('DRUPAL_ROOT', $this->drupalRoot);
+      require_once DRUPAL_ROOT . '/includes/bootstrap.inc';
+      $this->validateDrupalSite();
+    }
+
+    // Bootstrap Drupal.
+    $current_path = getcwd();
+    chdir(DRUPAL_ROOT);
+    drupal_bootstrap(DRUPAL_BOOTSTRAP_CONFIGURATION);
+    if (empty($GLOBALS['db_url'])) {
+      throw new BootstrapException('Missing database setting, verify the database configuration in settings.php.');
+    }
+    drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
+    chdir($current_path);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function clearCache() {
+    // Need to change into the Drupal root directory or the registry explodes.
+    $current_path = getcwd();
+    chdir(DRUPAL_ROOT);
+    drupal_flush_all_caches();
+    chdir($current_path);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function nodeCreate($node) {
+    $current_path = getcwd();
+    chdir(DRUPAL_ROOT);
+
+    // Set original if not set.
+    if (!isset($node->original)) {
+      $node->original = clone $node;
+    }
+
+    // Assign authorship if none exists and `author` is passed.
+    if (!isset($node->uid) && !empty($node->author) && ($user = user_load(array('name' => $node->author)))) {
+      $node->uid = $user->uid;
+    }
+
+    // Convert properties to expected structure.
+    $this->expandEntityProperties($node);
+
+    // Attempt to decipher any fields that may be specified.
+    $this->expandEntityFields('node', $node);
+
+    // Set defaults that haven't already been set.
+    $defaults = clone $node;
+    module_load_include('inc', 'node', 'node.pages');
+    node_object_prepare($defaults);
+    $node = (object) array_merge((array) $defaults, (array) $node);
+
+    node_save($node);
+
+    chdir($current_path);
+    return $node;
+
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function nodeDelete($node) {
+    node_delete($node->nid);
+  }
+
+  /**
+   * Implements CoreInterface::runCron().
+   */
+  public function runCron() {
+    return drupal_cron_run();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function userCreate(\stdClass $user) {
+    // Default status to TRUE if not explicitly creating a blocked user.
+    if (!isset($user->status)) {
+      $user->status = 1;
+    }
+
+    // Clone user object, otherwise user_save() changes the password to the
+    // hashed password.
+    $account = clone $user;
+    // Convert role array to a keyed array.
+    if (isset($user->roles)) {
+      $roles = array();
+      foreach ($user->roles as $rid) {
+        $roles[$rid] = $rid;
+      }
+      $user->roles = $roles;
+    }
+    $account = user_save((array) $account, (array) $account);
+    // Store the UID.
+    $user->uid = $account->uid;
+    return $user;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function userDelete(\stdClass $user) {
+    $current_path = getcwd();
+    chdir(DRUPAL_ROOT);
+    user_delete((array) $user, $user->uid);
+    chdir($current_path);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function processBatch() {
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function userAddRole(\stdClass $user, $role_name) {
+    $roles = array_flip(user_roles());
+    $role = $roles[$role_name];
+    if (!$role) {
+      throw new \RuntimeException(sprintf('No role "%s" exists.', $role_name));
+    }
+    user_multiple_role_edit(array($user->uid), 'add_role', $role);
+  }
+
+  /**
+   * Fetches a user role by role name.
+   *
+   * @param string $role_name
+   *   A string representing the role name.
+   *
+   * @return object
+   *   A fully-loaded role object if a role with the given name exists, or FALSE
+   *   otherwise.
+   *
+   * @see user_role_load()
+   */
+  protected function userRoleLoadByName($role_name) {
+    $result = db_query('SELECT * FROM {role} WHERE name = "%s"', $role_name);
+    return db_fetch_object($result);
+  }
+
+  /**
+   * Check to make sure that the array of permissions are valid.
+   *
+   * @param array $permissions
+   *   Permissions to check.
+   * @param bool $reset
+   *   Reset cached available permissions.
+   *
+   * @return bool
+   *   TRUE or FALSE depending on whether the permissions are valid.
+   */
+  protected function checkPermissions(array $permissions, $reset = FALSE) {
+
+    if (!isset($this->availablePermissons) || $reset) {
+      $this->availablePermissons = array_keys(module_invoke_all('permission'));
+    }
+
+    $valid = TRUE;
+    foreach ($permissions as $permission) {
+      if (!in_array($permission, $this->availablePermissons)) {
+        $valid = FALSE;
+      }
+    }
+    return $valid;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function roleCreate(array $permissions) {
+    // Verify permissions exist.
+    $all_permissions = module_invoke_all('perm');
+    foreach ($permissions as $name) {
+      $search = array_search($name, $all_permissions);
+      if (!$search) {
+        throw new \RuntimeException(sprintf("No permission '%s' exists.", $name));
+      }
+    }
+    // Create new role.
+    $name = $this->random->name(8);
+    db_query("INSERT INTO {role} SET name = '%s'", $name);
+    // Add permissions to role.
+    $rid = db_last_insert_id('role', 'rid');
+    db_query("INSERT INTO {permission} (rid, perm) VALUES (%d, '%s')", $rid, implode(', ', $permissions));
+    return $name;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function roleDelete($role_name) {
+    $roles = array_flip(user_roles());
+    $rid = $roles[$role_name];
+    db_query('DELETE FROM {role} WHERE rid = %d', $rid);
+    if (!db_affected_rows()) {
+      throw new \RuntimeException(sprintf('No role "%s" exists.', $rid));
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function validateDrupalSite() {
+    if ('default' !== $this->uri) {
+      // Fake the necessary HTTP headers that Drupal needs:
+      $drupal_base_url = parse_url($this->uri);
+      // If there's no url scheme set, add http:// and re-parse the url
+      // so the host and path values are set accurately.
+      if (!array_key_exists('scheme', $drupal_base_url)) {
+        $drupal_base_url = parse_url($this->uri);
+      }
+      // Fill in defaults.
+      $drupal_base_url += array(
+        'path' => NULL,
+        'host' => NULL,
+        'port' => NULL,
+      );
+      $_SERVER['HTTP_HOST'] = $drupal_base_url['host'];
+
+      if ($drupal_base_url['port']) {
+        $_SERVER['HTTP_HOST'] .= ':' . $drupal_base_url['port'];
+      }
+      $_SERVER['SERVER_PORT'] = $drupal_base_url['port'];
+
+      if (array_key_exists('path', $drupal_base_url)) {
+        $_SERVER['PHP_SELF'] = $drupal_base_url['path'] . '/index.php';
+      }
+      else {
+        $_SERVER['PHP_SELF'] = '/index.php';
+      }
+    }
+    else {
+      $_SERVER['HTTP_HOST'] = 'default';
+      $_SERVER['PHP_SELF'] = '/index.php';
+    }
+
+    $_SERVER['REQUEST_URI'] = $_SERVER['SCRIPT_NAME'] = $_SERVER['PHP_SELF'];
+    $_SERVER['REMOTE_ADDR'] = '127.0.0.1';
+    $_SERVER['REQUEST_METHOD']  = NULL;
+
+    $_SERVER['SERVER_SOFTWARE'] = NULL;
+    $_SERVER['HTTP_USER_AGENT'] = NULL;
+
+    $conf_path = conf_path(TRUE, TRUE);
+    $conf_file = $this->drupalRoot . "/$conf_path/settings.php";
+    if (!file_exists($conf_file)) {
+      throw new BootstrapException(sprintf('Could not find a Drupal settings.php file at "%s"', $conf_file));
+    }
+    $drushrc_file = $this->drupalRoot . "/$conf_path/drushrc.php";
+    if (file_exists($drushrc_file)) {
+      require_once $drushrc_file;
+    }
+  }
+
+  /**
+   * Expands properties on the given entity object to the expected structure.
+   *
+   * @param \stdClass $entity
+   *   The entity object.
+   */
+  protected function expandEntityProperties(\stdClass $entity) {
+    // The created field may come in as a readable date, rather than a
+    // timestamp.
+    if (isset($entity->created) && !is_numeric($entity->created)) {
+      $entity->created = strtotime($entity->created);
+    }
+
+    // Map human-readable node types to machine node types.
+    $types = node_get_types();
+    foreach ($types as $type) {
+      if ($entity->type == $type->name) {
+        $entity->type = $type->type;
+        continue;
+      }
+    }
+  }
+
+  /**
+   * Load vocabularies, optional by VIDs.
+   *
+   * @param array $vids
+   *   The vids to load.
+   *
+   * @return array
+   *   An array of vocabulary objects
+   */
+  protected function taxonomyVocabularyLoadMultiple($vids = array()) {
+    $vocabularies = taxonomy_get_vocabularies();
+    if ($vids) {
+      return array_intersect_key($vocabularies, array_flip($vids));
+    }
+    return $vocabularies;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function termCreate(\stdClass $term) {
+    // Map vocabulary names to vid, these take precedence over machine names.
+    if (!isset($term->vid)) {
+      $vocabularies = \taxonomy_get_vocabularies();
+      foreach ($vocabularies as $vid => $vocabulary) {
+        if ($vocabulary->name == $term->vocabulary_machine_name) {
+          $term->vid = $vocabulary->vid;
+        }
+      }
+    }
+
+    if (!isset($term->vid)) {
+
+      // Try to load vocabulary by machine name.
+      $vocabularies = $this->taxonomyVocabularyLoadMultiple(array($term->vid));
+      if (!empty($vocabularies)) {
+        $vids = array_keys($vocabularies);
+        $term->vid = reset($vids);
+      }
+    }
+
+    // If `parent` is set, look up a term in this vocab with that name.
+    if (isset($term->parent)) {
+      $parent = \taxonomy_get_term_by_name($term->parent);
+      if (!empty($parent)) {
+        $parent = reset($parent);
+        $term->parent = $parent->tid;
+      }
+    }
+
+    if (empty($term->vid)) {
+      throw new \Exception(sprintf('No "%s" vocabulary found.'));
+    }
+
+    // Attempt to decipher any fields that may be specified.
+    $this->expandEntityFields('taxonomy_term', $term);
+
+    // Protect against a failure from hook_taxonomy_term_insert() in pathauto.
+    $current_path = getcwd();
+    chdir(DRUPAL_ROOT);
+    $term_array = (array) $term;
+    \taxonomy_save_term($term_array);
+    chdir($current_path);
+
+    // Loading a term by name returns an array of term objects, but there should
+    // only be one matching term in a testing context, so take the first match
+    // by reset()'ing $matches.
+    $matches = \taxonomy_get_term_by_name($term->name);
+    $saved_term = reset($matches);
+
+    return $saved_term;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function termDelete(\stdClass $term) {
+    $status = 0;
+    if (isset($term->tid)) {
+      $status = \taxonomy_del_term($term->tid);
+    }
+    // Will be SAVED_DELETED (3) on success.
+    return $status;
+  }
+
+  /**
+   * Helper function to get all permissions.
+   *
+   * @return array
+   *   Array keyed by permission name, with the human-readable title as the
+   *   value.
+   */
+  protected function getAllPermissions() {
+    $permissions = array();
+    foreach (module_invoke_all('permission') as $name => $permission) {
+      $permissions[$name] = $permission['title'];
+    }
+    return $permissions;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getModuleList() {
+    return module_list();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getExtensionPathList() {
+    $paths = array();
+
+    // Get enabled modules.
+    $modules = $this->getModuleList();
+    foreach ($modules as $module) {
+      $paths[] = $this->drupalRoot . DIRECTORY_SEPARATOR . \drupal_get_path('module', $module);
+    }
+
+    return $paths;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function expandEntityFields($entity_type, \stdClass $entity) {
+    return parent::expandEntityFields($entity_type, $entity);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getEntityFieldTypes($entity_type) {
+    $taxonomy_fields = array('taxonomy' => 'taxonomy');
+    if (!module_exists('content')) {
+      return $taxonomy_fields;
+    }
+    $return = array();
+    $fields = content_fields();
+    foreach ($fields as $field_name => $field) {
+      if ($this->isField($entity_type, $field_name)) {
+        $return[$field_name] = $field['type'];
+      }
+    }
+
+    $return += $taxonomy_fields;
+
+    return $return;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isField($entity_type, $field_name) {
+    if ($field_name === 'taxonomy') {
+      return TRUE;
+    }
+    if (!module_exists('content')) {
+      return FALSE;
+    }
+    $map = content_fields();
+    return isset($map[$field_name]);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function languageCreate(\stdClass $language) {
+    throw new \Exception('Creating languages is not yet implemented for Drupal 6.');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function languageDelete(\stdClass $language) {
+    throw new \Exception('Deleting languages is not yet implemented for Drupal 6.');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function configGet($name, $key = '') {
+    throw new \Exception('Getting config is not yet implemented for Drupal 6.');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function configSet($name, $key, $value) {
+    throw new \Exception('Setting config is not yet implemented for Drupal 6.');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function clearStaticCaches() {
+    // Drupal 6 doesn't have a way of clearing all static caches.
+  }
+
+}
diff --git a/vendor/drupal/drupal-driver/src/Drupal/Driver/Cores/Drupal7.php b/vendor/drupal/drupal-driver/src/Drupal/Driver/Cores/Drupal7.php
new file mode 100644 (file)
index 0000000..3aa402c
--- /dev/null
@@ -0,0 +1,485 @@
+<?php
+
+namespace Drupal\Driver\Cores;
+
+use Drupal\Driver\Exception\BootstrapException;
+
+/**
+ * Drupal 7 core.
+ */
+class Drupal7 extends AbstractCore {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function bootstrap() {
+    // Validate, and prepare environment for Drupal bootstrap.
+    if (!defined('DRUPAL_ROOT')) {
+      define('DRUPAL_ROOT', $this->drupalRoot);
+      require_once DRUPAL_ROOT . '/includes/bootstrap.inc';
+      $this->validateDrupalSite();
+    }
+
+    // Bootstrap Drupal.
+    chdir(DRUPAL_ROOT);
+    drupal_bootstrap(DRUPAL_BOOTSTRAP_CONFIGURATION);
+    if (empty($GLOBALS['databases'])) {
+      throw new BootstrapException('Missing database setting, verify the database configuration in settings.php.');
+    }
+    drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function clearCache() {
+    drupal_flush_all_caches();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function nodeCreate($node) {
+    // Set original if not set.
+    if (!isset($node->original)) {
+      $node->original = clone $node;
+    }
+
+    // Assign authorship if none exists and `author` is passed.
+    if (!isset($node->uid) && !empty($node->author) && ($user = user_load_by_name($node->author))) {
+      $node->uid = $user->uid;
+    }
+
+    // Convert properties to expected structure.
+    $this->expandEntityProperties($node);
+
+    // Attempt to decipher any fields that may be specified.
+    $this->expandEntityFields('node', $node);
+
+    // Set defaults that haven't already been set.
+    $defaults = clone $node;
+    node_object_prepare($defaults);
+    $node = (object) array_merge((array) $defaults, (array) $node);
+
+    node_save($node);
+    return $node;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function nodeDelete($node) {
+    node_delete($node->nid);
+  }
+
+  /**
+   * Implements CoreInterface::runCron().
+   */
+  public function runCron() {
+    return drupal_cron_run();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function userCreate(\stdClass $user) {
+    // Default status to TRUE if not explicitly creating a blocked user.
+    if (!isset($user->status)) {
+      $user->status = 1;
+    }
+
+    // Clone user object, otherwise user_save() changes the password to the
+    // hashed password.
+    $account = clone $user;
+
+    // Attempt to decipher any fields that may be specified.
+    $this->expandEntityFields('user', $account);
+
+    user_save($account, (array) $account);
+
+    // Store UID.
+    $user->uid = $account->uid;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function userDelete(\stdClass $user) {
+    user_cancel(array(), $user->uid, 'user_cancel_delete');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function processBatch() {
+    $batch =& batch_get();
+    $batch['progressive'] = FALSE;
+    batch_process();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function userAddRole(\stdClass $user, $role_name) {
+    $role = user_role_load_by_name($role_name);
+
+    if (!$role) {
+      throw new \RuntimeException(sprintf('No role "%s" exists.', $role_name));
+    }
+
+    user_multiple_role_edit(array($user->uid), 'add_role', $role->rid);
+    $account = user_load($user->uid);
+    $user->roles = $account->roles;
+
+  }
+
+  /**
+   * Check to make sure that the array of permissions are valid.
+   *
+   * @param array $permissions
+   *   Permissions to check.
+   * @param bool $reset
+   *   Reset cached available permissions.
+   *
+   * @return bool
+   *   TRUE or FALSE depending on whether the permissions are valid.
+   */
+  protected function checkPermissions(array $permissions, $reset = FALSE) {
+    $available = &drupal_static(__FUNCTION__);
+
+    if (!isset($available) || $reset) {
+      $available = array_keys(module_invoke_all('permission'));
+    }
+
+    $valid = TRUE;
+    foreach ($permissions as $permission) {
+      if (!in_array($permission, $available)) {
+        $valid = FALSE;
+      }
+    }
+    return $valid;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function roleCreate(array $permissions) {
+
+    // Both machine name and permission title are allowed.
+    $all_permissions = $this->getAllPermissions();
+
+    foreach ($permissions as $key => $name) {
+      if (!isset($all_permissions[$name])) {
+        $search = array_search($name, $all_permissions);
+        if (!$search) {
+          throw new \RuntimeException(sprintf("No permission '%s' exists.", $name));
+        }
+        $permissions[$key] = $search;
+      }
+    }
+
+    // Create new role.
+    $role = new \stdClass();
+    $role->name = $this->random->name(8);
+    user_role_save($role);
+    user_role_grant_permissions($role->rid, $permissions);
+
+    if ($role && !empty($role->rid)) {
+      return $role->name;
+    }
+
+    throw new \RuntimeException(sprintf('Failed to create a role with "" permission(s).', implode(', ', $permissions)));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function roleDelete($role_name) {
+    $role = user_role_load_by_name($role_name);
+    user_role_delete((int) $role->rid);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function validateDrupalSite() {
+    if ('default' !== $this->uri) {
+      // Fake the necessary HTTP headers that Drupal needs:
+      $drupal_base_url = parse_url($this->uri);
+      // If there's no url scheme set, add http:// and re-parse the url
+      // so the host and path values are set accurately.
+      if (!array_key_exists('scheme', $drupal_base_url)) {
+        $drupal_base_url = parse_url($this->uri);
+      }
+      // Fill in defaults.
+      $drupal_base_url += array(
+        'path' => NULL,
+        'host' => NULL,
+        'port' => NULL,
+      );
+      $_SERVER['HTTP_HOST'] = $drupal_base_url['host'];
+
+      if ($drupal_base_url['port']) {
+        $_SERVER['HTTP_HOST'] .= ':' . $drupal_base_url['port'];
+      }
+      $_SERVER['SERVER_PORT'] = $drupal_base_url['port'];
+
+      if (array_key_exists('path', $drupal_base_url)) {
+        $_SERVER['PHP_SELF'] = $drupal_base_url['path'] . '/index.php';
+      }
+      else {
+        $_SERVER['PHP_SELF'] = '/index.php';
+      }
+    }
+    else {
+      $_SERVER['HTTP_HOST'] = 'default';
+      $_SERVER['PHP_SELF'] = '/index.php';
+    }
+
+    $_SERVER['REQUEST_URI'] = $_SERVER['SCRIPT_NAME'] = $_SERVER['PHP_SELF'];
+    $_SERVER['REMOTE_ADDR'] = '127.0.0.1';
+    $_SERVER['REQUEST_METHOD']  = NULL;
+
+    $_SERVER['SERVER_SOFTWARE'] = NULL;
+    $_SERVER['HTTP_USER_AGENT'] = NULL;
+
+    $conf_path = conf_path(TRUE, TRUE);
+    $conf_file = $this->drupalRoot . "/$conf_path/settings.php";
+    if (!file_exists($conf_file)) {
+      throw new BootstrapException(sprintf('Could not find a Drupal settings.php file at "%s"', $conf_file));
+    }
+    $drushrc_file = $this->drupalRoot . "/$conf_path/drushrc.php";
+    if (file_exists($drushrc_file)) {
+      require_once $drushrc_file;
+    }
+  }
+
+  /**
+   * Expands properties on the given entity object to the expected structure.
+   *
+   * @param \stdClass $entity
+   *   The entity object.
+   */
+  protected function expandEntityProperties(\stdClass $entity) {
+    // The created field may come in as a readable date, rather than a
+    // timestamp.
+    if (isset($entity->created) && !is_numeric($entity->created)) {
+      $entity->created = strtotime($entity->created);
+    }
+
+    // Map human-readable node types to machine node types.
+    $types = \node_type_get_types();
+    foreach ($types as $type) {
+      if ($entity->type == $type->name) {
+        $entity->type = $type->type;
+        continue;
+      }
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function termCreate(\stdClass $term) {
+    // Map vocabulary names to vid, these take precedence over machine names.
+    if (!isset($term->vid)) {
+      $vocabularies = \taxonomy_get_vocabularies();
+      foreach ($vocabularies as $vid => $vocabulary) {
+        if ($vocabulary->name == $term->vocabulary_machine_name) {
+          $term->vid = $vocabulary->vid;
+        }
+      }
+    }
+
+    if (!isset($term->vid)) {
+
+      // Try to load vocabulary by machine name.
+      $vocabularies = \taxonomy_vocabulary_load_multiple(FALSE, array(
+        'machine_name' => $term->vocabulary_machine_name,
+      ));
+      if (!empty($vocabularies)) {
+        $vids = array_keys($vocabularies);
+        $term->vid = reset($vids);
+      }
+    }
+
+    // If `parent` is set, look up a term in this vocab with that name.
+    if (isset($term->parent)) {
+      $parent = \taxonomy_get_term_by_name($term->parent, $term->vocabulary_machine_name);
+      if (!empty($parent)) {
+        $parent = reset($parent);
+        $term->parent = $parent->tid;
+      }
+    }
+
+    if (empty($term->vid)) {
+      throw new \Exception(sprintf('No "%s" vocabulary found.'));
+    }
+
+    // Attempt to decipher any fields that may be specified.
+    $this->expandEntityFields('taxonomy_term', $term);
+
+    \taxonomy_term_save($term);
+
+    return $term;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function termDelete(\stdClass $term) {
+    $status = 0;
+    if (isset($term->tid)) {
+      $status = \taxonomy_term_delete($term->tid);
+    }
+    // Will be SAVED_DELETED (3) on success.
+    return $status;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function languageCreate(\stdClass $language) {
+    if (!module_exists('locale')) {
+      throw new \Exception(sprintf("%s::%s line %s: This driver requires the 'locale' module be enabled in order to create languages", get_class($this), __FUNCTION__, __LINE__));
+    }
+    include_once DRUPAL_ROOT . '/includes/iso.inc';
+    include_once DRUPAL_ROOT . '/includes/locale.inc';
+
+    // Get all predefined languages, regardless if they are enabled or not.
+    $predefined_languages = _locale_get_predefined_list();
+
+    // If the language code is not valid then throw an InvalidArgumentException.
+    if (!isset($predefined_languages[$language->langcode])) {
+      throw new InvalidArgumentException("There is no predefined language with langcode '{$language->langcode}'.");
+    }
+
+    // Enable a language only if it has not been enabled already.
+    $enabled_languages = locale_language_list();
+    if (!isset($enabled_languages[$language->langcode])) {
+      locale_add_language($language->langcode);
+      return $language;
+    }
+
+    return FALSE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function languageDelete(\stdClass $language) {
+    $langcode = $language->langcode;
+    // Do not remove English or the default language.
+    if (!in_array($langcode, array(language_default('language'), 'en'))) {
+      // @see locale_languages_delete_form_submit().
+      $languages = language_list();
+      if (isset($languages[$langcode])) {
+        // Remove translations first.
+        db_delete('locales_target')
+          ->condition('language', $langcode)
+          ->execute();
+        cache_clear_all('locale:' . $langcode, 'cache');
+        // With no translations, this removes existing JavaScript translations
+        // file.
+        _locale_rebuild_js($langcode);
+        // Remove the language.
+        db_delete('languages')
+          ->condition('language', $langcode)
+          ->execute();
+        db_update('node')
+          ->fields(array('language' => ''))
+          ->condition('language', $langcode)
+          ->execute();
+        if ($languages[$langcode]->enabled) {
+          variable_set('language_count', variable_get('language_count', 1) - 1);
+        }
+        module_invoke_all('multilingual_settings_changed');
+        drupal_static_reset('language_list');
+      }
+
+      // Changing the language settings impacts the interface:
+      cache_clear_all('*', 'cache_page', TRUE);
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function configGet($name, $key = '') {
+    throw new \Exception('Getting config is not yet implemented for Drupal 7.');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function configSet($name, $key, $value) {
+    throw new \Exception('Setting config is not yet implemented for Drupal 7.');
+  }
+
+  /**
+   * Helper function to get all permissions.
+   *
+   * @return array
+   *   Array keyed by permission name, with the human-readable title as the
+   *   value.
+   */
+  protected function getAllPermissions() {
+    $permissions = array();
+    foreach (module_invoke_all('permission') as $name => $permission) {
+      $permissions[$name] = $permission['title'];
+    }
+    return $permissions;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getModuleList() {
+    return module_list();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getExtensionPathList() {
+    $paths = array();
+
+    // Get enabled modules.
+    $modules = $this->getModuleList();
+    foreach ($modules as $module) {
+      $paths[] = $this->drupalRoot . DIRECTORY_SEPARATOR . \drupal_get_path('module', $module);
+    }
+
+    return $paths;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getEntityFieldTypes($entity_type) {
+    $return = array();
+    $fields = field_info_field_map();
+    foreach ($fields as $field_name => $field) {
+      if (array_key_exists($entity_type, $field['bundles'])) {
+        $return[$field_name] = $field['type'];
+      }
+    }
+    return $return;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isField($entity_type, $field_name) {
+    $map = field_info_field_map();
+    return !empty($map[$field_name]) && array_key_exists($entity_type, $map[$field_name]['bundles']);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function clearStaticCaches() {
+    drupal_static_reset();
+  }
+
+}
diff --git a/vendor/drupal/drupal-driver/src/Drupal/Driver/Cores/Drupal8.php b/vendor/drupal/drupal-driver/src/Drupal/Driver/Cores/Drupal8.php
new file mode 100644 (file)
index 0000000..c1cd9ab
--- /dev/null
@@ -0,0 +1,423 @@
+<?php
+
+namespace Drupal\Driver\Cores;
+
+use Drupal\Core\DrupalKernel;
+use Drupal\Driver\Exception\BootstrapException;
+use Drupal\field\Entity\FieldStorageConfig;
+use Drupal\language\Entity\ConfigurableLanguage;
+use Drupal\node\Entity\Node;
+use Drupal\node\NodeInterface;
+use Drupal\taxonomy\Entity\Term;
+use Drupal\taxonomy\TermInterface;
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * Drupal 8 core.
+ */
+class Drupal8 extends AbstractCore {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function bootstrap() {
+    // Validate, and prepare environment for Drupal bootstrap.
+    if (!defined('DRUPAL_ROOT')) {
+      define('DRUPAL_ROOT', $this->drupalRoot);
+    }
+
+    // Bootstrap Drupal.
+    chdir(DRUPAL_ROOT);
+    $autoloader = require DRUPAL_ROOT . '/autoload.php';
+    require_once DRUPAL_ROOT . '/core/includes/bootstrap.inc';
+    $this->validateDrupalSite();
+
+    $request = Request::createFromGlobals();
+    $kernel = DrupalKernel::createFromRequest($request, $autoloader, 'prod');
+    $kernel->boot();
+    $kernel->prepareLegacyRequest($request);
+
+    // Initialise an anonymous session. required for the bootstrap.
+    \Drupal::service('session_manager')->start();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function clearCache() {
+    // Need to change into the Drupal root directory or the registry explodes.
+    drupal_flush_all_caches();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function nodeCreate($node) {
+    // Throw an exception if the node type is missing or does not exist.
+    if (!isset($node->type) || !$node->type) {
+      throw new \Exception("Cannot create content because it is missing the required property 'type'.");
+    }
+    $bundles = \Drupal::entityManager()->getBundleInfo('node');
+    if (!in_array($node->type, array_keys($bundles))) {
+      throw new \Exception("Cannot create content because provided content type '$node->type' does not exist.");
+    }
+    // Default status to 1 if not set.
+    if (!isset($node->status)) {
+      $node->status = 1;
+    }
+    // If 'author' is set, remap it to 'uid'.
+    if (isset($node->author)) {
+      $user = user_load_by_name($node->author);
+      if ($user) {
+        $node->uid = $user->id();
+      }
+    }
+    $this->expandEntityFields('node', $node);
+    $entity = entity_create('node', (array) $node);
+    $entity->save();
+
+    $node->nid = $entity->id();
+
+    return $node;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function nodeDelete($node) {
+    $node = $node instanceof NodeInterface ? $node : Node::load($node->nid);
+    if ($node instanceof NodeInterface) {
+      $node->delete();
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function runCron() {
+    return \Drupal::service('cron')->run();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function userCreate(\stdClass $user) {
+    $this->validateDrupalSite();
+
+    // Default status to TRUE if not explicitly creating a blocked user.
+    if (!isset($user->status)) {
+      $user->status = 1;
+    }
+
+    // Clone user object, otherwise user_save() changes the password to the
+    // hashed password.
+    $this->expandEntityFields('user', $user);
+    $account = entity_create('user', (array) $user);
+    $account->save();
+
+    // Store UID.
+    $user->uid = $account->id();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function roleCreate(array $permissions) {
+    // Generate a random, lowercase machine name.
+    $rid = strtolower($this->random->name(8, TRUE));
+
+    // Generate a random label.
+    $name = trim($this->random->name(8, TRUE));
+
+    // Convert labels to machine names.
+    $this->convertPermissions($permissions);
+
+    // Check the all the permissions strings are valid.
+    $this->checkPermissions($permissions);
+
+    // Create new role.
+    $role = entity_create('user_role', array(
+      'id' => $rid,
+      'label' => $name,
+    ));
+    $result = $role->save();
+
+    if ($result === SAVED_NEW) {
+      // Grant the specified permissions to the role, if any.
+      if (!empty($permissions)) {
+        user_role_grant_permissions($role->id(), $permissions);
+      }
+      return $role->id();
+    }
+
+    throw new \RuntimeException(sprintf('Failed to create a role with "%s" permission(s).', implode(', ', $permissions)));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function roleDelete($role_name) {
+    $role = user_role_load($role_name);
+
+    if (!$role) {
+      throw new \RuntimeException(sprintf('No role "%s" exists.', $role_name));
+    }
+
+    $role->delete();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function processBatch() {
+    $this->validateDrupalSite();
+    $batch =& batch_get();
+    $batch['progressive'] = FALSE;
+    batch_process();
+  }
+
+  /**
+   * Retrieve all permissions.
+   *
+   * @return array
+   *   Array of all defined permissions.
+   */
+  protected function getAllPermissions() {
+    $permissions = &drupal_static(__FUNCTION__);
+
+    if (!isset($permissions)) {
+      $permissions = \Drupal::service('user.permissions')->getPermissions();
+    }
+
+    return $permissions;
+  }
+
+  /**
+   * Convert any permission labels to machine name.
+   *
+   * @param array &$permissions
+   *   Array of permission names.
+   */
+  protected function convertPermissions(array &$permissions) {
+    $all_permissions = $this->getAllPermissions();
+
+    foreach ($all_permissions as $name => $definition) {
+      $key = array_search($definition['title'], $permissions);
+      if (FALSE !== $key) {
+        $permissions[$key] = $name;
+      }
+    }
+  }
+
+  /**
+   * Check to make sure that the array of permissions are valid.
+   *
+   * @param array $permissions
+   *   Permissions to check.
+   */
+  protected function checkPermissions(array &$permissions) {
+    $available = array_keys($this->getAllPermissions());
+
+    foreach ($permissions as $permission) {
+      if (!in_array($permission, $available)) {
+        throw new \RuntimeException(sprintf('Invalid permission "%s".', $permission));
+      }
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function userDelete(\stdClass $user) {
+    user_cancel(array(), $user->uid, 'user_cancel_delete');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function userAddRole(\stdClass $user, $role_name) {
+    // Allow both machine and human role names.
+    $roles = user_role_names();
+    $id = array_search($role_name, $roles);
+    if (FALSE !== $id) {
+      $role_name = $id;
+    }
+
+    if (!$role = user_role_load($role_name)) {
+      throw new \RuntimeException(sprintf('No role "%s" exists.', $role_name));
+    }
+
+    $account = \user_load($user->uid);
+    $account->addRole($role->id());
+    $account->save();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function validateDrupalSite() {
+    if ('default' !== $this->uri) {
+      // Fake the necessary HTTP headers that Drupal needs:
+      $drupal_base_url = parse_url($this->uri);
+      // If there's no url scheme set, add http:// and re-parse the url
+      // so the host and path values are set accurately.
+      if (!array_key_exists('scheme', $drupal_base_url)) {
+        $drupal_base_url = parse_url($this->uri);
+      }
+      // Fill in defaults.
+      $drupal_base_url += array(
+        'path' => NULL,
+        'host' => NULL,
+        'port' => NULL,
+      );
+      $_SERVER['HTTP_HOST'] = $drupal_base_url['host'];
+
+      if ($drupal_base_url['port']) {
+        $_SERVER['HTTP_HOST'] .= ':' . $drupal_base_url['port'];
+      }
+      $_SERVER['SERVER_PORT'] = $drupal_base_url['port'];
+
+      if (array_key_exists('path', $drupal_base_url)) {
+        $_SERVER['PHP_SELF'] = $drupal_base_url['path'] . '/index.php';
+      }
+      else {
+        $_SERVER['PHP_SELF'] = '/index.php';
+      }
+    }
+    else {
+      $_SERVER['HTTP_HOST'] = 'default';
+      $_SERVER['PHP_SELF'] = '/index.php';
+    }
+
+    $_SERVER['REQUEST_URI'] = $_SERVER['SCRIPT_NAME'] = $_SERVER['PHP_SELF'];
+    $_SERVER['REMOTE_ADDR'] = '127.0.0.1';
+    $_SERVER['REQUEST_METHOD']  = NULL;
+
+    $_SERVER['SERVER_SOFTWARE'] = NULL;
+    $_SERVER['HTTP_USER_AGENT'] = NULL;
+
+    $conf_path = DrupalKernel::findSitePath(Request::createFromGlobals());
+    $conf_file = $this->drupalRoot . "/$conf_path/settings.php";
+    if (!file_exists($conf_file)) {
+      throw new BootstrapException(sprintf('Could not find a Drupal settings.php file at "%s"', $conf_file));
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function termCreate(\stdClass $term) {
+    $term->vid = $term->vocabulary_machine_name;
+    $this->expandEntityFields('taxonomy_term', $term);
+    $entity = Term::create((array) $term);
+    $entity->save();
+
+    $term->tid = $entity->id();
+    return $term;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function termDelete(\stdClass $term) {
+    $term = $term instanceof TermInterface ? $term : Term::load($term->tid);
+    if ($term instanceof TermInterface) {
+      $term->delete();
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getModuleList() {
+    return array_keys(\Drupal::moduleHandler()->getModuleList());
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getExtensionPathList() {
+    $paths = array();
+
+    // Get enabled modules.
+    foreach (\Drupal::moduleHandler()->getModuleList() as $module) {
+      $paths[] = $this->drupalRoot . DIRECTORY_SEPARATOR . $module->getPath();
+    }
+
+    return $paths;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getEntityFieldTypes($entity_type) {
+    $return = array();
+    $fields = \Drupal::entityManager()->getFieldStorageDefinitions($entity_type);
+    foreach ($fields as $field_name => $field) {
+      if ($this->isField($entity_type, $field_name)) {
+        $return[$field_name] = $field->getType();
+      }
+    }
+    return $return;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isField($entity_type, $field_name) {
+    $fields = \Drupal::entityManager()->getFieldStorageDefinitions($entity_type);
+    return (isset($fields[$field_name]) && $fields[$field_name] instanceof FieldStorageConfig);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function languageCreate(\stdClass $language) {
+    $langcode = $language->langcode;
+
+    // Enable a language only if it has not been enabled already.
+    if (!ConfigurableLanguage::load($langcode)) {
+      $created_language = ConfigurableLanguage::createFromLangcode($language->langcode);
+      if (!$created_language) {
+        throw new InvalidArgumentException("There is no predefined language with langcode '{$langcode}'.");
+      }
+      $created_language->save();
+      return $language;
+    }
+
+    return FALSE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function languageDelete(\stdClass $language) {
+    $configurable_language = ConfigurableLanguage::load($language->langcode);
+    $configurable_language->delete();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function clearStaticCaches() {
+    drupal_static_reset();
+    \Drupal::service('cache_tags.invalidator')->resetChecksums();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function configGet($name, $key = '') {
+    return \Drupal::config($name)->get($key);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function configSet($name, $key, $value) {
+    \Drupal::configFactory()->getEditable($name)
+      ->set($key, $value)
+      ->save();
+  }
+
+}
diff --git a/vendor/drupal/drupal-driver/src/Drupal/Driver/DriverInterface.php b/vendor/drupal/drupal-driver/src/Drupal/Driver/DriverInterface.php
new file mode 100644 (file)
index 0000000..5bbafb5
--- /dev/null
@@ -0,0 +1,181 @@
+<?php
+
+namespace Drupal\Driver;
+
+/**
+ * Driver interface.
+ */
+interface DriverInterface {
+
+  /**
+   * Returns a random generator.
+   */
+  public function getRandom();
+
+  /**
+   * Bootstraps operations, as needed.
+   */
+  public function bootstrap();
+
+  /**
+   * Determines if the driver has been bootstrapped.
+   */
+  public function isBootstrapped();
+
+  /**
+   * Creates a user.
+   */
+  public function userCreate(\stdClass $user);
+
+  /**
+   * Deletes a user.
+   */
+  public function userDelete(\stdClass $user);
+
+  /**
+   * Processes a batch of actions.
+   */
+  public function processBatch();
+
+  /**
+   * Adds a role for a user.
+   *
+   * @param \stdClass $user
+   *   A user object.
+   * @param string $role
+   *   The role name to assign.
+   */
+  public function userAddRole(\stdClass $user, $role);
+
+  /**
+   * Retrieves watchdog entries.
+   *
+   * @param int $count
+   *   Number of entries to retrieve.
+   * @param string $type
+   *   Filter by watchdog type.
+   * @param string $severity
+   *   Filter by watchdog severity level.
+   *
+   * @return string
+   *   Watchdog output.
+   */
+  public function fetchWatchdog($count = 10, $type = NULL, $severity = NULL);
+
+  /**
+   * Clears Drupal caches.
+   *
+   * @param string $type
+   *   Type of cache to clear defaults to all.
+   */
+  public function clearCache($type = NULL);
+
+  /**
+   * Clears static Drupal caches.
+   */
+  public function clearStaticCaches();
+
+  /**
+   * Creates a node.
+   *
+   * @param object $node
+   *   Fully loaded node object.
+   *
+   * @return object
+   *   The node object including the node ID in the case of new nodes.
+   */
+  public function createNode($node);
+
+  /**
+   * Deletes a node.
+   *
+   * @param object $node
+   *   Fully loaded node object.
+   */
+  public function nodeDelete($node);
+
+  /**
+   * Runs cron.
+   */
+  public function runCron();
+
+  /**
+   * Creates a taxonomy term.
+   *
+   * @param \stdClass $term
+   *   Term object.
+   *
+   * @return object
+   *   The term object including the term ID in the case of new terms.
+   */
+  public function createTerm(\stdClass $term);
+
+  /**
+   * Deletes a taxonomy term.
+   *
+   * @param \stdClass $term
+   *   Term object to delete.
+   *
+   * @return bool
+   *   Status constant indicating deletion.
+   */
+  public function termDelete(\stdClass $term);
+
+  /**
+   * Creates a role.
+   *
+   * @param array $permissions
+   *   An array of permissions to create the role with.
+   *
+   * @return string
+   *   Role name of newly created role.
+   */
+  public function roleCreate(array $permissions);
+
+  /**
+   * Deletes a role.
+   *
+   * @param string $rid
+   *   A role name to delete.
+   */
+  public function roleDelete($rid);
+
+  /**
+   * Check if the specified field is an actual Drupal field.
+   *
+   * @param string $entity_type
+   *   The entity type to which the field should belong.
+   * @param string $field_name
+   *   The name of the field.
+   *
+   * @return bool
+   *   TRUE if the field exists in the entity type, FALSE if not.
+   */
+  public function isField($entity_type, $field_name);
+
+  /**
+   * Returns a configuration item.
+   *
+   * @param string $name
+   *   The name of the configuration object to retrieve.
+   * @param string $key
+   *   A string that maps to a key within the configuration data.
+   *
+   * @return mixed
+   *   The data that was requested.
+   */
+  public function configGet($name, $key);
+
+  /**
+   * Sets a value in a configuration object.
+   *
+   * @param string $name
+   *   The name of the configuration object.
+   * @param string $key
+   *   Identifier to store value in configuration.
+   * @param mixed $value
+   *   Value to associate with identifier.
+   */
+  public function configSet($name, $key, $value);
+
+}
diff --git a/vendor/drupal/drupal-driver/src/Drupal/Driver/DrupalDriver.php b/vendor/drupal/drupal-driver/src/Drupal/Driver/DrupalDriver.php
new file mode 100644 (file)
index 0000000..7764b55
--- /dev/null
@@ -0,0 +1,322 @@
+<?php
+
+namespace Drupal\Driver;
+
+use Drupal\Driver\Exception\BootstrapException;
+
+use Behat\Behat\Tester\Exception\PendingException;
+
+/**
+ * Fully bootstraps Drupal and uses native API calls.
+ */
+class DrupalDriver implements DriverInterface, SubDriverFinderInterface {
+
+  /**
+   * Track whether Drupal has been bootstrapped.
+   *
+   * @var bool
+   */
+  private $bootstrapped = FALSE;
+
+  /**
+   * Drupal core object.
+   *
+   * @var \Drupal\Driver\Cores\CoreInterface
+   */
+  public $core;
+
+  /**
+   * System path to the Drupal installation.
+   *
+   * @var string
+   */
+  private $drupalRoot;
+
+  /**
+   * URI for the Drupal installation.
+   *
+   * @var string
+   */
+  private $uri;
+
+  /**
+   * Drupal core version.
+   *
+   * @var integer
+   */
+  public $version;
+
+  /**
+   * Set Drupal root and URI.
+   *
+   * @param string $drupal_root
+   *   The Drupal root path.
+   * @param string $uri
+   *   The URI for the Drupal installation.
+   *
+   * @throws BootstrapException
+   *   Thrown when the Drupal installation is not found in the given root path.
+   */
+  public function __construct($drupal_root, $uri) {
+    $this->drupalRoot = realpath($drupal_root);
+    if (!$this->drupalRoot) {
+      throw new BootstrapException(sprintf('No Drupal installation found at %s', $drupal_root));
+    }
+    $this->uri = $uri;
+    $this->version = $this->getDrupalVersion();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getRandom() {
+    return $this->getCore()->getRandom();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function bootstrap() {
+    $this->getCore()->bootstrap();
+    $this->bootstrapped = TRUE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isBootstrapped() {
+    // Assume the blackbox is always bootstrapped.
+    return $this->bootstrapped;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function userCreate(\stdClass $user) {
+    $this->getCore()->userCreate($user);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function userDelete(\stdClass $user) {
+    $this->getCore()->userDelete($user);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function processBatch() {
+    $this->getCore()->processBatch();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function userAddRole(\stdClass $user, $role_name) {
+    $this->getCore()->userAddRole($user, $role_name);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function fetchWatchdog($count = 10, $type = NULL, $severity = NULL) {
+    throw new PendingException(sprintf('Currently no ability to access watchdog entries in %s', $this));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function clearCache($type = NULL) {
+    $this->getCore()->clearCache();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getSubDriverPaths() {
+    // Ensure system is bootstrapped.
+    if (!$this->isBootstrapped()) {
+      $this->bootstrap();
+    }
+
+    return $this->getCore()->getExtensionPathList();
+  }
+
+  /**
+   * Determine major Drupal version.
+   *
+   * @return int
+   *   The major Drupal version.
+   *
+   * @throws \Drupal\Driver\Exception\BootstrapException
+   *   Thrown when the Drupal version could not be determined.
+   *
+   * @see drush_drupal_version()
+   */
+  public function getDrupalVersion() {
+    if (!isset($this->version)) {
+      // Support 6, 7 and 8.
+      $version_constant_paths = array(
+        // Drupal 6.
+        '/modules/system/system.module',
+        // Drupal 7.
+        '/includes/bootstrap.inc',
+        // Drupal 8.
+        '/autoload.php',
+        '/core/includes/bootstrap.inc',
+      );
+
+      if ($this->drupalRoot === FALSE) {
+        throw new BootstrapException('`drupal_root` parameter must be defined.');
+      }
+
+      foreach ($version_constant_paths as $path) {
+        if (file_exists($this->drupalRoot . $path)) {
+          require_once $this->drupalRoot . $path;
+        }
+      }
+      if (defined('VERSION')) {
+        $version = VERSION;
+      }
+      elseif (defined('\Drupal::VERSION')) {
+        $version = \Drupal::VERSION;
+      }
+      else {
+        throw new BootstrapException('Unable to determine Drupal core version. Supported versions are 6, 7, and 8.');
+      }
+
+      // Extract the major version from VERSION.
+      $version_parts = explode('.', $version);
+      if (is_numeric($version_parts[0])) {
+        $this->version = (integer) $version_parts[0];
+      }
+      else {
+        throw new BootstrapException(sprintf('Unable to extract major Drupal core version from version string %s.', $version));
+      }
+    }
+    return $this->version;
+  }
+
+  /**
+   * Instantiate and set Drupal core class.
+   *
+   * @param array $available_cores
+   *   A major-version-keyed array of available core controllers.
+   */
+  public function setCore(array $available_cores) {
+    if (!isset($available_cores[$this->version])) {
+      throw new BootstrapException(sprintf('There is no available Drupal core controller for Drupal version %s.', $this->version));
+    }
+    $this->core = $available_cores[$this->version];
+  }
+
+  /**
+   * Automatically set the core from the current version.
+   */
+  public function setCoreFromVersion() {
+    $core = '\Drupal\Driver\Cores\Drupal' . $this->getDrupalVersion();
+    $this->core = new $core($this->drupalRoot, $this->uri);
+  }
+
+  /**
+   * Return current core.
+   */
+  public function getCore() {
+    return $this->core;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function createNode($node) {
+    return $this->getCore()->nodeCreate($node);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function nodeDelete($node) {
+    return $this->getCore()->nodeDelete($node);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function runCron() {
+    if (!$this->getCore()->runCron()) {
+      throw new \Exception('Failed to run cron.');
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function createTerm(\stdClass $term) {
+    return $this->getCore()->termCreate($term);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function termDelete(\stdClass $term) {
+    return $this->getCore()->termDelete($term);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function roleCreate(array $permissions) {
+    return $this->getCore()->roleCreate($permissions);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function roleDelete($rid) {
+    $this->getCore()->roleDelete($rid);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isField($entity_type, $field_name) {
+    return $this->getCore()->isField($entity_type, $field_name);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function languageCreate($language) {
+    return $this->getCore()->languageCreate($language);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function languageDelete($language) {
+    $this->getCore()->languageDelete($language);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function configGet($name, $key) {
+    return $this->getCore()->configGet($name, $key);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function configSet($name, $key, $value) {
+    $this->getCore()->configSet($name, $key, $value);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function clearStaticCaches() {
+    $this->getCore()->clearStaticCaches();
+  }
+
+}
diff --git a/vendor/drupal/drupal-driver/src/Drupal/Driver/DrushDriver.php b/vendor/drupal/drupal-driver/src/Drupal/Driver/DrushDriver.php
new file mode 100644 (file)
index 0000000..a51ec51
--- /dev/null
@@ -0,0 +1,354 @@
+<?php
+
+namespace Drupal\Driver;
+
+use Drupal\Component\Utility\Random;
+use Drupal\Driver\Exception\BootstrapException;
+
+use Symfony\Component\Process\Process;
+
+/**
+ * Implements DriverInterface.
+ */
+class DrushDriver extends BaseDriver {
+  /**
+   * Store a drush alias for tests requiring shell access.
+   *
+   * @var string
+   */
+  public $alias;
+
+  /**
+   * Stores the root path to a Drupal installation.
+   *
+   * This is an alternative to using drush aliases.
+   *
+   * @var string
+   */
+  public $root;
+
+  /**
+   * Store the path to drush binary.
+   *
+   * @var string
+   */
+  public $binary;
+
+  /**
+   * Track bootstrapping.
+   */
+  private $bootstrapped = FALSE;
+
+  /**
+   * Random generator.
+   *
+   * @var \Drupal\Component\Utility\Random
+   */
+  private $random;
+
+  /**
+   * Global arguments or options for drush commands.
+   *
+   * @var string
+   */
+  private $arguments = '';
+
+  /**
+   * Set drush alias or root path.
+   *
+   * @param string $alias
+   *   A drush alias.
+   * @param string $root_path
+   *   The root path of the Drupal install. This is an alternative to using
+   *   aliases.
+   * @param string $binary
+   *   The path to the drush binary.
+   * @param \Drupal\Component\Utility\Random $random
+   *   Random generator.
+   *
+   * @throws \Drupal\Driver\Exception\BootstrapException
+   *   Thrown when a required parameter is missing.
+   */
+  public function __construct($alias = NULL, $root_path = NULL, $binary = 'drush', Random $random = NULL) {
+    if (!empty($alias)) {
+      // Trim off the '@' symbol if it has been added.
+      $alias = ltrim($alias, '@');
+
+      $this->alias = $alias;
+    }
+    elseif (!empty($root_path)) {
+      $this->root = realpath($root_path);
+    }
+    else {
+      throw new BootstrapException('A drush alias or root path is required.');
+    }
+
+    $this->binary = $binary;
+
+    if (!isset($random)) {
+      $random = new Random();
+    }
+    $this->random = $random;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getRandom() {
+    return $this->random;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function bootstrap() {
+    // Check that the given alias works.
+    // @todo check that this is a functioning alias.
+    // See http://drupal.org/node/1615450
+    if (!isset($this->alias) && !isset($this->root)) {
+      throw new BootstrapException('A drush alias or root path is required.');
+    }
+    $this->bootstrapped = TRUE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isBootstrapped() {
+    return $this->bootstrapped;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function userCreate(\stdClass $user) {
+    $arguments = array(
+      sprintf('"%s"', $user->name),
+    );
+    $options = array(
+      'password' => $user->pass,
+      'mail' => $user->mail,
+    );
+    $this->drush('user-create', $arguments, $options);
+    if (isset($user->roles) && is_array($user->roles)) {
+      foreach ($user->roles as $role) {
+        $this->userAddRole($user, $role);
+      }
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function userDelete(\stdClass $user) {
+    $arguments = array(sprintf('"%s"', $user->name));
+    $options = array(
+      'yes' => NULL,
+      'delete-content' => NULL,
+    );
+    $this->drush('user-cancel', $arguments, $options);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function userAddRole(\stdClass $user, $role) {
+    $arguments = array(
+      sprintf('"%s"', $role),
+      sprintf('"%s"', $user->name),
+    );
+    $this->drush('user-add-role', $arguments);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function fetchWatchdog($count = 10, $type = NULL, $severity = NULL) {
+    $options = array(
+      'count' => $count,
+      'type' => $type,
+      'severity' => $severity,
+    );
+    return $this->drush('watchdog-show', array(), $options);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function clearCache($type = 'all') {
+    $type = array($type);
+    return $this->drush('cache-clear', $type, array());
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function clearStaticCaches() {
+    // The drush driver does each operation as a separate request;
+    // therefore, 'clearStaticCaches' can be a no-op.
+  }
+
+  /**
+   * Decodes JSON object returned by Drush.
+   *
+   * It will clean up any junk that may have appeared before or after the
+   * JSON object. This can happen with remote Drush aliases.
+   *
+   * @param string $output
+   *   The output from Drush.
+   * @return object
+   *   The decoded JSON object.
+   */
+  protected function decodeJsonObject($output) {
+    // Remove anything before the first '{'.
+    $output = preg_replace('/^[^\{]*/', '', $output);
+    // Remove anything after the last '}'.
+    $output = preg_replace('/[^\}]*$/s', '', $output);
+    return json_decode($output);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function createNode($node) {
+    $result = $this->drush('behat', array('create-node', escapeshellarg(json_encode($node))), array());
+    return $this->decodeJsonObject($result);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function nodeDelete($node) {
+    $this->drush('behat', array('delete-node', escapeshellarg(json_encode($node))), array());
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function createTerm(\stdClass $term) {
+    $result = $this->drush('behat', array('create-term', escapeshellarg(json_encode($term))), array());
+    return $this->decodeJsonObject($result);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function termDelete(\stdClass $term) {
+    $this->drush('behat', array('delete-term', escapeshellarg(json_encode($term))), array());
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isField($entity_type, $field_name) {
+    // If the Behat Drush Endpoint is not installed on the site-under-test,
+    // then the drush() method will throw an exception. In this instance, we
+    // want to treat all potential fields as non-fields.  This allows the
+    // Drush Driver to work with certain built-in Drush capabilities (e.g.
+    // creating users) even if the Behat Drush Endpoint is not available.
+    try {
+      $result = $this->drush('behat', array('is-field', escapeshellarg(json_encode(array($entity_type, $field_name)))), array());
+      return strpos($result, "true\n") !== FALSE;
+    }
+    catch (\Exception $e) {
+      return FALSE;
+    }
+  }
+
+  /**
+   * Sets common drush arguments or options.
+   *
+   * @param string $arguments
+   *   Global arguments to add to every drush command.
+   */
+  public function setArguments($arguments) {
+    $this->arguments = $arguments;
+  }
+
+  /**
+   * Get common drush arguments.
+   */
+  public function getArguments() {
+    return $this->arguments;
+  }
+
+  /**
+   * Parse arguments into a string.
+   *
+   * @param array $arguments
+   *   An array of argument/option names to values.
+   *
+   * @return string
+   *   The parsed arguments.
+   */
+  protected static function parseArguments(array $arguments) {
+    $string = '';
+    foreach ($arguments as $name => $value) {
+      if (is_null($value)) {
+        $string .= ' --' . $name;
+      }
+      else {
+        $string .= ' --' . $name . '=' . $value;
+      }
+    }
+    return $string;
+  }
+
+  /**
+   * Execute a drush command.
+   */
+  public function drush($command, array $arguments = array(), array $options = array()) {
+    $arguments = implode(' ', $arguments);
+
+    // Disable colored output from drush.
+    $options['nocolor'] = TRUE;
+    $string_options = $this->parseArguments($options);
+
+    $alias = isset($this->alias) ? "@{$this->alias}" : '--root=' . $this->root;
+
+    // Add any global arguments.
+    $global = $this->getArguments();
+
+    $process = new Process("{$this->binary} {$alias} {$string_options} {$global} {$command} {$arguments}");
+    $process->setTimeout(3600);
+    $process->run();
+
+    if (!$process->isSuccessful()) {
+      throw new \RuntimeException($process->getErrorOutput());
+    }
+
+    // Some drush commands write to standard error output (for example enable
+    // use drush_log which default to _drush_print_log) instead of returning a
+    // string (drush status use drush_print_pipe).
+    if (!$process->getOutput()) {
+      return $process->getErrorOutput();
+    }
+    else {
+      return $process->getOutput();
+    }
+
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function processBatch() {
+    // Do nothing. Drush should internally handle any needs for processing
+    // batch ops.
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function runCron() {
+    $this->drush('cron');
+  }
+
+  /**
+   * Run Drush commands dynamically from a DrupalContext.
+   */
+  public function __call($name, $arguments) {
+    return $this->drush($name, $arguments);
+  }
+
+}
diff --git a/vendor/drupal/drupal-driver/src/Drupal/Driver/Exception/BootstrapException.php b/vendor/drupal/drupal-driver/src/Drupal/Driver/Exception/BootstrapException.php
new file mode 100644 (file)
index 0000000..0ac7a1d
--- /dev/null
@@ -0,0 +1,24 @@
+<?php
+
+namespace Drupal\Driver\Exception;
+
+/**
+ * Bootstrap exception.
+ */
+class BootstrapException extends Exception {
+
+  /**
+   * Initializes exception.
+   *
+   * @param string $message
+   *   The exception message.
+   * @param int $code
+   *   Optional exception code. Defaults to 0.
+   * @param \Exception $previous
+   *   Optional previous exception that was thrown.
+   */
+  public function __construct($message, $code = 0, \Exception $previous = NULL) {
+    parent::__construct($message, NULL, $code, $previous);
+  }
+
+}
diff --git a/vendor/drupal/drupal-driver/src/Drupal/Driver/Exception/Exception.php b/vendor/drupal/drupal-driver/src/Drupal/Driver/Exception/Exception.php
new file mode 100644 (file)
index 0000000..b8b76a8
--- /dev/null
@@ -0,0 +1,41 @@
+<?php
+
+namespace Drupal\Driver\Exception;
+
+use Drupal\Driver\DriverInterface;
+
+/**
+ * Drupal driver manager base exception class.
+ */
+abstract class Exception extends \Exception {
+  private $driver;
+
+  /**
+   * Initializes Drupal driver manager exception.
+   *
+   * @param string $message
+   *   The exception message.
+   * @param DriverInterface $driver
+   *   The driver where the exception occurred.
+   * @param int $code
+   *   Optional exception code. Defaults to 0.
+   * @param \Exception $previous
+   *   Optional previous exception that was thrown.
+   */
+  public function __construct($message, DriverInterface $driver = NULL, $code = 0, \Exception $previous = NULL) {
+    $this->driver = $driver;
+
+    parent::__construct($message, $code, $previous);
+  }
+
+  /**
+   * Returns exception session.
+   *
+   * @return Session
+   *   The exception session.
+   */
+  public function getDriver() {
+    return $this->driver;
+  }
+
+}
diff --git a/vendor/drupal/drupal-driver/src/Drupal/Driver/Exception/UnsupportedDriverActionException.php b/vendor/drupal/drupal-driver/src/Drupal/Driver/Exception/UnsupportedDriverActionException.php
new file mode 100644 (file)
index 0000000..7e2ce40
--- /dev/null
@@ -0,0 +1,30 @@
+<?php
+
+namespace Drupal\Driver\Exception;
+
+use Drupal\Driver\DriverInterface;
+
+/**
+ * Unsupported driver action.
+ */
+class UnsupportedDriverActionException extends Exception {
+
+  /**
+   * Initializes exception.
+   *
+   * @param string $template
+   *   What is unsupported?
+   * @param DriverInterface $driver
+   *   Driver instance.
+   * @param int $code
+   *   The exception code.
+   * @param \Exception $previous
+   *   Previous exception.
+   */
+  public function __construct($template, DriverInterface $driver, $code = 0, \Exception $previous = NULL) {
+    $message = sprintf($template, get_class($driver));
+
+    parent::__construct($message, $driver, $code, $previous);
+  }
+
+}
diff --git a/vendor/drupal/drupal-driver/src/Drupal/Driver/Fields/Drupal6/TaxonomyHandler.php b/vendor/drupal/drupal-driver/src/Drupal/Driver/Fields/Drupal6/TaxonomyHandler.php
new file mode 100644 (file)
index 0000000..8fbac6f
--- /dev/null
@@ -0,0 +1,40 @@
+<?php
+
+namespace Drupal\Driver\Fields\Drupal6;
+
+use Drupal\Driver\Fields\FieldHandlerInterface;
+
+/**
+ * Provides a custom field handler to make it easier to include taxonomy terms.
+ */
+class TaxonomyHandler implements FieldHandlerInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function expand($values) {
+    $result = array();
+    $values = (array) $values;
+    foreach ($values as $entry) {
+      $terms = explode(',', $entry);
+      foreach ($terms as $term) {
+        // Try to split things out in order to find optional specified vocabs.
+        $term_name_or_tid = '';
+        $parts = explode(':', $term);
+        if (count($parts) == 1) {
+          $term_name_or_tid = $term;
+        }
+        elseif (count($parts) == 2) {
+          $term_name_or_tid = $term;
+        }
+        if ($term_list = taxonomy_get_term_by_name($term_name_or_tid)) {
+          $term = reset($term_list);
+          $result[] = $term;
+        }
+      }
+    }
+
+    return $result;
+  }
+
+}
diff --git a/vendor/drupal/drupal-driver/src/Drupal/Driver/Fields/Drupal7/AbstractHandler.php b/vendor/drupal/drupal-driver/src/Drupal/Driver/Fields/Drupal7/AbstractHandler.php
new file mode 100644 (file)
index 0000000..88da3a0
--- /dev/null
@@ -0,0 +1,98 @@
+<?php
+
+namespace Drupal\Driver\Fields\Drupal7;
+
+use Drupal\Driver\Fields\FieldHandlerInterface;
+
+/**
+ * Base class for field handlers in Drupal 7.
+ */
+abstract class AbstractHandler implements FieldHandlerInterface {
+
+  /**
+   * The entity language.
+   *
+   * @var string
+   */
+  protected $language = NULL;
+
+  /**
+   * The simulated entity.
+   *
+   * @var \stdClass
+   */
+  protected $entity = NULL;
+
+  /**
+   * The entity type.
+   *
+   * @var string
+   */
+  protected $entityType = NULL;
+
+  /**
+   * The field name.
+   *
+   * @var string
+   */
+  protected $fieldName = NULL;
+
+  /**
+   * The field array, as returned by field_read_fields().
+   *
+   * @var array
+   */
+  protected $fieldInfo = array();
+
+  /**
+   * Constructs an AbstractHandler object.
+   *
+   * @param \stdClass $entity
+   *   The simulated entity object containing field information.
+   * @param string $entity_type
+   *   The entity type.
+   * @param string $field_name
+   *   The field name.
+   */
+  public function __construct(\stdClass $entity, $entity_type, $field_name) {
+    $this->entity = $entity;
+    $this->entityType = $entity_type;
+    $this->fieldName = $field_name;
+    $this->fieldInfo = $this->getFieldInfo();
+    $this->language = $this->getEntityLanguage();
+  }
+
+  /**
+   * Magic caller.
+   */
+  public function __call($method, $args) {
+    if ($method == 'expand') {
+      $args['values'] = (array) $args['values'];
+    }
+    return call_user_func_array(array($this, $method), $args);
+  }
+
+  /**
+   * Returns field information.
+   *
+   * @return array
+   *   The field array, as returned by field_read_fields().
+   */
+  public function getFieldInfo() {
+    return field_info_field($this->fieldName);
+  }
+
+  /**
+   * Returns the entity language.
+   *
+   * @return string
+   *   The entity language.
+   */
+  public function getEntityLanguage() {
+    if (field_is_translatable($this->entityType, $this->fieldInfo)) {
+      return entity_language($this->entityType, $this->entity);
+    }
+    return LANGUAGE_NONE;
+  }
+
+}
diff --git a/vendor/drupal/drupal-driver/src/Drupal/Driver/Fields/Drupal7/DatetimeHandler.php b/vendor/drupal/drupal-driver/src/Drupal/Driver/Fields/Drupal7/DatetimeHandler.php
new file mode 100644 (file)
index 0000000..d5647bf
--- /dev/null
@@ -0,0 +1,31 @@
+<?php
+
+namespace Drupal\Driver\Fields\Drupal7;
+
+/**
+ * Datetime field handler for Drupal 7.
+ */
+class DatetimeHandler extends AbstractHandler {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function expand($values) {
+    $return = array();
+    if (isset($this->fieldInfo['columns']['value2'])) {
+      foreach ($values as $value) {
+        $return[$this->language][] = array(
+          'value' => $value[0],
+          'value2' => $value[1],
+        );
+      }
+    }
+    else {
+      foreach ($values as $value) {
+        $return[$this->language][] = array('value' => $value);
+      }
+    }
+    return $return;
+  }
+
+}
diff --git a/vendor/drupal/drupal-driver/src/Drupal/Driver/Fields/Drupal7/DefaultHandler.php b/vendor/drupal/drupal-driver/src/Drupal/Driver/Fields/Drupal7/DefaultHandler.php
new file mode 100644 (file)
index 0000000..e4d727e
--- /dev/null
@@ -0,0 +1,25 @@
+<?php
+
+namespace Drupal\Driver\Fields\Drupal7;
+
+/**
+ * Default field handler for Drupal 7.
+ */
+class DefaultHandler extends AbstractHandler {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function expand($values) {
+    $return = array();
+    foreach ($values as $value) {
+      // Use the column name 'value' by default if the value is not an array.
+      if (!is_array($value)) {
+        $value = array('value' => $value);
+      }
+      $return[$this->language][] = $value;
+    }
+    return $return;
+  }
+
+}
diff --git a/vendor/drupal/drupal-driver/src/Drupal/Driver/Fields/Drupal7/EntityreferenceHandler.php b/vendor/drupal/drupal-driver/src/Drupal/Driver/Fields/Drupal7/EntityreferenceHandler.php
new file mode 100644 (file)
index 0000000..b62be97
--- /dev/null
@@ -0,0 +1,34 @@
+<?php
+
+namespace Drupal\Driver\Fields\Drupal7;
+
+/**
+ * Entityreference field handler for Drupal 7.
+ */
+class EntityreferenceHandler extends AbstractHandler {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function expand($values) {
+    $entity_type = $this->fieldInfo['settings']['target_type'];
+    $entity_info = entity_get_info($entity_type);
+    // For users set label to username.
+    if ($entity_type == 'user') {
+      $entity_info['entity keys']['label'] = 'name';
+    }
+
+    $return = array();
+    foreach ($values as $value) {
+      $target_id = db_select($entity_info['base table'], 't')
+        ->fields('t', array($entity_info['entity keys']['id']))
+        ->condition('t.' . $entity_info['entity keys']['label'], $value)
+        ->execute()->fetchField();
+      if ($target_id) {
+        $return[$this->language][] = array('target_id' => $target_id);
+      }
+    }
+    return $return;
+  }
+
+}
diff --git a/vendor/drupal/drupal-driver/src/Drupal/Driver/Fields/Drupal7/FileHandler.php b/vendor/drupal/drupal-driver/src/Drupal/Driver/Fields/Drupal7/FileHandler.php
new file mode 100644 (file)
index 0000000..0f899af
--- /dev/null
@@ -0,0 +1,47 @@
+<?php
+
+namespace Drupal\Driver\Fields\Drupal7;
+
+/**
+ * File field handler for Drupal 7.
+ */
+class FileHandler extends AbstractHandler {
+
+  /**
+   * {@inheritdoc}
+   *
+   * Specify files in file fields by their filename.
+   */
+  public function expand($values) {
+    $return = array();
+
+    foreach ($values as $value) {
+      $query = new \EntityFieldQuery();
+
+      $query->entityCondition('entity_type', 'file')
+        ->propertyCondition('filename', $value)
+        ->propertyOrderBy('timestamp', 'DESC')
+        ->range(0, 1);
+
+      $result = $query->execute();
+
+      if (!empty($result['file'])) {
+        $files = entity_load('file', array_keys($result['file']));
+        $file = current($files);
+
+        $return[$this->language][] = array(
+          'filename' => $file->filename,
+          'uri' => $file->uri,
+          'fid' => $file->fid,
+          'display' => 1,
+        );
+      }
+      else {
+        throw new \Exception(sprintf('File with filename "%s" not found.', $value));
+      }
+    }
+
+    return $return;
+  }
+
+}
diff --git a/vendor/drupal/drupal-driver/src/Drupal/Driver/Fields/Drupal7/ImageHandler.php b/vendor/drupal/drupal-driver/src/Drupal/Driver/Fields/Drupal7/ImageHandler.php
new file mode 100644 (file)
index 0000000..05f0d90
--- /dev/null
@@ -0,0 +1,9 @@
+<?php
+
+namespace Drupal\Driver\Fields\Drupal7;
+
+/**
+ * Image field handler for Drupal 7.
+ */
+class ImageHandler extends FileHandler {
+}
diff --git a/vendor/drupal/drupal-driver/src/Drupal/Driver/Fields/Drupal7/LinkFieldHandler.php b/vendor/drupal/drupal-driver/src/Drupal/Driver/Fields/Drupal7/LinkFieldHandler.php
new file mode 100644 (file)
index 0000000..0b05b21
--- /dev/null
@@ -0,0 +1,24 @@
+<?php
+
+namespace Drupal\Driver\Fields\Drupal7;
+
+/**
+ * Link field handler for Drupal 7.
+ */
+class LinkFieldHandler extends AbstractHandler {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function expand($values) {
+    $return = array();
+    foreach ($values as $value) {
+      $return[$this->language][] = array(
+        'title' => $value[0],
+        'url' => $value[1],
+      );
+    }
+    return $return;
+  }
+
+}
diff --git a/vendor/drupal/drupal-driver/src/Drupal/Driver/Fields/Drupal7/ListBooleanHandler.php b/vendor/drupal/drupal-driver/src/Drupal/Driver/Fields/Drupal7/ListBooleanHandler.php
new file mode 100644 (file)
index 0000000..cc11928
--- /dev/null
@@ -0,0 +1,29 @@
+<?php
+
+namespace Drupal\Driver\Fields\Drupal7;
+
+/**
+ * ListBoolean field handler for Drupal 7.
+ */
+class ListBooleanHandler extends AbstractHandler {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function expand($values) {
+    $return = array();
+    $allowed_values = $this->fieldInfo['settings']['allowed_values'];
+    // If values are blank then use keys as value.
+    foreach ($allowed_values as $key => $value) {
+      if ($value == '') {
+        $allowed_values[$key] = $key;
+      }
+    }
+    $allowed_values = array_flip($allowed_values);
+    foreach ($values as $value) {
+      $return[$this->language][] = array('value' => $allowed_values[$value]);
+    }
+    return $return;
+  }
+
+}
diff --git a/vendor/drupal/drupal-driver/src/Drupal/Driver/Fields/Drupal7/ListTextHandler.php b/vendor/drupal/drupal-driver/src/Drupal/Driver/Fields/Drupal7/ListTextHandler.php
new file mode 100644 (file)
index 0000000..25b5f35
--- /dev/null
@@ -0,0 +1,38 @@
+<?php
+
+namespace Drupal\Driver\Fields\Drupal7;
+
+/**
+ * ListText field handler for Drupal 7.
+ */
+class ListTextHandler extends AbstractHandler {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function expand($values) {
+    $return = array();
+    if (!empty($this->fieldInfo['settings']['allowed_values_function'])) {
+      $cacheable = TRUE;
+      $callback = $this->fieldInfo['settings']['allowed_values_function'];
+      $allowed_values = call_user_func($callback, $this->fieldInfo, $this, $this->entityType, $this->entity, $cacheable);
+    }
+    else {
+      $allowed_values = array();
+      $options = array_flip($this->fieldInfo['settings']['allowed_values']);
+      foreach ($values as $value) {
+        if (array_key_exists($value, $options)) {
+          $allowed_values[$value] = $options[$value];
+        }
+        else {
+          $allowed_values[$value] = $value;
+        }
+      }
+    }
+    foreach ($values as $value) {
+      $return[$this->language][] = array('value' => $allowed_values[$value]);
+    }
+    return $return;
+  }
+
+}
diff --git a/vendor/drupal/drupal-driver/src/Drupal/Driver/Fields/Drupal7/TaxonomyTermReferenceHandler.php b/vendor/drupal/drupal-driver/src/Drupal/Driver/Fields/Drupal7/TaxonomyTermReferenceHandler.php
new file mode 100644 (file)
index 0000000..2acd302
--- /dev/null
@@ -0,0 +1,38 @@
+<?php
+
+namespace Drupal\Driver\Fields\Drupal7;
+
+/**
+ * Taxonomy term reference field handler for Drupal 7.
+ */
+class TaxonomyTermReferenceHandler extends AbstractHandler {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function expand($values) {
+    $return = array();
+    foreach ($values as $name) {
+      $terms = taxonomy_get_term_by_name($name, $this->getVocab());
+      if (!$terms) {
+        throw new \Exception(sprintf("No term '%s' exists.", $name));
+      }
+      $return[$this->language][] = array('tid' => array_shift($terms)->tid);
+    }
+    return $return;
+  }
+
+  /**
+   * Attempt to determine the vocabulary for which the field is configured.
+   *
+   * @return mixed
+   *   Returns a string containing the vocabulary in which the term must be
+   *   found or NULL if unable to determine.
+   */
+  protected function getVocab() {
+    if (!empty($this->field_info['settings']['allowed_values'][0]['vocabulary'])) {
+      return $this->field_info['settings']['allowed_values'][0]['vocabulary'];
+    }
+  }
+
+}
diff --git a/vendor/drupal/drupal-driver/src/Drupal/Driver/Fields/Drupal8/AbstractHandler.php b/vendor/drupal/drupal-driver/src/Drupal/Driver/Fields/Drupal8/AbstractHandler.php
new file mode 100644 (file)
index 0000000..d5f5127
--- /dev/null
@@ -0,0 +1,53 @@
+<?php
+
+namespace Drupal\Driver\Fields\Drupal8;
+
+use Drupal\Driver\Fields\FieldHandlerInterface;
+
+/**
+ * Base class for field handlers in Drupal 8.
+ */
+abstract class AbstractHandler implements FieldHandlerInterface {
+  /**
+   * Field storage definition.
+   *
+   * @var \Drupal\field\Entity\FieldStorageConfig
+   */
+  protected $fieldInfo = NULL;
+
+  /**
+   * Field configuration definition.
+   *
+   * @var \Drupal\field\Entity\FieldConfig
+   */
+  protected $fieldConfig = NULL;
+
+  /**
+   * Constructs an AbstractHandler object.
+   *
+   * @param \stdClass $entity
+   *   The simulated entity object containing field information.
+   * @param string $entity_type
+   *   The entity type.
+   * @param string $field_name
+   *   The field name.
+   *
+   * @throws \Exception
+   *   Thrown when the given field name does not exist on the entity.
+   */
+  public function __construct(\stdClass $entity, $entity_type, $field_name) {
+    $entity_manager = \Drupal::entityManager();
+    $fields = $entity_manager->getFieldStorageDefinitions($entity_type);
+    $this->fieldInfo = $fields[$field_name];
+
+    $bundle_key = $entity_manager->getDefinition($entity_type)->getKey('bundle');
+    $bundle = !empty($entity->$bundle_key) ? $entity->$bundle_key : $entity_type;
+
+    $fields = $entity_manager->getFieldDefinitions($entity_type, $bundle);
+    if (empty($fields[$field_name])) {
+      throw new \Exception(sprintf('The field "%s" does not exist on entity type "%s".', $field_name, $entity_type));
+    }
+    $this->fieldConfig = $fields[$field_name];
+  }
+
+}
diff --git a/vendor/drupal/drupal-driver/src/Drupal/Driver/Fields/Drupal8/DatetimeHandler.php b/vendor/drupal/drupal-driver/src/Drupal/Driver/Fields/Drupal8/DatetimeHandler.php
new file mode 100644 (file)
index 0000000..435e42f
--- /dev/null
@@ -0,0 +1,20 @@
+<?php
+
+namespace Drupal\Driver\Fields\Drupal8;
+
+/**
+ * Datetime field handler for Drupal 8.
+ */
+class DatetimeHandler extends AbstractHandler {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function expand($values) {
+    foreach ($values as $key => $value) {
+      $values[$key] = str_replace(' ', 'T', $value);
+    }
+    return $values;
+  }
+
+}
diff --git a/vendor/drupal/drupal-driver/src/Drupal/Driver/Fields/Drupal8/DefaultHandler.php b/vendor/drupal/drupal-driver/src/Drupal/Driver/Fields/Drupal8/DefaultHandler.php
new file mode 100644 (file)
index 0000000..f5e4aa7
--- /dev/null
@@ -0,0 +1,17 @@
+<?php
+
+namespace Drupal\Driver\Fields\Drupal8;
+
+/**
+ * Default field handler for Drupal 8.
+ */
+class DefaultHandler extends AbstractHandler {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function expand($values) {
+    return $values;
+  }
+
+}
diff --git a/vendor/drupal/drupal-driver/src/Drupal/Driver/Fields/Drupal8/EntityReferenceHandler.php b/vendor/drupal/drupal-driver/src/Drupal/Driver/Fields/Drupal8/EntityReferenceHandler.php
new file mode 100644 (file)
index 0000000..0552b6f
--- /dev/null
@@ -0,0 +1,53 @@
+<?php
+
+namespace Drupal\Driver\Fields\Drupal8;
+
+/**
+ * Entity Reference field handler for Drupal 8.
+ */
+class EntityReferenceHandler extends AbstractHandler {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function expand($values) {
+    $return = array();
+    $entity_type_id = $this->fieldInfo->getSetting('target_type');
+    $entity_definition = \Drupal::entityManager()->getDefinition($entity_type_id);
+    $label_key = $entity_definition->getKey('label');
+
+    // Determine target bundle restrictions.
+    $target_bundle_key = NULL;
+    if (!$target_bundles = $this->getTargetBundles()) {
+      $target_bundle_key = $entity_definition->getKey('bundle');
+    }
+
+    foreach ($values as $value) {
+      $query = \Drupal::entityQuery($entity_type_id)->condition($label_key, $value);
+      if ($target_bundles && $target_bundle_key) {
+        $query->condition($target_bundle_key, $target_bundles, 'IN');
+      }
+      if ($entities = $query->execute()) {
+        $return[] = array_shift($entities);
+      }
+      else {
+        throw new \Exception(sprintf("No entity '%s' of type '%s' exists.", $value, $entity_type_id));
+      }
+    }
+    return $return;
+  }
+
+  /**
+   * Retrieves bundles for which the field is configured to reference.
+   *
+   * @return mixed
+   *   Array of bundle names, or NULL if not able to determine bundles.
+   */
+  protected function getTargetBundles() {
+    $settings = $this->fieldConfig->getSettings();
+    if (!empty($settings['handler_settings']['target_bundles'])) {
+      return $settings['handler_settings']['target_bundles'];
+    }
+  }
+
+}
diff --git a/vendor/drupal/drupal-driver/src/Drupal/Driver/Fields/Drupal8/ImageHandler.php b/vendor/drupal/drupal-driver/src/Drupal/Driver/Fields/Drupal8/ImageHandler.php
new file mode 100644 (file)
index 0000000..81f6ebb
--- /dev/null
@@ -0,0 +1,38 @@
+<?php
+
+namespace Drupal\Driver\Fields\Drupal8;
+
+/**
+ * Image field handler for Drupal 7.
+ */
+class ImageHandler extends AbstractHandler {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function expand($values) {
+    $data = file_get_contents($values[0]);
+    if (FALSE === $data) {
+      throw new \Exception("Error reading file");
+    }
+
+    /* @var \Drupal\file\FileInterface $file */
+    $file = file_save_data(
+      $data,
+      'public://' . uniqid() . '.jpg');
+
+    if (FALSE === $file) {
+      throw new \Exception("Error saving file");
+    }
+
+    $file->save();
+
+    $return = array(
+      'target_id' => $file->id(),
+      'alt' => 'Behat test image',
+      'title' => 'Behat test image',
+    );
+    return $return;
+  }
+
+}
diff --git a/vendor/drupal/drupal-driver/src/Drupal/Driver/Fields/Drupal8/LinkHandler.php b/vendor/drupal/drupal-driver/src/Drupal/Driver/Fields/Drupal8/LinkHandler.php
new file mode 100644 (file)
index 0000000..34e540a
--- /dev/null
@@ -0,0 +1,27 @@
+<?php
+
+namespace Drupal\Driver\Fields\Drupal8;
+
+/**
+ * Link field handler for Drupal 8.
+ */
+class LinkHandler extends AbstractHandler {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function expand($values) {
+    $return = array();
+    foreach ($values as $value) {
+      $return[] = array(
+        // 'options' is required to be an array, otherwise the utility class
+        // Drupal\Core\Utility\UnroutedUrlAssembler::assemble() will complain.
+        'options' => array(),
+        'title' => $value[0],
+        'uri' => $value[1],
+      );
+    }
+    return $return;
+  }
+
+}
diff --git a/vendor/drupal/drupal-driver/src/Drupal/Driver/Fields/Drupal8/TaxonomyTermReferenceHandler.php b/vendor/drupal/drupal-driver/src/Drupal/Driver/Fields/Drupal8/TaxonomyTermReferenceHandler.php
new file mode 100644 (file)
index 0000000..58808c6
--- /dev/null
@@ -0,0 +1,29 @@
+<?php
+
+namespace Drupal\Driver\Fields\Drupal8;
+
+/**
+ * Field handler for taxonomy term references in Drupal 8.
+ */
+class TaxonomyTermReferenceHandler extends AbstractHandler {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function expand($values) {
+    $return = array();
+    foreach ($values as $name) {
+      $terms = \Drupal::entityManager()
+        ->getStorage('taxonomy_term')
+        ->loadByProperties(array('name' => $name));
+      if ($terms) {
+        $return[] = array_shift($terms)->id();
+      }
+      else {
+        throw new \Exception(sprintf("No term '%s' exists.", $name));
+      }
+    }
+    return $return;
+  }
+
+}
diff --git a/vendor/drupal/drupal-driver/src/Drupal/Driver/Fields/Drupal8/TextWithSummaryHandler.php b/vendor/drupal/drupal-driver/src/Drupal/Driver/Fields/Drupal8/TextWithSummaryHandler.php
new file mode 100644 (file)
index 0000000..2efeb12
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+
+namespace Drupal\Driver\Fields\Drupal8;
+
+use Drupal\Driver\Fields\FieldHandlerInterface;
+
+/**
+ * Default field handler for Drupal 8.
+ */
+class TextWithSummaryHandler implements FieldHandlerInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function expand($values) {
+    return $values;
+  }
+
+}
diff --git a/vendor/drupal/drupal-driver/src/Drupal/Driver/Fields/FieldHandlerInterface.php b/vendor/drupal/drupal-driver/src/Drupal/Driver/Fields/FieldHandlerInterface.php
new file mode 100644 (file)
index 0000000..784463e
--- /dev/null
@@ -0,0 +1,29 @@
+<?php
+
+namespace Drupal\Driver\Fields;
+
+/**
+ * Interface for handling fields.
+ *
+ * Saving fields on entities is handled differently depending on the Drupal
+ * version. This interface translates abstract field data into the format that
+ * is expected by the different storage handlers.
+ */
+interface FieldHandlerInterface {
+
+  /**
+   * Expand abstract field values so they can be saved on the entity.
+   *
+   * This method takes care of the different ways that field data is saved on
+   * entities in different versions of Drupal.
+   *
+   * @param mixed $values
+   *   A single value or an array of field values to save on the entity.
+   *
+   * @return array
+   *   An array of field values in the format expected by the entity storage
+   *   handlers in the driver's version of Drupal.
+   */
+  public function expand($values);
+
+}
diff --git a/vendor/drupal/drupal-driver/src/Drupal/Driver/SubDriverFinderInterface.php b/vendor/drupal/drupal-driver/src/Drupal/Driver/SubDriverFinderInterface.php
new file mode 100644 (file)
index 0000000..00f7ad1
--- /dev/null
@@ -0,0 +1,18 @@
+<?php
+
+namespace Drupal\Driver;
+
+/**
+ * Interface for discovery of sub-drivers.
+ */
+interface SubDriverFinderInterface {
+
+  /**
+   * Returns an array of paths in which to look for Drupal sub-drivers.
+   *
+   * @return array
+   *   An array of paths in which to find sub-drivers.
+   */
+  public function getSubDriverPaths();
+
+}
diff --git a/vendor/drupal/drupal-driver/tests/Drupal/Tests/Driver/Drupal7FieldHandlerTest.php b/vendor/drupal/drupal-driver/tests/Drupal/Tests/Driver/Drupal7FieldHandlerTest.php
new file mode 100644 (file)
index 0000000..3961a0d
--- /dev/null
@@ -0,0 +1,162 @@
+<?php
+
+namespace Drupal\Tests\Driver;
+
+/**
+ * Tests the Drupal 7 field handlers.
+ */
+class Drupal7FieldHandlerTest extends FieldHandlerAbstractTest {
+
+  /**
+   * Tests the field handlers.
+   *
+   * @param string $class_name
+   *   The name of the field handler class under test.
+   * @param object $entity
+   *   An object representing an entity. Should contain a single property which
+   *   represents a field containing a value.
+   * @param string $entity_type
+   *   The entity type under test.
+   * @param array $field
+   *   An associative array with the following keys:
+   *   - 'field_name': the field name that is used for the property on $entity.
+   *   - 'columns': an optional array containing the column names of the field
+   *     as keys.
+   * @param array $expected_values
+   *   The values in the expected format after expansion.
+   *
+   * @dataProvider dataProvider
+   */
+  public function testFieldHandlers($class_name, $entity, $entity_type, array $field, array $expected_values) {
+    $handler = $this->getMockHandler($class_name, $entity, $entity_type, $field);
+
+    $field_name = $field['field_name'];
+    $expanded_values = $handler->expand($this->values($entity->$field_name));
+    $this->assertArraySubset($expected_values, $expanded_values);
+  }
+
+  /**
+   * Data provider.
+   *
+   * @return array
+   *   An array of test data.
+   */
+  public function dataProvider() {
+    return array(
+      // Test default text field provided as simple text.
+      array(
+        'DefaultHandler',
+        (object) array('field_text' => 'Text'),
+        'node',
+        array('field_name' => 'field_text'),
+        array('en' => array(array('value' => 'Text'))),
+      ),
+
+      // Test default text field provided as array.
+      array(
+        'DefaultHandler',
+        (object) array('field_text' => array('Text')),
+        'node',
+        array('field_name' => 'field_text'),
+        array('en' => array(array('value' => 'Text'))),
+      ),
+
+      // Test default field handler using custom field columns.
+      array(
+        'DefaultHandler',
+        (object) array(
+          'field_addressfield' => array(
+            array(
+              'country' => 'BE',
+              'locality' => 'Brussels',
+              'thoroughfare' => 'Grote Markt 1',
+              'postal_code' => '1000',
+            ),
+          ),
+        ),
+        'node',
+        array('field_name' => 'field_addressfield'),
+        array(
+          'en' => array(
+            array(
+              'country' => 'BE',
+              'locality' => 'Brussels',
+              'thoroughfare' => 'Grote Markt 1',
+              'postal_code' => '1000',
+            ),
+          ),
+        ),
+      ),
+
+      // Test single-value date field provided as simple text.
+      array(
+        'DatetimeHandler',
+        (object) array('field_date' => '2015-01-01 00:00:00'),
+        'node',
+        array('field_name' => 'field_date'),
+        array('en' => array(array('value' => '2015-01-01 00:00:00'))),
+      ),
+
+      // Test single-value date field provided as an array.
+      array(
+        'DatetimeHandler',
+        (object) array('field_date' => array('2015-01-01 00:00:00')),
+        'node',
+        array('field_name' => 'field_date'),
+        array('en' => array(array('value' => '2015-01-01 00:00:00'))),
+      ),
+
+      // Test double-value date field. Can only be provided as an array
+      // due to array type casting we perform in
+      // \Drupal\Driver\Fields\Drupal7\AbstractFieldHandler::__call()
+      array(
+        'DatetimeHandler',
+        (object) array(
+          'field_date' => array(
+            array(
+              '2015-01-01 00:00:00',
+              '2015-01-02 00:00:00',
+            ),
+          ),
+        ),
+        'node',
+        array(
+          'field_name' => 'field_date',
+          'columns' => array('value' => '', 'value2' => ''),
+        ),
+        array(
+          'en' => array(
+            array(
+              'value' => '2015-01-01 00:00:00',
+              'value2' => '2015-01-02 00:00:00',
+            ),
+          ),
+        ),
+      ),
+
+      // Test list boolean field with blank 'On' and 'Off' values.
+      array(
+        'ListBooleanHandler',
+        (object) array('field_list_boolean' => array(0)),
+        'node',
+        array(
+          'field_name' => 'field_list_boolean',
+          'settings' => array(
+            'allowed_values' => array(
+              0 => '',
+              1 => '',
+            ),
+          ),
+        ),
+        array(
+          'en' => array(
+            array(
+              'value' => 0,
+            ),
+          ),
+        ),
+      ),
+    );
+  }
+
+}
diff --git a/vendor/drupal/drupal-driver/tests/Drupal/Tests/Driver/DrushDriverTest.php b/vendor/drupal/drupal-driver/tests/Drupal/Tests/Driver/DrushDriverTest.php
new file mode 100644 (file)
index 0000000..8322aa5
--- /dev/null
@@ -0,0 +1,47 @@
+<?php
+
+namespace Drupal\Tests\Driver;
+
+use Drupal\Driver\DrushDriver;
+
+/**
+ * Tests for the Drush driver.
+ */
+class DrushDriverTest extends \PHPUnit_Framework_TestCase {
+
+  /**
+   * Tests instantiating the driver with only an alias.
+   */
+  public function testWithAlias() {
+    $driver = new DrushDriver('alias');
+    $this->assertEquals('alias', $driver->alias, 'The drush alias was not properly set.');
+  }
+
+  /**
+   * Tests instantiating the driver with a prefixed alias.
+   */
+  public function testWithAliasPrefix() {
+    $driver = new DrushDriver('@alias');
+    $this->assertEquals('alias', $driver->alias, 'The drush alias did not remove the "@" prefix.');
+  }
+
+  /**
+   * Tests instantiating the driver with only the root path.
+   */
+  public function testWithRoot() {
+    // Bit of a hack here to use the path to this file, but all the driver cares
+    // about during initialization is that the root be a directory.
+    $driver = new DrushDriver('', __FILE__);
+    $this->assertEquals(__FILE__, $driver->root);
+  }
+
+  /**
+   * Tests instantiating the driver with missing alias and root path.
+   *
+   * @expectedException \Drupal\Driver\Exception\BootstrapException
+   */
+  public function testWithNeither() {
+    new DrushDriver('', '');
+  }
+
+}
diff --git a/vendor/drupal/drupal-driver/tests/Drupal/Tests/Driver/FieldHandlerAbstractTest.php b/vendor/drupal/drupal-driver/tests/Drupal/Tests/Driver/FieldHandlerAbstractTest.php
new file mode 100644 (file)
index 0000000..052ce5f
--- /dev/null
@@ -0,0 +1,59 @@
+<?php
+
+namespace Drupal\Tests\Driver;
+
+/**
+ * Base class for field handler tests.
+ */
+abstract class FieldHandlerAbstractTest extends \PHPUnit_Framework_TestCase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function tearDown() {
+    \Mockery::close();
+  }
+
+  /**
+   * Factory method to build and returned a mocked field handler.
+   *
+   * @param string $handler
+   *   The name of the field handler class under test.
+   * @param object $entity
+   *   An object representing an entity. Should contain a single property which
+   *   represents a field containing a value.
+   * @param string $entity_type
+   *   The entity type under test.
+   * @param array $field
+   *   An associative array with the following keys:
+   *   - 'field_name': the field name that is used for the property on $entity.
+   *   - 'columns': an optional array containing the column names of the field
+   *     as keys.
+   *
+   * @return \Mockery\MockInterface
+   *   The mocked field handler.
+   */
+  protected function getMockHandler($handler, $entity, $entity_type, array $field) {
+    $mock = \Mockery::mock(sprintf('Drupal\Driver\Fields\Drupal7\%s', $handler));
+    $mock->makePartial();
+    $mock->shouldReceive('getFieldInfo')->andReturn($field);
+    $mock->shouldReceive('getEntityLanguage')->andReturn('en');
+    $mock->__construct($entity, $entity_type, $field);
+
+    return $mock;
+  }
+
+  /**
+   * Simulate __call() since mocked handlers will not run through magic methods.
+   *
+   * @param mixed $values
+   *   The field value(s).
+   *
+   * @return array
+   *   The values parameter cast to an array.
+   */
+  protected function values($values) {
+    return (array) $values;
+  }
+
+}
diff --git a/vendor/drupal/drupal-extension/.gitignore b/vendor/drupal/drupal-extension/.gitignore
new file mode 100644 (file)
index 0000000..4d3f649
--- /dev/null
@@ -0,0 +1,7 @@
+*.tgz
+*.phar
+composer.lock
+vendor
+/drupal*
+behat.yml
+/node_modules
diff --git a/vendor/drupal/drupal-extension/.travis.yml b/vendor/drupal/drupal-extension/.travis.yml
new file mode 100644 (file)
index 0000000..bd347a2
--- /dev/null
@@ -0,0 +1,87 @@
+language: php
+
+php:
+  - 5.5
+  - 5.6
+  - 7.0
+
+env:
+  global:
+    - PATH=$PATH:/home/travis/.composer/vendor/bin
+    - TRAVIS_NODE_VERSION="4.0.0"
+  matrix:
+    - DRUPAL_VERSION=6
+    - DRUPAL_VERSION=7
+    - DRUPAL_VERSION=8
+
+matrix:
+  exclude:
+    - php: 5.6
+      env: DRUPAL_VERSION=6
+    - php: 7.0
+      env: DRUPAL_VERSION=6
+  allow_failures:
+    - php: 7.0
+      env: DRUPAL_VERSION=7
+    - php: 5.3
+
+# Enable Travis containers.
+sudo: false
+
+install:
+  - composer self-update
+  # Use the example composer.json file for Drupal 8, and also install the behat drush endpoint.
+  - test ${DRUPAL_VERSION} -ne 8 || (cp doc/_static/composer.json.d8 ./composer.json && composer require --prefer-source drush-ops/behat-drush-endpoint drupal/drupal-driver:dev-master)
+  - composer install
+  # Install drush.
+  - composer global require drush/drush:~8.0
+  # Install the Behat Drush Endpoint for Drupal 7 tests.
+  - test ${DRUPAL_VERSION} -ne 7 || (git clone https://github.com/drush-ops/behat-drush-endpoint.git drush/behat-drush-endpoint && (cd drush/behat-drush-endpoint && composer install))
+  # Pin node version.
+  # @see http://austinpray.com/ops/2015/09/20/change-travis-node-version.html
+  - rm -rf ~/.nvm && git clone https://github.com/creationix/nvm.git ~/.nvm && (cd ~/.nvm && git checkout `git describe --abbrev=0 --tags`) && source ~/.nvm/nvm.sh && nvm install $TRAVIS_NODE_VERSION
+  - npm install
+
+before_script:
+  # Set NODE_PATH for zombie driver.
+  - export NODE_PATH="`pwd`/node_modules"
+  # Define the module path according to the Drupal version being tested.
+  - test ${DRUPAL_VERSION} -eq 8 && export MODULE_PATH='drupal/modules' || export MODULE_PATH='drupal/sites/all/modules'
+  # Drupal 8 uses semantic versioning.
+  - test ${DRUPAL_VERSION} -eq 8 && export PROJECT_NAME='drupal-8.1.x' || export PROJECT_NAME="drupal-${DRUPAL_VERSION}.x"
+  # Set sendmail so drush doesn't throw an error during site install.
+  - echo "sendmail_path='true'" >> `php --ini | grep "Loaded Configuration" | awk '{print $4}'`
+  # Download and install Drupal so we can test API abilities.
+  - mysql -e 'create database drupal'
+  - drush --quiet dl ${PROJECT_NAME} --all --drupal-project-rename=drupal
+  - drush --yes --root=$PWD/drupal site-install --db-url=mysql://travis:@127.0.0.1/drupal
+  # Copy the static HTML that is used for blackbox testing in the web root.
+  - cp -r fixtures/blackbox $PWD/drupal
+  # Copy our test module to the correct location.
+  - cp -r fixtures/drupal${DRUPAL_VERSION}/modules/behat_test ${MODULE_PATH}
+  - cd drupal
+  - drush --yes en behat_test
+  - drush cc drush
+  - test ${DRUPAL_VERSION} -eq 6 || drush help behat
+  # Only revert features on Drupal 7.
+  - test \! ${DRUPAL_VERSION} -eq 7 || drush --yes fr behat_test
+  # Disable the page cache on Drupal 8.
+  - test \! ${DRUPAL_VERSION} -eq 8 || drush --yes pmu page_cache
+  # Test with big_pipe enabled for Drupal 8.
+  - test \! ${DRUPAL_VERSION} -eq 8 || drush --yes en -y big_pipe
+  # Clear the cache on Drupal 6 and 7, rebuild on Drupal 8.
+  - test ${DRUPAL_VERSION} -eq 8 && drush cr || drush cc all || true
+  - drush --debug runserver :8888 > ~/debug.txt 2>&1 &
+  - cd -
+  - sleep 4s
+
+script:
+  - find ./src -name "*.php" -print0 | xargs -0 -n1 -P8 php -l
+  - vendor/bin/phpspec run -f pretty --no-interaction
+  - vendor/bin/behat -fprogress --strict
+  - vendor/bin/behat -fprogress --profile=drupal${DRUPAL_VERSION} --strict
+  # Do not test the Drush profile unless Drupal 7 was installed.
+  - test ${DRUPAL_VERSION} -ne 7 || vendor/bin/behat -fprogress --profile=drush --strict
+
+after_failure:
+  - cat ~/debug.txt
diff --git a/vendor/drupal/drupal-extension/LICENSE b/vendor/drupal/drupal-extension/LICENSE
new file mode 100644 (file)
index 0000000..d159169
--- /dev/null
@@ -0,0 +1,339 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                            NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --git a/vendor/drupal/drupal-extension/README.md b/vendor/drupal/drupal-extension/README.md
new file mode 100644 (file)
index 0000000..5a4d0ff
--- /dev/null
@@ -0,0 +1,117 @@
+# Behat Drupal Extension
+
+The Drupal Extension is an integration layer between [Behat](http://behat.org),
+[Mink Extension](https://github.com/Behat/MinkExtension), and Drupal. It
+provides step definitions for common testing scenarios specific to Drupal
+sites.
+
+[![Build Status](https://travis-ci.org/jhedstrom/drupalextension.png?branch=master)](https://travis-ci.org/jhedstrom/drupalextension)
+
+The Drupal Extension 3.3.x supports Drupal 6, 7 and 8, utilizes Behat 3.2+ and
+runs on PHP 5.5+. It is compatible with Symfony components 2.x as well as 3.x
+so it can be used on Drupal 8.4.x.
+
+[![Latest Stable Version](https://poser.pugx.org/drupal/drupal-extension/v/stable.svg)](https://packagist.org/packages/drupal/drupal-extension)
+[![Total Downloads](https://poser.pugx.org/drupal/drupal-extension/downloads.svg)](https://packagist.org/packages/drupal/drupal-extension)
+[![Latest Unstable Version](https://poser.pugx.org/drupal/drupal-extension/v/unstable.svg)](https://packagist.org/packages/drupal/drupal-extension)
+[![License](https://poser.pugx.org/drupal/drupal-extension/license.svg)](https://packagist.org/packages/drupal/drupal-extension)
+[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/jhedstrom/drupalextension/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/jhedstrom/drupalextension/?branch=master)
+
+
+
+## Use it for testing your Drupal site.
+
+If you're new to the Drupal Extension, we recommend starting with 
+the [Full documentation](https://behat-drupal-extension.readthedocs.org)
+
+[![Documentation Status](https://readthedocs.org/projects/behat-drupal-extension/badge/?version=master)](https://behat-drupal-extension.readthedocs.org)
+
+### Quick start
+
+1. Install using [Composer](https://getcomposer.org/):
+
+    ``` bash
+    mkdir projectdir
+    cd projectdir
+    curl -sS https://getcomposer.org/installer | php
+    COMPOSER_BIN_DIR=bin php composer.phar require drupal/drupal-extension='~3.0'
+    ```
+
+1.  In the projectdir, create a file called `behat.yml`. Below is the
+    minimal configuration. Many more options are covered in the 
+    [Full documentation](https://behat-drupal-extension.readthedocs.org)  
+
+  ``` yaml
+  default:
+    suites:
+      default:
+        contexts:
+          - Drupal\DrupalExtension\Context\DrupalContext
+    extensions:
+      Behat\MinkExtension:
+        goutte: ~
+        base_url: http://example.org/  # Replace with your site's URL
+      Drupal\DrupalExtension:
+        blackbox: ~
+  ```
+
+1. In the projectdir, run
+
+    ``` bash
+    bin/behat --init
+    ```
+
+1. Find pre-defined steps to work with using:
+
+    ```bash
+    bin/behat -di
+    ```
+
+1. Define your own steps in `projectdir\features\FeatureContext.php`
+
+1. Start adding your [feature files](http://behat.org/en/latest/user_guide/gherkin.html) 
+   to the `features` directory of your repository.
+
+## Additional resources
+
+ * [Behat Drupal Extension documentation](https://behat-drupal-extension.readthedocs.org)
+ * [Behat documentation](http://docs.behat.org)
+ * [Mink documentation](http://mink.behat.org)
+ * [Drupal Behat group](http://groups.drupal.org/behat)
+
+## Examples and code snippets
+
+ * [Complex node creation, with field collections and entity references](https://gist.github.com/jhedstrom/5708233)
+ * [Achievements module support](https://gist.github.com/jhedstrom/9633067)
+ * [Drupal form element visibility](https://gist.github.com/pbuyle/7698675)
+ * [Track down PHP notices](https://www.godel.com.au/blog/use-behat-track-down-php-notices-they-take-over-your-drupal-site-forever)
+ * [Support for sites using basic HTTP authentication](https://gist.github.com/jhedstrom/5bc5192d6dacbf8cc459)
+
+## Release notes
+
+### Backwards incompatible changes
+
+Starting with 3.3.0 Behat Drupal Extension depends on Behat 3.2.0 which
+requires all callbacks to be defined as static methods.
+
+Before 3.3.0:
+
+```
+/**
+ * @afterUserCreate
+ */
+public function afterUserCreate(EntityScope $scope) {
+  // ...
+}
+```
+
+Starting with 3.3.0:
+
+```
+/**
+ * @afterUserCreate
+ */
+public static function afterUserCreate(EntityScope $scope) {
+  // ...
+}
+```
diff --git a/vendor/drupal/drupal-extension/behat.yml.dist b/vendor/drupal/drupal-extension/behat.yml.dist
new file mode 100644 (file)
index 0000000..eb9bcce
--- /dev/null
@@ -0,0 +1,131 @@
+default:
+  suites:
+    default:
+      contexts:
+        - FeatureContext
+        - Drupal\DrupalExtension\Context\ConfigContext
+        - Drupal\DrupalExtension\Context\DrupalContext
+        - Drupal\DrupalExtension\Context\MessageContext
+        - Drupal\DrupalExtension\Context\MinkContext
+        - Drupal\DrupalExtension\Context\MarkupContext
+      filters:
+        tags: "@blackbox"
+  extensions:
+    Behat\MinkExtension:
+      goutte: ~
+      zombie: ~
+      base_url: http://127.0.0.1:8888/blackbox
+      javascript_session: zombie
+    Drupal\DrupalExtension:
+      blackbox: ~
+      region_map:
+        content: "#content"
+        footer: "#footer"
+        navigation: "#nav-header"
+        left header: "#header-left"
+        right header: "#header-right"
+        right sidebar: "#aside-region"
+      selectors:
+        message_selector: '.messages'
+        error_message_selector: '.messages.error'
+        success_message_selector: '.messages.status'
+        warning_message_selector: '.messages.warning'
+
+# Separate profile for testing using the api driver. This assumes a
+# stock Drupal 6 install.
+drupal6:
+  suites:
+    default:
+      contexts:
+        - FeatureContext
+        - Drupal\DrupalExtension\Context\DrupalContext
+        - Drupal\DrupalExtension\Context\MinkContext
+        - Drupal\DrupalExtension\Context\MarkupContext
+      filters:
+        tags: "@d6"
+  extensions:
+    Behat\MinkExtension:
+      base_url: http://127.0.0.1:8888
+    Drupal\DrupalExtension:
+      api_driver: "drupal"
+      drupal:
+        # Change this to the absolute path to Drupal install.
+        drupal_root: "drupal"
+      region_map:
+        left sidebar: "#sidebar-first"
+        content: "#content"
+# Separate profile for testing using the api driver. This assumes a
+# stock Drupal 7 install.
+drupal7:
+  suites:
+    default:
+      contexts:
+        - FeatureContext
+        - Drupal\DrupalExtension\Context\DrupalContext
+        - Drupal\DrupalExtension\Context\MinkContext
+        - Drupal\DrupalExtension\Context\MarkupContext
+      filters:
+        tags: "@d7"
+  extensions:
+    Behat\MinkExtension:
+      base_url: http://127.0.0.1:8888
+    Drupal\DrupalExtension:
+      api_driver: "drupal"
+      drupal:
+        # Change this to the absolute path to Drupal install.
+        drupal_root: "drupal"
+      region_map:
+        left sidebar: "#sidebar-first"
+        content: "#content"
+
+# Separate profile for testing using the Drush driver. Assumes a stock
+# Drupal 7 install.
+drush:
+  suites:
+    default:
+      contexts:
+        - FeatureContext
+        - Drupal\DrupalExtension\Context\DrupalContext
+        - Drupal\DrupalExtension\Context\DrushContext
+        - Drupal\DrupalExtension\Context\MinkContext
+        - Drupal\DrupalExtension\Context\MarkupContext
+      filters:
+        tags: "@drushTest"
+  extensions:
+    Behat\MinkExtension:
+      base_url: http://127.0.0.1:8888
+    Drupal\DrupalExtension:
+      api_driver: "drush"
+      drush_driver: "drush"
+      drush:
+        root: "drupal"
+      region_map:
+        left sidebar: "#sidebar-first"
+        content: "#content"
+
+# Separate profile for testing D8. Assumes a stock Drupal 8 install.
+drupal8:
+  suites:
+    default:
+      contexts:
+        - FeatureContext
+        - Drupal\DrupalExtension\Context\ConfigContext
+        - Drupal\DrupalExtension\Context\DrupalContext
+        - Drupal\DrupalExtension\Context\MinkContext
+        - Drupal\DrupalExtension\Context\MarkupContext
+        - Drupal\DrupalExtension\Context\MessageContext
+      filters:
+        tags: "@d8&&~@d8wip"
+  extensions:
+    Behat\MinkExtension:
+      base_url: http://127.0.0.1:8888
+    Drupal\DrupalExtension:
+      api_driver: "drupal"
+      drupal:
+        # Change this to the absolute path to Drupal install.
+        drupal_root: "drupal"
+      region_map:
+        left sidebar: "#sidebar-first"
+        content: "#content"
+      selectors:
+        error_message_selector: '.messages--error'
diff --git a/vendor/drupal/drupal-extension/composer.json b/vendor/drupal/drupal-extension/composer.json
new file mode 100644 (file)
index 0000000..1308466
--- /dev/null
@@ -0,0 +1,41 @@
+{
+  "name": "drupal/drupal-extension",
+  "type": "behat-extension",
+  "description": "Drupal extension for Behat",
+  "keywords": ["drupal", "web", "test"],
+  "homepage": "http://drupal.org/project/drupalextension",
+  "license": "GPL-2.0+",
+  "authors": [
+     {
+       "name": "Jonathan Hedstrom",
+       "email": "jhedstrom@gmail.com"
+     }
+  ],
+  "require": {
+    "behat/mink": "~1.5",
+    "behat/mink-goutte-driver": "~1.0",
+    "behat/mink-selenium2-driver": "~1.1",
+    "behat/behat": "~3.2",
+    "behat/mink-extension": "~2.0",
+    "drupal/drupal-driver": "~1.2",
+    "symfony/dependency-injection": "~2.7|~3.0",
+    "symfony/event-dispatcher": "~2.7|~3.0"
+  },
+  "require-dev": {
+    "phpspec/phpspec": "~2.0",
+    "phpunit/phpunit": "3.7.*",
+    "behat/mink-zombie-driver": "^1.2"
+  },
+  "autoload": {
+    "psr-0": {
+      "Drupal\\Drupal": "src/",
+      "Drupal\\Exception": "src/",
+      "Drupal\\DrupalExtension": "src/"
+    }
+  },
+  "extra": {
+    "branch-alias": {
+      "dev-master": "3.2.x-dev"
+    }
+  }
+}
diff --git a/vendor/drupal/drupal-extension/doc/.gitignore b/vendor/drupal/drupal-extension/doc/.gitignore
new file mode 100644 (file)
index 0000000..a485625
--- /dev/null
@@ -0,0 +1 @@
+/_build
diff --git a/vendor/drupal/drupal-extension/doc/Makefile b/vendor/drupal/drupal-extension/doc/Makefile
new file mode 100644 (file)
index 0000000..a3b2825
--- /dev/null
@@ -0,0 +1,153 @@
+# Makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS    =
+SPHINXBUILD   = sphinx-build
+PAPER         =
+BUILDDIR      = _build
+
+# Internal variables.
+PAPEROPT_a4     = -D latex_paper_size=a4
+PAPEROPT_letter = -D latex_paper_size=letter
+ALLSPHINXOPTS   = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+# the i18n builder cannot share the environment and doctrees with the others
+I18NSPHINXOPTS  = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+
+.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
+
+help:
+       @echo "Please use \`make <target>' where <target> is one of"
+       @echo "  html       to make standalone HTML files"
+       @echo "  dirhtml    to make HTML files named index.html in directories"
+       @echo "  singlehtml to make a single large HTML file"
+       @echo "  pickle     to make pickle files"
+       @echo "  json       to make JSON files"
+       @echo "  htmlhelp   to make HTML files and a HTML help project"
+       @echo "  qthelp     to make HTML files and a qthelp project"
+       @echo "  devhelp    to make HTML files and a Devhelp project"
+       @echo "  epub       to make an epub"
+       @echo "  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+       @echo "  latexpdf   to make LaTeX files and run them through pdflatex"
+       @echo "  text       to make text files"
+       @echo "  man        to make manual pages"
+       @echo "  texinfo    to make Texinfo files"
+       @echo "  info       to make Texinfo files and run them through makeinfo"
+       @echo "  gettext    to make PO message catalogs"
+       @echo "  changes    to make an overview of all changed/added/deprecated items"
+       @echo "  linkcheck  to check all external links for integrity"
+       @echo "  doctest    to run all doctests embedded in the documentation (if enabled)"
+
+clean:
+       -rm -rf $(BUILDDIR)/*
+
+html:
+       $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
+       @echo
+       @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
+
+dirhtml:
+       $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
+       @echo
+       @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
+
+singlehtml:
+       $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
+       @echo
+       @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
+
+pickle:
+       $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
+       @echo
+       @echo "Build finished; now you can process the pickle files."
+
+json:
+       $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
+       @echo
+       @echo "Build finished; now you can process the JSON files."
+
+htmlhelp:
+       $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
+       @echo
+       @echo "Build finished; now you can run HTML Help Workshop with the" \
+             ".hhp project file in $(BUILDDIR)/htmlhelp."
+
+qthelp:
+       $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
+       @echo
+       @echo "Build finished; now you can run "qcollectiongenerator" with the" \
+             ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
+       @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/theDrupalExtensiontoBehatandMink.qhcp"
+       @echo "To view the help file:"
+       @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/theDrupalExtensiontoBehatandMink.qhc"
+
+devhelp:
+       $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
+       @echo
+       @echo "Build finished."
+       @echo "To view the help file:"
+       @echo "# mkdir -p $$HOME/.local/share/devhelp/theDrupalExtensiontoBehatandMink"
+       @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/theDrupalExtensiontoBehatandMink"
+       @echo "# devhelp"
+
+epub:
+       $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
+       @echo
+       @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
+
+latex:
+       $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+       @echo
+       @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
+       @echo "Run \`make' in that directory to run these through (pdf)latex" \
+             "(use \`make latexpdf' here to do that automatically)."
+
+latexpdf:
+       $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+       @echo "Running LaTeX files through pdflatex..."
+       $(MAKE) -C $(BUILDDIR)/latex all-pdf
+       @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
+
+text:
+       $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
+       @echo
+       @echo "Build finished. The text files are in $(BUILDDIR)/text."
+
+man:
+       $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
+       @echo
+       @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
+
+texinfo:
+       $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
+       @echo
+       @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
+       @echo "Run \`make' in that directory to run these through makeinfo" \
+             "(use \`make info' here to do that automatically)."
+
+info:
+       $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
+       @echo "Running Texinfo files through makeinfo..."
+       make -C $(BUILDDIR)/texinfo info
+       @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
+
+gettext:
+       $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
+       @echo
+       @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
+
+changes:
+       $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
+       @echo
+       @echo "The overview file is in $(BUILDDIR)/changes."
+
+linkcheck:
+       $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
+       @echo
+       @echo "Link check complete; look for any errors in the above output " \
+             "or in $(BUILDDIR)/linkcheck/output.txt."
+
+doctest:
+       $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
+       @echo "Testing of doctests in the sources finished, look at the " \
+             "results in $(BUILDDIR)/doctest/output.txt."
diff --git a/vendor/drupal/drupal-extension/doc/_static/beehat-drupalicon.png b/vendor/drupal/drupal-extension/doc/_static/beehat-drupalicon.png
new file mode 100644 (file)
index 0000000..eac3558
Binary files /dev/null and b/vendor/drupal/drupal-extension/doc/_static/beehat-drupalicon.png differ
diff --git a/vendor/drupal/drupal-extension/doc/_static/beehat.png b/vendor/drupal/drupal-extension/doc/_static/beehat.png
new file mode 100644 (file)
index 0000000..eac3558
Binary files /dev/null and b/vendor/drupal/drupal-extension/doc/_static/beehat.png differ
diff --git a/vendor/drupal/drupal-extension/doc/_static/composer.json.d8 b/vendor/drupal/drupal-extension/doc/_static/composer.json.d8
new file mode 100644 (file)
index 0000000..f7ec30f
--- /dev/null
@@ -0,0 +1,42 @@
+{
+  "name": "drupal/drupal-extension",
+  "type": "behat-extension",
+  "description": "Drupal extension for Behat",
+  "keywords": ["drupal", "web", "test"],
+  "homepage": "http://drupal.org/project/drupalextension",
+  "license": "GPL-2.0+",
+  "authors": [
+     {
+       "name": "Jonathan Hedstrom",
+       "email": "jhedstrom@gmail.com"
+     }
+  ],
+  "require": {
+    "behat/mink": "~1.5",
+    "behat/mink-goutte-driver": "~1.0",
+    "behat/mink-selenium2-driver": "~1.1",
+    "behat/behat": "~3.1.0-rc2",
+    "behat/mink-extension": "~2.0",
+    "drupal/drupal-driver": "dev-master",
+    "guzzlehttp/guzzle" : "^6.0@dev",
+    "symfony/dependency-injection": "2.8.2",
+    "symfony/event-dispatcher": "2.8.2"
+  },
+  "require-dev": {
+    "phpspec/phpspec": "~2.0",
+    "phpunit/phpunit": "3.7.*",
+    "behat/mink-zombie-driver": "^1.2"
+  },
+  "autoload": {
+    "psr-0": {
+      "Drupal\\Drupal": "src/",
+      "Drupal\\Exception": "src/",
+      "Drupal\\DrupalExtension": "src/"
+    }
+  },
+  "extra": {
+    "branch-alias": {
+      "dev-master": "3.2.x-dev"
+    }
+  }
+}
diff --git a/vendor/drupal/drupal-extension/doc/_static/custom.css b/vendor/drupal/drupal-extension/doc/_static/custom.css
new file mode 100644 (file)
index 0000000..cec3c59
--- /dev/null
@@ -0,0 +1,9 @@
+body {
+  background: green;
+}
+
+
+pre {
+  -moz-border-radius: 15px;
+  border-radius: 15px;
+}
diff --git a/vendor/drupal/drupal-extension/doc/_static/drupalize-purchase-1024.swf b/vendor/drupal/drupal-extension/doc/_static/drupalize-purchase-1024.swf
new file mode 100644 (file)
index 0000000..27210d0
Binary files /dev/null and b/vendor/drupal/drupal-extension/doc/_static/drupalize-purchase-1024.swf differ
diff --git a/vendor/drupal/drupal-extension/doc/_static/favicon.ico b/vendor/drupal/drupal-extension/doc/_static/favicon.ico
new file mode 100644 (file)
index 0000000..963ef66
Binary files /dev/null and b/vendor/drupal/drupal-extension/doc/_static/favicon.ico differ
diff --git a/vendor/drupal/drupal-extension/doc/_static/snippets/FeatureContext.php.inc b/vendor/drupal/drupal-extension/doc/_static/snippets/FeatureContext.php.inc
new file mode 100644 (file)
index 0000000..66d6136
--- /dev/null
@@ -0,0 +1,23 @@
+<?php
+
+use Behat\Behat\Tester\Exception\PendingException;
+use Drupal\DrupalExtension\Context\RawDrupalContext;
+use Behat\Behat\Context\SnippetAcceptingContext;
+use Behat\Gherkin\Node\PyStringNode;
+use Behat\Gherkin\Node\TableNode;
+
+/**
+ * Defines application features from the specific context.
+ */
+class FeatureContext extends RawDrupalContext implements SnippetAcceptingContext {
+
+  /**
+   * Initializes context.
+   *
+   * Every scenario gets its own context instance.
+   * You can also pass arbitrary arguments to the
+   * context constructor through behat.yml.
+   */
+  public function __construct() {
+  }
+}
diff --git a/vendor/drupal/drupal-extension/doc/_static/snippets/aliases.drushrc.php b/vendor/drupal/drupal-extension/doc/_static/snippets/aliases.drushrc.php
new file mode 100644 (file)
index 0000000..ca782a4
--- /dev/null
@@ -0,0 +1,9 @@
+<?php
+$aliases['local'] = array(
+  'root' => '/var/www/seven/drupal',
+  'uri'  =>  'seven.l'
+);
+$aliases['git7site'] = array(
+  'uri'  =>  'git7site.devdrupal.org',
+  'host' => 'git7site.devdrupal.org'
+);
diff --git a/vendor/drupal/drupal-extension/doc/_static/snippets/api.feature b/vendor/drupal/drupal-extension/doc/_static/snippets/api.feature
new file mode 100644 (file)
index 0000000..3fa40c6
--- /dev/null
@@ -0,0 +1,97 @@
+@api
+  Scenario: Create a node
+    Given I am logged in as a user with the "administrator" role
+    When I am viewing an "article" content with the title "My article"
+    Then I should see the heading "My article"
+
+  Scenario: Run cron
+    Given I am logged in as a user with the "administrator" role
+    When I run cron
+    And am on "admin/reports/dblog"
+    Then I should see the link "Cron run completed"
+
+  Scenario: Create many nodes
+    Given "page" content:
+    | title    |
+    | Page one |
+    | Page two |
+    And "article" content:
+    | title          |
+    | First article  |
+    | Second article |
+    And I am logged in as a user with the "administrator" role
+    When I go to "admin/content"
+    Then I should see "Page one"
+    And I should see "Page two"
+    And I should see "First article"
+    And I should see "Second article"
+
+  Scenario: Create nodes with fields
+    Given "article" content:
+    | title                     | promote | body             |
+    | First article with fields |       1 | PLACEHOLDER BODY |
+    When I am on the homepage
+    And follow "First article with fields"
+    Then I should see the text "PLACEHOLDER BODY"
+
+  Scenario: Create and view a node with fields
+    Given I am viewing an "Article" content:
+    | title | My article with fields! |
+    | body  | A placeholder           |
+    Then I should see the heading "My article with fields!"
+    And I should see the text "A placeholder"
+
+  Scenario: Create users
+    Given users:
+    | name     | mail            | status |
+    | Joe User | joe@example.com | 1      |
+    And I am logged in as a user with the "administrator" role
+    When I visit "admin/people"
+    Then I should see the link "Joe User"
+
+  Scenario: Login as a user created during this scenario
+    Given users:
+    | name      | status |
+    | Test user |      1 |
+    When I am logged in as "Test user"
+    Then I should see the link "Log out"
+
+  Scenario: Create a term
+    Given I am logged in as a user with the "administrator" role
+    When I am viewing a "tags" term with the name "My tag"
+    Then I should see the heading "My tag"
+
+  Scenario: Create many terms
+    Given "tags" terms:
+    | name    |
+    | Tag one |
+    | Tag two |
+    And I am logged in as a user with the "administrator" role
+    When I go to "admin/structure/taxonomy/tags"
+    Then I should see "Tag one"
+    And I should see "Tag two"
+
+  Scenario: Create nodes with specific authorship
+    Given users:
+    | name     | mail            | status |
+    | Joe User | joe@example.com | 1      |
+    And "article" content:
+    | title          | author   | body             | promote |
+    | Article by Joe | Joe User | PLACEHOLDER BODY | 1       |
+    When I am logged in as a user with the "administrator" role
+    And I am on the homepage
+    And I follow "Article by Joe"
+    Then I should see the link "Joe User"
+
+  Scenario: Create an article with multiple term references
+    Given "tags" terms:
+    | name      |
+    | Tag one   |
+    | Tag two   |
+    | Tag three |
+    | Tag four  |
+    And "article" content:
+    | title             | field_tags                   |
+    | My first article  | Tag one                      |
+    | My second article | Tag two, Tag three           |
+    | My third article  | Tag two, Tag three, Tag four |
diff --git a/vendor/drupal/drupal-extension/doc/_static/snippets/apitag.feature b/vendor/drupal/drupal-extension/doc/_static/snippets/apitag.feature
new file mode 100644 (file)
index 0000000..fcae32d
--- /dev/null
@@ -0,0 +1,15 @@
+Feature: Drush alias
+  In order to demonstrate the Drush driver
+  As a trainer
+  I need to show how to tag scenarios 
+
+  Scenario: Untagged scenario uses blackbox driver and fails
+    Given I am logged in as a user with the "authenticated user" role
+    When I click "My account"
+    Then I should see the heading "History"
+
+  @api
+  Scenario: Tagged scenario uses Drush driver and succeeds
+    Given I am logged in as a user with the "authenticated user" role
+    When I click "My account"
+    Then I should see the heading "History"
diff --git a/vendor/drupal/drupal-extension/doc/_static/snippets/apitag.output b/vendor/drupal/drupal-extension/doc/_static/snippets/apitag.output
new file mode 100644 (file)
index 0000000..f9fea8d
--- /dev/null
@@ -0,0 +1,29 @@
+Feature: Drush alias
+  In order to demonstrate the Drush driver
+  As a trainer
+  I need to show how to tag scenarios
+
+  Scenario: Untagged scenario uses blackbox driver and fails
+    # features/drush.feature:6
+    Given I am logged in as a user with the "authenticated user" role 
+    # FeatureContext::iAmLoggedInWithRole()
+      No ability to create users in Drupal\Driver\BlackboxDriver. 
+      Put `@api` into your feature and add an api driver 
+      (ex: `api_driver: drupal`) in behat.yml.
+    When I click "My account"                                         
+    # FeatureContext::iClick()
+    Then I should see the heading "History"                           
+    # FeatureContext::assertHeading()
+
+  @api
+  Scenario: Tagged scenario uses Drush driver and succeeds            
+            # features/drush.feature:12
+    Given I am logged in as a user with the "authenticated user" role 
+    # FeatureContext::iAmLoggedInWithRole()
+    When I click "My account"                                         
+    # FeatureContext::iClick()
+    Then I should see the heading "History"                           
+    # FeatureContext::assertHeading()
+
+2 scenarios (1 passed, 1 failed)
+6 steps (3 passed, 2 skipped, 1 failed)
diff --git a/vendor/drupal/drupal-extension/doc/_static/snippets/behat-1.yml b/vendor/drupal/drupal-extension/doc/_static/snippets/behat-1.yml
new file mode 100644 (file)
index 0000000..b2bf239
--- /dev/null
@@ -0,0 +1,16 @@
+default:
+  suites:
+    default:
+      contexts:
+        - FeatureContext
+        - Drupal\DrupalExtension\Context\DrupalContext
+        - Drupal\DrupalExtension\Context\MinkContext
+        - Drupal\DrupalExtension\Context\MessageContext
+        - Drupal\DrupalExtension\Context\DrushContext
+  extensions:
+    Behat\MinkExtension:
+      goutte: ~
+      selenium2: ~
+      base_url: http://seven.l
+    Drupal\DrupalExtension:
+      blackbox: ~
diff --git a/vendor/drupal/drupal-extension/doc/_static/snippets/behat-api.yml b/vendor/drupal/drupal-extension/doc/_static/snippets/behat-api.yml
new file mode 100644 (file)
index 0000000..1210f30
--- /dev/null
@@ -0,0 +1,21 @@
+default:
+  suites:
+    default:
+      contexts:
+        - FeatureContext
+        - Drupal\DrupalExtension\Context\DrupalContext
+        - Drupal\DrupalExtension\Context\MinkContext
+  extensions:
+    Behat\MinkExtension:
+      goutte: ~
+      selenium2: ~
+      base_url: http://seven.l
+    Drupal\DrupalExtension:
+      blackbox: ~
+      api_driver: 'drupal' 
+      drush:
+        alias: 'local'
+      drupal: 
+        drupal_root: '/var/www/seven/drupal' 
+      region_map:
+        footer: "#footer"
diff --git a/vendor/drupal/drupal-extension/doc/_static/snippets/behat-auto.yml b/vendor/drupal/drupal-extension/doc/_static/snippets/behat-auto.yml
new file mode 100644 (file)
index 0000000..aefa9e0
--- /dev/null
@@ -0,0 +1,25 @@
+default:
+  suites:
+    default:
+      contexts:
+        - FeatureContext
+        - Drupal\DrupalExtension\Context\DrupalContext
+        - Drupal\DrupalExtension\Context\MinkContext
+  extensions:
+    Behat\MinkExtension:
+      goutte: ~
+      selenium2: ~
+      base_url: http://seven.l
+    Drupal\DrupalExtension:
+      blackbox: ~
+      api_driver: 'drupal' 
+      drush:
+        alias: 'local'
+      drupal: 
+        drupal_root: '/var/www/seven/drupal' 
+      region_map:
+        footer: "#footer"
+      subcontexts:
+        paths:
+          - "/var/www/seven/drupal/sites/all"
+        autoload: 0
diff --git a/vendor/drupal/drupal-extension/doc/_static/snippets/behat-bb.yml b/vendor/drupal/drupal-extension/doc/_static/snippets/behat-bb.yml
new file mode 100644 (file)
index 0000000..a58d65d
--- /dev/null
@@ -0,0 +1,16 @@
+default:
+  suites:
+    default:
+      contexts:
+        - FeatureContext
+        - Drupal\DrupalExtension\Context\DrupalContext
+        - Drupal\DrupalExtension\Context\MinkContext
+  extensions:
+    Behat\MinkExtension:
+      goutte: ~
+      selenium2: ~
+      base_url: http://seven.l
+    Drupal\DrupalExtension:
+      blackbox: ~
+      region_map:
+        footer: "#footer"
diff --git a/vendor/drupal/drupal-extension/doc/_static/snippets/behat-drush.yml b/vendor/drupal/drupal-extension/doc/_static/snippets/behat-drush.yml
new file mode 100644 (file)
index 0000000..65a86d9
--- /dev/null
@@ -0,0 +1,19 @@
+default:
+  suites:
+    default:
+      contexts:
+        - FeatureContext
+        - Drupal\DrupalExtension\Context\DrupalContext
+        - Drupal\DrupalExtension\Context\MinkContext
+  extensions:
+    Behat\MinkExtension:
+      goutte: ~
+      selenium2: ~
+      base_url: http://seven.l
+    Drupal\DrupalExtension:
+      blackbox: ~
+      api_driver: 'drush' 
+      drush:
+        alias: 'local'
+      region_map:
+        footer: "#footer"
diff --git a/vendor/drupal/drupal-extension/doc/_static/snippets/behat-sub.yml b/vendor/drupal/drupal-extension/doc/_static/snippets/behat-sub.yml
new file mode 100644 (file)
index 0000000..0096b72
--- /dev/null
@@ -0,0 +1,27 @@
+default:
+  suites:
+    default:
+      contexts:
+        - FeatureContext
+        - Drupal\DrupalExtension\Context\DrupalContext
+        - Drupal\DrupalExtension\Context\MinkContext
+      paths:
+        - "./path_to_module/features"
+  extensions:
+    Behat\MinkExtension:
+      goutte: ~
+      selenium2: ~
+      base_url: http://seven.l
+    Drupal\DrupalExtension:
+      blackbox: ~
+      api_driver: 'drupal' 
+      drush:
+        alias: 'local'
+      drupal: 
+        drupal_root: '/var/www/seven/drupal' 
+      region_map:
+        footer: "#footer"
+      subcontexts:
+        paths:
+          - "/var/www/seven/drupal/sites/all"
+
diff --git a/vendor/drupal/drupal-extension/doc/_static/snippets/blackbox.feature b/vendor/drupal/drupal-extension/doc/_static/snippets/blackbox.feature
new file mode 100644 (file)
index 0000000..5265570
--- /dev/null
@@ -0,0 +1,81 @@
+Feature: Test DrupalContext
+  In order to prove the Drupal context using the blackbox driver is working properly
+  As a developer
+  I need to use the step definitions of this context
+
+  Scenario: Test the ability to find a heading in a region
+    Given I am on the homepage
+    When I click "Download & Extend"
+    Then I should see the heading "Core" in the "content" region
+
+  Scenario: Clicking content in a region
+    Given I am at "download"
+    When I click "About Distributions" in the "content" region
+    Then I should see "Page status" in the "right sidebar"
+    And I should see the link "Drupal News" in the "footer" region
+
+  Scenario: Viewing content in a region
+    Given I am on the homepage
+    Then I should see "Come for the software, stay for the community" in the "left header"
+
+  Scenario: Test ability to find text that should not appear in a region
+    Given I am on the homepage
+    Then I should not see the text "Proprietary software is cutting edge" in the "left header"
+
+  Scenario: Submit a form in a region
+    Given I am on the homepage
+    When I fill in "Search Drupal.org" with "Views" in the "right header" region
+    And I press "Search" in the "right header" region
+    Then I should see the text "Search again" in the "right sidebar" region
+
+  Scenario: Check a link should not exist in a region
+    Given I am on the homepage
+    Then I should not see the link "This link should never exist in a default Drupal install" in the "right header"
+
+  Scenario: Find a button
+    Given I am on the homepage
+    Then I should see the "Search" button
+
+  Scenario: Find a button in a region
+    Given I am on the homepage
+    Then I should see the "Search" button in the "right header"
+
+  Scenario: Find an element in a region
+    Given I am on the homepage
+    Then I should see the "h1" element in the "left header"
+
+  Scenario: Element not in region
+    Given I am on the homepage
+    Then I should not see the "h1" element in the "footer"
+
+  Scenario: Text not in element in region
+    Given I am on the homepage
+    Then I should not see "DotNetNuke" in the "h1" element in the "left header"
+
+  Scenario: Find an element with an attribute in a region
+    Given I am on the homepage
+    Then I should see the "h1" element with the "id" attribute set to "site-name" in the "left header" region
+
+  Scenario: Find text in an element with an attribute in a region
+    Given I am on the homepage
+    Then I should see "Drupal" in the "h1" element with the "id" attribute set to "site-name" in the "left header" region
+
+  Scenario: Error messages
+   Given I am on "/user"
+   When I press "Log in"
+   Then I should see the error message "Password field is required"
+   And I should not see the error message "Sorry, unrecognized username or password"
+   And I should see the following error messages:
+   | error messages             |
+   | Username field is required |
+   | Password field is required |
+   And I should not see the following error messages:
+   | error messages                                                                |
+   | Sorry, unrecognized username or password                                      |
+   | Unable to send e-mail. Contact the site administrator if the problem persists |
+
+ Scenario: Messages
+   Given I am on "/user/register"
+   When I press "Create new account"
+   Then I should see the message "Username field is required"
+   But I should not see the message "Registration successful. You are now logged in"
diff --git a/vendor/drupal/drupal-extension/doc/_static/snippets/composer.json b/vendor/drupal/drupal-extension/doc/_static/snippets/composer.json
new file mode 100644 (file)
index 0000000..67a5b38
--- /dev/null
@@ -0,0 +1,8 @@
+{
+  "require": {
+    "drupal/drupal-extension": "^3.2"
+  },
+  "config": {
+    "bin-dir": "bin/"
+  }
+}
diff --git a/vendor/drupal/drupal-extension/doc/_static/snippets/composer.json.d8 b/vendor/drupal/drupal-extension/doc/_static/snippets/composer.json.d8
new file mode 100644 (file)
index 0000000..208baf3
--- /dev/null
@@ -0,0 +1,9 @@
+{
+  "require": {
+    "drupal/drupal-extension": "^3.2",
+    "guzzlehttp/guzzle" : "^6.0@dev"
+  },
+  "config": {
+    "bin-dir": "bin/"
+  }
+}
diff --git a/vendor/drupal/drupal-extension/doc/_static/snippets/context-communication.inc b/vendor/drupal/drupal-extension/doc/_static/snippets/context-communication.inc
new file mode 100644 (file)
index 0000000..fbbb7ae
--- /dev/null
@@ -0,0 +1,15 @@
+<?php
+
+// Snippet to demonstrate context communications.
+
+  /**
+   * Gather any contexts needed.
+   *
+   * @BeforeScenario
+   */
+  public function gatherContexts(BeforeScenarioScope $scope) {
+    $environment = $scope->getEnvironment();
+
+    $this->drupalContext = $environment->getContext('Drupal\DrupalExtension\Context\DrupalContext');
+    $this->minkContext = $environment->getContext('Drupal\DrupalExtension\Context\MinkContext');
+  }
diff --git a/vendor/drupal/drupal-extension/doc/_static/snippets/drush.feature b/vendor/drupal/drupal-extension/doc/_static/snippets/drush.feature
new file mode 100644 (file)
index 0000000..d458fcb
--- /dev/null
@@ -0,0 +1,22 @@
+@api
+Feature: Drush driver
+  In order to show functionality added by the Drush driver 
+  As a trainer
+  I need to use the step definitions it supports
+
+  Scenario: Drush alias
+    Given I am logged in as a user with the "authenticated user" role
+    When I click "My account"
+    Then I should see the heading "History"
+
+  Scenario: Target links within table rows
+    Given I am logged in as a user with the "administrator" role
+    When I am at "admin/structure/types"
+    And I click "manage fields" in the "Article" row
+    Then I should be on "admin/structure/types/manage/article/fields"
+    And I should see text matching "Add new field"
+
+  Scenario: Clear cache
+    Given the cache has been cleared
+    When I am on the homepage
+    Then I should get a "200" HTTP response
diff --git a/vendor/drupal/drupal-extension/doc/_static/snippets/subcontext.inc b/vendor/drupal/drupal-extension/doc/_static/snippets/subcontext.inc
new file mode 100644 (file)
index 0000000..cf6247f
--- /dev/null
@@ -0,0 +1,55 @@
+<?php
+
+/**
+ * Contains \FooFoo.
+ */
+
+use Behat\Behat\Hook\Scope\BeforeScenarioScope;
+use Behat\Behat\Tester\Exception\PendingException;
+use Drupal\DrupalExtension\Context\DrupalSubContextBase;
+use Drupal\DrupalExtension\Context\DrupalSubContextInterface;
+
+/**
+ * Example subcontext.
+ */
+class FooFoo extends DrupalSubContextBase implements DrupalSubContextInterface {
+
+  /**
+   * @var \Drupal\DrupalExtension\Context\DrupalContext
+   */
+  protected $drupalContext;
+
+  /**
+   * @var \Drupal\DrupalExtension\Context\MinkContext
+   */
+  protected $minkContext;
+
+  /**
+   * @BeforeScenario
+   */
+  public function gatherContexts(BeforeScenarioScope $scope) {
+    $environment = $scope->getEnvironment();
+
+    $this->drupalContext = $environment->getContext('Drupal\DrupalExtension\Context\DrupalContext');
+    $this->minkContext = $environment->getContext('Drupal\DrupalExtension\Context\MinkContext');
+  }
+
+  /**
+   * @Given I create a(an) :arg1 content type
+   */
+  public function CreateAContentType($arg1) {
+    $this->minkContext->assertAtPath("admin/structure/types/add");
+    $node = [
+      'title' => 'Test content!',
+    ];
+    $this->drupalContext->nodeCreate($node);
+  }
+
+  /**
+   * @Then /^I should have a subcontext definition$/
+   */
+  public function assertSubContextDefinition() {
+    throw new PendingException();
+  }
+
+}
diff --git a/vendor/drupal/drupal-extension/doc/blackbox.rst b/vendor/drupal/drupal-extension/doc/blackbox.rst
new file mode 100644 (file)
index 0000000..f6a3477
--- /dev/null
@@ -0,0 +1,95 @@
+Blackbox Driver
+===============
+
+The blackbox driver assumes no privileged access to the site. You can run the
+tests on a local or remote server, and all the actions will take place through
+the site's user interface. This driver was enabled as part of the installation
+instructions by lines 13 and 14, highlighted below.
+
+.. literalinclude:: _static/snippets/behat-bb.yml
+   :language: yaml
+   :linenos:
+   :lines: 1-14
+   :emphasize-lines: 13-14
+
+Region steps
+------------
+
+It may be really important that a block is in the correct region, or you may
+have a link or button that doesn't have a unique label. The blackbox driver
+allows you to create a map between a CSS selector and a user-readable region
+name so you can use steps like the following without having to write any custom
+PHP::
+
+
+  I press "Search" in the "header" region
+  I fill in "a value" for "a field" in the "content" region
+  I fill in "a field" with "Stuff" in the "header" region
+  I click "About us" in the "footer" region
+
+Example:
+++++++++
+
+A stock Drupal 7 installation has a footer area identified by the CSS Id
+"footer". By editing the behat.yml file and adding lines 15 and 16 below:
+
+.. literalinclude:: _static/snippets/behat-bb.yml
+   :language: yaml
+   :linenos:
+   :emphasize-lines: 15-16
+
+You can use a step like the following without writing any custom PHP::
+
+  When I click "About us" in the "footer" region.
+
+
+Using the blackbox driver configured with the regions of your site, you can
+access the following region-related steps:
+
+.. Note::
+    These examples won't work unless you define the appropriate regions in
+     your behat.yml file.
+
+.. literalinclude:: _static/snippets/blackbox.feature
+   :language: gherkin
+   :linenos:
+   :lines: 1-61
+
+Message selectors
+-----------------
+
+The Drupal Extension makes use of three selectors for message. If your CSS
+values are different than the defaults (shown below), you'll need to update
+your behat.yml file:
+
+.. code-block:: yaml
+   :linenos:
+   :emphasize-lines: 2-5
+
+    Drupal\DrupalExtension:
+      selectors:
+        message_selector: '.messages'
+        error_message_selector: '.messages.messages-error'
+        success_message_selector: '.messages.messages-status'
+
+Message-related steps include:
+
+.. literalinclude::  _static/snippets/blackbox.feature
+   :language: gherkin
+   :linenos:
+   :lines: 63-81
+
+Override text strings
+---------------------
+
+The Drupal Extension relies on default text for certain steps. If you have
+customized the label visible to users, you can change that text as follows:
+
+.. code-block:: yaml
+
+     Drupal\DrupalExtension:
+       text:
+         log_out: "Sign out"
+         log_in: "Sign in"
+         password_field: "Enter your password"
+         username_field: "Nickname"
diff --git a/vendor/drupal/drupal-extension/doc/conf.py b/vendor/drupal/drupal-extension/doc/conf.py
new file mode 100644 (file)
index 0000000..7a6d4f7
--- /dev/null
@@ -0,0 +1,252 @@
+# -*- coding: utf-8 -*-
+#
+# the Drupal Extension to Behat and Mink documentation build configuration file, created by
+# sphinx-quickstart on Sun Jul  7 09:40:13 2013.
+#
+# This file is execfile()d with the current directory set to its containing dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+import sys, os
+
+# Check if this build is on readthedocs.org
+on_rtd = os.environ.get('READTHEDOCS', None) == 'True'
+if not on_rtd:
+  import sphinx_rtd_theme
+  html_theme = "sphinx_rtd_theme"
+  html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#sys.path.insert(0, os.path.abspath('.'))
+
+# -- General configuration -----------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+#needs_sphinx = '1.0'
+
+# Add any Sphinx extension module names here, as strings. They can be extensions
+# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
+extensions = ['sphinx.ext.todo', 'sphinx.ext.ifconfig']
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The suffix of source filenames.
+source_suffix = '.rst'
+
+# The encoding of source files.
+#source_encoding = 'utf-8-sig'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = u'the Drupal Extension to Behat and Mink'
+copyright = u'2013, Melissa Anderson'
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The short X.Y version.
+version = '1.1'
+# The full version, including alpha/beta/rc tags.
+release = '1.1'
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#language = None
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+#today_fmt = '%B %d, %Y'
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+exclude_patterns = ['_build']
+
+# The reST default role (used for this markup: `text`) to use for all documents.
+#default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+# pygments_style = 'sphinx'
+
+# A list of ignored prefixes for module index sorting.
+#modindex_common_prefix = []
+
+
+# -- Options for HTML output ---------------------------------------------------
+
+# The theme to use for HTML and HTML Help pages.  See the documentation for
+# a list of builtin themes.
+#html_theme = 'default'
+#html_sidebars = {
+#  '**':['globaltoc.html','searchbox.html'],
+#  'using/windows': ['windowssidebar.html', 'searchbox.html'],
+#}
+# Theme options are theme-specific and customize the look and feel of a theme
+# further.  For a list of options available for each theme, see the
+# documentation.
+#html_theme_options = {}
+
+# Add any paths that contain custom themes here, relative to this directory.
+#html_theme_path = []
+
+# The name for this set of Sphinx documents.  If None, it defaults to
+# "<project> v<release> documentation".
+#html_title = None
+
+# A shorter title for the navigation bar.  Default is the same as html_title.
+#html_short_title = None
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+#html_logo = None
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+html_favicon = "_static/favicon.ico"
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['_static']
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+#html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+#html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#html_additional_pages = {}
+
+# If false, no module index is generated.
+#html_domain_indices = True
+
+# If false, no index is generated.
+#html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+#html_split_index = False
+
+# If true, links to the reST sources are added to the pages.
+#html_show_sourcelink = True
+
+# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
+#html_show_sphinx = True
+
+# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
+html_show_copyright = False 
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a <link> tag referring to it.  The value of this option must be the
+# base URL from which the finished HTML is served.
+#html_use_opensearch = ''
+
+# This is the file name suffix for HTML files (e.g. ".xhtml").
+#html_file_suffix = None
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'theDrupalExtensiontoBehatandMinkdoc'
+
+
+# -- Options for LaTeX output --------------------------------------------------
+
+latex_elements = {
+# The paper size ('letterpaper' or 'a4paper').
+#'papersize': 'letterpaper',
+
+# The font size ('10pt', '11pt' or '12pt').
+#'pointsize': '10pt',
+
+# Additional stuff for the LaTeX preamble.
+#'preamble': '',
+}
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title, author, documentclass [howto/manual]).
+latex_documents = [
+  ('index', 'theDrupalExtensiontoBehatandMink.tex', u'the Drupal Extension to Behat and Mink Documentation',
+   u'Melissa Anderson', 'manual'),
+]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+#latex_logo = None
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+#latex_use_parts = False
+
+# If true, show page references after internal links.
+#latex_show_pagerefs = False
+
+# If true, show URL addresses after external links.
+#latex_show_urls = False
+
+# Documents to append as an appendix to all manuals.
+#latex_appendices = []
+
+# If false, no module index is generated.
+#latex_domain_indices = True
+
+
+# -- Options for manual page output --------------------------------------------
+
+# One entry per manual page. List of tuples
+# (source start file, name, description, authors, manual section).
+man_pages = [
+    ('main.rst', 'thedrupalextensiontobehatandmink', u'the Drupal Extension to Behat and Mink Documentation',
+     [u'Melissa Anderson'], 1)
+]
+
+# If true, show URL addresses after external links.
+#man_show_urls = False
+
+
+# -- Options for Texinfo output ------------------------------------------------
+
+# Grouping the document tree into Texinfo files. List of tuples
+# (source start file, target name, title, author,
+#  dir menu entry, description, category)
+texinfo_documents = [
+  ('main.rst', 'theDrupalExtensiontoBehatandMink', u'the Drupal Extension to Behat and Mink Documentation',
+   u'Melissa Anderson', 'theDrupalExtensiontoBehatandMink', 'One line description of project.',
+   'Miscellaneous'),
+]
+
+# Documents to append as an appendix to all manuals.
+#texinfo_appendices = []
+
+# If false, no module index is generated.
+#texinfo_domain_indices = True
+
+# How to display URL addresses: 'footnote', 'no', or 'inline'.
+#texinfo_show_urls = 'footnote'
diff --git a/vendor/drupal/drupal-extension/doc/contexts.rst b/vendor/drupal/drupal-extension/doc/contexts.rst
new file mode 100644 (file)
index 0000000..aee8114
--- /dev/null
@@ -0,0 +1,112 @@
+Contexts
+========
+
+Before Behat 3, each test suite was limited to a single context class. As of
+Behat 3, it is possible to flexibly structure your code by using multiple
+contexts in a single test suite.
+
+Available Contexts
+------------------
+
+In accordance with this new capability, The Drupal Extension includes the
+following contexts:
+
+*RawDrupalContext*
+  A context that provides no step definitions, but all of the
+  necessary functionality for interacting with Drupal, and with the
+  browser via Mink sessions.
+
+*DrupalContext*
+  Provides step-definitions for creating users, terms, and nodes.
+
+*MinkContext*
+  Builds on top of the Mink Extension and adds steps specific to regions and
+  forms.
+
+*MarkupContext*
+  Contains step definitions that deal with low-level markup (such as tags,
+  classes, and attributes).
+
+*MessageContext*
+  Step-definitions that are specific to Drupal messages that get displayed
+  (notice, warning, and error).
+
+*DrushContext*
+  Allows steps to directly call drush commands.
+
+Custom Contexts
+---------------
+
+You can structure your own code with additional contexts. See Behat's `testing features <http://docs.behat.org/en/latest/guides/4.contexts.html>`_ documentation for a detailed discussion of how contexts work.
+
+.. Important::
+
+   Every context you want to use in a suite must declare it in the behat.yml
+   file.
+
+Example
+#######
+
+In this example, you would have access to:
+
+ * pre-written step definitions for users, terms, and nodes
+   (from the ``DrupalContext``)
+ * steps you've implemented in the  main
+   ``features/bootstrap/FeatureContext.php`` file
+ * steps you've implemented in the ``CustomContext`` class
+
+You would not have access to the steps from the ``MarkupContext``,
+``MessageContext``, or ``DrushContext``, however.
+
+.. code-block:: yaml
+   :linenos:
+
+    default:
+      suites:
+        default:
+          contexts:
+            - Drupal\DrupalExtension\Context\DrupalContext
+            - FeatureContext
+            - CustomContext
+
+Context communication
+---------------------
+
+Since Behat 3 can have many concurrent contexts active, communication between those  contexts can be important.
+
+The following will gather any specified contexts before a given scenario is run:
+
+  .. literalinclude:: _static/snippets/context-communication.inc
+     :language: php
+     :linenos:
+
+Drupal Extension Hooks
+----------------------
+
+In addition to the `hooks provided by Behat
+<http://behat.readthedocs.org/en/v2.5/guides/3.hooks.html>`_, the Drupal
+Extension provides three additional ways to tag the methods in your
+``CustomContext`` class in order to have them fire before certain events.
+
+  1. ``@beforeNodeCreate``
+  2. ``@beforeTermCreate``
+  3. ``@beforeUserCreate``
+
+Example
+#######
+
+.. code-block:: php
+   :linenos:
+
+     use Drupal\DrupalExtension\Hook\Scope\EntityScope;
+      ...
+      /**
+       * Call this function before nodes are created.
+       *
+       * @beforeNodeCreate
+       */
+       public function alterNodeObject(EntityScope $scope) {
+         $node = $scope->getEntity();
+         // Alter node object as needed.
+       }
+
diff --git a/vendor/drupal/drupal-extension/doc/drivers.rst b/vendor/drupal/drupal-extension/doc/drivers.rst
new file mode 100644 (file)
index 0000000..713f4a0
--- /dev/null
@@ -0,0 +1,24 @@
+Drupal Extension Drivers
+========================
+
+The Drupal Extension provides drivers for interacting with your site which are
+compatible with Drupal 6, 7, and 8. Each driver has its own limitations.
+
++-----------------------+----------+---------+------------+
+| Feature               | Blackbox | Drush   | Drupal API |
++=======================+==========+=========+============+
+| Map Regions           | Yes      | Yes     | Yes        |
++-----------------------+----------+---------+------------+
+| Create users          | No       | Yes     | Yes        |
++-----------------------+----------+---------+------------+
+| Create nodes          | No       | Yes [*] | Yes        |
++-----------------------+----------+---------+------------+
+| Create vocabularies   | No       | Yes [*] | Yes        |
++-----------------------+----------+---------+------------+
+| Create taxonomy terms | No       | Yes [*] | Yes        |
++-----------------------+----------+---------+------------+
+| Run tests and site    |          |         |            |
+| on different servers  | Yes      | Yes     | No         |
++-----------------------+----------+---------+------------+
+
+[*] Requires that the `Behat Drush Endpoint <https://github.com/drush-ops/behat-drush-endpoint>`_ be installed on the Drupal site under test.
diff --git a/vendor/drupal/drupal-extension/doc/drupalapi.rst b/vendor/drupal/drupal-extension/doc/drupalapi.rst
new file mode 100644 (file)
index 0000000..c8f5d2a
--- /dev/null
@@ -0,0 +1,29 @@
+Drupal API Driver
+=================
+
+The Drupal API Driver is the fastest and the most powerful of the three
+drivers. Its biggest limitation is that the tests must run on the same server
+as the Drupal site.
+
+Enable the Drupal API Driver
+----------------------------
+To enable the Drupal API driver, edit the behat.yml file, change the api_driver
+to drupal and add the path to the local Drupal installation as shown below:
+
+.. literalinclude:: _static/snippets/behat-api.yml
+   :language: php
+   :linenos:
+   :emphasize-lines: 15,18-19
+
+.. note:: 
+   It's fine to leave the information for the drush driver in the file. It's 
+   the api_driver value that declares which setting will be used for scenarios 
+   tagged @api.
+
+Using this driver, you gain the ability to use all the steps in the 
+examples below (and more).
+
+.. literalinclude::  _static/snippets/api.feature
+   :language: gherkin
+   :linenos:
+   :emphasize-lines: 1
diff --git a/vendor/drupal/drupal-extension/doc/drush.rst b/vendor/drupal/drupal-extension/doc/drush.rst
new file mode 100644 (file)
index 0000000..6126b0d
--- /dev/null
@@ -0,0 +1,96 @@
+Drush Driver
+============
+
+Many tests require that a user logs into the site. With the blackbox driver,
+all user creation and login would have to take place via the user interface,
+which quickly becomes tedious and time consuming. You can use the Drush driver
+to add users, reset passwords, and log in by following the steps below, again,
+without having to write custom PHP. You can also do this with the Drupal API
+driver. The main advantage of the Drush driver is that it can work when your
+tests run on a different server than the site being tested.
+
+Install Drush
+-------------
+
+See the `Drush project page <https://drupal.org/project/drush>`_ for
+installation directions.
+
+Install the Behat Drush Endpoint
+--------------------------------
+
+The Behat Drush Endpoint is a Drush-based service that the Drush Driver uses in order to create content on the Drupal site being tested.  See the `Behat Drush Endpoint project page <https://github.com/drush-ops/behat-drush-endpoint>`_ for instructions on how to install it with your Drupal site.
+
+Point Drush at your Drupal site
+-------------------------------
+
+Drupal Alias (For local or remote sites)
+++++++++++++++++++++++++++++++++++++++++
+
+You'll need ssh-key access to a remote server to use Drush. If Drush and Drush
+aliases are new to you, see the `Drush site <http://drush.ws/help>`_ for
+`detailed examples <http://drush.ws/examples/example.aliases.drushrc.php>`_
+
+The alias for our example looks like:
+
+.. literalinclude:: _static/snippets/aliases.drushrc.php
+   :language: php
+   :linenos:
+
+Path to Drupal (local sites only)
++++++++++++++++++++++++++++++++++
+
+If you'll only be running drush commands to access a site on the same machine,
+you can specify the path to your Drupal root:
+
+.. code-block:: yaml
+   :linenos:
+
+    Drupal\DrupalExtension:
+      blackbox: ~
+    drush:
+      root: /my/path/to/drupal
+
+
+Enable the Drush driver
+-----------------------
+
+In the behat.yml file:
+
+.. literalinclude:: _static/snippets/behat-drush.yml
+   :language: yaml
+   :linenos:
+   :emphasize-lines: 15-17
+
+.. note:: Line 15 isn't strictly necessary for the Drush driver, which is the
+          default for the API.
+
+Calling the Drush driver
+------------------------
+
+Untagged tests use the blackbox driver. To invoke the Drush driver, tag the
+scenario with @api
+
+.. literalinclude:: _static/snippets/apitag.feature
+   :language: gherkin
+   :linenos:
+   :emphasize-lines: 11
+
+If you try to run a test without that tag, it will fail.
+
+Example:
+++++++++
+
+.. literalinclude:: _static/snippets/apitag.output
+   :language: gherkin
+   :linenos:
+   :emphasize-lines: 10-12
+   :lines: 1-24
+
+The Drush driver gives you access to all the blackbox steps, plus those used in
+each of the following examples:
+
+.. literalinclude:: _static/snippets/drush.feature
+   :language: gherkin
+   :linenos:
+
+If the Behat Drush Endpoint is installed on the Drupal site being tested, then you will also have access to all of the examples shown for the Drupal API driver.
diff --git a/vendor/drupal/drupal-extension/doc/environment.rst b/vendor/drupal/drupal-extension/doc/environment.rst
new file mode 100644 (file)
index 0000000..8454e1a
--- /dev/null
@@ -0,0 +1,42 @@
+Environment specific settings
+=============================
+
+Some of the settings in ``behat.yml`` are environment specific. For example the
+base URL may be ``http://mysite.localhost`` on your local development
+environment, while on a test server it might be ``http://127.0.0.1:8080``. Some
+other environment specific settings are the Drupal root path and the paths to
+search for subcontexts.
+
+If you intend to run your tests on different environments these settings should
+not be committed to ``behat.yml``. Instead they should be exported in an
+environment variable. Before running tests Behat will check the ``BEHAT_PARAMS``
+environment variable and add these settings to the ones that are present in
+``behat.yml``. This variable should contain a JSON object with your settings.
+
+Example JSON object:
+
+.. code-block:: json
+
+    {
+        "extensions": {
+            "Behat\\MinkExtension": {
+                "base_url": "http://myproject.localhost"
+            },
+            "Drupal\\DrupalExtension": {
+                "drupal": {
+                    "drupal_root": "/var/www/myproject"
+                }
+            }
+        }
+    }
+
+
+To export this into the ``BEHAT_PARAMS`` environment variable, squash the JSON
+object into a single line and surround with single quotes:
+
+.. code-block: bash
+
+    $ export BEHAT_PARAMS='{"extensions":{"Behat\\MinkExtension":{"base_url":"http://myproject.localhost"},"Drupal\\DrupalExtension":{"drupal":{"drupal_root":"/var/www/myproject"}}}}'
+
+There is also a `Drush extension <https://github.com/pfrenssen/drush-bde-env>`_
+that can help you generate these environment variables.
diff --git a/vendor/drupal/drupal-extension/doc/globalinstall.rst b/vendor/drupal/drupal-extension/doc/globalinstall.rst
new file mode 100644 (file)
index 0000000..de233b2
--- /dev/null
@@ -0,0 +1,119 @@
+System-wide installation 
+========================
+
+A system-wide installation allows you to maintain a single copy of the testing
+tool set and use it for multiple test environments. Configuration is slightly
+more complex than the stand-alone installation but many people prefer the
+flexibility and ease-of-maintenance this setup provides.
+
+Overview 
+--------
+
+To install the Drupal Extension globally:
+
+#. Install Composer 
+#. Install the Drupal Extension in `/opt/drupalextension` 
+#. Create an alias to the behat binary in `/usr/local/bin` 
+#. Create your test folder
+
+Install Composer 
+----------------
+
+Composer is a PHP dependency manager that will make sure all the pieces you
+need get installed. `Full directions for global installation
+<http://getcomposer.org/doc/00-intro.md#globally>`_ and more information can be
+found on the `Composer website <http://getcomposer.org/>`_.::
+
+  curl -sS https://getcomposer.org/installer | 
+  php mv composer.phar /usr/local/bin/composer
+
+Install the Drupal Extension 
+----------------------------
+
+#. Make a directory in /opt (or wherever you choose) for the Drupal Extension::
+
+    cd /opt/ 
+    sudo mkdir drupalextension
+    cd drupalextension/
+
+2. Create a file called `composer.json` and include the following:
+  
+  .. literalinclude:: _static/snippets/composer.json 
+     :language: javascript 
+     :linenos:
+
+3. Run the install command::
+
+    sudo composer install
+
+  It will be a bit before you start seeing any output. It will also suggest
+  that you install additional tools, but they're not normally needed so you can
+  safely ignore that message.
+
+4. Test that your install worked by typing the following::
+
+    bin/behat --help
+
+  If you were successful, you'll see the help output.
+
+5. Make the binary available system-wide::
+
+    ln -s /opt/drupalextension/bin/behat /usr/local/bin/behat
+
+Set up tests 
+------------ 
+
+1. Create the directory that will hold your tests. There is no technical
+   reason this needs to be inside the Drupal directory at all. It is best to
+   keep them in the same version control repository so that the tests match the 
+   version of the site they are written for.
+
+  One clear pattern is to keep them in the sites folder as follows:
+
+  Single site: `sites/default/behat-tests`
+  
+  Multi-site or named single site: `/sites/my.domain.com/behat-tests`
+
+2. Wherever you make your test folder, inside it create the behat.yml file:
+
+  .. literalinclude:: _static/snippets/behat-1.yml 
+     :language: yaml 
+     :linenos:
+
+3. Initialize behat. This creates the features folder with some basic things to
+   get you started::
+
+    bin/behat --init
+
+4. This will generate a FeatureContext.php file that looks like:
+
+  .. literalinclude:: _static/snippets/FeatureContext.php.inc
+     :language: php 
+     :linenos: 
+     :emphasize-lines: 12 
+
+  This will make your FeatureContext.php aware of both the Drupal Extension and
+  the Mink Extension, so you'll be able to take advantage of their drivers and
+  step definitions and add your own custom step definitions here. 
+  The FeatureContext.php file must be in the same directory as your behat.yml
+  file otherwise in step 5 you will get the following error:
+  
+    [Behat\Behat\Context\Exception\ContextNotFoundException]
+    `FeatureContext` context class not found and can not be used. 
+  
+
+5. To ensure everything is set up appropriately, type::
+
+    behat -dl
+
+   You'll see a list of steps like the following, but longer, if you've
+   installed everything successfully:
+
+
+  .. code-block:: gherkin 
+     :linenos:
+
+      default | Given I am an anonymous user                                    
+      default | Given I am not logged in                                        
+      default | Given I am logged in as a user with the :role role(s)           
+      default | Given I am logged in as :name     
diff --git a/vendor/drupal/drupal-extension/doc/index.rst b/vendor/drupal/drupal-extension/doc/index.rst
new file mode 100644 (file)
index 0000000..28de3e6
--- /dev/null
@@ -0,0 +1,24 @@
+.. the Drupal Extension to Behat and Mink documentation master file, created by
+   sphinx-quickstart on Sun Jul  7 09:40:13 2013.
+   You can adapt this file completely to your liking, but it should at least
+   contain the root `toctree` directive.
+
+Welcome to the Drupal Extension to Behat and Mink's documentation!
+==================================================================
+
+Contents:
+
+.. toctree::
+   :maxdepth: 1 
+
+   intro
+   requirements
+   localinstall
+   globalinstall
+   environment
+   drivers
+   blackbox
+   drush
+   drupalapi
+   contexts
+   subcontexts
diff --git a/vendor/drupal/drupal-extension/doc/intro.rst b/vendor/drupal/drupal-extension/doc/intro.rst
new file mode 100644 (file)
index 0000000..878eb46
--- /dev/null
@@ -0,0 +1,35 @@
+Testing your site with the Drupal Extension to Behat and Mink
+==============================================================
+
+.. container:: clear
+
+  .. image:: _static/beehat.png
+     :align: left
+     :height: 125px
+
+The `Drupal Extension to Behat and Mink
+<https://drupal.org/project/drupalextension>`_ provides Drupal-specific
+functionality for the `Behavior-Driven Development
+<http://dannorth.net/introducing-bdd/>`_ testing frameworks of `Behat and Mink
+<http://extensions.behat.org/mink/>`_.
+
+What do Behat and Mink Do?
+--------------------------
+
+Behat and Mink allow you to describe the behavior of a web site in plain, but
+stylized language, and then turn that description into an automated test that
+will visit the site and perform each step you describe. Such functional tests
+can help site builders ensure that the added value they've created when
+building a Drupal site continues to behave as expected after any sort of site
+change -- security updates, new module versions, changes to custom code, etc.
+
+What does the Drupal Extension add?
+-----------------------------------
+
+The Drupal Extension to Behat and Mink assists in the performance of these
+common Drupal testing tasks:
+
+*  Set up test data with Drush or the Drupal API 
+*  Define theme regions and test data appears within them 
+*  Clear the cache, log out, and other useful steps
+*  Detect and discover steps provided by contributed modules and themes
diff --git a/vendor/drupal/drupal-extension/doc/localinstall.rst b/vendor/drupal/drupal-extension/doc/localinstall.rst
new file mode 100644 (file)
index 0000000..da5d644
--- /dev/null
@@ -0,0 +1,81 @@
+Stand-alone installation 
+========================
+
+A stand-alone installation is recommended when you want your tests and testing
+environment to be portable, from local development to CI server, to client
+infrastructure. It also makes documentation consistent and reliable.
+
+1. Create a folder for your BDD tests::
+
+    mkdir projectfolder
+    cd projectfolder
+  
+  All the commands that follow are written to install from the root of your
+  project folder.
+
+2. Install Composer, a php package manager::
+
+     curl -s https://getcomposer.org/installer | php
+
+3. Create a composer.json file to tell Composer what to install.  To do that,
+   paste the following code into your editor and save as composer.json. The 
+   Drupal Extension requires Behat, Mink, and the Mink Extension. They will all 
+   be set up because they're dependencies of the Drupal Extension, so you don't 
+   have to specify them directly in the composer.json file:
+
+  .. literalinclude:: _static/snippets/composer.json 
+     :language: javascript 
+     :linenos:
+
+  For Drupal 8, you'll need to specify the correct version of Guzzle:
+
+  .. literalinclude:: _static/snippets/composer.json.d8
+     :language: javascript
+     :linenos:
+     :emphasize-lines: 4
+
+4. Run the following command to install the Drupal Extension and all those
+   dependencies. This takes a while before you start to see output::
+
+    php composer.phar install
+
+5. Configure your testing environment by creating a file called behat.yml with
+   the following. Be sure that you point the base_url at the web site YOU intend
+   to test. Do not include a trailing slash:
+
+  .. literalinclude:: _static/snippets/behat-1.yml 
+     :language: yaml 
+     :linenos:
+
+6. Initialize behat. This creates the features folder with some basic things to
+   get you started, including your own FeatureContext.php file:: 
+
+    bin/behat --init
+
+7. This will generate a FeatureContext.php file that looks like:
+
+  .. literalinclude:: _static/snippets/FeatureContext.php.inc
+     :language: php 
+     :linenos: 
+     :emphasize-lines: 12
+
+  This FeatureContext.php will be aware of both the Drupal Extension
+  and the Mink Extension, so you'll be able to take advantage of their
+  drivers add your own custom step definitions as well.
+
+8. To ensure everything is set up appropriately, type::
+
+    bin/behat -dl
+  
+   You'll see a list of steps like the following, but longer, if you've
+   installed everything successfully:
+  
+
+  .. code-block:: gherkin 
+     :linenos:
+
+      default | Given I am an anonymous user
+      default | Given I am not logged in
+      default | Given I am logged in as a user with the :role role(s)
+      default | Given I am logged in as :name
+
diff --git a/vendor/drupal/drupal-extension/doc/requirements.rst b/vendor/drupal/drupal-extension/doc/requirements.rst
new file mode 100644 (file)
index 0000000..85f6158
--- /dev/null
@@ -0,0 +1,46 @@
+System Requirements 
+===================
+
+Meet the system requirements
+----------------------------
+
+#. Check your PHP version::
+
+    php --version
+
+   It must be higher than 5.3.5! Note: This means you cannot use the same
+   version of PHP for testing that you might use to run a Drupal 5 site.
+
+  PHP will also need to have the following libraries installed:
+
+  * `curl <http://curl.haxx.se/libcurl/php/install.html>`_ 
+  * `mbstring <http://php.net/manual/en/mbstring.installation.php>`_ 
+  * `xml <http://www.php.net/manual/en/dom.setup.php#102046>`_ 
+  
+  Check your current modules by running::
+  
+    php -m
+
+2. Check for Java::
+
+    java -version
+
+   It doesn't necessarily matter what version, but it will be required for
+   Selenium.
+
+
+#. Directions are written to use command-line cURL. You can make sure it's
+   installed with::
+
+    curl --version
+
+#. Selenium
+
+  Download the latest version of `Selenium Server
+  <http://docs.seleniumhq.org/download/>`_ It's under the heading Selenium
+  Server (formerly the Selenium RC Server).   This is a single file which can be
+  placed any where you like on your system and run with the following command::
+
+    java -jar selenium-server-standalone-2.44.0.jar & 
+    // replace with the name of the version you downloaded
+
diff --git a/vendor/drupal/drupal-extension/doc/subcontexts.rst b/vendor/drupal/drupal-extension/doc/subcontexts.rst
new file mode 100644 (file)
index 0000000..a67dadf
--- /dev/null
@@ -0,0 +1,51 @@
+Contributed Module Subcontexts
+==============================
+
+Although not yet a wide-spread practice, the Drupal Extension to Behat and Mink
+makes it easy for maintainers to include custom step definitions in their
+contributed projects.
+
+
+Discovering SubContexts
+-----------------------
+
+In order to use contributed step definitions, define the search path in the
+behat.yml
+
+// sites/default/behat-tests/behat.yml
+
+.. literalinclude:: _static/snippets/behat-sub.yml
+   :language: yaml
+   :linenos:
+   :emphasize-lines: 8-9,25-26
+
+The Drupal Extension will search recursively within the directory or
+directories specified to discover and load any file ending in `.behat.inc`. This
+system, although created with Drupal contrib projects in mind, searches where
+it's pointed, so you can also use it for your own subcontexts, a strategy you
+might employ to re-use step definitions particular to your shop or company's
+development patterns. The `paths` key allows running tests located in features
+within the `features` directory of a contributed/custom module.
+
+Disable autoloading
+-------------------
+Autoloading can be disabled in the behat.yml file temporarily with the
+following:
+
+.. literalinclude:: _static/snippets/behat-auto.yml
+   :language: yaml
+   :linenos:
+   :emphasize-lines: 25 
+
+For Contributors
+----------------
+Behat `subcontexts
+<http://docs.behat.org/guides/4.context.html#using-subcontexts>`_ are no longer
+supported in version 3. The Drupal Extension, however, continues to support
+saving module-specific contexts in a file ending with `.behat.inc` 
+
+Just like functions, preface the filename with the project's machine name to prevent namespace collisions.
+
+  .. literalinclude:: _static/snippets/subcontext.inc
+     :language: php
+     :linenos:
diff --git a/vendor/drupal/drupal-extension/features/api.feature b/vendor/drupal/drupal-extension/features/api.feature
new file mode 100644 (file)
index 0000000..5fec342
--- /dev/null
@@ -0,0 +1,275 @@
+@api
+Feature: DrupalContext
+  In order to prove the Drupal context is working properly
+  As a developer
+  I need to use the step definitions of this context
+
+  # These scenarios assume a "standard" install of Drupal 7 and 8.
+
+  @drushTest @d7 @d8
+  Scenario: Create and log in as a user
+    Given I am logged in as a user with the "authenticated user" role
+    When I click "My account"
+    Then I should see the text "Member for"
+
+  @drushTest @d7
+  Scenario: Target links within table rows
+    Given I am logged in as a user with the "administrator" role
+    When I am at "admin/structure/types"
+    And I click "manage fields" in the "Article" row
+    Then I should be on "admin/structure/types/manage/article/fields"
+    And I should see text matching "Add new field"
+
+  @d8
+  Scenario: Target links within table rows
+    Given I am logged in as a user with the "administrator" role
+    When I am at "admin/structure/types"
+    And I click "Manage fields" in the "Article" row
+    Then I should be on "admin/structure/types/manage/article/fields"
+    And I should see text matching "Add field"
+
+  @drushTest @d7
+  Scenario: Find a heading in a region
+    Given I am not logged in
+    When I am on the homepage
+    Then I should see the heading "User login" in the "left sidebar" region
+
+  @d8
+  Scenario: Find a heading in a region
+    Given I am not logged in
+    When I am on the homepage
+    Then I should see the heading "Search" in the "left sidebar" region
+
+  @drushTest @d7 @d8
+  Scenario: Clear cache
+    Given the cache has been cleared
+    When I am on the homepage
+    Then I should get a "200" HTTP response
+
+  @d7 @d8
+  Scenario: Create a node
+    Given I am logged in as a user with the "administrator" role
+    When I am viewing an "article" with the title "My article"
+    Then I should see the heading "My article"
+
+  @drushTest @d7 @d8
+  Scenario: Run cron
+    Given I am logged in as a user with the "administrator" role
+    When I run cron
+    And am on "admin/reports/dblog"
+    Then I should see the link "Cron run completed"
+
+  @d7 @d8
+  Scenario: Create many nodes
+    Given "page" content:
+    | title    |
+    | Page one |
+    | Page two |
+    And "article" content:
+    | title          |
+    | First article  |
+    | Second article |
+    And I am logged in as a user with the "administrator" role
+    When I go to "admin/content"
+    Then I should see "Page one"
+    And I should see "Page two"
+    And I should see "First article"
+    And I should see "Second article"
+
+  @d7 @d8
+  Scenario: Create nodes with fields
+    Given "article" content:
+    | title                     | promote | body             |
+    | First article with fields |       1 | PLACEHOLDER BODY |
+    And I am logged in as a user with the "authenticated user" role
+    When I am on the homepage
+    And follow "First article with fields"
+    Then I should see the text "PLACEHOLDER BODY"
+
+  @d7 @d8
+  Scenario: Create and view a node with fields
+    Given I am viewing an "article":
+    | title | My article with fields! |
+    | body  | A placeholder           |
+    Then I should see the heading "My article with fields!"
+    And I should see the text "A placeholder"
+
+  @d7 @d8
+  Scenario: Create users
+    Given users:
+    | name     | mail            | status |
+    | Joe User | joe@example.com | 1      |
+    And I am logged in as a user with the "administrator" role
+    When I visit "admin/people"
+    Then I should see the link "Joe User"
+
+  @d7
+  Scenario: Create users with roles
+    Given users:
+    | name      | mail             | roles         |
+    | Joe User  | joe@example.com  | administrator |
+    | Jane User | jane@example.com |               |
+    And I am logged in as a user with the "administrator" role
+    When I visit "admin/people"
+    Then I should see the text "administrator" in the "Joe User" row
+    And  I should not see the text "administrator" in the "Jane User" row
+
+  @d8
+  Scenario: Create users with roles
+    Given users:
+    | name      | mail             | roles         |
+    | Joe User  | joe@example.com  | administrator |
+    | Jane User | jane@example.com |               |
+    And I am logged in as a user with the "administrator" role
+    When I visit "admin/people"
+    Then I should see the text "Administrator" in the "Joe User" row
+    And  I should not see the text "administrator" in the "Jane User" row
+
+  @d7 @d8
+  Scenario: Login as a user created during this scenario
+    Given users:
+    | name      | status |
+    | Test user |      1 |
+    When I am logged in as "Test user"
+    Then I should see the link "Log out"
+
+  @d7 @d8
+  Scenario: Create a term
+    Given I am logged in as a user with the "administrator" role
+    When I am viewing a "tags" term with the name "My tag"
+    Then I should see the heading "My tag"
+
+  @d7
+  Scenario: Create many terms
+    Given "tags" terms:
+    | name    |
+    | Tag one |
+    | Tag two |
+    And I am logged in as a user with the "administrator" role
+    When I go to "admin/structure/taxonomy/tags"
+    Then I should see "Tag one"
+    And I should see "Tag two"
+
+  @d8
+  Scenario: Create many terms
+    Given "tags" terms:
+    | name    |
+    | Tag one |
+    | Tag two |
+    And I am logged in as a user with the "administrator" role
+    When I go to "admin/structure/taxonomy/manage/tags/overview"
+    Then I should see "Tag one"
+    And I should see "Tag two"
+
+  @d7
+  Scenario: Create terms using vocabulary title rather than machine name.
+    Given "Tags" terms:
+    | name    |
+    | Tag one |
+    | Tag two |
+    And I am logged in as a user with the "administrator" role
+    When I go to "admin/structure/taxonomy/tags"
+    Then I should see "Tag one"
+    And I should see "Tag two"
+
+  @d8
+  Scenario: Create terms using vocabulary title rather than machine name.
+    Given "Tags" terms:
+    | name    |
+    | Tag one |
+    | Tag two |
+    And I am logged in as a user with the "administrator" role
+    When I go to "admin/structure/taxonomy/manage/tags/overview"
+    Then I should see "Tag one"
+    And I should see "Tag two"
+
+  @d7 @d8wip
+  # TODO: This doesn't work on Drupal 8 yet. For nodes the 'author' field is
+  # called 'uid' and only accepts numerical IDs.
+  Scenario: Create nodes with specific authorship
+    Given users:
+    | name     | mail            | status |
+    | Joe User | joe@example.com | 1      |
+    And "article" content:
+    | title          | author   | body             | promote |
+    | Article by Joe | Joe User | PLACEHOLDER BODY | 1       |
+    When I am logged in as a user with the "administrator" role
+    And I am on the homepage
+    And I follow "Article by Joe"
+    Then I should see the link "Joe User"
+
+  @d7 @d8
+  Scenario: Create an article with multiple term references
+    Given "tags" terms:
+    | name      |
+    | Tag one   |
+    | Tag two   |
+    | Tag three |
+    | Tag four  |
+    And "article" content:
+    | title           | body             | promote | field_tags                  |
+    | Article by Joe  | PLACEHOLDER BODY |       1 | Tag one, Tag two, Tag three |
+    | Article by Mike | PLACEHOLDER BODY |       1 | Tag four                    |
+    When I am on the homepage
+    Then I should see the link "Tag one"
+    And I should see the link "Tag two"
+    And I should see the link "Tag three"
+    And I should see the link "Tag four"
+
+  @d7 @d8
+  Scenario: Readable created dates
+    Given "article" content:
+    | title        | body             | created            | status | promote |
+    | Test article | PLACEHOLDER BODY | 07/27/2014 12:03am |      1 |       1 |
+    When I am on the homepage
+    Then I should see the text "Sun, 07/27/2014 - 00:03"
+
+  @d7 @d8
+  Scenario: Node hooks are functioning
+    Given "article" content:
+    | title        | body        | published on       | status | promote |
+    | Test article | PLACEHOLDER | 04/27/2013 11:11am |      1 |       1 |
+    When I am on the homepage
+    Then I should see the text "Sat, 04/27/2013 - 11:11"
+
+  @d7 @d8
+  Scenario: Node edit access by administrator
+    Given I am logged in as a user with the "administrator" role
+    Then I should be able to edit an "article"
+
+  @d7 @d8
+  Scenario: User hooks are functioning
+    Given users:
+    | First name | Last name | E-mail               |
+    | Joe        | User      | joe.user@example.com |
+    And I am logged in as a user with the "administrator" role
+    When I visit "admin/people"
+    Then I should see the link "Joe User"
+
+  @d7
+  Scenario: Term hooks are functioning
+    Given "tags" terms:
+    | Label     |
+    | Tag one   |
+    | Tag two   |
+    And I am logged in as a user with the "administrator" role
+    When I go to "admin/structure/taxonomy/tags"
+    Then I should see "Tag one"
+    And I should see "Tag two"
+
+  @d8
+  Scenario: Term hooks are functioning
+    Given "tags" terms:
+    | Label     |
+    | Tag one   |
+    | Tag two   |
+    And I am logged in as a user with the "administrator" role
+    When I go to "admin/structure/taxonomy/manage/tags/overview"
+    Then I should see "Tag one"
+    And I should see "Tag two"
+
+  @d7 @d8
+  Scenario: Log in as a user with specific permissions
+    Given I am logged in as a user with the "Administer content types" permission
+    When I go to "admin/structure/types"
+    Then I should see the link "Add content type"
diff --git a/vendor/drupal/drupal-extension/features/api_background.feature b/vendor/drupal/drupal-extension/features/api_background.feature
new file mode 100644 (file)
index 0000000..3d91199
--- /dev/null
@@ -0,0 +1,27 @@
+@d6 @d7 @d8 @api
+Feature: DrupalContext
+  Test DrupalContext in combination with Backgrounds
+
+  Background:
+    Given "tags" terms:
+      | name    |
+      | Tag one |
+      | Tag two |
+
+    Given users:
+      | name     |
+      | User one |
+      | User two |
+
+    Given "article" content:
+      | title    |
+      | Node one |
+      | Node two |
+
+  Scenario Outline:
+    Given I am not logged in
+
+    Examples:
+      | user |
+      | foo  |
+      | bar  |
diff --git a/vendor/drupal/drupal-extension/features/blackbox.feature b/vendor/drupal/drupal-extension/features/blackbox.feature
new file mode 100644 (file)
index 0000000..59a4336
--- /dev/null
@@ -0,0 +1,82 @@
+@blackbox
+Feature: Test DrupalContext
+  In order to prove the Drupal context using the blackbox driver is working properly
+  As a developer
+  I need to use the step definitions of this context
+
+  Scenario: Test the ability to find a heading in a region
+    Given I am on the homepage
+    When I click "Download & Extend"
+    Then I should see the heading "Download" in the "content" region
+
+  Scenario: Clicking content in a region
+    Given I am at "community.html"
+    When I click "IRC" in the "content" region
+    Then I should see "Page status" in the "right sidebar"
+    And I should see the link "Drupal News" in the "footer" region
+
+  Scenario: Viewing content in a region
+    Given I am on the homepage
+    Then I should see "Build something amazing." in the "left header"
+
+  Scenario: Test ability to find text that should not appear in a region
+    Given I am on the homepage
+    Then I should not see the text "Proprietary software is cutting edge" in the "left header"
+
+  Scenario: Submit a form in a region
+    Given I am on the homepage
+    When I fill in "Search…" with "Views" in the "navigation" region
+    And I press "Search" in the "navigation" region
+    Then I should see the text "Search again" in the "right sidebar" region
+
+  Scenario: Check a link should not exist in a region
+    Given I am on the homepage
+    Then I should not see the link "This link should never exist in a default Drupal install" in the "right header"
+
+  Scenario: Find a button
+    Given I am on the homepage
+    Then I should see the "Search" button
+
+  Scenario: Find a button in a region
+    Given I am on the homepage
+    Then I should see the "Search" button in the "navigation"
+
+  Scenario: Find an element in a region
+    Given I am on the homepage
+    Then I should see the "h1" element in the "left header"
+
+  Scenario: Element not in region
+    Given I am on the homepage
+    Then I should not see the "h1" element in the "footer"
+
+  Scenario: Text not in element in region
+    Given I am on the homepage
+    Then I should not see "DotNetNuke" in the "h1" element in the "left header"
+
+  Scenario: Find an element with an attribute in a region
+    Given I am on the homepage
+    Then I should see the "h1" element with the "id" attribute set to "site-name" in the "left header" region
+
+  Scenario: Find text in an element with an attribute in a region
+    Given I am on the homepage
+    Then I should see "Drupal" in the "h1" element with the "id" attribute set to "site-name" in the "left header" region
+
+  Scenario: Error messages
+   Given I am on "user.html"
+   When I press "Log in"
+   Then I should see the error message "Password field is required"
+   And I should not see the error message "Sorry, unrecognized username or password"
+   And I should see the following error messages:
+   | error messages                       |
+   | Username or email field is required. |
+   | Password field is required           |
+   And I should not see the following error messages:
+   | error messages                                                                |
+   | Sorry, unrecognized username or password                                      |
+   | Unable to send e-mail. Contact the site administrator if the problem persists |
+
+ @javascript
+ Scenario: Zombie driver is functional
+   Given I am on the homepage
+   When I click "Download & Extend"
+   Then I should see the link "Distributions"
diff --git a/vendor/drupal/drupal-extension/features/bootstrap/FeatureContext.php b/vendor/drupal/drupal-extension/features/bootstrap/FeatureContext.php
new file mode 100644 (file)
index 0000000..8a72e5e
--- /dev/null
@@ -0,0 +1,460 @@
+<?php
+
+use Behat\Behat\Context\Context;
+use Behat\Gherkin\Node\PyStringNode;
+use Behat\Gherkin\Node\TableNode;
+use Drupal\DrupalExtension\Hook\Scope\BeforeNodeCreateScope;
+use Drupal\DrupalExtension\Hook\Scope\EntityScope;
+use Symfony\Component\Process\PhpExecutableFinder;
+use Symfony\Component\Process\Process;
+
+/**
+ * Features context for testing the Drupal Extension.
+ *
+ * @todo we are duplicating code from Behat's FeatureContext here for the
+ * purposes of testing since we can't easily run that as a context due to naming
+ * conflicts.
+ */
+class FeatureContext implements Context {
+  /**
+   * Hook into node creation to test `@beforeNodeCreate`
+   *
+   * @beforeNodeCreate
+   */
+  public static function alterNodeParameters(BeforeNodeCreateScope $scope) {
+    call_user_func('\Drupal\DrupalExtension\Context\RawDrupalContext::alterNodeParameters', $scope);
+    // @see `features/api.feature`
+    // Change 'published on' to the expected 'created'.
+    $node = $scope->getEntity();
+    if (isset($node->{"published on"})) {
+      $node->created = $node->{"published on"};
+      unset($node->{"published on"});
+    }
+  }
+
+  /**
+   * Hook into term creation to test `@beforeTermCreate`
+   *
+   * @beforeTermCreate
+   */
+  public static function alterTermParameters(EntityScope $scope) {
+    // @see `features/api.feature`
+    // Change 'Label' to expected 'name'.
+    $term = $scope->getEntity();
+    if (isset($term->{'Label'})) {
+      $term->name = $term->{'Label'};
+      unset($term->{'Label'});
+    }
+  }
+
+  /**
+   * Hook into user creation to test `@beforeUserCreate`
+   *
+   * @beforeUserCreate
+   */
+  public static function alterUserParameters(EntityScope $scope) {
+    // @see `features/api.feature`
+    // Concatenate 'First name' and 'Last name' to form user name.
+    $user = $scope->getEntity();
+    if (isset($user->{"First name"}) && isset($user->{"Last name"})) {
+      $user->name = $user->{"First name"} . ' ' . $user->{"Last name"};
+      unset($user->{"First name"}, $user->{"Last name"});
+    }
+    // Transform custom 'E-mail' to 'mail'.
+    if (isset($user->{"E-mail"})) {
+      $user->mail = $user->{"E-mail"};
+      unset($user->{"E-mail"});
+    }
+  }
+
+  /**
+   * Test that a node is returned after node create.
+   *
+   * @afterNodeCreate
+   */
+  public static function afterNodeCreate(EntityScope $scope) {
+    if (!$node = $scope->getEntity()) {
+      throw new \Exception('Failed to find a node in @afterNodeCreate hook.');
+    }
+  }
+
+  /**
+   * Test that a term is returned after term create.
+   *
+   * @afterTermCreate
+   */
+  public static function afterTermCreate(EntityScope $scope) {
+    if (!$term = $scope->getEntity()) {
+      throw new \Exception('Failed to find a term in @afterTermCreate hook.');
+    }
+  }
+
+  /**
+   * Test that a user is returned after user create.
+   *
+   * @afterUserCreate
+   */
+  public static function afterUserCreate(EntityScope $scope) {
+    if (!$user = $scope->getEntity()) {
+      throw new \Exception('Failed to find a user in @afterUserCreate hook.');
+    }
+  }
+
+  /**
+   * Transforms long address field columns into shorter aliases.
+   *
+   * This is used in field_handlers.feature for testing if lengthy field:column
+   * combinations can be shortened to more human friendly aliases.
+   *
+   * @Transform table:name,mail,street,city,postcode,country
+   */
+  public function castUsersTable(TableNode $user_table) {
+    $aliases = array(
+      'country' => 'field_post_address:country',
+      'city' => 'field_post_address:locality',
+      'street' => 'field_post_address:thoroughfare',
+      'postcode' => 'field_post_address:postal_code',
+    );
+
+    // The first row of the table contains the field names.
+    $table = $user_table->getTable();
+    reset($table);
+    $first_row = key($table);
+
+    // Replace the aliased field names with the actual ones.
+    foreach ($table[$first_row] as $key => $alias) {
+      if (array_key_exists($alias, $aliases)) {
+        $table[$first_row][$key] = $aliases[$alias];
+      }
+    }
+
+    return new TableNode($table);
+  }
+
+  /**
+   * Transforms human readable field names into machine names.
+   *
+   * This is used in field_handlers.feature for testing if human readable names
+   * can be used instead of machine names in tests.
+   *
+   * @param TableNode $post_table
+   *   The original table.
+   *
+   * @return TableNode
+   *   The transformed table.
+   *
+   * @Transform rowtable:title,body,reference,date,links,select,address
+   */
+  public function transformPostContentTable(TableNode $post_table) {
+    $aliases = array(
+      'reference' => 'field_post_reference',
+      'date' => 'field_post_date',
+      'links' => 'field_post_links',
+      'select' => 'field_post_select',
+      'address' => 'field_post_address',
+    );
+
+    $table = $post_table->getTable();
+    array_walk($table, function (&$row) use ($aliases) {
+      // The first column of the row contains the field names. Replace the
+      // human readable field name with the machine name if it exists.
+      if (array_key_exists($row[0], $aliases)) {
+        $row[0] = $aliases[$row[0]];
+      }
+    });
+
+    return new TableNode($table);
+  }
+
+  /**
+   * From here down is the Behat FeatureContext.
+   *
+   * @defgroup Behat FeatureContext
+   * @{
+   */
+
+    /**
+     * @var string
+     */
+    private $phpBin;
+    /**
+     * @var Process
+     */
+    private $process;
+    /**
+     * @var string
+     */
+    private $workingDir;
+
+    /**
+     * Cleans test folders in the temporary directory.
+     *
+     * @BeforeSuite
+     * @AfterSuite
+     */
+    public static function cleanTestFolders()
+    {
+        if (is_dir($dir = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'behat')) {
+            self::clearDirectory($dir);
+        }
+    }
+
+    /**
+     * Prepares test folders in the temporary directory.
+     *
+     * @BeforeScenario
+     */
+    public function prepareTestFolders()
+    {
+        do {
+            $random_name = md5((int) microtime(true) * rand(0, 100000));
+            $dir = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'behat' . DIRECTORY_SEPARATOR . $random_name;
+        } while (is_dir($dir));
+
+        mkdir($dir . '/features/bootstrap/i18n', 0777, true);
+
+        $phpFinder = new PhpExecutableFinder();
+        if (false === $php = $phpFinder->find()) {
+            throw new \RuntimeException('Unable to find the PHP executable.');
+        }
+        $this->workingDir = $dir;
+        $this->phpBin = $php;
+        $this->process = new Process(null);
+    }
+
+    /**
+     * Creates a file with specified name and context in current workdir.
+     *
+     * @Given /^(?:there is )?a file named "([^"]*)" with:$/
+     *
+     * @param   string       $filename name of the file (relative path)
+     * @param   PyStringNode $content  PyString string instance
+     */
+    public function aFileNamedWith($filename, PyStringNode $content)
+    {
+        $content = strtr((string) $content, array("'''" => '"""'));
+        $this->createFile($this->workingDir . '/' . $filename, $content);
+    }
+
+    /**
+     * Moves user to the specified path.
+     *
+     * @Given /^I am in the "([^"]*)" path$/
+     *
+     * @param   string $path
+     */
+    public function iAmInThePath($path)
+    {
+        $this->moveToNewPath($path);
+    }
+
+    /**
+     * Checks whether a file at provided path exists.
+     *
+     * @Given /^file "([^"]*)" should exist$/
+     *
+     * @param   string $path
+     */
+    public function fileShouldExist($path)
+    {
+        PHPUnit_Framework_Assert::assertFileExists($this->workingDir . DIRECTORY_SEPARATOR . $path);
+    }
+
+    /**
+     * Sets specified ENV variable
+     *
+     * @When /^"BEHAT_PARAMS" environment variable is set to:$/
+     *
+     * @param PyStringNode $value
+     */
+    public function iSetEnvironmentVariable(PyStringNode $value)
+    {
+        $this->process->setEnv(array('BEHAT_PARAMS' => (string) $value));
+    }
+
+    /**
+     * Runs behat command with provided parameters
+     *
+     * @When /^I run "behat(?: ((?:\"|[^"])*))?"$/
+     *
+     * @param   string $argumentsString
+     */
+    public function iRunBehat($argumentsString = '')
+    {
+        $argumentsString = strtr($argumentsString, array('\'' => '"'));
+
+        $this->process->setWorkingDirectory($this->workingDir);
+        $this->process->setCommandLine(
+            sprintf(
+                '%s %s %s %s',
+                $this->phpBin,
+                escapeshellarg(BEHAT_BIN_PATH),
+                $argumentsString,
+                strtr('--format-settings=\'{"timer": false}\'', array('\'' => '"', '"' => '\"'))
+            )
+        );
+        $this->process->start();
+        $this->process->wait();
+    }
+
+    /**
+     * Checks whether previously ran command passes|fails with provided output.
+     *
+     * @Then /^it should (fail|pass) with:$/
+     *
+     * @param   string       $success "fail" or "pass"
+     * @param   PyStringNode $text    PyString text instance
+     */
+    public function itShouldPassWith($success, PyStringNode $text)
+    {
+        $this->itShouldFail($success);
+        $this->theOutputShouldContain($text);
+    }
+
+    /**
+     * Checks whether specified file exists and contains specified string.
+     *
+     * @Then /^"([^"]*)" file should contain:$/
+     *
+     * @param   string       $path file path
+     * @param   PyStringNode $text file content
+     */
+    public function fileShouldContain($path, PyStringNode $text)
+    {
+        $path = $this->workingDir . '/' . $path;
+        PHPUnit_Framework_Assert::assertFileExists($path);
+
+        $fileContent = trim(file_get_contents($path));
+        // Normalize the line endings in the output
+        if ("\n" !== PHP_EOL) {
+            $fileContent = str_replace(PHP_EOL, "\n", $fileContent);
+        }
+
+        PHPUnit_Framework_Assert::assertEquals($this->getExpectedOutput($text), $fileContent);
+    }
+
+    /**
+     * Checks whether last command output contains provided string.
+     *
+     * @Then the output should contain:
+     *
+     * @param   PyStringNode $text PyString text instance
+     */
+    public function theOutputShouldContain(PyStringNode $text)
+    {
+        PHPUnit_Framework_Assert::assertContains($this->getExpectedOutput($text), $this->getOutput());
+    }
+
+    private function getExpectedOutput(PyStringNode $expectedText)
+    {
+        $text = strtr($expectedText, array('\'\'\'' => '"""', '%%TMP_DIR%%' => sys_get_temp_dir() . DIRECTORY_SEPARATOR));
+
+        // windows path fix
+        if ('/' !== DIRECTORY_SEPARATOR) {
+            $text = preg_replace_callback(
+                '/ features\/[^\n ]+/', function ($matches) {
+                    return str_replace('/', DIRECTORY_SEPARATOR, $matches[0]);
+                }, $text
+            );
+            $text = preg_replace_callback(
+                '/\<span class\="path"\>features\/[^\<]+/', function ($matches) {
+                    return str_replace('/', DIRECTORY_SEPARATOR, $matches[0]);
+                }, $text
+            );
+            $text = preg_replace_callback(
+                '/\+[fd] [^ ]+/', function ($matches) {
+                    return str_replace('/', DIRECTORY_SEPARATOR, $matches[0]);
+                }, $text
+            );
+        }
+
+        return $text;
+    }
+
+    /**
+     * Checks whether previously ran command failed|passed.
+     *
+     * @Then /^it should (fail|pass)$/
+     *
+     * @param   string $success "fail" or "pass"
+     */
+    public function itShouldFail($success)
+    {
+        if ('fail' === $success) {
+            if (0 === $this->getExitCode()) {
+                echo 'Actual output:' . PHP_EOL . PHP_EOL . $this->getOutput();
+            }
+
+            PHPUnit_Framework_Assert::assertNotEquals(0, $this->getExitCode());
+        } else {
+            if (0 !== $this->getExitCode()) {
+                echo 'Actual output:' . PHP_EOL . PHP_EOL . $this->getOutput();
+            }
+
+            PHPUnit_Framework_Assert::assertEquals(0, $this->getExitCode());
+        }
+    }
+
+    private function getExitCode()
+    {
+        return $this->process->getExitCode();
+    }
+
+    private function getOutput()
+    {
+        $output = $this->process->getErrorOutput() . $this->process->getOutput();
+
+        // Normalize the line endings in the output
+        if ("\n" !== PHP_EOL) {
+            $output = str_replace(PHP_EOL, "\n", $output);
+        }
+
+        // Replace wrong warning message of HHVM
+        $output = str_replace('Notice: Undefined index: ', 'Notice: Undefined offset: ', $output);
+
+        return trim(preg_replace("/ +$/m", '', $output));
+    }
+
+    private function createFile($filename, $content)
+    {
+        $path = dirname($filename);
+        if (!is_dir($path)) {
+            mkdir($path, 0777, true);
+        }
+
+        file_put_contents($filename, $content);
+    }
+
+    private function moveToNewPath($path)
+    {
+        $newWorkingDir = $this->workingDir .'/' . $path;
+        if (!file_exists($newWorkingDir)) {
+            mkdir($newWorkingDir, 0777, true);
+        }
+
+        $this->workingDir = $newWorkingDir;
+    }
+
+    private static function clearDirectory($path)
+    {
+        $files = scandir($path);
+        array_shift($files);
+        array_shift($files);
+
+        foreach ($files as $file) {
+            $file = $path . DIRECTORY_SEPARATOR . $file;
+            if (is_dir($file)) {
+                self::clearDirectory($file);
+            } else {
+                unlink($file);
+            }
+        }
+
+        rmdir($path);
+    }
+
+  /**
+   * @} End of defgroup Behat FeatureContext.
+   */
+
+}
diff --git a/vendor/drupal/drupal-extension/features/config.feature b/vendor/drupal/drupal-extension/features/config.feature
new file mode 100644 (file)
index 0000000..c7754db
--- /dev/null
@@ -0,0 +1,20 @@
+@api @d8
+Feature: ConfigContext
+  In order to prove the Config context is working properly
+  As a developer
+  I need to use the step definitions of this context
+
+  Background: User is an administrator.
+    Given I am logged in as a user with the "administer site configuration" permission
+
+  Scenario: Set the site name and check it appears on the config form.
+    Given I set the configuration item "system.site" with key "name" to "Test config update"
+    When  I go to "admin/config/system/site-information"
+    Then  the "Site name" field should contain "Test config update"
+
+  Scenario: Set a complex config and check it appears on the config form.
+    Given I set the configuration item "system.performance" with key "css" with values:
+      |key        | value |
+      |preprocess | true  |
+    When I go to "admin/config/development/performance"
+    Then the "Aggregate CSS files" checkbox should be checked
diff --git a/vendor/drupal/drupal-extension/features/d6.feature b/vendor/drupal/drupal-extension/features/d6.feature
new file mode 100644 (file)
index 0000000..b79e7e1
--- /dev/null
@@ -0,0 +1,59 @@
+@api @d6
+Feature: Environment check
+
+  Scenario: Frontpage
+    Given I am not logged in
+      And I am on the homepage
+    Then I should see "User login"
+
+  Scenario: assertAnonymousUser
+    Given I am an anonymous user
+
+  @api
+  Scenario: assertAuthenticatedByRole
+    Given I am logged in as a user with the "authenticated" role
+
+  @api
+  Scenario: assertAuthenticatedByRoleWithGivenFields
+    Given I am logged in as a user with the "authenticated" role and I have the following fields:
+    | name | test |
+
+  @api
+  Scenario: createNode
+    Given I am viewing a story with the title "test"
+    Then I should see "test"
+
+  @api
+  Scenario: createNodes
+    Given article content:
+      | title    | author     | status | created           |
+      | My title | Joe Editor | 1      | 2014-10-17 8:00am |
+    When I am viewing a content with the title "My title"
+    Then I should see "My title"
+
+  @api
+  Scenario: createTerm
+    Given I am viewing a tags term with the name "example tag"
+    Then I should see "example tag"
+
+  @api
+  Scenario: createUsers
+    Given I am logged in as a user with the "administer users" permission
+    And users:
+    | name     | mail         |
+    | user foo | foo@bar.com  |
+    | user bar | baz@bar.com  |
+    When I visit "admin/user/user"
+    Then I should see "user foo"
+      And I should see "user bar"
+
+  @api
+  Scenario: create node with terms.
+    Given tags terms:
+      | name |
+      | test-tag |
+    And article content:
+      | title    | status | taxonomy |
+      | My title | 1      | test-tag |
+    When I am on the homepage
+    Then I should see "test-tag"
diff --git a/vendor/drupal/drupal-extension/features/d8.feature b/vendor/drupal/drupal-extension/features/d8.feature
new file mode 100644 (file)
index 0000000..d079c60
--- /dev/null
@@ -0,0 +1,32 @@
+@d8 @api
+Feature: DrupalContext
+  In order to prove the Drupal context is working properly for Drupal 8
+  As a developer
+  I need to use the step definitions of this context
+
+  Scenario: Create and log in as a user
+    Given I am logged in as a user with the "authenticated user" role
+    When I click "My account"
+    Then I should see the text "Member for"
+
+  Scenario: Target links within table rows
+    Given I am logged in as a user with the "administrator" role
+    When I am at "admin/structure/types"
+    And I click "Manage fields" in the "Article" row
+    Then I should be on "admin/structure/types/manage/article/fields"
+    And I should see the link "Add field"
+
+  Scenario: Create users with roles
+    Given users:
+    | name     | mail             | roles          |
+    | Joe User | joe@example.com  | Administrator  |
+    | Jane Doe | jane@example.com |                |
+    And I am logged in as a user with the "administrator" role
+    When I visit "admin/people"
+    Then I should see the text "Administrator" in the "Joe User" row
+    And  I should not see the text "administrator" in the "Jane Doe" row
+
+  Scenario: Find a heading in a region
+    Given I am not logged in
+    When I am on the homepage
+    Then I should see the heading "Search" in the "left sidebar" region
diff --git a/vendor/drupal/drupal-extension/features/drush.feature b/vendor/drupal/drupal-extension/features/drush.feature
new file mode 100644 (file)
index 0000000..ccc79cf
--- /dev/null
@@ -0,0 +1,26 @@
+@drushTest @drush
+Feature: Drush-specific steps
+  In order to prove that the drush driver is working properly
+  As a developer
+  I need to be able to use the steps provided here
+
+  Scenario: drush command with text matching: drush output correct status
+    Given I run drush "st"
+    Then drush output should contain "Drupal version"
+    Then drush output should contain "Site URI"
+    Then drush output should match "/.*Site\sURI\s+:.*/"
+    Then drush output should contain "Database driver"
+    Then drush output should contain "Successful"
+    Then drush output should not contain "NonExistantWord"
+
+  Scenario: drush command with arguments: re-enable toolbar
+    Given I run drush "en" "toolbar -y"
+      And I run drush "en" "toolbar -y"
+    Then drush output should contain "toolbar is already enabled."
+
+  Scenario: Create and view a node with fields using the Drush driver
+    Given I am viewing an "Article":
+    | title | My article with fields! |
+    | body  | A placeholder           |
+    Then I should see the heading "My article with fields!"
+    And I should see the text "A placeholder"
diff --git a/vendor/drupal/drupal-extension/features/field_handlers.feature b/vendor/drupal/drupal-extension/features/field_handlers.feature
new file mode 100644 (file)
index 0000000..b6d6ab8
--- /dev/null
@@ -0,0 +1,191 @@
+@api
+Feature: FieldHandlers
+  In order to prove field handling is working properly
+  As a developer
+  I need to use the step definitions of this context
+
+  # @d7 and @d8 scenarios assume a "standard" install of Drupal and require the
+  # feature "fixtures/drupalN/modules/behat_test" to enabled on the site.
+  @d7 @d8
+  Scenario: Test various node field handlers in Drupal 7 and 8
+    Given "page" content:
+      | title      |
+      | Page one   |
+      | Page two   |
+      | Page three |
+    When I am viewing a "post" content:
+      | title                | Post title                                                                       |
+      | body                 | PLACEHOLDER BODY                                                                 |
+      | field_post_reference | Page one, Page two                                                               |
+      | field_post_date      | 2015-02-08 17:45:00                                                              |
+      | field_post_links     | Link 1 - http://example.com, Link 2 - http://example.com                         |
+      | field_post_select    | One, Two                                                                         |
+      | field_post_address   | country: BE - locality: Brussel - thoroughfare: Louisalaan 1 - postal_code: 1000 |
+    Then I should see "Post title"
+    And I should see "PLACEHOLDER BODY"
+    And I should see "Page one"
+    And I should see "Page two"
+    And I should see "Sunday, February 8, 2015"
+    And I should see the link "Link 1"
+    And I should see the link "Link 2"
+    And I should see "One"
+    And I should see "Two"
+    And I should see "Belgium"
+    And I should see "Brussel"
+    And I should see "1000"
+    And I should see "Louisalaan 1"
+
+  # This is identical to the previous test, but uses human readable names for
+  # the field names. This is better from a BDD standpoint. Please have a look at
+  # FeatureContext::transformPostContentTable() to see how the mapping between
+  # the machine names and human readable names is defined.
+  @d7 @d8
+  Scenario: Test using human readable names for fields using @Transform
+    Given "page" content:
+      | title      |
+      | Page one   |
+      | Page two   |
+      | Page three |
+    When I am viewing a "post" content:
+      | title     | Post title                                                                       |
+      | body      | PLACEHOLDER BODY                                                                 |
+      | reference | Page one, Page two                                                               |
+      | date      | 2015-02-08 17:45:00                                                              |
+      | links     | Link 1 - http://example.com, Link 2 - http://example.com                         |
+      | select    | One, Two                                                                         |
+      | address   | country: BE - locality: Brussel - thoroughfare: Louisalaan 1 - postal_code: 1000 |
+    Then I should see "Page one"
+    And I should see "Page two"
+    And I should see "Sunday, February 8, 2015"
+    And I should see the link "Link 1"
+    And I should see the link "Link 2"
+    And I should see "One"
+    And I should see "Two"
+    And I should see "Belgium"
+    And I should see "Brussel"
+    And I should see "1000"
+    And I should see "Louisalaan 1"
+
+  @d7 @d8
+  Scenario: Test alternative syntax for named field columns on node content
+    When I am viewing a "post" content:
+      | title                           | Post title                  |
+      | field_post_address:country      | FR                          |
+      | field_post_address:locality     | Paris                       |
+      | field_post_address:thoroughfare | 1 Avenue des Champs Elysées |
+      | field_post_address:postal_code  | 75008                       |
+    Then I should see "France"
+    And I should see "Paris"
+    And I should see "1 Avenue des Champs Elysées"
+    And I should see "75008"
+
+  @d7 @d8
+  Scenario: Test shorthand syntax for named field columns on node content
+    When I am viewing a "post" content:
+      | title                      | Post title      |
+      | field_post_address:country | GB              |
+      | :locality                  | London          |
+      | :thoroughfare              | 1 Oxford Street |
+      | :postal_code               | W1D 1AN         |
+    Then I should see "United Kingdom"
+    And I should see "London"
+    And I should see "1 Oxford Street"
+    And I should see "W1D 1AN"
+
+  @d7 @d8
+  Scenario: Test multivalue fields with named field columns on node content
+    When I am viewing a "post" content:
+      | title                      | Post title                             |
+      | field_post_address:country | IT, JP                                 |
+      | :locality                  | Milan, Tokyo                           |
+      | :thoroughfare              | 1 Corso Buenos Aires, Shibuya Crossing |
+      | :postal_code               | 20124, 150-0040                        |
+    Then I should see "Italy"
+    And I should see "Milan"
+    And I should see "1 Corso Buenos Aires"
+    And I should see "20124"
+    And I should see "Japan"
+    And I should see "Tokyo"
+    And I should see "Shibuya Crossing"
+    And I should see "150-0040"
+
+  @d7 @d8
+  Scenario: Test various user field handlers in Drupal 7.
+    Given "tags" terms:
+      | name      |
+      | Tag one   |
+      | Tag two   |
+    And "page" content:
+      | title      |
+      | Page one   |
+      | Page two   |
+      | Page three |
+    And users:
+      | name     | mail         | field_tags       | field_post_reference | field_post_address                                                               |
+      | Jane Doe |              |                  |                      |                                                                                  |
+      | John Doe | john@doe.com | Tag one, Tag two | Page one, Page two   | country: BE - locality: Brussel - thoroughfare: Louisalaan 1 - postal_code: 1000 |
+    And I am logged in as a user with the "administrator" role
+    When I visit "admin/people"
+    Then I should see the link "Jane Doe"
+    And I should see the link "John Doe"
+    When I click "John Doe"
+    Then I should see the link "Tag one"
+    And I should see the link "Tag two"
+    But I should not see the link "Tag three"
+    And I should see "Page one"
+    And I should see "Page two"
+    But I should not see "Page three"
+    And I should see "Belgium"
+    And I should see "Brussel"
+    And I should see "1000"
+    And I should see "Louisalaan 1"
+
+  @d7 @d8
+  Scenario: Test using @Transform to provide human friendly aliases for named field columns
+    Given users:
+      | name     | mail             | street        | city     | postcode | country |
+      | Jane Doe | jane@example.com | Pioneer Place | Portland | OR 97204 | US      |
+    And I am logged in as a user with the "administrator" role
+    When I visit "admin/people"
+    And I click "Jane Doe"
+    Then I should see "United States"
+    And I should see "Portland"
+    And I should see "Pioneer Place"
+    And I should see "OR 97204"
+
+  @d7 @d8
+  Scenario: Test taxonomy term reference field handler
+    Given "tags" terms:
+      | name      |
+      | Tag one   |
+      | Tag two   |
+      | Tag three |
+      | Tag four  |
+    And "article" content:
+      | title           | body             | promote | field_tags                  |
+      | Article by Joe  | PLACEHOLDER BODY |       1 | Tag one, Tag two, Tag three |
+      | Article by Mike | PLACEHOLDER BODY |       1 | Tag four                    |
+      | Article by Jane |                  |         |                             |
+    And I am logged in as a user with the "administrator" role
+    When I visit "admin/content"
+    Then I should see the link "Article by Joe"
+    And I should see the link "Article by Mike"
+    And I should see the link "Article by Jane"
+    When I am on the homepage
+    Then I should see the link "Article by Joe"
+    And I should see the link "Tag one"
+    And I should see the link "Tag two"
+    And I should see the link "Tag three"
+    And I should see the link "Article by Mike"
+    And I should see the link "Tag four"
+    And I should see the link "Article by Joe"
+    And I should not see the link "Article by Jane"
+
+  @d7
+  # There is no support for date ranges in D8 yet, so only test D7 for now.
+  Scenario: Test date ranges in Drupal 7
+    When I am viewing a "post" content:
+      | title                | Post title                                                                       |
+      | body                 | PLACEHOLDER BODY                                                                 |
+      | field_post_dates     | 2015-02-10 17:45:00 - 2015-03-10 17:45:00                                        |
+    Then I should see "to Tuesday, March 10, 2015"
diff --git a/vendor/drupal/drupal-extension/features/language.feature b/vendor/drupal/drupal-extension/features/language.feature
new file mode 100644 (file)
index 0000000..8bfb73a
--- /dev/null
@@ -0,0 +1,21 @@
+@api @d7 @d8
+Feature: Language support
+  In order to demonstrate the language integration
+  As a developer for the Behat Extension
+  I need to provide test cases for the language support
+
+  # These test scenarios assume to have a clean installation of the "standard"
+  # profile and that the "behat_test" module from the "fixtures/" folder is
+  # enabled on the site.
+
+  Scenario: Enable multiple languages
+    Given the following languages are available:
+      | languages |
+      | en        |
+      | fr        |
+      | de        |
+    And I am logged in as a user with the 'administrator' role
+    When I go to "admin/config/regional/language"
+    Then I should see "English"
+    And I should see "French"
+    And I should see "German"
diff --git a/vendor/drupal/drupal-extension/features/messages.feature b/vendor/drupal/drupal-extension/features/messages.feature
new file mode 100644 (file)
index 0000000..802bbd7
--- /dev/null
@@ -0,0 +1,19 @@
+@api @d8
+Feature: Ensure that messages are working properly on local installs
+  In order to be sure that Drupal 8 with Big Pipe enabled can be tested
+  Messages are tested against a local installation
+
+  Scenario: Non-JS messages
+    Given I am on "/user/login"
+    When I fill in "a fake user" for "Username"
+    And I fill in "a fake password" for "Password"
+    When I press "Log in"
+    Then I should see the error message "Unrecognized username or password"
+
+  @javascript
+  Scenario: JS messages
+    Given I am on "/user/login"
+    When I fill in "a fake user" for "Username"
+    And I fill in "a fake password" for "Password"
+    When I press "Log in"
+    Then I should see the error message "Unrecognized username or password"
diff --git a/vendor/drupal/drupal-extension/features/subcontexts/find.feature b/vendor/drupal/drupal-extension/features/subcontexts/find.feature
new file mode 100644 (file)
index 0000000..91af75f
--- /dev/null
@@ -0,0 +1,68 @@
+Feature: Ability to find Drupal sub-contexts
+  In order to facilitate maintainable step-definitions
+  As a feature developer
+  I need to be able to define step-definitions within corresponding Drupal modules or projects
+
+  Background:
+    Given a file named "foo.behat.inc" with:
+      """
+      <?php
+
+      use Behat\Behat\Tester\Exception\PendingException;
+
+      use Drupal\DrupalExtension\Context\DrupalSubContextInterface;
+      use Drupal\DrupalDriverManager;
+
+      class FooFoo implements DrupalSubContextInterface {
+
+        private $drupal;
+
+        public function __construct(DrupalDriverManager $drupal) {
+          $this->drupal = $drupal;
+        }
+
+        /**
+         * @Then /^I should have a subcontext definition$/
+         */
+        public function assertSubContextDefinition() {
+          throw new PendingException();
+        }
+      }
+      """
+    And a file named "features/foo.feature" with:
+      """
+      Feature: Test foo subcontext
+
+        Scenario: Test foo subcontext
+          Given I should have a subcontext definition
+      """
+    And a file named "behat.yml" with:
+      """
+      default:
+        suites:
+          default:
+            contexts: [Drupal\DrupalExtension\Context\DrupalContext]
+        extensions:
+          Behat\MinkExtension:
+            goutte: ~
+            selenium2: ~
+            base_url: http://drupal.org
+          Drupal\DrupalExtension:
+            blackbox: ~
+            subcontexts:
+              paths: { foo: './' }
+      """
+
+  Scenario: Step-definitions in sub-contexts are available
+   When I run "behat --no-colors -dl"
+   Then the output should contain:
+      """
+      Then /^I should have a subcontext definition$/
+      """
+
+ Scenario: Subcontext can be instantiated
+   When I run "behat --no-colors"
+   Then the output should contain:
+     """
+     TODO: write pending definition
+     """
diff --git a/vendor/drupal/drupal-extension/fixtures/blackbox/community.html b/vendor/drupal/drupal-extension/fixtures/blackbox/community.html
new file mode 100644 (file)
index 0000000..6b13a75
--- /dev/null
@@ -0,0 +1,10 @@
+<html>
+  <head>
+    <title>Where is the Drupal community? | Drupal.org</title>
+  </head>
+  <body>
+    <div id="content">
+      <a href="irc.html">IRC</a>
+    </div>
+  </body>
+</html>
diff --git a/vendor/drupal/drupal-extension/fixtures/blackbox/download.html b/vendor/drupal/drupal-extension/fixtures/blackbox/download.html
new file mode 100644 (file)
index 0000000..fb4d5fc
--- /dev/null
@@ -0,0 +1,11 @@
+<html>
+  <head>
+    <title>Download &amp; Extend | Drupal.org</title>
+  </head>
+  <body>
+    <div id="content">
+      <h2>Download</h2>
+      <a href="index.html">Distributions</a>
+    </div>
+  </body>
+</html>
diff --git a/vendor/drupal/drupal-extension/fixtures/blackbox/form.html b/vendor/drupal/drupal-extension/fixtures/blackbox/form.html
new file mode 100644 (file)
index 0000000..b06f653
--- /dev/null
@@ -0,0 +1,17 @@
+<html>
+  <head>
+    <title>Search results | Drupal.org</title>
+  </head>
+  <body>
+    </div>
+    <div id="aside-region">
+      <a href="index.html">Search again</a>
+    </div>
+    <div class="messages error">
+      <ul>
+        <li>Username or email field is required.</li>
+        <li>Password field is required.</li>
+      </ul>
+    </div>
+  </body>
+</html>
diff --git a/vendor/drupal/drupal-extension/fixtures/blackbox/index.html b/vendor/drupal/drupal-extension/fixtures/blackbox/index.html
new file mode 100644 (file)
index 0000000..d50b7db
--- /dev/null
@@ -0,0 +1,23 @@
+<html>
+  <head>
+    <title>Drupal - Open Source CMS | Drupal.org</title>
+  </head>
+  <body>
+    <div id="nav-header">
+      <div id="header-left">
+        <h1 id="site-name">Drupal</h1>
+        <p>Build something amazing.</p>
+        <form action="form.html">
+          <label for="search">Search&hellip;</label>
+          <input id="search" name="search" type="text"/>
+          <input type="submit" value="Search"/>
+        </form>
+      </div>
+      <div id="header-right">
+        <a href="download.html">Download &amp; Extend</a>
+      </div>
+    </div>
+    <div id="footer">
+    </div>
+  </body>
+</html>
diff --git a/vendor/drupal/drupal-extension/fixtures/blackbox/irc.html b/vendor/drupal/drupal-extension/fixtures/blackbox/irc.html
new file mode 100644 (file)
index 0000000..a853ae6
--- /dev/null
@@ -0,0 +1,13 @@
+<html>
+  <head>
+    <title>Chat with the Drupal community on IRC | Drupal.org</title>
+  </head>
+  <body>
+    <div id="aside-region">
+      <p>Page status"</p>
+    </div>
+    <div id="footer">
+      <a href="index.html">Drupal News</a>
+    </div>
+  </body>
+</html>
diff --git a/vendor/drupal/drupal-extension/fixtures/blackbox/user.html b/vendor/drupal/drupal-extension/fixtures/blackbox/user.html
new file mode 100644 (file)
index 0000000..0082078
--- /dev/null
@@ -0,0 +1,12 @@
+<html>
+  <head>
+    <title>Log in | Drupal.org</title>
+  </head>
+  <body>
+    <div id="content">
+      <form action="form.html">
+        <input type="submit" value="Log in"/>
+      </form>
+    </div>
+  </body>
+</html>
diff --git a/vendor/drupal/drupal-extension/fixtures/drupal6/modules/behat_test/behat_test.info b/vendor/drupal/drupal-extension/fixtures/drupal6/modules/behat_test/behat_test.info
new file mode 100644 (file)
index 0000000..3e0bc3f
--- /dev/null
@@ -0,0 +1,3 @@
+name = Behat test
+description = Test feature exposing basic configuration for Behat Drupal extension test.
+core = 6.x
diff --git a/vendor/drupal/drupal-extension/fixtures/drupal6/modules/behat_test/behat_test.install b/vendor/drupal/drupal-extension/fixtures/drupal6/modules/behat_test/behat_test.install
new file mode 100644 (file)
index 0000000..d0a0ede
--- /dev/null
@@ -0,0 +1,11 @@
+<?php
+
+/**
+ * Implements hook_install().
+ */
+function behat_test_install() {
+  $edit = array();
+  $edit['name'] = 'tags';
+  $edit['help'] = '';
+  taxonomy_save_vocabulary($edit);
+}
diff --git a/vendor/drupal/drupal-extension/fixtures/drupal6/modules/behat_test/behat_test.module b/vendor/drupal/drupal-extension/fixtures/drupal6/modules/behat_test/behat_test.module
new file mode 100644 (file)
index 0000000..b3d9bbc
--- /dev/null
@@ -0,0 +1 @@
+<?php
diff --git a/vendor/drupal/drupal-extension/fixtures/drupal7/modules/behat_test/behat_test.features.field_base.inc b/vendor/drupal/drupal-extension/fixtures/drupal7/modules/behat_test/behat_test.features.field_base.inc
new file mode 100644 (file)
index 0000000..9fd91ba
--- /dev/null
@@ -0,0 +1,240 @@
+<?php
+/**
+ * @file
+ * behat_test.features.field_base.inc
+ */
+
+/**
+ * Implements hook_field_default_field_bases().
+ */
+function behat_test_field_default_field_bases() {
+  $field_bases = array();
+
+  // Exported field_base: 'body'
+  $field_bases['body'] = array(
+    'active' => 1,
+    'cardinality' => 1,
+    'deleted' => 0,
+    'entity_types' => array(
+      0 => 'node',
+    ),
+    'field_name' => 'body',
+    'foreign keys' => array(
+      'format' => array(
+        'columns' => array(
+          'format' => 'format',
+        ),
+        'table' => 'filter_format',
+      ),
+    ),
+    'indexes' => array(
+      'format' => array(
+        0 => 'format',
+      ),
+    ),
+    'locked' => 0,
+    'module' => 'text',
+    'settings' => array(),
+    'translatable' => 0,
+    'type' => 'text_with_summary',
+  );
+
+  // Exported field_base: 'field_post_address'
+  $field_bases['field_post_address'] = array(
+    'active' => 1,
+    'cardinality' => 2,
+    'deleted' => 0,
+    'entity_types' => array(),
+    'field_name' => 'field_post_address',
+    'indexes' => array(),
+    'locked' => 0,
+    'module' => 'addressfield',
+    'settings' => array(),
+    'translatable' => 0,
+    'type' => 'addressfield',
+  );
+
+  // Exported field_base: 'field_post_date'
+  $field_bases['field_post_date'] = array(
+    'active' => 1,
+    'cardinality' => 1,
+    'deleted' => 0,
+    'entity_types' => array(),
+    'field_name' => 'field_post_date',
+    'foreign keys' => array(),
+    'indexes' => array(),
+    'locked' => 0,
+    'module' => 'date',
+    'settings' => array(
+      'cache_count' => 4,
+      'cache_enabled' => 0,
+      'granularity' => array(
+        'day' => 'day',
+        'hour' => 'hour',
+        'minute' => 'minute',
+        'month' => 'month',
+        'second' => 0,
+        'year' => 'year',
+      ),
+      'timezone_db' => 'UTC',
+      'todate' => '',
+      'tz_handling' => 'site',
+    ),
+    'translatable' => 0,
+    'type' => 'datetime',
+  );
+
+  // Exported field_base: 'field_post_dates'
+  $field_bases['field_post_dates'] = array(
+    'active' => 1,
+    'cardinality' => 1,
+    'deleted' => 0,
+    'entity_types' => array(),
+    'field_name' => 'field_post_dates',
+    'foreign keys' => array(),
+    'indexes' => array(),
+    'locked' => 0,
+    'module' => 'date',
+    'settings' => array(
+      'cache_count' => 4,
+      'cache_enabled' => 0,
+      'granularity' => array(
+        'day' => 'day',
+        'hour' => 'hour',
+        'minute' => 'minute',
+        'month' => 'month',
+        'second' => 0,
+        'year' => 'year',
+      ),
+      'timezone_db' => 'UTC',
+      'todate' => 'optional',
+      'tz_handling' => 'site',
+    ),
+    'translatable' => 0,
+    'type' => 'datetime',
+  );
+
+  // Exported field_base: 'field_post_links'
+  $field_bases['field_post_links'] = array(
+    'active' => 1,
+    'cardinality' => -1,
+    'deleted' => 0,
+    'entity_types' => array(),
+    'field_name' => 'field_post_links',
+    'foreign keys' => array(),
+    'indexes' => array(),
+    'locked' => 0,
+    'module' => 'link',
+    'settings' => array(
+      'attributes' => array(
+        'class' => '',
+        'rel' => '',
+        'target' => 'default',
+      ),
+      'display' => array(
+        'url_cutoff' => 80,
+      ),
+      'enable_tokens' => 1,
+      'title' => 'optional',
+      'title_maxlength' => 128,
+      'title_value' => '',
+      'url' => 0,
+    ),
+    'translatable' => 0,
+    'type' => 'link_field',
+  );
+
+  // Exported field_base: 'field_post_reference'
+  $field_bases['field_post_reference'] = array(
+    'active' => 1,
+    'cardinality' => -1,
+    'deleted' => 0,
+    'entity_types' => array(),
+    'field_name' => 'field_post_reference',
+    'foreign keys' => array(),
+    'indexes' => array(
+      'target_id' => array(
+        0 => 'target_id',
+      ),
+    ),
+    'locked' => 0,
+    'module' => 'entityreference',
+    'settings' => array(
+      'handler' => 'base',
+      'handler_settings' => array(
+        'sort' => array(
+          'type' => 'none',
+        ),
+        'target_bundles' => array(
+          'page' => 'page',
+        ),
+      ),
+      'target_type' => 'node',
+    ),
+    'translatable' => 0,
+    'type' => 'entityreference',
+  );
+
+  // Exported field_base: 'field_post_select'
+  $field_bases['field_post_select'] = array(
+    'active' => 1,
+    'cardinality' => -1,
+    'deleted' => 0,
+    'entity_types' => array(),
+    'field_name' => 'field_post_select',
+    'foreign keys' => array(),
+    'indexes' => array(
+      'value' => array(
+        0 => 'value',
+      ),
+    ),
+    'locked' => 0,
+    'module' => 'list',
+    'settings' => array(
+      'allowed_values' => array(
+        1 => 'One',
+        2 => 'Two',
+        3 => 'Three',
+      ),
+      'allowed_values_function' => '',
+    ),
+    'translatable' => 0,
+    'type' => 'list_text',
+  );
+
+  // Exported field_base: 'field_tags'
+  $field_bases['field_tags'] = array(
+    'active' => 1,
+    'cardinality' => -1,
+    'deleted' => 0,
+    'entity_types' => array(),
+    'field_name' => 'field_tags',
+    'foreign keys' => array(
+      'tid' => array(
+        'columns' => array(
+          'tid' => 'tid',
+        ),
+        'table' => 'taxonomy_term_data',
+      ),
+    ),
+    'indexes' => array(
+      'tid' => array(
+        0 => 'tid',
+      ),
+    ),
+    'locked' => 0,
+    'module' => 'taxonomy',
+    'settings' => array(
+      'allowed_values' => array(
+        0 => array(
+          'vocabulary' => 'tags',
+          'parent' => 0,
+        ),
+      ),
+    ),
+    'translatable' => 0,
+    'type' => 'taxonomy_term_reference',
+  );
+
+  return $field_bases;
+}
diff --git a/vendor/drupal/drupal-extension/fixtures/drupal7/modules/behat_test/behat_test.features.field_instance.inc b/vendor/drupal/drupal-extension/fixtures/drupal7/modules/behat_test/behat_test.features.field_instance.inc
new file mode 100644 (file)
index 0000000..b74ea6a
--- /dev/null
@@ -0,0 +1,479 @@
+<?php
+/**
+ * @file
+ * behat_test.features.field_instance.inc
+ */
+
+/**
+ * Implements hook_field_default_field_instances().
+ */
+function behat_test_field_default_field_instances() {
+  $field_instances = array();
+
+  // Exported field_instance: 'node-post-body'
+  $field_instances['node-post-body'] = array(
+    'bundle' => 'post',
+    'default_value' => NULL,
+    'deleted' => 0,
+    'description' => '',
+    'display' => array(
+      'default' => array(
+        'label' => 'hidden',
+        'module' => 'text',
+        'settings' => array(),
+        'type' => 'text_default',
+        'weight' => 0,
+      ),
+      'teaser' => array(
+        'label' => 'hidden',
+        'module' => 'text',
+        'settings' => array(
+          'trim_length' => 600,
+        ),
+        'type' => 'text_summary_or_trimmed',
+        'weight' => 0,
+      ),
+    ),
+    'entity_type' => 'node',
+    'field_name' => 'body',
+    'label' => 'Body',
+    'required' => FALSE,
+    'settings' => array(
+      'display_summary' => TRUE,
+      'text_processing' => 1,
+      'user_register_form' => FALSE,
+    ),
+    'widget' => array(
+      'module' => 'text',
+      'settings' => array(
+        'rows' => 20,
+        'summary_rows' => 5,
+      ),
+      'type' => 'text_textarea_with_summary',
+      'weight' => 1,
+    ),
+  );
+
+  // Exported field_instance: 'node-post-field_post_address'
+  $field_instances['node-post-field_post_address'] = array(
+    'bundle' => 'post',
+    'default_value' => NULL,
+    'deleted' => 0,
+    'description' => '',
+    'display' => array(
+      'default' => array(
+        'label' => 'above',
+        'module' => 'addressfield',
+        'settings' => array(
+          'format_handlers' => array(
+            0 => 'address',
+          ),
+          'use_widget_handlers' => 1,
+        ),
+        'type' => 'addressfield_default',
+        'weight' => 6,
+      ),
+      'teaser' => array(
+        'label' => 'above',
+        'settings' => array(),
+        'type' => 'hidden',
+        'weight' => 0,
+      ),
+    ),
+    'entity_type' => 'node',
+    'field_name' => 'field_post_address',
+    'label' => 'Address',
+    'required' => 0,
+    'settings' => array(
+      'user_register_form' => FALSE,
+    ),
+    'widget' => array(
+      'active' => 1,
+      'module' => 'addressfield',
+      'settings' => array(
+        'available_countries' => array(),
+        'default_country' => 'site_default',
+        'format_handlers' => array(
+          'address' => 'address',
+          'address-hide-postal-code' => 0,
+          'address-hide-street' => 0,
+          'address-hide-country' => 0,
+          'organisation' => 0,
+          'name-full' => 0,
+          'name-oneline' => 0,
+          'address-optional' => 0,
+        ),
+      ),
+      'type' => 'addressfield_standard',
+      'weight' => 7,
+    ),
+  );
+
+  // Exported field_instance: 'node-post-field_post_date'
+  $field_instances['node-post-field_post_date'] = array(
+    'bundle' => 'post',
+    'deleted' => 0,
+    'description' => '',
+    'display' => array(
+      'default' => array(
+        'label' => 'above',
+        'module' => 'date',
+        'settings' => array(
+          'format_type' => 'long',
+          'fromto' => 'both',
+          'multiple_from' => '',
+          'multiple_number' => '',
+          'multiple_to' => '',
+        ),
+        'type' => 'date_default',
+        'weight' => 5,
+      ),
+      'teaser' => array(
+        'label' => 'above',
+        'settings' => array(),
+        'type' => 'hidden',
+        'weight' => 0,
+      ),
+    ),
+    'entity_type' => 'node',
+    'field_name' => 'field_post_date',
+    'label' => 'Single date',
+    'required' => 0,
+    'settings' => array(
+      'default_value' => 'now',
+      'default_value2' => 'same',
+      'default_value_code' => '',
+      'default_value_code2' => '',
+      'user_register_form' => FALSE,
+    ),
+    'widget' => array(
+      'active' => 1,
+      'module' => 'date',
+      'settings' => array(
+        'increment' => 15,
+        'input_format' => 'm/d/Y - H:i:s',
+        'input_format_custom' => '',
+        'label_position' => 'above',
+        'text_parts' => array(),
+        'year_range' => '-3:+3',
+      ),
+      'type' => 'date_select',
+      'weight' => 2,
+    ),
+  );
+
+  // Exported field_instance: 'node-post-field_post_dates'
+  $field_instances['node-post-field_post_dates'] = array(
+    'bundle' => 'post',
+    'deleted' => 0,
+    'description' => '',
+    'display' => array(
+      'default' => array(
+        'label' => 'above',
+        'module' => 'date',
+        'settings' => array(
+          'format_type' => 'long',
+          'fromto' => 'both',
+          'multiple_from' => '',
+          'multiple_number' => '',
+          'multiple_to' => '',
+        ),
+        'type' => 'date_default',
+        'weight' => 1,
+      ),
+      'teaser' => array(
+        'label' => 'above',
+        'settings' => array(),
+        'type' => 'hidden',
+        'weight' => 0,
+      ),
+    ),
+    'entity_type' => 'node',
+    'field_name' => 'field_post_dates',
+    'label' => 'Start/ending dates',
+    'required' => 0,
+    'settings' => array(
+      'default_value' => 'now',
+      'default_value2' => 'same',
+      'default_value_code' => '',
+      'default_value_code2' => '',
+      'user_register_form' => FALSE,
+    ),
+    'widget' => array(
+      'active' => 1,
+      'module' => 'date',
+      'settings' => array(
+        'increment' => 15,
+        'input_format' => 'm/d/Y - H:i:s',
+        'input_format_custom' => '',
+        'label_position' => 'above',
+        'text_parts' => array(),
+        'year_range' => '-3:+3',
+      ),
+      'type' => 'date_select',
+      'weight' => 3,
+    ),
+  );
+
+  // Exported field_instance: 'node-post-field_post_links'
+  $field_instances['node-post-field_post_links'] = array(
+    'bundle' => 'post',
+    'default_value' => NULL,
+    'deleted' => 0,
+    'description' => '',
+    'display' => array(
+      'default' => array(
+        'label' => 'above',
+        'module' => 'link',
+        'settings' => array(),
+        'type' => 'link_default',
+        'weight' => 2,
+      ),
+      'teaser' => array(
+        'label' => 'above',
+        'settings' => array(),
+        'type' => 'hidden',
+        'weight' => 0,
+      ),
+    ),
+    'entity_type' => 'node',
+    'field_name' => 'field_post_links',
+    'label' => 'Links',
+    'required' => 0,
+    'settings' => array(
+      'absolute_url' => 1,
+      'attributes' => array(
+        'class' => '',
+        'configurable_class' => 0,
+        'configurable_title' => 0,
+        'rel' => '',
+        'target' => 'default',
+        'title' => '',
+      ),
+      'display' => array(
+        'url_cutoff' => 80,
+      ),
+      'enable_tokens' => 1,
+      'rel_remove' => 'default',
+      'title' => 'optional',
+      'title_label_use_field_label' => 0,
+      'title_maxlength' => 128,
+      'title_value' => '',
+      'url' => 0,
+      'user_register_form' => FALSE,
+      'validate_url' => 1,
+    ),
+    'widget' => array(
+      'active' => 0,
+      'module' => 'link',
+      'settings' => array(),
+      'type' => 'link_field',
+      'weight' => 4,
+    ),
+  );
+
+  // Exported field_instance: 'node-post-field_post_reference'
+  $field_instances['node-post-field_post_reference'] = array(
+    'bundle' => 'post',
+    'default_value' => NULL,
+    'deleted' => 0,
+    'description' => '',
+    'display' => array(
+      'default' => array(
+        'label' => 'above',
+        'module' => 'entityreference',
+        'settings' => array(
+          'link' => FALSE,
+        ),
+        'type' => 'entityreference_label',
+        'weight' => 3,
+      ),
+      'teaser' => array(
+        'label' => 'above',
+        'settings' => array(),
+        'type' => 'hidden',
+        'weight' => 0,
+      ),
+    ),
+    'entity_type' => 'node',
+    'field_name' => 'field_post_reference',
+    'label' => 'Reference',
+    'required' => 0,
+    'settings' => array(
+      'user_register_form' => FALSE,
+    ),
+    'widget' => array(
+      'active' => 1,
+      'module' => 'options',
+      'settings' => array(),
+      'type' => 'options_buttons',
+      'weight' => 5,
+    ),
+  );
+
+  // Exported field_instance: 'node-post-field_post_select'
+  $field_instances['node-post-field_post_select'] = array(
+    'bundle' => 'post',
+    'default_value' => NULL,
+    'deleted' => 0,
+    'description' => '',
+    'display' => array(
+      'default' => array(
+        'label' => 'above',
+        'module' => 'list',
+        'settings' => array(),
+        'type' => 'list_default',
+        'weight' => 4,
+      ),
+      'teaser' => array(
+        'label' => 'above',
+        'settings' => array(),
+        'type' => 'hidden',
+        'weight' => 0,
+      ),
+    ),
+    'entity_type' => 'node',
+    'field_name' => 'field_post_select',
+    'label' => 'Select list',
+    'required' => 0,
+    'settings' => array(
+      'user_register_form' => FALSE,
+    ),
+    'widget' => array(
+      'active' => 1,
+      'module' => 'options',
+      'settings' => array(),
+      'type' => 'options_buttons',
+      'weight' => 6,
+    ),
+  );
+
+  // Exported field_instance: 'user-user-field_post_address'
+  $field_instances['user-user-field_post_address'] = array(
+    'bundle' => 'user',
+    'default_value' => NULL,
+    'deleted' => 0,
+    'description' => '',
+    'display' => array(
+      'default' => array(
+        'label' => 'above',
+        'module' => 'addressfield',
+        'settings' => array(
+          'format_handlers' => array(
+            0 => 'address',
+          ),
+          'use_widget_handlers' => 1,
+        ),
+        'type' => 'addressfield_default',
+        'weight' => 2,
+      ),
+    ),
+    'entity_type' => 'user',
+    'field_name' => 'field_post_address',
+    'label' => 'Address',
+    'required' => 0,
+    'settings' => array(
+      'user_register_form' => 0,
+    ),
+    'widget' => array(
+      'active' => 1,
+      'module' => 'addressfield',
+      'settings' => array(
+        'available_countries' => array(),
+        'default_country' => 'site_default',
+        'format_handlers' => array(
+          'address' => 'address',
+          'address-hide-postal-code' => 0,
+          'address-hide-street' => 0,
+          'address-hide-country' => 0,
+          'organisation' => 0,
+          'name-full' => 0,
+          'name-oneline' => 0,
+          'address-optional' => 0,
+        ),
+      ),
+      'type' => 'addressfield_standard',
+      'weight' => 12,
+    ),
+  );
+
+  // Exported field_instance: 'user-user-field_post_reference'
+  $field_instances['user-user-field_post_reference'] = array(
+    'bundle' => 'user',
+    'default_value' => NULL,
+    'deleted' => 0,
+    'description' => '',
+    'display' => array(
+      'default' => array(
+        'label' => 'above',
+        'module' => 'entityreference',
+        'settings' => array(
+          'link' => FALSE,
+        ),
+        'type' => 'entityreference_label',
+        'weight' => 1,
+      ),
+    ),
+    'entity_type' => 'user',
+    'field_name' => 'field_post_reference',
+    'label' => 'Reference',
+    'required' => 0,
+    'settings' => array(
+      'user_register_form' => 0,
+    ),
+    'widget' => array(
+      'active' => 1,
+      'module' => 'options',
+      'settings' => array(),
+      'type' => 'options_buttons',
+      'weight' => 10,
+    ),
+  );
+
+  // Exported field_instance: 'user-user-field_tags'
+  $field_instances['user-user-field_tags'] = array(
+    'bundle' => 'user',
+    'default_value' => NULL,
+    'deleted' => 0,
+    'description' => '',
+    'display' => array(
+      'default' => array(
+        'label' => 'above',
+        'module' => 'taxonomy',
+        'settings' => array(),
+        'type' => 'taxonomy_term_reference_link',
+        'weight' => 0,
+      ),
+    ),
+    'entity_type' => 'user',
+    'field_name' => 'field_tags',
+    'label' => 'Tags',
+    'required' => 0,
+    'settings' => array(
+      'user_register_form' => 0,
+    ),
+    'widget' => array(
+      'active' => 0,
+      'module' => 'taxonomy',
+      'settings' => array(
+        'autocomplete_path' => 'taxonomy/autocomplete',
+        'size' => 60,
+      ),
+      'type' => 'taxonomy_autocomplete',
+      'weight' => 8,
+    ),
+  );
+
+  // Translatables
+  // Included for use with string extractors like potx.
+  t('Address');
+  t('Body');
+  t('Links');
+  t('Reference');
+  t('Select list');
+  t('Single date');
+  t('Start/ending dates');
+  t('Tags');
+
+  return $field_instances;
+}
diff --git a/vendor/drupal/drupal-extension/fixtures/drupal7/modules/behat_test/behat_test.features.inc b/vendor/drupal/drupal-extension/fixtures/drupal7/modules/behat_test/behat_test.features.inc
new file mode 100644 (file)
index 0000000..6145dc7
--- /dev/null
@@ -0,0 +1,23 @@
+<?php
+/**
+ * @file
+ * behat_test.features.inc
+ */
+
+/**
+ * Implements hook_node_info().
+ */
+function behat_test_node_info() {
+  $items = array(
+    'post' => array(
+      'name' => t('Post'),
+      'base' => 'node_content',
+      'description' => t('Post content type.'),
+      'has_title' => '1',
+      'title_label' => t('Title'),
+      'help' => '',
+    ),
+  );
+  drupal_alter('node_info', $items);
+  return $items;
+}
diff --git a/vendor/drupal/drupal-extension/fixtures/drupal7/modules/behat_test/behat_test.features.taxonomy.inc b/vendor/drupal/drupal-extension/fixtures/drupal7/modules/behat_test/behat_test.features.taxonomy.inc
new file mode 100644 (file)
index 0000000..d287b7c
--- /dev/null
@@ -0,0 +1,36 @@
+<?php
+/**
+ * @file
+ * behat_test.features.taxonomy.inc
+ */
+
+/**
+ * Implements hook_taxonomy_default_vocabularies().
+ */
+function behat_test_taxonomy_default_vocabularies() {
+  return array(
+    'tags' => array(
+      'name' => 'Tags',
+      'machine_name' => 'tags',
+      'description' => 'Use tags to group articles on similar topics into categories.',
+      'hierarchy' => 0,
+      'module' => 'taxonomy',
+      'weight' => 0,
+      'rdf_mapping' => array(
+        'rdftype' => array(
+          0 => 'skos:ConceptScheme',
+        ),
+        'name' => array(
+          'predicates' => array(
+            0 => 'dc:title',
+          ),
+        ),
+        'description' => array(
+          'predicates' => array(
+            0 => 'rdfs:comment',
+          ),
+        ),
+      ),
+    ),
+  );
+}
diff --git a/vendor/drupal/drupal-extension/fixtures/drupal7/modules/behat_test/behat_test.features.user_permission.inc b/vendor/drupal/drupal-extension/fixtures/drupal7/modules/behat_test/behat_test.features.user_permission.inc
new file mode 100644 (file)
index 0000000..e7f57fe
--- /dev/null
@@ -0,0 +1,49 @@
+<?php
+/**
+ * @file
+ * behat_test.features.user_permission.inc
+ */
+
+/**
+ * Implements hook_user_default_permissions().
+ */
+function behat_test_user_default_permissions() {
+  $permissions = array();
+
+  // Exported permission: 'create post content'.
+  $permissions['create post content'] = array(
+    'name' => 'create post content',
+    'roles' => array(),
+    'module' => 'node',
+  );
+
+  // Exported permission: 'delete any post content'.
+  $permissions['delete any post content'] = array(
+    'name' => 'delete any post content',
+    'roles' => array(),
+    'module' => 'node',
+  );
+
+  // Exported permission: 'delete own post content'.
+  $permissions['delete own post content'] = array(
+    'name' => 'delete own post content',
+    'roles' => array(),
+    'module' => 'node',
+  );
+
+  // Exported permission: 'edit any post content'.
+  $permissions['edit any post content'] = array(
+    'name' => 'edit any post content',
+    'roles' => array(),
+    'module' => 'node',
+  );
+
+  // Exported permission: 'edit own post content'.
+  $permissions['edit own post content'] = array(
+    'name' => 'edit own post content',
+    'roles' => array(),
+    'module' => 'node',
+  );
+
+  return $permissions;
+}
diff --git a/vendor/drupal/drupal-extension/fixtures/drupal7/modules/behat_test/behat_test.info b/vendor/drupal/drupal-extension/fixtures/drupal7/modules/behat_test/behat_test.info
new file mode 100644 (file)
index 0000000..d9fa946
--- /dev/null
@@ -0,0 +1,41 @@
+name = Behat test
+description = Test feature exposing basic configuration for Behat Drupal extension test.
+core = 7.x
+package = Features
+dependencies[] = addressfield
+dependencies[] = date
+dependencies[] = entityreference
+dependencies[] = features
+dependencies[] = link
+dependencies[] = list
+dependencies[] = locale
+dependencies[] = node
+dependencies[] = options
+dependencies[] = taxonomy
+dependencies[] = text
+features[features_api][] = api:2
+features[field_base][] = body
+features[field_base][] = field_post_address
+features[field_base][] = field_post_date
+features[field_base][] = field_post_dates
+features[field_base][] = field_post_links
+features[field_base][] = field_post_reference
+features[field_base][] = field_post_select
+features[field_base][] = field_tags
+features[field_instance][] = node-post-body
+features[field_instance][] = node-post-field_post_address
+features[field_instance][] = node-post-field_post_date
+features[field_instance][] = node-post-field_post_dates
+features[field_instance][] = node-post-field_post_links
+features[field_instance][] = node-post-field_post_reference
+features[field_instance][] = node-post-field_post_select
+features[field_instance][] = user-user-field_post_address
+features[field_instance][] = user-user-field_post_reference
+features[field_instance][] = user-user-field_tags
+features[node][] = post
+features[taxonomy][] = tags
+features[user_permission][] = create post content
+features[user_permission][] = delete any post content
+features[user_permission][] = delete own post content
+features[user_permission][] = edit any post content
+features[user_permission][] = edit own post content
diff --git a/vendor/drupal/drupal-extension/fixtures/drupal7/modules/behat_test/behat_test.module b/vendor/drupal/drupal-extension/fixtures/drupal7/modules/behat_test/behat_test.module
new file mode 100644 (file)
index 0000000..57996ac
--- /dev/null
@@ -0,0 +1,7 @@
+<?php
+/**
+ * @file
+ * Code for the Behat test feature.
+ */
+
+include_once 'behat_test.features.inc';
diff --git a/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/behat_test.info.yml b/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/behat_test.info.yml
new file mode 100644 (file)
index 0000000..989a97b
--- /dev/null
@@ -0,0 +1,9 @@
+name: Behat test
+type: module
+description: 'Test feature exposing basic configuration for Behat Drupal extension test.'
+package: Test
+version: '8.x-1.x-dev'
+core: '8.x'
+project: 'behat_test'
+dependencies:
+  - language
diff --git a/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/behat_test.install b/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/behat_test.install
new file mode 100644 (file)
index 0000000..3423052
--- /dev/null
@@ -0,0 +1,23 @@
+<?php
+
+/**
+ * Implements hook_install()
+ */
+function behat_test_install() {
+  $storage = \Drupal::service('behat_test.config.storage.install');
+
+  // Override Standard profile's user settings with our own.
+  $config_names = array(
+    'core.entity_form_mode.user.register',
+    'core.entity_form_display.user.user.default',
+    'core.entity_view_display.user.user.default',
+    'core.entity_view_display.user.user.compact',
+    'core.entity_view_mode.user.compact',
+    'core.entity_view_mode.user.full',
+  );
+
+  foreach ($config_names as $config_name) {
+    $data = $storage->read($config_name);
+    \Drupal::configFactory()->getEditable($config_name)->setData($data)->save();
+  }
+}
diff --git a/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/behat_test.services.yml b/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/behat_test.services.yml
new file mode 100644 (file)
index 0000000..7bfd336
--- /dev/null
@@ -0,0 +1,5 @@
+services:
+  behat_test.config.storage.install:
+    class: Drupal\behat_test\Config\BehatTestExtensionInstallStorage
+    arguments: ['@config.storage', 'config/install']
+
diff --git a/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/config/install/core.entity_form_display.node.post.default.yml b/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/config/install/core.entity_form_display.node.post.default.yml
new file mode 100644 (file)
index 0000000..80c9fc0
--- /dev/null
@@ -0,0 +1,97 @@
+langcode: en
+status: true
+dependencies:
+  config:
+    - field.field.node.post.body
+    - field.field.node.post.field_post_address
+    - field.field.node.post.field_post_date
+    - field.field.node.post.field_post_links
+    - field.field.node.post.field_post_reference
+    - field.field.node.post.field_post_select
+    - node.type.post
+  module:
+    - datetime
+    - link
+    - path
+    - text
+id: node.post.default
+targetEntityType: node
+bundle: post
+mode: default
+content:
+  title:
+    type: string_textfield
+    weight: -5
+    settings:
+      size: 60
+      placeholder: ''
+    third_party_settings: {  }
+  uid:
+    type: entity_reference_autocomplete
+    weight: 5
+    settings:
+      match_operator: CONTAINS
+      size: 60
+      placeholder: ''
+    third_party_settings: {  }
+  created:
+    type: datetime_timestamp
+    weight: 10
+    settings: {  }
+    third_party_settings: {  }
+  promote:
+    type: boolean_checkbox
+    settings:
+      display_label: true
+    weight: 15
+    third_party_settings: {  }
+  sticky:
+    type: boolean_checkbox
+    settings:
+      display_label: true
+    weight: 16
+    third_party_settings: {  }
+  path:
+    type: path
+    weight: 30
+    settings: {  }
+    third_party_settings: {  }
+  body:
+    type: text_textarea_with_summary
+    weight: 31
+    settings:
+      rows: 9
+      summary_rows: 3
+      placeholder: ''
+    third_party_settings: {  }
+  field_post_reference:
+    weight: 32
+    settings:
+      match_operator: CONTAINS
+      size: 60
+      placeholder: ''
+    third_party_settings: {  }
+    type: entity_reference_autocomplete
+  field_post_address:
+    weight: 37
+    settings: {  }
+    third_party_settings: {  }
+    type: behat_test_address_field_default
+  field_post_date:
+    weight: 33
+    settings: {  }
+    third_party_settings: {  }
+    type: datetime_default
+  field_post_select:
+    weight: 35
+    settings: {  }
+    third_party_settings: {  }
+    type: options_select
+  field_post_links:
+    weight: 36
+    settings:
+      placeholder_url: ''
+      placeholder_title: ''
+    third_party_settings: {  }
+    type: link_default
+hidden: {  }
diff --git a/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/config/install/core.entity_view_display.node.post.default.yml b/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/config/install/core.entity_view_display.node.post.default.yml
new file mode 100644 (file)
index 0000000..50d6429
--- /dev/null
@@ -0,0 +1,71 @@
+langcode: en
+status: true
+dependencies:
+  config:
+    - field.field.node.post.body
+    - field.field.node.post.field_post_address
+    - field.field.node.post.field_post_date
+    - field.field.node.post.field_post_links
+    - field.field.node.post.field_post_reference
+    - field.field.node.post.field_post_select
+    - node.type.post
+  module:
+    - datetime
+    - link
+    - options
+    - text
+    - user
+id: node.post.default
+targetEntityType: node
+bundle: post
+mode: default
+content:
+  links:
+    weight: 100
+    settings: {  }
+    third_party_settings: {  }
+  body:
+    label: hidden
+    type: text_default
+    weight: 101
+    settings: {  }
+    third_party_settings: {  }
+  field_post_reference:
+    weight: 102
+    label: above
+    settings:
+      link: true
+    third_party_settings: {  }
+    type: entity_reference_label
+  field_post_address:
+    weight: 107
+    label: above
+    settings: {  }
+    third_party_settings: {  }
+    type: behat_test_address_field
+  field_post_date:
+    weight: 103
+    label: above
+    settings:
+      timezone_override: ''
+      date_format: 'l, F j, Y'
+    third_party_settings: {  }
+    type: datetime_custom
+  field_post_select:
+    weight: 105
+    label: above
+    settings: {  }
+    third_party_settings: {  }
+    type: list_default
+  field_post_links:
+    weight: 106
+    label: above
+    settings:
+      trim_length: 80
+      url_only: false
+      url_plain: false
+      rel: ''
+      target: ''
+    third_party_settings: {  }
+    type: link
+hidden: {  }
diff --git a/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/config/install/core.entity_view_display.node.post.teaser.yml b/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/config/install/core.entity_view_display.node.post.teaser.yml
new file mode 100644 (file)
index 0000000..69cf620
--- /dev/null
@@ -0,0 +1,36 @@
+langcode: en
+status: true
+dependencies:
+  config:
+    - core.entity_view_mode.node.teaser
+    - field.field.node.post.body
+    - field.field.node.post.field_post_address
+    - field.field.node.post.field_post_date
+    - field.field.node.post.field_post_links
+    - field.field.node.post.field_post_reference
+    - field.field.node.post.field_post_select
+    - node.type.post
+  module:
+    - text
+    - user
+id: node.post.teaser
+targetEntityType: node
+bundle: post
+mode: teaser
+content:
+  links:
+    weight: 100
+  body:
+    label: hidden
+    type: text_summary_or_trimmed
+    weight: 101
+    settings:
+      trim_length: 600
+    third_party_settings: {  }
+hidden:
+  field_post_address: true
+  field_post_date: true
+  field_post_reference: true
+  field_post_dates: true
+  field_post_links: true
+  field_post_select: true
diff --git a/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/config/install/field.field.node.post.body.yml b/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/config/install/field.field.node.post.body.yml
new file mode 100644 (file)
index 0000000..fc13ab1
--- /dev/null
@@ -0,0 +1,21 @@
+langcode: en
+status: true
+dependencies:
+  config:
+    - field.storage.node.body
+    - node.type.post
+  module:
+    - text
+id: node.post.body
+field_name: body
+entity_type: node
+bundle: post
+label: Body
+description: ''
+required: false
+translatable: true
+default_value: {  }
+default_value_callback: ''
+settings:
+  display_summary: true
+field_type: text_with_summary
diff --git a/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/config/install/field.field.node.post.field_post_address.yml b/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/config/install/field.field.node.post.field_post_address.yml
new file mode 100644 (file)
index 0000000..21eb3f0
--- /dev/null
@@ -0,0 +1,22 @@
+langcode: en
+status: true
+dependencies:
+  config:
+    - node.type.post
+id: node.post.field_post_address
+field_name: field_post_address
+entity_type: node
+bundle: post
+label: Address
+description: ''
+required: false
+translatable: false
+default_value:
+  -
+    country: ''
+    locality: ''
+    thoroughfare: ''
+    postal_code: ''
+default_value_callback: ''
+settings: {  }
+field_type: behat_test_address_field
diff --git a/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/config/install/field.field.node.post.field_post_date.yml b/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/config/install/field.field.node.post.field_post_date.yml
new file mode 100644 (file)
index 0000000..65121a0
--- /dev/null
@@ -0,0 +1,20 @@
+langcode: en
+status: true
+dependencies:
+  config:
+    - field.storage.node.field_post_date
+    - node.type.post
+  module:
+    - datetime
+id: node.post.field_post_date
+field_name: field_post_date
+entity_type: node
+bundle: post
+label: Date
+description: ''
+required: false
+translatable: false
+default_value: {  }
+default_value_callback: ''
+settings: {  }
+field_type: datetime
diff --git a/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/config/install/field.field.node.post.field_post_links.yml b/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/config/install/field.field.node.post.field_post_links.yml
new file mode 100644 (file)
index 0000000..6e58c8d
--- /dev/null
@@ -0,0 +1,22 @@
+langcode: en
+status: true
+dependencies:
+  config:
+    - field.storage.node.field_post_links
+    - node.type.post
+  module:
+    - link
+id: node.post.field_post_links
+field_name: field_post_links
+entity_type: node
+bundle: post
+label: Links
+description: ''
+required: false
+translatable: false
+default_value: {  }
+default_value_callback: ''
+settings:
+  link_type: 17
+  title: 1
+field_type: link
diff --git a/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/config/install/field.field.node.post.field_post_reference.yml b/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/config/install/field.field.node.post.field_post_reference.yml
new file mode 100644 (file)
index 0000000..10348e2
--- /dev/null
@@ -0,0 +1,24 @@
+langcode: en
+status: true
+dependencies:
+  config:
+    - field.storage.node.field_post_reference
+    - node.type.post
+id: node.post.field_post_reference
+field_name: field_post_reference
+entity_type: node
+bundle: post
+label: Reference
+description: ''
+required: false
+translatable: false
+default_value: {  }
+default_value_callback: ''
+settings:
+  handler: default
+  handler_settings:
+    target_bundles:
+      page: page
+    sort:
+      field: _none
+field_type: entity_reference
diff --git a/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/config/install/field.field.node.post.field_post_select.yml b/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/config/install/field.field.node.post.field_post_select.yml
new file mode 100644 (file)
index 0000000..772de60
--- /dev/null
@@ -0,0 +1,20 @@
+langcode: en
+status: true
+dependencies:
+  config:
+    - field.storage.node.field_post_select
+    - node.type.post
+  module:
+    - options
+id: node.post.field_post_select
+field_name: field_post_select
+entity_type: node
+bundle: post
+label: Select
+description: ''
+required: false
+translatable: false
+default_value: {  }
+default_value_callback: ''
+settings: {  }
+field_type: list_string
diff --git a/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/config/install/field.field.user.user.field_post_address.yml b/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/config/install/field.field.user.user.field_post_address.yml
new file mode 100644 (file)
index 0000000..8495afb
--- /dev/null
@@ -0,0 +1,27 @@
+langcode: en
+status: true
+dependencies:
+  config:
+    - field.storage.user.field_post_address
+id: user.user.field_post_address
+field_name: field_post_address
+entity_type: user
+bundle: user
+label: Address
+description: ''
+required: false
+translatable: false
+default_value:
+  -
+    country: ''
+    locality: ''
+    thoroughfare: ''
+    postal_code: ''
+  -
+    country: ''
+    locality: ''
+    thoroughfare: ''
+    postal_code: ''
+default_value_callback: ''
+settings: {  }
+field_type: behat_test_address_field
diff --git a/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/config/install/field.field.user.user.field_post_reference.yml b/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/config/install/field.field.user.user.field_post_reference.yml
new file mode 100644 (file)
index 0000000..ffdef30
--- /dev/null
@@ -0,0 +1,23 @@
+langcode: en
+status: true
+dependencies:
+  config:
+    - field.storage.user.field_post_reference
+id: user.user.field_post_reference
+field_name: field_post_reference
+entity_type: user
+bundle: user
+label: Reference
+description: ''
+required: false
+translatable: false
+default_value: {  }
+default_value_callback: ''
+settings:
+  handler: default
+  handler_settings:
+    target_bundles:
+      page: page
+    sort:
+      field: _none
+field_type: entity_reference
diff --git a/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/config/install/field.field.user.user.field_tags.yml b/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/config/install/field.field.user.user.field_tags.yml
new file mode 100644 (file)
index 0000000..d94d447
--- /dev/null
@@ -0,0 +1,26 @@
+langcode: en
+status: true
+dependencies:
+  config:
+    - field.storage.user.field_tags
+  module:
+    - taxonomy
+id: user.user.field_tags
+field_name: field_tags
+entity_type: user
+bundle: user
+label: Tags
+description: ''
+required: false
+translatable: false
+default_value: {  }
+default_value_callback: ''
+settings:
+  handler: default
+  handler_settings:
+    target_bundles:
+      tags: tags
+    sort:
+      field: _none
+    auto_create: true
+field_type: entity_reference
diff --git a/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/config/install/field.storage.node.field_post_adress.yml b/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/config/install/field.storage.node.field_post_adress.yml
new file mode 100644 (file)
index 0000000..1d476f1
--- /dev/null
@@ -0,0 +1,16 @@
+langcode: en
+status: true
+dependencies:
+  module:
+    - node
+id: node.field_post_address
+field_name: field_post_address
+entity_type: node
+type: behat_test_address_field
+settings: {  }
+module: behat_test
+locked: false
+cardinality: 2
+translatable: true
+indexes: {  }
+persist_with_no_fields: false
diff --git a/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/config/install/field.storage.node.field_post_date.yml b/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/config/install/field.storage.node.field_post_date.yml
new file mode 100644 (file)
index 0000000..91d41db
--- /dev/null
@@ -0,0 +1,18 @@
+langcode: en
+status: true
+dependencies:
+  module:
+    - datetime
+    - node
+id: node.field_post_date
+field_name: field_post_date
+entity_type: node
+type: datetime
+settings:
+  datetime_type: datetime
+module: datetime
+locked: false
+cardinality: 1
+translatable: true
+indexes: {  }
+persist_with_no_fields: false
diff --git a/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/config/install/field.storage.node.field_post_links.yml b/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/config/install/field.storage.node.field_post_links.yml
new file mode 100644 (file)
index 0000000..a5fc596
--- /dev/null
@@ -0,0 +1,17 @@
+langcode: en
+status: true
+dependencies:
+  module:
+    - link
+    - node
+id: node.field_post_links
+field_name: field_post_links
+entity_type: node
+type: link
+settings: {  }
+module: link
+locked: false
+cardinality: -1
+translatable: true
+indexes: {  }
+persist_with_no_fields: false
diff --git a/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/config/install/field.storage.node.field_post_reference.yml b/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/config/install/field.storage.node.field_post_reference.yml
new file mode 100644 (file)
index 0000000..7ab8cdf
--- /dev/null
@@ -0,0 +1,17 @@
+langcode: en
+status: true
+dependencies:
+  module:
+    - node
+id: node.field_post_reference
+field_name: field_post_reference
+entity_type: node
+type: entity_reference
+settings:
+  target_type: node
+module: entity_reference
+locked: false
+cardinality: -1
+translatable: true
+indexes: {  }
+persist_with_no_fields: false
diff --git a/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/config/install/field.storage.node.field_post_select.yml b/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/config/install/field.storage.node.field_post_select.yml
new file mode 100644 (file)
index 0000000..415c6e1
--- /dev/null
@@ -0,0 +1,28 @@
+langcode: en
+status: true
+dependencies:
+  module:
+    - node
+    - options
+id: node.field_post_select
+field_name: field_post_select
+entity_type: node
+type: list_string
+settings:
+  allowed_values:
+    -
+      value: '1'
+      label: One
+    -
+      value: '2'
+      label: Two
+    -
+      value: '3'
+      label: Three
+  allowed_values_function: ''
+module: options
+locked: false
+cardinality: 1
+translatable: true
+indexes: {  }
+persist_with_no_fields: false
diff --git a/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/config/install/field.storage.user.field_post_address.yml b/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/config/install/field.storage.user.field_post_address.yml
new file mode 100644 (file)
index 0000000..b290107
--- /dev/null
@@ -0,0 +1,16 @@
+langcode: en
+status: true
+dependencies:
+  module:
+    - user
+id: user.field_post_address
+field_name: field_post_address
+entity_type: user
+type: behat_test_address_field
+settings: {  }
+module: behat_test
+locked: false
+cardinality: 2
+translatable: true
+indexes: {  }
+persist_with_no_fields: false
diff --git a/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/config/install/field.storage.user.field_post_reference.yml b/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/config/install/field.storage.user.field_post_reference.yml
new file mode 100644 (file)
index 0000000..f039227
--- /dev/null
@@ -0,0 +1,17 @@
+langcode: en
+status: true
+dependencies:
+  module:
+    - user
+id: user.field_post_reference
+field_name: field_post_reference
+entity_type: user
+type: entity_reference
+settings:
+  target_type: node
+module: core
+locked: false
+cardinality: -1
+translatable: true
+indexes: {  }
+persist_with_no_fields: false
diff --git a/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/config/install/field.storage.user.field_tags.yml b/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/config/install/field.storage.user.field_tags.yml
new file mode 100644 (file)
index 0000000..86559b3
--- /dev/null
@@ -0,0 +1,17 @@
+langcode: en
+status: true
+dependencies:
+  module:
+    - taxonomy
+    - user
+id: user.field_tags
+field_name: field_tags
+entity_type: user
+type: entity_reference
+settings:
+  target_type: taxonomy_term
+module: core
+locked: false
+cardinality: -1
+translatable: true
+persist_with_no_fields: false
diff --git a/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/config/install/node.type.post.yml b/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/config/install/node.type.post.yml
new file mode 100644 (file)
index 0000000..e070259
--- /dev/null
@@ -0,0 +1,17 @@
+langcode: en
+status: true
+dependencies:
+  module:
+    - menu_ui
+third_party_settings:
+  menu_ui:
+    available_menus:
+      - main
+    parent: 'main:'
+name: Post
+type: post
+description: 'Post content type.'
+help: ''
+new_revision: false
+preview_mode: 1
+display_submitted: true
diff --git a/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/config/schema/behat_test.schema.yml b/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/config/schema/behat_test.schema.yml
new file mode 100644 (file)
index 0000000..9102c19
--- /dev/null
@@ -0,0 +1,18 @@
+# Schema for the configuration files of the Behat Test module.
+
+field.value.behat_test_address_field:
+  type: mapping
+  label: 'Default value'
+  mapping:
+    country:
+      type: string
+      label: 'Country'
+    locality:
+      type: string
+      label: 'Locality'
+    thoroughfare:
+      type: string
+      label: 'Thoroughfare'
+    postal_code:
+      type: string
+      label: 'Postal code'
diff --git a/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/override_config/core.entity_form_display.user.user.default.yml b/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/override_config/core.entity_form_display.user.user.default.yml
new file mode 100644 (file)
index 0000000..0aeb7fd
--- /dev/null
@@ -0,0 +1,66 @@
+langcode: und
+status: true
+dependencies:
+  config:
+    - field.field.user.user.field_post_address
+    - field.field.user.user.field_post_reference
+    - field.field.user.user.field_tags
+    - field.field.user.user.user_picture
+  module:
+    - image
+    - user
+id: user.user.default
+targetEntityType: user
+bundle: user
+mode: default
+content:
+  account:
+    weight: 0
+    settings: {  }
+    third_party_settings: {  }
+  user_picture:
+    type: image_image
+    weight: 1
+    settings:
+      progress_indicator: throbber
+      preview_image_style: thumbnail
+    third_party_settings: {  }
+  language:
+    weight: 2
+    settings: {  }
+    third_party_settings: {  }
+  contact:
+    weight: 3
+    settings: {  }
+    third_party_settings: {  }
+  timezone:
+    weight: 4
+    settings: {  }
+    third_party_settings: {  }
+  field_post_address:
+    type: behat_test_address_field_default
+    weight: 0
+    settings: {  }
+    third_party_settings: {  }
+  field_post_reference:
+    type: entity_reference_autocomplete
+    weight: 0
+    settings:
+      match_operator: CONTAINS
+      size: 60
+      placeholder: ''
+    third_party_settings: {  }
+  field_tags:
+    type: options_buttons
+    weight: 5
+    settings: {  }
+    third_party_settings: {  }
+  field_user_reference:
+    type: entity_reference_autocomplete
+    weight: 6
+    settings:
+      match_operator: CONTAINS
+      size: 60
+      placeholder: ''
+    third_party_settings: {  }
+hidden: {  }
diff --git a/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/override_config/core.entity_form_mode.user.register.yml b/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/override_config/core.entity_form_mode.user.register.yml
new file mode 100644 (file)
index 0000000..6857431
--- /dev/null
@@ -0,0 +1,9 @@
+langcode: und
+status: true
+dependencies:
+  module:
+    - user
+id: user.register
+label: Register
+targetEntityType: user
+cache: true
diff --git a/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/override_config/core.entity_view_display.user.user.compact.yml b/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/override_config/core.entity_view_display.user.user.compact.yml
new file mode 100644 (file)
index 0000000..e2fd9c7
--- /dev/null
@@ -0,0 +1,28 @@
+langcode: und
+status: true
+dependencies:
+  config:
+    - core.entity_view_mode.user.compact
+    - field.field.user.user.field_user_reference
+    - field.field.user.user.field_tags
+    - field.field.user.user.user_picture
+  module:
+    - image
+    - user
+id: user.user.compact
+targetEntityType: user
+bundle: user
+mode: compact
+content:
+  user_picture:
+    type: image
+    weight: 0
+    settings:
+      image_style: thumbnail
+      image_link: content
+    third_party_settings: {  }
+    label: hidden
+hidden:
+  member_for: true
+  field_user_reference: true
+  field_tags: true
diff --git a/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/override_config/core.entity_view_display.user.user.default.yml b/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/override_config/core.entity_view_display.user.user.default.yml
new file mode 100644 (file)
index 0000000..2ced21a
--- /dev/null
@@ -0,0 +1,59 @@
+langcode: und
+status: true
+dependencies:
+  config:
+    - field.field.user.user.field_post_address
+    - field.field.user.user.field_post_reference
+    - field.field.user.user.field_tags
+    - field.field.user.user.user_picture
+  module:
+    - entity_reference
+    - image
+    - taxonomy
+    - user
+id: user.user.default
+targetEntityType: user
+bundle: user
+mode: default
+content:
+  user_picture:
+    type: image
+    weight: 0
+    settings:
+      image_style: thumbnail
+      image_link: content
+    third_party_settings: {  }
+    label: hidden
+  member_for:
+    weight: 1
+    settings: {  }
+    third_party_settings: {  }
+  field_post_address:
+    type: behat_test_address_field
+    weight: 0
+    label: above
+    settings: {  }
+    third_party_settings: {  }
+  field_post_reference:
+    type: entity_reference_label
+    weight: 0
+    label: above
+    settings:
+      link: true
+    third_party_settings: {  }
+  field_tags:
+    type: entity_reference_label
+    weight: 2
+    settings:
+      link: true
+    third_party_settings: {  }
+    label: above
+  field_user_reference:
+    type: entity_reference_entity_view
+    weight: 3
+    settings:
+      view_mode: default
+      link: false
+    third_party_settings: {  }
+    label: above
+hidden: {  }
diff --git a/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/override_config/core.entity_view_mode.user.compact.yml b/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/override_config/core.entity_view_mode.user.compact.yml
new file mode 100644 (file)
index 0000000..0b6794d
--- /dev/null
@@ -0,0 +1,9 @@
+langcode: und
+status: true
+dependencies:
+  module:
+    - user
+id: user.compact
+label: Compact
+targetEntityType: user
+cache: true
diff --git a/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/override_config/core.entity_view_mode.user.full.yml b/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/override_config/core.entity_view_mode.user.full.yml
new file mode 100644 (file)
index 0000000..978f610
--- /dev/null
@@ -0,0 +1,9 @@
+langcode: und
+status: false
+dependencies:
+  module:
+    - user
+id: user.full
+label: 'User account'
+targetEntityType: user
+cache: true
diff --git a/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/src/Config/BehatTestExtensionInstallStorage.php b/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/src/Config/BehatTestExtensionInstallStorage.php
new file mode 100644 (file)
index 0000000..e68ce39
--- /dev/null
@@ -0,0 +1,37 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\behat_test\Config\BehatTestExtensionInstallStorage
+ */
+
+namespace Drupal\behat_test\Config;
+
+use Drupal\Core\Config\ExtensionInstallStorage;
+use Drupal\Core\Config\StorageInterface;
+use Drupal\Core\Extension\ExtensionDiscovery;
+
+class BehatTestExtensionInstallStorage extends ExtensionInstallStorage {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function __construct(StorageInterface $config_storage, $directory = self::CONFIG_INSTALL_DIRECTORY, $collection = StorageInterface::DEFAULT_COLLECTION, $include_profile = TRUE) {
+    parent::__construct($config_storage, $directory, $collection, $include_profile);
+
+    $this->directory = 'override_config';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getAllFolders() {
+    if (!isset($this->folders)) {
+      $listing = new ExtensionDiscovery(\Drupal::root());
+      $modules = $listing->scan('module');
+      $this->folders = $this->getComponentNames(array('behat_test' => $modules['behat_test']));
+    }
+    return $this->folders;
+  }
+
+}
diff --git a/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/src/Plugin/Field/FieldFormatter/AddressFieldFormatter.php b/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/src/Plugin/Field/FieldFormatter/AddressFieldFormatter.php
new file mode 100644 (file)
index 0000000..6c8ce43
--- /dev/null
@@ -0,0 +1,106 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\behat_test\Plugin\Field\FieldFormatter\AddressFieldFormatter.
+ */
+
+namespace Drupal\behat_test\Plugin\Field\FieldFormatter;
+
+use Drupal\Core\Field\FieldDefinitionInterface;
+use Drupal\Core\Field\FieldItemListInterface;
+use Drupal\Core\Field\FormatterBase;
+use Drupal\Core\Locale\CountryManagerInterface;
+use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Plugin implementation of the 'behat_test_address_field' formatter.
+ *
+ * @FieldFormatter(
+ *   id = "behat_test_address_field",
+ *   label = @Translation("Address field formatter"),
+ *   module = "behat_test",
+ *   field_types = {
+ *     "behat_test_address_field"
+ *   }
+ * )
+ */
+class AddressFieldFormatter extends FormatterBase implements ContainerFactoryPluginInterface {
+
+  /**
+   * The country manager.
+   *
+   * @var \Drupal\Core\Locale\CountryManagerInterface;
+   */
+  protected $countryManager;
+
+  /**
+   * Constructs an AddressFieldFormatter object.
+   *
+   * @param string $plugin_id
+   *   The plugin_id for the formatter.
+   * @param mixed $plugin_definition
+   *   The plugin implementation definition.
+   * @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition
+   *   The definition of the field to which the formatter is associated.
+   * @param array $settings
+   *   The formatter settings.
+   * @param string $label
+   *   The formatter label display setting.
+   * @param string $view_mode
+   *   The view mode.
+   * @param array $third_party_settings
+   *   Any third party settings.
+   * @param \Drupal\Core\Locale\CountryManagerInterface $country_manager
+   *   The country manager.
+   */
+  public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, CountryManagerInterface $country_manager) {
+    parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode, $third_party_settings);
+
+    $this->countryManager = $country_manager;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+    return new static(
+      $plugin_id,
+      $plugin_definition,
+      $configuration['field_definition'],
+      $configuration['settings'],
+      $configuration['label'],
+      $configuration['view_mode'],
+      $configuration['third_party_settings'],
+      $container->get('country_manager')
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function viewElements(FieldItemListInterface $items, $language) {
+    $elements = [];
+
+    foreach ($items as $delta => $item) {
+      foreach (['country', 'locality', 'thoroughfare', 'postal_code'] as $key) {
+        $value = $item->$key;
+        // Replace the country code with the country name.
+        if ($key === 'country') {
+          $countries = $this->countryManager->getList();
+          $value = !empty($countries[$value]) ? $countries[$value] : '';
+        }
+
+        $elements[$delta][$key] = [
+          '#type' => 'html_tag',
+          '#tag' => 'p',
+          '#value' => $value,
+        ];
+      }
+    }
+
+    return $elements;
+  }
+
+}
diff --git a/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/src/Plugin/Field/FieldType/AddressFieldItem.php b/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/src/Plugin/Field/FieldType/AddressFieldItem.php
new file mode 100644 (file)
index 0000000..541104d
--- /dev/null
@@ -0,0 +1,85 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\behat_test\Plugin\Field\FieldType\AddressFieldItem.
+ */
+
+namespace Drupal\behat_test\Plugin\Field\FieldType;
+
+use Drupal\Core\Field\FieldItemBase;
+use Drupal\Core\Field\FieldStorageDefinitionInterface;
+use Drupal\Core\TypedData\DataDefinition;
+
+/**
+ * Plugin implementation of a simulated 'address_field' field type.
+ *
+ * This is intended as a temporary solution for testing complex fields using
+ * the Behat Extension. Once the AddressField module is ported this will become
+ * obsolete.
+ *
+ * @FieldType(
+ *   id = "behat_test_address_field",
+ *   label = @Translation("Address"),
+ *   module = "behat_test",
+ *   description = @Translation("A simulated address field type, intended for testing the Behat Extension."),
+ *   default_widget = "behat_test_address_field_default",
+ *   default_formatter = "behat_test_address_field"
+ * )
+ */
+class AddressFieldItem extends FieldItemBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
+    return [
+      'country' => DataDefinition::create('string')->setLabel(t('Country')),
+      'locality' => DataDefinition::create('string')->setLabel(t('Locality')),
+      'thoroughfare' => DataDefinition::create('string')->setLabel(t('Thoroughfare')),
+      'postal_code' => DataDefinition::create('string')->setLabel(t('Postal code')),
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function schema(FieldStorageDefinitionInterface $field_definition) {
+    return [
+      'columns' => [
+        'country' => [
+          'description' => 'The ISO country code.',
+          'type' => 'varchar',
+          'length' => 2,
+        ],
+        'locality' => [
+          'description' => 'The locality.',
+          'type' => 'varchar',
+          'length' => 255,
+        ],
+        'thoroughfare' => [
+          'description' => 'The thoroughfare.',
+          'type' => 'varchar',
+          'length' => 255,
+        ],
+        'postal_code' => [
+          'description' => 'The postal code.',
+          'type' => 'varchar',
+          'length' => 255,
+        ],
+      ],
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isEmpty() {
+    $empty = TRUE;
+    foreach (['country', 'locality', 'thoroughfare', 'postal_code'] as $column) {
+      $empty &= $this->get($column)->getValue() === NULL;
+    }
+    return (bool) $empty;
+  }
+
+}
diff --git a/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/src/Plugin/Field/FieldWidget/AddressFieldWidget.php b/vendor/drupal/drupal-extension/fixtures/drupal8/modules/behat_test/src/Plugin/Field/FieldWidget/AddressFieldWidget.php
new file mode 100644 (file)
index 0000000..b780f57
--- /dev/null
@@ -0,0 +1,53 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\behat_test\Plugin\field\widget\AddressFieldWidget.
+ */
+
+namespace Drupal\behat_test\Plugin\Field\FieldWidget;
+
+use Drupal\Core\Field\FieldItemListInterface;
+use Drupal\Core\Field\WidgetBase;
+use Drupal\Core\Form\FormStateInterface;
+
+/**
+ * Plugin implementation of the 'behat_test_address_field' widget.
+ *
+ * @FieldWidget(
+ *   id = "behat_test_address_field_default",
+ *   label = @Translation("Address field"),
+ *   module = "behat_test",
+ *   field_types = {
+ *     "behat_test_address_field"
+ *   }
+ * )
+ */
+class AddressFieldWidget extends WidgetBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
+    // Set up the form element.
+    $element += ['#type' => 'details', '#open' => TRUE];
+
+    // Add in the textfields.
+    $columns = [
+      'country' => t('Country'),
+      'locality' => t('Locality'),
+      'thoroughfare' => t('Thoroughfare'),
+      'postal_code' => t('Postal code'),
+    ];
+    foreach ($columns as $key => $title) {
+      $element[$key] = [
+        '#type' => 'textfield',
+        '#title' => $title,
+        '#default_value' => isset($items[$delta]->$key) ? $items[$delta]->$key : '',
+      ];
+    }
+
+    return $element;
+  }
+
+}
diff --git a/vendor/drupal/drupal-extension/i18n/da.xliff b/vendor/drupal/drupal-extension/i18n/da.xliff
new file mode 100644 (file)
index 0000000..21ba937
--- /dev/null
@@ -0,0 +1,207 @@
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+  <file source-language="en" datatype="plaintext" original="global" target-language="da">
+    <header />
+    <body>
+      <trans-unit id="i-am-at-page">
+       <source><![CDATA[/^(?:that I|I) am at "(?P[^"]*)"$/]]></source>
+       <target><![CDATA[/^(?:at jeg|jeg) er på siden "(?P[^"]*)"$/]]></target>
+      </trans-unit>
+      <trans-unit id="i-visit-page">
+       <source><![CDATA[/^I visit "(?P[^"]*)"$/]]></source>
+       <target><![CDATA[/^jeg besøger "(?P[^"]*)"$/]]></target>
+      </trans-unit>
+      <trans-unit id="i-click-link">
+       <source><![CDATA[/^I click "(?P<link>[^"]*)"$/]]></source>
+       <target><![CDATA[/^jeg klikker på linket "(?P<link>[^"]*)"$/]]></target>
+       </trans-unit>
+       <trans-unit id="for-fields-i-enter-value">
+       <source><![CDATA[/^for "(?P<field>[^"]*)" I enter "(?P<value>[^"]*)"$/]]></source>
+       <target><![CDATA[/^for "(?P<felt>[^"]*)" indtaster jeg værdien "(?P<value>[^"]*)"$/]]></target>
+      </trans-unit>
+      <trans-unit id="i-enter-value-for-fields">
+       <source><![CDATA[/^I enter "(?P<value>[^"]*)" for "(?P<field>[^"]*)"$/]]></source>
+       <target><![CDATA[/^jeg indtaster "(?P<value>[^"]*)" i feltet "(?P<felt>[^"]*)"$/]]></target>
+      </trans-unit>
+      <trans-unit id="i-press-the-button-button">
+       <source><![CDATA[/^I press the "(?P<button>[^"]*)" button$/]]></source>
+       <target><![CDATA[/^jeg trykker på "(?P<knap>[^"]*)" knappen$/]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-see-the-link-link">
+       <source><![CDATA[/^I should see the link "(?P<link>[^"]*)"$/]]></source>
+       <target><![CDATA[/^(?:|bør jeg )se linket "(?P<link>[^"]*)"$/]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-not-see-the-link-link">
+       <source><![CDATA[/^I should not see the link "(?P<link>[^"]*)"$/]]></source>
+       <target><![CDATA[/^(?:|bør jeg )ikke se linket "(?P<link>[^"]*)"$/]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-see-the-heading-heading">
+       <source><![CDATA[/^I (?:|should )see the heading "(?P<heading>[^"]*)"$/]]></source>
+       <target><![CDATA[/^(?:|bør jeg )se overskriften "(?P<overskrift>[^"]*)"$/]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-see-the-heading-heading-in-the-region">
+       <source><![CDATA[/^I should see the heading "(?P<heading>[^"]*)" in the "(?P<region>[^"]*)"(?:| region)$/]]></source>
+       <target><![CDATA[/^(?:|bør jeg )se overskriften "(?P<overskrift>[^"]*)" i (?:|regionen )"(?P<region>[^"]*)"$/]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-see-the-heading-in-the-region">
+       <source><![CDATA[/^I should see the "(?P<heading>[^"]*)" heading in the "(?P<region>[^"]*)"(?:| region)$/]]></source>
+       <target><![CDATA[/^(?:|bør jeg )se "(?P<overskrift>[^"]*)" overskriften i "(?P<region>[^"]*)"(?:| regionen)$/]]></target>
+      </trans-unit>
+      <trans-unit id="i-follow-link-in-the-region-region">
+       <source><![CDATA[/^I (?:follow|click) "(?P<link>[^"]*)" in the "(?P<region>[^"]*)"(?:| region)$/]]></source>
+       <target><![CDATA[/^jeg (?:følger|klikker) "(?P<link>[^"]*)" i "(?P<region>[^"]*)"(?:| regionen)$/]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-see-the-link-in-the-region">
+       <source><![CDATA[/^I should see the link "(?P<link>[^"]*)" in the "(?P<region>[^"]*)"(?:| region)$/]]></source>
+       <target><![CDATA[/^(?:|bør jeg )se linket "(?P<link>[^"]*)" i "(?P<region>[^"]*)"(?:| regionen)$/]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-see-the-text-in-the-region">
+       <source><![CDATA[/^I should see (?:the text |)"(?P<text>[^"]*)" in the "(?P<region>[^"]*)"(?:| region)$/]]></source>
+       <target><![CDATA[/^(?:|bør jeg )se (?:teksten |)"(?P<tekst>[^"]*)" i "(?P<region>[^"]*)"(?:| regionen)$/]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-not-see-the-text-in-the-region">
+       <source><![CDATA[/^I should not see (?:the text |)"(?P<text>[^"]*)" in the "(?P<region>[^"]*)"(?:| region)$/]]></source>
+       <target><![CDATA[/^(?:|bør jeg )ikke se (?:teksten |)"(?P<tekst>[^"]*)" i "(?P<region>[^"]*)"(?:| regionen)$/]]></target>
+      </trans-unit>
+      <trans-unit id="i-press-button-in-the-region">
+       <source><![CDATA[/^I press "(?P<button>[^"]*)" in the "(?P<region>[^"]*)"(?:| region)$/]]></source>
+       <target><![CDATA[/^jeg trykker "(?P<knap>[^"]*)" i "(?P<region>[^"]*)"(?:| regionen)$/]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-see-the-text">
+       <source><![CDATA[/^(?:I|I should) see the text "(?P<text>[^"]*)"$/]]></source>
+       <target><![CDATA[/^(?:|bør jeg )se teksten "(?P<tekst>[^"]*)"$/]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-not-see-the-text">
+       <source><![CDATA[/^I should not see the text "(?P<text>[^"]*)"$/]]></source>
+       <target><![CDATA[/^(?:|bør jeg )ikke se teksten "(?P<tekst>[^"]*)"$/]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-get-a-code-http-response">
+       <source><![CDATA[/^I should get a "(?P<code>[^"]*)" HTTP response$/]]></source>
+       <target><![CDATA[/^(?:|bør jeg )få HTTP responset "(?P<kode>[^"]*)"$/]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-not-get-a-code-http-response">
+       <source><![CDATA[/^I should not get a "(?P<code>[^"]*)" HTTP response$/]]></source>
+       <target><![CDATA[/^(?:|bør jeg )ikke få HTTP responset "(?P<kode>[^"]*)"$/]]></target>
+      </trans-unit>
+      <trans-unit id="i-check-the-box">
+       <source><![CDATA[/^I check the box "(?P<checkbox>[^"]*)"$/]]></source>
+       <target><![CDATA[/^jeg sætter kryds i boksen "(?P<checkbox>[^"]*)"$/]]></target>
+      </trans-unit>
+      <trans-unit id="i-uncheck-the-box">
+       <source><![CDATA[/^I uncheck the box "(?P<checkbox>[^"]*)"$/]]></source>
+       <target><![CDATA[/^jeg fjerner kryds i boksen "(?P<checkbox>[^"]*)"$/]]></target>
+      </trans-unit>
+      <trans-unit id="i-select-the-radio-button-with-the-id">
+       <source><![CDATA[/^I select the radio button "(?P<label>[^"]*)" with the id "(?P<id>[^"]*)"$/]]></source>
+       <target><![CDATA[/^jeg vælger radioknappen "(?P<label>[^"]*)" med id "(?P<id>[^"]*)"$/]]></target>
+      </trans-unit>
+      <trans-unit id="i-select-the-radio-button">
+       <source><![CDATA[/^I select the radio button "(?P<label>[^"]*)"$/]]></source>
+       <target><![CDATA[/^jeg vælger radioknappen "(?P<label>[^"]*)"$/]]></target>
+      </trans-unit>
+      <trans-unit id="i-am-an-anonymous-user">
+       <source><![CDATA[/^I am an anonymous user$/]]></source>
+       <target><![CDATA[/^jeg er en anonym bruger$/]]></target>
+      </trans-unit>
+      <trans-unit id="i-am-not-logged-in">
+       <source><![CDATA[/^I am not logged in$/]]></source>
+       <target><![CDATA[/^jeg ikke er logget ind$/]]></target>
+      </trans-unit>
+      <trans-unit id="i-am-logged-in-as-a-user-with-the-role">
+       <source><![CDATA[/^I am logged in as a user with the "(?P<role>[^"]*)" role$/]]></source>
+       <target><![CDATA[/^jeg er logget ind som bruger med rollen "(?P<rolle>[^"]*)"$/]]></target>
+      </trans-unit>
+      <trans-unit id="i-click-link-in-the-row">
+       <source><![CDATA[/^I click "(?P<link>[^"]*)" in the "(?P<row_text>[^"]*)" row$/]]></source>
+       <target><![CDATA[/^jeg klikker "(?P<link>[^"]*)" i rækken "(?P<row_text>[^"]*)"$/]]></target>
+      </trans-unit>
+      <trans-unit id="the-cache-has-been-cleared">
+       <source><![CDATA[/^the cache has been cleared$/]]></source>
+       <target><![CDATA[/^cachen er clearet$/]]></target>
+      </trans-unit>
+      <trans-unit id="i-run-cron">
+       <source><![CDATA[/^I run cron$/]]></source>
+       <target><![CDATA[/^jeg kører cron$/]]></target>
+      </trans-unit>
+      <trans-unit id="i-am-viewing-a-type-node-with-the-title">
+       <source><![CDATA[/^I am viewing (?:a|an) "(?P<type>[^"]*)" node with the title "(?P<title>[^"]*)"$/]]></source>
+       <target><![CDATA[/^jeg ser en "(?P<type>[^"]*)" node med titlen "(?P<titel>[^"]*)"$/]]></target>
+      </trans-unit>
+      <trans-unit id="a-type-node-with-the-title">
+       <source><![CDATA[/^(?:a|an) "(?P<type>[^"]*)" node with the title "(?P<title>[^"]*)"$/]]></source>
+       <target><![CDATA[/^en "(?P<type>[^"]*)" node med titlen "(?P<title>[^"]*)"$/]]></target>
+      </trans-unit>
+      <trans-unit id="type-nodes">
+       <source><![CDATA[/^"(?P<type>[^"]*)" nodes:$/]]></source>
+       <target><![CDATA[/^"(?P<type>[^"]*)" noder:$/]]></target>
+      </trans-unit>
+      <trans-unit id="i-am-viewing-a-vocabulary-term-with-the-name">
+       <source><![CDATA[/^I am viewing (?:a|an) "(?P<vocabulary>[^"]*)" term with the name "(?P<name>[^"]*)"$/]]></source>
+       <target><![CDATA[/^jeg ser et "(?P<vocabulary>[^"]*)" term med navnet "(?P<navn>[^"]*)"$/]]></target>
+      </trans-unit>
+      <trans-unit id="a-vocabulary-term-with-the-name">
+       <source><![CDATA[/^(?:a|an) "(?P<vocabulary>[^"]*)" term with the name "(?P<name>[^"]*)"$/]]></source>
+       <target><![CDATA[/^et "(?P<vocabulary>[^"]*)" term med navnet "(?P<navn>[^"]*)"$/]]></target>
+      </trans-unit>
+      <trans-unit id="vocabulary-terms">
+       <source><![CDATA[/^"(?P<vocabulary>[^"]*)" terms:$/]]></source>
+       <target><![CDATA[/^"(?P<vocabulary>[^"]*)" termer:$/]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-see-the-error-message">
+       <source><![CDATA[/^I should see the error message(?:| containing) "([^"]*)"$/]]></source>
+       <target><![CDATA[/^(?:|bør jeg )se fejlbeskeden(?:| indeholdende) "([^"]*)"$/]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-see-the-following-error-messages">
+       <source><![CDATA[/^I should see the following <error messages>$/]]></source>
+       <target><![CDATA[/^(?:|bør jeg )se følgende <error messages>$/]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-not-see-the-error-message">
+       <source><![CDATA[/^I should not see the error message(?:| containing) "([^"]*)"$/]]></source>
+       <target><![CDATA[/^(?:|bør jeg )ikke se fejlbeskeden(?:| indeholdende) "([^"]*)"$/]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-not-see-the-following-error">
+       <source><![CDATA[/^I should not see the following <error messages>$/]]></source>
+       <target><![CDATA[/^(?:|bør jeg )ikke se følgende <error messages>$/]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-see-the-success-message">
+       <source><![CDATA[/^I should see the success message(?:| containing) "([^"]*)"$/]]></source>
+       <target><![CDATA[/^(?:|bør jeg )se succes beskeden(?:| indeholdende) "([^"]*)"$/]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-see-the-following-success">
+       <source><![CDATA[/^I should see the following <success messages>$/]]></source>
+       <target><![CDATA[/^(?:|bør jeg )se følgende <success messages>$/]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-not-see-the-success-message">
+       <source><![CDATA[/^I should not see the success message(?:| containing) "([^"]*)"$/]]></source>
+       <target><![CDATA[/^(?:|bør jeg )ikke se succes beskederne(?:| indeholdende) "([^"]*)"$/]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-not-see-the-following-success-messages">
+       <source><![CDATA[/^I should not see the following <success messages>$/]]></source>
+       <target><![CDATA[/^(?:|bør jeg )ikke se følgende <success messages>$/]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-see-the-warning-message">
+       <source><![CDATA[/^I should see the warning message(?:| containing) "([^"]*)"$/]]></source>
+       <target><![CDATA[/^(?:|bør jeg )se advarslen(?:| indeholdende) "([^"]*)"$/]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-see-the-following-warning">
+       <source><![CDATA[/^I should see the following <warning messages>$/]]></source>
+       <target><![CDATA[/^(?:|bør jeg )se følgende <warning messages>$/]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-not-see-the-warning-message">
+       <source><![CDATA[/^I should not see the warning message(?:| containing) "([^"]*)"$/]]></source>
+       <target><![CDATA[/^(?:|bør jeg )ikke se advarslen(?:| indeholdende) "([^"]*)"$/]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-not-see-the-following-warning-messages">
+       <source><![CDATA[/^I should not see the following <warning messages>$/]]></source>
+       <target><![CDATA[/^(?:|bør jeg )ikke se følgende <warning messages>$/]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-see-the-message">
+       <source><![CDATA[/^I should see the message(?:| containing) "([^"]*)"$/]]></source>
+       <target><![CDATA[/^(?:|bør jeg )se beskeden(?:| indeholdende) "([^"]*)"$/]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-not-see-the-message">
+       <source><![CDATA[/^I should not see the message(?:| containing) "([^"]*)"$/]]></source>
+       <target><![CDATA[/^(?:|bør jeg )ikke se beskeden(?:| indeholdende) "([^"]*)"$/]]></target>
+      </trans-unit>
+    </body>
+  </file>
+</xliff>
diff --git a/vendor/drupal/drupal-extension/i18n/es.xliff b/vendor/drupal/drupal-extension/i18n/es.xliff
new file mode 100644 (file)
index 0000000..c37226c
--- /dev/null
@@ -0,0 +1,286 @@
+<?xml version="1.0"?><xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+  <file source-language="en" datatype="plaintext" original="global" target-language="es">
+    <body>
+      <trans-unit id="i-am-an-anonymous-user">
+        <source><![CDATA[I am an anonymous user]]></source>
+        <target><![CDATA[(que )soy un usuario anónimo]]></target>
+      </trans-unit>
+      <trans-unit id="i-am-not-logged-in">
+        <source><![CDATA[I am not logged in]]></source>
+        <target><![CDATA[(que )no estoy conectado]]></target>
+      </trans-unit>
+      <trans-unit id="i-am-logged-in-as-a-user-with-the-role-roles">
+        <source><![CDATA[I am logged in as a user with the :role role(s)]]></source>
+        <target><![CDATA[(que )estoy conectado como usuario con rol(es) :role]]></target>
+      </trans-unit>
+      <trans-unit id="i-am-logged-in-as-name">
+        <source><![CDATA[I am logged in as :name]]></source>
+        <target><![CDATA[(que )estoy conectado como :name]]></target>
+      </trans-unit>
+      <trans-unit id="i-am-logged-in-as-a-user-with-the-permissions-permissions">
+        <source><![CDATA[I am logged in as a user with the :permissions permission(s)]]></source>
+        <target><![CDATA[(que )estoy conectado com un usuario con permiso(s) :permissions]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-see-the-text-text-in-the-rowtext-row">
+        <source><![CDATA[I should see (the text ):text in the ":rowText" row]]></source>
+        <target><![CDATA[debo ver (el texto ):text en la fila ":rowText"]]></target>
+      </trans-unit>
+      <trans-unit id="i-click-link-in-the-rowtext-row">
+        <source><![CDATA[I click :link in the :rowText row]]></source>
+        <target><![CDATA[hago click en el enlace :link de la fila :rowText]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-see-the-link-in-the-rowtext-row">
+        <source><![CDATA[I (should )see the :link in the :rowText row]]></source>
+        <target><![CDATA[debo ver el enlace :link de la fila :rowText]]></target>
+      </trans-unit>
+      <trans-unit id="the-cache-has-been-cleared">
+        <source><![CDATA[the cache has been cleared]]></source>
+        <target><![CDATA[la cache ha sido limpiada]]></target>
+      </trans-unit>
+      <trans-unit id="i-run-cron">
+        <source><![CDATA[I run cron]]></source>
+        <target><![CDATA[lanzo el cron]]></target>
+      </trans-unit>
+      <trans-unit id="i-am-viewing-a-an-type-content-with-the-title-title">
+        <source><![CDATA[I am viewing a/an :type (content )with the title :title]]></source>
+        <target><![CDATA[(que )estoy viendo un contenido de tipo :type con el título :title]]></target>
+      </trans-unit>
+      <trans-unit id="a-an-type-content-with-the-title-title">
+        <source><![CDATA[a/an :type (content )with the title :title]]></source>
+        <target><![CDATA[un contenido de tipo :type con el título :title]]></target>
+      </trans-unit>
+      <trans-unit id="i-am-viewing-my-type-content-with-the-title-title">
+        <source><![CDATA[I am viewing my :type (content )with the title :title]]></source>
+        <target><![CDATA[(que )estoy viendo mi contenido de tipo :type con el título :title]]></target>
+      </trans-unit>
+      <trans-unit id="type-content">
+        <source><![CDATA[:type content:]]></source>
+        <target><![CDATA[:type con contenido:]]></target>
+      </trans-unit>
+      <trans-unit id="i-am-viewing-a-an-type-content">
+        <source><![CDATA[I am viewing a/an :type( content):]]></source>
+        <target><![CDATA[(que )veo un(a) :type( con contenido):]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-be-able-to-edit-a-an-type-content">
+        <source><![CDATA[I should be able to edit a/an :type( content)]]></source>
+        <target><![CDATA[debo poder editar un contenido de tipo :type]]></target>
+      </trans-unit>
+      <trans-unit id="i-am-viewing-a-an-vocabulary-term-with-the-name-name">
+        <source><![CDATA[I am viewing a/an :vocabulary term with the name :name]]></source>
+        <target><![CDATA[(que )estoy viendo un término de :vocabulary con el nombre :name]]></target>
+      </trans-unit>
+      <trans-unit id="a-an-vocabulary-term-with-the-name-name">
+        <source><![CDATA[a/an :vocabulary term with the name :name]]></source>
+        <target><![CDATA[un término de :vocabulary con el nombre :name]]></target>
+      </trans-unit>
+      <trans-unit id="users">
+        <source><![CDATA[users:]]></source>
+        <target><![CDATA[users:]]></target>
+      </trans-unit>
+      <trans-unit id="vocabulary-terms">
+        <source><![CDATA[:vocabulary terms:]]></source>
+        <target><![CDATA[:vocabulary términos:]]></target>
+      </trans-unit>
+      <trans-unit id="i-break">
+        <source><![CDATA[(I )break]]></source>
+        <target><![CDATA[break]]></target>
+      </trans-unit>
+      <trans-unit id="i-run-drush-command">
+        <source><![CDATA[I run drush :command]]></source>
+        <target><![CDATA[ejecuto el comando drush :command]]></target>
+      </trans-unit>
+      <trans-unit id="i-run-drush-command-arguments">
+        <source><![CDATA[I run drush :command :arguments]]></source>
+        <target><![CDATA[ejecuto el comando drush :command :arguments]]></target>
+      </trans-unit>
+      <trans-unit id="drush-output-should-contain-output">
+        <source><![CDATA[drush output should contain :output]]></source>
+        <target><![CDATA[la salidad de drush debe contener :output]]></target>
+      </trans-unit>
+      <trans-unit id="drush-output-should-not-contain-output">
+        <source><![CDATA[drush output should not contain :output]]></source>
+        <target><![CDATA[la salidad de drush no debe contener :output]]></target>
+      </trans-unit>
+      <trans-unit id="print-last-drush-output">
+        <source><![CDATA[print last drush output]]></source>
+        <target><![CDATA[imprime la última salida de drush]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-see-the-error-message-containing-message">
+        <source><![CDATA[I should see the error message( containing) :message]]></source>
+        <target><![CDATA[debo ver un mensaje de error( conteniendo) :message]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-see-the-following-error-messages">
+        <source><![CDATA[I should see the following error message(s):]]></source>
+        <target><![CDATA[debo ver los siguientes mensajes de error:]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-not-see-the-error-message-containing-message">
+        <source><![CDATA[I should not see the error message( containing) :message]]></source>
+        <target><![CDATA[no debo ver un mensaje de error( conteniendo) :message]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-not-see-the-following-error-messages">
+        <source><![CDATA[I should not see the following error messages:]]></source>
+        <target><![CDATA[no debo ver los siguientes mensajes de error:]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-see-the-success-message-containing-message">
+        <source><![CDATA[I should see the success message( containing) :message]]></source>
+        <target><![CDATA[debo ver el mensaje de confirmación( conteniendo) :message]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-see-the-following-success-messages">
+        <source><![CDATA[I should see the following success messages:]]></source>
+        <target><![CDATA[debo ver los mensajes de siguientes mensajes de confirmación:]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-not-see-the-success-message-containing-message">
+        <source><![CDATA[I should not see the success message( containing) :message]]></source>
+        <target><![CDATA[no debo ver el mensaje de confirmación( conteniendo) :message]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-not-see-the-following-success-messages">
+        <source><![CDATA[I should not see the following success messages:]]></source>
+        <target><![CDATA[no debo ver los mensajes de siguientes mensajes de confirmación:]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-see-the-warning-message-containing-message">
+        <source><![CDATA[I should see the warning message( containing) :message]]></source>
+        <target><![CDATA[debo ver el mensaje de aviso( conteniendo) :message]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-see-the-following-warning-messages">
+        <source><![CDATA[I should see the following warning messages:]]></source>
+        <target><![CDATA[debo ver los mensajes de siguientes mensajes de aviso:]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-not-see-the-warning-message-containing-message">
+        <source><![CDATA[I should not see the warning message( containing) :message]]></source>
+        <target><![CDATA[no debo ver el mensaje de aviso( conteniendo) :message]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-not-see-the-following-warning-messages">
+        <source><![CDATA[I should not see the following warning messages:]]></source>
+        <target><![CDATA[no debo ver los mensajes de siguientes mensajes de confirmación:]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-see-the-message-containing-message">
+        <source><![CDATA[I should see the message( containing) :message]]></source>
+        <target><![CDATA[debo ver el mensaje( conteniendo) :message]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-not-see-the-message-containing-message">
+        <source><![CDATA[I should not see the message( containing) :message]]></source>
+        <target><![CDATA[no debo ver el mensaje( conteniendo) :message]]></target>
+      </trans-unit>
+      <trans-unit id="i-am-at-path">
+        <source><![CDATA[I am at :path]]></source>
+        <target><![CDATA[(que )estoy en :path]]></target>
+      </trans-unit>
+      <trans-unit id="i-visit-path">
+        <source><![CDATA[I visit :path]]></source>
+        <target><![CDATA[visito :path]]></target>
+      </trans-unit>
+      <trans-unit id="i-click-link">
+        <source><![CDATA[I click :link]]></source>
+        <target><![CDATA[hago click en :link]]></target>
+      </trans-unit>
+      <trans-unit id="for-field-i-enter-value">
+        <source><![CDATA[for :field I enter :value]]></source>
+        <target><![CDATA[para el campo :field introduzco( el valor) :value]]></target>
+      </trans-unit>
+      <trans-unit id="i-enter-value-for-field">
+        <source><![CDATA[I enter :value for :field]]></source>
+        <target><![CDATA[introduzco( el valor) :value para el campo :field]]></target>
+      </trans-unit>
+      <trans-unit id="i-wait-for-ajax-to-finish">
+        <source><![CDATA[I wait for AJAX to finish]]></source>
+        <target><![CDATA[espero a que AJAX termine]]></target>
+      </trans-unit>
+      <trans-unit id="i-press-the-button-button">
+        <source><![CDATA[I press the :button button]]></source>
+        <target><![CDATA[pulso el botón :button]]></target>
+      </trans-unit>
+      <trans-unit id="i-press-the-char-key-in-the-field-field">
+        <source><![CDATA[I press the :char key in the :field field]]></source>
+        <target><![CDATA[pulso la tecla :char en el campo :field]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-see-the-link-link">
+        <source><![CDATA[I should see the link :link]]></source>
+        <target><![CDATA[debo ver el enlace :link]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-not-see-the-link-link">
+        <source><![CDATA[I should not see the link :link]]></source>
+        <target><![CDATA[no debo ver el enlace :link]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-see-the-heading-heading">
+        <source><![CDATA[I (should )see the heading :heading]]></source>
+        <target><![CDATA[debo ver el encabezado :heading]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-not-see-the-heading-heading">
+        <source><![CDATA[I (should )not see the heading :heading]]></source>
+        <target><![CDATA[no debo ver el encabezado :heading]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-see-the-heading-heading-in-the-region-region">
+        <source><![CDATA[I should see the heading :heading in the :region( region)]]></source>
+        <target><![CDATA[debo ver el encabezado :heading en( la zona) :region]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-see-the-heading-heading-in-the-region-region-1">
+        <source><![CDATA[I should see the :heading heading in the :region( region)]]></source>
+        <target><![CDATA[debo ver :heading como encabezado en( la zona) :region]]></target>
+      </trans-unit>
+      <trans-unit id="i-follow-click-link-in-the-region-region">
+        <source><![CDATA[I follow/click :link in the :region( region)]]></source>
+        <target><![CDATA[hago click en :link de( la zona) :region]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-see-the-link-link-in-the-region-region">
+        <source><![CDATA[I should see the link :link in the :region( region)]]></source>
+        <target><![CDATA[debo ver el enlace :link en( la zona) :region]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-not-see-the-link-link-in-the-region-region">
+        <source><![CDATA[I should not see the link :link in the :region( region)]]></source>
+        <target><![CDATA[no debo ver el enlace :link en( la zona) :region]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-see-the-text-text-in-the-region-region">
+        <source><![CDATA[I should see( the text) :text in the :region( region)]]></source>
+        <target><![CDATA[debo ver( el texto) :text en( la zona) :region]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-not-see-the-text-text-in-the-region-region">
+        <source><![CDATA[I should not see( the text) :text in the :region( region)]]></source>
+        <target><![CDATA[no debo ver( el texto) :text en( la zona) :region]]></target>
+      </trans-unit>
+      <trans-unit id="i-press-button-in-the-region-region">
+        <source><![CDATA[I press :button in the :region( region)]]></source>
+        <target><![CDATA[pulso( el botón) :button en( la zona) :region]]></target>
+      </trans-unit>
+      <trans-unit id="i-fill-in-value-for-field-in-the-region-region">
+        <source><![CDATA[I fill in :value for :field in the :region( region)]]></source>
+        <target><![CDATA[relleno con :value el campo :field en( la zona) :region]]></target>
+      </trans-unit>
+      <trans-unit id="i-fill-in-field-with-value-in-the-region-region">
+        <source><![CDATA[I fill in :field with :value in the :region( region)]]></source>
+        <target><![CDATA[relleno el campo :field con :value en( la zona) :region]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-see-the-text-text">
+        <source><![CDATA[I (should )see the text :text]]></source>
+        <target><![CDATA[debo ver el texto :text]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-not-see-the-text-text">
+        <source><![CDATA[I should not see the text :text]]></source>
+        <target><![CDATA[no debo ver el texto :text]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-get-a-code-http-response">
+        <source><![CDATA[I should get a :code HTTP response]]></source>
+        <target><![CDATA[debo obtener una respuesta HTTP( con) código :code]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-not-get-a-code-http-response">
+        <source><![CDATA[I should not get a :code HTTP response]]></source>
+        <target><![CDATA[no debo obtener una respuesta HTTP( con) código :code]]></target>
+      </trans-unit>
+      <trans-unit id="i-check-the-box-checkbox">
+        <source><![CDATA[I check the box :checkbox]]></source>
+        <target><![CDATA[marco la opción :checkbox]]></target>
+      </trans-unit>
+      <trans-unit id="i-uncheck-the-box-checkbox">
+        <source><![CDATA[I uncheck the box :checkbox]]></source>
+        <target><![CDATA[desmarco la opción :checkbox]]></target>
+      </trans-unit>
+      <trans-unit id="i-select-the-radio-button-label-with-the-id-id">
+        <source><![CDATA[I select the radio button :label with the id :id]]></source>
+        <target><![CDATA[selecciono el botón de radio :label con el id :id]]></target>
+      </trans-unit>
+      <trans-unit id="i-select-the-radio-button-label">
+        <source><![CDATA[I select the radio button :label]]></source>
+        <target><![CDATA[selecciono el botón de radio :label]]></target>
+      </trans-unit>
+    </body>
+  </file>
+</xliff>
diff --git a/vendor/drupal/drupal-extension/i18n/fr.xliff b/vendor/drupal/drupal-extension/i18n/fr.xliff
new file mode 100644 (file)
index 0000000..f73ff57
--- /dev/null
@@ -0,0 +1,286 @@
+<?xml version="1.0"?><xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+  <file source-language="en" datatype="plaintext" original="global" target-language="fr">
+    <body>
+      <trans-unit id="i-am-an-anonymous-user">
+        <source><![CDATA[I am an anonymous user]]></source>
+        <target><![CDATA[I am an anonymous user]]></target>
+      </trans-unit>
+      <trans-unit id="i-am-not-logged-in">
+        <source><![CDATA[I am not logged in]]></source>
+        <target><![CDATA[I am not logged in]]></target>
+      </trans-unit>
+      <trans-unit id="i-am-logged-in-as-a-user-with-the-role-roles">
+        <source><![CDATA[I am logged in as a user with the :role role(s)]]></source>
+        <target><![CDATA[I am logged in as a user with the :role role(s)]]></target>
+      </trans-unit>
+      <trans-unit id="i-am-logged-in-as-name">
+        <source><![CDATA[I am logged in as :name]]></source>
+        <target><![CDATA[I am logged in as :name]]></target>
+      </trans-unit>
+      <trans-unit id="i-am-logged-in-as-a-user-with-the-permissions-permissions">
+        <source><![CDATA[I am logged in as a user with the :permissions permission(s)]]></source>
+        <target><![CDATA[I am logged in as a user with the :permissions permission(s)]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-see-the-text-text-in-the-rowtext-row">
+        <source><![CDATA[I should see (the text ):text in the ":rowText" row]]></source>
+        <target><![CDATA[I should see (the text ):text in the ":rowText" row]]></target>
+      </trans-unit>
+      <trans-unit id="i-click-link-in-the-rowtext-row">
+        <source><![CDATA[I click :link in the :rowText row]]></source>
+        <target><![CDATA[I click :link in the :rowText row]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-see-the-link-in-the-rowtext-row">
+        <source><![CDATA[I (should )see the :link in the :rowText row]]></source>
+        <target><![CDATA[I (should )see the :link in the :rowText row]]></target>
+      </trans-unit>
+      <trans-unit id="the-cache-has-been-cleared">
+        <source><![CDATA[the cache has been cleared]]></source>
+        <target><![CDATA[the cache has been cleared]]></target>
+      </trans-unit>
+      <trans-unit id="i-run-cron">
+        <source><![CDATA[I run cron]]></source>
+        <target><![CDATA[I run cron]]></target>
+      </trans-unit>
+      <trans-unit id="i-am-viewing-a-an-type-content-with-the-title-title">
+        <source><![CDATA[I am viewing a/an :type (content )with the title :title]]></source>
+        <target><![CDATA[I am viewing a/an :type (content )with the title :title]]></target>
+      </trans-unit>
+      <trans-unit id="a-an-type-content-with-the-title-title">
+        <source><![CDATA[a/an :type (content )with the title :title]]></source>
+        <target><![CDATA[a/an :type (content )with the title :title]]></target>
+      </trans-unit>
+      <trans-unit id="i-am-viewing-my-type-content-with-the-title-title">
+        <source><![CDATA[I am viewing my :type (content )with the title :title]]></source>
+        <target><![CDATA[I am viewing my :type (content )with the title :title]]></target>
+      </trans-unit>
+      <trans-unit id="type-content">
+        <source><![CDATA[:type content:]]></source>
+        <target><![CDATA[:type content:]]></target>
+      </trans-unit>
+      <trans-unit id="i-am-viewing-a-an-type-content">
+        <source><![CDATA[I am viewing a/an :type( content):]]></source>
+        <target><![CDATA[I am viewing a/an :type( content):]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-be-able-to-edit-a-an-type-content">
+        <source><![CDATA[I should be able to edit a/an :type( content)]]></source>
+        <target><![CDATA[I should be able to edit a/an :type( content)]]></target>
+      </trans-unit>
+      <trans-unit id="i-am-viewing-a-an-vocabulary-term-with-the-name-name">
+        <source><![CDATA[I am viewing a/an :vocabulary term with the name :name]]></source>
+        <target><![CDATA[I am viewing a/an :vocabulary term with the name :name]]></target>
+      </trans-unit>
+      <trans-unit id="a-an-vocabulary-term-with-the-name-name">
+        <source><![CDATA[a/an :vocabulary term with the name :name]]></source>
+        <target><![CDATA[a/an :vocabulary term with the name :name]]></target>
+      </trans-unit>
+      <trans-unit id="users">
+        <source><![CDATA[users:]]></source>
+        <target><![CDATA[users:]]></target>
+      </trans-unit>
+      <trans-unit id="vocabulary-terms">
+        <source><![CDATA[:vocabulary terms:]]></source>
+        <target><![CDATA[:vocabulary terms:]]></target>
+      </trans-unit>
+      <trans-unit id="i-break">
+        <source><![CDATA[(I )break]]></source>
+        <target><![CDATA[(I )break]]></target>
+      </trans-unit>
+      <trans-unit id="i-run-drush-command">
+        <source><![CDATA[I run drush :command]]></source>
+        <target><![CDATA[I run drush :command]]></target>
+      </trans-unit>
+      <trans-unit id="i-run-drush-command-arguments">
+        <source><![CDATA[I run drush :command :arguments]]></source>
+        <target><![CDATA[I run drush :command :arguments]]></target>
+      </trans-unit>
+      <trans-unit id="drush-output-should-contain-output">
+        <source><![CDATA[drush output should contain :output]]></source>
+        <target><![CDATA[drush output should contain :output]]></target>
+      </trans-unit>
+      <trans-unit id="drush-output-should-not-contain-output">
+        <source><![CDATA[drush output should not contain :output]]></source>
+        <target><![CDATA[drush output should not contain :output]]></target>
+      </trans-unit>
+      <trans-unit id="print-last-drush-output">
+        <source><![CDATA[print last drush output]]></source>
+        <target><![CDATA[print last drush output]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-see-the-error-message-containing-message">
+        <source><![CDATA[I should see the error message( containing) :message]]></source>
+        <target><![CDATA[I should see the error message( containing) :message]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-see-the-following-error-messages">
+        <source><![CDATA[I should see the following error message(s):]]></source>
+        <target><![CDATA[I should see the following error message(s):]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-not-see-the-error-message-containing-message">
+        <source><![CDATA[I should not see the error message( containing) :message]]></source>
+        <target><![CDATA[I should not see the error message( containing) :message]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-not-see-the-following-error-messages">
+        <source><![CDATA[I should not see the following error messages:]]></source>
+        <target><![CDATA[I should not see the following error messages:]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-see-the-success-message-containing-message">
+        <source><![CDATA[I should see the success message( containing) :message]]></source>
+        <target><![CDATA[I should see the success message( containing) :message]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-see-the-following-success-messages">
+        <source><![CDATA[I should see the following success messages:]]></source>
+        <target><![CDATA[I should see the following success messages:]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-not-see-the-success-message-containing-message">
+        <source><![CDATA[I should not see the success message( containing) :message]]></source>
+        <target><![CDATA[I should not see the success message( containing) :message]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-not-see-the-following-success-messages">
+        <source><![CDATA[I should not see the following success messages:]]></source>
+        <target><![CDATA[I should not see the following success messages:]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-see-the-warning-message-containing-message">
+        <source><![CDATA[I should see the warning message( containing) :message]]></source>
+        <target><![CDATA[I should see the warning message( containing) :message]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-see-the-following-warning-messages">
+        <source><![CDATA[I should see the following warning messages:]]></source>
+        <target><![CDATA[I should see the following warning messages:]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-not-see-the-warning-message-containing-message">
+        <source><![CDATA[I should not see the warning message( containing) :message]]></source>
+        <target><![CDATA[I should not see the warning message( containing) :message]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-not-see-the-following-warning-messages">
+        <source><![CDATA[I should not see the following warning messages:]]></source>
+        <target><![CDATA[I should not see the following warning messages:]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-see-the-message-containing-message">
+        <source><![CDATA[I should see the message( containing) :message]]></source>
+        <target><![CDATA[I should see the message( containing) :message]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-not-see-the-message-containing-message">
+        <source><![CDATA[I should not see the message( containing) :message]]></source>
+        <target><![CDATA[I should not see the message( containing) :message]]></target>
+      </trans-unit>
+      <trans-unit id="i-am-at-path">
+        <source><![CDATA[I am at :path]]></source>
+        <target><![CDATA[I am at :path]]></target>
+      </trans-unit>
+      <trans-unit id="i-visit-path">
+        <source><![CDATA[I visit :path]]></source>
+        <target><![CDATA[I visit :path]]></target>
+      </trans-unit>
+      <trans-unit id="i-click-link">
+        <source><![CDATA[I click :link]]></source>
+        <target><![CDATA[I click :link]]></target>
+      </trans-unit>
+      <trans-unit id="for-field-i-enter-value">
+        <source><![CDATA[for :field I enter :value]]></source>
+        <target><![CDATA[for :field I enter :value]]></target>
+      </trans-unit>
+      <trans-unit id="i-enter-value-for-field">
+        <source><![CDATA[I enter :value for :field]]></source>
+        <target><![CDATA[I enter :value for :field]]></target>
+      </trans-unit>
+      <trans-unit id="i-wait-for-ajax-to-finish">
+        <source><![CDATA[I wait for AJAX to finish]]></source>
+        <target><![CDATA[I wait for AJAX to finish]]></target>
+      </trans-unit>
+      <trans-unit id="i-press-the-button-button">
+        <source><![CDATA[I press the :button button]]></source>
+        <target><![CDATA[I press the :button button]]></target>
+      </trans-unit>
+      <trans-unit id="i-press-the-char-key-in-the-field-field">
+        <source><![CDATA[I press the :char key in the :field field]]></source>
+        <target><![CDATA[I press the :char key in the :field field]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-see-the-link-link">
+        <source><![CDATA[I should see the link :link]]></source>
+        <target><![CDATA[I should see the link :link]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-not-see-the-link-link">
+        <source><![CDATA[I should not see the link :link]]></source>
+        <target><![CDATA[I should not see the link :link]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-see-the-heading-heading">
+        <source><![CDATA[I (should )see the heading :heading]]></source>
+        <target><![CDATA[I (should )see the heading :heading]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-not-see-the-heading-heading">
+        <source><![CDATA[I (should )not see the heading :heading]]></source>
+        <target><![CDATA[I (should )not see the heading :heading]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-see-the-heading-heading-in-the-region-region">
+        <source><![CDATA[I should see the heading :heading in the :region( region)]]></source>
+        <target><![CDATA[I should see the heading :heading in the :region( region)]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-see-the-heading-heading-in-the-region-region-1">
+        <source><![CDATA[I should see the :heading heading in the :region( region)]]></source>
+        <target><![CDATA[I should see the :heading heading in the :region( region)]]></target>
+      </trans-unit>
+      <trans-unit id="i-follow-click-link-in-the-region-region">
+        <source><![CDATA[I follow/click :link in the :region( region)]]></source>
+        <target><![CDATA[I follow/click :link in the :region( region)]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-see-the-link-link-in-the-region-region">
+        <source><![CDATA[I should see the link :link in the :region( region)]]></source>
+        <target><![CDATA[I should see the link :link in the :region( region)]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-not-see-the-link-link-in-the-region-region">
+        <source><![CDATA[I should not see the link :link in the :region( region)]]></source>
+        <target><![CDATA[I should not see the link :link in the :region( region)]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-see-the-text-text-in-the-region-region">
+        <source><![CDATA[I should see( the text) :text in the :region( region)]]></source>
+        <target><![CDATA[I should see( the text) :text in the :region( region)]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-not-see-the-text-text-in-the-region-region">
+        <source><![CDATA[I should not see( the text) :text in the :region( region)]]></source>
+        <target><![CDATA[I should not see( the text) :text in the :region( region)]]></target>
+      </trans-unit>
+      <trans-unit id="i-press-button-in-the-region-region">
+        <source><![CDATA[I press :button in the :region( region)]]></source>
+        <target><![CDATA[I press :button in the :region( region)]]></target>
+      </trans-unit>
+      <trans-unit id="i-fill-in-value-for-field-in-the-region-region">
+        <source><![CDATA[I fill in :value for :field in the :region( region)]]></source>
+        <target><![CDATA[I fill in :value for :field in the :region( region)]]></target>
+      </trans-unit>
+      <trans-unit id="i-fill-in-field-with-value-in-the-region-region">
+        <source><![CDATA[I fill in :field with :value in the :region( region)]]></source>
+        <target><![CDATA[I fill in :field with :value in the :region( region)]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-see-the-text-text">
+        <source><![CDATA[I (should )see the text :text]]></source>
+        <target><![CDATA[I (should )see the text :text]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-not-see-the-text-text">
+        <source><![CDATA[I should not see the text :text]]></source>
+        <target><![CDATA[I should not see the text :text]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-get-a-code-http-response">
+        <source><![CDATA[I should get a :code HTTP response]]></source>
+        <target><![CDATA[I should get a :code HTTP response]]></target>
+      </trans-unit>
+      <trans-unit id="i-should-not-get-a-code-http-response">
+        <source><![CDATA[I should not get a :code HTTP response]]></source>
+        <target><![CDATA[I should not get a :code HTTP response]]></target>
+      </trans-unit>
+      <trans-unit id="i-check-the-box-checkbox">
+        <source><![CDATA[I check the box :checkbox]]></source>
+        <target><![CDATA[I check the box :checkbox]]></target>
+      </trans-unit>
+      <trans-unit id="i-uncheck-the-box-checkbox">
+        <source><![CDATA[I uncheck the box :checkbox]]></source>
+        <target><![CDATA[I uncheck the box :checkbox]]></target>
+      </trans-unit>
+      <trans-unit id="i-select-the-radio-button-label-with-the-id-id">
+        <source><![CDATA[I select the radio button :label with the id :id]]></source>
+        <target><![CDATA[I select the radio button :label with the id :id]]></target>
+      </trans-unit>
+      <trans-unit id="i-select-the-radio-button-label">
+        <source><![CDATA[I select the radio button :label]]></source>
+        <target><![CDATA[I select the radio button :label]]></target>
+      </trans-unit>
+    </body>
+  </file>
+</xliff>
diff --git a/vendor/drupal/drupal-extension/package.json b/vendor/drupal/drupal-extension/package.json
new file mode 100644 (file)
index 0000000..20df640
--- /dev/null
@@ -0,0 +1,5 @@
+{
+  "devDependencies": {
+    "zombie": "^2.5"
+  }
+}
diff --git a/vendor/drupal/drupal-extension/spec/Drupal/DrupalDriverManagerSpec.php b/vendor/drupal/drupal-extension/spec/Drupal/DrupalDriverManagerSpec.php
new file mode 100644 (file)
index 0000000..408e064
--- /dev/null
@@ -0,0 +1,36 @@
+<?php
+
+namespace spec\Drupal;
+
+use Behat\Testwork\Environment\Environment;
+
+use Drupal\Driver\DriverInterface;
+
+use PhpSpec\ObjectBehavior;
+use Prophecy\Argument;
+
+class DrupalDriverManagerSpec extends ObjectBehavior
+{
+    function it_is_initializable()
+    {
+        $this->shouldHaveType('Drupal\DrupalDriverManager');
+    }
+
+    function it_registers_drivers(DriverInterface $driver)
+    {
+        $this->registerDriver('name', $driver);
+        $this->setDefaultDriverName('name');
+
+        $driver = $this->getDriver();
+        $driver->shouldBeAnInstanceOf('Drupal\Driver\DriverInterface');
+    }
+
+    function it_sets_behat_environments(Environment $environment)
+    {
+        $this->setEnvironment($environment);
+
+        $env = $this->getEnvironment();
+        $env->shouldBeAnInstanceOf('Behat\Testwork\Environment\Environment');
+    }
+
+}
diff --git a/vendor/drupal/drupal-extension/spec/Drupal/DrupalExtension/Context/Annotation/ReaderSpec.php b/vendor/drupal/drupal-extension/spec/Drupal/DrupalExtension/Context/Annotation/ReaderSpec.php
new file mode 100644 (file)
index 0000000..ba41cbc
--- /dev/null
@@ -0,0 +1,15 @@
+<?php
+
+namespace spec\Drupal\DrupalExtension\Context\Annotation;
+
+use PhpSpec\ObjectBehavior;
+use Prophecy\Argument;
+use ReflectionMethod;
+
+class ReaderSpec extends ObjectBehavior
+{
+    function it_is_initializable()
+    {
+        $this->shouldHaveType('Drupal\DrupalExtension\Context\Annotation\Reader');
+    }
+}
diff --git a/vendor/drupal/drupal-extension/spec/Drupal/DrupalExtension/Context/DrupalContextSpec.php b/vendor/drupal/drupal-extension/spec/Drupal/DrupalExtension/Context/DrupalContextSpec.php
new file mode 100644 (file)
index 0000000..4cf4878
--- /dev/null
@@ -0,0 +1,20 @@
+<?php
+
+namespace spec\Drupal\DrupalExtension\Context;
+
+use PhpSpec\ObjectBehavior;
+use Prophecy\Argument;
+
+class DrupalContextSpec extends ObjectBehavior
+{
+    function it_is_drupal_aware()
+    {
+        $this->shouldHaveType('Drupal\DrupalExtension\Context\RawDrupalContext');
+    }
+
+    function it_is_a_translatable_context()
+    {
+        $this->shouldHaveType('Behat\Behat\Context\TranslatableContext');
+    }
+
+}
diff --git a/vendor/drupal/drupal-extension/spec/Drupal/DrupalExtension/Context/DrushContextSpec.php b/vendor/drupal/drupal-extension/spec/Drupal/DrupalExtension/Context/DrushContextSpec.php
new file mode 100644 (file)
index 0000000..88c9b96
--- /dev/null
@@ -0,0 +1,26 @@
+<?php
+
+namespace spec\Drupal\DrupalExtension\Context;
+
+use PhpSpec\ObjectBehavior;
+use Prophecy\Argument;
+
+use Drupal\DrupalDriverManager;
+
+class DrushContextSpec extends ObjectBehavior
+{
+    function it_should_be_drupal_aware()
+    {
+        $this->shouldHaveType('Drupal\DrupalExtension\Context\RawDrupalContext');
+    }
+
+    function it_will_catch_scenarios_without_any_output()
+    {
+        $this->shouldThrow('\RuntimeException')->duringReadDrushOutput();
+    }
+
+    function it_is_a_translatable_context()
+    {
+        $this->shouldHaveType('Behat\Behat\Context\TranslatableContext');
+    }
+}
diff --git a/vendor/drupal/drupal-extension/spec/Drupal/DrupalExtension/Context/Environment/Reader/ReaderSpec.php b/vendor/drupal/drupal-extension/spec/Drupal/DrupalExtension/Context/Environment/Reader/ReaderSpec.php
new file mode 100644 (file)
index 0000000..331b4af
--- /dev/null
@@ -0,0 +1,23 @@
+<?php
+
+namespace spec\Drupal\DrupalExtension\Context\Environment\Reader;
+
+use PhpSpec\ObjectBehavior;
+use Prophecy\Argument;
+
+use Drupal\DrupalDriverManager;
+
+class ReaderSpec extends ObjectBehavior
+{
+    function let(DrupalDriverManager $drupal)
+    {
+        $parameters = array();
+        $this->beConstructedWith($drupal, $parameters);
+    }
+
+    function it_is_initializable()
+    {
+        $this->shouldHaveType('Drupal\DrupalExtension\Context\Environment\Reader\Reader');
+    }
+
+}
diff --git a/vendor/drupal/drupal-extension/spec/Drupal/DrupalExtension/Context/Initializer/DrupalAwareInitializerSpec.php b/vendor/drupal/drupal-extension/spec/Drupal/DrupalExtension/Context/Initializer/DrupalAwareInitializerSpec.php
new file mode 100644 (file)
index 0000000..4805639
--- /dev/null
@@ -0,0 +1,49 @@
+<?php
+
+namespace spec\Drupal\DrupalExtension\Context\Initializer;
+
+use Behat\Behat\Context\Context;
+
+use Drupal\DrupalDriverManager;
+use Drupal\DrupalExtension\Context\DrupalAwareInterface;
+
+use Behat\Testwork\Call\CallCenter;
+use Behat\Testwork\Environment\EnvironmentManager;
+use Behat\Testwork\Hook\HookDispatcher;
+use Behat\Testwork\Hook\HookRepository;
+
+use PhpSpec\ObjectBehavior;
+use Prophecy\Argument;
+
+class DrupalAwareInitializerSpec extends ObjectBehavior
+{
+    private $dispatcher;
+
+    function let(DrupalDriverManager $drupal)
+    {
+        $callCenter = new CallCenter();
+        $manager = new EnvironmentManager();
+        $repository = new HookRepository($manager);
+        // Cannot mock this class as it is marked as final.
+        $this->dispatcher = new HookDispatcher($repository, $callCenter);
+        $this->beConstructedWith($drupal, array(), $this->dispatcher);
+    }
+
+    function it_is_a_context_initializer()
+    {
+        $this->shouldHaveType('Behat\Behat\Context\Initializer\ContextInitializer');
+    }
+
+    function it_does_nothing_for_basic_contexts(Context $context)
+    {
+        $this->initializeContext($context);
+    }
+
+    function it_injects_drupal_and_parameters_and_dispatcher_in_drupal_aware_Contexts(DrupalAwareInterface $context, $drupal)
+    {
+        $context->setDispatcher($this->dispatcher)->shouldBeCAlled();
+        $context->setDrupal($drupal)->shouldBeCAlled();
+        $context->setDrupalParameters(array())->shouldBeCAlled();
+        $this->initializeContext($context);
+    }
+}
diff --git a/vendor/drupal/drupal-extension/spec/Drupal/DrupalExtension/Context/MessageContextSpec.php b/vendor/drupal/drupal-extension/spec/Drupal/DrupalExtension/Context/MessageContextSpec.php
new file mode 100644 (file)
index 0000000..4e99d78
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+
+namespace spec\Drupal\DrupalExtension\Context;
+
+use PhpSpec\ObjectBehavior;
+use Prophecy\Argument;
+
+class MessageContextSpec extends ObjectBehavior
+{
+    function it_is_drupal_aware()
+    {
+        $this->shouldHaveType('Drupal\DrupalExtension\Context\RawDrupalContext');
+    }
+
+    function it_is_a_translatable_context()
+    {
+        $this->shouldHaveType('Behat\Behat\Context\TranslatableContext');
+    }
+}
diff --git a/vendor/drupal/drupal-extension/spec/Drupal/DrupalExtension/Context/MinkContextSpec.php b/vendor/drupal/drupal-extension/spec/Drupal/DrupalExtension/Context/MinkContextSpec.php
new file mode 100644 (file)
index 0000000..7742cad
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+
+namespace spec\Drupal\DrupalExtension\Context;
+
+use PhpSpec\ObjectBehavior;
+use Prophecy\Argument;
+
+class MinkContextSpec extends ObjectBehavior
+{
+    function it_extends_the_mink_context()
+    {
+        $this->shouldHaveType('Behat\MinkExtension\Context\MinkContext');
+    }
+
+    function it_is_a_translatable_context()
+    {
+        $this->shouldHaveType('Behat\Behat\Context\TranslatableContext');
+    }
+}
diff --git a/vendor/drupal/drupal-extension/spec/Drupal/DrupalExtension/Context/RawDrupalContextSpec.php b/vendor/drupal/drupal-extension/spec/Drupal/DrupalExtension/Context/RawDrupalContextSpec.php
new file mode 100644 (file)
index 0000000..23c9425
--- /dev/null
@@ -0,0 +1,55 @@
+<?php
+
+namespace spec\Drupal\DrupalExtension\Context;
+
+use PhpSpec\ObjectBehavior;
+use Prophecy\Argument;
+
+use Behat\Testwork\Hook\HookDispatcher;
+use Behat\Testwork\Hook\HookRepository;
+
+use Drupal\DrupalDriverManager;
+
+class RawDrupalContextSpec extends ObjectBehavior
+{
+    function it_should_be_drupal_aware()
+    {
+        $this->shouldHaveType('Drupal\DrupalExtension\Context\DrupalAwareInterface');
+    }
+
+    function it_can_set_and_get_drupal_manager(DrupalDriverManager $drupal)
+    {
+        $this->setDrupal($drupal);
+        $this->getDrupal()->shouldBeAnInstanceOf('Drupal\DrupalDriverManager');
+    }
+
+    function it_can_set_and_get_drupal_parameters()
+    {
+        $parameters = array(
+            'one' => '1',
+            'two' => '2',
+        );
+        $this->setDrupalParameters($parameters);
+        $this->getDrupalParameter('one')->shouldReturn('1');
+        $this->getDrupalParameter('two')->shouldReturn('2');
+    }
+
+    function it_can_manage_text_values()
+    {
+        $parameters = array(
+            'text' => array(
+                'login' => 'Log in',
+            ),
+        );
+        $this->setDrupalParameters($parameters);
+        $this->getDrupalText('login')->shouldReturn('Log in');
+        $this->shouldThrow('Exception')->duringGetDrupalText('No such string');
+    }
+
+    function it_can_get_the_current_drupal_driver(DrupalDriverManager $drupal)
+    {
+        $this->setDrupal($drupal);
+        $this->getDriver();
+    }
+
+}
diff --git a/vendor/drupal/drupal-extension/spec/Drupal/DrupalExtension/Hook/Scope/BeforeNodeCreateScopeSpec.php b/vendor/drupal/drupal-extension/spec/Drupal/DrupalExtension/Hook/Scope/BeforeNodeCreateScopeSpec.php
new file mode 100644 (file)
index 0000000..ae9330e
--- /dev/null
@@ -0,0 +1,34 @@
+<?php
+
+namespace spec\Drupal\DrupalExtension\Hook\Scope;
+
+use Behat\Behat\Context\Context;
+use Behat\Testwork\Environment\Environment;
+
+use PhpSpec\ObjectBehavior;
+use Prophecy\Argument;
+
+class BeforeNodeCreateScopeSpec extends ObjectBehavior
+{
+    function let(Environment $environment, Context $context)
+    {
+        $node = new \stdClass();
+        $this->beConstructedWith($environment, $context, $node);
+    }
+
+    function it_is_initializable()
+    {
+        $this->shouldHaveType('Drupal\DrupalExtension\Hook\Scope\BeforeNodeCreateScope');
+    }
+
+    function it_should_return_context()
+    {
+        $context = $this->getContext();
+        $context->shouldBeAnInstanceOf('Behat\Behat\Context\Context');
+    }
+
+    function it_should_return_a_node()
+    {
+        $this->getEntity()->shouldBeAnInstanceOf('stdClass');
+    }
+}
diff --git a/vendor/drupal/drupal-extension/spec/Drupal/DrupalExtension/Listener/DriverListenerSpec.php b/vendor/drupal/drupal-extension/spec/Drupal/DrupalExtension/Listener/DriverListenerSpec.php
new file mode 100644 (file)
index 0000000..d115a4d
--- /dev/null
@@ -0,0 +1,61 @@
+<?php
+
+namespace spec\Drupal\DrupalExtension\Listener;
+
+use Behat\Behat\EventDispatcher\Event\ScenarioTested;
+use Behat\Gherkin\Node\FeatureNode;
+use Behat\Gherkin\Node\ScenarioNode;
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\Suite\Suite;
+
+use Drupal\DrupalDriverManager;
+
+use PhpSpec\ObjectBehavior;
+use Prophecy\Argument;
+
+class DriverListenerSpec extends ObjectBehavior
+{
+    function let(DrupalDriverManager $drupal, ScenarioTested $event, FeatureNode $feature, ScenarioNode $scenario, Suite $suite, Environment $environment)
+    {
+        $parameters = array(
+            'default_driver' => 'blackbox',
+            'api_driver' => 'drupal_driver',
+        );
+        $this->beConstructedWith($drupal, $parameters);
+
+        $event->getFeature()->willReturn($feature);
+        $event->getScenario()->willReturn($scenario);
+        $event->getEnvironment()->willReturn($environment);
+
+        $feature->getTags()->willReturn(array('api'));
+        $feature->hasTag('api')->willReturn(TRUE);
+
+        $scenario->getTags()->willReturn(array());
+    }
+
+    function it_should_be_an_event_subscriber()
+    {
+        $this->shouldHaveType('Symfony\Component\EventDispatcher\EventSubscriberInterface');
+    }
+
+    function it_resets_the_default_drupal_driver_before_scenarios($event, $drupal, $environment, $feature, $scenario)
+    {
+        $drupal->setDefaultDriverName('drupal_driver')->shouldBeCalled();
+        $drupal->setEnvironment($environment)->shouldBeCalled();
+        $event->getEnvironment()->shouldBeCalled();
+        $event->getFeature()->shouldBeCalled();
+        $event->getScenario()->shouldBeCalled();
+        $feature->getTags()->shouldBeCalled();
+        $scenario->getTags()->shouldBeCalled();
+        $this->prepareDefaultDrupalDriver($event);
+    }
+
+    function it_subscribes_to_scenarios_and_outlines()
+    {
+        $subscribedEvents = array(
+            'tester.scenario_tested.before' => array('prepareDefaultDrupalDriver', 11),
+            'tester.example_tested.before' => array('prepareDefaultDrupalDriver', 11),
+        );
+        $this->getSubscribedEvents()->shouldReturn($subscribedEvents);;
+    }
+}
diff --git a/vendor/drupal/drupal-extension/spec/Drupal/DrupalExtension/Selector/RegionSelectorSpec.php b/vendor/drupal/drupal-extension/spec/Drupal/DrupalExtension/Selector/RegionSelectorSpec.php
new file mode 100644 (file)
index 0000000..641eb2c
--- /dev/null
@@ -0,0 +1,36 @@
+<?php
+
+namespace spec\Drupal\DrupalExtension\Selector;
+
+use Behat\Mink\Selector\SelectorInterface;
+use Behat\Mink\Selector\CssSelector;
+
+use PhpSpec\ObjectBehavior;
+use Prophecy\Argument;
+
+class RegionSelectorSpec extends ObjectBehavior
+{
+    function let(CssSelector $selector)
+    {
+        $regionMap = array(
+            'Left sidebar' => '#left-sidebar',
+        );
+        $this->beConstructedWith($selector, $regionMap);
+    }
+
+    function it_is_initializable()
+    {
+        $this->shouldHaveType('Drupal\DrupalExtension\Selector\RegionSelector');
+    }
+
+    function it_should_translate_to_xpath()
+    {
+        // @todo this is not returning properly for some reason.
+        $xpath = $this->translateToXPath('Left sidebar');
+    }
+
+    function it_should_not_accept_invalid_regions()
+    {
+        $this->shouldThrow('\InvalidArgumentException')->duringTranslateToXPath('Invalid region');
+    }
+}
diff --git a/vendor/drupal/drupal-extension/spec/Drupal/DrupalExtension/ServiceContainer/DrupalExtensionSpec.php b/vendor/drupal/drupal-extension/spec/Drupal/DrupalExtension/ServiceContainer/DrupalExtensionSpec.php
new file mode 100644 (file)
index 0000000..4934f78
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+
+namespace spec\Drupal\DrupalExtension\ServiceContainer;
+
+use PhpSpec\ObjectBehavior;
+use Prophecy\Argument;
+
+class DrupalExtensionSpec extends ObjectBehavior
+{
+    function it_is_a_testwork_extension()
+    {
+        $this->shouldHaveType('Behat\Testwork\ServiceContainer\Extension');
+    }
+
+    function it_is_named_drupal()
+    {
+        $this->getConfigKey()->shouldReturn('drupal');
+    }
+}
diff --git a/vendor/drupal/drupal-extension/src/Drupal/DrupalDriverManager.php b/vendor/drupal/drupal-extension/src/Drupal/DrupalDriverManager.php
new file mode 100644 (file)
index 0000000..aac3d1b
--- /dev/null
@@ -0,0 +1,147 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\DrupalDriverManager.
+ */
+
+namespace Drupal;
+
+use Behat\Testwork\Environment\Environment;
+use Drupal\Driver\DriverInterface;
+
+/**
+ * Drupal driver manager.
+ */
+class DrupalDriverManager {
+
+  /**
+   * The name of the default driver.
+   *
+   * @var string
+   */
+  private $defaultDriverName;
+
+  /**
+   * All registered drivers.
+   *
+   * @var \Drupal\Driver\DriverInterface[]
+   */
+  private $drivers = array();
+
+  /**
+   * Behat environment.
+   *
+   * @var \Behat\Testwork\Environment\Environment
+   */
+  private $environment;
+
+  /**
+   * Initialize the driver manager.
+   *
+   * @param \Drupal\Driver\DriverInterface[] $drivers
+   *   An array of drivers to register.
+   */
+  public function __construct(array $drivers = array()) {
+    foreach ($drivers as $name => $driver) {
+      $this->registerDriver($name, $driver);
+    }
+  }
+
+  /**
+   * Register a new driver.
+   *
+   * @param string $name
+   *   Driver name.
+   * @param \Drupal\Driver\DriverInterface $driver
+   *   An instance of a DriverInterface.
+   */
+  public function registerDriver($name, DriverInterface $driver) {
+    $name = strtolower($name);
+    $this->drivers[$name] = $driver;
+  }
+
+  /**
+   * Return a registered driver by name, or the default driver.
+   *
+   * @param string $name
+   *   The name of the driver to return. If omitted the default driver is
+   *   returned.
+   *
+   * @return \Drupal\Driver\DriverInterface
+   *   The requested driver.
+   *
+   * @throws \InvalidArgumentException
+   *   Thrown when the requested driver is not registered.
+   */
+  public function getDriver($name = NULL) {
+    $name = strtolower($name) ?: $this->defaultDriverName;
+
+    if (NULL === $name) {
+      throw new \InvalidArgumentException('Specify a Drupal driver to get.');
+    }
+
+    if (!isset($this->drivers[$name])) {
+      throw new \InvalidArgumentException(sprintf('Driver "%s" is not registered', $name));
+    }
+
+    $driver = $this->drivers[$name];
+
+    // Bootstrap driver if needed.
+    if (!$driver->isBootstrapped()) {
+      $driver->bootstrap();
+    }
+
+    return $driver;
+  }
+
+  /**
+   * Set the default driver name.
+   *
+   * @param string $name
+   *   Default driver name to set.
+   *
+   * @throws \InvalidArgumentException
+   *   Thrown when the driver is not registered.
+   */
+  public function setDefaultDriverName($name) {
+    $name = strtolower($name);
+
+    if (!isset($this->drivers[$name])) {
+      throw new \InvalidArgumentException(sprintf('Driver "%s" is not registered.', $name));
+    }
+
+    $this->defaultDriverName = $name;
+  }
+
+  /**
+   * Returns all registered drivers.
+   *
+   * @return \Drupal\Driver\DriverInterface[]
+   *   An array of drivers.
+   */
+  public function getDrivers() {
+    return $this->drivers;
+  }
+
+  /**
+   * Sets the Behat Environment.
+   *
+   * @param \Behat\Testwork\Environment\Environment $environment
+   *   The Behat Environment to set.
+   */
+  public function setEnvironment(Environment $environment) {
+    $this->environment = $environment;
+  }
+
+  /**
+   * Returns the Behat Environment.
+   *
+   * @return \Behat\Testwork\Environment\Environment
+   *   The Behat Environment.
+   */
+  public function getEnvironment() {
+    return $this->environment;
+  }
+
+}
diff --git a/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Compiler/DriverPass.php b/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Compiler/DriverPass.php
new file mode 100644 (file)
index 0000000..6fc862a
--- /dev/null
@@ -0,0 +1,53 @@
+<?php
+
+namespace Drupal\DrupalExtension\Compiler;
+
+use Symfony\Component\DependencyInjection\Reference,
+    Symfony\Component\DependencyInjection\ContainerBuilder,
+    Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
+
+/**
+ * Drupal\DrupalExtension container compilation pass.
+ */
+class DriverPass implements CompilerPassInterface {
+  /**
+   * Register Drupal drivers.
+   */
+  public function process(ContainerBuilder $container) {
+    if (!$container->hasDefinition('drupal.drupal')) {
+      return;
+    }
+
+    $drupalDefinition = $container->getDefinition('drupal.drupal');
+    foreach ($container->findTaggedServiceIds('drupal.driver') as $id => $attributes) {
+      foreach ($attributes as $attribute) {
+        if (isset($attribute['alias']) && $name = $attribute['alias']) {
+          $drupalDefinition->addMethodCall(
+            'registerDriver', array($name, new Reference($id))
+          );
+        }
+      }
+
+      // If this is Drupal Driver, then a core controller needs to be
+      // instantiated as well.
+      if ('drupal.driver.drupal' === $id) {
+        $drupalDriverDefinition = $container->getDefinition($id);
+        $availableCores = array();
+        foreach ($container->findTaggedServiceIds('drupal.core') as $coreId => $coreAttributes) {
+          foreach ($coreAttributes as $attribute) {
+            if (isset($attribute['alias']) && $name = $attribute['alias']) {
+              $availableCores[$name] = $container->getDefinition($coreId);
+            }
+          }
+        }
+        $drupalDriverDefinition->addMethodCall(
+          'setCore', array($availableCores)
+        );
+      }
+    }
+
+    $drupalDefinition->addMethodCall(
+      'setDefaultDriverName', array($container->getParameter('drupal.drupal.default_driver'))
+    );
+  }
+}
diff --git a/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Compiler/EventSubscriberPass.php b/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Compiler/EventSubscriberPass.php
new file mode 100644 (file)
index 0000000..45daa1d
--- /dev/null
@@ -0,0 +1,33 @@
+<?php
+
+namespace Drupal\DrupalExtension\Compiler;
+
+use Symfony\Component\DependencyInjection\Reference,
+    Symfony\Component\DependencyInjection\ContainerBuilder,
+    Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
+
+/**
+ * Event subscribers pass - registers all available event subscribers.
+ */
+class EventSubscriberPass implements CompilerPassInterface {
+  /**
+   * Processes container.
+   *
+   * @param ContainerBuilder $container
+   */
+  public function process(ContainerBuilder $container) {
+    if (!$container->hasDefinition('drupal.event_dispatcher')) {
+      return;
+    }
+    $dispatcherDefinition = $container->getDefinition('drupal.event_dispatcher');
+
+    foreach ($container->findTaggedServiceIds('drupal.event_subscriber') as $id => $attributes) {
+      foreach ($attributes as $attribute) {
+        $priority = isset($attribute['priority']) ? intval($attribute['priority']) : 0;
+        $dispatcherDefinition->addMethodCall(
+          'addSubscriber', array(new Reference($id), $priority)
+        );
+      }
+    }
+  }
+}
diff --git a/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Context/Annotation/Reader.php b/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Context/Annotation/Reader.php
new file mode 100644 (file)
index 0000000..0d03b66
--- /dev/null
@@ -0,0 +1,50 @@
+<?php
+
+namespace Drupal\DrupalExtension\Context\Annotation;
+
+use Behat\Behat\Context\Annotation\AnnotationReader;
+use Drupal\DrupalExtension\Hook\Dispatcher;
+use ReflectionMethod;
+
+/**
+ * Annotated contexts reader.
+ *
+ * @see \Behat\Behat\Context\Loader\AnnotatedLoader
+ */
+class Reader implements AnnotationReader {
+
+  /**
+   * @var string
+   */
+  private static $regex = '/^\@(beforenodecreate|afternodecreate|beforetermcreate|aftertermcreate|beforeusercreate|afterusercreate)(?:\s+(.+))?$/i';
+
+  /**
+   * @var string[]
+   */
+  private static $classes = array(
+    'afternodecreate' => 'Drupal\DrupalExtension\Hook\Call\AfterNodeCreate',
+    'aftertermcreate' => 'Drupal\DrupalExtension\Hook\Call\AfterTermCreate',
+    'afterusercreate' => 'Drupal\DrupalExtension\Hook\Call\AfterUserCreate',
+    'beforenodecreate' => 'Drupal\DrupalExtension\Hook\Call\BeforeNodeCreate',
+    'beforetermcreate' => 'Drupal\DrupalExtension\Hook\Call\BeforeTermCreate',
+    'beforeusercreate' => 'Drupal\DrupalExtension\Hook\Call\BeforeUserCreate',
+  );
+
+  /**
+   * {@inheritDoc}
+   */
+  public function readCallee($contextClass, ReflectionMethod $method, $docLine, $description) {
+
+    if (!preg_match(self::$regex, $docLine, $match)) {
+      return null;
+    }
+
+    $type = strtolower($match[1]);
+    $class = self::$classes[$type];
+    $pattern = isset($match[2]) ? $match[2] : null;
+    $callable = array($contextClass, $method->getName());
+
+    return new $class($pattern, $callable, $description);
+  }
+
+}
diff --git a/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Context/BatchContext.php b/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Context/BatchContext.php
new file mode 100644 (file)
index 0000000..0f7f64e
--- /dev/null
@@ -0,0 +1,24 @@
+<?php
+
+namespace Drupal\DrupalExtension\Context;
+
+use Behat\MinkExtension\Context\RawMinkContext;
+
+/**
+ * Extensions to the Mink Extension.
+ */
+class BatchContext extends RawMinkContext {
+
+  /**
+   * Wait for the Batch API to finish.
+   *
+   * Wait until the id="updateprogress" element is gone,
+   * or timeout after 3 minutes (180,000 ms).
+   *
+   * @Given /^I wait for the batch job to finish$/
+   */
+  public function iWaitForTheBatchJobToFinish() {
+    $this->getSession()->wait(180000, 'jQuery("#updateprogress").length === 0');
+  }
+
+}
diff --git a/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Context/ConfigContext.php b/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Context/ConfigContext.php
new file mode 100644 (file)
index 0000000..256865e
--- /dev/null
@@ -0,0 +1,107 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\DrupalExtension\Context\ConfigContext.
+ */
+
+namespace Drupal\DrupalExtension\Context;
+
+use Behat\Behat\Context\TranslatableContext;
+use Behat\Gherkin\Node\TableNode;
+
+/**
+ * Provides pre-built step definitions for interacting with Drupal config.
+ */
+class ConfigContext extends RawDrupalContext implements TranslatableContext {
+
+  /**
+   * {@inheritDoc}
+   */
+  public static function getTranslationResources() {
+    return glob(__DIR__ . '/../../../../i18n/*.xliff');
+  }
+
+  /**
+   * Keep track of any config that was changed so they can easily be reverted.
+   *
+   * @var array
+   */
+  protected $config = array();
+
+  /**
+   * Revert any changed config.
+   *
+   * @AfterScenario
+   */
+  public function cleanConfig() {
+    // Revert config that was changed.
+    foreach ($this->config as $name => $key_value) {
+      foreach ($key_value as $key => $value) {
+        $this->getDriver()->configSet($name, $key, $value);
+      }
+    }
+    $this->config = array();
+  }
+
+  /**
+   * Sets basic configuration item.
+   *
+   * @param string $name
+   *   The name of the configuration object.
+   * @param string $key
+   *   Identifier to store value in configuration.
+   * @param mixed $value
+   *   Value to associate with identifier.
+   *
+   * @Given I set the configuration item :name with key :key to :value
+   */
+  public function setBasicConfig($name, $key, $value) {
+    $this->setConfig($name, $key, $value);
+  }
+
+  /**
+   * Sets complex configuration.
+   *
+   * @param string $name
+   *   The name of the configuration object.
+   * @param string $key
+   *   Identifier to store value in configuration.
+   * @param TableNode $config_table
+   *   The table listing configuration keys and values.
+   *
+   * @Given I set the configuration item :name with key :key with values:
+   *
+   * Provide configuration data in the following format:
+   *  | key   | value  |
+   *  | foo   | bar    |
+   */
+  public function setComplexConfig($name, $key, TableNode $config_table) {
+    $value = array();
+    foreach ($config_table->getHash() as $row) {
+      // Allow json values for extra complexity.
+      if (json_decode($row['value'])) {
+        $row['value'] = json_decode($row['value'], TRUE);
+      }
+      $value[$row['key']] = $row['value'];
+    }
+    $this->setConfig($name, $key, $value);
+  }
+
+  /**
+   * Sets a value in a configuration object.
+   *
+   * @param string $name
+   *   The name of the configuration object.
+   * @param string $key
+   *   Identifier to store value in configuration.
+   * @param mixed $value
+   *   Value to associate with identifier.
+   */
+  public function setConfig($name, $key, $value) {
+    $backup = $this->getDriver()->configGet($name, $key);
+    $this->getDriver()->configSet($name, $key, $value);
+    $this->config[$name][$key] = $backup;
+  }
+
+}
\ No newline at end of file
diff --git a/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Context/ContextClass/ClassGenerator.php b/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Context/ContextClass/ClassGenerator.php
new file mode 100644 (file)
index 0000000..fe2d7bd
--- /dev/null
@@ -0,0 +1,71 @@
+<?php
+
+namespace Drupal\DrupalExtension\Context\ContextClass;
+
+use Behat\Behat\Context\ContextClass\ClassGenerator as BehatClassGenerator;
+use Behat\Testwork\Suite\Suite;
+
+/**
+ * Generates a starting class that extends the RawDrupalContext.
+ */
+class ClassGenerator implements BehatClassGenerator {
+
+  /**
+   * @var string
+   */
+  protected static $template = <<<'PHP'
+<?php
+
+{namespace}use Drupal\DrupalExtension\Context\RawDrupalContext;
+use Behat\Behat\Context\SnippetAcceptingContext;
+use Behat\Gherkin\Node\PyStringNode;
+use Behat\Gherkin\Node\TableNode;
+use Behat\Behat\Tester\Exception\PendingException;
+
+/**
+ * Defines application features from the specific context.
+ */
+class {className} extends RawDrupalContext implements SnippetAcceptingContext {
+
+  /**
+   * Initializes context.
+   *
+   * Every scenario gets its own context instance.
+   * You can also pass arbitrary arguments to the
+   * context constructor through behat.yml.
+   */
+  public function __construct() {
+  }
+
+}
+
+PHP;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function supportsSuiteAndClass(Suite $suite, $contextClass) {
+    return TRUE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function generateClass(Suite $suite, $contextClass) {
+    $fqn = $contextClass;
+
+    $namespace = '';
+    if (false !== $pos = strrpos($fqn, '\\')) {
+      $namespace = 'namespace ' . substr($fqn, 0, $pos) . ";\n\n";
+      $contextClass = substr($fqn, $pos + 1);
+    }
+
+    return strtr(
+      static::$template,
+      array(
+        '{namespace}' => $namespace,
+        '{className}' => $contextClass,
+      )
+    );
+  }
+}
diff --git a/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Context/DrupalAwareInterface.php b/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Context/DrupalAwareInterface.php
new file mode 100644 (file)
index 0000000..67c597d
--- /dev/null
@@ -0,0 +1,34 @@
+<?php
+
+namespace Drupal\DrupalExtension\Context;
+
+use Behat\Behat\Context\Context;
+use Behat\Testwork\Hook\HookDispatcher;
+
+use Drupal\DrupalDriverManager;
+use Symfony\Component\EventDispatcher\EventDispatcher;
+
+interface DrupalAwareInterface extends Context {
+
+  /**
+   * Sets Drupal instance.
+   */
+  public function setDrupal(DrupalDriverManager $drupal);
+
+  /**
+   * Set event dispatcher.
+   */
+  public function setDispatcher(HookDispatcher $dispatcher);
+
+  /**
+   * Gets Drupal instance.
+   */
+  public function getDrupal();
+
+  /**
+   * Sets parameters provided for Drupal.
+   *
+   * @param array $parameters
+   */
+  public function setDrupalParameters(array $parameters);
+}
diff --git a/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Context/DrupalContext.php b/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Context/DrupalContext.php
new file mode 100644 (file)
index 0000000..3ac77dc
--- /dev/null
@@ -0,0 +1,454 @@
+<?php
+
+namespace Drupal\DrupalExtension\Context;
+
+use Behat\Behat\Context\TranslatableContext;
+use Behat\Mink\Element\Element;
+
+use Behat\Gherkin\Node\TableNode;
+
+/**
+ * Provides pre-built step definitions for interacting with Drupal.
+ */
+class DrupalContext extends RawDrupalContext implements TranslatableContext {
+
+  /**
+   * Returns list of definition translation resources paths.
+   *
+   * @return array
+   */
+  public static function getTranslationResources() {
+    return glob(__DIR__ . '/../../../../i18n/*.xliff');
+  }
+
+  /**
+   * @Given I am an anonymous user
+   * @Given I am not logged in
+   */
+  public function assertAnonymousUser() {
+    // Verify the user is logged out.
+    if ($this->loggedIn()) {
+      $this->logout();
+    }
+  }
+
+  /**
+   * Creates and authenticates a user with the given role(s).
+   *
+   * @Given I am logged in as a user with the :role role(s)
+   * @Given I am logged in as a/an :role
+   */
+  public function assertAuthenticatedByRole($role) {
+    // Check if a user with this role is already logged in.
+    if (!$this->loggedInWithRole($role)) {
+      // Create user (and project)
+      $user = (object) array(
+        'name' => $this->getRandom()->name(8),
+        'pass' => $this->getRandom()->name(16),
+        'role' => $role,
+      );
+      $user->mail = "{$user->name}@example.com";
+
+      $this->userCreate($user);
+
+      $roles = explode(',', $role);
+      $roles = array_map('trim', $roles);
+      foreach ($roles as $role) {
+        if (!in_array(strtolower($role), array('authenticated', 'authenticated user'))) {
+          // Only add roles other than 'authenticated user'.
+          $this->getDriver()->userAddRole($user, $role);
+        }
+      }
+
+      // Login.
+      $this->login();
+    }
+  }
+
+  /**
+   * Creates and authenticates a user with the given role(s) and given fields.
+   * | field_user_name     | John  |
+   * | field_user_surname  | Smith |
+   * | ...                 | ...   |
+   *
+   * @Given I am logged in as a user with the :role role(s) and I have the following fields:
+   */
+  public function assertAuthenticatedByRoleWithGivenFields($role, TableNode $fields) {
+    // Check if a user with this role is already logged in.
+    if (!$this->loggedInWithRole($role)) {
+      // Create user (and project)
+      $user = (object) array(
+        'name' => $this->getRandom()->name(8),
+        'pass' => $this->getRandom()->name(16),
+        'role' => $role,
+      );
+      $user->mail = "{$user->name}@example.com";
+
+      // Assign fields to user before creation.
+      foreach ($fields->getRowsHash() as $field => $value) {
+        $user->{$field} = $value;
+      }
+
+      $this->userCreate($user);
+
+      $roles = explode(',', $role);
+      $roles = array_map('trim', $roles);
+      foreach ($roles as $role) {
+        if (!in_array(strtolower($role), array('authenticated', 'authenticated user'))) {
+          // Only add roles other than 'authenticated user'.
+          $this->getDriver()->userAddRole($user, $role);
+        }
+      }
+
+      // Login.
+      $this->login();
+    }
+  }
+
+
+  /**
+   * @Given I am logged in as :name
+   */
+  public function assertLoggedInByName($name) {
+    if (!isset($this->users[$name])) {
+      throw new \Exception(sprintf('No user with %s name is registered with the driver.', $name));
+    }
+
+    // Change internal current user.
+    $this->user = $this->users[$name];
+
+    // Login.
+    $this->login();
+  }
+
+  /**
+   * @Given I am logged in as a user with the :permissions permission(s)
+   */
+  public function assertLoggedInWithPermissions($permissions) {
+    // Create user.
+    $user = (object) array(
+      'name' => $this->getRandom()->name(8),
+      'pass' => $this->getRandom()->name(16),
+    );
+    $user->mail = "{$user->name}@example.com";
+    $this->userCreate($user);
+
+    // Create and assign a temporary role with given permissions.
+    $permissions = array_map('trim', explode(',', $permissions));
+    $rid = $this->getDriver()->roleCreate($permissions);
+    $this->getDriver()->userAddRole($user, $rid);
+    $this->roles[] = $rid;
+
+    // Login.
+    $this->login();
+  }
+
+  /**
+   * Retrieve a table row containing specified text from a given element.
+   *
+   * @param \Behat\Mink\Element\Element
+   * @param string
+   *   The text to search for in the table row.
+   *
+   * @return \Behat\Mink\Element\NodeElement
+   *
+   * @throws \Exception
+   */
+  public function getTableRow(Element $element, $search) {
+    $rows = $element->findAll('css', 'tr');
+    if (empty($rows)) {
+      throw new \Exception(sprintf('No rows found on the page %s', $this->getSession()->getCurrentUrl()));
+    }
+    foreach ($rows as $row) {
+      if (strpos($row->getText(), $search) !== FALSE) {
+        return $row;
+      }
+    }
+    throw new \Exception(sprintf('Failed to find a row containing "%s" on the page %s', $search, $this->getSession()->getCurrentUrl()));
+  }
+
+  /**
+   * Find text in a table row containing given text.
+   *
+   * @Then I should see (the text ):text in the :rowText row
+   */
+  public function assertTextInTableRow($text, $rowText) {
+    $row = $this->getTableRow($this->getSession()->getPage(), $rowText);
+    if (strpos($row->getText(), $text) === FALSE) {
+      throw new \Exception(sprintf('Found a row containing "%s", but it did not contain the text "%s".', $rowText, $text));
+    }
+  }
+
+  /**
+   * Asset text not in a table row containing given text.
+   *
+   * @Then I should not see (the text ):text in the :rowText row
+   */
+  public function assertTextNotInTableRow($text, $rowText) {
+    $row = $this->getTableRow($this->getSession()->getPage(), $rowText);
+    if (strpos($row->getText(), $text) !== FALSE) {
+      throw new \Exception(sprintf('Found a row containing "%s", but it contained the text "%s".', $rowText, $text));
+    }
+  }
+
+  /**
+   * Attempts to find a link in a table row containing giving text. This is for
+   * administrative pages such as the administer content types screen found at
+   * `admin/structure/types`.
+   *
+   * @Given I click :link in the :rowText row
+   * @Then I (should )see the :link in the :rowText row
+   */
+  public function assertClickInTableRow($link, $rowText) {
+    $page = $this->getSession()->getPage();
+    if ($link_element = $this->getTableRow($page, $rowText)->findLink($link)) {
+      // Click the link and return.
+      $link_element->click();
+      return;
+    }
+    throw new \Exception(sprintf('Found a row containing "%s", but no "%s" link on the page %s', $rowText, $link, $this->getSession()->getCurrentUrl()));
+  }
+
+  /**
+   * @Given the cache has been cleared
+   */
+  public function assertCacheClear() {
+    $this->getDriver()->clearCache();
+  }
+
+  /**
+   * @Given I run cron
+   */
+  public function assertCron() {
+    $this->getDriver()->runCron();
+  }
+
+  /**
+   * Creates content of the given type.
+   *
+   * @Given I am viewing a/an :type (content )with the title :title
+   * @Given a/an :type (content )with the title :title
+   */
+  public function createNode($type, $title) {
+    // @todo make this easily extensible.
+    $node = (object) array(
+      'title' => $title,
+      'type' => $type,
+    );
+    $saved = $this->nodeCreate($node);
+    // Set internal page on the new node.
+    $this->getSession()->visit($this->locatePath('/node/' . $saved->nid));
+  }
+
+  /**
+   * Creates content authored by the current user.
+   *
+   * @Given I am viewing my :type (content )with the title :title
+   */
+  public function createMyNode($type, $title) {
+    if (!isset($this->user->uid)) {
+      throw new \Exception(sprintf('There is no current logged in user to create a node for.'));
+    }
+
+    $node = (object) array(
+      'title' => $title,
+      'type' => $type,
+      'body' => $this->getRandom()->name(255),
+      'uid' => $this->user->uid,
+    );
+    $saved = $this->nodeCreate($node);
+
+    // Set internal page on the new node.
+    $this->getSession()->visit($this->locatePath('/node/' . $saved->nid));
+  }
+
+  /**
+   * Creates content of a given type provided in the form:
+   * | title    | author     | status | created           |
+   * | My title | Joe Editor | 1      | 2014-10-17 8:00am |
+   * | ...      | ...        | ...    | ...               |
+   *
+   * @Given :type content:
+   */
+  public function createNodes($type, TableNode $nodesTable) {
+    foreach ($nodesTable->getHash() as $nodeHash) {
+      $node = (object) $nodeHash;
+      $node->type = $type;
+      $this->nodeCreate($node);
+    }
+  }
+
+  /**
+   * Creates content of the given type, provided in the form:
+   * | title     | My node        |
+   * | Field One | My field value |
+   * | author    | Joe Editor     |
+   * | status    | 1              |
+   * | ...       | ...            |
+   *
+   * @Given I am viewing a/an :type( content):
+   */
+  public function assertViewingNode($type, TableNode $fields) {
+    $node = (object) array(
+      'type' => $type,
+    );
+    foreach ($fields->getRowsHash() as $field => $value) {
+      $node->{$field} = $value;
+    }
+
+    $saved = $this->nodeCreate($node);
+
+    // Set internal browser on the node.
+    $this->getSession()->visit($this->locatePath('/node/' . $saved->nid));
+  }
+
+  /**
+   * Asserts that a given content type is editable.
+   *
+   * @Then I should be able to edit a/an :type( content)
+   */
+  public function assertEditNodeOfType($type) {
+    $node = (object) array(
+      'type' => $type,
+      'title' => "Test $type",
+    );
+    $saved = $this->nodeCreate($node);
+
+    // Set internal browser on the node edit page.
+    $this->getSession()->visit($this->locatePath('/node/' . $saved->nid . '/edit'));
+
+    // Test status.
+    $this->assertSession()->statusCodeEquals('200');
+  }
+
+
+  /**
+   * Creates a term on an existing vocabulary.
+   *
+   * @Given I am viewing a/an :vocabulary term with the name :name
+   * @Given a/an :vocabulary term with the name :name
+   */
+  public function createTerm($vocabulary, $name) {
+    // @todo make this easily extensible.
+    $term = (object) array(
+      'name' => $name,
+      'vocabulary_machine_name' => $vocabulary,
+      'description' => $this->getRandom()->name(255),
+    );
+    $saved = $this->termCreate($term);
+
+    // Set internal page on the term.
+    $this->getSession()->visit($this->locatePath('/taxonomy/term/' . $saved->tid));
+  }
+
+  /**
+   * Creates multiple users.
+   *
+   * Provide user data in the following format:
+   *
+   * | name     | mail         | roles        |
+   * | user foo | foo@bar.com  | role1, role2 |
+   *
+   * @Given users:
+   */
+  public function createUsers(TableNode $usersTable) {
+    foreach ($usersTable->getHash() as $userHash) {
+
+      // Split out roles to process after user is created.
+      $roles = array();
+      if (isset($userHash['roles'])) {
+        $roles = explode(',', $userHash['roles']);
+        $roles = array_filter(array_map('trim', $roles));
+        unset($userHash['roles']);
+      }
+
+      $user = (object) $userHash;
+      // Set a password.
+      if (!isset($user->pass)) {
+        $user->pass = $this->getRandom()->name();
+      }
+      $this->userCreate($user);
+
+      // Assign roles.
+      foreach ($roles as $role) {
+        $this->getDriver()->userAddRole($user, $role);
+      }
+    }
+  }
+
+  /**
+   * Creates one or more terms on an existing vocabulary.
+   *
+   * Provide term data in the following format:
+   *
+   * | name  | parent | description | weight | taxonomy_field_image |
+   * | Snook | Fish   | Marine fish | 10     | snook-123.jpg        |
+   * | ...   | ...    | ...         | ...    | ...                  |
+   *
+   * Only the 'name' field is required.
+   *
+   * @Given :vocabulary terms:
+   */
+  public function createTerms($vocabulary, TableNode $termsTable) {
+    foreach ($termsTable->getHash() as $termsHash) {
+      $term = (object) $termsHash;
+      $term->vocabulary_machine_name = $vocabulary;
+      $this->termCreate($term);
+    }
+  }
+
+  /**
+   * Creates one or more languages.
+   *
+   * @Given the/these (following )languages are available:
+   *
+   * Provide language data in the following format:
+   *
+   * | langcode |
+   * | en       |
+   * | fr       |
+   *
+   * @param TableNode $langcodesTable
+   *   The table listing languages by their ISO code.
+   */
+  public function createLanguages(TableNode $langcodesTable) {
+    foreach ($langcodesTable->getHash() as $row) {
+      $language = (object) array(
+        'langcode' => $row['languages'],
+      );
+      $this->languageCreate($language);
+    }
+  }
+
+  /**
+   * Pauses the scenario until the user presses a key. Useful when debugging a scenario.
+   *
+   * @Then (I )break
+   */
+    public function iPutABreakpoint()
+    {
+      fwrite(STDOUT, "\033[s \033[93m[Breakpoint] Press \033[1;93m[RETURN]\033[0;93m to continue, or 'q' to quit...\033[0m");
+      do {
+        $line = trim(fgets(STDIN, 1024));
+        //Note: this assumes ASCII encoding.  Should probably be revamped to
+        //handle other character sets.
+        $charCode = ord($line);
+        switch($charCode){
+          case 0: //CR
+          case 121: //y
+          case 89: //Y
+            break 2;
+          // case 78: //N
+          // case 110: //n
+          case 113: //q
+          case 81: //Q
+            throw new \Exception("Exiting test intentionally.");
+          default:
+            fwrite(STDOUT, sprintf("\nInvalid entry '%s'.  Please enter 'y', 'q', or the enter key.\n", $line));
+          break;
+        }
+      } while (true);
+      fwrite(STDOUT, "\033[u");
+    }
+
+}
diff --git a/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Context/DrupalSubContextBase.php b/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Context/DrupalSubContextBase.php
new file mode 100644 (file)
index 0000000..8bdac83
--- /dev/null
@@ -0,0 +1,85 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\DrupalExtension\Context\DrupalSubContextBase.
+ */
+
+namespace Drupal\DrupalExtension\Context;
+
+use Behat\Behat\Context\Environment\InitializedContextEnvironment;
+use Drupal\DrupalDriverManager;
+
+/**
+ * Base class for subcontexts that use the Drupal API.
+ */
+abstract class DrupalSubContextBase extends RawDrupalContext implements DrupalSubContextInterface {
+
+  /**
+   * The Drupal Driver Manager.
+   *
+   * @var \Drupal\DrupalDriverManager $drupal
+   */
+  protected $drupal;
+
+  /**
+   * Constructs a DrupalSubContextBase object.
+   *
+   * @param \Drupal\DrupalDriverManager $drupal
+   *   The Drupal driver manager.
+   */
+  public function __construct(DrupalDriverManager $drupal) {
+    $this->drupal = $drupal;
+  }
+
+  /**
+   * Get the currently logged in user from DrupalContext.
+   */
+  protected function getUser() {
+    /** @var DrupalContext $context */
+    $context = $this->getContext('\Drupal\DrupalExtension\Context\DrupalContext');
+    if (empty($context->user)) {
+      throw new \Exception('No user is logged in.');
+    }
+
+    return $context->user;
+  }
+
+  /**
+   * Returns the Behat context that corresponds with the given class name.
+   *
+   * This is inspired by InitializedContextEnvironment::getContext() but also
+   * returns subclasses of the given class name. This allows us to retrieve for
+   * example DrupalContext even if it is overridden in a project.
+   *
+   * @param string $class
+   *   A fully namespaced class name.
+   *
+   * @return \Behat\Behat\Context\Context|false
+   *   The requested context, or FALSE if the context is not registered.
+   *
+   * @throws \Exception
+   *   Thrown when the environment is not yet initialized, meaning that contexts
+   *   cannot yet be retrieved.
+   */
+  protected function getContext($class) {
+    /** @var InitializedContextEnvironment $environment */
+    $environment = $this->drupal->getEnvironment();
+    // Throw an exception if the environment is not yet initialized. To make
+    // sure state doesn't leak between test scenarios, the environment is
+    // reinitialized at the start of every scenario. If this code is executed
+    // before a test scenario starts (e.g. in a `@BeforeScenario` hook) then the
+    // contexts cannot yet be retrieved.
+    if (!$environment instanceof InitializedContextEnvironment) {
+      throw new \Exception('Cannot retrieve contexts when the environment is not yet initialized.');
+    }
+    foreach ($environment->getContexts() as $context) {
+      if ($context instanceof $class) {
+        return $context;
+      }
+    }
+
+    return FALSE;
+  }
+
+}
diff --git a/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Context/DrupalSubContextInterface.php b/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Context/DrupalSubContextInterface.php
new file mode 100644 (file)
index 0000000..03699b1
--- /dev/null
@@ -0,0 +1,31 @@
+<?php
+
+/**
+ * Contains \Drupal\DrupalExtension\Context\DrupalSubContextInterface.
+ */
+
+namespace Drupal\DrupalExtension\Context;
+
+use Behat\Behat\Context\Context;
+use Drupal\DrupalDriverManager;
+
+/**
+ * Interface for subcontexts.
+ *
+ * Implement this interface if you want to provide custom Behat step definitions
+ * for your contributed modules. The class should be placed in a file named
+ * 'MYMODULE.behat.inc'.
+ *
+ * See the documentation on "Contributed module subcontexts".
+ */
+interface DrupalSubContextInterface extends Context {
+
+  /**
+   * Instantiates the subcontext.
+   *
+   * @param \Drupal\DrupalDriverManager $drupal
+   *   The Drupal Driver manager.
+   */
+  public function __construct(DrupalDriverManager $drupal);
+
+}
diff --git a/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Context/DrushContext.php b/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Context/DrushContext.php
new file mode 100644 (file)
index 0000000..3b33c60
--- /dev/null
@@ -0,0 +1,102 @@
+<?php
+
+namespace Drupal\DrupalExtension\Context;
+
+use Behat\Behat\Context\TranslatableContext;
+
+/**
+ * Provides step definitions for interacting directly with Drush commands.
+ */
+class DrushContext extends RawDrupalContext implements TranslatableContext {
+
+  /**
+   * Keep track of drush output.
+   *
+   * @var string|boolean
+   */
+  protected $drushOutput;
+
+  /**
+   * {@inheritDoc}
+   */
+  public static function getTranslationResources() {
+    return glob(__DIR__ . '/../../../../i18n/*.xliff');
+  }
+
+  /**
+   * Return the most recent drush command output.
+   *
+   * @return string
+   */
+  public function readDrushOutput() {
+    if (!isset($this->drushOutput)) {
+      throw new \RuntimeException('No drush output was found.');
+    }
+    return $this->drushOutput;
+  }
+
+  /**
+   * @Given I run drush :command
+   */
+  public function assertDrushCommand($command) {
+    if (!$this->drushOutput = $this->getDriver('drush')->$command()) {
+       $this->drushOutput = TRUE;
+    }
+  }
+
+  /**
+   * @Given I run drush :command :arguments
+   */
+  public function assertDrushCommandWithArgument($command, $arguments) {
+    $this->drushOutput = $this->getDriver('drush')->$command($this->fixStepArgument($arguments));
+    if (!isset($this->drushOutput)) {
+      $this->drushOutput = TRUE;
+    }
+  }
+
+  /**
+   * @Then drush output should contain :output
+   */
+  public function assertDrushOutput($output) {
+    if (strpos((string) $this->readDrushOutput(), $this->fixStepArgument($output)) === FALSE) {
+      throw new \Exception(sprintf("The last drush command output did not contain '%s'.\nInstead, it was:\n\n%s'", $output, $this->drushOutput));
+    }
+  }
+
+  /**
+   * @Then drush output should match :regex
+   */
+  public function assertDrushOutputMatches($regex) {
+    if (!preg_match($regex, (string) $this->readDrushOutput())) {
+      throw new \Exception(sprintf("The pattern %s was not found anywhere in the drush output.\nOutput:\n\n%s", $regex, $this->drushOutput));
+    }
+  }
+
+  /**
+   * @Then drush output should not contain :output
+   */
+  public function drushOutputShouldNotContain($output) {
+    if (strpos((string) $this->readDrushOutput(), $this->fixStepArgument($output)) !== FALSE) {
+        throw new \Exception(sprintf("The last drush command output did contain '%s' although it should not.\nOutput:\n\n%s'", $output, $this->drushOutput));
+    }
+  }
+
+  /**
+   * @Then print last drush output
+   */
+  public function printLastDrushOutput() {
+    echo $this->readDrushOutput();
+  }
+
+  /**
+   * Returns fixed step argument (with \\" replaced back to ").
+   *
+   * @param string $argument
+   *
+   * @return string
+   */
+  protected function fixStepArgument($argument) {
+    return str_replace('\\"', '"', $argument);
+  }
+
+}
diff --git a/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Context/Environment/Reader/Reader.php b/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Context/Environment/Reader/Reader.php
new file mode 100644 (file)
index 0000000..dace00d
--- /dev/null
@@ -0,0 +1,229 @@
+<?php
+
+namespace Drupal\DrupalExtension\Context\Environment\Reader;
+
+use Behat\Behat\Context\Environment\UninitializedContextEnvironment;
+use Behat\Behat\Context\Environment\ContextEnvironment;
+use Behat\Behat\Context\Reader\ContextReader;
+use Behat\Testwork\Call\Callee;
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\Environment\Exception\EnvironmentReadException;
+use Behat\Testwork\Environment\Reader\EnvironmentReader;
+
+use Drupal\DrupalDriverManager;
+use Drupal\Driver\SubDriverFinderInterface;
+
+use RecursiveDirectoryIterator;
+use RecursiveIteratorIterator;
+use RegexIterator;
+
+/**
+ * Read in additional contexts provided by core and contrib.
+ */
+final class Reader implements EnvironmentReader {
+
+  /**
+   * @var ContextReader[]
+   */
+  private $contextReaders = array();
+
+  /**
+   * Drupal driver manager.
+   *
+   * @var \Drupal\DrupalDriverManager
+   */
+  private $drupal;
+
+  /**
+   * Configuration parameters for this suite.
+   */
+  private $parameters;
+
+  /**
+   * Statically cached lists of subcontexts by path.
+   *
+   * @var array
+   */
+  static protected $subContexts;
+
+  /**
+   * Register the Drupal driver manager.
+   */
+  public function __construct(DrupalDriverManager $drupal, array $parameters) {
+    $this->drupal = $drupal;
+    $this->parameters = $parameters;
+  }
+
+  /**
+   * Registers context loader.
+   *
+   * @param ContextReader $contextReader
+   */
+  public function registerContextReader(ContextReader $contextReader) {
+    $this->contextReaders[] = $contextReader;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function supportsEnvironment(Environment $environment) {
+    return $environment instanceof ContextEnvironment;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function readEnvironmentCallees(Environment $environment) {
+
+    if (!$environment instanceof ContextEnvironment) {
+      throw new EnvironmentReadException(sprintf(
+          'ContextEnvironmentReader does not support `%s` environment.',
+          get_class($environment)
+        ), $environment);
+    }
+
+    $callees = array();
+    if (!$environment instanceof UninitializedContextEnvironment) {
+      return $callees;
+    }
+
+    $contextClasses = $this->findSubContextClasses();
+
+    foreach ($contextClasses as $contextClass) {
+      // When executing test scenarios with an examples table the registering of
+      // contexts is handled differently in newer version of Behat. Starting
+      // with Behat 3.2.0 the contexts are already registered, and the callees
+      // are returned by the default reader.
+      // Work around this and provide compatibility with Behat 3.1.0 as well as
+      // 3.2.0 and higher by checking if the class already exists before
+      // registering it and returning the callees.
+      // @see https://github.com/Behat/Behat/issues/758
+      if (!$environment->hasContextClass($contextClass)) {
+        $callees = array_merge(
+          $callees,
+          $this->readContextCallees($environment, $contextClass)
+        );
+
+        // Register context.
+        $environment->registerContextClass($contextClass, array($this->drupal));
+      }
+    }
+
+    return $callees;
+  }
+
+    /**
+     * Reads callees from a specific suite's context.
+     *
+     * @param ContextEnvironment $environment
+     * @param string             $contextClass
+     *
+     * @return Callee[]
+     */
+    private function readContextCallees(ContextEnvironment $environment, $contextClass)
+    {
+        $callees = array();
+        foreach ($this->contextReaders as $loader) {
+            $callees = array_merge(
+                $callees,
+                $loader->readContextCallees($environment, $contextClass)
+            );
+        }
+
+        return $callees;
+    }
+
+  /**
+   * Finds and loads available subcontext classes.
+   */
+  private function findSubContextClasses() {
+    $class_names = array();
+
+    // Initialize any available sub-contexts.
+    if (isset($this->parameters['subcontexts'])) {
+      $paths = array();
+      // Drivers may specify paths to subcontexts.
+      if ($this->parameters['subcontexts']['autoload']) {
+        foreach ($this->drupal->getDrivers() as $name => $driver) {
+          if ($driver instanceof SubDriverFinderInterface) {
+            $paths += $driver->getSubDriverPaths();
+          }
+        }
+      }
+
+      // Additional subcontext locations may be specified manually in behat.yml.
+      if (isset($this->parameters['subcontexts']['paths'])) {
+        $paths = array_merge($paths, $this->parameters['subcontexts']['paths']);
+      }
+
+      // Load each class.
+      foreach ($paths as $path) {
+        if ($subcontexts = $this->findAvailableSubContexts($path)) {
+          $this->loadSubContexts($subcontexts);
+        }
+      }
+
+      // Find all subcontexts, excluding abstract base classes.
+      $classes = get_declared_classes();
+      foreach ($classes as $class) {
+        $reflect = new \ReflectionClass($class);
+        if (!$reflect->isAbstract() && $reflect->implementsInterface('Drupal\DrupalExtension\Context\DrupalSubContextInterface')) {
+          $class_names[] = $class;
+        }
+      }
+
+    }
+
+    return $class_names;
+  }
+
+  /**
+   * Find Sub-contexts matching a given pattern located at the passed path.
+   *
+   * @param string $path
+   *   Absolute path to the directory to search for sub-contexts.
+   * @param string $pattern
+   *   File pattern to match. Defaults to `/^.+\.behat\.inc/i`.
+   *
+   * @return array
+   *   An array of paths.
+   */
+  private function findAvailableSubContexts($path, $pattern = '/^.+\.behat\.inc/i') {
+
+    if (isset(static::$subContexts[$pattern][$path])) {
+      return static::$subContexts[$pattern][$path];
+    }
+
+    static::$subContexts[$pattern][$path] = array();
+
+    $fileIterator = new RegexIterator(
+      new RecursiveIteratorIterator(
+        new RecursiveDirectoryIterator($path)
+      ), $pattern,
+      RegexIterator::MATCH
+    );
+    foreach ($fileIterator as $found) {
+      static::$subContexts[$pattern][$path][$found->getRealPath()] = $found->getFileName();
+    }
+
+    return static::$subContexts[$pattern][$path];
+  }
+
+  /**
+   * Load each subcontext file.
+   *
+   * @param array $subcontexts
+   *   An array of files to include.
+   */
+  private function loadSubContexts($subcontexts) {
+    foreach ($subcontexts as $path => $subcontext) {
+      if (!file_exists($path)) {
+        throw new \RuntimeException(sprintf('Subcontext path %s path does not exist.', $path));
+      }
+
+      // Load file.
+      require_once $path;
+    }
+  }
+
+}
diff --git a/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Context/Initializer/DrupalAwareInitializer.php b/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Context/Initializer/DrupalAwareInitializer.php
new file mode 100644 (file)
index 0000000..b9e4e07
--- /dev/null
@@ -0,0 +1,42 @@
+<?php
+
+namespace Drupal\DrupalExtension\Context\Initializer;
+
+use Behat\Behat\Context\Initializer\ContextInitializer;
+use Behat\Behat\Context\Context;
+use Behat\Testwork\Hook\HookDispatcher;
+
+use Drupal\DrupalDriverManager;
+use Drupal\DrupalExtension\Context\DrupalContext;
+use Drupal\DrupalExtension\Context\DrupalAwareInterface;
+
+class DrupalAwareInitializer implements ContextInitializer {
+  private $drupal, $parameters, $dispatcher;
+
+  public function __construct(DrupalDriverManager $drupal, array $parameters, HookDispatcher $dispatcher) {
+    $this->drupal = $drupal;
+    $this->parameters = $parameters;
+    $this->dispatcher = $dispatcher;
+  }
+
+  /**
+   * {@inheritdocs}
+   */
+  public function initializeContext(Context $context) {
+
+    // All contexts are passed here, only DrupalAwareInterface is allowed.
+    if (!$context instanceof DrupalAwareInterface) {
+      return;
+    }
+
+    // Set Drupal driver manager.
+    $context->setDrupal($this->drupal);
+
+    // Set event dispatcher.
+    $context->setDispatcher($this->dispatcher);
+
+    // Add all parameters to the context.
+    $context->setDrupalParameters($this->parameters);
+  }
+
+}
diff --git a/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Context/MarkupContext.php b/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Context/MarkupContext.php
new file mode 100644 (file)
index 0000000..5d059d7
--- /dev/null
@@ -0,0 +1,194 @@
+<?php
+
+namespace Drupal\DrupalExtension\Context;
+
+use Behat\MinkExtension\Context\RawMinkContext;
+
+/**
+ * Extensions to the Mink Extension.
+ */
+class MarkupContext extends RawMinkContext {
+
+  /**
+   * Return a region from the current page.
+   *
+   * @throws \Exception
+   *   If region cannot be found.
+   *
+   * @param string $region
+   *   The machine name of the region to return.
+   *
+   * @return \Behat\Mink\Element\NodeElement
+   *
+   * @todo this should be a trait when PHP 5.3 support is dropped.
+   */
+  public function getRegion($region) {
+    $session = $this->getSession();
+    $regionObj = $session->getPage()->find('region', $region);
+    if (!$regionObj) {
+      throw new \Exception(sprintf('No region "%s" found on the page %s.', $region, $session->getCurrentUrl()));
+    }
+
+    return $regionObj;
+  }
+
+  /**
+   * Checks if a button with id|name|title|alt|value exists in a region
+   *
+   * @Then I should see the button :button in the :region( region)
+   * @Then I should see the :button button in the :region( region)
+   *
+   * @param $button
+   *   string The id|name|title|alt|value of the button
+   * @param $region
+   *   string The region in which the button should be found
+   *
+   * @throws \Exception
+   *   If region or button within it cannot be found.
+   */
+  public function assertRegionButton($button, $region) {
+    $regionObj = $this->getRegion($region);
+
+    $buttonObj = $regionObj->findButton($button);
+    if (empty($buttonObj)) {
+      throw new \Exception(sprintf("The button '%s' was not found in the region '%s' on the page %s", $button, $region, $this->getSession()->getCurrentUrl()));
+    }
+  }
+
+  /**
+   * @Then I( should) see the :tag element in the :region( region)
+   */
+  public function assertRegionElement($tag, $region) {
+    $regionObj = $this->getRegion($region);
+    $elements = $regionObj->findAll('css', $tag);
+    if (!empty($elements)) {
+      return;
+    }
+    throw new \Exception(sprintf('The element "%s" was not found in the "%s" region on the page %s', $tag, $region, $this->getSession()->getCurrentUrl()));
+  }
+
+  /**
+   * @Then I( should) not see the :tag element in the :region( region)
+   */
+  public function assertNotRegionElement($tag, $region) {
+    $regionObj = $this->getRegion($region);
+    $result = $regionObj->findAll('css', $tag);
+    if (!empty($result)) {
+      throw new \Exception(sprintf('The element "%s" was found in the "%s" region on the page %s', $tag, $region, $this->getSession()->getCurrentUrl()));
+    }
+  }
+
+  /**
+   * @Then I( should) not see :text in the :tag element in the :region( region)
+   */
+  public function assertNotRegionElementText($text, $tag, $region) {
+    $regionObj = $this->getRegion($region);
+    $results = $regionObj->findAll('css', $tag);
+    if (!empty($results)) {
+      foreach ($results as $result) {
+        if ($result->getText() == $text) {
+          throw new \Exception(sprintf('The text "%s" was found in the "%s" element in the "%s" region on the page %s', $text, $tag, $region, $this->getSession()->getCurrentUrl()));
+        }
+      }
+    }
+  }
+
+  /**
+   * @Then I( should) see the :tag element with the :attribute attribute set to :value in the :region( region)
+   */
+  public function assertRegionElementAttribute($tag, $attribute, $value, $region) {
+    $regionObj = $this->getRegion($region);
+    $elements = $regionObj->findAll('css', $tag);
+    if (empty($elements)) {
+      throw new \Exception(sprintf('The element "%s" was not found in the "%s" region on the page %s', $tag, $region, $this->getSession()->getCurrentUrl()));
+    }
+    if (!empty($attribute)) {
+      $found = FALSE;
+      foreach ($elements as $element) {
+        $attr = $element->getAttribute($attribute);
+        if (!empty($attr)) {
+          $found = TRUE;
+          if (strpos($attr, "$value") === FALSE) {
+            throw new \Exception(sprintf('The "%s" attribute does not equal "%s" on the element "%s" in the "%s" region on the page %s', $attribute, $value, $tag, $region, $this->getSession()->getCurrentUrl()));
+          }
+          break;
+        }
+      }
+      if (!$found) {
+        throw new \Exception(sprintf('The "%s" attribute is not present on the element "%s" in the "%s" region on the page %s', $attribute, $tag, $region, $this->getSession()->getCurrentUrl()));
+      }
+    }
+  }
+
+  /**
+   * @Then I( should) see :text in the :tag element with the :attribute attribute set to :value in the :region( region)
+   */
+  public function assertRegionElementTextAttribute($text, $tag, $attribute, $value, $region) {
+    $regionObj = $this->getRegion($region);
+    $elements = $regionObj->findAll('css', $tag);
+    if (empty($elements)) {
+      throw new \Exception(sprintf('The element "%s" was not found in the "%s" region on the page %s', $tag, $region, $this->getSession()->getCurrentUrl()));
+    }
+
+    $found = FALSE;
+    foreach ($elements as $element) {
+      if ($element->getText() == $text) {
+        $found = TRUE;
+        break;
+      }
+    }
+    if (!$found) {
+      throw new \Exception(sprintf('The text "%s" was not found in the "%s" element in the "%s" region on the page %s', $text, $tag, $region, $this->getSession()->getCurrentUrl()));
+    }
+
+    if (!empty($attribute)) {
+      $attr = $element->getAttribute($attribute);
+      if (empty($attr)) {
+        throw new \Exception(sprintf('The "%s" attribute is not present on the element "%s" in the "%s" region on the page %s', $attribute, $tag, $region, $this->getSession()->getCurrentUrl()));
+      }
+      if (strpos($attr, "$value") === FALSE) {
+        throw new \Exception(sprintf('The "%s" attribute does not equal "%s" on the element "%s" in the "%s" region on the page %s', $attribute, $value, $tag, $region, $this->getSession()->getCurrentUrl()));
+      }
+    }
+  }
+
+  /**
+   * @Then I( should) see :text in the :tag element with the :property CSS property set to :value in the :region( region)
+   */
+  public function assertRegionElementTextCss($text, $tag, $property, $value, $region) {
+    $regionObj = $this->getRegion($region);
+    $elements = $regionObj->findAll('css', $tag);
+    if (empty($elements)) {
+      throw new \Exception(sprintf('The element "%s" was not found in the "%s" region on the page %s', $tag, $region, $this->getSession()->getCurrentUrl()));
+    }
+
+    $found = FALSE;
+    foreach ($elements as $element) {
+      if ($element->getText() == $text) {
+        $found = TRUE;
+        break;
+      }
+    }
+    if (!$found) {
+      throw new \Exception(sprintf('The text "%s" was not found in the "%s" element in the "%s" region on the page %s', $text, $tag, $region, $this->getSession()->getCurrentUrl()));
+    }
+
+    $found = FALSE;
+    if (!empty($property)) {
+      $style = $element->getAttribute('style');
+      $rules = explode(";", $style);
+      foreach ($rules as $rule) {
+        if (strpos($rule, $property) !== FALSE) {
+          if (strpos($rule, $value) === FALSE) {
+            throw new \Exception(sprintf('The "%s" style property does not equal "%s" on the element "%s" in the "%s" region on the page %s', $property, $value, $tag, $region, $this->getSession()->getCurrentUrl()));
+          }
+          $found = TRUE;
+          break;
+        }
+      }
+      if (!$found) {
+        throw new \Exception(sprintf('The "%s" style property was not found in the "%s" element in the "%s" region on the page %s', $property, $tag, $region, $this->getSession()->getCurrentUrl()));
+      }
+    }
+  }
+}
diff --git a/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Context/MessageContext.php b/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Context/MessageContext.php
new file mode 100644 (file)
index 0000000..0d5e7dd
--- /dev/null
@@ -0,0 +1,295 @@
+<?php
+
+namespace Drupal\DrupalExtension\Context;
+
+use Behat\Behat\Context\TranslatableContext;
+use Behat\Gherkin\Node\TableNode;
+
+/**
+ * Provides step-definitions for interacting with Drupal messages.
+ */
+class MessageContext extends RawDrupalContext implements TranslatableContext {
+
+  /**
+   * {@inheritDoc}
+   */
+  public static function getTranslationResources() {
+    return glob(__DIR__ . '/../../../../i18n/*.xliff');
+  }
+
+  /**
+   * Checks if the current page contains the given error message
+   *
+   * @param $message
+   *   string The text to be checked
+   *
+   * @Then I should see the error message( containing) :message
+   */
+  public function assertErrorVisible($message) {
+    $this->_assert(
+      $message,
+      'error_message_selector',
+      "The page '%s' does not contain any error messages",
+      "The page '%s' does not contain the error message '%s'"
+    );
+  }
+
+  /**
+   * Checks if the current page contains the given set of error messages
+   *
+   * @param $messages
+   *   array An array of texts to be checked
+   *
+   * @Then I should see the following error message(s):
+   */
+  public function assertMultipleErrors(TableNode $messages) {
+    foreach ($messages->getHash() as $key => $value) {
+      $message = trim($value['error messages']);
+      $this->assertErrorVisible($message);
+    }
+  }
+
+  /**
+   * Checks if the current page does not contain the given error message
+   *
+   * @param $message
+   *   string The text to be checked
+   *
+   * @Given I should not see the error message( containing) :message
+   */
+  public function assertNotErrorVisible($message) {
+    $this->_assertNot(
+      $message,
+      'error_message_selector',
+      "The page '%s' contains the error message '%s'"
+    );
+  }
+
+  /**
+   * Checks if the current page does not contain the given set error messages
+   *
+   * @param $messages
+   *   array An array of texts to be checked
+   *
+   * @Then I should not see the following error messages:
+   */
+  public function assertNotMultipleErrors(TableNode $messages) {
+    foreach ($messages->getHash() as $key => $value) {
+      $message = trim($value['error messages']);
+      $this->assertNotErrorVisible($message);
+    }
+  }
+
+  /**
+   * Checks if the current page contains the given success message
+   *
+   * @param $message
+   *   string The text to be checked
+   *
+   * @Then I should see the success message( containing) :message
+   */
+  public function assertSuccessMessage($message) {
+    $this->_assert(
+      $message,
+      'success_message_selector',
+      "The page '%s' does not contain any success messages",
+      "The page '%s' does not contain the success message '%s'"
+    );
+  }
+
+  /**
+   * Checks if the current page contains the given set of success messages
+   *
+   * @param $message
+   *   array An array of texts to be checked
+   *
+   * @Then I should see the following success messages:
+   */
+  public function assertMultipleSuccessMessage(TableNode $messages) {
+    foreach ($messages->getHash() as $key => $value) {
+      $message = trim($value['success messages']);
+      $this->assertSuccessMessage($message);
+    }
+  }
+
+  /**
+   * Checks if the current page does not contain the given set of success message
+   *
+   * @param $message
+   *   string The text to be checked
+   *
+   * @Given I should not see the success message( containing) :message
+   */
+  public function assertNotSuccessMessage($message) {
+    $this->_assertNot(
+      $message,
+      'success_message_selector',
+      "The page '%s' contains the success message '%s'"
+    );
+  }
+
+  /**
+   * Checks if the current page does not contain the given set of success messages
+   *
+   * @param $message
+   *   array An array of texts to be checked
+   *
+   * @Then I should not see the following success messages:
+   */
+  public function assertNotMultipleSuccessMessage(TableNode $messages) {
+    foreach ($messages->getHash() as $key => $value) {
+      $message = trim($value['success messages']);
+      $this->assertNotSuccessMessage($message);
+    }
+  }
+
+  /**
+   * Checks if the current page contains the given warning message
+   *
+   * @param $message
+   *   string The text to be checked
+   *
+   * @Then I should see the warning message( containing) :message
+   */
+  public function assertWarningMessage($message) {
+    $this->_assert(
+      $message,
+      'warning_message_selector',
+      "The page '%s' does not contain any warning messages",
+      "The page '%s' does not contain the warning message '%s'"
+    );
+  }
+
+  /**
+   * Checks if the current page contains the given set of warning messages
+   *
+   * @param $message
+   *   array An array of texts to be checked
+   *
+   * @Then I should see the following warning messages:
+   */
+  public function assertMultipleWarningMessage(TableNode $messages) {
+    foreach ($messages->getHash() as $key => $value) {
+      $message = trim($value['warning messages']);
+      $this->assertWarningMessage($message);
+    }
+  }
+
+  /**
+   * Checks if the current page does not contain the given set of warning message
+   *
+   * @param $message
+   *   string The text to be checked
+   *
+   * @Given I should not see the warning message( containing) :message
+   */
+  public function assertNotWarningMessage($message) {
+    $this->_assertNot(
+      $message,
+      'warning_message_selector',
+      "The page '%s' contains the warning message '%s'"
+    );
+  }
+
+  /**
+   * Checks if the current page does not contain the given set of warning messages
+   *
+   * @param $message
+   *   array An array of texts to be checked
+   *
+   * @Then I should not see the following warning messages:
+   */
+  public function assertNotMultipleWarningMessage(TableNode $messages) {
+    foreach ($messages->getHash() as $key => $value) {
+      $message = trim($value['warning messages']);
+      $this->assertNotWarningMessage($message);
+    }
+  }
+
+  /**
+   * Checks if the current page contain the given message
+   *
+   * @param $message
+   *   string The message to be checked
+   *
+   * @Then I should see the message( containing) :message
+   */
+  public function assertMessage($message) {
+    $this->_assert(
+      $message,
+      'message_selector',
+      "The page '%s' does not contain any messages",
+      "The page '%s' does not contain the message '%s'"
+    );
+  }
+
+  /**
+   * Checks if the current page does not contain the given message
+   *
+   * @param $message
+   *   string The message to be checked
+   *
+   * @Then I should not see the message( containing) :message
+   */
+  public function assertNotMessage($message) {
+    $this->_assertNot(
+      $message,
+      'message_selector',
+      "The page '%s' contains the message '%s'"
+    );
+  }
+
+  /**
+   * Internal callback to check for a specific message in a given context.
+   *
+   * @param $message
+   *   string The message to be checked
+   * @param $selectorId
+   *   string CSS selector name
+   * @param $exceptionMsgNone
+   *   string The message being thrown when no message is contained, string
+   *   should contain one '%s' as a placeholder for the current URL
+   * @param $exceptionMsgMissing
+   *   string The message being thrown when the message is not contained, string
+   *   should contain two '%s' as placeholders for the current URL and the message.
+   * @throws \Exception
+   */
+  private function _assert($message, $selectorId, $exceptionMsgNone, $exceptionMsgMissing) {
+    $selector = $this->getDrupalSelector($selectorId);
+    $selectorObjects = $this->getSession()->getPage()->findAll("css", $selector);
+    if (empty($selectorObjects)) {
+      throw new \Exception(sprintf($exceptionMsgNone, $this->getSession()->getCurrentUrl()));
+    }
+    foreach ($selectorObjects as $selectorObject) {
+      if (strpos(trim($selectorObject->getText()), $message) !== FALSE) {
+        return;
+      }
+    }
+    throw new \Exception(sprintf($exceptionMsgMissing, $this->getSession()->getCurrentUrl(), $message));
+  }
+
+  /**
+   * Internal callback to check if the current page does not contain the given message
+   *
+   * @param $message
+   *   string The message to be checked
+   * @param $selectorId
+   *   string CSS selector name
+   * @param $exceptionMsg
+   *   string The message being thrown when the message is contained, string
+   *   should contain two '%s' as placeholders for the current URL and the message.
+   * @throws \Exception
+   */
+  private function _assertNot($message, $selectorId, $exceptionMsg) {
+    $selector = $this->getDrupalSelector($selectorId);
+    $selectorObjects = $this->getSession()->getPage()->findAll("css", $selector);
+    if (!empty($selectorObjects)) {
+      foreach ($selectorObjects as $selectorObject) {
+        if (strpos(trim($selectorObject->getText()), $message) !== FALSE) {
+          throw new \Exception(sprintf($exceptionMsg, $this->getSession()->getCurrentUrl(), $message));
+        }
+      }
+    }
+  }
+
+}
diff --git a/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Context/MinkContext.php b/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Context/MinkContext.php
new file mode 100644 (file)
index 0000000..d6274cf
--- /dev/null
@@ -0,0 +1,567 @@
+<?php
+
+namespace Drupal\DrupalExtension\Context;
+
+use Behat\Behat\Context\TranslatableContext;
+use Behat\Mink\Exception\UnsupportedDriverActionException;
+use Behat\MinkExtension\Context\MinkContext as MinkExtension;
+
+/**
+ * Extensions to the Mink Extension.
+ */
+class MinkContext extends MinkExtension implements TranslatableContext {
+
+  /**
+   * Returns list of definition translation resources paths.
+   *
+   * @return array
+   */
+  public static function getTranslationResources() {
+    return self::getMinkTranslationResources() + glob(__DIR__ . '/../../../../i18n/*.xliff');
+  }
+
+  /**
+   * Return a region from the current page.
+   *
+   * @throws \Exception
+   *   If region cannot be found.
+   *
+   * @param string $region
+   *   The machine name of the region to return.
+   *
+   * @return \Behat\Mink\Element\NodeElement
+   */
+  public function getRegion($region) {
+    $session = $this->getSession();
+    $regionObj = $session->getPage()->find('region', $region);
+    if (!$regionObj) {
+      throw new \Exception(sprintf('No region "%s" found on the page %s.', $region, $session->getCurrentUrl()));
+    }
+
+    return $regionObj;
+  }
+
+  /**
+   * Visit a given path, and additionally check for HTTP response code 200.
+   *
+   * @Given I am at :path
+   * @When I visit :path
+   *
+   * @throws UnsupportedDriverActionException
+   */
+  public function assertAtPath($path) {
+    $this->getSession()->visit($this->locatePath($path));
+
+    // If available, add extra validation that this is a 200 response.
+    try {
+      $this->getSession()->getStatusCode();
+      $this->assertHttpResponse('200');
+    }
+    catch (UnsupportedDriverActionException $e) {
+      // Simply continue on, as this driver doesn't support HTTP response codes.
+    }
+  }
+
+  /**
+   * @When I click :link
+   */
+  public function assertClick($link) {
+    // Use the Mink Extenstion step definition.
+    $this->clickLink($link);
+  }
+
+  /**
+   * @Given for :field I enter :value
+   * @Given I enter :value for :field
+   */
+  public function assertEnterField($field, $value) {
+    // Use the Mink Extenstion step definition.
+    $this->fillField($field, $value);
+  }
+
+  /**
+   * For javascript enabled scenarios, always wait for AJAX before clicking.
+   *
+   * @BeforeStep
+   */
+  public function beforeJavascriptStep($event) {
+    /** @var \Behat\Behat\Hook\Scope\BeforeStepScope $event */
+    $tags = $event->getFeature()->getTags();
+    if (!in_array('javascript', $tags)) {
+      return;
+    }
+    $text = $event->getStep()->getText();
+    if (preg_match('/(follow|press|click|submit)/i', $text)) {
+      $this->iWaitForAjaxToFinish();
+    }
+  }
+
+  /**
+   * For javascript enabled scenarios, always wait for AJAX after clicking.
+   *
+   * @AfterStep
+   */
+  public function afterJavascriptStep($event) {
+    /** @var \Behat\Behat\Hook\Scope\BeforeStepScope $event */
+    $tags = $event->getFeature()->getTags();
+    if (!in_array('javascript', $tags)) {
+      return;
+    }
+    $text = $event->getStep()->getText();
+    if (preg_match('/(follow|press|click|submit)/i', $text)) {
+      $this->iWaitForAjaxToFinish();
+    }
+  }
+
+  /**
+   * Wait for AJAX to finish.
+   *
+   * @see \Drupal\FunctionalJavascriptTests\JSWebAssert::assertWaitOnAjaxRequest()
+   *
+   * @Given I wait for AJAX to finish
+   */
+  public function iWaitForAjaxToFinish() {
+    $condition = <<<JS
+    (function() {
+      function isAjaxing(instance) {
+        return instance && instance.ajaxing === true;
+      }
+      return (
+        // Assert no AJAX request is running (via jQuery or Drupal) and no
+        // animation is running.
+        (typeof jQuery === 'undefined' || (jQuery.active === 0 && jQuery(':animated').length === 0)) &&
+        (typeof Drupal === 'undefined' || typeof Drupal.ajax === 'undefined' || !Drupal.ajax.instances.some(isAjaxing))
+      );
+    }());
+JS;
+    $result = $this->getSession()->wait(5000, $condition);
+    if (!$result) {
+      throw new \RuntimeException('Unable to complete AJAX request.');
+    }
+  }
+  /**
+   * Presses button with specified id|name|title|alt|value.
+   *
+   * @When I press the :button button
+   */
+  public function pressButton($button) {
+    // Wait for any open autocomplete boxes to finish closing.  They block
+    // form-submission if they are still open.
+    // Use a step 'I press the "Esc" key in the "LABEL" field' to close
+    // autocomplete suggestion boxes with Mink.  "Click" events on the
+    // autocomplete suggestion do not work.
+    try {
+      $this->getSession()->wait(1000, 'typeof(jQuery)=="undefined" || jQuery("#autocomplete").length === 0');
+    }
+    catch (UnsupportedDriverActionException $e) {
+      // The jQuery probably failed because the driver does not support
+      // javascript.  That is okay, because if the driver does not support
+      // javascript, it does not support autocomplete boxes either.
+    }
+
+    // Use the Mink Extension step definition.
+    return parent::pressButton($button);
+  }
+
+  /**
+   * @Given I press the :char key in the :field field
+   *
+   * @param mixed $char could be either char ('b') or char-code (98)
+   * @throws \Exception
+   */
+  public function pressKey($char, $field) {
+    static $keys = array(
+      'backspace' => 8,
+      'tab' => 9,
+      'enter' => 13,
+      'shift' => 16,
+      'ctrl' =>  17,
+      'alt' => 18,
+      'pause' => 19,
+      'break' => 19,
+      'escape' =>  27,
+      'esc' =>  27,
+      'end' => 35,
+      'home' =>  36,
+      'left' => 37,
+      'up' => 38,
+      'right' =>39,
+      'down' => 40,
+      'insert' =>  45,
+      'delete' =>  46,
+      'pageup' => 33,
+      'pagedown' => 34,
+      'capslock' => 20,
+    );
+
+    if (is_string($char)) {
+      if (strlen($char) < 1) {
+        throw new \Exception('FeatureContext->keyPress($char, $field) was invoked but the $char parameter was empty.');
+      }
+      elseif (strlen($char) > 1) {
+        // Support for all variations, e.g. ESC, Esc, page up, pageup.
+        $char = $keys[strtolower(str_replace(' ', '', $char))];
+      }
+    }
+
+    $element = $this->getSession()->getPage()->findField($field);
+    if (!$element) {
+      throw new \Exception("Field '$field' not found");
+    }
+
+    $driver = $this->getSession()->getDriver();
+    // $driver->keyPress($element->getXpath(), $char);
+    // This alternative to Driver->keyPress() handles cases that depend on
+    // javascript which binds to key down/up events directly, such as Drupal's
+    // autocomplete.js.
+    $driver->keyDown($element->getXpath(), $char);
+    $driver->keyUp($element->getXpath(), $char);
+  }
+
+  /**
+   * @Then I should see the link :link
+   */
+  public function assertLinkVisible($link) {
+    $element = $this->getSession()->getPage();
+    $result = $element->findLink($link);
+
+    try {
+      if ($result && !$result->isVisible()) {
+        throw new \Exception(sprintf("No link to '%s' on the page %s", $link, $this->getSession()->getCurrentUrl()));
+      }
+    }
+    catch (UnsupportedDriverActionException $e) {
+      // We catch the UnsupportedDriverActionException exception in case
+      // this step is not being performed by a driver that supports javascript.
+      // All other exceptions are valid.
+    }
+
+    if (empty($result)) {
+      throw new \Exception(sprintf("No link to '%s' on the page %s", $link, $this->getSession()->getCurrentUrl()));
+    }
+  }
+
+  /**
+   * Links are not loaded on the page.
+   *
+   * @Then I should not see the link :link
+   */
+  public function assertNotLinkVisible($link) {
+    $element = $this->getSession()->getPage();
+    $result = $element->findLink($link);
+
+    try {
+      if ($result && $result->isVisible()) {
+        throw new \Exception(sprintf("The link '%s' was present on the page %s and was not supposed to be", $link, $this->getSession()->getCurrentUrl()));
+      }
+    }
+    catch (UnsupportedDriverActionException $e) {
+      // We catch the UnsupportedDriverActionException exception in case
+      // this step is not being performed by a driver that supports javascript.
+      // All other exceptions are valid.
+    }
+
+    if ($result) {
+      throw new \Exception(sprintf("The link '%s' was present on the page %s and was not supposed to be", $link, $this->getSession()->getCurrentUrl()));
+    }
+  }
+
+  /**
+   * Links are loaded but not visually visible (e.g they have display: hidden applied).
+   *
+   * @Then I should not visibly see the link :link
+   */
+  public function assertNotLinkVisuallyVisible($link) {
+    $element = $this->getSession()->getPage();
+    $result = $element->findLink($link);
+
+    try {
+      if ($result && $result->isVisible()) {
+        throw new \Exception(sprintf("The link '%s' was visually visible on the page %s and was not supposed to be", $link, $this->getSession()->getCurrentUrl()));
+      }
+    }
+    catch (UnsupportedDriverActionException $e) {
+      // We catch the UnsupportedDriverActionException exception in case
+      // this step is not being performed by a driver that supports javascript.
+      // All other exceptions are valid.
+    }
+
+    if (!$result) {
+      throw new \Exception(sprintf("The link '%s' was not loaded on the page %s at all", $link, $this->getSession()->getCurrentUrl()));
+    }
+
+  }
+
+  /**
+   * @Then I (should )see the heading :heading
+   */
+  public function assertHeading($heading) {
+    $element = $this->getSession()->getPage();
+    foreach (array('h1', 'h2', 'h3', 'h4', 'h5', 'h6') as $tag) {
+      $results = $element->findAll('css', $tag);
+      foreach ($results as $result) {
+        if ($result->getText() == $heading) {
+          return;
+        }
+      }
+    }
+    throw new \Exception(sprintf("The text '%s' was not found in any heading on the page %s", $heading, $this->getSession()->getCurrentUrl()));
+  }
+
+  /**
+   * @Then I (should )not see the heading :heading
+   */
+  public function assertNotHeading($heading) {
+    $element = $this->getSession()->getPage();
+    foreach (array('h1', 'h2', 'h3', 'h4', 'h5', 'h6') as $tag) {
+      $results = $element->findAll('css', $tag);
+      foreach ($results as $result) {
+        if ($result->getText() == $heading) {
+          throw new \Exception(sprintf("The text '%s' was found in a heading on the page %s", $heading, $this->getSession()->getCurrentUrl()));
+        }
+      }
+    }
+  }
+
+  /**
+   * @Then I (should ) see the button :button
+   * @Then I (should ) see the :button button
+   */
+  public function assertButton($button) {
+    $element = $this->getSession()->getPage();
+    $buttonObj = $element->findButton($button);
+    if (empty($buttonObj)) {
+      throw new \Exception(sprintf("The button '%s' was not found on the page %s", $button, $this->getSession()->getCurrentUrl()));
+    }
+  }
+
+  /**
+   * @Then I should not see the button :button
+   * @Then I should not see the :button button
+   */
+  public function assertNotButton($button) {
+    $element = $this->getSession()->getPage();
+    $buttonObj = $element->findButton($button);
+    if (!empty($buttonObj)) {
+      throw new \Exception(sprintf("The button '%s' was found on the page %s", $button, $this->getSession()->getCurrentUrl()));
+    }
+  }
+
+  /**
+   * @When I follow/click :link in the :region( region)
+   *
+   * @throws \Exception
+   *   If region or link within it cannot be found.
+   */
+  public function assertRegionLinkFollow($link, $region) {
+    $regionObj = $this->getRegion($region);
+
+    // Find the link within the region
+    $linkObj = $regionObj->findLink($link);
+    if (empty($linkObj)) {
+      throw new \Exception(sprintf('The link "%s" was not found in the region "%s" on the page %s', $link, $region, $this->getSession()->getCurrentUrl()));
+    }
+    $linkObj->click();
+  }
+
+  /**
+   * Checks, if a button with id|name|title|alt|value exists or not and pressess the same
+   *
+   * @Given I press :button in the :region( region)
+   *
+   * @param $button
+   *   string The id|name|title|alt|value of the button to be pressed
+   * @param $region
+   *   string The region in which the button should be pressed
+   *
+   * @throws \Exception
+   *   If region or button within it cannot be found.
+   */
+  public function assertRegionPressButton($button, $region) {
+    $regionObj = $this->getRegion($region);
+
+    $buttonObj = $regionObj->findButton($button);
+    if (empty($buttonObj)) {
+      throw new \Exception(sprintf("The button '%s' was not found in the region '%s' on the page %s", $button, $region, $this->getSession()->getCurrentUrl()));
+    }
+    $regionObj->pressButton($button);
+  }
+
+  /**
+   * Fills in a form field with id|name|title|alt|value in the specified region.
+   *
+   * @Given I fill in :value for :field in the :region( region)
+   * @Given I fill in :field with :value in the :region( region)
+   *
+   * @throws \Exception
+   *   If region cannot be found.
+   */
+  public function regionFillField($field, $value, $region) {
+    $field = $this->fixStepArgument($field);
+    $value = $this->fixStepArgument($value);
+    $regionObj = $this->getRegion($region);
+    $regionObj->fillField($field, $value);
+  }
+
+  /**
+   * Find a heading in a specific region.
+   *
+   * @Then I should see the heading :heading in the :region( region)
+   * @Then I should see the :heading heading in the :region( region)
+   *
+   * @throws \Exception
+   *   If region or header within it cannot be found.
+   */
+  public function assertRegionHeading($heading, $region) {
+    $regionObj = $this->getRegion($region);
+
+    foreach (array('h1', 'h2', 'h3', 'h4', 'h5', 'h6') as $tag) {
+      $elements = $regionObj->findAll('css', $tag);
+      if (!empty($elements)) {
+        foreach ($elements as $element) {
+          if (trim($element->getText()) === $heading) {
+            return;
+          }
+        }
+      }
+    }
+
+    throw new \Exception(sprintf('The heading "%s" was not found in the "%s" region on the page %s', $heading, $region, $this->getSession()->getCurrentUrl()));
+  }
+
+  /**
+   * @Then I should see the link :link in the :region( region)
+   *
+   * @throws \Exception
+   *   If region or link within it cannot be found.
+   */
+  public function assertLinkRegion($link, $region) {
+    $regionObj = $this->getRegion($region);
+
+    $result = $regionObj->findLink($link);
+    if (empty($result)) {
+      throw new \Exception(sprintf('No link to "%s" in the "%s" region on the page %s', $link, $region, $this->getSession()->getCurrentUrl()));
+    }
+  }
+
+  /**
+   * @Then I should not see the link :link in the :region( region)
+   *
+   * @throws \Exception
+   *   If region or link within it cannot be found.
+   */
+  public function assertNotLinkRegion($link, $region) {
+    $regionObj = $this->getRegion($region);
+
+    $result = $regionObj->findLink($link);
+    if (!empty($result)) {
+      throw new \Exception(sprintf('Link to "%s" in the "%s" region on the page %s', $link, $region, $this->getSession()->getCurrentUrl()));
+    }
+  }
+
+  /**
+   * @Then I should see( the text) :text in the :region( region)
+   *
+   * @throws \Exception
+   *   If region or text within it cannot be found.
+   */
+  public function assertRegionText($text, $region) {
+    $regionObj = $this->getRegion($region);
+
+    // Find the text within the region
+    $regionText = $regionObj->getText();
+    if (strpos($regionText, $text) === FALSE) {
+      throw new \Exception(sprintf("The text '%s' was not found in the region '%s' on the page %s", $text, $region, $this->getSession()->getCurrentUrl()));
+    }
+  }
+
+  /**
+   * @Then I should not see( the text) :text in the :region( region)
+   *
+   * @throws \Exception
+   *   If region or text within it cannot be found.
+   */
+  public function assertNotRegionText($text, $region) {
+    $regionObj = $this->getRegion($region);
+
+    // Find the text within the region.
+    $regionText = $regionObj->getText();
+    if (strpos($regionText, $text) !== FALSE) {
+      throw new \Exception(sprintf('The text "%s" was found in the region "%s" on the page %s', $text, $region, $this->getSession()->getCurrentUrl()));
+    }
+  }
+
+  /**
+   * @Then I (should )see the text :text
+   */
+  public function assertTextVisible($text) {
+    // Use the Mink Extension step definition.
+    $this->assertPageContainsText($text);
+  }
+
+  /**
+   * @Then I should not see the text :text
+   */
+  public function assertNotTextVisible($text) {
+    // Use the Mink Extension step definition.
+    $this->assertPageNotContainsText($text);
+  }
+
+  /**
+   * @Then I should get a :code HTTP response
+   */
+  public function assertHttpResponse($code) {
+    // Use the Mink Extension step definition.
+    $this->assertResponseStatus($code);
+  }
+
+  /**
+   * @Then I should not get a :code HTTP response
+   */
+  public function assertNotHttpResponse($code) {
+    // Use the Mink Extension step definition.
+    $this->assertResponseStatusIsNot($code);
+  }
+
+  /**
+   * @Given I check the box :checkbox
+   */
+  public function assertCheckBox($checkbox) {
+    // Use the Mink Extension step definition.
+    $this->checkOption($checkbox);
+  }
+
+  /**
+   * @Given I uncheck the box :checkbox
+   */
+  public function assertUncheckBox($checkbox) {
+    // Use the Mink Extension step definition.
+    $this->uncheckOption($checkbox);
+  }
+
+  /**
+   * @When I select the radio button :label with the id :id
+   * @When I select the radio button :label
+   *
+   * @TODO convert to mink extension.
+   */
+  public function assertSelectRadioById($label, $id = '') {
+    $element = $this->getSession()->getPage();
+    $radiobutton = $id ? $element->findById($id) : $element->find('named', array('radio', $this->getSession()->getSelectorsHandler()->xpathLiteral($label)));
+    if ($radiobutton === NULL) {
+      throw new \Exception(sprintf('The radio button with "%s" was not found on the page %s', $id ? $id : $label, $this->getSession()->getCurrentUrl()));
+    }
+    $value = $radiobutton->getAttribute('value');
+    $labelonpage = $radiobutton->getParent()->getText();
+    if ($label != $labelonpage) {
+      throw new \Exception(sprintf("Button with id '%s' has label '%s' instead of '%s' on the page %s", $id, $labelonpage, $label, $this->getSession()->getCurrentUrl()));
+    }
+    $radiobutton->selectOption($value, FALSE);
+  }
+
+  /**
+   * @} End of defgroup "mink extensions"
+   */
+
+
+}
diff --git a/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Context/RawDrupalContext.php b/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Context/RawDrupalContext.php
new file mode 100644 (file)
index 0000000..6ca74c9
--- /dev/null
@@ -0,0 +1,557 @@
+<?php
+
+namespace Drupal\DrupalExtension\Context;
+
+use Behat\MinkExtension\Context\RawMinkContext;
+use Behat\Mink\Exception\DriverException;
+use Behat\Testwork\Hook\HookDispatcher;
+
+use Drupal\DrupalDriverManager;
+
+use Drupal\DrupalExtension\Hook\Scope\AfterLanguageEnableScope;
+use Drupal\DrupalExtension\Hook\Scope\AfterNodeCreateScope;
+use Drupal\DrupalExtension\Hook\Scope\AfterTermCreateScope;
+use Drupal\DrupalExtension\Hook\Scope\AfterUserCreateScope;
+use Drupal\DrupalExtension\Hook\Scope\BaseEntityScope;
+use Drupal\DrupalExtension\Hook\Scope\BeforeLanguageEnableScope;
+use Drupal\DrupalExtension\Hook\Scope\BeforeNodeCreateScope;
+use Drupal\DrupalExtension\Hook\Scope\BeforeUserCreateScope;
+use Drupal\DrupalExtension\Hook\Scope\BeforeTermCreateScope;
+
+
+/**
+ * Provides the raw functionality for interacting with Drupal.
+ */
+class RawDrupalContext extends RawMinkContext implements DrupalAwareInterface {
+
+  /**
+   * Drupal driver manager.
+   *
+   * @var \Drupal\DrupalDriverManager
+   */
+  private $drupal;
+
+  /**
+   * Test parameters.
+   *
+   * @var array
+   */
+  private $drupalParameters;
+
+  /**
+   * Event dispatcher object.
+   *
+   * @var \Behat\Testwork\Hook\HookDispatcher
+   */
+  protected $dispatcher;
+
+  /**
+   * Keep track of nodes so they can be cleaned up.
+   *
+   * @var array
+   */
+  protected $nodes = array();
+
+  /**
+   * Current authenticated user.
+   *
+   * A value of FALSE denotes an anonymous user.
+   *
+   * @var \stdClass|bool
+   */
+  public $user = FALSE;
+
+  /**
+   * Keep track of all users that are created so they can easily be removed.
+   *
+   * @var array
+   */
+  protected $users = array();
+
+  /**
+   * Keep track of all terms that are created so they can easily be removed.
+   *
+   * @var array
+   */
+  protected $terms = array();
+
+  /**
+   * Keep track of any roles that are created so they can easily be removed.
+   *
+   * @var array
+   */
+  protected $roles = array();
+
+  /**
+   * Keep track of any languages that are created so they can easily be removed.
+   *
+   * @var array
+   */
+  protected $languages = array();
+
+  /**
+   * {@inheritDoc}
+   */
+  public function setDrupal(DrupalDriverManager $drupal) {
+    $this->drupal = $drupal;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public function getDrupal() {
+    return $this->drupal;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public function setDispatcher(HookDispatcher $dispatcher) {
+    $this->dispatcher = $dispatcher;
+  }
+
+  /**
+   * Set parameters provided for Drupal.
+   */
+  public function setDrupalParameters(array $parameters) {
+    $this->drupalParameters = $parameters;
+  }
+
+  /**
+   * Returns a specific Drupal parameter.
+   *
+   * @param string $name
+   *   Parameter name.
+   *
+   * @return mixed
+   */
+  public function getDrupalParameter($name) {
+    return isset($this->drupalParameters[$name]) ? $this->drupalParameters[$name] : NULL;
+  }
+
+  /**
+   * Returns a specific Drupal text value.
+   *
+   * @param string $name
+   *   Text value name, such as 'log_out', which corresponds to the default 'Log
+   *   out' link text.
+   * @throws \Exception
+   * @return
+   */
+  public function getDrupalText($name) {
+    $text = $this->getDrupalParameter('text');
+    if (!isset($text[$name])) {
+      throw new \Exception(sprintf('No such Drupal string: %s', $name));
+    }
+    return $text[$name];
+  }
+
+  /**
+   * Returns a specific css selector.
+   *
+   * @param $name
+   *   string CSS selector name
+   */
+  public function getDrupalSelector($name) {
+    $text = $this->getDrupalParameter('selectors');
+    if (!isset($text[$name])) {
+      throw new \Exception(sprintf('No such selector configured: %s', $name));
+    }
+    return $text[$name];
+  }
+
+  /**
+   * Get active Drupal Driver.
+   *
+   * @return \Drupal\Driver\DrupalDriver
+   */
+  public function getDriver($name = NULL) {
+    return $this->getDrupal()->getDriver($name);
+  }
+
+  /**
+   * Get driver's random generator.
+   */
+  public function getRandom() {
+    return $this->getDriver()->getRandom();
+  }
+
+  /**
+   * Massage node values to match the expectations on different Drupal versions.
+   *
+   * @beforeNodeCreate
+   */
+  public static function alterNodeParameters(BeforeNodeCreateScope $scope) {
+    $node = $scope->getEntity();
+
+    // Get the Drupal API version if available. This is not available when
+    // using e.g. the BlackBoxDriver or DrushDriver.
+    $api_version = NULL;
+    $driver = $scope->getContext()->getDrupal()->getDriver();
+    if ($driver instanceof \Drupal\Driver\DrupalDriver) {
+      $api_version = $scope->getContext()->getDrupal()->getDriver()->version;
+    }
+
+    // On Drupal 8 the timestamps should be in UNIX time.
+    switch ($api_version) {
+      case 8:
+        foreach (array('changed', 'created', 'revision_timestamp') as $field) {
+          if (!empty($node->$field) && !is_numeric($node->$field)) {
+            $node->$field = strtotime($node->$field);
+          }
+        }
+      break;
+    }
+  }
+
+  /**
+   * Remove any created nodes.
+   *
+   * @AfterScenario
+   */
+  public function cleanNodes() {
+    // Remove any nodes that were created.
+    foreach ($this->nodes as $node) {
+      $this->getDriver()->nodeDelete($node);
+    }
+    $this->nodes = array();
+  }
+
+  /**
+   * Remove any created users.
+   *
+   * @AfterScenario
+   */
+  public function cleanUsers() {
+    // Remove any users that were created.
+    if (!empty($this->users)) {
+      foreach ($this->users as $user) {
+        $this->getDriver()->userDelete($user);
+      }
+      $this->getDriver()->processBatch();
+      $this->users = array();
+      $this->user = FALSE;
+      if ($this->loggedIn()) {
+        $this->logout();
+      }
+    }
+  }
+
+  /**
+   * Remove any created terms.
+   *
+   * @AfterScenario
+   */
+  public function cleanTerms() {
+    // Remove any terms that were created.
+    foreach ($this->terms as $term) {
+      $this->getDriver()->termDelete($term);
+    }
+    $this->terms = array();
+  }
+
+  /**
+   * Remove any created roles.
+   *
+   * @AfterScenario
+   */
+  public function cleanRoles() {
+    // Remove any roles that were created.
+    foreach ($this->roles as $rid) {
+      $this->getDriver()->roleDelete($rid);
+    }
+    $this->roles = array();
+  }
+
+  /**
+   * Remove any created languages.
+   *
+   * @AfterScenario
+   */
+  public function cleanLanguages() {
+    // Delete any languages that were created.
+    foreach ($this->languages as $language) {
+      $this->getDriver()->languageDelete($language);
+      unset($this->languages[$language->langcode]);
+    }
+  }
+
+  /**
+   * Clear static caches.
+   *
+   * @AfterScenario @api
+   */
+  public function clearStaticCaches() {
+    $this->getDriver()->clearStaticCaches();
+  }
+
+  /**
+   * Dispatch scope hooks.
+   *
+   * @param string $scope
+   *   The entity scope to dispatch.
+   * @param \stdClass $entity
+   *   The entity.
+   */
+  protected function dispatchHooks($scopeType, \stdClass $entity) {
+    $fullScopeClass = 'Drupal\\DrupalExtension\\Hook\\Scope\\' . $scopeType;
+    $scope = new $fullScopeClass($this->getDrupal()->getEnvironment(), $this, $entity);
+    $callResults = $this->dispatcher->dispatchScopeHooks($scope);
+
+    // The dispatcher suppresses exceptions, throw them here if there are any.
+    foreach ($callResults as $result) {
+      if ($result->hasException()) {
+        $exception = $result->getException();
+        throw $exception;
+      }
+    }
+  }
+
+  /**
+   * Create a node.
+   *
+   * @return object
+   *   The created node.
+   */
+  public function nodeCreate($node) {
+    $this->dispatchHooks('BeforeNodeCreateScope', $node);
+    $this->parseEntityFields('node', $node);
+    $saved = $this->getDriver()->createNode($node);
+    $this->dispatchHooks('AfterNodeCreateScope', $saved);
+    $this->nodes[] = $saved;
+    return $saved;
+  }
+
+  /**
+   * Parse multi-value fields. Possible formats:
+   *    A, B, C
+   *    A - B, C - D, E - F
+   *
+   * @param string $entity_type
+   *   The entity type.
+   * @param \stdClass $entity
+   *   An object containing the entity properties and fields as properties.
+   */
+  public function parseEntityFields($entity_type, \stdClass $entity) {
+    $multicolumn_field = '';
+    $multicolumn_fields = array();
+
+    foreach (clone $entity as $field => $field_value) {
+      // Reset the multicolumn field if the field name does not contain a column.
+      if (strpos($field, ':') === FALSE) {
+        $multicolumn_field = '';
+      }
+      // Start tracking a new multicolumn field if the field name contains a ':'
+      // which is preceded by at least 1 character.
+      elseif (strpos($field, ':', 1) !== FALSE) {
+        list($multicolumn_field, $multicolumn_column) = explode(':', $field);
+      }
+      // If a field name starts with a ':' but we are not yet tracking a
+      // multicolumn field we don't know to which field this belongs.
+      elseif (empty($multicolumn_field)) {
+        throw new \Exception('Field name missing for ' . $field);
+      }
+      // Update the column name if the field name starts with a ':' and we are
+      // already tracking a multicolumn field.
+      else {
+        $multicolumn_column = substr($field, 1);
+      }
+
+      $is_multicolumn = $multicolumn_field && $multicolumn_column;
+      $field_name = $multicolumn_field ?: $field;
+      if ($this->getDriver()->isField($entity_type, $field_name)) {
+        // Split up multiple values in multi-value fields.
+        $values = array();
+        foreach (explode(', ', $field_value) as $key => $value) {
+          $columns = $value;
+          // Split up field columns if the ' - ' separator is present.
+          if (strstr($value, ' - ') !== FALSE) {
+            $columns = array();
+            foreach (explode(' - ', $value) as $column) {
+              // Check if it is an inline named column.
+              if (!$is_multicolumn && strpos($column, ': ', 1) !== FALSE) {
+                list ($key, $column) = explode(': ', $column);
+                $columns[$key] = $column;
+              }
+              else {
+                $columns[] = $column;
+              }
+            }
+          }
+          // Use the column name if we are tracking a multicolumn field.
+          if ($is_multicolumn) {
+            $multicolumn_fields[$multicolumn_field][$key][$multicolumn_column] = $columns;
+            unset($entity->$field);
+          }
+          else {
+            $values[] = $columns;
+          }
+        }
+        // Replace regular fields inline in the entity after parsing.
+        if (!$is_multicolumn) {
+          $entity->$field_name = $values;
+          // Don't specify any value if the step author has left it blank.
+          if ($field_value === '') {
+            unset($entity->$field_name);
+          }
+        }
+      }
+    }
+
+    // Add the multicolumn fields to the entity.
+    foreach ($multicolumn_fields as $field_name => $columns) {
+      // Don't specify any value if the step author has left it blank.
+      if (count(array_filter($columns, function ($var) {
+        return ($var !== '');
+      })) > 0) {
+        $entity->$field_name = $columns;
+      }
+    }
+  }
+
+  /**
+   * Create a user.
+   *
+   * @return object
+   *   The created user.
+   */
+  public function userCreate($user) {
+    $this->dispatchHooks('BeforeUserCreateScope', $user);
+    $this->parseEntityFields('user', $user);
+    $this->getDriver()->userCreate($user);
+    $this->dispatchHooks('AfterUserCreateScope', $user);
+    $this->users[$user->name] = $this->user = $user;
+    return $user;
+  }
+
+  /**
+   * Create a term.
+   *
+   * @return object
+   *   The created term.
+   */
+  public function termCreate($term) {
+    $this->dispatchHooks('BeforeTermCreateScope', $term);
+    $this->parseEntityFields('taxonomy_term', $term);
+    $saved = $this->getDriver()->createTerm($term);
+    $this->dispatchHooks('AfterTermCreateScope', $saved);
+    $this->terms[] = $saved;
+    return $saved;
+  }
+
+  /**
+   * Creates a language.
+   *
+   * @param \stdClass $language
+   *   An object with the following properties:
+   *   - langcode: the langcode of the language to create.
+   *
+   * @return object|FALSE
+   *   The created language, or FALSE if the language was already created.
+   */
+  public function languageCreate(\stdClass $language) {
+    $this->dispatchHooks('BeforeLanguageCreateScope', $language);
+    $language = $this->getDriver()->languageCreate($language);
+    if ($language) {
+      $this->dispatchHooks('AfterLanguageCreateScope', $language);
+      $this->languages[$language->langcode] = $language;
+    }
+    return $language;
+  }
+
+  /**
+   * Log-in the current user.
+   */
+  public function login() {
+    // Check if logged in.
+    if ($this->loggedIn()) {
+      $this->logout();
+    }
+
+    if (!$this->user) {
+      throw new \Exception('Tried to login without a user.');
+    }
+
+    $this->getSession()->visit($this->locatePath('/user'));
+    $element = $this->getSession()->getPage();
+    $element->fillField($this->getDrupalText('username_field'), $this->user->name);
+    $element->fillField($this->getDrupalText('password_field'), $this->user->pass);
+    $submit = $element->findButton($this->getDrupalText('log_in'));
+    if (empty($submit)) {
+      throw new \Exception(sprintf("No submit button at %s", $this->getSession()->getCurrentUrl()));
+    }
+
+    // Log in.
+    $submit->click();
+
+    if (!$this->loggedIn()) {
+      if (isset($this->user->role)) {
+        throw new \Exception(sprintf("Unable to determine if logged in because 'log_out' link cannot be found for user '%s' with role '%s'", $this->user->name, $this->user->role));
+      }
+      else {
+        throw new \Exception(sprintf("Unable to determine if logged in because 'log_out' link cannot be found for user '%s'", $this->user->name));
+      }
+    }
+  }
+
+  /**
+   * Logs the current user out.
+   */
+  public function logout() {
+    $this->getSession()->visit($this->locatePath('/user/logout'));
+  }
+
+  /**
+   * Determine if the a user is already logged in.
+   *
+   * @return boolean
+   *   Returns TRUE if a user is logged in for this session.
+   */
+  public function loggedIn() {
+    $session = $this->getSession();
+
+    // If the session has not been started yet, or no page has yet been loaded,
+    // then this is a brand new test session and the user is not logged in.
+    if (!$session->isStarted() || !$page = $session->getPage()) {
+      return FALSE;
+    }
+
+    // Look for a css selector to determine if a user is logged in.
+    // Default is the logged-in class on the body tag.
+    // Which should work with almost any theme.
+    try {
+      if ($page->has('css', $this->getDrupalSelector('logged_in_selector'))) {
+        return TRUE;
+      }
+    } catch (DriverException $e) {
+      // This test may fail if the driver did not load any site yet.
+    }
+
+    // Some themes do not add that class to the body, so lets check if the
+    // login form is displayed on /user/login.
+    $session->visit($this->locatePath('/user/login'));
+    if (!$page->has('css', $this->getDrupalSelector('login_form_selector'))) {
+      return TRUE;
+    }
+
+    $session->visit($this->locatePath('/'));
+
+    // As a last resort, if a logout link is found, we are logged in. While not
+    // perfect, this is how Drupal SimpleTests currently work as well.
+    return $page->findLink($this->getDrupalText('log_out'));
+  }
+
+  /**
+   * User with a given role is already logged in.
+   *
+   * @param string $role
+   *   A single role, or multiple comma-separated roles in a single string.
+   *
+   * @return boolean
+   *   Returns TRUE if the current logged in user has this role (or roles).
+   */
+  public function loggedInWithRole($role) {
+    return $this->loggedIn() && $this->user && isset($this->user->role) && $this->user->role == $role;
+  }
+
+}
diff --git a/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Definition/Proposal/AnnotatedDefinitionProposal.php b/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Definition/Proposal/AnnotatedDefinitionProposal.php
new file mode 100644 (file)
index 0000000..e57f713
--- /dev/null
@@ -0,0 +1,24 @@
+<?php
+/**
+ * @file
+ * Override the output of proposed methods to match Drupal coding standards.
+ */
+
+namespace Drupal\DrupalExtension\Definition\Proposal;
+
+use Behat\Behat\Definition\Proposal\AnnotatedDefinitionProposal as BaseAnnotatedDefinitionProposal;
+
+class AnnotatedDefinitionProposal extends BaseAnnotatedDefinitionProposal {
+  protected function generateSnippet($regex, $methodName, array $args) {
+    return sprintf(<<<PHP
+  /**
+   * @%s /^%s$/
+   */
+  public function %s(%s) {
+    throw new PendingException();
+  }
+PHP
+      , '%s', $regex, $methodName, implode(', ', $args)
+    );
+  }
+}
diff --git a/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Hook/Call/AfterNodeCreate.php b/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Hook/Call/AfterNodeCreate.php
new file mode 100644 (file)
index 0000000..b51bc32
--- /dev/null
@@ -0,0 +1,25 @@
+<?php
+
+namespace Drupal\DrupalExtension\Hook\Call;
+
+use Drupal\DrupalExtension\Hook\Scope\NodeScope;
+
+/**
+ * AfterNodeCreate hook class.
+ */
+class AfterNodeCreate extends EntityHook {
+
+  /**
+   * Initializes hook.
+   */
+  public function __construct($filterString, $callable, $description = null) {
+    parent::__construct(NodeScope::AFTER, $filterString, $callable, $description);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getName() {
+    return 'AfterNodeCreate';
+  }
+}
diff --git a/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Hook/Call/AfterTermCreate.php b/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Hook/Call/AfterTermCreate.php
new file mode 100644 (file)
index 0000000..50cf655
--- /dev/null
@@ -0,0 +1,26 @@
+<?php
+
+namespace Drupal\DrupalExtension\Hook\Call;
+
+use Drupal\DrupalExtension\Hook\Scope\TermScope;
+
+
+/**
+ * AfterTermCreate hook class.
+ */
+class AfterTermCreate extends EntityHook {
+
+  /**
+   * Initializes hook.
+   */
+  public function __construct($filterString, $callable, $description = null) {
+    parent::__construct(TermScope::AFTER, $filterString, $callable, $description);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getName() {
+    return 'AfterTermCreate';
+  }
+}
diff --git a/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Hook/Call/AfterUserCreate.php b/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Hook/Call/AfterUserCreate.php
new file mode 100644 (file)
index 0000000..c722d84
--- /dev/null
@@ -0,0 +1,25 @@
+<?php
+
+namespace Drupal\DrupalExtension\Hook\Call;
+
+use Drupal\DrupalExtension\Hook\Scope\UserScope;
+
+/**
+ * AfterUserCreate hook class.
+ */
+class AfterUserCreate extends EntityHook {
+
+  /**
+   * Initializes hook.
+   */
+  public function __construct($filterString, $callable, $description = null) {
+    parent::__construct(UserScope::AFTER, $filterString, $callable, $description);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getName() {
+    return 'AfterUserCreate';
+  }
+}
diff --git a/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Hook/Call/BeforeNodeCreate.php b/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Hook/Call/BeforeNodeCreate.php
new file mode 100644 (file)
index 0000000..822b803
--- /dev/null
@@ -0,0 +1,25 @@
+<?php
+
+namespace Drupal\DrupalExtension\Hook\Call;
+
+use Drupal\DrupalExtension\Hook\Scope\NodeScope;
+
+/**
+ * BeforeNodeCreate hook class.
+ */
+class BeforeNodeCreate extends EntityHook {
+
+  /**
+   * Initializes hook.
+   */
+  public function __construct($filterString, $callable, $description = null) {
+    parent::__construct(NodeScope::BEFORE, $filterString, $callable, $description);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getName() {
+    return 'BeforeNodeCreate';
+  }
+}
diff --git a/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Hook/Call/BeforeTermCreate.php b/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Hook/Call/BeforeTermCreate.php
new file mode 100644 (file)
index 0000000..199c14b
--- /dev/null
@@ -0,0 +1,25 @@
+<?php
+
+namespace Drupal\DrupalExtension\Hook\Call;
+
+use Drupal\DrupalExtension\Hook\Scope\TermScope;
+
+/**
+ * BeforeTermCreate hook class.
+ */
+class BeforeTermCreate extends EntityHook {
+
+  /**
+   * Initializes hook.
+   */
+  public function __construct($filterString, $callable, $description = null) {
+    parent::__construct(TermScope::BEFORE, $filterString, $callable, $description);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getName() {
+    return 'BeforeTermCreate';
+  }
+}
diff --git a/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Hook/Call/BeforeUserCreate.php b/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Hook/Call/BeforeUserCreate.php
new file mode 100644 (file)
index 0000000..bb1cf7c
--- /dev/null
@@ -0,0 +1,26 @@
+<?php
+
+namespace Drupal\DrupalExtension\Hook\Call;
+
+use Drupal\DrupalExtension\Hook\Scope\UserScope;
+
+/**
+ * BeforeUserCreate hook class.
+ */
+class BeforeUserCreate extends EntityHook {
+
+  /**
+   * Initializes hook.
+   */
+  public function __construct($filterString, $callable, $description = null) {
+    parent::__construct(UserScope::BEFORE, $filterString, $callable, $description);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getName() {
+    return 'BeforeUserCreate';
+  }
+
+}
diff --git a/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Hook/Call/EntityHook.php b/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Hook/Call/EntityHook.php
new file mode 100644 (file)
index 0000000..f36c06b
--- /dev/null
@@ -0,0 +1,22 @@
+<?php
+
+namespace Drupal\DrupalExtension\Hook\Call;
+
+use Behat\Testwork\Hook\Call\RuntimeFilterableHook;
+use Behat\Testwork\Hook\Scope\HookScope;
+
+/**
+ * Entity hook class.
+ */
+abstract class EntityHook extends RuntimeFilterableHook {
+
+  /**
+   * {@inheritDoc}
+   */
+  public function filterMatches(HookScope $scope) {
+    if (NULL === ($filterString = $this->getFilterString())) {
+      return TRUE;
+    }
+  }
+
+}
diff --git a/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Hook/Scope/AfterLanguageCreateScope.php b/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Hook/Scope/AfterLanguageCreateScope.php
new file mode 100644 (file)
index 0000000..ab2ba6f
--- /dev/null
@@ -0,0 +1,23 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\DrupalExtension\Hook\Scope\AfterLanguageCreateScope.
+ */
+namespace Drupal\DrupalExtension\Hook\Scope;
+
+/**
+ * Represents a language hook scope.
+ */
+final class AfterLanguageCreateScope extends LanguageScope {
+
+  /**
+   * Return the scope name.
+   *
+   * @return string
+   */
+  public function getName() {
+    return self::AFTER;
+  }
+
+}
diff --git a/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Hook/Scope/AfterNodeCreateScope.php b/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Hook/Scope/AfterNodeCreateScope.php
new file mode 100644 (file)
index 0000000..e89d45b
--- /dev/null
@@ -0,0 +1,24 @@
+<?php
+/**
+ * @file
+ * Entity scope.
+ */
+namespace Drupal\DrupalExtension\Hook\Scope;
+
+use Behat\Testwork\Hook\Scope\HookScope;
+
+/**
+ * Represents an Entity hook scope.
+ */
+final class AfterNodeCreateScope extends NodeScope {
+
+  /**
+   * Return the scope name.
+   *
+   * @return string
+   */
+  public function getName() {
+    return self::AFTER;
+  }
+
+}
diff --git a/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Hook/Scope/AfterTermCreateScope.php b/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Hook/Scope/AfterTermCreateScope.php
new file mode 100644 (file)
index 0000000..0f7dc22
--- /dev/null
@@ -0,0 +1,24 @@
+<?php
+/**
+ * @file
+ * Entity scope.
+ */
+namespace Drupal\DrupalExtension\Hook\Scope;
+
+use Behat\Testwork\Hook\Scope\HookScope;
+
+/**
+ * Represents an Entity hook scope.
+ */
+final class AfterTermCreateScope extends TermScope {
+
+  /**
+   * Return the scope name.
+   *
+   * @return string
+   */
+  public function getName() {
+    return self::AFTER;
+  }
+
+}
diff --git a/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Hook/Scope/AfterUserCreateScope.php b/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Hook/Scope/AfterUserCreateScope.php
new file mode 100644 (file)
index 0000000..c5cde4e
--- /dev/null
@@ -0,0 +1,24 @@
+<?php
+/**
+ * @file
+ * Entity scope.
+ */
+namespace Drupal\DrupalExtension\Hook\Scope;
+
+use Behat\Testwork\Hook\Scope\HookScope;
+
+/**
+ * Represents an Entity hook scope.
+ */
+final class AfterUserCreateScope extends UserScope {
+
+  /**
+   * Return the scope name.
+   *
+   * @return string
+   */
+  public function getName() {
+    return self::AFTER;
+  }
+
+}
diff --git a/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Hook/Scope/BaseEntityScope.php b/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Hook/Scope/BaseEntityScope.php
new file mode 100644 (file)
index 0000000..055e153
--- /dev/null
@@ -0,0 +1,72 @@
+<?php
+/**
+ * @file
+ * Entity scope.
+ */
+namespace Drupal\DrupalExtension\Hook\Scope;
+
+use Behat\Behat\Context\Context;
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\Hook\Scope\HookScope;
+
+/**
+ * Represents an Entity hook scope.
+ */
+abstract class BaseEntityScope implements EntityScope {
+
+  /**
+   * @var Environment
+   */
+  private $environment;
+
+  /**
+   * Context object.
+   *
+   * @var \Behat\Behat\Context\Context
+   */
+  private $context;
+
+  /**
+   * Entity object.
+   */
+  private $entity;
+
+  /**
+   * Initializes the scope.
+   */
+  public function __construct(Environment $environment, Context $context, $entity) {
+    $this->context = $context;
+    $this->entity = $entity;
+    $this->environment = $environment;
+  }
+
+  /**
+   * Returns the context.
+   *
+   * @return \Behat\Behat\Context\Context
+   */
+  public function getContext() {
+    return $this->context;
+  }
+
+  /**
+   * Returns the entity object.
+   */
+  public function getEntity() {
+    return $this->entity;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public function getEnvironment() {
+    return $this->environment;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public function getSuite() {
+    return $this->environment->getSuite();
+  }
+}
diff --git a/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Hook/Scope/BeforeLanguageCreateScope.php b/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Hook/Scope/BeforeLanguageCreateScope.php
new file mode 100644 (file)
index 0000000..2e88627
--- /dev/null
@@ -0,0 +1,23 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\DrupalExtension\Hook\Scope\BeforeLanguageCreateScope.
+ */
+namespace Drupal\DrupalExtension\Hook\Scope;
+
+/**
+ * Represents a language hook scope.
+ */
+final class BeforeLanguageCreateScope extends LanguageScope {
+
+  /**
+   * Returns the scope name.
+   *
+   * @return string
+   */
+  public function getName() {
+    return self::BEFORE;
+  }
+
+}
diff --git a/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Hook/Scope/BeforeNodeCreateScope.php b/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Hook/Scope/BeforeNodeCreateScope.php
new file mode 100644 (file)
index 0000000..9f2af23
--- /dev/null
@@ -0,0 +1,24 @@
+<?php
+/**
+ * @file
+ * Entity scope.
+ */
+namespace Drupal\DrupalExtension\Hook\Scope;
+
+use Behat\Testwork\Hook\Scope\HookScope;
+
+/**
+ * Represents an Entity hook scope.
+ */
+final class BeforeNodeCreateScope extends NodeScope {
+
+  /**
+   * Return the scope name.
+   *
+   * @return string
+   */
+  public function getName() {
+    return self::BEFORE;
+  }
+
+}
diff --git a/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Hook/Scope/BeforeTermCreateScope.php b/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Hook/Scope/BeforeTermCreateScope.php
new file mode 100644 (file)
index 0000000..bab9d72
--- /dev/null
@@ -0,0 +1,24 @@
+<?php
+/**
+ * @file
+ * Entity scope.
+ */
+namespace Drupal\DrupalExtension\Hook\Scope;
+
+use Behat\Testwork\Hook\Scope\HookScope;
+
+/**
+ * Represents an Entity hook scope.
+ */
+final class BeforeTermCreateScope extends TermScope {
+
+  /**
+   * Return the scope name.
+   *
+   * @return string
+   */
+  public function getName() {
+    return self::BEFORE;
+  }
+
+}
diff --git a/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Hook/Scope/BeforeUserCreateScope.php b/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Hook/Scope/BeforeUserCreateScope.php
new file mode 100644 (file)
index 0000000..c5b30a4
--- /dev/null
@@ -0,0 +1,24 @@
+<?php
+/**
+ * @file
+ * Entity scope.
+ */
+namespace Drupal\DrupalExtension\Hook\Scope;
+
+use Behat\Testwork\Hook\Scope\HookScope;
+
+/**
+ * Represents an Entity hook scope.
+ */
+final class BeforeUserCreateScope extends UserScope {
+
+  /**
+   * Return the scope name.
+   *
+   * @return string
+   */
+  public function getName() {
+    return self::BEFORE;
+  }
+
+}
diff --git a/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Hook/Scope/EntityScope.php b/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Hook/Scope/EntityScope.php
new file mode 100644 (file)
index 0000000..641ec01
--- /dev/null
@@ -0,0 +1,31 @@
+<?php
+/**
+ * @file
+ * Entity scope.
+ */
+namespace Drupal\DrupalExtension\Hook\Scope;
+
+use Behat\Testwork\Hook\Scope\HookScope;
+
+/**
+ * Represents an Entity hook scope.
+ */
+interface EntityScope extends HookScope {
+
+  const BEFORE = 'entity.create.before';
+  const AFTER = 'entity.create.after';
+
+  /**
+   * Returns the context.
+   *
+   * @return \Behat\Behat\Context\Context
+   */
+  public function getContext();
+
+  /**
+   * Returns scope entity.
+   *
+   * @return StepNode
+   */
+  public function getEntity();
+}
diff --git a/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Hook/Scope/LanguageScope.php b/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Hook/Scope/LanguageScope.php
new file mode 100644 (file)
index 0000000..002d330
--- /dev/null
@@ -0,0 +1,17 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\DrupalExtension\Hook\Scope\LanguageScope.
+ */
+namespace Drupal\DrupalExtension\Hook\Scope;
+
+/**
+ * Represents the LanguageScope object.
+ */
+abstract class LanguageScope extends BaseEntityScope {
+
+  const BEFORE = 'language.create.before';
+  const AFTER = 'language.create.after';
+
+}
diff --git a/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Hook/Scope/NodeScope.php b/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Hook/Scope/NodeScope.php
new file mode 100644 (file)
index 0000000..a4ee625
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+/**
+ * @file
+ * Node scope.
+ */
+namespace Drupal\DrupalExtension\Hook\Scope;
+
+use Behat\Behat\Context\Context;
+use Behat\Testwork\Hook\Scope\HookScope;
+
+/**
+ * Represents an Entity hook scope.
+ */
+abstract class NodeScope extends BaseEntityScope {
+
+  const BEFORE = 'node.create.before';
+  const AFTER = 'node.create.after';
+
+}
diff --git a/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Hook/Scope/TermScope b/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Hook/Scope/TermScope
new file mode 100644 (file)
index 0000000..5e8b93b
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+/**
+ * @file
+ * User scope.
+ */
+namespace Drupal\DrupalExtension\Hook\Scope;
+
+use Behat\Behat\Context\Context;
+use Behat\Testwork\Hook\Scope\HookScope;
+
+/**
+ * Represents an Entity hook scope.
+ */
+abstract class UserScope extends BaseEntityScope {
+
+  const BEFORE = 'user.create.before';
+  const AFTER = 'user.create.after';
+
+}
diff --git a/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Hook/Scope/TermScope.php b/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Hook/Scope/TermScope.php
new file mode 100644 (file)
index 0000000..531f7d7
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+/**
+ * @file
+ * Term scope.
+ */
+namespace Drupal\DrupalExtension\Hook\Scope;
+
+use Behat\Behat\Context\Context;
+use Behat\Testwork\Hook\Scope\HookScope;
+
+/**
+ * Represents an Entity hook scope.
+ */
+abstract class TermScope extends BaseEntityScope {
+
+  const BEFORE = 'term.create.before';
+  const AFTER = 'term.create.after';
+
+}
diff --git a/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Hook/Scope/UserScope.php b/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Hook/Scope/UserScope.php
new file mode 100644 (file)
index 0000000..5e8b93b
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+/**
+ * @file
+ * User scope.
+ */
+namespace Drupal\DrupalExtension\Hook\Scope;
+
+use Behat\Behat\Context\Context;
+use Behat\Testwork\Hook\Scope\HookScope;
+
+/**
+ * Represents an Entity hook scope.
+ */
+abstract class UserScope extends BaseEntityScope {
+
+  const BEFORE = 'user.create.before';
+  const AFTER = 'user.create.after';
+
+}
diff --git a/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Listener/DriverListener.php b/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Listener/DriverListener.php
new file mode 100644 (file)
index 0000000..89e0abe
--- /dev/null
@@ -0,0 +1,79 @@
+<?php
+
+namespace Drupal\DrupalExtension\Listener;
+
+use Behat\Behat\EventDispatcher\Event\ExampleTested;
+use Behat\Behat\EventDispatcher\Event\ScenarioLikeTested;
+use Behat\Behat\EventDispatcher\Event\ScenarioTested;
+
+use Drupal\DrupalDriverManager;
+
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+
+/**
+ * Drupal driver listener.
+ *
+ * Determines which Drupal driver to use for a given scenario or outline.
+ */
+class DriverListener implements EventSubscriberInterface {
+
+  /**
+   * Drupal driver manager.
+   *
+   * @var \Drupal\DrupalDriverManager
+   */
+  private $drupal;
+
+  /**
+   * Test parameters.
+   *
+   * @var array
+   */
+  private $parameters;
+
+  public function __construct(DrupalDriverManager $drupal, array $parameters) {
+    $this->drupal = $drupal;
+    $this->parameters = $parameters;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public static function getSubscribedEvents() {
+    return array(
+      ScenarioTested::BEFORE => array('prepareDefaultDrupalDriver', 11),
+      ExampleTested::BEFORE => array('prepareDefaultDrupalDriver', 11),
+    );
+  }
+
+  /**
+   * Configures default Drupal driver to use before each scenario or outline.
+   *
+   * `@api` tagged scenarios will get the `api_driver` as the default driver.
+   *
+   * Other scenarios get the `default_driver` as the default driver.
+   *
+   * @param ScenarioEvent|OutlineEvent $event
+   */
+  public function prepareDefaultDrupalDriver($event) {
+    $feature = $event->getFeature();
+    $scenario = $event instanceof ScenarioLikeTested ? $event->getScenario() : $event->getOutline();
+
+    // Get the default driver.
+    $driver = $this->parameters['default_driver'];
+
+    foreach (array_merge($feature->getTags(), $scenario->getTags()) as $tag) {
+      if (!empty($this->parameters[$tag . '_driver'])) {
+        $driver = $this->parameters[$tag . '_driver'];
+      }
+    }
+
+    // Set the default driver.
+    $this->drupal->setDefaultDriverName($driver);
+
+    // Set the environment.
+    $environment = $event->getEnvironment();
+    $this->drupal->setEnvironment($environment);
+  }
+
+}
diff --git a/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Selector/RegionSelector.php b/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Selector/RegionSelector.php
new file mode 100644 (file)
index 0000000..3db98d2
--- /dev/null
@@ -0,0 +1,36 @@
+<?php
+
+namespace Drupal\DrupalExtension\Selector;
+
+use Behat\Mink\Selector\SelectorInterface;
+use Behat\Mink\Selector\CssSelector;
+
+/**
+ * Custom "region" selector to help select Drupal regions
+ */
+class RegionSelector implements SelectorInterface {
+  private $cssSelector;
+
+  private $regionMap;
+
+  public function __construct(CssSelector $cssSelector, array $regionMap) {
+    $this->cssSelector = $cssSelector;
+    $this->regionMap = $regionMap;
+  }
+
+  /**
+   * Translates provided locator into XPath.
+   *
+   * @param string $region
+   * @return string
+   * @throws \InvalidArgumentException
+   */
+  public function translateToXPath($region) {
+    if (!isset($this->regionMap[$region])) {
+      throw new \InvalidArgumentException(sprintf('The "%s" region isn\'t configured!', $region));
+    }
+    $css = $this->regionMap[$region];
+
+    return $this->cssSelector->translateToXPath($css);
+  }
+}
diff --git a/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/ServiceContainer/DrupalExtension.php b/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/ServiceContainer/DrupalExtension.php
new file mode 100644 (file)
index 0000000..9d532bf
--- /dev/null
@@ -0,0 +1,293 @@
+<?php
+
+namespace Drupal\DrupalExtension\ServiceContainer;
+
+use Behat\Behat\Context\ServiceContainer\ContextExtension;
+use Behat\Testwork\ServiceContainer\Extension as ExtensionInterface;
+use Behat\Testwork\ServiceContainer\ExtensionManager;
+use Behat\Testwork\ServiceContainer\ServiceProcessor;
+use Drupal\DrupalExtension\Compiler\DriverPass;
+use Drupal\DrupalExtension\Compiler\EventSubscriberPass;
+use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
+use Symfony\Component\Config\FileLocator;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Definition;
+use Symfony\Component\DependencyInjection\Loader\FileLoader;
+use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
+
+class DrupalExtension implements ExtensionInterface {
+
+  /**
+   * Extension configuration ID.
+   */
+  const DRUPAL_ID = 'drupal';
+
+  /**
+   * Selectors handler ID.
+   */
+  const SELECTORS_HANDLER_ID = 'drupal.selectors_handler';
+
+  /**
+   * @var ServiceProcessor
+   */
+  private $processor;
+
+  /**
+   * Initializes compiler pass.
+   *
+   * @param null|ServiceProcessor $processor
+   */
+  public function __construct(ServiceProcessor $processor = null) {
+    $this->processor = $processor ? : new ServiceProcessor();
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public function getConfigKey() {
+    return self::DRUPAL_ID;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public function initialize(ExtensionManager $extensionManager) {
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public function load(ContainerBuilder $container, array $config) {
+    $loader = new YamlFileLoader($container, new FileLocator(__DIR__ . '/config'));
+    $loader->load('services.yml');
+    $container->setParameter('drupal.drupal.default_driver', $config['default_driver']);
+
+    $this->loadParameters($container, $config);
+
+    // Setup any drivers if requested.
+    $this->loadBlackbox($loader, $config);
+    $this->loadDrupal($loader, $container, $config);
+    $this->loadDrush($loader, $container, $config);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public function process(ContainerBuilder $container) {
+    $this->processDriverPass($container);
+    $this->processEventSubscriberPass($container);
+    $this->processEnvironmentReaderPass($container);
+    $this->processClassGenerator($container);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public function configure(ArrayNodeDefinition $builder) {
+    $builder->
+      children()->
+        scalarNode('default_driver')->
+          defaultValue('blackbox')->
+          info('Use "blackbox" to test remote site. See "api_driver" for easier integration.')->
+        end()->
+        scalarNode('api_driver')->
+          defaultValue('drush')->
+          info('Bootstraps drupal through "drupal8" or "drush".')->
+        end()->
+        scalarNode('drush_driver')->
+          defaultValue('drush')->
+        end()->
+        arrayNode('region_map')->
+          info("Targeting content in specific regions can be accomplished once those regions have been defined." . PHP_EOL
+            . '  My region: "#css-selector"' . PHP_EOL
+            . '  Content: "#main .region-content"'. PHP_EOL
+            . '  Right sidebar: "#sidebar-second"'. PHP_EOL
+          )->
+          useAttributeAsKey('key')->
+          prototype('variable')->
+          end()->
+        end()->
+        arrayNode('text')->
+          info(
+              'Text strings, such as Log out or the Username field can be altered via behat.yml if they vary from the default values.' . PHP_EOL
+            . '  log_out: "Sign out"' . PHP_EOL
+            . '  log_in: "Sign in"' . PHP_EOL
+            . '  password_field: "Enter your password"' . PHP_EOL
+            . '  username_field: "Nickname"'
+          )->
+          addDefaultsIfNotSet()->
+          children()->
+            scalarNode('log_in')->
+              defaultValue('Log in')->
+            end()->
+            scalarNode('log_out')->
+              defaultValue('Log out')->
+            end()->
+            scalarNode('password_field')->
+              defaultValue('Password')->
+            end()->
+            scalarNode('username_field')->
+              defaultValue('Username')->
+            end()->
+          end()->
+        end()->
+        arrayNode('selectors')->
+          addDefaultsIfNotSet()->
+          children()->
+            scalarNode('message_selector')->end()->
+            scalarNode('error_message_selector')->end()->
+            scalarNode('success_message_selector')->end()->
+            scalarNode('warning_message_selector')->end()->
+            scalarNode('login_form_selector')->
+              defaultValue('form#user-login')->
+            end()->
+            scalarNode('logged_in_selector')->
+              defaultValue('body.logged-in,body.user-logged-in')->
+            end()->
+          end()->
+        end()->
+        // Drupal drivers.
+        arrayNode('blackbox')->
+        end()->
+        arrayNode('drupal')->
+          children()->
+            scalarNode('drupal_root')->end()->
+          end()->
+        end()->
+        arrayNode('drush')->
+          children()->
+            scalarNode('alias')->end()->
+            scalarNode('binary')->defaultValue('drush')->end()->
+            scalarNode('root')->end()->
+            scalarNode('global_options')->end()->
+          end()->
+        end()->
+        // Subcontext paths.
+        arrayNode('subcontexts')->
+          info(
+              'The Drupal Extension is capable of discovering additional step-definitions provided by subcontexts.' . PHP_EOL
+            . 'Module authors can provide these in files following the naming convention of foo.behat.inc. Once that module is enabled, the Drupal Extension will load these.' . PHP_EOL
+            . PHP_EOL
+            . 'Additional subcontexts can be loaded by either placing them in the bootstrap directory (typically features/bootstrap) or by adding them to behat.yml.'
+          )->
+          addDefaultsIfNotSet()->
+          children()->
+            arrayNode('paths')->
+              info(
+                '- /path/to/additional/subcontexts' . PHP_EOL
+              . '- /another/path'
+              )->
+              useAttributeAsKey('key')->
+              prototype('variable')->end()->
+            end()->
+            scalarNode('autoload')->
+              defaultValue(TRUE)->
+            end()->
+          end()->
+        end()->
+      end()->
+    end();
+  }
+
+  /**
+   * Load test parameters.
+   */
+  private function loadParameters(ContainerBuilder $container, array $config) {
+    // Store config in parameters array to be passed into the DrupalContext.
+    $drupal_parameters = array();
+    foreach ($config as $key => $value) {
+      $drupal_parameters[$key] = $value;
+    }
+    $container->setParameter('drupal.parameters', $drupal_parameters);
+
+    $container->setParameter('drupal.region_map', $config['region_map']);
+  }
+
+  /**
+   * Load the blackbox driver.
+   */
+  private function loadBlackBox(FileLoader $loader, array $config) {
+    // Always include the blackbox driver.
+    $loader->load('drivers/blackbox.yml');
+  }
+
+  /**
+   * Load the Drupal driver.
+   */
+  private function loadDrupal(FileLoader $loader, ContainerBuilder $container, array $config) {
+    if (isset($config['drupal'])) {
+      $loader->load('drivers/drupal.yml');
+      $container->setParameter('drupal.driver.drupal.drupal_root', $config['drupal']['drupal_root']);
+    }
+  }
+
+  /**
+   * Load the Drush driver.
+   */
+  private function loadDrush(FileLoader $loader, ContainerBuilder $container, array $config) {
+    if (isset($config['drush'])) {
+      $loader->load('drivers/drush.yml');
+      if (!isset($config['drush']['alias']) && !isset($config['drush']['root'])) {
+        throw new \RuntimeException('Drush `alias` or `root` path is required for the Drush driver.');
+      }
+      $config['drush']['alias'] = isset($config['drush']['alias']) ? $config['drush']['alias'] : FALSE;
+      $container->setParameter('drupal.driver.drush.alias', $config['drush']['alias']);
+
+      $config['drush']['binary'] = isset($config['drush']['binary']) ? $config['drush']['binary'] : 'drush';
+      $container->setParameter('drupal.driver.drush.binary', $config['drush']['binary']);
+
+      $config['drush']['root'] = isset($config['drush']['root']) ? $config['drush']['root'] : FALSE;
+      $container->setParameter('drupal.driver.drush.root', $config['drush']['root']);
+
+      // Set global arguments.
+      $this->setDrushOptions($container, $config);
+    }
+  }
+
+  /**
+   * Set global drush arguments.
+   */
+  private function setDrushOptions(ContainerBuilder $container, array $config) {
+    if (isset($config['drush']['global_options'])) {
+      $definition = $container->getDefinition('drupal.driver.drush');
+      $definition->addMethodCall('setArguments', array($config['drush']['global_options']));
+    }
+  }
+
+  /**
+   * Process the Driver Pass.
+   */
+  private function processDriverPass(ContainerBuilder $container) {
+    $driverPass = new DriverPass();
+    $driverPass->process($container);
+  }
+
+  /**
+   * Process the Event Subscriber Pass.
+   */
+  private function processEventSubscriberPass(ContainerBuilder $container) {
+    $eventSubscriberPass = new EventSubscriberPass();
+    $eventSubscriberPass->process($container);
+  }
+
+  /**
+   * Process the Environment Reader pass.
+   */
+  private function processEnvironmentReaderPass(ContainerBuilder $container) {
+    // Register Behat context readers.
+    $references = $this->processor->findAndSortTaggedServices($container, ContextExtension::READER_TAG);
+    $definition = $container->getDefinition('drupal.context.environment.reader');
+
+    foreach ($references as $reference) {
+      $definition->addMethodCall('registerContextReader', array($reference));
+    }
+  }
+
+  /**
+   * Switch to custom class generator.
+   */
+  private function processClassGenerator(ContainerBuilder $container) {
+    $definition = new Definition('Drupal\DrupalExtension\Context\ContextClass\ClassGenerator');
+    $container->setDefinition(ContextExtension::CLASS_GENERATOR_TAG . '.simple', $definition);
+  }
+}
diff --git a/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/ServiceContainer/config/drivers/blackbox.yml b/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/ServiceContainer/config/drivers/blackbox.yml
new file mode 100644 (file)
index 0000000..8843d34
--- /dev/null
@@ -0,0 +1,8 @@
+parameters:
+  drupal.driver.blackbox.class: Drupal\Driver\BlackboxDriver
+
+services:
+  drupal.driver.blackbox:
+    class: %drupal.driver.blackbox.class%
+    tags:
+      - { name: drupal.driver, alias: blackbox }
diff --git a/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/ServiceContainer/config/drivers/drupal.yml b/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/ServiceContainer/config/drivers/drupal.yml
new file mode 100644 (file)
index 0000000..abe243d
--- /dev/null
@@ -0,0 +1,46 @@
+parameters:
+  drupal.driver.drupal.class: Drupal\Driver\DrupalDriver
+
+  # Random generator.
+  drupal.random.class: Drupal\Component\Utility\Random
+
+  # Core controllers.
+  drupal.driver.cores.6.class: Drupal\Driver\Cores\Drupal6
+  drupal.driver.cores.7.class: Drupal\Driver\Cores\Drupal7
+  drupal.driver.cores.8.class: Drupal\Driver\Cores\Drupal8
+
+services:
+  drupal.driver.random:
+    class: %drupal.random.class%
+  drupal.driver.drupal:
+    class: %drupal.driver.drupal.class%
+    arguments:
+      - %drupal.driver.drupal.drupal_root%
+      - %mink.base_url%
+      - "@drupal.driver.random"
+    tags:
+      - { name: drupal.driver, alias: drupal }
+  drupal.driver.cores.6:
+    class: %drupal.driver.cores.6.class%
+    tags:
+      - { name: drupal.core, alias: 6 }
+    arguments:
+      - %drupal.driver.drupal.drupal_root%
+      - %mink.base_url%
+      - "@drupal.driver.random"
+  drupal.driver.cores.7:
+    class: %drupal.driver.cores.7.class%
+    tags:
+      - { name: drupal.core, alias: 7 }
+    arguments:
+      - %drupal.driver.drupal.drupal_root%
+      - %mink.base_url%
+      - "@drupal.driver.random"
+  drupal.driver.cores.8:
+    class: %drupal.driver.cores.8.class%
+    tags:
+      - { name: drupal.core, alias: 8 }
+    arguments:
+      - %drupal.driver.drupal.drupal_root%
+      - %mink.base_url%
+      - "@drupal.driver.random"
diff --git a/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/ServiceContainer/config/drivers/drush.yml b/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/ServiceContainer/config/drivers/drush.yml
new file mode 100644 (file)
index 0000000..26bf173
--- /dev/null
@@ -0,0 +1,18 @@
+parameters:
+  drupal.driver.drush.class: Drupal\Driver\DrushDriver
+
+  # Random generator.
+  drupal.random.class: Drupal\Component\Utility\Random
+
+services:
+  drupal.driver.random:
+    class: %drupal.random.class%
+  drupal.driver.drush:
+    class: %drupal.driver.drush.class%
+    arguments:
+      - %drupal.driver.drush.alias%
+      - %drupal.driver.drush.root%
+      - %drupal.driver.drush.binary%
+      - "@drupal.driver.random"
+    tags:
+      - { name: drupal.driver, alias: drush }
diff --git a/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/ServiceContainer/config/services.yml b/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/ServiceContainer/config/services.yml
new file mode 100644 (file)
index 0000000..34c3543
--- /dev/null
@@ -0,0 +1,74 @@
+parameters:
+  # This overrides the class for the core version of this class
+  behat.definition.proposal.annotated.class: Drupal\DrupalExtension\Definition\Proposal\AnnotatedDefinitionProposal
+
+  # Drupal driver manager.
+  drupal.drupal.class: Drupal\DrupalDriverManager
+  drupal.drupal.default_session: blackbox
+  drupal.drupal.api_driver: drush
+
+  # Random generator.
+  drupal.random.class: Drupal\Component\Utility\Random
+
+  # Context initializer.
+  drupal.context.initializer.class: Drupal\DrupalExtension\Context\Initializer\DrupalAwareInitializer
+
+  # Environment reader.
+  drupal.context.environment.reader.class: Drupal\DrupalExtension\Context\Environment\Reader\Reader
+
+  # Event listeners.
+  drupal.listener.drivers.class: Drupal\DrupalExtension\Listener\DriverListener
+
+  # Hook loader.
+  drupal.context.annotation.reader.class: Drupal\DrupalExtension\Context\Annotation\Reader
+
+  # Region selector class.
+  drupal.context.region_selector.class: Drupal\DrupalExtension\Selector\RegionSelector
+
+  # Parameters.
+  drupal.parameters: {}
+  drupal.region_map: {}
+
+services:
+  drupal.drupal:
+    class: %drupal.drupal.class%
+    arguments:
+      - {}
+      - "@drupal.random"
+  drupal.random:
+    class: %drupal.random.class%
+  drupal.context.initializer:
+    class: %drupal.context.initializer.class%
+    arguments:
+      - "@drupal.drupal"
+      - %drupal.parameters%
+      - "@hook.dispatcher"
+    tags:
+      - { name: context.initializer }
+  drupal.context.environment.reader:
+    class: %drupal.context.environment.reader.class%
+    arguments:
+      - "@drupal.drupal"
+      - %drupal.parameters%
+    tags:
+      - { name: environment.reader }
+  drupal.context.loader.annotated:
+    class: %drupal.context.annotation.reader.class%
+    arguments:
+    tags:
+      - { name: context.annotation_reader }
+  drupal.listener.driver:
+    class: %drupal.listener.drivers.class%
+    arguments:
+      - "@drupal.drupal"
+      - %drupal.parameters%
+    tags:
+      - { name: event_dispatcher.subscriber, priority: 0 }
+  drupal.region_selector:
+    class: %drupal.context.region_selector.class%
+    arguments:
+      # inject the CSSSelector
+      - "@mink.selector.css"
+      - %drupal.region_map%
+    tags:
+      - { name: mink.selector, alias: region }
diff --git a/vendor/instaclick/php-webdriver/.coveralls.yml b/vendor/instaclick/php-webdriver/.coveralls.yml
new file mode 100644 (file)
index 0000000..6b74c21
--- /dev/null
@@ -0,0 +1 @@
+src_dir: lib
diff --git a/vendor/instaclick/php-webdriver/.gitignore b/vendor/instaclick/php-webdriver/.gitignore
new file mode 100644 (file)
index 0000000..fbd8148
--- /dev/null
@@ -0,0 +1,7 @@
+build/
+logs/
+nbproject/
+vendor/
+.idea/
+composer.lock
+composer.phar
diff --git a/vendor/instaclick/php-webdriver/.travis.yml b/vendor/instaclick/php-webdriver/.travis.yml
new file mode 100644 (file)
index 0000000..941a80a
--- /dev/null
@@ -0,0 +1,32 @@
+dist: trusty
+
+language: php
+
+php:
+  # - 5.3
+  - 5.4
+  - 5.5
+  - 5.6
+  - 7.0
+  - 7.1
+  - hhvm
+
+#before_install:
+#  # This update is mandatory or the 'apt-get install' calls following will fail
+#  - sudo apt-get update -qq
+#  - sudo apt-get install -y apache2 libapache2-mod-fastcgi
+#  # start the xvfb display needed for firefox
+#  - export DISPLAY=:99.0
+#  - sh -e /etc/init.d/xvfb start
+#  - sh ./test/CI/Travis/setup_selenium.sh
+#  - sh ./test/CI/Travis/setup_apache.sh
+
+before_script:
+  - composer install --no-interaction
+
+script:
+  - mkdir -p build/logs
+  - vendor/bin/phpunit --coverage-clover build/logs/clover.xml --group Unit
+
+after_script:
+  - vendor/bin/coveralls
diff --git a/vendor/instaclick/php-webdriver/README.md b/vendor/instaclick/php-webdriver/README.md
new file mode 100644 (file)
index 0000000..ad5ef3a
--- /dev/null
@@ -0,0 +1,25 @@
+WebDriver for Selenium 2
+========================
+This WebDriver client implementation is based on Facebook's [php-webdriver](https://github.com/facebook/php-webdriver/) project by Justin Bishop.
+
+Distinguishing features:
+* Up-to-date with [Selenium 2 JSON Wire Protocol](https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol) (including WebDriver commands yet to be documented).
+* In the *master* branch, class names and file organization follow PSR-0 conventions for php 5.3+ namespaces.
+* Coding style follows PSR-1, PSR-2, and Symfony2 conventions.
+* Auto-generate API documentation via [phpDocumentor 2.x](http://phpdoc.org/).
+
+[![Build Status](https://travis-ci.org/instaclick/php-webdriver.png)](https://travis-ci.org/instaclick/php-webdriver)
+[![Coverage Status](https://coveralls.io/repos/instaclick/php-webdriver/badge.png)](https://coveralls.io/r/instaclick/php-webdriver)
+[![Dependency Status](https://www.versioneye.com/php/instaclick:php-webdriver/badge.png)](https://www.versioneye.com/php/instaclick:php-webdriver/)
+
+[![Latest Stable Version](https://poser.pugx.org/instaclick/php-webdriver/v/stable.png)](https://packagist.org/packages/instaclick/php-webdriver)
+[![Total Downloads](https://poser.pugx.org/instaclick/php-webdriver/downloads.png)](https://packagist.org/packages/instaclick/php-webdriver)
+
+Downloads
+=========
+* [Packagist (dev-master)](http://packagist.org/packages/instaclick/php-webdriver)
+* [Github](https://github.com/instaclick/php-webdriver)
+
+Notes
+=====
+* The *5.2.x* branch is no longer maintained. This branch features class names and file re-organization that follow PEAR/ZF1 conventions. Bug fixes and enhancements from the master branch likely won't be backported.
diff --git a/vendor/instaclick/php-webdriver/composer.json b/vendor/instaclick/php-webdriver/composer.json
new file mode 100644 (file)
index 0000000..b0c5855
--- /dev/null
@@ -0,0 +1,43 @@
+{
+    "name": "instaclick/php-webdriver",
+    "type": "library",
+    "description": "PHP WebDriver for Selenium 2",
+    "keywords": [
+        "selenium",
+        "webdriver",
+        "webtest",
+        "browser"
+    ],
+    "homepage": "http://instaclick.com/",
+    "license": "Apache-2.0",
+    "authors": [
+        {
+            "name": "Justin Bishop",
+            "email": "jubishop@gmail.com",
+            "role": "Developer"
+        },
+        {
+            "name": "Anthon Pang",
+            "email": "apang@softwaredevelopment.ca",
+            "role": "Fork Maintainer"
+        }
+    ],
+    "require": {
+        "php": ">=5.3.2",
+        "ext-curl": "*"
+    },
+    "require-dev": {
+        "satooshi/php-coveralls": "^1.0||^2.0",
+        "phpunit/phpunit": "^4.8"
+    },
+    "autoload": {
+        "psr-0": {
+            "WebDriver": "lib/"
+       }
+    },
+    "extra": {
+        "branch-alias": {
+            "dev-master": "1.4.x-dev"
+        }
+    }
+}
diff --git a/vendor/instaclick/php-webdriver/doc/README.md b/vendor/instaclick/php-webdriver/doc/README.md
new file mode 100644 (file)
index 0000000..c5f366a
--- /dev/null
@@ -0,0 +1,208 @@
+php-webdriver -- A very thin wrapper of WebDriver
+=================================================
+
+##  DESCRIPTION
+
+This client aims to be as thin as possible, abusing the dynamic nature of PHP to allow almost all API calls to be a direct transformation of what is defined in the WebDriver protocol itself.
+
+Most clients require you to first read the protocol to see what's possible, then study the client itself to see how to call it.  This hopes to eliminate the latter step, and invites you to rely almost exclusively on https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol
+
+Each command is just the name of a function call, and each additional path is just another chained function call.  The function parameter is then either an array() if the command takes JSON parameters, or an individual primitive if it takes a URL parameter.
+
+The function's return value is exactly what is returned from the server as part of the protocol definition.  If an error is returned, the function will throw the appropriate WebDriverException instance.
+
+##  GETTING STARTED
+
+*   All you need as the server for this client is the selenium-server-standalone-#.jar file provided here:  http://www.seleniumhq.org/download/
+
+*   Download and run that file, replacing # with the current server version.
+
+        java -jar selenium-server-standalone-#.jar
+
+*   Then when you create a session, be sure to pass the url to where your server is running.
+
+        // This would be the url of the host running the server-standalone.jar
+        $wd_host = 'http://localhost:4444/wd/hub'; // this is the default
+        $web_driver = new WebDriver($wd_host);
+
+        // First param to session() is the 'browserName' (default = 'firefox')
+        // Second param is a JSON object of additional 'desiredCapabilities'
+
+        // POST /session
+        $session = $web_driver->session('firefox');
+
+* See also [wiki page for launching different browsers](https://github.com/facebook/php-webdriver/wiki/Launching-Browsers).
+
+##  SIMPLE EXAMPLES
+
+### Note that all of these match the Protocol exactly
+*   Move to a specific spot on the screen
+
+        // POST /session/:sessionId/moveto
+        $session->moveto(array('xoffset' => 3, 'yoffset' => 300));
+
+*   Get the current url
+
+        // GET /session/:sessionId/url
+        $session->url();
+
+*   Change focus to another frame
+
+        // POST /session/:sessionId/frame
+        $session->frame(array('id' => 'some_frame_id'));
+
+*   Get a list of window handles for all open windows
+
+        // GET /session/:sessionId/window_handles
+        $session->window_handles();
+
+*   Accept the currently displayed alert dialog
+
+        // POST /session/:sessionId/accept_alert
+        $session->accept_alert();
+
+*   Change asynchronous script timeout
+
+        // POST /session/:sessionId/timeouts/async_script
+        $session->timeouts()->async_script(array('ms' => 2000));
+
+*   Doubleclick an element on a touch screen
+
+        // POST session/:sessionId/touch/doubleclick
+        $session->touch()->doubleclick(array('element' => $element->getID())
+
+*   Check if two elements are equal
+
+        // GET /session/:sessionId/element/:id/equals/:other
+        $element->equals($other_element->getID()))
+
+*   Get value of a css property on element
+
+        // GET /session/:sessionId/element/:id/css/:propertyName
+        $element->css($property_name)
+
+## 'GET', 'POST', or 'DELETE' to the same command examples
+
+### When you can do multiple http methods for the same command, call the command directly for the 'GET', and prepend the http method for the 'POST' or 'DELETE'.
+
+*   Set landscape orientation with 'POST'
+
+        // POST /session/:sessionId/orientation
+        $session->postOrientation(array('orientation' => 'LANDSCAPE'));
+
+*   Get landscape orientation with normal 'GET'
+
+        // GET /session/:sessionId/orientation
+        $session->orientation();
+
+*   Set size of window that has $window_handle with 'POST'
+
+        // If excluded, $window_handle defaults to 'current'
+        // POST /session/:sessionId/window/:windowHandle/size
+        $session
+          ->window($window_handle)
+          ->postSize(array('width' => 10, 'height' => 10));
+
+*   Get current window size with 'GET'
+
+        // GET /session/:sessionId/window/:windowHandle/size
+        $session->window()->size();
+
+* Send keystrokes to an element with 'POST'
+
+        // POST /session/:sessionId/element/:id/value
+        // getValue() is deprecated; use postValue($json) or value($json)
+        $element->postValue(array("value" => str_split('some text to send to element')));
+
+## Some unavoidable exceptions to direct protocol translation.
+
+*   Opening pages
+
+        // POST /session/:sessionId/url
+        $session->open('http://www.facebook.com');
+
+*   Dealing with the session
+
+        // DELETE /session/:sessionId
+        $session->close();
+
+        // GET /session/:sessionId
+        $session->capabilities();
+        
+*   To find elements
+
+        // POST /session/:sessionId/element
+        $element = $session->element($using, $value);
+
+        // POST /session/:sessionId/elements
+        $session->elements($using, $value);
+
+        // POST /session/:sessionId/element/:id/element
+        $element->element($using, $value);
+
+        // POST /session/:sessionId/element/:id/elements
+        $element->elements($using, $value);
+
+*   To get the active element
+
+        // POST /session/:sessionId/element/active
+        $session->activeElement();
+
+*   To manipulate cookies
+
+        // GET /session/:sessionId/cookie
+        $session->getAllCookies();
+
+        // POST /session/:sessionId/cookie
+        $session->setCookie($cookie_json);
+
+        // DELETE /session/:sessionId/cookie
+        $session->deleteAllCookies()
+
+        // DELETE /session/:sessionId/cookie/:name
+        $session->deleteCookie($name)
+
+*   To manipulate windows
+
+        // POST /session/:sessionId/window
+        $session->focusWindow($window_handle);
+
+        // DELETE /session/:sessionId/window
+        $session->deleteWindow();
+
+## More esoteric examples
+
+*   To set curl options (e.g., timeout and proxy settings)
+
+```
+use WebDriver\Service\CurlService;
+use WebDriver\ServiceFactory;
+
+class MyCurlService extends CurlService
+{
+    const PROXY = 'http://proxyHost:8080';
+    const AUTH = 'proxyUser:proxyPassword';
+
+    /**
+     * {@inheritdoc}
+     */
+    public function execute($requestMethod, $url, $parameters = null, $extraOptions = null)
+    {
+        $extraOptions = array_replace(
+            $extraOptions,
+            array(
+                CURLOPT_CONNECTTIMEOUT => 30,
+                CURLOPT_TIMEOUT => 300,
+                CURLOPT_PROXY => self::PROXY,
+                CURLOPT_PROXYUSERPWD => self::AUTH,
+            )
+        );
+
+        return parent::execute($requestMethod, $url, $parameters, $extraOptions);
+    }
+}
+
+ServiceFactory::setServiceClass('service.curl', 'MyCurlService');
+```
+
+
diff --git a/vendor/instaclick/php-webdriver/lib/WebDriver/AbstractWebDriver.php b/vendor/instaclick/php-webdriver/lib/WebDriver/AbstractWebDriver.php
new file mode 100644 (file)
index 0000000..0d69023
--- /dev/null
@@ -0,0 +1,248 @@
+<?php
+/**
+ * Copyright 2004-2017 Facebook. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package WebDriver
+ *
+ * @author Justin Bishop <jubishop@gmail.com>
+ * @author Anthon Pang <apang@softwaredevelopment.ca>
+ * @author Fabrizio Branca <mail@fabrizio-branca.de>
+ * @author Tsz Ming Wong <tszming@gmail.com>
+ */
+
+namespace WebDriver;
+
+use WebDriver\Exception as WebDriverException;
+
+/**
+ * Abstract WebDriver\AbstractWebDriver class
+ *
+ * @package WebDriver
+ */
+abstract class AbstractWebDriver
+{
+    /**
+     * URL
+     *
+     * @var string
+     */
+    protected $url;
+
+    /**
+     * Return array of supported method names and corresponding HTTP request methods
+     *
+     * @return array
+     */
+    abstract protected function methods();
+
+    /**
+     * Return array of obsolete method names and corresponding HTTP request methods
+     *
+     * @return array
+     */
+    protected function obsoleteMethods()
+    {
+        return array();
+    }
+
+    /**
+     * Constructor
+     *
+     * @param string $url URL to Selenium server
+     */
+    public function __construct($url = 'http://localhost:4444/wd/hub')
+    {
+        $this->url = $url;
+    }
+
+    /**
+     * Magic method which returns URL to Selenium server
+     *
+     * @return string
+     */
+    public function __toString()
+    {
+        return $this->url;
+    }
+
+    /**
+     * Returns URL to Selenium server
+     *
+     * @return string
+     */
+    public function getURL()
+    {
+        return $this->url;
+    }
+
+    /**
+     * Curl request to webdriver server.
+     *
+     * @param string $requestMethod HTTP request method, e.g., 'GET', 'POST', or 'DELETE'
+     * @param string $command       If not defined in methods() this function will throw.
+     * @param array  $parameters    If an array(), they will be posted as JSON parameters
+     *                              If a number or string, "/$params" is appended to url
+     * @param array  $extraOptions  key=>value pairs of curl options to pass to curl_setopt()
+     *
+     * @return array array('value' => ..., 'info' => ...)
+     *
+     * @throws \WebDriver\Exception if error
+     */
+    protected function curl($requestMethod, $command, $parameters = null, $extraOptions = array())
+    {
+        if ($parameters && is_array($parameters) && $requestMethod !== 'POST') {
+            throw WebDriverException::factory(
+                WebDriverException::NO_PARAMETERS_EXPECTED,
+                sprintf(
+                    'The http request method called for %s is %s but it has to be POST if you want to pass the JSON parameters %s',
+                    $command,
+                    $requestMethod,
+                    json_encode($parameters)
+                )
+            );
+        }
+
+        $url = sprintf('%s%s', $this->url, $command);
+
+        if ($parameters && (is_int($parameters) || is_string($parameters))) {
+            $url .= '/' . $parameters;
+        }
+
+        list($rawResult, $info) = ServiceFactory::getInstance()->getService('service.curl')->execute($requestMethod, $url, $parameters, $extraOptions);
+
+        $httpCode = $info['http_code'];
+
+        // According to https://w3c.github.io/webdriver/webdriver-spec.html all 4xx responses are to be considered
+        // an error and return plaintext, while 5xx responses are json encoded
+        if ($httpCode >= 400 && $httpCode <= 499) {
+            throw WebDriverException::factory(
+                WebDriverException::CURL_EXEC,
+                'Webdriver http error: ' . $httpCode . ', payload :' . substr($rawResult, 0, 1000)
+            );
+        }
+
+        $result = json_decode($rawResult, true);
+
+        if (!empty($rawResult) && $result === null && json_last_error() != JSON_ERROR_NONE) {
+            throw WebDriverException::factory(
+                WebDriverException::CURL_EXEC,
+                'Payload received from webdriver is not valid json: ' . substr($rawResult, 0, 1000)
+            );
+        }
+
+        if (is_array($result) && !array_key_exists('status', $result)) {
+            throw WebDriverException::factory(
+                WebDriverException::CURL_EXEC,
+                'Payload received from webdriver is valid but unexpected json: ' . substr($rawResult, 0, 1000)
+            );
+        }
+
+        $value   = (is_array($result) && array_key_exists('value', $result)) ? $result['value'] : null;
+        $message = (is_array($value) && array_key_exists('message', $value)) ? $value['message'] : null;
+
+        // if not success, throw exception
+        if ((int) $result['status'] !== 0) {
+            throw WebDriverException::factory($result['status'], $message);
+        }
+
+        $sessionId = isset($result['sessionId'])
+           ? $result['sessionId']
+           : (isset($value['webdriver.remote.sessionid'])
+               ? $value['webdriver.remote.sessionid']
+               : null
+           );
+
+        return array(
+            'value'      => $value,
+            'info'       => $info,
+            'sessionId'  => $sessionId,
+            'sessionUrl' => $sessionId ? $this->url . '/session/' . $sessionId : $info['url'],
+        );
+    }
+
+    /**
+     * Magic method that maps calls to class methods to execute WebDriver commands
+     *
+     * @param string $name      Method name
+     * @param array  $arguments Arguments
+     *
+     * @return mixed
+     *
+     * @throws \WebDriver\Exception if invalid WebDriver command
+     */
+    public function __call($name, $arguments)
+    {
+        if (count($arguments) > 1) {
+            throw WebDriverException::factory(
+                WebDriverException::JSON_PARAMETERS_EXPECTED,
+                'Commands should have at most only one parameter, which should be the JSON Parameter object'
+            );
+        }
+
+        if (preg_match('/^(get|post|delete)/', $name, $matches)) {
+            $requestMethod = strtoupper($matches[0]);
+            $webdriverCommand = strtolower(substr($name, strlen($requestMethod)));
+        } else {
+            $webdriverCommand = $name;
+            $requestMethod = $this->getRequestMethod($webdriverCommand);
+        }
+
+        $methods = $this->methods();
+
+        if (!in_array($requestMethod, (array) $methods[$webdriverCommand])) {
+            throw WebDriverException::factory(
+                WebDriverException::INVALID_REQUEST,
+                sprintf(
+                    '%s is not an available http request method for the command %s.',
+                    $requestMethod,
+                    $webdriverCommand
+                )
+            );
+        }
+
+        $result = $this->curl(
+            $requestMethod,
+            '/' . $webdriverCommand,
+            array_shift($arguments)
+        );
+
+        return $result['value'];
+    }
+
+    /**
+     * Get default HTTP request method for a given WebDriver command
+     *
+     * @param string $webdriverCommand
+     *
+     * @return string
+     *
+     * @throws \WebDriver\Exception if invalid WebDriver command
+     */
+    private function getRequestMethod($webdriverCommand)
+    {
+        if (!array_key_exists($webdriverCommand, $this->methods())) {
+            throw WebDriverException::factory(
+                array_key_exists($webdriverCommand, $this->obsoleteMethods())
+                ? WebDriverException::OBSOLETE_COMMAND : WebDriverException::UNKNOWN_COMMAND,
+                sprintf('%s is not a valid WebDriver command.', $webdriverCommand)
+            );
+        }
+
+        $methods = $this->methods();
+        $requestMethods = (array) $methods[$webdriverCommand];
+
+        return array_shift($requestMethods);
+    }
+}
diff --git a/vendor/instaclick/php-webdriver/lib/WebDriver/AppCacheStatus.php b/vendor/instaclick/php-webdriver/lib/WebDriver/AppCacheStatus.php
new file mode 100644 (file)
index 0000000..b92a600
--- /dev/null
@@ -0,0 +1,42 @@
+<?php
+/**
+ * Copyright 2012-2017 Anthon Pang. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package WebDriver
+ *
+ * @author Anthon Pang <apang@softwaredevelopment.ca>
+ */
+
+namespace WebDriver;
+
+/**
+ * WebDriver\AppCacheStatus class
+ *
+ * @package WebDriver
+ */
+final class AppCacheStatus
+{
+    /**
+     * Application cache status
+     *
+     * @see https://code.google.com/p/selenium/source/browse/java/client/src/org/openqa/selenium/html5/AppCacheStatus.java
+     */
+    const UNCACHED     = 0;
+    const IDLE         = 1;
+    const CHECKING     = 2;
+    const DOWNLOADING  = 3;
+    const UPDATE_READY = 4;
+    const OBSOLETE     = 5;
+}
diff --git a/vendor/instaclick/php-webdriver/lib/WebDriver/ApplicationCache.php b/vendor/instaclick/php-webdriver/lib/WebDriver/ApplicationCache.php
new file mode 100644 (file)
index 0000000..6f7de02
--- /dev/null
@@ -0,0 +1,42 @@
+<?php
+/**
+ * Copyright 2012-2017 Anthon Pang. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package WebDriver
+ *
+ * @author Anthon Pang <apang@softwaredevelopment.ca>
+ */
+
+namespace WebDriver;
+
+/**
+ * WebDriver\ApplicationCache class
+ *
+ * @package WebDriver
+ *
+ * @method integer status() Get application cache status.
+ */
+final class ApplicationCache extends AbstractWebDriver
+{
+    /**
+     * {@inheritdoc}
+     */
+    protected function methods()
+    {
+        return array(
+            'status' => array('GET'),
+        );
+    }
+}
diff --git a/vendor/instaclick/php-webdriver/lib/WebDriver/Browser.php b/vendor/instaclick/php-webdriver/lib/WebDriver/Browser.php
new file mode 100644 (file)
index 0000000..d23c308
--- /dev/null
@@ -0,0 +1,52 @@
+<?php
+/**
+ * Copyright 2011-2017 Fabrizio Branca. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package WebDriver
+ *
+ * @author Fabrizio Branca <mail@fabrizio-branca.de>
+ * @author Anthon Pang <apang@softwaredevelopment.ca>
+ */
+
+namespace WebDriver;
+
+/**
+ * WebDriver\Browser class
+ *
+ * @package WebDriver
+ */
+final class Browser
+{
+    /**
+     * Check browser names used in static functions in the selenium source:
+     * @see http://code.google.com/p/selenium/source/browse/java/client/src/org/openqa/selenium/remote/DesiredCapabilities.java
+     *
+     * Note: Capability array takes these browserNames and not the "browserTypes"
+     *
+     * Also check
+     * @see http://code.google.com/p/selenium/wiki/JsonWireProtocol#Capabilities_JSON_Object
+     */
+    const ANDROID           = 'android';
+    const CHROME            = 'chrome';
+    const FIREFOX           = 'firefox';
+    const HTMLUNIT          = 'htmlunit';
+    const IE                = 'internet explorer';
+    const INTERNET_EXPLORER = 'internet explorer';
+    const IPHONE            = 'iPhone';
+    const IPAD              = 'iPad';
+    const OPERA             = 'opera';
+    const PHANTOMJS         = 'phantomjs';
+    const SAFARI            = 'safari';
+}
diff --git a/vendor/instaclick/php-webdriver/lib/WebDriver/Capability.php b/vendor/instaclick/php-webdriver/lib/WebDriver/Capability.php
new file mode 100644 (file)
index 0000000..50d6664
--- /dev/null
@@ -0,0 +1,67 @@
+<?php
+/**
+ * Copyright 2011-2017 Fabrizio Branca. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package WebDriver
+ *
+ * @author Fabrizio Branca <mail@fabrizio-branca.de>
+ * @author Anthon Pang <apang@softwaredevelopment.ca>
+ */
+
+namespace WebDriver;
+
+/**
+ * WebDriver\Capability class
+ *
+ * @package WebDriver
+ */
+class Capability
+{
+    /**
+     * Desired capabilities
+     *
+     * @see http://code.google.com/p/selenium/source/browse/trunk/java/client/src/org/openqa/selenium/remote/CapabilityType.java
+     * @see http://code.google.com/p/selenium/wiki/JsonWireProtocol#Capabilities_JSON_Object
+     */
+    const BROWSER_NAME               = 'browserName';
+    const VERSION                    = 'version';
+    const PLATFORM                   = 'platform';
+    const JAVASCRIPT_ENABLED         = 'javascriptEnabled';
+    const TAKES_SCREENSHOT           = 'takesScreenshot';
+    const HANDLES_ALERTS             = 'handlesAlerts';
+    const DATABASE_ENABLED           = 'databaseEnabled';
+    const LOCATION_CONTEXT_ENABLED   = 'locationContextEnabled';
+    const APPLICATION_CACHE_ENABLED  = 'applicationCacheEnabled';
+    const BROWSER_CONNECTION_ENABLED = 'browserConnectionEnabled';
+    const CSS_SELECTORS_ENABLED      = 'cssSelectorsEnabled';
+    const WEB_STORAGE_ENABLED        = 'webStorageEnabled';
+    const ROTATABLE                  = 'rotatable';
+    const ACCEPT_SSL_CERTS           = 'acceptSslCerts';
+    const NATIVE_EVENTS              = 'nativeEvents';
+    const PROXY                      = 'proxy';
+    const UNEXPECTED_ALERT_BEHAVIOUR = 'unexpectedAlertBehaviour';
+    const ELEMENT_SCROLL_BEHAVIOR    = 'elementScrollBehavior';
+
+    /**
+     * Proxy types
+     *
+     * @see http://code.google.com/p/selenium/wiki/JsonWireProtocol#Proxy_JSON_Object
+     */
+    const DIRECT     = 'direct';
+    const MANUAL     = 'manual';
+    const PAC        = 'pac';
+    const AUTODETECT = 'autodetect';
+    const SYSTEM     = 'system';
+}
diff --git a/vendor/instaclick/php-webdriver/lib/WebDriver/ClassLoader.php b/vendor/instaclick/php-webdriver/lib/WebDriver/ClassLoader.php
new file mode 100644 (file)
index 0000000..8b1830b
--- /dev/null
@@ -0,0 +1,85 @@
+<?php
+/**
+ * Copyright 2012-2017 Anthon Pang. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package WebDriver
+ *
+ * @author Anthon Pang <apang@softwaredevelopment.ca>
+ */
+
+namespace WebDriver;
+
+/**
+ * WebDriver\ClassLoader (autoloader) class
+ *
+ * @package WebDriver
+ */
+final class ClassLoader
+{
+    /**
+     * Load class
+     *
+     * @param string $class Class name
+     */
+    public static function loadClass($class)
+    {
+        $file = strpos($class, '\\') !== false
+            ? str_replace('\\', DIRECTORY_SEPARATOR, $class)
+            : str_replace('_', DIRECTORY_SEPARATOR, $class);
+
+        $path = dirname(__DIR__) . DIRECTORY_SEPARATOR . $file . '.php';
+
+        if (file_exists($path)) {
+            include_once $path;
+        }
+    }
+
+    /**
+     * Autoloader
+     *
+     * @param string $class Class name
+     */
+    public static function autoload($class)
+    {
+        try {
+            self::loadClass($class);
+        } catch (\Exception $e) {
+        }
+    }
+}
+
+if (function_exists('spl_autoload_register')) {
+    /**
+     * use the SPL autoload stack
+     */
+    spl_autoload_register(array('WebDriver\ClassLoader', 'autoload'));
+
+    /**
+     * preserve any existing __autoload
+     */
+    if (function_exists('__autoload')) {
+        spl_autoload_register('__autoload');
+    }
+} else {
+    /**
+     * Our fallback; only one __autoload per PHP instance
+     *
+     * @param string $class Class name
+     */
+    function __autoload($class)
+    {
+        ClassLoader::autoload($class);
+    }
+}
diff --git a/vendor/instaclick/php-webdriver/lib/WebDriver/Container.php b/vendor/instaclick/php-webdriver/lib/WebDriver/Container.php
new file mode 100644 (file)
index 0000000..be1cfa7
--- /dev/null
@@ -0,0 +1,235 @@
+<?php
+/**
+ * Copyright 2004-2017 Facebook. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package WebDriver
+ *
+ * @author Justin Bishop <jubishop@gmail.com>
+ * @author Anthon Pang <apang@softwaredevelopment.ca>
+ * @author Fabrizio Branca <mail@fabrizio-branca.de>
+ */
+
+namespace WebDriver;
+
+use WebDriver\Exception as WebDriverException;
+
+/**
+ * Abstract WebDriver\Container class
+ *
+ * @package WebDriver
+ */
+abstract class Container extends AbstractWebDriver
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function __construct($url = 'http://localhost:4444/wd/hub')
+    {
+        parent::__construct($url);
+
+        $locatorStrategy = new \ReflectionClass('WebDriver\LocatorStrategy');
+        $this->strategies  = $locatorStrategy->getConstants();
+    }
+
+    /**
+     * Find element: /session/:sessionId/element (POST)
+     * Find child element: /session/:sessionId/element/:id/element (POST)
+     * Search for element on page, starting from the document root.
+     *
+     * @param string $using the locator strategy to use
+     * @param string $value the search target
+     *
+     * @return \WebDriver\Element
+     *
+     * @throws \WebDriver\Exception if element not found, or invalid XPath
+     */
+    public function element($using = null, $value = null)
+    {
+        $locatorJson = $this->parseArgs('element', func_get_args());
+
+        try {
+            $result = $this->curl(
+                'POST',
+                '/element',
+                $locatorJson
+            );
+        } catch (WebDriverException\NoSuchElement $e) {
+            throw WebDriverException::factory(
+                WebDriverException::NO_SUCH_ELEMENT,
+                sprintf(
+                    "Element not found with %s, %s\n\n%s",
+                    $locatorJson['using'],
+                    $locatorJson['value'],
+                    $e->getMessage()
+                ),
+                $e
+            );
+        }
+
+        $element = $this->webDriverElement($result['value']);
+
+        if ($element === null) {
+            throw WebDriverException::factory(
+                WebDriverException::NO_SUCH_ELEMENT,
+                sprintf(
+                    "Element not found with %s, %s\n",
+                    $locatorJson['using'],
+                    $locatorJson['value']
+                )
+            );
+        }
+
+        return $element;
+    }
+
+    /**
+     * Find elements: /session/:sessionId/elements (POST)
+     * Find child elements: /session/:sessionId/element/:id/elements (POST)
+     * Search for multiple elements on page, starting from the document root.
+     *
+     * @param string $using the locator strategy to use
+     * @param string $value the search target
+     *
+     * @return array
+     *
+     * @throws \WebDriver\Exception if invalid XPath
+     */
+    public function elements($using = null, $value = null)
+    {
+        $locatorJson = $this->parseArgs('elements', func_get_args());
+
+        $result = $this->curl(
+            'POST',
+            '/elements',
+            $locatorJson
+        );
+
+        if (!is_array($result['value'])) {
+            return array();
+        }
+
+        return array_filter(
+            array_map(
+                array($this, 'webDriverElement'),
+                $result['value']
+            )
+        );
+    }
+
+    /**
+     * Parse arguments allowing either separate $using and $value parameters, or
+     * as an array containing the JSON parameters
+     *
+     * @param string $method method name
+     * @param array  $argv   arguments
+     *
+     * @return array
+     *
+     * @throws \WebDriver\Exception if invalid number of arguments to the called method
+     */
+    private function parseArgs($method, $argv)
+    {
+        $argc = count($argv);
+
+        switch ($argc) {
+            case 2:
+                $using = $argv[0];
+                $value = $argv[1];
+                break;
+
+            case 1:
+                $arg = $argv[0];
+
+                if (is_array($arg)) {
+                    $using = $arg['using'];
+                    $value = $arg['value'];
+                    break;
+                }
+
+                // fall through
+            default:
+                throw WebDriverException::factory(
+                    WebDriverException::JSON_PARAMETERS_EXPECTED,
+                    sprintf('Invalid arguments to %s method: %s', $method, print_r($argv, true))
+                );
+        }
+
+        return $this->locate($using, $value);
+    }
+
+    /**
+     * Return JSON parameter for element / elements command
+     *
+     * @param string $using locator strategy
+     * @param string $value search target
+     *
+     * @return array
+     *
+     * @throws \WebDriver\Exception if invalid locator strategy
+     */
+    public function locate($using, $value)
+    {
+        if (!in_array($using, $this->strategies)) {
+            throw WebDriverException::factory(
+                WebDriverException::UNKNOWN_LOCATOR_STRATEGY,
+                sprintf('Invalid locator strategy %s', $using)
+            );
+        }
+
+        return array(
+            'using' => $using,
+            'value' => $value,
+        );
+    }
+
+    /**
+     * Return WebDriver\Element wrapper for $value
+     *
+     * @param mixed $value
+     *
+     * @return \WebDriver\Element|null
+     */
+    protected function webDriverElement($value)
+    {
+        return array_key_exists('ELEMENT', (array) $value)
+            ? new Element(
+                $this->getElementPath($value['ELEMENT']), // url
+                $value['ELEMENT'] // id
+            )
+            : null;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function __call($name, $arguments)
+    {
+        if (count($arguments) === 1 && in_array(str_replace('_', ' ', $name), $this->strategies)) {
+            return $this->locate($name, $arguments[0]);
+        }
+
+        // fallback to executing WebDriver commands
+        return parent::__call($name, $arguments);
+    }
+
+    /**
+     * Get wire protocol URL for an element
+     *
+     * @param string $elementId
+     *
+     * @return string
+     */
+    abstract protected function getElementPath($elementId);
+}
diff --git a/vendor/instaclick/php-webdriver/lib/WebDriver/Element.php b/vendor/instaclick/php-webdriver/lib/WebDriver/Element.php
new file mode 100644 (file)
index 0000000..09bbc91
--- /dev/null
@@ -0,0 +1,124 @@
+<?php
+/**
+ * Copyright 2004-2017 Facebook. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package WebDriver
+ *
+ * @author Justin Bishop <jubishop@gmail.com>
+ * @author Anthon Pang <apang@softwaredevelopment.ca>
+ * @author Fabrizio Branca <mail@fabrizio-branca.de>
+ */
+
+namespace WebDriver;
+
+/**
+ * WebDriver\Element class
+ *
+ * @package WebDriver
+ *
+ * @method void click() Click on an element.
+ * @method void submit() Submit a FORM element.
+ * @method string text() Returns the visible text for the element.
+ * @method void postValue($json) Send a sequence of key strokes to an element.
+ * @method string name() Query for an element's tag name.
+ * @method void clear() Clear a TEXTAREA or text INPUT element's value.
+ * @method boolean selected() Determine if an OPTION element, or an INPUT element of type checkbox or radiobutton is currently selected.
+ * @method boolean enabled() Determine if an element is currently enabled.
+ * @method string attribute($attributeName) Get the value of an element's attribute.
+ * @method boolean equals($otherId) Test if two element IDs refer to the same DOM element.
+ * @method boolean displayed() Determine if an element is currently displayed.
+ * @method array location() Determine an element's location on the page.
+ * @method array location_in_view() Determine an element's location on the screen once it has been scrolled into view.
+ * @method array size() Determine an element's size in pixels.
+ * @method string css($propertyName) Query the value of an element's computed CSS property.
+ */
+final class Element extends Container
+{
+    /**
+     * {@inheritdoc}
+     */
+    protected function methods()
+    {
+        return array(
+            'click' => array('POST'),
+            'submit' => array('POST'),
+            'text' => array('GET'),
+            'value' => array('POST'),
+            'name' => array('GET'),
+            'clear' => array('POST'),
+            'selected' => array('GET'),
+            'enabled' => array('GET'),
+            'attribute' => array('GET'),
+            'equals' => array('GET'),
+            'displayed' => array('GET'),
+            'location' => array('GET'),
+            'location_in_view' => array('GET'),
+            'size' => array('GET'),
+            'css' => array('GET'),
+        );
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function obsoleteMethods()
+    {
+        return array(
+            'value' => array('GET'),
+            'selected' => array('POST'),
+            'toggle' => array('POST'),
+            'hover' => array('POST'),
+            'drag' => array('POST'),
+        );
+    }
+
+    /**
+     * Element ID
+     *
+     * @var string
+     */
+    private $id;
+
+    /**
+     * Constructor
+     *
+     * @param string $url URL
+     * @param string $id  element ID
+     */
+    public function __construct($url, $id)
+    {
+        parent::__construct($url);
+
+        $this->id = $id;
+    }
+
+    /**
+     * Get element ID
+     *
+     * @return string
+     */
+    public function getID()
+    {
+        return $this->id;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function getElementPath($elementId)
+    {
+        return preg_replace(sprintf('/%s$/', $this->id), $elementId, $this->url);
+    }
+}
diff --git a/vendor/instaclick/php-webdriver/lib/WebDriver/Exception.php b/vendor/instaclick/php-webdriver/lib/WebDriver/Exception.php
new file mode 100644 (file)
index 0000000..bacb9cb
--- /dev/null
@@ -0,0 +1,157 @@
+<?php
+/**
+ * Copyright 2004-2017 Facebook. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package WebDriver
+ *
+ * @author Justin Bishop <jubishop@gmail.com>
+ * @author Anthon Pang <apang@softwaredevelopment.ca>
+ */
+
+namespace WebDriver;
+
+/**
+ * WebDriver\Exception class
+ *
+ * @package WebDriver
+ */
+abstract class Exception extends \Exception
+{
+    /**
+     * Response status codes
+     *
+     * @link http://code.google.com/p/selenium/wiki/JsonWireProtocol#Response_Status_Codes
+     */
+    const SUCCESS = 0;
+    const NO_SUCH_DRIVER = 6;
+    const NO_SUCH_ELEMENT = 7;
+    const NO_SUCH_FRAME = 8;
+    const UNKNOWN_COMMAND = 9;
+    const STALE_ELEMENT_REFERENCE = 10;
+    const ELEMENT_NOT_VISIBLE = 11;
+    const INVALID_ELEMENT_STATE = 12;
+    const UNKNOWN_ERROR = 13;
+    const ELEMENT_IS_NOT_SELECTABLE = 15;
+    const JAVASCRIPT_ERROR = 17;
+    const XPATH_LOOKUP_ERROR = 19;
+    const TIMEOUT = 21;
+    const NO_SUCH_WINDOW = 23;
+    const INVALID_COOKIE_DOMAIN = 24;
+    const UNABLE_TO_SET_COOKIE = 25;
+    const UNEXPECTED_ALERT_OPEN = 26;
+    const NO_ALERT_OPEN_ERROR = 27;
+    const SCRIPT_TIMEOUT = 28;
+    const INVALID_ELEMENT_COORDINATES = 29;
+    const IME_NOT_AVAILABLE = 30;
+    const IME_ENGINE_ACTIVATION_FAILED = 31;
+    const INVALID_SELECTOR = 32;
+    const SESSION_NOT_CREATED = 33;
+    const MOVE_TARGET_OUT_OF_BOUNDS = 34;
+
+    // obsolete
+    const INDEX_OUT_OF_BOUNDS = 1;
+    const NO_COLLECTION = 2;
+    const NO_STRING = 3;
+    const NO_STRING_LENGTH = 4;
+    const NO_STRING_WRAPPER = 5;
+    const OBSOLETE_ELEMENT = 10;
+    const ELEMENT_NOT_DISPLAYED = 11;
+    const UNHANDLED = 13;
+    const EXPECTED = 14;
+    const ELEMENT_NOT_SELECTABLE = 15;
+    const NO_SUCH_DOCUMENT = 16;
+    const UNEXPECTED_JAVASCRIPT = 17;
+    const NO_SCRIPT_RESULT = 18;
+    const NO_SUCH_COLLECTION = 20;
+    const NULL_POINTER = 22;
+    const NO_MODAL_DIALOG_OPEN_ERROR = 27;
+
+    // user-defined
+    const CURL_EXEC = -1;
+    const OBSOLETE_COMMAND = -2;
+    const NO_PARAMETERS_EXPECTED = -3;
+    const JSON_PARAMETERS_EXPECTED = -4;
+    const UNEXPECTED_PARAMETERS = -5;
+    const INVALID_REQUEST = -6;
+    const UNKNOWN_LOCATOR_STRATEGY = -7;
+
+    private static $errs = array(
+//      self::SUCCESS => array('Success', 'This should never be thrown!'),
+
+        self::NO_SUCH_DRIVER => array('NoSuchDriver', 'A session is either terminated or not started'),
+        self::NO_SUCH_ELEMENT => array('NoSuchElement', 'An element could not be located on the page using the given search parameters.'),
+        self::NO_SUCH_FRAME => array('NoSuchFrame', 'A request to switch to a frame could not be satisfied because the frame could not be found.'),
+        self::UNKNOWN_COMMAND => array('UnknownCommand', 'The requested resource could not be found, or a request was received using an HTTP method that is not supported by the mapped resource.'),
+        self::STALE_ELEMENT_REFERENCE => array('StaleElementReference', 'An element command failed because the referenced element is no longer attached to the DOM.'),
+        self::ELEMENT_NOT_VISIBLE => array('ElementNotVisible', 'An element command could not be completed because the element is not visible on the page.'),
+        self::INVALID_ELEMENT_STATE => array('InvalidElementState', 'An element command could not be completed because the element is in an invalid state (e.g., attempting to click a disabled element).'),
+        self::UNKNOWN_ERROR => array('UnknownError', 'An unknown server-side error occurred while processing the command.'),
+        self::ELEMENT_IS_NOT_SELECTABLE => array('ElementIsNotSelectable', 'An attempt was made to select an element that cannot be selected.'),
+        self::JAVASCRIPT_ERROR => array('JavaScriptError', 'An error occurred while executing user supplied JavaScript.'),
+        self::XPATH_LOOKUP_ERROR => array('XPathLookupError', 'An error occurred while searching for an element by XPath.'),
+        self::TIMEOUT => array('Timeout', 'An operation did not complete before its timeout expired.'),
+        self::NO_SUCH_WINDOW => array('NoSuchWindow', 'A request to switch to a different window could not be satisfied because the window could not be found.'),
+        self::INVALID_COOKIE_DOMAIN => array('InvalidCookieDomain', 'An illegal attempt was made to set a cookie under a different domain than the current page.'),
+        self::UNABLE_TO_SET_COOKIE => array('UnableToSetCookie', 'A request to set a cookie\'s value could not be satisfied.'),
+        self::UNEXPECTED_ALERT_OPEN => array('UnexpectedAlertOpen', 'A modal dialog was open, blocking this operation'),
+        self::NO_ALERT_OPEN_ERROR => array('NoAlertOpenError', 'An attempt was made to operate on a modal dialog when one was not open.'),
+        self::SCRIPT_TIMEOUT => array('ScriptTimeout', 'A script did not complete before its timeout expired.'),
+        self::INVALID_ELEMENT_COORDINATES => array('InvalidElementCoordinates', 'The coordinates provided to an interactions operation are invalid.'),
+        self::IME_NOT_AVAILABLE => array('IMENotAvailable', 'IME was not available.'),
+        self::IME_ENGINE_ACTIVATION_FAILED => array('IMEEngineActivationFailed', 'An IME engine could not be started.'),
+        self::INVALID_SELECTOR => array('InvalidSelector', 'Argument was an invalid selector (e.g., XPath/CSS).'),
+        self::SESSION_NOT_CREATED => array('SessionNotCreated', 'A new session could not be created (e.g., a required capability could not be set).'),
+        self::MOVE_TARGET_OUT_OF_BOUNDS => array('MoveTargetOutOfBounds', 'Target provided for a move action is out of bounds.'),
+
+        self::CURL_EXEC => array('CurlExec', 'curl_exec() error.'),
+        self::OBSOLETE_COMMAND => array('ObsoleteCommand', 'This WebDriver command is obsolete.'),
+        self::NO_PARAMETERS_EXPECTED => array('NoParametersExpected', 'This HTTP request method expects no parameters.'),
+        self::JSON_PARAMETERS_EXPECTED => array('JsonParameterExpected', 'This POST request expects a JSON parameter (array).'),
+        self::UNEXPECTED_PARAMETERS => array('UnexpectedParameters', 'This command does not expect this number of parameters.'),
+        self::INVALID_REQUEST => array('InvalidRequest', 'This command does not support this HTTP request method.'),
+        self::UNKNOWN_LOCATOR_STRATEGY => array('UnknownLocatorStrategy', 'This locator strategy is not supported.'),
+    );
+
+    /**
+     * Factory method to create WebDriver\Exception objects
+     *
+     * @param integer    $code              Code
+     * @param string     $message           Message
+     * @param \Exception $previousException Previous exception
+     *
+     * @return \Exception
+     */
+    public static function factory($code, $message = null, $previousException = null)
+    {
+        // unknown error
+        if (!isset(self::$errs[$code])) {
+            if (trim($message) === '') {
+                $message = 'Unknown Error';
+            }
+
+            return new \Exception($message, $code, $previousException);
+        }
+
+        $errorDefinition = self::$errs[$code];
+
+        if (trim($message) === '') {
+            $message = $errorDefinition[1];
+        }
+
+        $className = __CLASS__ . '\\' . $errorDefinition[0];
+
+        return new $className($message, $code, $previousException);
+    }
+}
diff --git a/vendor/instaclick/php-webdriver/lib/WebDriver/Exception/CurlExec.php b/vendor/instaclick/php-webdriver/lib/WebDriver/Exception/CurlExec.php
new file mode 100644 (file)
index 0000000..29c15cb
--- /dev/null
@@ -0,0 +1,59 @@
+<?php
+/**
+ * Copyright 2004-2017 Facebook. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package WebDriver
+ *
+ * @author Justin Bishop <jubishop@gmail.com>
+ * @author Anthon Pang <apang@softwaredevelopment.ca>
+ * @author Gaetano Giunta <giunta.gaetano@gmail.com>
+ */
+
+namespace WebDriver\Exception;
+
+use WebDriver\Exception as BaseException;
+
+/**
+ * WebDriver\Exception\CurlExec class
+ *
+ * @package WebDriver
+ */
+final class CurlExec extends BaseException
+{
+    /**
+     * @var array
+     */
+    private $curlInfo = array();
+
+    /**
+     * {@inheritdoc}
+     */
+    public function __construct($message = null, $code = 0, \Exception $previous = null, $curlInfo = array())
+    {
+        parent::__construct($message, $code, $previous);
+
+        $this->curlInfo = $curlInfo;
+    }
+
+    /**
+     * Get curl info
+     *
+     * @return array
+     */
+    public function getCurlInfo()
+    {
+        return $this->curlInfo;
+    }
+}
diff --git a/vendor/instaclick/php-webdriver/lib/WebDriver/Exception/ElementIsNotSelectable.php b/vendor/instaclick/php-webdriver/lib/WebDriver/Exception/ElementIsNotSelectable.php
new file mode 100644 (file)
index 0000000..2b6c124
--- /dev/null
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Copyright 2004-2017 Facebook. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package WebDriver
+ *
+ * @author Justin Bishop <jubishop@gmail.com>
+ * @author Anthon Pang <apang@softwaredevelopment.ca>
+ */
+
+namespace WebDriver\Exception;
+
+use WebDriver\Exception as BaseException;
+
+/**
+ * WebDriver\Exception\ElementIsNotSelectable class
+ *
+ * @package WebDriver
+ */
+final class ElementIsNotSelectable extends BaseException
+{
+}
diff --git a/vendor/instaclick/php-webdriver/lib/WebDriver/Exception/ElementNotVisible.php b/vendor/instaclick/php-webdriver/lib/WebDriver/Exception/ElementNotVisible.php
new file mode 100644 (file)
index 0000000..80287c0
--- /dev/null
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Copyright 2004-2017 Facebook. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package WebDriver
+ *
+ * @author Justin Bishop <jubishop@gmail.com>
+ * @author Anthon Pang <apang@softwaredevelopment.ca>
+ */
+
+namespace WebDriver\Exception;
+
+use WebDriver\Exception as BaseException;
+
+/**
+ * WebDriver\Exception\ElementNotVisible class
+ *
+ * @package WebDriver
+ */
+final class ElementNotVisible extends BaseException
+{
+}
diff --git a/vendor/instaclick/php-webdriver/lib/WebDriver/Exception/IMEEngineActivationFailed.php b/vendor/instaclick/php-webdriver/lib/WebDriver/Exception/IMEEngineActivationFailed.php
new file mode 100644 (file)
index 0000000..cb2610f
--- /dev/null
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Copyright 2004-2017 Facebook. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package WebDriver
+ *
+ * @author Justin Bishop <jubishop@gmail.com>
+ * @author Anthon Pang <apang@softwaredevelopment.ca>
+ */
+
+namespace WebDriver\Exception;
+
+use WebDriver\Exception as BaseException;
+
+/**
+ * WebDriver\Exception\IMEEngineActivationFailed class
+ *
+ * @package WebDriver
+ */
+final class IMEEngineActivationFailed extends BaseException
+{
+}
diff --git a/vendor/instaclick/php-webdriver/lib/WebDriver/Exception/IMENotAvailable.php b/vendor/instaclick/php-webdriver/lib/WebDriver/Exception/IMENotAvailable.php
new file mode 100644 (file)
index 0000000..45fc10f
--- /dev/null
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Copyright 2004-2017 Facebook. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package WebDriver
+ *
+ * @author Justin Bishop <jubishop@gmail.com>
+ * @author Anthon Pang <apang@softwaredevelopment.ca>
+ */
+
+namespace WebDriver\Exception;
+
+use WebDriver\Exception as BaseException;
+
+/**
+ * WebDriver\Exception\IMENotAvailable class
+ *
+ * @package WebDriver
+ */
+final class IMENotAvailable extends BaseException
+{
+}
diff --git a/vendor/instaclick/php-webdriver/lib/WebDriver/Exception/InvalidCookieDomain.php b/vendor/instaclick/php-webdriver/lib/WebDriver/Exception/InvalidCookieDomain.php
new file mode 100644 (file)
index 0000000..89ba23d
--- /dev/null
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Copyright 2004-2017 Facebook. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package WebDriver
+ *
+ * @author Justin Bishop <jubishop@gmail.com>
+ * @author Anthon Pang <apang@softwaredevelopment.ca>
+ */
+
+namespace WebDriver\Exception;
+
+use WebDriver\Exception as BaseException;
+
+/**
+ * WebDriver\Exception\InvalidCookieDomain class
+ *
+ * @package WebDriver
+ */
+final class InvalidCookieDomain extends BaseException
+{
+}
diff --git a/vendor/instaclick/php-webdriver/lib/WebDriver/Exception/InvalidElementCoordinates.php b/vendor/instaclick/php-webdriver/lib/WebDriver/Exception/InvalidElementCoordinates.php
new file mode 100644 (file)
index 0000000..7a486b0
--- /dev/null
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Copyright 2004-2017 Facebook. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package WebDriver
+ *
+ * @author Justin Bishop <jubishop@gmail.com>
+ * @author Anthon Pang <apang@softwaredevelopment.ca>
+ */
+
+namespace WebDriver\Exception;
+
+use WebDriver\Exception as BaseException;
+
+/**
+ * WebDriver\Exception\InvalidElementCoordinates class
+ *
+ * @package WebDriver
+ */
+final class InvalidElementCoordinates extends BaseException
+{
+}
diff --git a/vendor/instaclick/php-webdriver/lib/WebDriver/Exception/InvalidElementState.php b/vendor/instaclick/php-webdriver/lib/WebDriver/Exception/InvalidElementState.php
new file mode 100644 (file)
index 0000000..ba4f7a7
--- /dev/null
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Copyright 2004-2017 Facebook. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package WebDriver
+ *
+ * @author Justin Bishop <jubishop@gmail.com>
+ * @author Anthon Pang <apang@softwaredevelopment.ca>
+ */
+
+namespace WebDriver\Exception;
+
+use WebDriver\Exception as BaseException;
+
+/**
+ * WebDriver\Exception\InvalidElementState class
+ *
+ * @package WebDriver
+ */
+final class InvalidElementState extends BaseException
+{
+}
diff --git a/vendor/instaclick/php-webdriver/lib/WebDriver/Exception/InvalidRequest.php b/vendor/instaclick/php-webdriver/lib/WebDriver/Exception/InvalidRequest.php
new file mode 100644 (file)
index 0000000..e18f76c
--- /dev/null
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Copyright 2004-2017 Facebook. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package WebDriver
+ *
+ * @author Justin Bishop <jubishop@gmail.com>
+ * @author Anthon Pang <apang@softwaredevelopment.ca>
+ */
+
+namespace WebDriver\Exception;
+
+use WebDriver\Exception as BaseException;
+
+/**
+ * WebDriver\Exception\InvalidRequest class
+ *
+ * @package WebDriver
+ */
+final class InvalidRequest extends BaseException
+{
+}
diff --git a/vendor/instaclick/php-webdriver/lib/WebDriver/Exception/InvalidSelector.php b/vendor/instaclick/php-webdriver/lib/WebDriver/Exception/InvalidSelector.php
new file mode 100644 (file)
index 0000000..065fc40
--- /dev/null
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Copyright 2004-2017 Facebook. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package WebDriver
+ *
+ * @author Justin Bishop <jubishop@gmail.com>
+ * @author Anthon Pang <apang@softwaredevelopment.ca>
+ */
+
+namespace WebDriver\Exception;
+
+use WebDriver\Exception as BaseException;
+
+/**
+ * WebDriver\Exception\InvalidSelector class
+ *
+ * @package WebDriver
+ */
+final class InvalidSelector extends BaseException
+{
+}
diff --git a/vendor/instaclick/php-webdriver/lib/WebDriver/Exception/JavaScriptError.php b/vendor/instaclick/php-webdriver/lib/WebDriver/Exception/JavaScriptError.php
new file mode 100644 (file)
index 0000000..202bdce
--- /dev/null
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Copyright 2004-2017 Facebook. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package WebDriver
+ *
+ * @author Justin Bishop <jubishop@gmail.com>
+ * @author Anthon Pang <apang@softwaredevelopment.ca>
+ */
+
+namespace WebDriver\Exception;
+
+use WebDriver\Exception as BaseException;
+
+/**
+ * WebDriver\Exception\JavaScriptError class
+ *
+ * @package WebDriver
+ */
+final class JavaScriptError extends BaseException
+{
+}
diff --git a/vendor/instaclick/php-webdriver/lib/WebDriver/Exception/JsonParameterExpected.php b/vendor/instaclick/php-webdriver/lib/WebDriver/Exception/JsonParameterExpected.php
new file mode 100644 (file)
index 0000000..1f9b287
--- /dev/null
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Copyright 2004-2017 Facebook. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package WebDriver
+ *
+ * @author Justin Bishop <jubishop@gmail.com>
+ * @author Anthon Pang <apang@softwaredevelopment.ca>
+ */
+
+namespace WebDriver\Exception;
+
+use WebDriver\Exception as BaseException;
+
+/**
+ * WebDriver\Exception\JsonParameterExpected class
+ *
+ * @package WebDriver
+ */
+final class JsonParameterExpected extends BaseException
+{
+}
diff --git a/vendor/instaclick/php-webdriver/lib/WebDriver/Exception/MoveTargetOutOfBounds.php b/vendor/instaclick/php-webdriver/lib/WebDriver/Exception/MoveTargetOutOfBounds.php
new file mode 100644 (file)
index 0000000..e6fbbb9
--- /dev/null
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Copyright 2004-2017 Facebook. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package WebDriver
+ *
+ * @author Justin Bishop <jubishop@gmail.com>
+ * @author Anthon Pang <apang@softwaredevelopment.ca>
+ */
+
+namespace WebDriver\Exception;
+
+use WebDriver\Exception as BaseException;
+
+/**
+ * WebDriver\Exception\MoveTargetOutOfBounds class
+ *
+ * @package WebDriver
+ */
+final class MoveTargetOutOfBounds extends BaseException
+{
+}
diff --git a/vendor/instaclick/php-webdriver/lib/WebDriver/Exception/NoAlertOpenError.php b/vendor/instaclick/php-webdriver/lib/WebDriver/Exception/NoAlertOpenError.php
new file mode 100644 (file)
index 0000000..9df6db1
--- /dev/null
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Copyright 2004-2017 Facebook. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package WebDriver
+ *
+ * @author Justin Bishop <jubishop@gmail.com>
+ * @author Anthon Pang <apang@softwaredevelopment.ca>
+ */
+
+namespace WebDriver\Exception;
+
+use WebDriver\Exception as BaseException;
+
+/**
+ * WebDriver\Exception\NoAlertOpenError class
+ *
+ * @package WebDriver
+ */
+final class NoAlertOpenError extends BaseException
+{
+}
diff --git a/vendor/instaclick/php-webdriver/lib/WebDriver/Exception/NoParametersExpected.php b/vendor/instaclick/php-webdriver/lib/WebDriver/Exception/NoParametersExpected.php
new file mode 100644 (file)
index 0000000..c35c6b4
--- /dev/null
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Copyright 2004-2017 Facebook. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package WebDriver
+ *
+ * @author Justin Bishop <jubishop@gmail.com>
+ * @author Anthon Pang <apang@softwaredevelopment.ca>
+ */
+
+namespace WebDriver\Exception;
+
+use WebDriver\Exception as BaseException;
+
+/**
+ * WebDriver\Exception\NoParametersExpected class
+ *
+ * @package WebDriver
+ */
+final class NoParametersExpected extends BaseException
+{
+}
diff --git a/vendor/instaclick/php-webdriver/lib/WebDriver/Exception/NoSuchDriver.php b/vendor/instaclick/php-webdriver/lib/WebDriver/Exception/NoSuchDriver.php
new file mode 100644 (file)
index 0000000..0f177da
--- /dev/null
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Copyright 2004-2017 Facebook. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package WebDriver
+ *
+ * @author Justin Bishop <jubishop@gmail.com>
+ * @author Anthon Pang <apang@softwaredevelopment.ca>
+ */
+
+namespace WebDriver\Exception;
+
+use WebDriver\Exception as BaseException;
+
+/**
+ * WebDriver\Exception\NoSuchDriver class
+ *
+ * @package WebDriver
+ */
+final class NoSuchDriver extends BaseException
+{
+}
diff --git a/vendor/instaclick/php-webdriver/lib/WebDriver/Exception/NoSuchElement.php b/vendor/instaclick/php-webdriver/lib/WebDriver/Exception/NoSuchElement.php
new file mode 100644 (file)
index 0000000..83e957c
--- /dev/null
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Copyright 2004-2017 Facebook. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package WebDriver
+ *
+ * @author Justin Bishop <jubishop@gmail.com>
+ * @author Anthon Pang <apang@softwaredevelopment.ca>
+ */
+
+namespace WebDriver\Exception;
+
+use WebDriver\Exception as BaseException;
+
+/**
+ * WebDriver\Exception\NoSuchElement class
+ *
+ * @package WebDriver
+ */
+final class NoSuchElement extends BaseException
+{
+}
diff --git a/vendor/instaclick/php-webdriver/lib/WebDriver/Exception/NoSuchFrame.php b/vendor/instaclick/php-webdriver/lib/WebDriver/Exception/NoSuchFrame.php
new file mode 100644 (file)
index 0000000..47b1b51
--- /dev/null
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Copyright 2004-2017 Facebook. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package WebDriver
+ *
+ * @author Justin Bishop <jubishop@gmail.com>
+ * @author Anthon Pang <apang@softwaredevelopment.ca>
+ */
+
+namespace WebDriver\Exception;
+
+use WebDriver\Exception as BaseException;
+
+/**
+ * WebDriver\Exception\NoSuchFrame class
+ *
+ * @package WebDriver
+ */
+final class NoSuchFrame extends BaseException
+{
+}
diff --git a/vendor/instaclick/php-webdriver/lib/WebDriver/Exception/NoSuchWindow.php b/vendor/instaclick/php-webdriver/lib/WebDriver/Exception/NoSuchWindow.php
new file mode 100644 (file)
index 0000000..3a971a8
--- /dev/null
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Copyright 2004-2017 Facebook. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package WebDriver
+ *
+ * @author Justin Bishop <jubishop@gmail.com>
+ * @author Anthon Pang <apang@softwaredevelopment.ca>
+ */
+
+namespace WebDriver\Exception;
+
+use WebDriver\Exception as BaseException;
+
+/**
+ * WebDriver\Exception\NoSuchWindow class
+ *
+ * @package WebDriver
+ */
+final class NoSuchWindow extends BaseException
+{
+}
diff --git a/vendor/instaclick/php-webdriver/lib/WebDriver/Exception/ObsoleteCommand.php b/vendor/instaclick/php-webdriver/lib/WebDriver/Exception/ObsoleteCommand.php
new file mode 100644 (file)
index 0000000..e841919
--- /dev/null
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Copyright 2004-2017 Facebook. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package WebDriver
+ *
+ * @author Justin Bishop <jubishop@gmail.com>
+ * @author Anthon Pang <apang@softwaredevelopment.ca>
+ */
+
+namespace WebDriver\Exception;
+
+use WebDriver\Exception as BaseException;
+
+/**
+ * WebDriver\Exception\ObsoleteCommand class
+ *
+ * @package WebDriver
+ */
+final class ObsoleteCommand extends BaseException
+{
+}
diff --git a/vendor/instaclick/php-webdriver/lib/WebDriver/Exception/ScriptTimeout.php b/vendor/instaclick/php-webdriver/lib/WebDriver/Exception/ScriptTimeout.php
new file mode 100644 (file)
index 0000000..2c8ba7e
--- /dev/null
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Copyright 2004-2017 Facebook. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package WebDriver
+ *
+ * @author Justin Bishop <jubishop@gmail.com>
+ * @author Anthon Pang <apang@softwaredevelopment.ca>
+ */
+
+namespace WebDriver\Exception;
+
+use WebDriver\Exception as BaseException;
+
+/**
+ * WebDriver\Exception\ScriptTimeout class
+ *
+ * @package WebDriver
+ */
+final class ScriptTimeout extends BaseException
+{
+}
diff --git a/vendor/instaclick/php-webdriver/lib/WebDriver/Exception/SessionNotCreated.php b/vendor/instaclick/php-webdriver/lib/WebDriver/Exception/SessionNotCreated.php
new file mode 100644 (file)
index 0000000..d2c5c99
--- /dev/null
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Copyright 2004-2017 Facebook. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package WebDriver
+ *
+ * @author Justin Bishop <jubishop@gmail.com>
+ * @author Anthon Pang <apang@softwaredevelopment.ca>
+ */
+
+namespace WebDriver\Exception;
+
+use WebDriver\Exception as BaseException;
+
+/**
+ * WebDriver\Exception\SessionNotCreated class
+ *
+ * @package WebDriver
+ */
+final class SessionNotCreated extends BaseException
+{
+}
diff --git a/vendor/instaclick/php-webdriver/lib/WebDriver/Exception/StaleElementReference.php b/vendor/instaclick/php-webdriver/lib/WebDriver/Exception/StaleElementReference.php
new file mode 100644 (file)
index 0000000..2c6f21a
--- /dev/null
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Copyright 2004-2017 Facebook. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package WebDriver
+ *
+ * @author Justin Bishop <jubishop@gmail.com>
+ * @author Anthon Pang <apang@softwaredevelopment.ca>
+ */
+
+namespace WebDriver\Exception;
+
+use WebDriver\Exception as BaseException;
+
+/**
+ * WebDriver\Exception\StaleElementReference class
+ *
+ * @package WebDriver
+ */
+final class StaleElementReference extends BaseException
+{
+}
diff --git a/vendor/instaclick/php-webdriver/lib/WebDriver/Exception/Timeout.php b/vendor/instaclick/php-webdriver/lib/WebDriver/Exception/Timeout.php
new file mode 100644 (file)
index 0000000..7c1b7ad
--- /dev/null
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Copyright 2004-2017 Facebook. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package WebDriver
+ *
+ * @author Justin Bishop <jubishop@gmail.com>
+ * @author Anthon Pang <apang@softwaredevelopment.ca>
+ */
+
+namespace WebDriver\Exception;
+
+use WebDriver\Exception as BaseException;
+
+/**
+ * WebDriver\Exception\Timeout class
+ *
+ * @package WebDriver
+ */
+final class Timeout extends BaseException
+{
+}
diff --git a/vendor/instaclick/php-webdriver/lib/WebDriver/Exception/UnableToSetCookie.php b/vendor/instaclick/php-webdriver/lib/WebDriver/Exception/UnableToSetCookie.php
new file mode 100644 (file)
index 0000000..7fc6b11
--- /dev/null
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Copyright 2004-2017 Facebook. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package WebDriver
+ *
+ * @author Justin Bishop <jubishop@gmail.com>
+ * @author Anthon Pang <apang@softwaredevelopment.ca>
+ */
+
+namespace WebDriver\Exception;
+
+use WebDriver\Exception as BaseException;
+
+/**
+ * WebDriver\Exception\UnableToSetCookie class
+ *
+ * @package WebDriver
+ */
+final class UnableToSetCookie extends BaseException
+{
+}
diff --git a/vendor/instaclick/php-webdriver/lib/WebDriver/Exception/UnexpectedAlertOpen.php b/vendor/instaclick/php-webdriver/lib/WebDriver/Exception/UnexpectedAlertOpen.php
new file mode 100644 (file)
index 0000000..0ad6640
--- /dev/null
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Copyright 2004-2017 Facebook. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package WebDriver
+ *
+ * @author Justin Bishop <jubishop@gmail.com>
+ * @author Anthon Pang <apang@softwaredevelopment.ca>
+ */
+
+namespace WebDriver\Exception;
+
+use WebDriver\Exception as BaseException;
+
+/**
+ * WebDriver\Exception\UnexpectedAlertOpen class
+ *
+ * @package WebDriver
+ */
+final class UnexpectedAlertOpen extends BaseException
+{
+}
diff --git a/vendor/instaclick/php-webdriver/lib/WebDriver/Exception/UnexpectedParameters.php b/vendor/instaclick/php-webdriver/lib/WebDriver/Exception/UnexpectedParameters.php
new file mode 100644 (file)
index 0000000..a0c3f4e
--- /dev/null
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Copyright 2004-2014 Facebook. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package WebDriver
+ *
+ * @author Justin Bishop <jubishop@gmail.com>
+ * @author Anthon Pang <apang@softwaredevelopment.ca>
+ */
+
+namespace WebDriver\Exception;
+
+use WebDriver\Exception as BaseException;
+
+/**
+ * WebDriver\Exception\UnexpectedParameters class
+ *
+ * @package WebDriver
+ */
+final class UnexpectedParameters extends BaseException
+{
+}
diff --git a/vendor/instaclick/php-webdriver/lib/WebDriver/Exception/UnknownCommand.php b/vendor/instaclick/php-webdriver/lib/WebDriver/Exception/UnknownCommand.php
new file mode 100644 (file)
index 0000000..e03a746
--- /dev/null
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Copyright 2004-2017 Facebook. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package WebDriver
+ *
+ * @author Justin Bishop <jubishop@gmail.com>
+ * @author Anthon Pang <apang@softwaredevelopment.ca>
+ */
+
+namespace WebDriver\Exception;
+
+use WebDriver\Exception as BaseException;
+
+/**
+ * WebDriver\Exception\UnknownCommand class
+ *
+ * @package WebDriver
+ */
+final class UnknownCommand extends BaseException
+{
+}
diff --git a/vendor/instaclick/php-webdriver/lib/WebDriver/Exception/UnknownError.php b/vendor/instaclick/php-webdriver/lib/WebDriver/Exception/UnknownError.php
new file mode 100644 (file)
index 0000000..4773fd1
--- /dev/null
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Copyright 2004-2017 Facebook. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package WebDriver
+ *
+ * @author Justin Bishop <jubishop@gmail.com>
+ * @author Anthon Pang <apang@softwaredevelopment.ca>
+ */
+
+namespace WebDriver\Exception;
+
+use WebDriver\Exception as BaseException;
+
+/**
+ * WebDriver\Exception\UnknownError class
+ *
+ * @package WebDriver
+ */
+final class UnknownError extends BaseException
+{
+}
diff --git a/vendor/instaclick/php-webdriver/lib/WebDriver/Exception/UnknownLocatorStrategy.php b/vendor/instaclick/php-webdriver/lib/WebDriver/Exception/UnknownLocatorStrategy.php
new file mode 100644 (file)
index 0000000..bd0050e
--- /dev/null
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Copyright 2004-2017 Facebook. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package WebDriver
+ *
+ * @author Justin Bishop <jubishop@gmail.com>
+ * @author Anthon Pang <apang@softwaredevelopment.ca>
+ */
+
+namespace WebDriver\Exception;
+
+use WebDriver\Exception as BaseException;
+
+/**
+ * WebDriver\Exception\UnknownLocatorStrategy class
+ *
+ * @package WebDriver
+ */
+final class UnknownLocatorStrategy extends BaseException
+{
+}
diff --git a/vendor/instaclick/php-webdriver/lib/WebDriver/Exception/XPathLookupError.php b/vendor/instaclick/php-webdriver/lib/WebDriver/Exception/XPathLookupError.php
new file mode 100644 (file)
index 0000000..94110eb
--- /dev/null
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Copyright 2004-2017 Facebook. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package WebDriver
+ *
+ * @author Justin Bishop <jubishop@gmail.com>
+ * @author Anthon Pang <apang@softwaredevelopment.ca>
+ */
+
+namespace WebDriver\Exception;
+
+use WebDriver\Exception as BaseException;
+
+/**
+ * WebDriver\Exception\XPathLookupError class
+ *
+ * @package WebDriver
+ */
+final class XPathLookupError extends BaseException
+{
+}
diff --git a/vendor/instaclick/php-webdriver/lib/WebDriver/Frame.php b/vendor/instaclick/php-webdriver/lib/WebDriver/Frame.php
new file mode 100644 (file)
index 0000000..464bcc6
--- /dev/null
@@ -0,0 +1,42 @@
+<?php
+/**
+ * Copyright 2011-2017 Anthon Pang. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package WebDriver
+ *
+ * @author Anthon Pang <apang@softwaredevelopment.ca>
+ */
+
+namespace WebDriver;
+
+/**
+ * WebDriver\Frame class
+ *
+ * @package WebDriver
+ *
+ * @method void parentt() Change focus to the parent context.
+ */
+final class Frame extends AbstractWebDriver
+{
+    /**
+     * {@inheritdoc}
+     */
+    protected function methods()
+    {
+        return array(
+            'parent' => array('POST'),
+        );
+    }
+}
diff --git a/vendor/instaclick/php-webdriver/lib/WebDriver/Ime.php b/vendor/instaclick/php-webdriver/lib/WebDriver/Ime.php
new file mode 100644 (file)
index 0000000..37ea785
--- /dev/null
@@ -0,0 +1,50 @@
+<?php
+/**
+ * Copyright 2011-2017 Anthon Pang. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package WebDriver
+ *
+ * @author Anthon Pang <apang@softwaredevelopment.ca>
+ */
+
+namespace WebDriver;
+
+/**
+ * WebDriver\Ime class
+ *
+ * @package WebDriver
+ *
+ * @method array available_engines() List all available engines on the machines.
+ * @method string active_engine() Get the name of the active IME engine.
+ * @method boolean activated() Indicates whether IME input is active at the moment.
+ * @method void deactivate() De-activates the currently active IME engine.
+ * @method void activate($json) Make an engine that is available active.
+ */
+final class Ime extends AbstractWebDriver
+{
+    /**
+     * {@inheritdoc}
+     */
+    protected function methods()
+    {
+        return array(
+            'available_engines' => array('GET'),
+            'active_engine' => array('GET'),
+            'activated' => array('GET'),
+            'deactivate' => array('POST'),
+            'activate' => array('POST'),
+        );
+    }
+}
diff --git a/vendor/instaclick/php-webdriver/lib/WebDriver/Key.php b/vendor/instaclick/php-webdriver/lib/WebDriver/Key.php
new file mode 100644 (file)
index 0000000..ee6fbdc
--- /dev/null
@@ -0,0 +1,96 @@
+<?php
+/**
+ * Copyright 2011-2017 Anthon Pang. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package WebDriver
+ *
+ * @author Anthon Pang <apang@softwaredevelopment.ca>
+ * @author Fabrizio Branca <mail@fabrizio-branca.de>
+ */
+
+namespace WebDriver;
+
+/**
+ * WebDriver\Key class
+ *
+ * @package WebDriver
+ */
+final class Key
+{
+    /*
+     * The Unicode "Private Use Area" code points (0xE000-0xF8FF) are used to represent
+     * pressable, non-text keys.
+     *
+     * @link http://code.google.com/p/selenium/wiki/JsonWireProtocol#/session/:sessionId/element/:id/value
+     *
+     *    key_name    = "UTF-8";        // UCS-2
+     */
+    const NULL_KEY    = "\xEE\x80\x80"; // E000
+    const CANCEL      = "\xEE\x80\x81"; // E001
+    const HELP        = "\xEE\x80\x82"; // E002
+    const BACKSPACE   = "\xEE\x80\x83"; // E003
+    const TAB         = "\xEE\x80\x84"; // E004
+    const CLEAR       = "\xEE\x80\x85"; // E005
+    const RETURN_KEY  = "\xEE\x80\x86"; // E006
+    const ENTER       = "\xEE\x80\x87"; // E007
+    const SHIFT       = "\xEE\x80\x88"; // E008
+    const CONTROL     = "\xEE\x80\x89"; // E009
+    const ALT         = "\xEE\x80\x8A"; // E00A
+    const PAUSE       = "\xEE\x80\x8B"; // E00B
+    const ESCAPE      = "\xEE\x80\x8C"; // E00C
+    const SPACE       = "\xEE\x80\x8D"; // E00D
+    const PAGE_UP     = "\xEE\x80\x8E"; // E00E
+    const PAGE_DOWN   = "\xEE\x80\x8F"; // E00F
+    const END         = "\xEE\x80\x90"; // E010
+    const HOME        = "\xEE\x80\x91"; // E011
+    const LEFT_ARROW  = "\xEE\x80\x92"; // E012
+    const UP_ARROW    = "\xEE\x80\x93"; // E013
+    const RIGHT_ARROW = "\xEE\x80\x94"; // E014
+    const DOWN_ARROW  = "\xEE\x80\x95"; // E015
+    const INSERT      = "\xEE\x80\x96"; // E016
+    const DELETE      = "\xEE\x80\x97"; // E017
+    const SEMICOLON   = "\xEE\x80\x98"; // E018
+    const EQUALS      = "\xEE\x80\x99"; // E019
+    const NUMPAD_0    = "\xEE\x80\x9A"; // E01A
+    const NUMPAD_1    = "\xEE\x80\x9B"; // E01B
+    const NUMPAD_2    = "\xEE\x80\x9C"; // E01C
+    const NUMPAD_3    = "\xEE\x80\x9D"; // E01D
+    const NUMPAD_4    = "\xEE\x80\x9E"; // E01E
+    const NUMPAD_5    = "\xEE\x80\x9F"; // E01F
+    const NUMPAD_6    = "\xEE\x80\xA0"; // E020
+    const NUMPAD_7    = "\xEE\x80\xA1"; // E021
+    const NUMPAD_8    = "\xEE\x80\xA2"; // E022
+    const NUMPAD_9    = "\xEE\x80\xA3"; // E023
+    const MULTIPLY    = "\xEE\x80\xA4"; // E024
+    const ADD         = "\xEE\x80\xA5"; // E025
+    const SEPARATOR   = "\xEE\x80\xA6"; // E026
+    const SUBTRACT    = "\xEE\x80\xA7"; // E027
+    const DECIMAL     = "\xEE\x80\xA8"; // E028
+    const DIVIDE      = "\xEE\x80\xA9"; // E029
+    const F1          = "\xEE\x80\xB1"; // E031
+    const F2          = "\xEE\x80\xB2"; // E032
+    const F3          = "\xEE\x80\xB3"; // E033
+    const F4          = "\xEE\x80\xB4"; // E034
+    const F5          = "\xEE\x80\xB5"; // E035
+    const F6          = "\xEE\x80\xB6"; // E036
+    const F7          = "\xEE\x80\xB7"; // E037
+    const F8          = "\xEE\x80\xB8"; // E038
+    const F9          = "\xEE\x80\xB9"; // E039
+    const F10         = "\xEE\x80\xBA"; // E03A
+    const F11         = "\xEE\x80\xBB"; // E03B
+    const F12         = "\xEE\x80\xBC"; // E03C
+    const COMMAND     = "\xEE\x80\xBD"; // E03D
+    const META        = "\xEE\x80\xBD"; // E03D
+}
diff --git a/vendor/instaclick/php-webdriver/lib/WebDriver/LocatorStrategy.php b/vendor/instaclick/php-webdriver/lib/WebDriver/LocatorStrategy.php
new file mode 100644 (file)
index 0000000..1d7dea9
--- /dev/null
@@ -0,0 +1,40 @@
+<?php
+/**
+ * Copyright 2011-2017 Fabrizio Branca. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package WebDriver
+ *
+ * @author Fabrizio Branca <mail@fabrizio-branca.de>
+ * @author Anthon Pang <apang@softwaredevelopment.ca>
+ */
+
+namespace WebDriver;
+
+/**
+ * WebDriver\LocatorStrategy class
+ *
+ * @package WebDriver
+ */
+final class LocatorStrategy
+{
+    const CLASS_NAME        = 'class name';
+    const CSS_SELECTOR      = 'css selector';
+    const ID                = 'id';
+    const NAME              = 'name';
+    const LINK_TEXT         = 'link text';
+    const PARTIAL_LINK_TEXT = 'partial link text';
+    const TAG_NAME          = 'tag name';
+    const XPATH             = 'xpath';
+}
diff --git a/vendor/instaclick/php-webdriver/lib/WebDriver/Log.php b/vendor/instaclick/php-webdriver/lib/WebDriver/Log.php
new file mode 100644 (file)
index 0000000..25b7136
--- /dev/null
@@ -0,0 +1,42 @@
+<?php
+/**
+ * Copyright 2014-2017 Anthon Pang. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package WebDriver
+ *
+ * @author Anthon Pang <apang@softwaredevelopment.ca>
+ */
+
+namespace WebDriver;
+
+/**
+ * WebDriver\Log class
+ *
+ * @package WebDriver
+ *
+ * @method array types() Get available log types.
+ */
+final class Log extends AbstractWebDriver
+{
+    /**
+     * {@inheritdoc}
+     */
+    protected function methods()
+    {
+        return array(
+            'types' => array('GET'),
+        );
+    }
+}
diff --git a/vendor/instaclick/php-webdriver/lib/WebDriver/LogType.php b/vendor/instaclick/php-webdriver/lib/WebDriver/LogType.php
new file mode 100644 (file)
index 0000000..a722aee
--- /dev/null
@@ -0,0 +1,42 @@
+<?php
+/**
+ * Copyright 2014-2017 Anthon Pang. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package WebDriver
+ *
+ * @author Anthon Pang <apang@softwaredevelopment.ca>
+ */
+
+namespace WebDriver;
+
+/**
+ * WebDriver\LogType class
+ *
+ * @package WebDriver
+ */
+final class LogType
+{
+    /**
+     * Log Type
+     *
+     * @see https://code.google.com/p/selenium/source/browse/java/client/src/org/openqa/selenium/logging/LogType.java
+     */
+    const BROWSER     = 'browser';
+    const CLIENT      = 'client';
+    const DRIVER      = 'driver';
+    const PERFORMANCE = 'performance';
+    const PROFILER    = 'driver';
+    const SERVER      = 'server';
+}
diff --git a/vendor/instaclick/php-webdriver/lib/WebDriver/SauceLabs/Capability.php b/vendor/instaclick/php-webdriver/lib/WebDriver/SauceLabs/Capability.php
new file mode 100644 (file)
index 0000000..dc326e1
--- /dev/null
@@ -0,0 +1,76 @@
+<?php
+/**
+ * Copyright 2012-2017 Anthon Pang. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package WebDriver
+ *
+ * @author Anthon Pang <apang@softwaredevelopment.ca>
+ */
+
+namespace WebDriver\SauceLabs;
+
+use WebDriver\Capability as BaseCapability;
+
+/**
+ * WebDriver\SauceLabs\Capability class
+ *
+ * @package WebDriver
+ */
+class Capability extends BaseCapability
+{
+    /**
+     * Desired capabilities - SauceLabs
+     *
+     * @see https://saucelabs.com/docs/additional-config
+     */
+
+    // Job Annotation
+    const NAME                  = 'name';                  // Name the job
+    const BUILD                 = 'build';                 // Record the build number
+    const TAGS                  = 'tags';                  // Tag your jobs
+    const PASSED                = 'passed';                // Record pass/fail status
+    const CUSTOM_DATA           = 'custom-data';           // Record custom data
+
+    // Performance improvements and data collection
+    const RECORD_VIDEO          = 'record-video';          // Video recording
+    const VIDEO_UPLOAD_ON_PASS  = 'video-upload-on-pass';  // Video upload on pass
+    const RECORD_SCREENSHOTS    = 'record-screenshots';    // Record step-by-step screenshots
+    const CAPTURE_HTML          = 'capture-html';          // HTML source capture
+    const QUIET_EXCEPTIONS      = 'webdriver.remote.quietExceptions'; // Enable Selenium 2's automatic screenshots
+    const SAUCE_ADVISOR         = 'sauce-advisor';         // Sauce Advisor
+
+    // Selenium specific
+    const SELENIUM_VERSION      = 'selenium-version';      // Use a specific Selenium version
+    const SINGLE_WINDOW         = 'single-window';         // Selenium RC's single window mode
+    const USER_EXTENSIONS_URL   = 'user-extensions-url';   // Selenium RC's user extensions
+    const FIREFOX_PROFILE_URL   = 'firefox-profile-url';   // Selenium RC's custom Firefox profiles
+
+    // Timeouts
+    const MAX_DURATION          = 'max-duration';          // Set maximum test duration
+    const COMMAND_TIMEOUT       = 'command-timeout';       // Set command timeout
+    const IDLE_TIMEOUT          = 'idle-timeout';          // Set idle test timeout
+
+    // Sauce specific
+    const PRERUN                = 'prerun';                // Prerun executables
+    const TUNNEL_IDENTIFIER     = 'tunnel-identifier';     // Use identified tunnel
+    const SCREEN_RESOLUTION     = 'screen-resolution';     // Use specific screen resolution
+    const DISABLE_POPUP_HANDLER = 'disable-popup-handler'; // Disable popup handler
+    const AVOID_PROXY           = 'avoid-proxy';           // Avoid proxy
+    const DEVICE_ORIENTATION    = 'deviceOrientation';     // Device orientation (portrait or landscape)
+    const DEVICE_TYPE           = 'deviceType';            // Device type (phone or tablet)
+
+    // Job Sharing
+    const PUBLIC_RESULTS        = 'public';                // Make public, private, or share jobs
+}
diff --git a/vendor/instaclick/php-webdriver/lib/WebDriver/SauceLabs/SauceRest.php b/vendor/instaclick/php-webdriver/lib/WebDriver/SauceLabs/SauceRest.php
new file mode 100644 (file)
index 0000000..7bec171
--- /dev/null
@@ -0,0 +1,313 @@
+<?php
+/**
+ * Copyright 2012-2017 Anthon Pang. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package WebDriver
+ *
+ * @author Anthon Pang <apang@softwaredevelopment.ca>
+ * @author Fabrizio Branca <mail@fabrizio-branca.de>
+ */
+
+namespace WebDriver\SauceLabs;
+
+use WebDriver\ServiceFactory;
+
+/**
+ * WebDriver\SauceLabs\SauceRest class
+ *
+ * @package WebDriver
+ */
+class SauceRest
+{
+    /**
+     * @var string
+     */
+    private $userId;
+
+    /**
+     * @var string
+     */
+    private $accessKey;
+
+    /**
+     * Constructor
+     *
+     * @param string $userId    Your Sauce user name
+     * @param string $accessKey Your Sauce API key
+     */
+    public function __construct($userId, $accessKey)
+    {
+        $this->userId = $userId;
+        $this->accessKey = $accessKey;
+    }
+
+    /**
+     * Execute Sauce Labs REST API command
+     *
+     * @param string $requestMethod HTTP request method
+     * @param string $url           URL
+     * @param mixed  $parameters    Parameters
+     *
+     * @return mixed
+     *
+     * @throws \WebDriver\Exception\CurlExec
+     *
+     * @see http://saucelabs.com/docs/saucerest
+     */
+    protected function execute($requestMethod, $url, $parameters = null)
+    {
+        $extraOptions = array(
+            CURLOPT_HTTPAUTH => CURLAUTH_BASIC,
+            CURLOPT_USERPWD => $this->userId . ':' . $this->accessKey,
+
+            // don't verify SSL certificates
+            CURLOPT_SSL_VERIFYPEER => false,
+            CURLOPT_SSL_VERIFYHOST => false,
+
+            CURLOPT_HTTPHEADER => array('Expect:'),
+            CURLOPT_FAILONERROR => true,
+        );
+
+        $url = 'https://saucelabs.com/rest/v1/' . $url;
+
+        list($rawResult, $info) = ServiceFactory::getInstance()->getService('service.curl')->execute($requestMethod, $url, $parameters, $extraOptions);
+
+        return json_decode($rawResult, true);
+    }
+
+    /**
+     * Get account details: /rest/v1/users/:userId (GET)
+     *
+     * @param string $userId
+     *
+     * @return array
+     */
+    public function getAccountDetails($userId)
+    {
+        return $this->execute('GET', 'users/' . $userId);
+    }
+
+    /**
+     * Check account limits: /rest/v1/limits (GET)
+     *
+     * @return array
+     */
+    public function getAccountLimits()
+    {
+        return $this->execute('GET', 'limits');
+    }
+
+    /**
+     * Create new sub-account: /rest/v1/users/:userId (POST)
+     *
+     * For "partners", $accountInfo also contains 'plan' => (one of 'free', 'small', 'team', 'com', or 'complus')
+     *
+     * @param array $accountInfo array('username' => ..., 'password' => ..., 'name' => ..., 'email' => ...)
+     *
+     * @return array array('access_key' => ..., 'minutes' => ..., 'id' => ...)
+     */
+    public function createSubAccount($accountInfo)
+    {
+        return $this->execute('POST', 'users/' . $this->userId, $accountInfo);
+    }
+
+    /**
+     * Update sub-account service plan: /rest/v1/users/:userId/subscription (POST)
+     *
+     * @param string $userId User ID
+     * @param string $plan   Plan
+     *
+     * @return array
+     */
+    public function updateSubAccount($userId, $plan)
+    {
+        return $this->execute('POST', 'users/' . $userId . '/subscription', array('plan' => $plan));
+    }
+
+    /**
+     * Unsubscribe a sub-account: /rest/v1/users/:userId/subscription (DELETE)
+     *
+     * @param string $userId User ID
+     *
+     * @return array
+     */
+    public function unsubscribeSubAccount($userId)
+    {
+        return $this->execute('DELETE', 'users/' . $userId . '/subscription');
+    }
+
+    /**
+     * Get current account activity: /rest/v1/:userId/activity (GET)
+     *
+     * @return array
+     */
+    public function getActivity()
+    {
+        return $this->execute('GET', $this->userId . '/activity');
+    }
+
+    /**
+     * Get historical account usage: /rest/v1/:userId/usage (GET)
+     *
+     * @param string $start Optional start date YYYY-MM-DD
+     * @param string $end   Optional end date YYYY-MM-DD
+     *
+     * @return array
+     */
+    public function getUsage($start = null, $end = null)
+    {
+        $query = http_build_query(array(
+            'start' => $start,
+            'end' => $end,
+        ));
+
+        return $this->execute('GET', $this->userId . '/usage' . (strlen($query) ? '?' . $query : ''));
+    }
+
+    /**
+     * Get jobs: /rest/v1/:userId/jobs (GET)
+     *
+     * @param boolean $full
+     *
+     * @return array
+     */
+    public function getJobs($full = null)
+    {
+        $query = http_build_query(array(
+            'full' => (isset($full) && $full) ? 'true' : null,
+        ));
+
+        return $this->execute('GET', $this->userId . '/jobs' . (strlen($query) ? '?' . $query : ''));
+    }
+
+    /**
+     * Get full information for job: /rest/v1/:userId/jobs/:jobId (GET)
+     *
+     * @param string $jobId
+     *
+     * @return array
+     */
+    public function getJob($jobId)
+    {
+        return $this->execute('GET', $this->userId . '/jobs/' . $jobId);
+    }
+
+    /**
+     * Update existing job: /rest/v1/:userId/jobs/:jobId (PUT)
+     *
+     * @param string $jobId   Job ID
+     * @param array  $jobInfo Job information
+     *
+     * @return array
+     */
+    public function updateJob($jobId, $jobInfo)
+    {
+        return $this->execute('PUT', $this->userId . '/jobs/' . $jobId, $jobInfo);
+    }
+
+    /**
+     * Stop job: /rest/v1/:userId/jobs/:jobId/stop (PUT)
+     *
+     * @param string $jobId
+     *
+     * @return array
+     */
+    public function stopJob($jobId)
+    {
+        return $this->execute('PUT', $this->userId . '/jobs/' . $jobId . '/stop');
+    }
+
+    /**
+     * Delete job: /rest/v1/:userId/jobs/:jobId (DELETE)
+     *
+     * @param string $jobId
+     *
+     * @return array
+     */
+    public function deleteJob($jobId)
+    {
+        return $this->execute('DELETE', $this->userId . '/jobs/' . $jobId);
+    }
+
+    /**
+     * Get running tunnels for a given user: /rest/v1/:userId/tunnels (GET)
+     *
+     * @return array
+     */
+    public function getTunnels()
+    {
+        return $this->execute('GET', $this->userId . '/tunnels');
+    }
+
+    /**
+     * Get full information for a tunnel: /rest/v1/:userId/tunnels/:tunnelId (GET)
+     *
+     * @param string $tunnelId
+     *
+     * @return array
+     */
+    public function getTunnel($tunnelId)
+    {
+        return $this->execute('GET', $this->userId . '/tunnels/' . $tunnelId);
+    }
+
+    /**
+     * Shut down a tunnel: /rest/v1/:userId/tunnels/:tunnelId (DELETE)
+     *
+     * @param string $tunnelId
+     *
+     * @return array
+     */
+    public function shutdownTunnel($tunnelId)
+    {
+        return $this->execute('DELETE', $this->userId . '/tunnels/' . $tunnelId);
+    }
+
+    /**
+     * Get current status of Sauce Labs' services: /rest/v1/info/status (GET)
+     *
+     * @return array array('wait_time' => ..., 'service_operational' => ..., 'status_message' => ...)
+     */
+    public function getStatus()
+    {
+        return $this->execute('GET', 'info/status');
+    }
+
+    /**
+     * Get currently supported browsers: /rest/v1/info/browsers (GET)
+     *
+     * @param string $termination Optional termination (one of "all", "selenium-rc", or "webdriver')
+     *
+     * @return array
+     */
+    public function getBrowsers($termination = false)
+    {
+        if ($termination) {
+            return $this->execute('GET', 'info/browsers/' . $termination);
+        }
+
+        return $this->execute('GET', 'info/browsers');
+    }
+
+    /**
+     * Get number of tests executed so far on Sauce Labs: /rest/v1/info/counter (GET)
+     *
+     * @return array
+     */
+    public function getCounter()
+    {
+        return $this->execute('GET', 'info/counter');
+    }
+}
diff --git a/vendor/instaclick/php-webdriver/lib/WebDriver/Service/CurlService.php b/vendor/instaclick/php-webdriver/lib/WebDriver/Service/CurlService.php
new file mode 100755 (executable)
index 0000000..99af82e
--- /dev/null
@@ -0,0 +1,122 @@
+<?php
+/**
+ * Copyright 2004-2017 Facebook. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package WebDriver
+ *
+ * @author Justin Bishop <jubishop@gmail.com>
+ * @author Anthon Pang <apang@softwaredevelopment.ca>
+ * @author Fabrizio Branca <mail@fabrizio-branca.de>
+ */
+
+namespace WebDriver\Service;
+
+use WebDriver\Exception as WebDriverException;
+
+/**
+ * WebDriver\Service\CurlService class
+ *
+ * @package WebDriver
+ */
+class CurlService implements CurlServiceInterface
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function execute($requestMethod, $url, $parameters = null, $extraOptions = array())
+    {
+        $customHeaders = array(
+            'Content-Type: application/json;charset=UTF-8',
+            'Accept: application/json;charset=UTF-8',
+        );
+
+        $curl = curl_init($url);
+        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
+
+        switch ($requestMethod) {
+            case 'GET':
+                break;
+
+            case 'POST':
+                if ($parameters && is_array($parameters)) {
+                    curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($parameters));
+                } else {
+                    $customHeaders[] = 'Content-Length: 0';
+                }
+
+                // Suppress "Expect: 100-continue" header automatically added by cURL that
+                // causes a 1 second delay if the remote server does not support Expect.
+                $customHeaders[] = 'Expect:';
+
+                curl_setopt($curl, CURLOPT_POST, true);
+                break;
+
+            case 'DELETE':
+                curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'DELETE');
+                break;
+
+            case 'PUT':
+                if ($parameters && is_array($parameters)) {
+                    curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($parameters));
+                } else {
+                    $customHeaders[] = 'Content-Length: 0';
+                }
+
+                // Suppress "Expect: 100-continue" header automatically added by cURL that
+                // causes a 1 second delay if the remote server does not support Expect.
+                $customHeaders[] = 'Expect:';
+
+                curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'PUT');
+                break;
+        }
+
+        foreach ($extraOptions as $option => $value) {
+            curl_setopt($curl, $option, $value);
+        }
+
+        curl_setopt($curl, CURLOPT_HTTPHEADER, $customHeaders);
+
+        $rawResult = trim(curl_exec($curl));
+
+        $info = curl_getinfo($curl);
+        $info['request_method'] = $requestMethod;
+
+        if (array_key_exists(CURLOPT_FAILONERROR, $extraOptions) &&
+            $extraOptions[CURLOPT_FAILONERROR] &&
+            CURLE_GOT_NOTHING !== ($errno = curl_errno($curl)) &&
+            $error = curl_error($curl)
+        ) {
+            curl_close($curl);
+
+            throw WebDriverException::factory(
+                WebDriverException::CURL_EXEC,
+                sprintf(
+                    "Curl error thrown for http %s to %s%s\n\n%s",
+                    $requestMethod,
+                    $url,
+                    $parameters && is_array($parameters) ? ' with params: ' . json_encode($parameters) : '',
+                    $error
+                ),
+                $errno,
+                null,
+                $info
+            );
+        }
+
+        curl_close($curl);
+
+        return array($rawResult, $info);
+    }
+}
diff --git a/vendor/instaclick/php-webdriver/lib/WebDriver/Service/CurlServiceInterface.php b/vendor/instaclick/php-webdriver/lib/WebDriver/Service/CurlServiceInterface.php
new file mode 100755 (executable)
index 0000000..1323531
--- /dev/null
@@ -0,0 +1,45 @@
+<?php
+/**
+ * Copyright 2012-2017 Anthon Pang. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package WebDriver
+ *
+ * @author Anthon Pang <apang@softwaredevelopment.ca>
+ */
+
+namespace WebDriver\Service;
+
+/**
+ * WebDriver\Service\CurlServiceInterface class
+ *
+ * @package WebDriver
+ */
+interface CurlServiceInterface
+{
+    /**
+     * Send protocol request to WebDriver server using curl extension API.
+     *
+     * @param string $requestMethod HTTP request method, e.g., 'GET', 'POST', or 'DELETE'
+     * @param string $url           Request URL
+     * @param array  $parameters    If an array(), they will be posted as JSON parameters
+     *                              If a number or string, "/$params" is appended to url
+     * @param array  $extraOptions  key=>value pairs of curl options to pass to curl_setopt()
+     *
+     * @return array
+     *
+     * @throws \WebDriver\Exception\CurlExec only if http error and CURLOPT_FAILONERROR has been set in extraOptions
+     */
+    public function execute($requestMethod, $url, $parameters = null, $extraOptions = array());
+}
diff --git a/vendor/instaclick/php-webdriver/lib/WebDriver/ServiceFactory.php b/vendor/instaclick/php-webdriver/lib/WebDriver/ServiceFactory.php
new file mode 100755 (executable)
index 0000000..bf03708
--- /dev/null
@@ -0,0 +1,120 @@
+<?php
+/**
+ * Copyright 2012-2017 Anthon Pang. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package WebDriver
+ *
+ * @author Anthon Pang <apang@softwaredevelopment.ca>
+ */
+
+namespace WebDriver;
+
+/**
+ * WebDriver\ServiceFactory class
+ *
+ * A service factory
+ *
+ * @package WebDriver
+ */
+final class ServiceFactory
+{
+    /**
+     * singleton
+     *
+     * @var \WebDriver\ServiceFactory
+     */
+    private static $instance;
+
+    /**
+     * @var array
+     */
+    protected $services;
+
+    /**
+     * @var array
+     */
+    protected $serviceClasses;
+
+    /**
+     * Private constructor
+     */
+    private function __construct()
+    {
+        $this->services = array();
+
+        $this->serviceClasses = array(
+            'service.curl' => '\\WebDriver\\Service\\CurlService',
+        );
+    }
+
+    /**
+     * Get singleton instance
+     *
+     * @return \WebDriver\ServiceFactory
+     */
+    public static function getInstance()
+    {
+        if (!self::$instance) {
+            self::$instance = new self;
+        }
+
+        return self::$instance;
+    }
+
+    /**
+     * Get service
+     *
+     * @param string $serviceName Name of service
+     *
+     * @return object
+     */
+    public function getService($serviceName)
+    {
+        if (!isset($this->services[$serviceName])) {
+            $className = $this->serviceClasses[$serviceName];
+
+            $this->services[$serviceName] = new $className;
+        }
+
+        return $this->services[$serviceName];
+    }
+
+    /**
+     * Set service
+     *
+     * @param string $serviceName Name of service
+     * @param object $service     Service instance
+     */
+    public function setService($serviceName, $service)
+    {
+        $this->services[$serviceName] = $service;
+    }
+
+    /**
+     * Override default service class
+     *
+     * @param string $serviceName Name of service
+     * @param string $className   Name of service class
+     */
+    public function setServiceClass($serviceName, $className)
+    {
+        if (substr($className, 0, 1) !== '\\') {
+            $className = '\\' . $className;
+        }
+
+        $this->serviceClasses[$serviceName] = $className;
+        $this->services[$serviceName] = null;
+    }
+}
diff --git a/vendor/instaclick/php-webdriver/lib/WebDriver/Session.php b/vendor/instaclick/php-webdriver/lib/WebDriver/Session.php
new file mode 100644 (file)
index 0000000..1186745
--- /dev/null
@@ -0,0 +1,436 @@
+<?php
+/**
+ * Copyright 2004-2017 Facebook. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package WebDriver
+ *
+ * @author Justin Bishop <jubishop@gmail.com>
+ * @author Anthon Pang <apang@softwaredevelopment.ca>
+ */
+
+namespace WebDriver;
+
+/**
+ * WebDriver\Session class
+ *
+ * @package WebDriver
+ *
+ * @method string window_handle() Retrieve the current window handle.
+ * @method array window_handles() Retrieve the list of all window handles available to the session.
+ * @method string url() Retrieve the URL of the current page
+ * @method void postUrl($jsonUrl) Navigate to a new URL
+ * @method void forward() Navigates forward in the browser history, if possible.
+ * @method void back() Navigates backward in the browser history, if possible.
+ * @method void refresh() Refresh the current page.
+ * @method mixed execute($jsonScript) Inject a snippet of JavaScript into the page for execution in the context of the currently selected frame. (synchronous)
+ * @method mixed execute_async($jsonScript) Inject a snippet of JavaScript into the page for execution in the context of the currently selected frame. (asynchronous)
+ * @method string screenshot() Take a screenshot of the current page.
+ * @method array getCookie() Retrieve all cookies visible to the current page.
+ * @method array postCookie($jsonCookie) Set a cookie.
+ * @method string source() Get the current page source.
+ * @method string title() Get the current page title.
+ * @method void keys($jsonKeys) Send a sequence of key strokes to the active element.
+ * @method string getOrientation() Get the current browser orientation.
+ * @method void postOrientation($jsonOrientation) Set the current browser orientation.
+ * @method string getAlert_text() Gets the text of the currently displayed JavaScript alert(), confirm(), or prompt() dialog.
+ * @method void postAlert_text($jsonText) Sends keystrokes to a JavaScript prompt() dialog.
+ * @method void accept_alert() Accepts the currently displayed alert dialog.
+ * @method void dismiss_alert() Dismisses the currently displayed alert dialog.
+ * @method void moveto($jsonCoordinates) Move the mouse by an offset of the specified element (or current mouse cursor).
+ * @method void click($jsonButton) Click any mouse button (at the coordinates set by the last moveto command).
+ * @method void buttondown() Click and hold the left mouse button (at the coordinates set by the last moveto command).
+ * @method void buttonup() Releases the mouse button previously held (where the mouse is currently at).
+ * @method void doubleclick() Double-clicks at the current mouse coordinates (set by moveto).
+ * @method array execute_sql($jsonQuery) Execute SQL.
+ * @method array getLocation() Get the current geo location.
+ * @method void postLocation($jsonCoordinates) Set the current geo location.
+ * @method boolean getBrowser_connection() Is browser online?
+ * @method void postBrowser_connection($jsonState) Set browser online.
+ */
+final class Session extends Container
+{
+    /**
+     * @var array
+     */
+    private $capabilities = null;
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function methods()
+    {
+        return array(
+            'window_handle' => array('GET'),
+            'window_handles' => array('GET'),
+            'url' => array('GET', 'POST'), // alternate for POST, use open($url)
+            'forward' => array('POST'),
+            'back' => array('POST'),
+            'refresh' => array('POST'),
+            'execute' => array('POST'),
+            'execute_async' => array('POST'),
+            'screenshot' => array('GET'),
+            'cookie' => array('GET', 'POST'), // for DELETE, use deleteAllCookies()
+            'source' => array('GET'),
+            'title' => array('GET'),
+            'keys' => array('POST'),
+            'orientation' => array('GET', 'POST'),
+            'alert_text' => array('GET', 'POST'),
+            'accept_alert' => array('POST'),
+            'dismiss_alert' => array('POST'),
+            'moveto' => array('POST'),
+            'click' => array('POST'),
+            'buttondown' => 'POST',
+            'buttonup' => array('POST'),
+            'doubleclick' => array('POST'),
+            'execute_sql' => array('POST'),
+            'location' => array('GET', 'POST'),
+            'browser_connection' => array('GET', 'POST'),
+
+            // specific to Java SeleniumServer
+            'file' => array('POST'),
+        );
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function obsoleteMethods()
+    {
+        return array(
+            'modifier' => array('POST'),
+            'speed' => array('GET', 'POST'),
+            'alert' => array('GET'),
+            'visible' => array('GET', 'POST'),
+        );
+    }
+
+    /**
+     * Open URL: /session/:sessionId/url (POST)
+     * An alternative to $session->url($url);
+     *
+     * @param string $url
+     *
+     * @return \WebDriver\Session
+     */
+    public function open($url)
+    {
+        $this->curl('POST', '/url', array('url' => $url));
+
+        return $this;
+    }
+
+    /**
+     * Get browser capabilities: /session/:sessionId (GET)
+     *
+     * @return mixed
+     */
+    public function capabilities()
+    {
+        if (! isset($this->capabilities)) {
+            $result = $this->curl('GET', '');
+
+            $this->capabilities = $result['value'];
+        }
+
+        return $this->capabilities;
+    }
+
+    /**
+     * Close session: /session/:sessionId (DELETE)
+     *
+     * @return mixed
+     */
+    public function close()
+    {
+        $result = $this->curl('DELETE', '');
+
+        return $result['value'];
+    }
+
+    // There's a limit to our ability to exploit the dynamic nature of PHP when it
+    // comes to the cookie methods because GET and DELETE request methods are indistinguishable
+    // from each other: neither takes parameters.
+
+    /**
+     * Get all cookies: /session/:sessionId/cookie (GET)
+     * Alternative to: $session->cookie();
+     *
+     * Note: get cookie by name not implemented in API
+     *
+     * @return mixed
+     */
+    public function getAllCookies()
+    {
+        $result = $this->curl('GET', '/cookie');
+
+        return $result['value'];
+    }
+
+    /**
+     * Set cookie: /session/:sessionId/cookie (POST)
+     * Alternative to: $session->cookie($cookie_json);
+     *
+     * @param array $cookieJson
+     *
+     * @return \WebDriver\Session
+     */
+    public function setCookie($cookieJson)
+    {
+        $this->curl('POST', '/cookie', array('cookie' => $cookieJson));
+
+        return $this;
+    }
+
+    /**
+     * Delete all cookies: /session/:sessionId/cookie (DELETE)
+     *
+     * @return \WebDriver\Session
+     */
+    public function deleteAllCookies()
+    {
+        $this->curl('DELETE', '/cookie');
+
+        return $this;
+    }
+
+    /**
+     * Delete a cookie: /session/:sessionId/cookie/:name (DELETE)
+     *
+     * @param string $cookieName
+     *
+     * @return \WebDriver\Session
+     */
+    public function deleteCookie($cookieName)
+    {
+        $this->curl('DELETE', '/cookie/' . $cookieName);
+
+        return $this;
+    }
+
+    /**
+     * window methods: /session/:sessionId/window (POST, DELETE)
+     * - $session->window() - close current window
+     * - $session->window($name) - set focus
+     * - $session->window($window_handle)->method() - chaining
+     *
+     * @return \WebDriver\Window|\WebDriver\Session
+     */
+    public function window()
+    {
+        // close current window
+        if (func_num_args() === 0) {
+            $this->curl('DELETE', '/window');
+
+            return $this;
+        }
+
+        // set focus
+        $arg = func_get_arg(0); // window handle or name attribute
+
+        if (is_array($arg)) {
+            $this->curl('POST', '/window', $arg);
+
+            return $this;
+        }
+
+        // chaining
+        return new Window($this->url . '/window', $arg);
+    }
+
+    /**
+     * Delete window: /session/:sessionId/window (DELETE)
+     *
+     * @return \WebDriver\Session
+     */
+    public function deleteWindow()
+    {
+        $this->curl('DELETE', '/window');
+
+        return $this;
+    }
+
+    /**
+     * Set focus to window: /session/:sessionId/window (POST)
+     *
+     * @param mixed $name window handler or name attribute
+     *
+     * @return \WebDriver\Session
+     */
+    public function focusWindow($name)
+    {
+        $this->curl('POST', '/window', array('name' => $name));
+
+        return $this;
+    }
+
+    /**
+     * frame methods: /session/:sessionId/frame (POST)
+     * - $session->frame($json) - change focus to another frame on the page
+     * - $session->frame()->method() - chaining
+     *
+     * @return \WebDriver\Session|\WebDriver\Frame
+     */
+    public function frame()
+    {
+        if (func_num_args() === 1) {
+            $arg = func_get_arg(0); // json
+
+            $this->curl('POST', '/frame', $arg);
+
+            return $this;
+        }
+
+        // chaining
+        return new Frame($this->url . '/frame');
+    }
+
+    /**
+     * timeouts methods: /session/:sessionId/timeouts (POST)
+     * - $session->timeouts($json) - set timeout for an operation
+     * - $session->timeouts()->method() - chaining
+     *
+     * @return \WebDriver\Session|\WebDriver\Timeouts
+     */
+    public function timeouts()
+    {
+        // set timeouts
+        if (func_num_args() === 1) {
+            $arg = func_get_arg(0); // json
+
+            $this->curl('POST', '/timeouts', $arg);
+
+            return $this;
+        }
+
+        if (func_num_args() === 2) {
+            $arg = array(
+                'type' => func_get_arg(0), // 'script' or 'implicit'
+                'ms' => func_get_arg(1),   // timeout in milliseconds
+            );
+
+            $this->curl('POST', '/timeouts', $arg);
+
+            return $this;
+        }
+
+        // chaining
+        return new Timeouts($this->url . '/timeouts');
+    }
+
+    /**
+     * ime method chaining, e.g.,
+     * - $session->ime()->method()
+     *
+     * @return \WebDriver\Ime
+     */
+    public function ime()
+    {
+        return new Ime($this->url . '/ime');
+    }
+
+    /**
+     * Get active element (i.e., has focus): /session/:sessionId/element/active (POST)
+     * - $session->activeElement()
+     *
+     * @return mixed
+     */
+    public function activeElement()
+    {
+        $result = $this->curl('POST', '/element/active');
+
+        return $this->webDriverElement($result['value']);
+    }
+
+    /**
+     * touch method chaining, e.g.,
+     * - $session->touch()->method()
+     *
+     * @return \WebDriver\Touch
+     *
+     */
+    public function touch()
+    {
+        return new Touch($this->url . '/touch');
+    }
+
+    /**
+     * local_storage method chaining, e.g.,
+     * - $session->local_storage()->method()
+     *
+     * @return \WebDriver\Storage
+     */
+    public function local_storage()
+    {
+        return Storage::factory('local', $this->url . '/local_storage');
+    }
+
+    /**
+     * session_storage method chaining, e.g.,
+     * - $session->session_storage()->method()
+     *
+     * @return \WebDriver\Storage
+     */
+    public function session_storage()
+    {
+        return Storage::factory('session', $this->url . '/session_storage');
+    }
+
+    /**
+     * application cache chaining, e.g.,
+     * - $session->application_cache()->status()
+     *
+     * @return \WebDriver\ApplicationCache
+     */
+    public function application_cache()
+    {
+        return new ApplicationCache($this->url . '/application_cache');
+    }
+
+    /**
+     * log methods: /session/:sessionId/log (POST)
+     * - $session->log($type) - get log for given log type
+     * - $session->log()->method() - chaining
+     *
+     * @return mixed
+     */
+    public function log()
+    {
+        // get log for given log type
+        if (func_num_args() === 1) {
+            $arg = func_get_arg(0);
+
+            if (is_string($arg)) {
+                $arg = array(
+                    'type' => $arg,
+                );
+            }
+
+            $result = $this->curl('POST', '/log', $arg);
+
+            return $result['value'];
+        }
+
+        // chaining
+        return new Log($this->url . '/log');
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function getElementPath($elementId)
+    {
+        return sprintf('%s/element/%s', $this->url, $elementId);
+    }
+}
diff --git a/vendor/instaclick/php-webdriver/lib/WebDriver/Storage.php b/vendor/instaclick/php-webdriver/lib/WebDriver/Storage.php
new file mode 100644 (file)
index 0000000..d4586ff
--- /dev/null
@@ -0,0 +1,146 @@
+<?php
+/**
+ * Copyright 2011-2017 Anthon Pang. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package WebDriver
+ *
+ * @author Anthon Pang <apang@softwaredevelopment.ca>
+ */
+
+namespace WebDriver;
+
+use WebDriver\Exception as WebDriverException;
+
+/**
+ * WebDriver\Storage class
+ *
+ * @package WebDriver
+ *
+ * @method mixed getKey($key) Get key/value pair.
+ * @method void deleteKey($key) Delete a specific key.
+ * @method integer size() Get the number of items in the storage.
+ */
+abstract class Storage extends AbstractWebDriver
+{
+    /**
+     * {@inheritdoc}
+     */
+    protected function methods()
+    {
+        return array(
+            'key' => array('GET', 'DELETE'),
+            'size' => array('GET'),
+        );
+    }
+
+    /**
+     * Get all keys from storage or a specific key/value pair
+     *
+     * @return mixed
+     */
+    public function get()
+    {
+        // get all keys
+        if (func_num_args() === 0) {
+            $result = $this->curl('GET', '');
+
+            return $result['value'];
+        }
+
+        // get key/value pair
+        if (func_num_args() === 1) {
+            return $this->getKey(func_get_arg(0));
+        }
+
+        throw WebDriverException::factory(WebDriverException::UNEXPECTED_PARAMETERS);
+    }
+
+    /**
+     * Set specific key/value pair
+     *
+     * @return \WebDriver\Storage
+     *
+     * @throw \WebDriver\Exception\UnexpectedParameters if unexpected parameters
+     */
+    public function set()
+    {
+        if (func_num_args() === 1
+            && is_array($arg = func_get_arg(0))
+        ) {
+            $this->curl('POST', '', $arg);
+
+            return $this;
+        }
+
+        if (func_num_args() === 2) {
+            $arg = array(
+                'key' => func_get_arg(0),
+                'value' => func_get_arg(1),
+            );
+            $this->curl('POST', '', $arg);
+
+            return $this;
+        }
+
+        throw WebDriverException::factory(WebDriverException::UNEXPECTED_PARAMETERS);
+    }
+
+    /**
+     * Delete storage or a specific key
+     *
+     * @return \WebDriver\Storage
+     *
+     * @throw \WebDriver\Exception\UnexpectedParameters if unexpected parameters
+     */
+    public function delete()
+    {
+        // delete storage
+        if (func_num_args() === 0) {
+            $this->curl('DELETE', '');
+
+            return $this;
+        }
+
+        // delete key from storage
+        if (func_num_args() === 1) {
+            return $this->deleteKey(func_get_arg(0));
+        }
+
+        throw WebDriverException::factory(WebDriverException::UNEXPECTED_PARAMETERS);
+    }
+
+    /**
+     * Factory method to create Storage objects
+     *
+     * @param string $type 'local' or 'session' storage
+     * @param string $url  URL
+     *
+     * @return \WebDriver\Storage
+     */
+    public static function factory($type, $url)
+    {
+        // dynamically define custom storage classes
+        $className = ucfirst(strtolower($type));
+        $namespacedClassName = __CLASS__ . '\\' . $className;
+
+        if (!class_exists($namespacedClassName, false)) {
+            eval(
+                'namespace ' . __CLASS__ . '; final class ' . $className . ' extends \\' . __CLASS__ . '{}'
+            );
+        }
+
+        return new $namespacedClassName($url);
+    }
+}
diff --git a/vendor/instaclick/php-webdriver/lib/WebDriver/Timeouts.php b/vendor/instaclick/php-webdriver/lib/WebDriver/Timeouts.php
new file mode 100644 (file)
index 0000000..4ce7251
--- /dev/null
@@ -0,0 +1,76 @@
+<?php
+/**
+ * Copyright 2011-2017 Anthon Pang. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package WebDriver
+ *
+ * @author Anthon Pang <apang@softwaredevelopment.ca>
+ */
+
+namespace WebDriver;
+
+use WebDriver\Exception as WebDriverException;
+
+/**
+ * WebDriver\Timeouts class
+ *
+ * @package WebDriver
+ *
+ * @method void async_script($json) Set the amount of time, in milliseconds, that asynchronous scripts (executed by execute_async) are permitted to run before they are aborted and a timeout error is returned to the client.
+ * @method void implicit_wait($json) Set the amount of time the driver should wait when searching for elements.
+ */
+final class Timeouts extends AbstractWebDriver
+{
+    /**
+     * {@inheritdoc}
+     */
+    protected function methods()
+    {
+        return array(
+            'async_script' => array('POST'),
+            'implicit_wait' => array('POST'),
+        );
+    }
+
+    /**
+     * helper method to wait until user-defined condition is met
+     *
+     * @param function $callback      callback which returns non-false result if wait condition was met
+     * @param integer  $maxIterations maximum number of iterations
+     * @param integer  $sleep         sleep duration in seconds between iterations
+     * @param array    $args          optional args; if the callback needs $this, then pass it here
+     *
+     * @return mixed result from callback function
+     *
+     * @throws \Exception if thrown by callback, or \WebDriver\Exception\Timeout if helper times out
+     */
+    public function wait($callback, $maxIterations = 1, $sleep = 0, $args = array())
+    {
+        $i = max(1, $maxIterations);
+
+        while ($i-- > 0) {
+            $result = call_user_func_array($callback, $args);
+
+            if ($result !== false) {
+                return $result;
+            }
+
+            // don't sleep on the last iteration
+            $i && sleep($sleep);
+        }
+
+        throw WebDriverException::factory(WebDriverException::TIMEOUT, 'wait() method timed out');
+    }
+}
diff --git a/vendor/instaclick/php-webdriver/lib/WebDriver/Touch.php b/vendor/instaclick/php-webdriver/lib/WebDriver/Touch.php
new file mode 100644 (file)
index 0000000..af21bba
--- /dev/null
@@ -0,0 +1,56 @@
+<?php
+/**
+ * Copyright 2011-2017 Anthon Pang. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package WebDriver
+ *
+ * @author Anthon Pang <apang@softwaredevelopment.ca>
+ */
+
+namespace WebDriver;
+
+/**
+ * WebDriver\Touch class
+ *
+ * @package WebDriver
+ *
+ * @method void click($jsonElement) Single tap on the touch enabled device.
+ * @method void down($jsonCoordinates) Finger down on the screen.
+ * @method void up($jsonCoordinates) Finger up on the screen.
+ * @method void move($jsonCoordinates) Finger move on the screen.
+ * @method void scroll($jsonCoordinates) Scroll on the touch screen using finger based motion events.  Coordinates are either absolute, or relative to a element (if specified).
+ * @method void doubleclick($jsonElement) Double tap on the touch screen using finger motion events.
+ * @method void longclick($jsonElement) Long press on the touch screen using finger motion events.
+ * @method void flick($json) Flick on the touch screen using finger motion events.
+ */
+final class Touch extends AbstractWebDriver
+{
+    /**
+     * {@inheritdoc}
+     */
+    protected function methods()
+    {
+        return array(
+            'click' => array('POST'),
+            'down' => array('POST'),
+            'up' => array('POST'),
+            'move' => array('POST'),
+            'scroll' => array('POST'),
+            'doubleclick' => array('POST'),
+            'longclick' => array('POST'),
+            'flick' => array('POST'),
+        );
+    }
+}
diff --git a/vendor/instaclick/php-webdriver/lib/WebDriver/WebDriver.php b/vendor/instaclick/php-webdriver/lib/WebDriver/WebDriver.php
new file mode 100644 (file)
index 0000000..0c34dcf
--- /dev/null
@@ -0,0 +1,90 @@
+<?php
+/**
+ * Copyright 2004-2017 Facebook. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package WebDriver
+ *
+ * @author Justin Bishop <jubishop@gmail.com>
+ * @author Anthon Pang <apang@softwaredevelopment.ca>
+ */
+
+namespace WebDriver;
+
+/**
+ * WebDriver class
+ *
+ * @package WebDriver
+ *
+ * @method status
+ */
+class WebDriver extends AbstractWebDriver implements WebDriverInterface
+{
+    /**
+     * {@inheritdoc}
+     */
+    protected function methods()
+    {
+        return array(
+            'status' => 'GET',
+        );
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function session($requiredCapabilities = Browser::FIREFOX, $desiredCapabilities = array())
+    {
+        // for backwards compatibility when the only required capability was browser name
+        if (! is_array($requiredCapabilities)) {
+            $desiredCapabilities[Capability::BROWSER_NAME] = $requiredCapabilities ?: Browser::FIREFOX;
+
+            $requiredCapabilities = array();
+        }
+
+        // required
+        $parameters = array(
+            'desiredCapabilities' => array_merge($desiredCapabilities, $requiredCapabilities)
+        );
+
+        // optional
+        if (! empty($requiredCapabilities)) {
+            $parameters['requiredCapabilities'] = $requiredCapabilities;
+        }
+
+        $result = $this->curl(
+            'POST',
+            '/session',
+            $parameters,
+            array(CURLOPT_FOLLOWLOCATION => true)
+        );
+
+        return new Session($result['sessionUrl']);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function sessions()
+    {
+        $result   = $this->curl('GET', '/sessions');
+        $sessions = array();
+
+        foreach ($result['value'] as $session) {
+            $sessions[] = new Session($this->url . '/session/' . $session['id']);
+        }
+
+        return $sessions;
+    }
+}
diff --git a/vendor/instaclick/php-webdriver/lib/WebDriver/WebDriverInterface.php b/vendor/instaclick/php-webdriver/lib/WebDriver/WebDriverInterface.php
new file mode 100644 (file)
index 0000000..f9bdc67
--- /dev/null
@@ -0,0 +1,49 @@
+<?php
+/**
+ * Copyright 2004-2017 Facebook. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package WebDriver
+ *
+ * @author Justin Bishop <jubishop@gmail.com>
+ * @author Anthon Pang <apang@softwaredevelopment.ca>
+ */
+
+namespace WebDriver;
+
+/**
+ * WebDriverInterface interface
+ *
+ * @package WebDriver
+ */
+interface WebDriverInterface
+{
+    /**
+     * New Session: /session (POST)
+     * Get session object for chaining
+     *
+     * @param array|string $requiredCapabilities Required capabilities (or browser name)
+     * @param array        $desiredCapabilities  Desired capabilities
+     *
+     * @return \WebDriver\Session
+     */
+    public function session($requiredCapabilities = Browser::FIREFOX, $desiredCapabilities = array());
+
+    /**
+     * Get list of currently active sessions
+     *
+     * @return array an array of \WebDriver\Session objects
+     */
+    public function sessions();
+}
diff --git a/vendor/instaclick/php-webdriver/lib/WebDriver/Window.php b/vendor/instaclick/php-webdriver/lib/WebDriver/Window.php
new file mode 100644 (file)
index 0000000..2aad99c
--- /dev/null
@@ -0,0 +1,89 @@
+<?php
+/**
+ * Copyright 2011-2017 Anthon Pang. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package WebDriver
+ *
+ * @author Anthon Pang <apang@softwaredevelopment.ca>
+ * @author Fabrizio Branca <mail@fabrizio-branca.de>
+ */
+
+namespace WebDriver;
+
+/**
+ * WebDriver\Window class
+ *
+ * @package WebDriver
+ *
+ * @method array getSize() Get size of the window.
+ * @method void postSize($json) Change the size of the window.
+ * @method array getPosition() Get position of the window.
+ * @method void postPosition($json) Change position of the window.
+ * @method void maximize() Maximize the window if not already maximized.
+ */
+final class Window extends AbstractWebDriver
+{
+    /**
+     * Window handle
+     *
+     * @var string
+     */
+    private $windowHandle;
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function methods()
+    {
+        return array(
+            'size' => array('GET', 'POST'),
+            'position' => array('GET', 'POST'),
+            'maximize' => array('POST'),
+        );
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function obsoleteMethods()
+    {
+        return array(
+            'restore' => array('POST'),
+        );
+    }
+
+    /**
+     * Get window handle
+     *
+     * @return string
+     */
+    public function getHandle()
+    {
+        return $this->windowHandle;
+    }
+
+    /**
+     * Constructor
+     *
+     * @param string $url          URL
+     * @param string $windowHandle Window handle
+     */
+    public function __construct($url, $windowHandle)
+    {
+        $this->windowHandle = $windowHandle;
+
+        parent::__construct($url . '/' . $windowHandle);
+    }
+}
diff --git a/vendor/instaclick/php-webdriver/phpdoc.dist.xml b/vendor/instaclick/php-webdriver/phpdoc.dist.xml
new file mode 100644 (file)
index 0000000..c58cae1
--- /dev/null
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<phpdoc>
+    <title>PHP WebDriver for Selenium 2</title>
+    <parser>
+        <target>doc</target>
+        <markers>
+            <item>TODO</item>
+            <item>FIXME</item>
+        </markers>
+        <extensions>
+            <extension>php</extension>
+        </extensions>
+        <visibility></visibility>
+    </parser>
+    <transformer>
+        <target>doc</target>
+    </transformer>
+    <logging>
+        <level>warn</level>
+        <paths>
+            <default>logs/phpdoc.log</default>
+            <errors>logs/phpdoc.errors.log</errors>
+        </paths>
+    </logging>
+    <transformations>
+        <template name="responsive" />
+    </transformations>
+    <files>
+        <directory>lib</directory>
+    </files>
+</phpdoc>
diff --git a/vendor/instaclick/php-webdriver/phpunit.xml.dist b/vendor/instaclick/php-webdriver/phpunit.xml.dist
new file mode 100644 (file)
index 0000000..836e35d
--- /dev/null
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!-- http://www.phpunit.de/manual/current/en/appendixes.configuration.html -->
+<phpunit
+    backupGlobals               = "false"
+    backupStaticAttributes      = "false"
+    colors                      = "true"
+    convertErrorsToExceptions   = "true"
+    convertNoticesToExceptions  = "true"
+    convertWarningsToExceptions = "true"
+    processIsolation            = "false"
+    stopOnFailure               = "false"
+    syntaxCheck                 = "false"
+    bootstrap                   = "lib/WebDriver/ClassLoader.php" >
+
+    <testsuites>
+        <testsuite name="Project Test Suite">
+            <directory>test/Test</directory>
+        </testsuite>
+    </testsuites>
+
+    <filter>
+        <whitelist>
+            <directory>lib</directory>
+            <exclude>
+                <file>__init__.php</file>
+            </exclude>
+        </whitelist>
+    </filter>
+
+</phpunit>
diff --git a/vendor/instaclick/php-webdriver/test/Assets/index.html b/vendor/instaclick/php-webdriver/test/Assets/index.html
new file mode 100644 (file)
index 0000000..71ce692
--- /dev/null
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+<head lang="en">
+    <meta charset="UTF-8">
+    <title></title>
+</head>
+<body>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/vendor/instaclick/php-webdriver/test/CI/Travis/setup_apache.sh b/vendor/instaclick/php-webdriver/test/CI/Travis/setup_apache.sh
new file mode 100644 (file)
index 0000000..c33abe7
--- /dev/null
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+# set up Apache
+# @see https://github.com/travis-ci/travis-ci.github.com/blob/master/docs/user/languages/php.md#apache--php
+
+sudo a2enmod rewrite actions fastcgi alias ssl
+
+# configure apache root dir
+sudo sed -i -e "s,/var/www,$(pwd),g" /etc/apache2/sites-available/default
+sudo service apache2 restart
diff --git a/vendor/instaclick/php-webdriver/test/CI/Travis/setup_selenium.sh b/vendor/instaclick/php-webdriver/test/CI/Travis/setup_selenium.sh
new file mode 100644 (file)
index 0000000..ceb6756
--- /dev/null
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+# set up Selenium for functional tests
+
+wget --max-redirect=1 https://goo.gl/s4o9Vx -O selenium.jar
+
+java -jar selenium.jar &
diff --git a/vendor/instaclick/php-webdriver/test/Test/WebDriver/ExceptionTest.php b/vendor/instaclick/php-webdriver/test/Test/WebDriver/ExceptionTest.php
new file mode 100644 (file)
index 0000000..508a43b
--- /dev/null
@@ -0,0 +1,52 @@
+<?php
+/**
+ * Copyright 2011-2017 Anthon Pang. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package WebDriver
+ *
+ * @author Anthon Pang <apang@softwaredevelopment.ca>
+ */
+
+namespace Test\WebDriver;
+
+use WebDriver\Exception;
+
+/**
+ * Test WebDriver\Exception class
+ *
+ * @package WebDriver
+ *
+ * @group Unit
+ */
+class ExceptionTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * test factory()
+     */
+    public function testFactory()
+    {
+        $out = Exception::factory(255, 'wtf');
+        $this->assertTrue(get_class($out) === 'Exception');
+        $this->assertTrue($out->getMessage() === 'wtf');
+
+        $out = Exception::factory(Exception::SUCCESS);
+        $this->assertTrue(get_class($out) === 'Exception');
+        $this->assertTrue($out->getMessage() === 'Unknown Error');
+
+        $out = Exception::factory(Exception::CURL_EXEC);
+        $this->assertTrue($out instanceof Exception\CurlExec);
+        $this->assertTrue($out->getMessage() === 'curl_exec() error.');
+    }
+}
diff --git a/vendor/instaclick/php-webdriver/test/Test/WebDriver/StorageTest.php b/vendor/instaclick/php-webdriver/test/Test/WebDriver/StorageTest.php
new file mode 100644 (file)
index 0000000..50af104
--- /dev/null
@@ -0,0 +1,46 @@
+<?php
+/**
+ * Copyright 2011-2017 Anthon Pang. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package WebDriver
+ *
+ * @author Anthon Pang <apang@softwaredevelopment.ca>
+ */
+
+namespace Test\WebDriver;
+
+use WebDriver\Storage;
+
+/**
+ * Test WebDriver\Storage class
+ *
+ * @package WebDriver
+ *
+ * @group Unit
+ */
+class StorageTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * test factory()
+     */
+    public function testFactory()
+    {
+        $out = Storage::factory('Local', '/');
+        $this->assertTrue($out instanceof Storage\Local);
+
+        $out = Storage::factory('sEsSiOn', '/');
+        $this->assertTrue($out instanceof Storage\Session);
+    }
+}
diff --git a/vendor/instaclick/php-webdriver/test/Test/WebDriver/WebDriverTest.php b/vendor/instaclick/php-webdriver/test/Test/WebDriver/WebDriverTest.php
new file mode 100644 (file)
index 0000000..056b8e7
--- /dev/null
@@ -0,0 +1,267 @@
+<?php
+/**
+ * Copyright 2014-2017 Anthon Pang. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package WebDriver
+ *
+ * @author Anthon Pang <apang@softwaredevelopment.ca>
+ * @author Damian Mooyman <damian@silverstripe.com>
+ */
+
+namespace Test\WebDriver;
+
+use WebDriver\ServiceFactory;
+use WebDriver\WebDriver;
+
+/**
+ * Test WebDriver\WebDriver class
+ *
+ * @package WebDriver
+ *
+ * @group Functional
+ */
+class WebDriverTest extends \PHPUnit_Framework_TestCase
+{
+    private $driver;
+    private $session;
+    private $testDocumentRootUrl = 'http://localhost';
+    private $testSeleniumRootUrl = 'http://localhost:4444/wd/hub';
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function setUp()
+    {
+        ServiceFactory::getInstance()->setServiceClass('service.curl', '\\WebDriver\\Service\\CurlService');
+
+        if ($url = getenv('ROOT_URL')) {
+            $this->testDocumentRootUrl = $url;
+        }
+
+        if ($url = getenv('SELENIUM_URL')) {
+            $this->testSeleniumRootUrl = $url;
+        }
+
+        $this->driver  = new WebDriver($this->getTestSeleniumRootUrl());
+        $this->session = null;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function tearDown()
+    {
+        if ($this->session) {
+            $this->session->close();
+        }
+    }
+
+    /**
+     * Returns the full url to the test site (corresponding to the root dir of the library).
+     * You can set this via env var ROOT_URL
+     *
+     * @return string
+     */
+    protected function getTestDocumentRootUrl()
+    {
+        return $this->testDocumentRootUrl;
+    }
+
+    /**
+     * Returns the full url to the Selenium server used for functional tests
+     *
+     * @return string
+     *
+     * @todo make this configurable via env var
+     */
+    protected function getTestSeleniumRootUrl()
+    {
+        return $this->testSeleniumRootUrl;
+    }
+
+    /**
+     * Is Selenium down?
+     *
+     * @param \Exception $exception
+     *
+     * @return boolean
+     */
+    protected function isSeleniumDown($exception)
+    {
+        return preg_match('/Failed to connect to .* Connection refused/', $exception->getMessage()) != false
+            || strpos($exception->getMessage(), 'couldn\'t connect to host') !== false
+            || strpos($exception->getMessage(), 'Unable to connect to host') !== false;
+    }
+
+    /**
+     * Test driver sessions
+     */
+    public function testSessions()
+    {
+        try {
+            $this->assertCount(0, $this->driver->sessions());
+
+            $this->session = $this->driver->session();
+        } catch (\Exception $e) {
+            if ($this->isSeleniumDown($e)) {
+                $this->markTestSkipped('selenium server not running');
+
+                return;
+            }
+
+            throw $e;
+        }
+
+        $this->assertCount(1, $this->driver->sessions());
+        $this->assertEquals($this->getTestSeleniumRootUrl(), $this->driver->getUrl());
+    }
+
+    /**
+     * Test driver status
+     */
+    public function testStatus()
+    {
+        try {
+            $status = $this->driver->status();
+        } catch (\Exception $e) {
+            if ($this->isSeleniumDown($e)) {
+                $this->markTestSkipped('selenium server not running');
+
+                return;
+            }
+
+            throw $e;
+        }
+
+        $this->assertCount(3, $status);
+        $this->assertTrue(isset($status['java']));
+        $this->assertTrue(isset($status['os']));
+        $this->assertTrue(isset($status['build']));
+    }
+
+    /**
+     * Checks that an error connecting to Selenium gives back the expected exception
+     */
+    public function testSeleniumError()
+    {
+        try {
+            $this->driver = new WebDriver($this->getTestSeleniumRootUrl() . '/../invalidurl');
+
+            $status = $this->driver->status();
+
+            $this->fail('Exception not thrown while connecting to invalid Selenium url');
+        } catch (\Exception $e) {
+            if ($this->isSeleniumDown($e)) {
+                $this->markTestSkipped('selenium server not running');
+
+                return;
+            }
+
+            $this->assertEquals('WebDriver\Exception\CurlExec', get_class($e));
+        }
+    }
+
+    /**
+     * Checks that a successful command to Selenium which returns an http error response gives back the expected exception
+     */
+    public function testSeleniumErrorResponse()
+    {
+        try {
+            $status = $this->driver->status();
+        } catch (\Exception $e) {
+            if ($this->isSeleniumDown($e)) {
+                $this->markTestSkipped('selenium server not running');
+
+                return;
+            }
+
+            throw $e;
+        }
+
+        try {
+            $this->session = $this->driver->session();
+            $this->session->open($this->getTestDocumentRootUrl().'/test/Assets/index.html');
+
+            $element = $this->session->element('id', 'a-quite-unlikely-html-element-id');
+
+            $this->fail('Exception not thrown while looking for missing element in page');
+        } catch (\Exception $e) {
+            $this->assertEquals('WebDriver\Exception\NoSuchElement', get_class($e));
+        }
+    }
+
+    /**
+     * Checks that a successful command to Selenium which returns 'nothing' according to spec does not raise an error
+     */
+    public function testSeleniumNoResponse()
+    {
+        try {
+            $status = $this->driver->status();
+        } catch (\Exception $e) {
+            if ($this->isSeleniumDown($e)) {
+                $this->markTestSkipped('selenium server not running');
+
+                return;
+            }
+
+            throw $e;
+        }
+
+        $this->session = $this->driver->session();
+        $timeouts = $this->session->timeouts();
+        $out = $timeouts->async_script(array('type' => 'implicit', 'ms' => 1000));
+
+        $this->assertEquals(null, $out);
+    }
+
+    /**
+     * Assert that empty response does not trigger exception, but invalid JSON does
+     */
+    public function testNonJsonResponse()
+    {
+        $mockCurlService = $this->createMock('WebDriver\Service\CurlService');
+        $mockCurlService->expects($this->once())
+            ->method('execute')
+            ->will($this->returnCallback(function ($requestMethod, $url) {
+                $info = array(
+                    'url' => $url,
+                    'request_method' => $requestMethod,
+                    'http_code' => 200,
+                );
+
+                $result = preg_match('#.*session$#', $url)
+                    ? $result = 'some invalid json'
+                    : $result = '';
+
+                return array($result, $info);
+            }));
+
+        ServiceFactory::getInstance()->setService('service.curl', $mockCurlService);
+
+        $result = $this->driver->status();
+
+        $this->assertNull($result);
+
+        // Test /session should error
+        $this->setExpectedException(
+            'WebDriver\Exception\CurlExec',
+            'Payload received from webdriver is not valid json: some invalid json'
+        );
+
+        $result = $this->driver->session();
+
+        $this->assertNull($result);
+    }
+}
diff --git a/vendor/psr/container/.gitignore b/vendor/psr/container/.gitignore
new file mode 100644 (file)
index 0000000..b2395aa
--- /dev/null
@@ -0,0 +1,3 @@
+composer.lock
+composer.phar
+/vendor/
diff --git a/vendor/psr/container/LICENSE b/vendor/psr/container/LICENSE
new file mode 100644 (file)
index 0000000..2877a48
--- /dev/null
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2013-2016 container-interop
+Copyright (c) 2016 PHP Framework Interoperability Group
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/vendor/psr/container/README.md b/vendor/psr/container/README.md
new file mode 100644 (file)
index 0000000..084f6df
--- /dev/null
@@ -0,0 +1,5 @@
+# PSR Container
+
+This repository holds all interfaces/classes/traits related to [PSR-11](https://github.com/container-interop/fig-standards/blob/master/proposed/container.md).
+
+Note that this is not a container implementation of its own. See the specification for more details.
diff --git a/vendor/psr/container/composer.json b/vendor/psr/container/composer.json
new file mode 100644 (file)
index 0000000..b8ee012
--- /dev/null
@@ -0,0 +1,27 @@
+{
+    "name": "psr/container",
+    "type": "library",
+    "description": "Common Container Interface (PHP FIG PSR-11)",
+    "keywords": ["psr", "psr-11", "container", "container-interop", "container-interface"],
+    "homepage": "https://github.com/php-fig/container",
+    "license": "MIT",
+    "authors": [
+        {
+            "name": "PHP-FIG",
+            "homepage": "http://www.php-fig.org/"
+        }
+    ],
+    "require": {
+        "php": ">=5.3.0"
+    },
+    "autoload": {
+        "psr-4": {
+            "Psr\\Container\\": "src/"
+        }
+    },
+    "extra": {
+        "branch-alias": {
+            "dev-master": "1.0.x-dev"
+        }
+    }
+}
diff --git a/vendor/psr/container/src/ContainerExceptionInterface.php b/vendor/psr/container/src/ContainerExceptionInterface.php
new file mode 100644 (file)
index 0000000..d35c6b4
--- /dev/null
@@ -0,0 +1,13 @@
+<?php
+/**
+ * @license http://www.opensource.org/licenses/mit-license.php MIT (see the LICENSE file)
+ */
+
+namespace Psr\Container;
+
+/**
+ * Base interface representing a generic exception in a container.
+ */
+interface ContainerExceptionInterface
+{
+}
diff --git a/vendor/psr/container/src/ContainerInterface.php b/vendor/psr/container/src/ContainerInterface.php
new file mode 100644 (file)
index 0000000..c3a7206
--- /dev/null
@@ -0,0 +1,37 @@
+<?php
+/**
+ * @license http://www.opensource.org/licenses/mit-license.php MIT (see the LICENSE file)
+ */
+
+namespace Psr\Container;
+
+/**
+ * Describes the interface of a container that exposes methods to read its entries.
+ */
+interface ContainerInterface
+{
+    /**
+     * Finds an entry of the container by its identifier and returns it.
+     *
+     * @param string $id Identifier of the entry to look for.
+     *
+     * @throws NotFoundExceptionInterface  No entry was found for **this** identifier.
+     * @throws ContainerExceptionInterface Error while retrieving the entry.
+     *
+     * @return mixed Entry.
+     */
+    public function get($id);
+
+    /**
+     * Returns true if the container can return an entry for the given identifier.
+     * Returns false otherwise.
+     *
+     * `has($id)` returning true does not mean that `get($id)` will not throw an exception.
+     * It does however mean that `get($id)` will not throw a `NotFoundExceptionInterface`.
+     *
+     * @param string $id Identifier of the entry to look for.
+     *
+     * @return bool
+     */
+    public function has($id);
+}
diff --git a/vendor/psr/container/src/NotFoundExceptionInterface.php b/vendor/psr/container/src/NotFoundExceptionInterface.php
new file mode 100644 (file)
index 0000000..6566704
--- /dev/null
@@ -0,0 +1,13 @@
+<?php
+/**
+ * @license http://www.opensource.org/licenses/mit-license.php MIT (see the LICENSE file)
+ */
+
+namespace Psr\Container;
+
+/**
+ * No entry was found in the container.
+ */
+interface NotFoundExceptionInterface extends ContainerExceptionInterface
+{
+}
index 9d642cf20b1060ee6d96ba0067b0ad64c98d47fd..6011ac4ddb98c0fb9c3fa6b0752306d5f8660cc6 100644 (file)
@@ -1,4 +1,8 @@
-# Ignore test run data like screenshots etc.
-tests/codeception/tests/_output/*
-
-tests/build.xml
+# Copy the .dist file and modify the copy as your local PHPUnit configuration file.
+tests/phpunit.xml
+# Ignore PhpStorm IDE files
+.idea
+js/node_modules
+npm-debug.log
+# Ignore Mac DS_Store files
+.DS_Store
diff --git a/web/modules/contrib/permissions_by_term/README.md b/web/modules/contrib/permissions_by_term/README.md
new file mode 100755 (executable)
index 0000000..b169224
--- /dev/null
@@ -0,0 +1,69 @@
+Permissions by Term
+====================================
+
+Visit [Pbt's documentation page on Drupal.org](https://www.drupal.org/docs/8/modules/permissions-by-term) to
+learn how to use this module.
+
+## Modules which extend PbT's functionality
+- [Webform Permissions By Term](https://www.drupal.org/project/webform_permissions_by_term)
+This modules will be merged into PbT soon.
+- [Permissions by Entity](https://www.drupal.org/project/permissions_by_entity)
+This module is now merged into PbT
+
+## Behat testing
+
+### composer.json config
+Make sure that the dependencies the PbT module are installed. Check your drupal's `composer.json` file
+for the following contents:
+
+    "require": {
+        "composer/installers": "^1.0.24",
+        "wikimedia/composer-merge-plugin": "~1.4"
+    },
+    
+    ...
+    
+    "merge-plugin": {
+        "include": [
+            "core/composer.json",
+            "modules/permissions_by_term/composer.json"
+        ],
+        "recurse": false,
+        "replace": false,
+        "merge-extra": false
+    },
+    
+    ...
+    
+    "autoload": {
+        "psr-4": {
+            "Drupal\\Core\\Composer\\": "core/lib/Drupal/Core/Composer",
+            "Drupal\\Tests\\permissions_by_term\\Behat\\Context\\": "modules/permissions_by_term/tests/src/Behat/Context"
+        }
+    },
+    
+### behat.yml file
+Use the file at `tests/src/Behat/behat.yml.dist` as a template for your needs. Copy and name it to `behat.yml` and change
+it's paths according to your needs.
+    
+### Chromedriver
+It is recommended to use the [Chromedriver](https://sites.google.com/a/chromium.org/chromedriver/) as the driver between
+your Google Chrome browser and Behat. Make sure, that the Chromedriver version matches your operating system and your
+Google Chrome browser version.
+
+### Quick testing with a SQlite database
+In permissions_by_term/tests/src/Behat/fixtures/db.sqlite` you can find a SQLite database to test from. It is a standard
+Drupal 8 installation with PbT module installed. That way each test run proceeds quicker, because it is 1 file
+instead an entire relational database.
+
+Make sure that the path to the SQLite database is contained in your `settings.php` file. PbT awaits that the path is
+`/sites/default/db.sqlite`. E.g.:
+
+    $databases['default']['default'] = array (
+      'database' => '/Users/peter/Dev/mamp/permissions-by-term/sites/default/db.sqlite',
+      'prefix' => '',
+      'namespace' => 'Drupal\\Core\\Database\\Driver\\sqlite',
+      'driver' => 'sqlite',
+    );
+
+The database file location is fixed, because the DB gets wiped after each Behat test suite run.
diff --git a/web/modules/contrib/permissions_by_term/README.txt b/web/modules/contrib/permissions_by_term/README.txt
deleted file mode 100755 (executable)
index cc9532b..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-Permissions by Term
-====================================
-
-DESCRIPTION
------------
-Restricts users from accessing the nodes related to specific taxonomy terms per
-roles and users. Restriction also works for views, if teaser display mode is
-used, as well as individual fields, like Title and Body.
-
-Permissions by Term module additionally disallows users to select taxonomy
-terms, for which they don't have access, on the node edit form.
-
-WHY THIS MODULE WAS CREATED AND HOW?
-------------------------------------
-During work on a client project the Taxonomy Term Permissions module was
-forked. It couldn't handle a different language and couldn't handle permissions
-on a views page with listed taxonomy terms.
-
-HOW TO SETUP THE MODULES FUNCTIONALITY ON YOUR DRUPAL-SITE?
------------------------------------------------------------
-1., Install the module.
-2., Create a vocabulary and go to the taxonomy term add/edit-form for this
-taxonomy term vocabulary. In the top of the form you can see the term
-permissions. You can specify here, which roles and users can "use" this
-taxonomy term either by node editing or accessing the nodes on a view or
-on node display. The module hides nodes on a view.
-3., After you have set permissions by term, they will take effect for the
-related nodes on view and edit.
diff --git a/web/modules/contrib/permissions_by_term/composer.json b/web/modules/contrib/permissions_by_term/composer.json
new file mode 100644 (file)
index 0000000..1eea125
--- /dev/null
@@ -0,0 +1,27 @@
+{
+    "name": "drupal/permissions-by-term",
+    "description": "Restricts access to nodes by taxonomy terms in relation to users and their roles.",
+    "type": "drupal-module",
+    "license": "GPL-2.0+",
+    "authors": [
+        {
+            "name": "Peter Majmesku",
+            "email": "p.majmesku@gmail.com"
+        }
+    ],
+    "require": {
+        "drupal/drupal-extension": "~3.0",
+        "guzzlehttp/guzzle" : "^6.0@dev",
+        "drupal/drupal-driver": "~1.0",
+        "behat/behat": "^3.1",
+        "behat/mink": "^1.7",
+        "behat/mink-extension": "^2.2",
+        "behat/mink-selenium2-driver": "^1.3",
+        "behat/mink-goutte-driver": "^1.2"
+    },
+    "autoload": {
+        "psr-4": {
+            "PermissionsByTerm\\": "tests/src/Behat/Context/"
+        }
+    }
+}
\ No newline at end of file
diff --git a/web/modules/contrib/permissions_by_term/config/install/permissions_by_term.settings.single_term_permission.yml b/web/modules/contrib/permissions_by_term/config/install/permissions_by_term.settings.single_term_permission.yml
new file mode 100644 (file)
index 0000000..68cde9b
--- /dev/null
@@ -0,0 +1,20 @@
+# This file defines a default config entity. This allows the module to include
+# config entities that are present 'out of the box'. Default config entities
+# are created in Drupal when the module is enabled. They are removed when the
+# module is uninstalled.
+
+# Default config entities can be edited by the user within Drupal. This edited
+# entity wil become exportable through the configuration system. This file,
+# however, will remain untouched.
+
+# For our config entity to be added at installation time, we have to place it in
+# the config/install directory of our module. Thus our file is located at:
+# config/install/config_entity_example.robot.marvin.yml.
+
+# You can see where these properties are defined in the annotation of
+# Drupal\config_entity_example\Entity\Robot.
+
+# The id of the config entity.
+id: single_term_restriction
+# Our properties follow.
+value: FALSE
diff --git a/web/modules/contrib/permissions_by_term/config/schema/permissions_by_term.schema.yml b/web/modules/contrib/permissions_by_term/config/schema/permissions_by_term.schema.yml
new file mode 100644 (file)
index 0000000..b6613d0
--- /dev/null
@@ -0,0 +1,22 @@
+# Schema for the configuration files of the Config Entity Example module.
+
+# This schema tells the config system how to read our config YML files.
+# See for example the file config/config_entity_example.robot.marvin.yml, which
+# contains our default config entity.
+
+# Documentation for schema files like this one is located here:
+# https://drupal.org/node/1905070
+
+permissions_by_term.settings.*:
+  type: mapping
+  label: 'Settings'
+  mapping:
+    id:
+      type: string
+      label: 'Id'
+    value:
+      type: boolean
+      label: 'Value'
+    langcode:
+      type: string
+      label: 'Default language'
\ No newline at end of file
diff --git a/web/modules/contrib/permissions_by_term/js/README.md b/web/modules/contrib/permissions_by_term/js/README.md
new file mode 100644 (file)
index 0000000..63840ca
--- /dev/null
@@ -0,0 +1,2 @@
+JavaScript code has been tested with [Jasmine](https://jasmine.github.io/). Install the dependencies by [Yarn](https://yarnpkg.com/lang/en/).
+Just run `yarn`. To run the tests, switch to the `js` folder and run `yarn test`.
\ No newline at end of file
diff --git a/web/modules/contrib/permissions_by_term/js/node-form.js b/web/modules/contrib/permissions_by_term/js/node-form.js
new file mode 100644 (file)
index 0000000..0ace453
--- /dev/null
@@ -0,0 +1,113 @@
+/**
+ * @file
+ * Info behaviors on node edit form.
+ */
+
+(function ($, window) {
+
+  'use strict';
+
+  var relationFieldsPathByContentType = "/admin/permissions-by-term/access-info-by-content-type/",
+      relationFieldsPathByUrl = "/admin/permissions-by-term/access-info-by-url?url=";
+
+  /**
+   * @type {Drupal~behavior}
+   */
+  Drupal.behaviors.nodeForm = {
+    attach: function () {
+
+      var contentType = getContentType(),
+          getFormInfo = null;
+
+      if (contentType !== null) {
+        getFormInfo = $.get(relationFieldsPathByContentType + contentType);
+      } else {
+        getFormInfo = $.get(relationFieldsPathByUrl + window.location.pathname);
+      }
+
+      $.when(getFormInfo).done(function(formInfo){
+
+        if (formInfo['taxonomyRelationFieldNames'] !== null) {
+
+          var nodeForm = new NodeForm($),
+              fieldWrapperCSSClasses = nodeForm.computeFieldWrapperCSSClasses(formInfo['taxonomyRelationFieldNames']);
+
+          initPermissionInfoByFormElements(nodeForm, fieldWrapperCSSClasses, formInfo);
+
+          for (var index = 0; index < fieldWrapperCSSClasses.length; ++index) {
+
+            var formElementCssClass = fieldWrapperCSSClasses[index];
+
+            nodeForm.addFormElementCssClass(formElementCssClass);
+
+            $(formElementCssClass + ' select').change(function (){
+              nodeForm.displayPermissionsBySelect(fieldWrapperCSSClasses, formInfo['permissions']);
+            });
+
+            $(formElementCssClass + ' input[type="text"]').on('autocomplete-select', function (){
+              nodeForm.displayPermissionsByAutocomplete(fieldWrapperCSSClasses, formInfo['permissions']);
+            });
+
+            $(formElementCssClass + ' input[type="text"]').on('keyup', function (){
+              nodeForm.displayPermissionsByAutocomplete(fieldWrapperCSSClasses, formInfo['permissions']);
+            });
+
+            $(formElementCssClass + ' input[type="checkbox"]').change(function (){
+              nodeForm.displayPermissionsByCheckbox($(this).prop('value'), $(this).prop('checked'), formInfo['permissions']);
+            });
+          }
+        }
+
+      });
+
+      function initPermissionInfoByFormElements(nodeForm, fieldWrapperCSSClasses, formInfo) {
+        nodeForm.displayPermissionsBySelect(fieldWrapperCSSClasses, formInfo['permissions']);
+        nodeForm.displayPermissionsByAutocomplete(fieldWrapperCSSClasses, formInfo['permissions']);
+        nodeForm.displayPermissionsByCheckbox($(this).prop('value'), $(this).prop('checked'), formInfo['permissions']);
+      }
+
+      function getContentType() {
+        if (window.location.href.indexOf('/node/add') !== -1) {
+          return window.location.href.split("/").pop();
+        }
+
+        return null;
+      }
+
+    }
+  };
+
+  /**
+   * Handles an auto-complete select event.
+   *
+   * Override the autocomplete method to add a custom event. Overriding is
+   * happening to get full input.
+   *
+   * @param {jQuery.Event} event
+   *   The event triggered.
+   * @param {object} ui
+   *   The jQuery UI settings object.
+   *
+   * @return {boolean}
+   *   Returns false to indicate the event status.
+   */
+  Drupal.autocomplete.options.select = function selectHandler(event, ui) {
+    var terms = Drupal.autocomplete.splitValues(event.target.value);
+    // Remove the current input.
+    terms.pop();
+    // Add the selected item.
+    if (ui.item.value.search(',') > 0) {
+      terms.push('"' + ui.item.value + '"');
+    }
+    else {
+      terms.push(ui.item.value);
+    }
+    event.target.value = terms.join(', ');
+    // Fire custom event that other controllers can listen to.
+    jQuery(event.target).trigger('autocomplete-select');
+
+    // Return false to tell jQuery UI that we've filled in the value already.
+    return false;
+  }
+
+})(jQuery, window);
\ No newline at end of file
diff --git a/web/modules/contrib/permissions_by_term/js/node-form.prototype.js b/web/modules/contrib/permissions_by_term/js/node-form.prototype.js
new file mode 100644 (file)
index 0000000..6d09956
--- /dev/null
@@ -0,0 +1,242 @@
+var NodeForm = function($){
+  this.jQuery = $;
+  this.selectedTids = [];
+  this.formElementCssClasses = [];
+};
+
+NodeForm.prototype.getSelectedTids = function() {
+  var tids = [];
+
+  for (var index = 0; index < this.formElementCssClasses.length; ++index) {
+    if (this.selectedTids[this.formElementCssClasses[index]] !== undefined && this.selectedTids[this.formElementCssClasses[index]].constructor === Array) {
+
+      this.selectedTids[this.formElementCssClasses[index]].forEach(function(tid){
+        tids.push(tid);
+      })
+    }
+  }
+
+  return tids;
+}
+
+NodeForm.prototype.addFormElementCssClass = function(formElementCssClass) {
+  this.formElementCssClasses.push(formElementCssClass);
+}
+
+
+NodeForm.prototype.keyExists = function(key, array) {
+  if (!array || (array.constructor !== Array && array.constructor !== Object)) {
+    return false;
+  }
+  for (var i = 0; i < array.length; i++) {
+    if (array[i] === key) {
+      return true;
+    }
+  }
+  return key in array;
+}
+
+NodeForm.prototype.addSelectedTid = function(tid, formElementCssClass) {
+  if (!this.keyExists(formElementCssClass, this.formElementCssClasses)) {
+    this.formElementCssClasses.push(formElementCssClass);
+  }
+
+  if (this.selectedTids[formElementCssClass] === undefined) {
+
+    this.selectedTids[formElementCssClass] = [];
+  }
+
+  this.selectedTids[formElementCssClass].push(tid);
+}
+
+NodeForm.prototype.removeTid = function(value, formElementCssClass) {
+  const index = this.selectedTids[formElementCssClass].indexOf(parseInt(value));
+
+  if (index !== -1) {
+    this.selectedTids[formElementCssClass].splice(index, 1);
+  }
+}
+
+NodeForm.prototype.resetData = function(formElementCssClass) {
+  this.selectedTids[formElementCssClass] = [];
+}
+
+NodeForm.prototype.computeFieldWrapperCSSClasses = function(fieldNames) {
+  var wrapperCssClasses = [];
+
+  for (var index = 0; index < fieldNames.length; ++index) {
+    var fieldWrapperClass = '.field--name-' + fieldNames[index].replace(/_/g, '-');
+
+    wrapperCssClasses.push(fieldWrapperClass);
+  }
+
+  return wrapperCssClasses;
+}
+
+NodeForm.prototype.displayPermissionsByCheckbox = function(tid, checked, permissions) {
+  if (checked === false) {
+    this.resetData('checkbox_tid_' + tid);
+  } else if (checked === true){
+    this.addSelectedTid(parseInt(tid), 'checkbox_tid_' + tid);
+  }
+
+  this.renderPermissionsInfo(permissions);
+}
+
+NodeForm.prototype.displayPermissionsBySelect = function(fieldWrapperCSSClasses, permissions) {
+  for (var index = 0; index < fieldWrapperCSSClasses.length; ++index) {
+    var inputTypes = ['select', 'input'];
+
+    var fieldWrapperCSSClass = fieldWrapperCSSClasses[index];
+
+    for (var inputTypesIndex = 0; inputTypesIndex <= inputTypes.length; inputTypesIndex++) {
+      var values = this.jQuery(fieldWrapperCSSClass + ' select').val();
+
+      if (values !== undefined && values !== null && values.constructor === Array) {
+        if (values[0] === '_none') {
+          this.resetData(fieldWrapperCSSClass);
+        }
+
+        for (var i = 0; i < values.length; ++i) {
+          if (isNaN(values[i]) === false) {
+            this.addSelectedTid(parseInt(values[i]), fieldWrapperCSSClass);
+          }
+        }
+      }
+
+    }
+
+  }
+
+  this.renderPermissionsInfo(permissions);
+
+}
+
+NodeForm.prototype.displayPermissionsByAutocomplete = function(fieldWrapperCSSClasses, permissions) {
+  for (var index = 0; index < fieldWrapperCSSClasses.length; ++index) {
+    var fieldWrapperCSSClass = fieldWrapperCSSClasses[index];
+
+    var values = this.jQuery(fieldWrapperCSSClass + ' input').val();
+
+    if (values !== undefined && values.indexOf('(') !== -1 && values.indexOf(')')) {
+
+      this.resetData(fieldWrapperCSSClass);
+
+      var tidsInBrackets = values.match(/\(\d+\)/g);
+
+      if (tidsInBrackets !== undefined && tidsInBrackets !== null && tidsInBrackets.constructor === Array) {
+
+        for (var i = 0; i < tidsInBrackets.length; ++i) {
+          var selectedTid = parseInt(tidsInBrackets[i].replace('(', '').replace(')', ''));
+          this.addSelectedTid(selectedTid, fieldWrapperCSSClass);
+        }
+
+      }
+
+    }
+
+  }
+
+  this.renderPermissionsInfo(permissions);
+
+}
+
+NodeForm.prototype.separateByComma = function(values) {
+  return values.join(', ');
+}
+
+NodeForm.prototype.renderPermissionsInfo = function(permissions) {
+
+  var permissionsToDisplay = this.getPermissionsByTids(this.getSelectedTids(), permissions);
+
+  var allowedUsersHtml = '<b>' + Drupal.t('Allowed users:') + '</b> ';
+
+  if (this.isAllowedUsersRestriction(permissionsToDisplay)) {
+    allowedUsersHtml += this.separateByComma(permissionsToDisplay['permittedUsers']);
+  } else {
+    allowedUsersHtml += '<i>' + Drupal.t('No user restrictions.') + '</i>';
+  }
+
+  var allowedRolesHtml = '<b>' + Drupal.t('Allowed roles:') + '</b> ';
+
+  if (this.isAllowedRolesRestriction(permissionsToDisplay)) {
+    allowedRolesHtml += this.separateByComma(permissionsToDisplay['permittedRoles']);
+  } else {
+    allowedRolesHtml += '<i>' + Drupal.t('No role restrictions.') + '</i>';;
+  }
+
+  var generalInfoText = Drupal.t("This widget shows information about taxonomy term related permissions. It's being updated, as soon you make any related changes in the form.");
+
+  this.jQuery('#edit-permissions-by-term-info .form-type-item').html(generalInfoText + '<br /><br />' + allowedUsersHtml + '<br />' + allowedRolesHtml);
+}
+
+NodeForm.prototype.isAllowedUsersRestriction = function(permissionsToDisplay) {
+  if (permissionsToDisplay['permittedUsers'].length > 0 && permissionsToDisplay['permittedUsers'] !== null) {
+    return true;
+  }
+
+  return false;
+}
+
+NodeForm.prototype.isAllowedRolesRestriction = function(permissionsToDisplay) {
+  if (permissionsToDisplay['permittedRoles'].length > 0 && permissionsToDisplay['permittedRoles'] !== null) {
+    return true;
+  }
+
+  return false;
+}
+
+NodeForm.prototype.pushUserDisplayNames = function(tids, permissionsToDisplay, permissions) {
+  for (var index = 0; index < tids.length; ++index) {
+    if (permissions['userDisplayNames'][tids[index]] !== undefined && permissions['userDisplayNames'][tids[index]] !== null &&
+        permissionsToDisplay['permittedUsers'].indexOf(permissions['userDisplayNames'][tids[index]]) === -1) {
+
+      var userDisplayNames = permissions['userDisplayNames'][tids[index]];
+
+      if (userDisplayNames.constructor === Array && userDisplayNames.length > 1) {
+        userDisplayNames.forEach(function(value){
+          if (permissionsToDisplay['permittedUsers'].indexOf(value) === -1) {
+            permissionsToDisplay['permittedUsers'].push(value);
+          }
+        });
+      } else {
+        if (permissionsToDisplay['permittedUsers'].indexOf(userDisplayNames) === -1) {
+          permissionsToDisplay['permittedUsers'].push(userDisplayNames);
+        }
+      }
+    }
+  }
+
+  return permissionsToDisplay;
+}
+
+NodeForm.prototype.pushRoles = function(tids, permissionsToDisplay, permissions) {
+  for (var index = 0; index < tids.length; ++index) {
+
+    if (permissions['roleLabels'] === undefined) {
+      return permissionsToDisplay;
+    }
+
+    if (permissions['roleLabels'][tids[index]] !== undefined && permissions['roleLabels'][tids[index]] !== null) {
+      permissions['roleLabels'][tids[index]].forEach(function(role){
+        if (permissionsToDisplay['permittedRoles'].indexOf(role) === -1) {
+          permissionsToDisplay['permittedRoles'].push(role);
+        }
+      });
+    }
+  }
+
+  return permissionsToDisplay;
+}
+
+NodeForm.prototype.getPermissionsByTids = function(tids, permissions) {
+  var permissionsToDisplay = {
+    permittedUsers: [],
+    permittedRoles: []
+  };
+
+  permissionsToDisplay = this.pushRoles(tids, permissionsToDisplay, permissions);
+  permissionsToDisplay = this.pushUserDisplayNames(tids, permissionsToDisplay, permissions);
+
+  return permissionsToDisplay;
+}
diff --git a/web/modules/contrib/permissions_by_term/js/package.json b/web/modules/contrib/permissions_by_term/js/package.json
new file mode 100644 (file)
index 0000000..de58229
--- /dev/null
@@ -0,0 +1,9 @@
+{
+  "dependencies": {
+    "jasmine": "^2.8.0"
+  },
+  "scripts": {
+    "test": "jasmine $NODE_DEBUG_OPTION"
+  },
+  "license": "GPL-2.0+"
+}
diff --git a/web/modules/contrib/permissions_by_term/js/spec/node-form.spec.js b/web/modules/contrib/permissions_by_term/js/spec/node-form.spec.js
new file mode 100644 (file)
index 0000000..b1a3069
--- /dev/null
@@ -0,0 +1,15 @@
+describe("Permissions by Term Suite", function() {
+
+  it("Compute field wrapper CSS classes", function() {
+    fs = require('fs')
+    prototypeClass = fs.readFileSync('node-form.prototype.js','utf-8')
+    eval(prototypeClass)
+
+    var NodeForm = new NodeForm();
+
+    var fieldNames = ['field_name-one', 'field_name_two'];
+
+    expect(NodeForm.computeFieldWrapperCSSClasses(fieldNames)).toEqual(['.field--name-field-name-one', '.field--name-field-name-two']);
+  });
+
+});
\ No newline at end of file
diff --git a/web/modules/contrib/permissions_by_term/js/spec/support/jasmine.json b/web/modules/contrib/permissions_by_term/js/spec/support/jasmine.json
new file mode 100644 (file)
index 0000000..3ea3166
--- /dev/null
@@ -0,0 +1,11 @@
+{
+  "spec_dir": "spec",
+  "spec_files": [
+    "**/*[sS]pec.js"
+  ],
+  "helpers": [
+    "helpers/**/*.js"
+  ],
+  "stopSpecOnExpectationFailure": false,
+  "random": false
+}
diff --git a/web/modules/contrib/permissions_by_term/js/yarn.lock b/web/modules/contrib/permissions_by_term/js/yarn.lock
new file mode 100644 (file)
index 0000000..d3e14ce
--- /dev/null
@@ -0,0 +1,80 @@
+# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
+# yarn lockfile v1
+
+
+balanced-match@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
+
+brace-expansion@^1.1.7:
+  version "1.1.8"
+  resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292"
+  dependencies:
+    balanced-match "^1.0.0"
+    concat-map "0.0.1"
+
+concat-map@0.0.1:
+  version "0.0.1"
+  resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
+
+exit@^0.1.2:
+  version "0.1.2"
+  resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c"
+
+fs.realpath@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
+
+glob@^7.0.6:
+  version "7.1.2"
+  resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15"
+  dependencies:
+    fs.realpath "^1.0.0"
+    inflight "^1.0.4"
+    inherits "2"
+    minimatch "^3.0.4"
+    once "^1.3.0"
+    path-is-absolute "^1.0.0"
+
+inflight@^1.0.4:
+  version "1.0.6"
+  resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
+  dependencies:
+    once "^1.3.0"
+    wrappy "1"
+
+inherits@2:
+  version "2.0.3"
+  resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
+
+jasmine-core@~2.8.0:
+  version "2.8.0"
+  resolved "https://registry.yarnpkg.com/jasmine-core/-/jasmine-core-2.8.0.tgz#bcc979ae1f9fd05701e45e52e65d3a5d63f1a24e"
+
+jasmine@^2.8.0:
+  version "2.8.0"
+  resolved "https://registry.yarnpkg.com/jasmine/-/jasmine-2.8.0.tgz#6b089c0a11576b1f16df11b80146d91d4e8b8a3e"
+  dependencies:
+    exit "^0.1.2"
+    glob "^7.0.6"
+    jasmine-core "~2.8.0"
+
+minimatch@^3.0.4:
+  version "3.0.4"
+  resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
+  dependencies:
+    brace-expansion "^1.1.7"
+
+once@^1.3.0:
+  version "1.4.0"
+  resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
+  dependencies:
+    wrappy "1"
+
+path-is-absolute@^1.0.0:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
+
+wrappy@1:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
diff --git a/web/modules/contrib/permissions_by_term/modules/permissions_by_entity/LICENSE.txt b/web/modules/contrib/permissions_by_term/modules/permissions_by_entity/LICENSE.txt
new file mode 100644 (file)
index 0000000..d159169
--- /dev/null
@@ -0,0 +1,339 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                            NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --git a/web/modules/contrib/permissions_by_term/modules/permissions_by_entity/README.txt b/web/modules/contrib/permissions_by_term/modules/permissions_by_entity/README.txt
new file mode 100644 (file)
index 0000000..772f70c
--- /dev/null
@@ -0,0 +1 @@
+Permissions By Entity
diff --git a/web/modules/contrib/permissions_by_term/modules/permissions_by_entity/permissions_by_entity.info.yml b/web/modules/contrib/permissions_by_term/modules/permissions_by_entity/permissions_by_entity.info.yml
new file mode 100644 (file)
index 0000000..722d453
--- /dev/null
@@ -0,0 +1,12 @@
+name: 'Permissions by Entity'
+description: 'Extends the functionality of Permissions By Term to be able to limit the selection of specific taxonomy terms by users or roles for an entity.'
+type: module
+# core: '8.x'
+dependencies:
+  - permissions_by_term
+package: 'Permissions by Term (Experimental)'
+# Information added by Drupal.org packaging script on 2017-11-05
+version: '8.x-1.35'
+core: '8.x'
+project: 'permissions_by_term'
+datestamp: 1509913093
diff --git a/web/modules/contrib/permissions_by_term/modules/permissions_by_entity/permissions_by_entity.services.yml b/web/modules/contrib/permissions_by_term/modules/permissions_by_entity/permissions_by_entity.services.yml
new file mode 100644 (file)
index 0000000..9d62bdd
--- /dev/null
@@ -0,0 +1,25 @@
+services:
+  permissions_by_entity.checked_entity_cache:
+    class: Drupal\permissions_by_entity\Service\CheckedEntityCache
+
+  permissions_by_entity.access_checker:
+    class: Drupal\permissions_by_entity\Service\AccessChecker
+    arguments:
+      - '@event_dispatcher'
+      - '@permissions_by_entity.checked_entity_cache'
+      - '@entity.manager'
+      - '@database'
+
+  permissions_by_entity.kernel_event_subscriber:
+    class: Drupal\permissions_by_entity\EventSubscriber\PermissionsByEntityKernelEventSubscriber
+    arguments:
+      - '@permissions_by_entity.access_checker'
+      - '@string_translation'
+      - '@permissions_by_entity.checked_entity_cache'
+    tags:
+      - { name: event_subscriber }
+
+  permissions_by_entity.remove_entity_from_view_event_subscriber:
+    class: Drupal\permissions_by_entity\EventSubscriber\RemoveEntityFromViewEventSubscriber
+    tags:
+      - { name: event_subscriber }
diff --git a/web/modules/contrib/permissions_by_term/modules/permissions_by_entity/src/Event/EntityFieldValueAccessDeniedEvent.php b/web/modules/contrib/permissions_by_term/modules/permissions_by_entity/src/Event/EntityFieldValueAccessDeniedEvent.php
new file mode 100644 (file)
index 0000000..5297faa
--- /dev/null
@@ -0,0 +1,123 @@
+<?php
+
+namespace Drupal\permissions_by_entity\Event;
+
+use Drupal\Core\Entity\ContentEntityInterface;
+use Drupal\Core\Field\FieldItemListInterface;
+use Symfony\Component\EventDispatcher\Event;
+
+/**
+ * Class EntityFieldValueAccessDeniedEvent.
+ *
+ * @package Drupal\permissions_by_entity\Event
+ */
+class EntityFieldValueAccessDeniedEvent extends Event {
+
+  /**
+   * The field that contains the content entity.
+   *
+   * @var \Drupal\Core\Field\FieldItemListInterface
+   */
+  private $field;
+
+  /**
+   * The content entity.
+   *
+   * @var \Drupal\Core\Entity\ContentEntityInterface
+   */
+  private $entity;
+
+  /**
+   * The user id.
+   *
+   * @var int
+   */
+  private $uid;
+
+  /**
+   * The current index.
+   *
+   * @var int
+   */
+  private $index;
+
+  /**
+   * Sets the field.
+   *
+   * @param \Drupal\Core\Field\FieldItemListInterface $field
+   *   The field that contains the content entity.
+   */
+  public function setField(FieldItemListInterface $field) {
+    $this->field = $field;
+  }
+
+  /**
+   * Returns the field.
+   *
+   * @return \Drupal\Core\Field\FieldItemListInterface
+   *   The field that contains the content entity.
+   */
+  public function getField() {
+    return $this->field;
+  }
+
+  /**
+   * Sets the content entity.
+   *
+   * @param \Drupal\Core\Entity\ContentEntityInterface $entity
+   *   The content entity.
+   */
+  public function setEntity(ContentEntityInterface $entity) {
+    $this->entity = $entity;
+  }
+
+  /**
+   * Returns the entity.
+   *
+   * @return \Drupal\Core\Entity\ContentEntityInterface
+   *   The content entity.
+   */
+  public function getEntity() {
+    return $this->entity;
+  }
+
+  /**
+   * Sets the uid.
+   *
+   * @param int $uid
+   *   The user id.
+   */
+  public function setUid($uid) {
+    $this->uid = $uid;
+  }
+
+  /**
+   * Returns the uid.
+   *
+   * @return int
+   *   The user id.
+   */
+  public function getUid() {
+    return $this->uid;
+  }
+
+  /**
+   * Sets the index.
+   *
+   * @param int $index
+   *   The current index.
+   */
+  public function setIndex($index) {
+    $this->index = $index;
+  }
+
+  /**
+   * Returns index.
+   *
+   * @return int
+   *   The current index.
+   */
+  public function getIndex() {
+    return $this->index;
+  }
+}
diff --git a/web/modules/contrib/permissions_by_term/modules/permissions_by_entity/src/Event/PermissionsByEntityEvents.php b/web/modules/contrib/permissions_by_term/modules/permissions_by_entity/src/Event/PermissionsByEntityEvents.php
new file mode 100644 (file)
index 0000000..8a82059
--- /dev/null
@@ -0,0 +1,22 @@
+<?php
+
+namespace Drupal\permissions_by_entity\Event;
+
+/**
+ * Class PermissionsByEntity.
+ *
+ * @package Drupal\permissions_by_entity\Event
+ */
+class PermissionsByEntityEvents {
+
+  /**
+   * Entity Field Value Access Denied event.
+   *
+   * This event occurs when the access to a referenced
+   * content entity is denied for a user.
+   *
+   * @Event('Drupal/booking/Event/CreateTourbookBookingIframeUrlEvent')
+   */
+  const ENTITY_FIELD_VALUE_ACCESS_DENIED_EVENT = 'permissions_by_entity.entity_field_value_access_denied_event';
+
+}
diff --git a/web/modules/contrib/permissions_by_term/modules/permissions_by_entity/src/EventSubscriber/PermissionsByEntityKernelEventSubscriber.php b/web/modules/contrib/permissions_by_term/modules/permissions_by_entity/src/EventSubscriber/PermissionsByEntityKernelEventSubscriber.php
new file mode 100644 (file)
index 0000000..49dacf5
--- /dev/null
@@ -0,0 +1,121 @@
+<?php
+
+namespace Drupal\permissions_by_entity\EventSubscriber;
+
+use Drupal\Core\Entity\ContentEntityInterface;
+use Drupal\Core\StringTranslation\TranslationInterface;
+use Drupal\permissions_by_entity\Service\AccessCheckerInterface;
+use Drupal\permissions_by_entity\Service\CheckedEntityCache;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+use Symfony\Component\HttpKernel\Event\GetResponseEvent;
+use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
+use Symfony\Component\HttpKernel\KernelEvents;
+
+/**
+ * Class PermissionsByEntityKernelEventSubscriber.
+ *
+ * @package Drupal\permissions_by_entity\EventSubscriber
+ */
+class PermissionsByEntityKernelEventSubscriber implements EventSubscriberInterface {
+
+  /**
+   * The access checker.
+   *
+   * @var \Drupal\permissions_by_entity\Service\AccessCheckerInterface
+   */
+  private $accessChecker;
+
+  /**
+   * The core string translator.
+   *
+   * @var \Drupal\Core\StringTranslation\TranslationInterface
+   */
+  private $translation;
+
+  /**
+   * The cache for checked entities.
+   *
+   * @var \Drupal\permissions_by_entity\Service\CheckedEntityCache
+   */
+  private $checkedEntityCache;
+
+  /**
+   * PermissionsByEntityKernelEventSubscriber constructor.
+   *
+   * @param \Drupal\permissions_by_entity\Service\AccessCheckerInterface $access_checker
+   *   The service to check if the current user is allowed to access an entity.
+   * @param \Drupal\Core\StringTranslation\TranslationInterface $translation
+   *   The core string translator.
+   * @param \Drupal\permissions_by_entity\Service\CheckedEntityCache $checked_entity_cache
+   *   The cache for checked entities.
+   */
+  public function __construct(
+    AccessCheckerInterface $access_checker,
+    TranslationInterface $translation,
+    CheckedEntityCache $checked_entity_cache
+  ) {
+    $this->accessChecker = $access_checker;
+    $this->translation = $translation;
+    $this->checkedEntityCache = $checked_entity_cache;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getSubscribedEvents() {
+    return [
+      KernelEvents::REQUEST => ['onKernelRequest', 5],
+    ];
+  }
+
+  /**
+   * Callback method for the KernelEvents::REQUEST event.
+   *
+   * @param \Symfony\Component\HttpKernel\Event\GetResponseEvent $event
+   *   The event instance.
+   */
+  public function onKernelRequest(GetResponseEvent $event) {
+    // Get the current request from the event.
+    $request = $event->getRequest();
+
+    // Get the entity.
+    /** @var \Drupal\Core\Entity\ContentEntityInterface $entity */
+    $entity = NULL;
+    if ($request->attributes->has('node')) {
+      $entity = $request->attributes->get('node');
+    }
+    elseif ($request->attributes->has('_entity')) {
+      $entity = $request->attributes->get('_entity');
+    }
+
+    // If there is no entity abort here.
+    if (!$entity) {
+      return;
+    }
+
+    // If we already checked this entity, we do nothing.
+    if ($this->checkedEntityCache->isChecked($entity)) {
+      return;
+    }
+    else {
+      // Add this entity to the cache.
+      $this->checkedEntityCache->add($entity);
+    }
+
+    // Check if the current user is allowed to access this entity.
+    if (
+      $entity && $entity instanceof ContentEntityInterface &&
+      !$this->accessChecker->isAccessAllowed($entity)
+    ) {
+
+      // If the current user is not allowed to access this entity,
+      // we throw an AccessDeniedHttpException.
+      throw new AccessDeniedHttpException(
+        $this->translation->translate(
+          'You are not allowed to view content of this entity type.'
+        )
+      );
+    }
+  }
+
+}
diff --git a/web/modules/contrib/permissions_by_term/modules/permissions_by_entity/src/EventSubscriber/RemoveEntityFromViewEventSubscriber.php b/web/modules/contrib/permissions_by_term/modules/permissions_by_entity/src/EventSubscriber/RemoveEntityFromViewEventSubscriber.php
new file mode 100644 (file)
index 0000000..c17a2e4
--- /dev/null
@@ -0,0 +1,65 @@
+<?php
+
+namespace Drupal\permissions_by_entity\EventSubscriber;
+
+use Drupal\permissions_by_entity\Event\EntityFieldValueAccessDeniedEvent;
+use Drupal\permissions_by_entity\Event\PermissionsByEntityEvents;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+
+/**
+ * Class RemoveEntityFromViewEventSubscriber.
+ *
+ * @package Drupal\permissions_by_entity\EventSubscriber
+ */
+class RemoveEntityFromViewEventSubscriber implements EventSubscriberInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getSubscribedEvents() {
+    return [
+      PermissionsByEntityEvents::ENTITY_FIELD_VALUE_ACCESS_DENIED_EVENT =>
+      [
+        'onEntityFieldAccessDenied',
+      ],
+    ];
+  }
+
+  /**
+   * Callback method.
+   *
+   * Callback method that will be called when the
+   * ENTITY_FIELD_VALUE_ACCESS_DENIED_EVENT has been triggered.
+   *
+   * @param \Drupal\permissions_by_entity\Event\EntityFieldValueAccessDeniedEvent $event
+   *   The event.
+   */
+  public function onEntityFieldAccessDenied(EntityFieldValueAccessDeniedEvent $event) {
+    // Get the field.
+    $field = $event->getField();
+
+    // Get the number of values this field contains.
+    $num_values = $field->count();
+
+    // Get the current value of the field.
+    $field_values = $field->getValue();
+
+    // Iterate over the values.
+    for ($i = 0; $i < $num_values; $i++) {
+      $field_entity = $field->get($i)->entity;
+
+      // If the entity matches the entity of the event.
+      if ($field_entity === $event->getEntity()) {
+        // Remove the this value from the values array.
+        unset($field_values[$i]);
+
+        // We need to decrement the current index.
+        $event->setIndex($event->getIndex() - 1);
+      }
+    }
+
+    // Set the field values.
+    $field->setValue($field_values);
+  }
+
+}
diff --git a/web/modules/contrib/permissions_by_term/modules/permissions_by_entity/src/Service/AccessChecker.php b/web/modules/contrib/permissions_by_term/modules/permissions_by_entity/src/Service/AccessChecker.php
new file mode 100644 (file)
index 0000000..0911b9f
--- /dev/null
@@ -0,0 +1,170 @@
+<?php
+
+namespace Drupal\permissions_by_entity\Service;
+
+use Drupal\Core\Database\Connection;
+use Drupal\Core\Database\Database;
+use Drupal\Core\Entity\ContentEntityInterface;
+use Drupal\Core\Entity\EntityManagerInterface;
+use Drupal\Core\Entity\EntityTypeManagerInterface;
+use Drupal\permissions_by_entity\Event\EntityFieldValueAccessDeniedEvent;
+use Drupal\permissions_by_entity\Event\PermissionsByEntityEvents;
+use Drupal\permissions_by_term\Service\AccessCheck;
+use Symfony\Component\EventDispatcher\EventDispatcherInterface;
+
+/**
+ * Class AccessChecker.
+ *
+ * @package Drupal\permissions_by_entity\Service
+ */
+class AccessChecker extends AccessCheck implements AccessCheckerInterface {
+
+  /**
+   * The event dispatcher.
+   *
+   * @var \Symfony\Component\EventDispatcher\EventDispatcherInterface
+   */
+  private $eventDispatcher;
+
+  /**
+   * The cache for checked entities.
+   *
+   * @var \Drupal\permissions_by_entity\Service\CheckedEntityCache
+   */
+  private $checkedEntityCache;
+
+  /**
+   * The entity field value access denied event.
+   *
+   * @var \Drupal\permissions_by_entity\Event\EntityFieldValueAccessDeniedEvent
+   */
+  private $event;
+
+  /**
+   * AccessChecker constructor.
+   *
+   * We override the constructor, because we do not need the entity manager.
+   *
+   * @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $event_dispatcher
+   *   The event dispatcher.
+   * @param \Drupal\permissions_by_entity\Service\CheckedEntityCache $checked_entity_cache
+   *   The cache for checked entities.
+   * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
+   *   The core entity type manager.
+   * @param \Drupal\Core\Database\Connection $database
+   *   The database connection.
+   */
+  public function __construct(
+    EventDispatcherInterface $event_dispatcher,
+    CheckedEntityCache $checked_entity_cache,
+    EntityManagerInterface $entity_manager,
+    Connection $database
+  ) {
+    parent::__construct($database, $event_dispatcher);
+    $this->eventDispatcher = $event_dispatcher;
+    $this->checkedEntityCache = $checked_entity_cache;
+
+    $this->event = new EntityFieldValueAccessDeniedEvent();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isAccessAllowed(ContentEntityInterface $entity, $uid = FALSE) {
+    // Iterate over the fields the entity contains.
+    foreach ($entity->getFields() as $field) {
+
+      // We only need to check for entity reference fields
+      // which references to a taxonomy term.
+      if (
+        $field->getFieldDefinition()->getType() == 'entity_reference' &&
+        $field->getFieldDefinition()->getSetting('target_type') == 'taxonomy_term'
+      ) {
+
+        // Iterate over each referenced taxonomy term.
+        /** @var \Drupal\Core\Field\FieldItemInterface $item */
+        foreach ($field->getValue() as $item) {
+          // Let "Permissions By Term" do the actual check.
+          if (
+            !empty($item['target_id']) &&
+            !$this->isAccessAllowedByDatabase($item['target_id'], $uid)
+          ) {
+            // Return that the user is not allowed to access this entity.
+            return FALSE;
+          }
+        }
+      }
+
+      // Check if the field contains another content entity,
+      // that we need to check.
+      if ($field->entity && $field->entity instanceof ContentEntityInterface) {
+
+        // We need to iterate over the entities.
+        $num_values = $field->count();
+        if ($num_values > 0) {
+
+          // Iterate over the field values.
+          for ($i = 0; $i < $num_values; $i++) {
+
+            // Get the value of the current field index.
+            $field_value = $field->get($i);
+
+            // If the value is null or empty we continue with the next index of
+            // the loop.
+            if (!$field_value) {
+              continue;
+            }
+
+            // Get the field entity.
+            $field_entity = $field_value->entity;
+
+            // If the field entity is null we also continue with the next index
+            // of the loop.
+            if (!$field_entity) {
+              continue;
+            }
+
+            // It is possible, that the referenced field entity creates a
+            // circular dependency to the current entity. This will cause
+            // memory limit exhausted errors because there is no way out for
+            // the script. To avoid this, we need to be able to imagine if we
+            // already checked this field entity before. If so, we ignore this
+            // field entity, if not we can securely do a recursive call.
+            //
+            // Using own method to avoid "max nesting level error" trying to
+            // check if the field entity is stored in the entitiesChecked array.
+            if ($this->checkedEntityCache->isChecked($field_entity)) {
+              continue;
+            }
+            else {
+              // Add the current entity to the list of checked entities.
+              $this->checkedEntityCache->add($field_entity);
+            }
+
+            // Do a recursive call to check if the user is allowed to access
+            // this entity.
+            if (!$this->isAccessAllowed($field_entity, $uid)) {
+
+              // Dispatch an event to allow subscribers
+              // to do something in this case.
+              $this->event->setIndex($i);
+              $this->event->setField($field);
+              $this->event->setEntity($field_entity);
+              $this->event->setUid($uid);
+
+              $this->eventDispatcher
+                ->dispatch(
+                  PermissionsByEntityEvents::ENTITY_FIELD_VALUE_ACCESS_DENIED_EVENT,
+                  $this->event
+                );
+              $i = $this->event->getIndex();
+            }
+          }
+        }
+      }
+    }
+
+    return TRUE;
+  }
+
+}
diff --git a/web/modules/contrib/permissions_by_term/modules/permissions_by_entity/src/Service/AccessCheckerInterface.php b/web/modules/contrib/permissions_by_term/modules/permissions_by_entity/src/Service/AccessCheckerInterface.php
new file mode 100644 (file)
index 0000000..ec89b28
--- /dev/null
@@ -0,0 +1,27 @@
+<?php
+
+namespace Drupal\permissions_by_entity\Service;
+
+use Drupal\Core\Entity\ContentEntityInterface;
+
+/**
+ * Interface AccessCheckerInterface.
+ *
+ * @package Drupal\permissions_by_entity\Service
+ */
+interface AccessCheckerInterface {
+
+  /**
+   * Checks if a user is allowed to access a content entity.
+   *
+   * @param \Drupal\Core\Entity\ContentEntityInterface $entity
+   *   The content entity.
+   * @param bool|int $uid
+   *   (Optional) Defaults to the uid of the current user.
+   *
+   * @return bool TRUE if access is allowed, otherwise FALSE.
+   * TRUE if access is allowed, otherwise FALSE.
+   */
+  public function isAccessAllowed(ContentEntityInterface $entity, $uid = FALSE);
+
+}
diff --git a/web/modules/contrib/permissions_by_term/modules/permissions_by_entity/src/Service/CheckedEntityCache.php b/web/modules/contrib/permissions_by_term/modules/permissions_by_entity/src/Service/CheckedEntityCache.php
new file mode 100644 (file)
index 0000000..edda07b
--- /dev/null
@@ -0,0 +1,59 @@
+<?php
+
+namespace Drupal\permissions_by_entity\Service;
+
+use Drupal\Core\Entity\ContentEntityInterface;
+
+/**
+ * Class CheckedEntityCache.
+ *
+ * @package Drupal\permissions_by_entity\Service
+ */
+class CheckedEntityCache {
+
+  /**
+   * The checked entities.
+   *
+   * @var \Drupal\Core\Entity\ContentEntityInterface[]
+   */
+  private $entities = [];
+
+  /**
+   * Returns if an entity has already been checked.
+   *
+   * @param \Drupal\Core\Entity\ContentEntityInterface $entity
+   *   The content entity.
+   *
+   * @return bool
+   *   Returns TRUE if the entity has already been checked, otherwise FALSE.
+   */
+  public function isChecked(ContentEntityInterface $entity) {
+    return in_array($entity, $this->entities, TRUE);
+  }
+
+  /**
+   * Adds a content entity to the cache.
+   *
+   * If the entity has already been added to the cache, nothing will be done.
+   *
+   * @param \Drupal\Core\Entity\ContentEntityInterface $entity
+   *   The content entity.
+   */
+  public function add(ContentEntityInterface $entity) {
+    // In order to avoid duplicate entries we check if the entity is already in
+    // the list of entities.
+    if (!$this->isChecked($entity)) {
+      $this->entities[] = $entity;
+    }
+  }
+
+  /**
+   * Clears the cache.
+   *
+   * All cached content entities will be removed irretrievably from the cache.
+   */
+  public function clear() {
+    $this->entities = [];
+  }
+
+}
index 6feef6bccff588ff6ef7b239bd3b587350fa67d6..fef86bf97979fc14fad0ccc150cbb53e7d54c484 100644 (file)
@@ -1,13 +1,13 @@
 name: 'Permissions by Term'
-description: 'Limits the selection of specific taxonomy terms by users or roles. Prevents users to display nodes and nodes on views pages, for which which they do not have access by taxonomy term restriction.'
+description: 'Restricts access to nodes and taxonomy terms via user to term relations.'
 dependencies:
   - taxonomy
 type: module
 # core: '8.x'
-# version: '8.x-1.0'
-
-# Information added by Drupal.org packaging script on 2017-05-09
-version: '8.x-1.19'
+# version: '8.x-1.33'
+package: 'Permissions by Term'
+# Information added by Drupal.org packaging script on 2017-11-05
+version: '8.x-1.35'
 core: '8.x'
 project: 'permissions_by_term'
-datestamp: 1494360198
+datestamp: 1509913093
index edc0be0a9d4f587fd0cd8e44981a44d38680523e..738b9bf77351828374485751e0a85cc0cbe2d07f 100644 (file)
@@ -77,4 +77,11 @@ function permissions_by_term_uninstall() {
  */
 function permissions_by_term_update_8113() {
   node_access_rebuild(TRUE);
-}
\ No newline at end of file
+}
+
+/**
+ * Force a node access rebuild to fix node access grants.
+ */
+function permissions_by_term_update_8114() {
+  node_access_rebuild(TRUE);
+}
diff --git a/web/modules/contrib/permissions_by_term/permissions_by_term.libraries.yml b/web/modules/contrib/permissions_by_term/permissions_by_term.libraries.yml
new file mode 100644 (file)
index 0000000..e29ba49
--- /dev/null
@@ -0,0 +1,5 @@
+nodeForm:
+  version: 'VERSION'
+  js:
+    js/node-form.js: {}
+    js/node-form.prototype.js: {}
\ No newline at end of file
diff --git a/web/modules/contrib/permissions_by_term/permissions_by_term.links.menu.yml b/web/modules/contrib/permissions_by_term/permissions_by_term.links.menu.yml
new file mode 100644 (file)
index 0000000..7b01a9e
--- /dev/null
@@ -0,0 +1,5 @@
+permissions_by_term.settings:
+  title: 'Permissions by Term'
+  description: 'Manage settings for the Permissions by Term module.'
+  parent: system.admin_config_system
+  route_name: permissions_by_term.settings
\ No newline at end of file
index 5886d9859907ce04adc3c9174b02781d6f174349..e7c8e0adfce3ed3999cf54122ae52e6f5e2d34df 100644 (file)
@@ -11,6 +11,7 @@ use Drupal\permissions_by_term\Controller\PermissionsByTermController;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\node\NodeInterface;
 use Drupal\Core\Session\AccountInterface;
+use Drupal\permissions_by_term\Event\PermissionsByTermDeniedEvent;
 use Drupal\taxonomy\Entity\Term;
 use Drupal\Core\Routing\RouteMatchInterface;
 use Drupal\Core\Cache\Cache;
@@ -27,7 +28,7 @@ function permissions_by_term_help($route_name, RouteMatchInterface $arg) {
         ability to restrict setting individual terms on nodes by user
         or role. If a user is unable to set any terms for a required
         vocabulary, they are blocked from adding or editing content with
-        that vocabulary. For more information, see the online documentation for <a href=":PbT-documentation" target="_blan" title="Online Documentation">Permissions by Term</a>.', [':PbT-documentation' => 'https://www.drupal.org/project/permissions_by_term']) . '</p>';
+        that vocabulary. For more information, see the online documentation for <a href=":PbT-documentation" target="_blan" title="Online Documentation">Permissions by Term</a>.', [':PbT-documentation' => 'https://www.drupal.org/docs/8/modules/permissions-by-term']) . '</p>';
       $output .= '<h3>' . t('Uses') . '</h3>';
       $output .= '<dl>';
       $output .= '<dt>' . t('General') . '</dt>';
@@ -56,7 +57,7 @@ function permissions_by_term_validate($form, FormState $oFormState) {
       if (!empty($terms)) {
         foreach ($terms as $term) {
           $term_id = $term['target_id'];
-          /* @var \Drupal\permissions_by_term\AccessCheck $access_check_service */
+          /* @var \Drupal\permissions_by_term\Service\AccessCheck $access_check_service */
           $access_check_service = \Drupal::service('permissions_by_term.access_check');
           if (!$access_check_service->isAccessAllowedByDatabase($term_id)) {
             $term = Term::load($term_id);
@@ -73,8 +74,8 @@ function permissions_by_term_validate($form, FormState $oFormState) {
     else {
       $term_names = $not_allowed_term_names['0'];
     }
-    $oFormState->setErrorByName('field_tags', t('You are not allowed to use specific taxonomy terms like the following: "term-names". Remove the restricted taxonomy terms from the form field and try again.',
-      ['term-names' => $term_names]));
+    $oFormState->setErrorByName('field_tags', t('You are not allowed to use taxonomy terms like: "@termNames". Remove the restricted taxonomy terms from the form field and try again.',
+      ['@termNames' => $term_names]));
   }
 }
 
@@ -83,15 +84,25 @@ function permissions_by_term_validate($form, FormState $oFormState) {
  */
 function permissions_by_term_submit($form, FormState $formState) {
   $termId = $formState->getFormObject()->getEntity()->id();
-  /* @var \Drupal\permissions_by_term\AccessStorage $access_storage */
+  /* @var \Drupal\permissions_by_term\Service\AccessStorage $access_storage */
   $access_storage = \Drupal::service('permissions_by_term.access_storage');
-  $access_storage->saveTermPermissions($formState, $termId);
-  /**
-   * @var \Drupal\permissions_by_term\NodeAccess $nodeAccess
-   */
-  $nodeAccess = \Drupal::service('permissions_by_term.node_access');
-  $nodeAccess->rebuildByTid($termId, $formState);
-  Cache::invalidateTags(['search_index:node_search']);
+  $access_update = $access_storage->saveTermPermissions($formState, $termId);
+
+  // Check if we need to rebuild node_access by term id
+  $invalidate_cache_tag = false;
+
+  // Has anything has changed?
+  foreach($access_update as $values) {
+    if(!empty($values)) {
+      $invalidate_cache_tag = true;
+      break;
+    }
+  }
+
+  // Do we need to flush the cache?
+  if($invalidate_cache_tag === true) {
+    Cache::invalidateTags(['search_index:node_search']);
+  }
 }
 
 /**
@@ -101,7 +112,7 @@ function permissions_by_term_form_taxonomy_term_form_alter(&$form, FormStateInte
   if (\Drupal::currentUser()->hasPermission('show term permission form on term page')) {
     $iTermId = $oFormState->getFormObject()->getEntity()->id();
 
-    /* @var \Drupal\permissions_by_term\AccessStorage $access_storage */
+    /* @var \Drupal\permissions_by_term\Service\AccessStorage $access_storage */
     $access_storage = \Drupal::service('permissions_by_term.access_storage');
 
     $form['access'] = [
@@ -143,7 +154,7 @@ function permissions_by_term_form_taxonomy_term_form_alter(&$form, FormStateInte
       '#weight' => -10,
     ];
 
-    $aAllowedRoles = $access_storage->getExistingRoleTermPermissionsByTid($iTermId);
+    $aAllowedRoles = $access_storage->getRoleTermPermissionsByTid($iTermId);
 
     // Firstly fetch all translated allowed role names.
     $aTranslatedAllowedRoleNames = [];
@@ -190,6 +201,41 @@ function permissions_by_term_form_taxonomy_term_form_alter(&$form, FormStateInte
  */
 function permissions_by_term_form_alter(&$form, FormStateInterface $oFormState, $form_id) {
   $form['#validate'][] = 'permissions_by_term_validate';
+  if (isNodeEditForm()) {
+    $form['permissions_by_term_info'] = [
+      '#type' => 'details',
+      '#group' => 'advanced',
+      '#title' => t('Permissions by Term'),
+      '#access' => \Drupal::currentUser()->hasPermission('show term permissions on node edit page'),
+    ];
+
+    $nid = null;
+    if (!empty($node = \Drupal::routeMatch()->getParameter('node'))) {
+      $nid = $node->id();
+    }
+
+    $viewFilePath = drupal_get_path('module', 'permissions_by_term') . '/src/View/node-details.html.twig';
+    /**
+     * @var \Drupal\permissions_by_term\Service\NodeEntityBundleInfo $nodeEntityBundleInfo
+     */
+    $nodeEntityBundleInfo = \Drupal::service('permissions_by_term.node_entity_bundle_info');
+
+    $form['permissions_by_term_info']['revision'] = array(
+      '#type' => 'item',
+      '#markup' => $nodeEntityBundleInfo->renderNodeDetails($viewFilePath, $nid),
+    );
+
+    $form['#attached']['library'][] = 'permissions_by_term/nodeForm';
+  }
+}
+
+function isNodeEditForm() {
+  $currentPath = \Drupal::service('path.current')->getPath();
+  if (is_numeric(strpos($currentPath, '/node/'))
+    && (is_numeric(strpos($currentPath, '/edit')) || is_numeric(strpos($currentPath, '/add')))) {
+    return TRUE;
+  }
+  return FALSE;
 }
 
 /**
@@ -203,16 +249,19 @@ function permissions_by_term_form_alter(&$form, FormStateInterface $oFormState,
  * through the administrative interface.
  */
 function permissions_by_term_node_access(NodeInterface $node, $op, AccountInterface $account) {
-  if (method_exists($node, 'id') && $op == 'view') {
+  if (method_exists($node, 'id') && ($op == 'view' OR $op == 'update' OR $op == 'delete')) {
     if (!$node->isPublished() && !$account->hasPermission('Bypass content access control', $account)) {
+      $eventDispatcher = \Drupal::service('event_dispatcher');
+      $accessDeniedEvent = new PermissionsByTermDeniedEvent($node->id());
+      $eventDispatcher->dispatch(PermissionsByTermDeniedEvent::NAME, $accessDeniedEvent);
+
       return AccessResult::forbidden();
     }
 
-    /* @var \Drupal\permissions_by_term\AccessCheck $access_check_service */
-    $access_check_service = \Drupal::service('permissions_by_term.access_check');
-    $oPermissionsByTermController = new PermissionsByTermController($access_check_service);
+    /* @var \Drupal\permissions_by_term\Service\AccessCheck $accessCheck */
+    $accessCheck = \Drupal::service('permissions_by_term.access_check');
 
-    return $oPermissionsByTermController->handleNode($node->id());
+    return $accessCheck->handleNode($node->id());
   }
 }
 
@@ -223,10 +272,10 @@ function permissions_by_term_node_grants(\Drupal\Core\Session\AccountInterface $
 {
     if ($op == 'view') {
       /**
-       * @var \Drupal\permissions_by_term\AccessStorage $accessStorage
+       * @var \Drupal\permissions_by_term\Service\AccessStorage $accessStorage
        */
       $accessStorage = \Drupal::service('permissions_by_term.access_storage');
-      $grants = $accessStorage->getGidsByRealm('permissions_by_term__uid_' . \Drupal::currentUser()->id());
+      $grants = $accessStorage->getGids(\Drupal::currentUser());
 
       return $grants;
     }
@@ -238,27 +287,41 @@ function permissions_by_term_node_grants(\Drupal\Core\Session\AccountInterface $
  * Permissions can be rebuild at /admin/reports/status/rebuild.
  */
 function permissions_by_term_node_access_records(\Drupal\node\NodeInterface $node) {
+  // Do not return any grants for nodes that this module doesn't manage.
+  if (!$node->isPublished()) {
+    return;
+  }
+  $has_term_access_restrictions = FALSE;
+  /* @var \Drupal\permissions_by_term\Service\AccessStorage $access_storage */
+  $access_storage = \Drupal::service('permissions_by_term.access_storage');
+  foreach ($access_storage->getTidsByNid($node->id()) as $tid) {
+    /* @var \Drupal\permissions_by_term\Service\AccessCheck $access_check_service */
+    $access_check_service = \Drupal::service('permissions_by_term.access_check');
+    if ($access_check_service->isAnyPermissionSetForTerm($tid)) {
+      $has_term_access_restrictions = TRUE;
+      break;
+    }
+  }
+  if (!$has_term_access_restrictions) {
+    return;
+  }
+
   /**
-   * @var \Drupal\permissions_by_term\NodeAccess $nodeAccess
+   * @var \Drupal\permissions_by_term\Service\NodeAccess $nodeAccess
    */
   $nodeAccess = \Drupal::service('permissions_by_term.node_access');
-  $grantsForThisNode = $nodeAccess->createGrants($node->id());
-
-  $grants = [];
-  if (!empty($grantsForThisNode)) {
-    foreach ($grantsForThisNode as $grantObject) {
-      $grants[] = [
-        'realm' => $grantObject->realm,
-        'gid' => $grantObject->gid,
-        'grant_view' => $grantObject->grant_view,
-        'grant_update' => $grantObject->grant_update,
-        'grant_delete' => $grantObject->grant_delete,
-        'langcode' => $grantObject->langcode,
-        'fallback' => 1,
-        'nid' => $node->id(),
-      ];
-    }
-  }
+  $grantObject = $nodeAccess->createGrant($node->id(), $node->id());
+
+  $grants[] = [
+    'realm' => $grantObject->realm,
+    'gid' => $grantObject->gid,
+    'grant_view' => $grantObject->grant_view,
+    'grant_update' => $grantObject->grant_update,
+    'grant_delete' => $grantObject->grant_delete,
+    'langcode' => $grantObject->langcode,
+    'fallback' => 1,
+    'nid' => $node->id(),
+  ];
 
   return $grants;
 }
@@ -267,11 +330,6 @@ function permissions_by_term_node_access_records(\Drupal\node\NodeInterface $nod
  * Implements hook_user_insert().
  */
 function permissions_by_term_user_insert($user) {
-  /**
-   * @var \Drupal\permissions_by_term\NodeAccess $nodeAccess
-   */
-  $nodeAccess = \Drupal::service('permissions_by_term.node_access');
-  $nodeAccess->rebuildByUid($user->id(), TRUE);
   Cache::invalidateTags(['search_index:node_search']);
 }
 
@@ -279,22 +337,62 @@ function permissions_by_term_user_insert($user) {
  * Implements hook_user_update().
  */
 function permissions_by_term_user_update($user) {
-  /**
-   * @var \Drupal\permissions_by_term\NodeAccess $nodeAccess
-   */
-  $nodeAccess = \Drupal::service('permissions_by_term.node_access');
-  $nodeAccess->rebuildByUid($user->id());
-  Cache::invalidateTags(['search_index:node_search']);
+  if (\Drupal::currentUser()->hasPermission('administer permissions')) {
+    Cache::invalidateTags(['search_index:node_search']);
+  }
 }
 
 /**
  * Implements hook_node_insert().
  */
 function permissions_by_term_node_insert($node) {
-  /**
-   * @var \Drupal\permissions_by_term\NodeAccess $nodeAccess
-   */
-  $nodeAccess = \Drupal::service('permissions_by_term.node_access');
-  $nodeAccess->rebuildByNid($node->id());
   Cache::invalidateTags(['search_index:node_search']);
 }
+
+/**
+ * Implements hook_options_list_alter().
+ */
+function permissions_by_term_options_list_alter(array &$options, array $context) {
+  $fieldDefinitionSettings = $context['fieldDefinition']->getFieldStorageDefinition()->getSettings();
+  if (!empty($fieldDefinitionSettings['target_type']) && $fieldDefinitionSettings['target_type'] == 'taxonomy_term') {
+    foreach ($options as $id => $names) {
+      if ($id !== '_none') {
+        /**
+         * @var \Drupal\permissions_by_term\Service\Term $term
+         */
+        $term = \Drupal::service('permissions_by_term.term');
+
+        /**
+         * @var \Drupal\permissions_by_term\Service\AccessCheck $accessCheck
+         */
+        $accessCheck = \Drupal::service('permissions_by_term.access_check');
+
+        if (is_array($names)) {
+          foreach ($names as $name) {
+            if (!$accessCheck->isAccessAllowedByDatabase($term->getTermIdByName($name))) {
+              unset($options[$id]);
+            }
+          }
+        } elseif(is_string($names)) {
+          if (!$accessCheck->isAccessAllowedByDatabase($term->getTermIdByName($names))) {
+            unset($options[$id]);
+          }
+        }
+      }
+
+    }
+  }
+}
+
+/**
+ * Implements hook_user_cancel().
+ *
+ * Deletes all term permissions for a user when their account is cancelled.
+ */
+function permissions_by_term_user_cancel($edit, $account, $method) {
+  $deleted_user_id = $account->id();
+
+  /* @var \Drupal\permissions_by_term\Service\AccessStorage $access_storage */
+  $access_storage = \Drupal::service('permissions_by_term.access_storage');
+  $access_storage->deleteAllTermPermissionsByUserId($deleted_user_id);
+}
index eefb14e3672122e493d8efe948ef7123fb07b0cb..73233b583b66b9b544bbaed42c59c2f1971dae66 100644 (file)
@@ -2,3 +2,8 @@ show term permission form on term page:
   title: 'Term permission form on term page'
   description: 'Enables the specific role to edit the term permissions on the term edit page.'
   restrict access: true
+
+show term permissions on node edit page:
+  title: 'Term permission information on node edit page'
+  description: 'Enables the specific role to see the term permissions on the node edit page.'
+  restrict access: true
\ No newline at end of file
index 041b2b78d1c3580b42aecf5e56990a5af3c55c45..d590a7adeea65b4c7143190a1d59c96bfdc7276c 100644 (file)
@@ -5,3 +5,29 @@ permissions_by_term.autocomplete_multiple:
     _controller: '\Drupal\permissions_by_term\Controller\PermissionsByTermController::autoCompleteMultiple'
   requirements:
     _permission: 'access user profiles'
+
+permissions_by_term.settings:
+  path: '/admin/permissions-by-term/settings'
+  defaults:
+    _form: 'Drupal\permissions_by_term\Form\SettingsForm'
+    _title: 'Permissions by Term Settings'
+  requirements:
+    _permission: 'administer site configuration'
+
+permissions_by_term.access_info_by_content_type:
+  path: '/admin/permissions-by-term/access-info-by-content-type/{nodeType}'
+  defaults:
+    _title: ''
+    _controller: '\Drupal\permissions_by_term\Controller\NodeEntityBundleController::getFormInfoByContentType'
+  requirements:
+    _permission: 'show term permissions on node edit page'
+    user: '^[a-zA-Z0-9_]+'
+
+permissions_by_term.access_info_by_url:
+  path: '/admin/permissions-by-term/access-info-by-url'
+  defaults:
+    _title: ''
+    _controller: '\Drupal\permissions_by_term\Controller\NodeEntityBundleController::getFormInfoByUrl'
+  requirements:
+    _permission: 'show term permissions on node edit page'
+    user: '^[a-zA-Z0-9_]+'
\ No newline at end of file
index e0f0f0966fd0a4b844103f3d9b595618fab97562..daca7ac2ed6451d502c6a941f3217b181433fb3c 100644 (file)
@@ -1,18 +1,23 @@
 services:
     permissions_by_term.kernel_event_listener:
-        class: Drupal\permissions_by_term\KernelEventListener
+        class: Drupal\permissions_by_term\Listener\KernelEventListener
         arguments: []
         tags:
             - { name: event_subscriber }
     permissions_by_term.access_check:
-        class: Drupal\permissions_by_term\AccessCheck
-        arguments: ['@entity.manager']
+        class: Drupal\permissions_by_term\Service\AccessCheck
+        arguments: ['@database', '@event_dispatcher']
     permissions_by_term.access_storage:
-        class: Drupal\permissions_by_term\AccessStorage
-        arguments: ['@database']
+        class: Drupal\permissions_by_term\Service\AccessStorage
+        arguments: ['@database',  '@permissions_by_term.term', '@permissions_by_term.access_check']
     permissions_by_term.node_access_record_factory:
         class: \Drupal\permissions_by_term\Factory\NodeAccessRecordFactory
     permissions_by_term.node_access:
-        class: \Drupal\permissions_by_term\NodeAccess
-        arguments: ['@permissions_by_term.access_storage', '@permissions_by_term.node_access_record_factory', '@entity.manager', '@permissions_by_term.access_check', '@database']
-
+        class: \Drupal\permissions_by_term\Service\NodeAccess
+        arguments: ['@permissions_by_term.access_storage', '@permissions_by_term.node_access_record_factory', '@entity_type.manager', '@permissions_by_term.access_check', '@database']
+    permissions_by_term.term:
+        class: \Drupal\permissions_by_term\Service\Term
+        arguments: ['@database']
+    permissions_by_term.node_entity_bundle_info:
+        class: \Drupal\permissions_by_term\Service\NodeEntityBundleInfo
+        arguments: ['@permissions_by_term.access_storage', '@permissions_by_term.term', '@twig', '@database']
\ No newline at end of file
diff --git a/web/modules/contrib/permissions_by_term/phpunit.xml b/web/modules/contrib/permissions_by_term/phpunit.xml
deleted file mode 100644 (file)
index 0e7e570..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-<phpunit bootstrap="./../../core/tests/bootstrap.php" colors="true"
-         beStrictAboutTestsThatDoNotTestAnything="true"
-         beStrictAboutOutputDuringTests="true"
-         beStrictAboutChangesToGlobalState="true"
-         printerClass="\Drupal\Tests\Listeners\HtmlOutputPrinter">
-
-  <env name="PHP_IDE_CONFIG" value="PHPSTORM"/>
-
-  <testsuites>
-    <testsuite name="Unit Test Suite">
-      <directory>./tests/src/Unit</directory>
-    </testsuite>
-  </testsuites>
-
-
-</phpunit>
diff --git a/web/modules/contrib/permissions_by_term/src/AccessCheck.php b/web/modules/contrib/permissions_by_term/src/AccessCheck.php
deleted file mode 100644 (file)
index 9c54f49..0000000
+++ /dev/null
@@ -1,180 +0,0 @@
-<?php
-
-namespace Drupal\permissions_by_term;
-
-use Drupal\Core\Entity\EntityManagerInterface;
-use Drupal\user\Entity\User;
-
-/**
- * AccessCheckService class.
- */
-class AccessCheck implements AccessCheckInterface{
-
-  /**
-   * AccessCheckService constructor.
-   */
-  public function __construct(EntityManagerInterface $entity_manager) {
-    $this->entityManager = $entity_manager;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function canUserAccessByNodeId($iNid, $uid = FALSE) {
-    $node = $this->entityManager->getStorage('node')->load($iNid);
-
-    $access_allowed = TRUE;
-
-    foreach ($node->getFields() as $field) {
-      if ($field->getFieldDefinition()->getType() == 'entity_reference' && $field->getFieldDefinition()->getSetting('target_type') == 'taxonomy_term') {
-        $aReferencedTaxonomyTerms = $field->getValue();
-        if (!empty($aReferencedTaxonomyTerms)) {
-          foreach ($aReferencedTaxonomyTerms as $aReferencedTerm) {
-            if (isset($aReferencedTerm['target_id']) && !$this->isAccessAllowedByDatabase($aReferencedTerm['target_id'], $uid)) {
-              $access_allowed = FALSE;
-            }
-          }
-        }
-      }
-    }
-
-    return $access_allowed;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function viewContainsNode($view) {
-    $bViewContainsNodes = FALSE;
-
-    foreach ($view->result as $view_result) {
-      if (array_key_exists('nid', $view_result) === TRUE) {
-        $bViewContainsNodes = TRUE;
-        break;
-      }
-    }
-    return $bViewContainsNodes;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function removeForbiddenNodesFromView(&$view) {
-    $aNodesToHideInView = [];
-
-    // Iterate over all nodes in view.
-    foreach ($view->result as $v) {
-
-      if ($this->canUserAccessByNodeId($v->nid) === FALSE) {
-        $aNodesToHideInView[] = $v->nid;
-      }
-
-    }
-
-    $counter = 0;
-
-    foreach ($view->result as $v) {
-      if (in_array($v->nid, $aNodesToHideInView)) {
-        unset($view->result[$counter]);
-      }
-      $counter++;
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function isAccessAllowedByDatabase($tid, $uid = FALSE) {
-
-    if ($uid === FALSE) {
-      $user = \Drupal::currentUser();
-    } elseif (is_numeric($uid)) {
-      $user = User::load($uid);
-    }
-
-    // Admin can access everything (user id "1").
-    if ($user->id() == 1) {
-      return TRUE;
-    }
-
-    $tid = intval($tid);
-
-    if (!$this->isAnyPermissionSetForTerm($tid)) {
-      return TRUE;
-    }
-
-    /* At this point permissions are enabled, check to see if this user or one
-     * of their roles is allowed.
-     */
-    $aUserRoles = $user->getRoles();
-
-    foreach ($aUserRoles as $sUserRole) {
-
-      if ($this->isTermAllowedByUserRole($tid, $sUserRole)) {
-        return TRUE;
-      }
-
-    }
-
-    $iUid = intval($user->id());
-
-    if ($this->isTermAllowedByUserId($tid, $iUid)) {
-      return TRUE;
-    }
-
-    return FALSE;
-
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function isTermAllowedByUserId($tid, $iUid) {
-
-    $query_result = db_query("SELECT uid FROM {permissions_by_term_user} WHERE tid = :tid AND uid = :uid",
-      [':tid' => $tid, ':uid' => $iUid])->fetchField();
-
-    if (!empty($query_result)) {
-      return TRUE;
-    }
-    else {
-      return FALSE;
-    }
-
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function isTermAllowedByUserRole($tid, $sUserRole) {
-    $query_result = db_query("SELECT rid FROM {permissions_by_term_role} WHERE tid = :tid AND rid IN (:user_roles)",
-      [':tid' => $tid, ':user_roles' => $sUserRole])->fetchField();
-
-    if (!empty($query_result)) {
-      return TRUE;
-    }
-    else {
-      return FALSE;
-    }
-
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function isAnyPermissionSetForTerm($tid) {
-
-    $iUserTableResults = intval(db_query("SELECT COUNT(1) FROM {permissions_by_term_user} WHERE tid = :tid",
-      [':tid' => $tid])->fetchField());
-
-    $iRoleTableResults = intval(db_query("SELECT COUNT(1) FROM {permissions_by_term_role} WHERE tid = :tid",
-      [':tid' => $tid])->fetchField());
-
-    if ($iUserTableResults > 0 ||
-      $iRoleTableResults > 0) {
-      return TRUE;
-    }
-
-  }
-
-}
diff --git a/web/modules/contrib/permissions_by_term/src/AccessCheckInterface.php b/web/modules/contrib/permissions_by_term/src/AccessCheckInterface.php
deleted file mode 100644 (file)
index 49b6da8..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-<?php
-
-namespace Drupal\permissions_by_term;
-
-interface AccessCheckInterface {
-
-  /**
-   * Checks if a user can access a node by given node id.
-   */
-  public function canUserAccessByNodeId($iNid, $uid = FALSE);
-
-  /**
-   * Returns a boolean if the view is containing nodes.
-   */
-  public function viewContainsNode($view);
-
-  /**
-   * Removes forbidden nodes from view listing.
-   */
-  public function removeForbiddenNodesFromView(&$view);
-
-  /**
-   * @param int $tid
-   * @param bool|int $uid
-   * @return mixed
-   */
-  public function isAccessAllowedByDatabase($tid, $uid = FALSE);
-
-  /**
-   * Returns a boolean if the term is allowed by given user id.
-   *
-   * @param int $iTid
-   *   The taxonomy term id.
-   * @param int $iUid
-   *   The user id.
-   *
-   * @return bool
-   *   Determines by boolean if the given term id is allowed by given user id.
-   */
-  public function isTermAllowedByUserId($iTid, $iUid);
-
-  /**
-   * Returns a boolean if the term is allowed by given user role id.
-   *
-   * @param int $iTid
-   *   The term id.
-   * @param string $sUserRole
-   *   The user role.
-   *
-   * @return bool
-   *   Determines if the term is allowed by the given user role.
-   */
-  public function isTermAllowedByUserRole($iTid, $sUserRole);
-
-  /**
-   * Gets boolean for set permission on a term.
-   *
-   * @param int $iTid
-   *   The taxonomy term id.
-   *
-   * @return bool
-   *   Returns either TRUE or FALSE if there is any permission set for the term.
-   */
-  public function isAnyPermissionSetForTerm($iTid);
-
-}
diff --git a/web/modules/contrib/permissions_by_term/src/AccessStorageInterface.php b/web/modules/contrib/permissions_by_term/src/AccessStorageInterface.php
deleted file mode 100644 (file)
index edea45e..0000000
+++ /dev/null
@@ -1,183 +0,0 @@
-<?php
-
-namespace Drupal\permissions_by_term;
-
-use \Drupal\Core\Form\FormState;
-
-/**
- * Defines an interface for access storage classes.
- */
-interface AccessStorageInterface {
-
-  /**
-   * Checks if the submitted users are existing.
-   *
-   * If an user isn't existing, set an error message.
-   *
-   * @param \Drupal\Core\Form\FormState $form_state
-   */
-  public function checkIfUsersExists(FormState $form_state);
-
-  /**
-   * Gets user term permissions by tid.
-   *
-   * @param int $term_id
-   *
-   * @return mixed
-   *   Existing term permissions.
-   */
-  public function getExistingUserTermPermissionsByTid($term_id);
-
-  /**
-   * Gets role term permissions by tid.
-   *
-   * @param int $term_id
-   *
-   * @return mixed
-   *   Existing role term permissions.
-   */
-  public function getExistingRoleTermPermissionsByTid($term_id);
-
-  /**
-   * Gets single user id by user name.
-   *
-   * @param string $sUsername
-   *   An user name.
-   *
-   * @return int
-   *   User id.
-   */
-  public function getUserIdByName($sUsername);
-
-  /**
-   * Gets multiple user ids by user names.
-   *
-   * @param array $aUserNames
-   *   An array with user names.
-   *
-   * @return array
-   *   User ids.
-   */
-  public function getUserIdsByNames($aUserNames);
-
-  /**
-   * Gets the user names from users.
-   *
-   * Users which have granted access for a taxonomy term.
-   *
-   * @param int $term_id
-   *
-   * @return mixed
-   *   Gets user ids, which are allowed to access.
-   */
-  public function getAllowedUserIds($term_id);
-
-  /**
-   * Deletes term permissions by user id.
-   *
-   * @param array $aUserIdsAccessRemove
-   *   An array with user ids, which access will be removed.
-   * @param int $term_id
-   *   The term id to remove.
-   */
-  public function deleteTermPermissionsByUserIds($aUserIdsAccessRemove, $term_id);
-
-  /**
-   * Deletes term permissions by role ids.
-   *
-   * @param array $aRoleIdsAccessRemove
-   *   An array with role ids, that will be removed.
-   * @param int $term_id
-   *   The term id.
-   */
-  public function deleteTermPermissionsByRoleIds($aRoleIdsAccessRemove, $term_id);
-
-  /**
-   * Adds term permissions by user ids.
-   *
-   * @param array $aUserIdsGrantedAccess
-   *   The user ids which will get granted access.
-   * @param int $term_id
-   *
-   * @throws \Exception
-   */
-  public function addTermPermissionsByUserIds($aUserIdsGrantedAccess, $term_id);
-
-  /**
-   * Adds term permissions by role ids.
-   *
-   * @param array $aRoleIdsGrantedAccess
-   *   The role ids which will gain access.
-   * @param int $term_id
-   *
-   * @throws \Exception
-   */
-  public function addTermPermissionsByRoleIds($aRoleIdsGrantedAccess, $term_id);
-
-  /**
-   * Gets the term id by term name.
-   *
-   * @param string $sTermName
-   *   The term name.
-   *
-   * @return int
-   *   The term id.
-   */
-  public function getTermIdByName($sTermName);
-
-  /**
-   * Gets the taxonomy name by id.
-   *
-   * @param int $term_id
-   *   The taxonomy term id.
-   *
-   * @return string
-   *   Gets a term name by an id.
-   */
-  public function getTermNameById($term_id);
-
-  /**
-   * Saves term permissions by users.
-   *
-   * Opposite to save term permission by roles.
-   *
-   * @param \Drupal\Core\Form\FormState $form_state
-   * @param int $term_id
-   *
-   * @return array
-   *   Data for database queries.
-   */
-  public function saveTermPermissions(FormState $form_state, $term_id);
-
-  /**
-   * Prepares the data which has to be applied to the database.
-   *
-   * @param array $aExistingUserPermissions
-   *   The permissions for existing user.
-   * @param array $aSubmittedUserIdsGrantedAccess
-   *   The user ids which get access.
-   * @param array $aExistingRoleIdsGrantedAccess
-   *   The existing role ids.
-   * @param array $aSubmittedRolesGrantedAccess
-   *   The user roles which get access.
-   *
-   * @return array
-   *   User ID and role data.
-   */
-  public function getPreparedDataForDatabaseQueries($aExistingUserPermissions,
-                                                    $aSubmittedUserIdsGrantedAccess,
-                                                    $aExistingRoleIdsGrantedAccess,
-                                                    $aSubmittedRolesGrantedAccess);
-
-  /**
-   * The form value for allowed users as string to be shown to the user.
-   *
-   * @param \Drupal\user\Entity\User[] $aAllowedUsers
-   *   An array with the allowed users.
-   *
-   * @return null|string
-   *   Either null or the user name.
-   */
-  public function getUserFormValue($aAllowedUsers);
-
-}
diff --git a/web/modules/contrib/permissions_by_term/src/Controller/NodeEntityBundleController.php b/web/modules/contrib/permissions_by_term/src/Controller/NodeEntityBundleController.php
new file mode 100644 (file)
index 0000000..016ea4f
--- /dev/null
@@ -0,0 +1,116 @@
+<?php
+
+namespace Drupal\permissions_by_term\Controller;
+
+use Drupal\Core\Controller\ControllerBase;
+use Drupal\Core\Entity\EntityFieldManager;
+use Drupal\permissions_by_term\Service\AccessStorage;
+use Drupal\permissions_by_term\Service\NodeEntityBundleInfo;
+use Symfony\Component\HttpFoundation\JsonResponse;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Class NodeEntityBundleController
+ *
+ * @package Drupal\permissions_by_term\Controller
+ */
+class NodeEntityBundleController extends ControllerBase {
+
+  /**
+   * @var EntityFieldManager
+   */
+  private $entityFieldManager;
+
+  /**
+   * @var AccessStorage
+   */
+  private $accessStorage;
+
+  /**
+   * @var NodeEntityBundleInfo
+   */
+  private $nodeEntityBundleInfo;
+
+  /**
+   * NodeBundleInfoController constructor.
+   *
+   * @param EntityFieldManager   $entityFieldManager
+   * @param AccessStorage        $accessStorage
+   * @param NodeEntityBundleInfo $nodeEntityBundleInfo
+   */
+  public function __construct(EntityFieldManager $entityFieldManager, AccessStorage $accessStorage, NodeEntityBundleInfo $nodeEntityBundleInfo) {
+    $this->entityFieldManager = $entityFieldManager;
+    $this->accessStorage = $accessStorage;
+    $this->nodeEntityBundleInfo = $nodeEntityBundleInfo;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container) {
+    return new static(
+      $container->get('entity_field.manager'),
+      $container->get('permissions_by_term.access_storage'),
+      $container->get('permissions_by_term.node_entity_bundle_info')
+    );
+  }
+
+  /**
+   * @param string $nodeType
+   *
+   * @return JsonResponse
+   */
+  public function getFormInfoByContentType($nodeType) {
+    $fields = $this->entityFieldManager->getFieldDefinitions('node', $nodeType);
+
+    $fieldNames = null;
+    foreach ($fields as $field) {
+      $fieldDefinitionSettings = $field->getSettings();
+      if (!empty($fieldDefinitionSettings['target_type']) && $fieldDefinitionSettings['target_type'] == 'taxonomy_term') {
+        $fieldNames[] = $field->getFieldStorageDefinition()->getName();
+      }
+    }
+
+    return new JsonResponse(
+      [
+        'taxonomyRelationFieldNames' => $fieldNames,
+        'permissions'                => $this->nodeEntityBundleInfo->getPermissions()
+      ]
+    );
+  }
+
+  /**
+   * @return JsonResponse
+   */
+  public function getFormInfoByUrl() {
+
+    $contentType = $this->getContentType(\Drupal::request()->query->get('url'));
+
+    $fields = $this->entityFieldManager->getFieldDefinitions('node', $contentType);
+
+    $fieldNames = null;
+    foreach ($fields as $field) {
+      $fieldDefinitionSettings = $field->getSettings();
+      if (!empty($fieldDefinitionSettings['target_type']) && $fieldDefinitionSettings['target_type'] == 'taxonomy_term') {
+        $fieldNames[] = $field->getFieldStorageDefinition()->getName();
+      }
+    }
+
+    return new JsonResponse(
+      [
+        'taxonomyRelationFieldNames' => $fieldNames,
+        'permissions'                => $this->nodeEntityBundleInfo->getPermissions()
+      ]
+    );
+  }
+
+  private function getContentType($nodeEditPath) {
+    preg_match_all('!\d+!', $nodeEditPath, $matches);
+    $nid = $matches[0][0];
+
+    $node = \Drupal::entityTypeManager()->getStorage('node')->load($nid);
+
+    return $node->getType();
+  }
+
+}
\ No newline at end of file
index c35448d8aa1b9099fe464abd2b7b5e600f87f314..4121de26e59d9bbac000dfe02cbbf18bcd704c5b 100644 (file)
@@ -5,48 +5,12 @@ namespace Drupal\permissions_by_term\Controller;
 use Drupal\Core\Controller\ControllerBase;
 use \Drupal\Component\Utility\Tags;
 use Symfony\Component\HttpFoundation\JsonResponse;
-use \Drupal\permissions_by_term\AccessCheckInterface;
-use \Drupal\Component\Utility\Html;
-use \Drupal\Core\Access\AccessResult;
 
 /**
  * Default controller for the permissions_by_term module.
  */
 class PermissionsByTermController extends ControllerBase {
 
-  /**
-   * PermissionsByTermController constructor.
-   *
-   * @param \Drupal\permissions_by_term\AccessCheckInterface
-   */
-  public function __construct(AccessCheckInterface $access_check_service) {
-    $this->oAccessCheckService = $access_check_service;
-  }
-
-  /**
-   * Handles views in module's logic.
-   */
-  public function handleViews(&$view) {
-    if ($this->oAccessCheckService->viewContainsNode($view) === TRUE) {
-      $this->oAccessCheckService->removeForbiddenNodesFromView($view);
-    }
-  }
-
-  /**
-   * Handles nodes in module's logic.
-   *
-   * @return \Drupal\Core\Access\AccessResult
-   *   The AccessResult object.
-   */
-  public function handleNode($node_id) {
-    if ($this->oAccessCheckService->canUserAccessByNodeId($node_id) === TRUE) {
-      return AccessResult::neutral();
-    }
-    else {
-      return AccessResult::forbidden();
-    }
-  }
-
   /**
    * Returns JSON response for user's autocomplete field in permissions form.
    *
@@ -71,7 +35,7 @@ class PermissionsByTermController extends ControllerBase {
 
     foreach ($aUserIds as $iUserId) {
       $oUser = user_load($iUserId);
-      $matches[$prefix . $oUser->getUsername()] = Html::escape($oUser->getUsername());
+      $matches[$prefix . $oUser->getDisplayName()] = $oUser->getDisplayName();
     }
 
     return new JsonResponse($matches);
diff --git a/web/modules/contrib/permissions_by_term/src/Entity/Config/Settings.php b/web/modules/contrib/permissions_by_term/src/Entity/Config/Settings.php
new file mode 100644 (file)
index 0000000..368b072
--- /dev/null
@@ -0,0 +1,57 @@
+<?php
+
+namespace Drupal\permissions_by_term\Entity\Config;
+
+use Drupal\Core\Config\Entity\ConfigEntityBase;
+
+/**
+ * Defines the settings entity.
+ *
+ * The lines below, starting with '@ConfigEntityType,' are a plugin annotation.
+ * These define the entity type to the entity type manager.
+ *
+ * The properties in the annotation are as follows:
+ *  - id: The machine name of the entity type.
+ *  - label: The human-readable label of the entity type. We pass this through
+ *    the "@Translation" wrapper so that the multilingual system may
+ *    translate it in the user interface.
+ *  - handlers: An array of entity handler classes, keyed by handler type.
+ *    - access: The class that is used for access checks.
+ *    - list_builder: The class that provides listings of the entity.
+ *    - form: An array of entity form classes keyed by their operation.
+ *  - entity_keys: Specifies the class properties in which unique keys are
+ *    stored for this entity type. Unique keys are properties which you know
+ *    will be unique, and which the entity manager can use as unique in database
+ *    queries.
+ *  - links: entity URL definitions. These are mostly used for Field UI.
+ *    Arbitrary keys can set here. For example, User sets cancel-form, while
+ *    Node uses delete-form.
+ *
+ * @see http://previousnext.com.au/blog/understanding-drupal-8s-config-entities
+ * @see annotation
+ * @see Drupal\Core\Annotation\Translation
+ *
+ * @ingroup permissions_by_term
+ *
+ * @ConfigEntityType(
+ *   id = "settings",
+ *   label = @Translation("Settings"),
+ *   entity_keys = {
+ *     "id" = "id",
+ *     "value" = "value"
+ *   }
+ * )
+ */
+class Settings extends ConfigEntityBase {
+
+  /**
+   * @var string
+   */
+  public $id;
+
+  /**
+   * @var bool
+   */
+  public $value;
+
+}
diff --git a/web/modules/contrib/permissions_by_term/src/Event/PermissionsByTermDeniedEvent.php b/web/modules/contrib/permissions_by_term/src/Event/PermissionsByTermDeniedEvent.php
new file mode 100644 (file)
index 0000000..2b80be2
--- /dev/null
@@ -0,0 +1,36 @@
+<?php
+
+namespace Drupal\permissions_by_term\Event;
+
+use Symfony\Component\EventDispatcher\Event;
+
+/**
+ * Class PermissionsByTermDeniedEvent
+ *
+ * @package Drupal\permissions_by_term\Event
+ */
+class PermissionsByTermDeniedEvent extends Event {
+  const NAME = 'permissions_by_term.access.denied';
+
+  /**
+   * @var int
+   */
+  protected $nid;
+
+  /**
+   * PermissionsByTermDeniedEvent constructor.
+   *
+   * @param int $nid
+   */
+  public function __construct($nid) {
+    $this->nid = $nid;
+  }
+
+  /**
+   * @return int
+   */
+  public function getNid() {
+    return $this->nid;
+  }
+
+}
\ No newline at end of file
diff --git a/web/modules/contrib/permissions_by_term/src/Form/SettingsForm.php b/web/modules/contrib/permissions_by_term/src/Form/SettingsForm.php
new file mode 100644 (file)
index 0000000..fe2dff6
--- /dev/null
@@ -0,0 +1,67 @@
+<?php
+
+namespace Drupal\permissions_by_term\Form;
+
+use Drupal\Core\Form\ConfigFormBase;
+use Drupal\Core\Form\FormStateInterface;
+
+
+class SettingsForm extends ConfigFormBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getFormId() {
+    return 'permissions_by_term_settings';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getEditableConfigNames() {
+    return [
+      'permissions_by_term.settings'
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildForm(array $form, FormStateInterface $form_state) {
+    $config = $this->config('permissions_by_term.settings');
+
+    $form = parent::buildForm($form, $form_state);
+
+    $description = <<<EOT
+By default users have granted access to an node, as long they have access to a <strong>single</strong>
+related taxonomy term. If the single term restriction option is checked, they must
+have access to <strong>all</strong> related taxonomy terms to access an node. Because as soon the
+specific node is related to a "single" non-permitted taxonomy term, the access will 
+be disallowed.
+EOT;
+
+    $form['single_term_restriction'] = [
+      '#type' => 'checkbox',
+      '#title' => t('Single Term Restriction'),
+      '#description' => t($description),
+      '#default_value' => \Drupal::config('permissions_by_term.settings.single_term_restriction')->get('value'),
+    ];
+
+    return parent::buildForm($form, $form_state);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitForm(array &$form, FormStateInterface $form_state) {
+    \Drupal::configFactory()
+      ->getEditable('permissions_by_term.settings.single_term_restriction')
+      ->set('value', $form_state->getValue('single_term_restriction'))
+      ->save();
+
+    node_access_rebuild(true);
+
+    parent::submitForm($form, $form_state);
+  }
+
+}
similarity index 79%
rename from web/modules/contrib/permissions_by_term/src/KernelEventListener.php
rename to web/modules/contrib/permissions_by_term/src/Listener/KernelEventListener.php
index 276583de381bb200ccaf8ce73c21836bc650d962..e3a8df074810c0d4857b38013c3125cc0d0f8cb1 100644 (file)
@@ -1,7 +1,9 @@
 <?php
 
-namespace Drupal\permissions_by_term;
+namespace Drupal\permissions_by_term\Listener;
 
+use Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher;
+use Drupal\permissions_by_term\Event\PermissionsByTermDeniedEvent;
 use Symfony\Component\EventDispatcher\EventSubscriberInterface;
 use Symfony\Component\HttpKernel\KernelEvents;
 use Symfony\Component\HttpFoundation\JsonResponse;
@@ -9,6 +11,8 @@ use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
 use Symfony\Component\HttpKernel\Event\GetResponseEvent;
 use Symfony\Component\HttpFoundation\RedirectResponse;
 use Symfony\Component\HttpFoundation\Request;
+use Drupal\permissions_by_term\Service\AccessCheck;
+use Drupal\permissions_by_term\Service\Term;
 
 /**
  * Class KernelEventListener.
@@ -18,13 +22,29 @@ use Symfony\Component\HttpFoundation\Request;
 class KernelEventListener implements EventSubscriberInterface
 {
 
+  /**
+   * @var AccessCheck
+   */
+  private $accessCheckService;
+
+  /**
+   * @var Term
+   */
+  private $term;
+
+  /**
+   * @var ContainerAwareEventDispatcher
+   */
+  private $eventDispatcher;
+
   /**
    * Instantiating of objects on class construction.
    */
   public function __construct()
   {
     $this->accessCheckService = \Drupal::service('permissions_by_term.access_check');
-    $this->accessStorageService = \Drupal::service('permissions_by_term.access_storage');
+    $this->term = \Drupal::service('permissions_by_term.term');
+    $this->eventDispatcher = \Drupal::service('event_dispatcher');
   }
 
   /**
@@ -36,6 +56,9 @@ class KernelEventListener implements EventSubscriberInterface
     if ($this->canRequestGetNode($event->getRequest())) {
       $nid = $event->getRequest()->attributes->get('node')->get('nid')->getValue()['0']['value'];
       if (!$this->accessCheckService->canUserAccessByNodeId($nid)) {
+        $accessDeniedEvent = new PermissionsByTermDeniedEvent($nid);
+        $this->eventDispatcher->dispatch(PermissionsByTermDeniedEvent::NAME, $accessDeniedEvent);
+
         $this->sendUserToAccessDeniedPage();
       }
     }
@@ -46,7 +69,7 @@ class KernelEventListener implements EventSubscriberInterface
       $query_string = $event->getRequest()->get('q');
       $query_string = trim($query_string);
 
-      $tid = $this->accessStorageService->getTermIdByName($query_string);
+      $tid = $this->term->getTermIdByName($query_string);
       if (!$this->accessCheckService->isAccessAllowedByDatabase($tid)) {
         $this->sendUserToAccessDeniedPage();
       }
@@ -71,7 +94,7 @@ class KernelEventListener implements EventSubscriberInterface
       $suggested_terms = json_decode($json_suggested_terms);
       $allowed_terms = [];
       foreach ($suggested_terms as $term) {
-        $tid = $this->accessStorageService->getTermIdByName($term->label);
+        $tid = $this->term->getTermIdByName($term->label);
         if ($this->accessCheckService->isAccessAllowedByDatabase($tid)) {
           $allowed_terms[] = [
             'value' => $term->value,
diff --git a/web/modules/contrib/permissions_by_term/src/Plugin/views/filter/PermissionsByTerm.php b/web/modules/contrib/permissions_by_term/src/Plugin/views/filter/PermissionsByTerm.php
deleted file mode 100644 (file)
index aee728b..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-<?php
-
-namespace Drupal\d8views\Plugin\views\filter;
-
-use Drupal\views\Plugin\views\display\DisplayPluginBase;
-use Drupal\views\Plugin\views\filter\InOperator;
-use Drupal\views\ViewExecutable;
-
-/**
- * Filters by given list of node title options.
- *
- * @ingroup views_filter_handlers
- *
- * @ViewsFilter("d8views_node_titles")
- */
-class PermissionsByTerm extends InOperator {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function init(ViewExecutable $view, DisplayPluginBase $display, array &$options = NULL) {
-    parent::init($view, $display, $options);
-    $this->valueTitle = t('Allowed node titles');
-    $this->definition['options callback'] = [$this, 'generateOptions'];
-  }
-
-  /**
-   * Override the query.
-   *
-   * So that no filtering takes place if the user doesn't
-   * select any options.
-   */
-  public function query() {
-    if (!empty($this->value)) {
-      parent::query();
-    }
-  }
-
-  /**
-   * Skip validation.
-   *
-   * If no options have been chosen so we can use it as a non-filter.
-   */
-  public function validate() {
-    if (!empty($this->value)) {
-      parent::validate();
-    }
-  }
-
-  /**
-   * Helper function that generates the options.
-   *
-   * @return array
-   *   Array keys are used to compare with the table field values.
-   */
-  public function generateOptions() {
-    return [
-      'my title' => 'my title',
-      'another title' => 'another title',
-    ];
-  }
-
-}
diff --git a/web/modules/contrib/permissions_by_term/src/Service/AccessCheck.php b/web/modules/contrib/permissions_by_term/src/Service/AccessCheck.php
new file mode 100644 (file)
index 0000000..9e1c03b
--- /dev/null
@@ -0,0 +1,189 @@
+<?php
+
+namespace Drupal\permissions_by_term\Service;
+
+use Drupal\Core\Access\AccessResult;
+use Drupal\Core\Database\Connection;
+use Drupal\user\Entity\User;
+use Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher;
+use Drupal\permissions_by_term\Event\PermissionsByTermDeniedEvent;
+
+/**
+ * AccessCheckService class.
+ */
+class AccessCheck {
+
+  /**
+   * The database connection.
+   *
+   * @var \Drupal\Core\Database\Connection
+   */
+  protected $database;
+
+  /**
+   * @var ContainerAwareEventDispatcher
+   */
+  private $eventDispatcher;
+
+  /**
+   * Constructs AccessCheck object.
+   *
+   * @param Connection $database
+   *   The database connection.
+   */
+  public function __construct(Connection $database, ContainerAwareEventDispatcher $eventDispatcher) {
+    $this->database  = $database;
+    $this->eventDispatcher = $eventDispatcher;
+  }
+
+  /**
+   * @return bool
+   */
+  public function canUserAccessByNodeId($nid, $uid = FALSE) {
+    if (!$singleTermRestriction = \Drupal::config('permissions_by_term.settings.single_term_restriction')->get('value')) {
+      $access_allowed = TRUE;
+    } else {
+      $access_allowed = FALSE;
+    }
+
+    $terms = $this->database
+      ->query("SELECT tid FROM {taxonomy_index} WHERE nid = :nid",
+      [':nid' => $nid])->fetchAll();
+
+    foreach ($terms as $term) {
+      $access_allowed = $this->isAccessAllowedByDatabase($term->tid, $uid);
+      if (!$access_allowed) {
+        if ($singleTermRestriction) {
+          return $access_allowed;
+        }
+      }
+
+      if ($access_allowed && !$singleTermRestriction) {
+        return $access_allowed;
+      }
+
+    }
+
+    return $access_allowed;
+  }
+
+  /**
+   * @param int      $tid
+   * @param bool|int $uid
+   * @return array
+   */
+  public function isAccessAllowedByDatabase($tid, $uid = FALSE) {
+
+    if ($uid === FALSE) {
+      $user = \Drupal::currentUser();
+    } elseif (is_numeric($uid)) {
+      $user = User::load($uid);
+    }
+
+    // Admin can access everything (user id "1").
+    if ($user->id() == 1) {
+      return TRUE;
+    }
+
+    $tid = intval($tid);
+
+    if (!$this->isAnyPermissionSetForTerm($tid)) {
+      return TRUE;
+    }
+
+    /* At this point permissions are enabled, check to see if this user or one
+     * of their roles is allowed.
+     */
+    $aUserRoles = $user->getRoles();
+
+    foreach ($aUserRoles as $sUserRole) {
+
+      if ($this->isTermAllowedByUserRole($tid, $sUserRole)) {
+        return TRUE;
+      }
+
+    }
+
+    $iUid = intval($user->id());
+
+    if ($this->isTermAllowedByUserId($tid, $iUid)) {
+      return TRUE;
+    }
+
+    return FALSE;
+
+  }
+
+  /**
+   * @param int $tid
+   * @param int $iUid
+   *
+   * @return bool
+   */
+  private function isTermAllowedByUserId($tid, $iUid) {
+    $query_result = $this->database->query("SELECT uid FROM {permissions_by_term_user} WHERE tid = :tid AND uid = :uid",
+      [':tid' => $tid, ':uid' => $iUid])->fetchField();
+
+    if (!empty($query_result)) {
+      return TRUE;
+    }
+    else {
+      return FALSE;
+    }
+  }
+
+  /**
+   * @param int    $tid
+   * @param string $sUserRole
+   *
+   * @return bool
+   */
+  public function isTermAllowedByUserRole($tid, $sUserRole) {
+    $query_result = $this->database->query("SELECT rid FROM {permissions_by_term_role} WHERE tid = :tid AND rid IN (:user_roles)",
+      [':tid' => $tid, ':user_roles' => $sUserRole])->fetchField();
+
+    if (!empty($query_result)) {
+      return TRUE;
+    }
+    else {
+      return FALSE;
+    }
+
+  }
+
+  /**
+   * @param int $tid
+   *
+   * @return bool
+   */
+  public function isAnyPermissionSetForTerm($tid) {
+
+    $iUserTableResults = intval($this->database->query("SELECT COUNT(1) FROM {permissions_by_term_user} WHERE tid = :tid",
+      [':tid' => $tid])->fetchField());
+
+    $iRoleTableResults = intval($this->database->query("SELECT COUNT(1) FROM {permissions_by_term_role} WHERE tid = :tid",
+      [':tid' => $tid])->fetchField());
+
+    if ($iUserTableResults > 0 ||
+      $iRoleTableResults > 0) {
+      return TRUE;
+    }
+
+  }
+
+  /**
+   * @return AccessResult
+   */
+  public function handleNode($nodeId) {
+    if ($this->canUserAccessByNodeId($nodeId) === TRUE) {
+      return AccessResult::neutral();
+    }
+    else {
+      $accessDeniedEvent = new PermissionsByTermDeniedEvent($nodeId);
+      $this->eventDispatcher->dispatch(PermissionsByTermDeniedEvent::NAME, $accessDeniedEvent);
+
+      return AccessResult::forbidden();
+    }
+  }
+
+}
similarity index 59%
rename from web/modules/contrib/permissions_by_term/src/AccessStorage.php
rename to web/modules/contrib/permissions_by_term/src/Service/AccessStorage.php
index 50961cef7e35ea6598788c17826fbed6435e0834..2342e898837846e100e24e21878f80d75175c55f 100644 (file)
@@ -1,31 +1,26 @@
 <?php
 
-namespace Drupal\permissions_by_term;
+namespace Drupal\permissions_by_term\Service;
 
-use Drupal\Core\Database\Driver\mysql\Connection;
+use Drupal\Core\Database\Connection;
 use Drupal\Component\Utility\Tags;
 use Drupal\Core\Form\FormState;
+use Drupal\Core\Session\AccountInterface;
+use Drupal\user\Entity\User;
 
 /**
  * Class AccessStorage.
  *
- * Defines an API to the database in the term access context.
- *
- * The "protected" class methods are meant for protection regarding Drupal's
- * forms and presentation layer.
- *
- * The "public" class methods can be used for extensions.
- *
  * @package Drupal\permissions_by_term
  */
-class AccessStorage implements AccessStorageInterface {
+class AccessStorage {
 
   /**
-   * Drupal\Core\Database\Driver\mysql\Connection definition.
+   * The database connection.
    *
-   * @var Drupal\Core\Database\Driver\mysql\Connection
+   * @var Connection
    */
-  protected $oDatabase;
+  protected $database;
 
   /**
    * The term name for which the access is set.
@@ -48,14 +43,32 @@ class AccessStorage implements AccessStorageInterface {
    */
   protected $aSubmittedRolesGrantedAccess;
 
+  /**
+   * @var Term
+   */
+  protected $term;
+
+  /**
+   * @var string
+   */
+  const NODE_ACCESS_REALM = 'permissions_by_term';
+
+  /**
+   * @var AccessCheck
+   */
+  protected $accessCheck;
+
   /**
    * AccessStorageService constructor.
    *
-   * @param \Drupal\Core\Database\Driver\mysql\Connection $database
-   *   The connection to the database.
+   * @param Connection  $database
+   * @param Term        $term
+   * @param AccessCheck $accessCheck
    */
-  public function __construct(Connection $database) {
-    $this->oDatabase  = $database;
+  public function __construct(Connection $database, Term $term, AccessCheck $accessCheck) {
+    $this->database  = $database;
+    $this->term = $term;
+    $this->accessCheck = $accessCheck;
   }
 
   /**
@@ -76,7 +89,7 @@ class AccessStorage implements AccessStorageInterface {
   }
 
   /**
-   * {@inheritdoc}
+   * @param FormState $form_state
    */
   public function checkIfUsersExists(FormState $form_state) {
     $sAllowedUsers = $form_state->getValue('access')['user'];
@@ -94,10 +107,12 @@ class AccessStorage implements AccessStorageInterface {
   }
 
   /**
-   * {@inheritdoc}
+   * @param int $term_id
+   *
+   * @return array
    */
-  public function getExistingUserTermPermissionsByTid($term_id) {
-    return $this->oDatabase->select('permissions_by_term_user', 'pu')
+  public function getUserTermPermissionsByTid($term_id) {
+    return $this->database->select('permissions_by_term_user', 'pu')
       ->condition('tid', $term_id)
       ->fields('pu', ['uid'])
       ->execute()
@@ -105,10 +120,57 @@ class AccessStorage implements AccessStorageInterface {
   }
 
   /**
-   * {@inheritdoc}
+   * @param int   $uid
+   * @param array $rids
+   *
+   * @return array
+   */
+  public function getPermittedTids($uid, $rids) {
+    $permittedTids = $this->database->select('permissions_by_term_user', 'pu')
+      ->condition('uid', $uid)
+      ->fields('pu', ['tid'])
+      ->execute()
+      ->fetchCol();
+
+    foreach ($rids as $rid) {
+      $permittedTidsByRid = $this->database->select('permissions_by_term_role', 'pr')
+        ->condition('rid', $rid)
+        ->fields('pr', ['tid'])
+        ->execute()
+        ->fetchCol();
+
+      $permittedTids = array_merge($permittedTidsByRid, $permittedTids);
+    }
+
+    return array_unique($permittedTids);
+  }
+
+  /**
+   * @param array $tids
+   *
+   * @return array
+   */
+  public function getUserTermPermissionsByTids($tids) {
+    $uids = [];
+
+    foreach ($tids as $tid) {
+      if (!empty($tmpUids = $this->getUserTermPermissionsByTid($tid))) {
+        foreach ($tmpUids as $tmpUid) {
+          $uids[] = $tmpUid;
+        }
+      }
+    }
+
+    return $uids;
+  }
+
+  /**
+   * @param int $term_id
+   *
+   * @return array
    */
-  public function getExistingRoleTermPermissionsByTid($term_id) {
-    return $this->oDatabase->select('permissions_by_term_role', 'pr')
+  public function getRoleTermPermissionsByTid($term_id) {
+    return $this->database->select('permissions_by_term_role', 'pr')
       ->condition('tid', $term_id)
       ->fields('pr', ['rid'])
       ->execute()
@@ -116,10 +178,32 @@ class AccessStorage implements AccessStorageInterface {
   }
 
   /**
-   * {@inheritdoc}
+   * @param array $tids
+   *
+   * @return array
+   */
+  public function getRoleTermPermissionsByTids($tids) {
+    $rids = [];
+
+    foreach ($tids as $tid) {
+      $tmpRids = $this->getRoleTermPermissionsByTid($tid);
+      if (!empty($tmpRids)) {
+        foreach ($tmpRids as $tmpRid) {
+          $rids[] = $tmpRid;
+        }
+      }
+    }
+
+    return $rids;
+  }
+
+  /**
+   * @param string $sUsername
+   *
+   * @return int
    */
   public function getUserIdByName($sUsername) {
-    return $this->oDatabase->select('users_field_data', 'ufd')
+    return $this->database->select('users_field_data', 'ufd')
       ->condition('name', $sUsername)
       ->fields('ufd', ['uid'])
       ->execute()
@@ -127,7 +211,9 @@ class AccessStorage implements AccessStorageInterface {
   }
 
   /**
-   * {@inheritdoc}
+   * @param array $aUserNames
+   *
+   * @return array
    */
   public function getUserIdsByNames($aUserNames) {
     $aUserIds = [];
@@ -139,10 +225,12 @@ class AccessStorage implements AccessStorageInterface {
   }
 
   /**
-   * {@inheritdoc}
+   * @param int $term_id
+   *
+   * @return array
    */
   public function getAllowedUserIds($term_id) {
-    $query = $this->oDatabase->select('permissions_by_term_user', 'p')
+    $query = $this->database->select('permissions_by_term_user', 'p')
       ->fields('p', ['uid'])
       ->condition('p.tid', $term_id);
 
@@ -152,11 +240,12 @@ class AccessStorage implements AccessStorageInterface {
   }
 
   /**
-   * {@inheritdoc}
+   * @param array $aUserIdsAccessRemove
+   * @param int   $term_id
    */
   public function deleteTermPermissionsByUserIds($aUserIdsAccessRemove, $term_id) {
     foreach ($aUserIdsAccessRemove as $iUserId) {
-      $this->oDatabase->delete('permissions_by_term_user')
+      $this->database->delete('permissions_by_term_user')
         ->condition('uid', $iUserId, '=')
         ->condition('tid', $term_id, '=')
         ->execute();
@@ -164,11 +253,12 @@ class AccessStorage implements AccessStorageInterface {
   }
 
   /**
-   * {@inheritdoc}
+   * @param array $aRoleIdsAccessRemove
+   * @param int   $term_id
    */
   public function deleteTermPermissionsByRoleIds($aRoleIdsAccessRemove, $term_id) {
     foreach ($aRoleIdsAccessRemove as $sRoleId) {
-      $this->oDatabase->delete('permissions_by_term_role')
+      $this->database->delete('permissions_by_term_role')
         ->condition('rid', $sRoleId, '=')
         ->condition('tid', $term_id, '=')
         ->execute();
@@ -176,47 +266,42 @@ class AccessStorage implements AccessStorageInterface {
   }
 
   /**
-   * {@inheritdoc}
+   * @param int $userId
+   */
+  public function deleteAllTermPermissionsByUserId($userId) {
+    $this->database->delete('permissions_by_term_user')
+      ->condition('uid', $userId, '=')
+      ->execute();
+  }
+
+  /**
+   * @param array $aUserIdsGrantedAccess
+   * @param int   $term_id
+   *
+   * @throws \Exception
    */
   public function addTermPermissionsByUserIds($aUserIdsGrantedAccess, $term_id) {
     foreach ($aUserIdsGrantedAccess as $iUserIdGrantedAccess) {
-      $this->oDatabase->insert('permissions_by_term_user')
+      $this->database->insert('permissions_by_term_user')
         ->fields(['tid', 'uid'], [$term_id, $iUserIdGrantedAccess])
         ->execute();
     }
   }
 
   /**
-   * {@inheritdoc}
+   * @param array $aRoleIdsGrantedAccess
+   * @param int   $term_id
+   *
+   * @throws \Exception
    */
   public function addTermPermissionsByRoleIds($aRoleIdsGrantedAccess, $term_id) {
     foreach ($aRoleIdsGrantedAccess as $sRoleIdGrantedAccess) {
-      $this->oDatabase->insert('permissions_by_term_role')
+      $this->database->insert('permissions_by_term_role')
         ->fields(['tid', 'rid'], [$term_id, $sRoleIdGrantedAccess])
         ->execute();
     }
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public function getTermIdByName($sTermName) {
-    $aTermId = \Drupal::entityQuery('taxonomy_term')
-      ->condition('name', $sTermName)
-      ->execute();
-    return key($aTermId);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getTermNameById($term_id) {
-    $term_name = \Drupal::entityQuery('taxonomy_term')
-      ->condition('id', $term_id)
-      ->execute();
-    return key($term_name);
-  }
-
   /**
    * Gets the user ids which have been submitted by form.
    *
@@ -264,13 +349,21 @@ class AccessStorage implements AccessStorageInterface {
   }
 
   /**
-   * {@inheritdoc}
+   * Saves term permissions by users.
+   *
+   * Opposite to save term permission by roles.
+   *
+   * @param FormState $form_state
+   * @param int       $term_id
+   *
+   * @return array
+   *   Data for database queries.
    */
   public function saveTermPermissions(FormState $form_state, $term_id) {
-    $aExistingUserPermissions       = $this->getExistingUserTermPermissionsByTid($term_id);
+    $aExistingUserPermissions       = $this->getUserTermPermissionsByTid($term_id);
     $aSubmittedUserIdsGrantedAccess = $this->getSubmittedUserIds();
 
-    $aExistingRoleIdsGrantedAccess = $this->getExistingRoleTermPermissionsByTid($term_id);
+    $aExistingRoleIdsGrantedAccess = $this->getRoleTermPermissionsByTid($term_id);
     $aSubmittedRolesGrantedAccess  = $this->getSubmittedRolesGrantedAccess($form_state);
 
     $aRet = $this->getPreparedDataForDatabaseQueries($aExistingUserPermissions,
@@ -340,7 +433,19 @@ class AccessStorage implements AccessStorageInterface {
   }
 
   /**
-   * {@inheritdoc}
+   * Prepares the data which has to be applied to the database.
+   *
+   * @param array $aExistingUserPermissions
+   *   The permissions for existing user.
+   * @param array $aSubmittedUserIdsGrantedAccess
+   *   The user ids which get access.
+   * @param array $aExistingRoleIdsGrantedAccess
+   *   The existing role ids.
+   * @param array $aSubmittedRolesGrantedAccess
+   *   The user roles which get access.
+   *
+   * @return array
+   *   User ID and role data.
    */
   public function getPreparedDataForDatabaseQueries($aExistingUserPermissions,
                                                     $aSubmittedUserIdsGrantedAccess,
@@ -370,7 +475,13 @@ class AccessStorage implements AccessStorageInterface {
   }
 
   /**
-   * {@inheritdoc}
+   * The form value for allowed users as string to be shown to the user.
+   *
+   * @param User[] $aAllowedUsers
+   *   An array with the allowed users.
+   *
+   * @return null|string
+   *   Either null or the user name.
    */
   public function getUserFormValue($aAllowedUsers) {
 
@@ -381,7 +492,7 @@ class AccessStorage implements AccessStorageInterface {
       foreach ($aAllowedUsers as $oUser) {
         $iUid = intval($oUser->id());
         if ($iUid !== 0) {
-          $sUsername = $oUser->getUsername();
+          $sUsername = $oUser->getDisplayName();
         }
         else {
           $sUsername = t('Anonymous User');
@@ -402,16 +513,21 @@ class AccessStorage implements AccessStorageInterface {
    */
   public function getAllNids()
   {
-    $query = $this->oDatabase->select('node', 'n')
+    $query = $this->database->select('node', 'n')
         ->fields('n', ['nid']);
 
     return $query->execute()
         ->fetchCol();
   }
 
+  /**
+   * @param $nid
+   *
+   * @return array
+   */
   public function getTidsByNid($nid)
   {
-    $node = $this->entityManager->getStorage('node')->load($nid);
+    $node = \Drupal::entityTypeManager()->getStorage('node')->load($nid);
     $tids = [];
 
     foreach ($node->getFields() as $field) {
@@ -430,6 +546,9 @@ class AccessStorage implements AccessStorageInterface {
     return $tids;
   }
 
+  /**
+   * @return array
+   */
   public function getAllUids()
   {
     $nodes = \Drupal::entityQuery('user')
@@ -438,9 +557,14 @@ class AccessStorage implements AccessStorageInterface {
     return array_values($nodes);
   }
 
+  /**
+   * @param $nid
+   *
+   * @return array
+   */
   public function getNodeType($nid)
   {
-    $query = $this->oDatabase->select('node', 'n')
+    $query = $this->database->select('node', 'n')
       ->fields('n', ['type'])
       ->condition('n.nid', $nid);
 
@@ -448,9 +572,14 @@ class AccessStorage implements AccessStorageInterface {
       ->fetchAssoc()['type'];
   }
 
+  /**
+   * @param $nid
+   *
+   * @return array
+   */
   public function getLangCode($nid)
   {
-    $query = $this->oDatabase->select('node', 'n')
+    $query = $this->database->select('node', 'n')
       ->fields('n', ['langcode'])
       ->condition('n.nid', $nid);
 
@@ -458,24 +587,80 @@ class AccessStorage implements AccessStorageInterface {
       ->fetchAssoc()['langcode'];
   }
 
-  public function getGidsByRealm($realm)
+  /**
+   * @param AccountInterface $user
+   *
+   * @return array
+   */
+  public function getGids(AccountInterface $user)
   {
-    $query = $this->oDatabase->select('node_access', 'na')
-      ->fields('na', ['gid'])
-      ->condition('na.realm', $realm);
+    $grants = null;
+
+    if (!empty($permittedNids = $this->computePermittedTids($user))) {
+      $query = $this->database->select('node_access', 'na')
+        ->fields('na', ['gid'])
+        ->condition('na.nid', $permittedNids, 'IN')
+        ->condition('na.realm', self::NODE_ACCESS_REALM);
 
-    $gids = $query->execute()->fetchCol();
+      $gids = $query->execute()->fetchCol();
 
-    foreach ($gids as $gid) {
-      $grants[$realm][] = $gid;
+      foreach ($gids as $gid) {
+        $grants[self::NODE_ACCESS_REALM][] = $gid;
+      }
     }
 
     return $grants;
   }
 
+  private function computePermittedTids(AccountInterface $user)
+  {
+    $nidsWithNoTidRestriction = $this->getNidsWithNoTidRestriction();
+    $nidsByTids = $this->term->getNidsByTids($this->getPermittedTids($user->id(), $user->getRoles()));
+
+    if (\Drupal::config('permissions_by_term.settings.single_term_restriction')->get('value')) {
+      $permittedNids = [];
+      foreach ($nidsByTids as $nid) {
+        if($this->accessCheck->canUserAccessByNodeId($nid)) {
+          $permittedNids[] = $nid;
+        }
+      }
+      $nidsByTids = $permittedNids;
+    }
+
+    if (!empty($nidsByTids)) {
+      return array_merge(
+        $this->getNidsWithNoTidRestriction(),
+        $nidsByTids
+      );
+    }
+
+    return $nidsWithNoTidRestriction;
+  }
+
+  private function getNidsWithNoTidRestriction() {
+    $queryNidsNoRestriction = $this->database->select('node', 'n')
+      ->fields('n', ['nid']);
+
+    $queryNidsNoRestriction->leftJoin('taxonomy_index', 'ti', 'n.nid = ti.nid');
+    $queryNidsNoRestriction->leftJoin('permissions_by_term_user', 'ptu', 'ptu.tid = ti.tid');
+    $queryNidsNoRestriction->condition('ptu.tid', NULL, 'IS');
+    $queryNidsNoRestriction->leftJoin('permissions_by_term_role', 'ptr', 'ptr.tid = ti.tid');
+    $queryNidsNoRestriction->condition('ptr.tid', NULL, 'IS');
+
+     return $queryNidsNoRestriction
+      ->execute()
+      ->fetchCol();
+  }
+
+
+  /**
+   * @param $uid
+   *
+   * @return array
+   */
   public function getAllNidsUserCanAccess($uid)
   {
-    $query = $this->oDatabase->select('node_access', 'na')
+    $query = $this->database->select('node_access', 'na')
       ->fields('na', ['nid'])
       ->condition('na.realm', 'permissions_by_term__uid_' . $uid);
 
@@ -483,9 +668,14 @@ class AccessStorage implements AccessStorageInterface {
       ->fetchCol();
   }
 
+  /**
+   * @param $tid
+   *
+   * @return array
+   */
   public function getNidsByTid($tid)
   {
-      $query = $this->oDatabase->select('taxonomy_index', 'ti')
+      $query = $this->database->select('taxonomy_index', 'ti')
         ->fields('ti', ['nid'])
         ->condition('ti.tid', $tid);
 
similarity index 50%
rename from web/modules/contrib/permissions_by_term/src/NodeAccess.php
rename to web/modules/contrib/permissions_by_term/src/Service/NodeAccess.php
index 4015c65952b84475e6c7b81733cb5396fee25eba..42e0798c647f3ff1bdbedfc479c28f0e8119bb36 100644 (file)
@@ -1,17 +1,23 @@
 <?php
 
-namespace Drupal\permissions_by_term;
+namespace Drupal\permissions_by_term\Service;
 
-use Drupal\Core\Entity\EntityManager;
+use Drupal\Core\Entity\EntityTypeManagerInterface;
 use Drupal\permissions_by_term\Factory\NodeAccessRecordFactory;
-use Drupal\user\Entity\User;
 use Drupal\node\Entity\Node;
-use Drupal\Core\Database\Driver\mysql\Connection;
+use Drupal\Core\Database\Connection;
+use Drupal\permissions_by_term\Model\NodeAccessRecordModel;
+use Drupal\user\Entity\User;
 
+/**
+ * Class NodeAccess
+ *
+ * @package Drupal\permissions_by_term
+ */
 class NodeAccess {
 
   /**
-   * @var array $uniqueGid
+   * @var int $uniqueGid
    */
   private $uniqueGid = 0;
 
@@ -31,9 +37,9 @@ class NodeAccess {
   private $node;
 
   /**
-   * @var EntityManager $entityManager
+   * @var EntityTypeManagerInterface $entityTypeManager
    */
-  private $entityManager;
+  private $entityTypeManager;
 
   /**
    * @var AccessCheck $accessCheck
@@ -51,65 +57,72 @@ class NodeAccess {
   private $userInstance;
 
   /**
-   * @var Connection $database
+   * The database connection.
+   *
+   * @var Connection
    */
   private $database;
 
-  public function __construct(AccessStorage $accessStorage, NodeAccessRecordFactory $nodeAccessRecordFactory, EntityManager $entityManager, AccessCheck $accessCheck, Connection $database) {
+  /**
+   * NodeAccess constructor.
+   *
+   * @param AccessStorage           $accessStorage
+   * @param NodeAccessRecordFactory $nodeAccessRecordFactory
+   * @param EntityTypeManagerInterface           $entityTypeManager
+   * @param AccessCheck             $accessCheck
+   * @param Connection              $database
+   */
+  public function __construct(
+    AccessStorage $accessStorage,
+    NodeAccessRecordFactory $nodeAccessRecordFactory,
+    EntityTypeManagerInterface $entityTypeManager,
+    AccessCheck $accessCheck,
+    Connection $database
+  ) {
     $this->accessStorage = $accessStorage;
     $this->nodeAccessRecordFactory = $nodeAccessRecordFactory;
-    $this->entityManager = $entityManager;
-    $this->userEntityStorage = $this->entityManager->getStorage('user');
-    $this->node = $this->entityManager->getStorage('node');
+    $this->entityTypeManager = $entityTypeManager;
+    $this->userEntityStorage = $this->entityTypeManager->getStorage('user');
+    $this->node = $this->entityTypeManager->getStorage('node');
     $this->accessCheck = $accessCheck;
     $this->database = $database;
   }
 
-  public function createRealm($uid) {
-    return 'permissions_by_term__uid_' . $uid;
-  }
-
-  public function createGrants($nid, $uid = FALSE) {
-    if (empty($uid)) {
-      $uids = $this->accessStorage->getAllUids();
-    } else {
-      $uids[] = $uid;
-    }
-
-    $grants = [];
-    foreach ($uids as $uid) {
-      if ($this->accessCheck->canUserAccessByNodeId($nid, $uid)) {
-        $realm = $this->createRealm($uid);
-        $nodeType = $this->accessStorage->getNodeType($nid);
-        $langcode = $this->accessStorage->getLangCode($nid);
-        $grants[] = $this->nodeAccessRecordFactory->create($realm, $this->createUniqueGid(), $nid, $langcode, $this->getGrantUpdate($uid, $nodeType, $nid), $this->getGrantDelete($uid, $nodeType, $nid));
-      }
-    }
-
-    return $grants;
-  }
-
-  public function createUniqueGid() {
-    $uniqueGid = $this->getUniqueGid();
-    $uniqueGid++;
-    $this->setUniqueGid($uniqueGid);
-    return $this->getUniqueGid();
+  /**
+   * @return NodeAccessRecordModel
+   */
+  public function createGrant($nid, $gid) {
+    return $this->nodeAccessRecordFactory->create(
+      AccessStorage::NODE_ACCESS_REALM,
+      $gid,
+      $nid,
+      $this->accessStorage->getLangCode($nid),
+      0,
+      0
+    );
   }
 
   /**
-   * @return array
+   * @return int
    */
   public function getUniqueGid() {
     return $this->uniqueGid;
   }
 
   /**
-   * @param array $uniqueGid
+   * @param int $uniqueGid
    */
   public function setUniqueGid($uniqueGid) {
     $this->uniqueGid = $uniqueGid;
   }
 
+  /**
+   * @param $uid
+   * @param $nodeType
+   * @param $nid
+   *
+   * @return bool
+   */
   public function canUserUpdateNode($uid, $nodeType, $nid) {
     $user = $this->getUserInstance($uid);
 
@@ -135,6 +148,13 @@ class NodeAccess {
     return FALSE;
   }
 
+  /**
+   * @param $uid
+   * @param $nodeType
+   * @param $nid
+   *
+   * @return bool
+   */
   public function canUserDeleteNode($uid, $nodeType, $nid) {
     $user = $this->getUserInstance($uid);
     if ($user->hasPermission('delete any ' . $nodeType . ' content')) {
@@ -172,6 +192,12 @@ class NodeAccess {
     return 0;
   }
 
+  /**
+   * @param $nid
+   * @param $uid
+   *
+   * @return bool
+   */
   public function isNodeOwner($nid, $uid) {
     $node = $this->node->load($nid);
     if (intval($node->getOwnerId()) == intval($uid)) {
@@ -199,6 +225,11 @@ class NodeAccess {
     return 0;
   }
 
+  /**
+   * @param $nid
+   *
+   * @return array
+   */
   public function getGrantsByNid($nid) {
     $grants = [];
     foreach ($this->grants as $grant) {
@@ -244,73 +275,25 @@ class NodeAccess {
     $this->userInstance = $userInstance;
   }
 
-  public function rebuildByTid($tid, $formState) {
-    $nids = $this->accessStorage->getNidsByTid($tid);
-    if (!empty($nids)) {
-      $this->dropRecordsByNids($nids);
-    }
-
-    if (empty($this->accessStorage->getSubmittedUserIds()) && empty($this->accessStorage->getSubmittedRolesGrantedAccess($formState))) {
-      return;
-    }
-
-    foreach ($nids as $nid) {
-      $grants = $this->createGrants($nid);
-      foreach ($grants as $grant) {
-        $this->database->insert('node_access')
-          ->fields(
-            ['nid', 'langcode', 'fallback', 'gid', 'realm', 'grant_view', 'grant_update', 'grant_delete'],
-            [$nid, $grant->langcode, 1, $grant->gid, $grant->realm, $grant->grant_view, $grant->grant_update, $grant->grant_delete]
-          )
-          ->execute();
-      }
-    }
-
-  }
-
-  private function dropRecordsByNids($nids) {
-    $this->database->delete('node_access')
-      ->condition('nid', $nids, 'IN')
-      ->execute();
-  }
+  /**
+   * @param int $nid
+   *
+   * @return bool
+   */
+  public function isAccessRecordExisting($nid) {
+    $query = $this->database->select('node_access', 'na')
+      ->fields('na', ['nid'])
+      ->condition('na.nid', $nid)
+      ->condition('na.realm', AccessStorage::NODE_ACCESS_REALM);
 
-  private function dropRecordsByUid($uid) {
-    $this->database->delete('node_access')
-      ->condition('realm', 'permissions_by_term__uid_' . $uid)
-      ->execute();
-  }
+    $result = $query->execute()
+      ->fetchCol();
 
-  public function rebuildByUid($uid, $noDrop = FALSE) {
-    if ($noDrop === FALSE) {
-      $this->dropRecordsByUid($uid);
+    if (empty($result)) {
+      return FALSE;
     }
 
-    $nids = $this->accessStorage->getAllNids();
-
-    foreach ($nids as $nid) {
-      $grants = $this->createGrants($nid, $uid);
-      foreach ($grants as $grant) {
-        $this->database->insert('node_access')
-          ->fields(
-            ['nid', 'langcode', 'fallback', 'gid', 'realm', 'grant_view', 'grant_update', 'grant_delete'],
-            [$nid, $grant->langcode, 1, $grant->gid, $grant->realm, $grant->grant_view, $grant->grant_update, $grant->grant_delete]
-          )
-          ->execute();
-      }
-    }
-
-  }
-
-  public function rebuildByNid($nid) {
-    $grants = $this->createGrants($nid);
-    foreach ($grants as $grant) {
-      $this->database->insert('node_access')
-        ->fields(
-          ['nid', 'langcode', 'fallback', 'gid', 'realm', 'grant_view', 'grant_update', 'grant_delete'],
-          [$nid, $grant->langcode, 1, $grant->gid, $grant->realm, $grant->grant_view, $grant->grant_update, $grant->grant_delete]
-        )
-        ->execute();
-    }
+    return TRUE;
   }
 
-}
\ No newline at end of file
+}
diff --git a/web/modules/contrib/permissions_by_term/src/Service/NodeEntityBundleInfo.php b/web/modules/contrib/permissions_by_term/src/Service/NodeEntityBundleInfo.php
new file mode 100644 (file)
index 0000000..a0b7940
--- /dev/null
@@ -0,0 +1,129 @@
+<?php
+
+namespace Drupal\permissions_by_term\Service;
+
+use Drupal\Core\Template\TwigEnvironment;
+use Drupal\user\Entity\Role;
+use Drupal\user\Entity\User;
+use Drupal\Core\Database\Connection;
+use PDO;
+
+/**
+ * Class Info
+ *
+ * @package Drupal\permissions_by_term\Service
+ */
+class NodeEntityBundleInfo {
+
+  /**
+   * @var AccessStorage
+   */
+  private $accessStorage;
+
+  /**
+   * @var Term
+   */
+  private $term;
+
+  /**
+   * @var TwigEnvironment
+   */
+  private $twig;
+
+  /**
+   * @var Connection
+   */
+  private $database;
+
+  /**
+   * Info constructor.
+   *
+   * @param AccessStorage   $accessStorage
+   * @param Term            $term
+   * @param TwigEnvironment $twig
+   * @param Connection      $database
+   */
+  public function __construct(
+    AccessStorage $accessStorage,
+    Term $term,
+    TwigEnvironment $twig,
+    Connection $database
+  ) {
+    $this->accessStorage = $accessStorage;
+    $this->term = $term;
+    $this->twig = $twig;
+    $this->database = $database;
+  }
+
+  /**
+   * @param string   $viewFilePath
+   * @param int|null $nid
+   * @return string
+   */
+  public function renderNodeDetails($viewFilePath, $nid = null) {
+    $roles = null;
+    $users = null;
+
+    if (!empty($nid)) {
+      $tids = $this->term->getTidsByNid($nid);
+      if (!empty($tids)) {
+        $uids = $this->accessStorage->getUserTermPermissionsByTids($tids);
+        $rids = $this->accessStorage->getRoleTermPermissionsByTids($tids);
+      }
+    }
+
+    if (!empty($rids)) {
+      $roles = Role::loadMultiple($rids);
+    }
+
+    if (!empty($uids)) {
+      $users = User::loadMultiple($uids);
+    }
+
+    $template = $this->twig->loadTemplate($viewFilePath);
+
+    return $template->render(['roles' => $roles, 'users' => $users]);
+
+  }
+
+  /**
+   * @return array
+   */
+  public function getPermissions()
+  {
+    $returnArray = null;
+
+    $permittedUsers = $this->database->select('permissions_by_term_user', 'pu')
+      ->fields('pu', ['uid', 'tid'])
+      ->execute()
+      ->fetchAll();
+
+    $permittedRoles = $this->database->select('permissions_by_term_role', 'pr')
+      ->fields('pr', ['rid', 'tid'])
+      ->execute()
+      ->fetchAll();
+
+    if (!empty($permittedRoles)) {
+      $returnArray['roleLabels'] = [];
+      foreach ($permittedRoles as $permittedRole) {
+        $role = Role::load($permittedRole->rid);
+        if (!empty($role)) {
+          $returnArray['roleLabels'][$permittedRole->tid][] = $role->label();
+        }
+      }
+    }
+
+    if (!empty($permittedUsers)) {
+      $returnArray['userDisplayNames'] = [];
+      foreach ($permittedUsers as $permittedUser) {
+        $user = User::load($permittedUser->uid);
+        if (!empty($user)) {
+          $returnArray['userDisplayNames'][$permittedUser->tid][] = $user->getDisplayName();
+        }
+      }
+    }
+
+    return $returnArray;
+  }
+
+}
\ No newline at end of file
diff --git a/web/modules/contrib/permissions_by_term/src/Service/Term.php b/web/modules/contrib/permissions_by_term/src/Service/Term.php
new file mode 100644 (file)
index 0000000..fae9a4c
--- /dev/null
@@ -0,0 +1,91 @@
+<?php
+
+namespace Drupal\permissions_by_term\Service;
+
+use Drupal\Core\Database\Connection;
+
+/**
+ * Class Term
+ *
+ * @package Drupal\permissions_by_term\Service
+ */
+class Term {
+
+  /**
+   * The database connection.
+   *
+   * @var Connection
+   */
+  private $database;
+
+  /**
+   * Term constructor.
+   *
+   * @param Connection $database
+   */
+  public function __construct(
+    Connection $database
+  ) {
+    $this->database = $database;
+  }
+
+  /**
+   * @param int $nid
+   *
+   * @return array
+   */
+  public function getTidsByNid($nid) {
+    $query = $this->database->select('taxonomy_index', 'ti')
+      ->fields('ti', ['tid'])
+      ->condition('ti.nid', $nid);
+
+    return $query->execute()
+      ->fetchCol();
+  }
+
+  /**
+   * @param array $tids
+   *
+   * @return array
+   */
+  public function getNidsByTids($tids) {
+    if (!empty($tids)) {
+      $query = $this->database->select('taxonomy_index', 'ti')
+          ->fields('ti', ['nid'])
+          ->condition('ti.tid', $tids, 'IN');
+
+      $nids = $query->execute()
+        ->fetchCol();
+
+      return array_unique($nids);
+    }
+    else {
+      return [];
+    }
+  }
+
+  /**
+   * @param string $sTermName
+   *
+   * @return int
+   */
+  public function getTermIdByName($sTermName) {
+    $aTermId = \Drupal::entityQuery('taxonomy_term')
+      ->condition('name', $sTermName)
+      ->execute();
+    return key($aTermId);
+  }
+
+  /**
+   * @param int $term_id
+   *
+   * @return string
+   */
+  public function getTermNameById($term_id) {
+    $term_name = \Drupal::entityQuery('taxonomy_term')
+      ->condition('id', $term_id)
+      ->execute();
+    return key($term_name);
+  }
+
+}
diff --git a/web/modules/contrib/permissions_by_term/src/View/node-details.html.twig b/web/modules/contrib/permissions_by_term/src/View/node-details.html.twig
new file mode 100644 (file)
index 0000000..3ad7c9d
--- /dev/null
@@ -0,0 +1,19 @@
+{% trans %}This widget shows information about taxonomy term related permissions. It's being updated, as soon you make any related changes in the form.{% endtrans %}<br /><br />
+
+<b>{% trans %}Allowed users:{% endtrans %}</b>
+{% if users is not empty %}
+  {% for user in users  %}
+    {{ user.displayname }}{% if not loop.last %}, {% endif %}
+  {% endfor %}
+{% else %}
+  <i>{% trans %}No user restrictions.{% endtrans %}</i>
+{% endif %}
+<br />
+<b>{% trans %}Allowed roles:{% endtrans %}</b>
+{% if roles is not empty %}
+  {% for role in roles %}
+    {{ role.label }}{% if not loop.last %}, {% endif %}
+  {% endfor %}
+{% else %}
+  <i>{% trans %}No role restrictions.{% endtrans %}</i>
+{% endif %}
\ No newline at end of file
diff --git a/web/modules/contrib/permissions_by_term/tests/bootstrap.php b/web/modules/contrib/permissions_by_term/tests/bootstrap.php
deleted file mode 100644 (file)
index f6acd1f..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-<?php
-
-/**
- * @file
- * Loads the bootstrap for the tests.
- */
-
-require __DIR__ . '/../../../core/tests/bootstrap.php';
diff --git a/web/modules/contrib/permissions_by_term/tests/build.xml.example b/web/modules/contrib/permissions_by_term/tests/build.xml.example
deleted file mode 100644 (file)
index 2ccb859..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-<project name="Permissions by Term" basedir="." default="none">
-
-    <property name="db-name" value="pbt_d8" />
-    <property name="db-username" value="root" />
-    <property name="db-password" value="password" />
-    <property name="module-root-dir" value="~/Websites/pbt-d8/modules/permissions_by_term" />
-
-    <target name="resetDbForTests"
-            description="Resets the database by the tests dump.">
-        <echo msg="Deleting old database." />
-        <exec command="mysql -u${db-username} -p${db-password} -e 'drop database ${db-name}'"
-              passthru="true"
-              checkreturn="false" />
-        <echo msg="Create new empty database." />
-        <exec command="mysql -u${db-username} -p${db-password} -e 'create database ${db-name}'"
-              passthru="true"
-              checkreturn="true" />
-        <echo msg="Import database dump." />
-        <exec command="mysql -u${db-username} -p${db-password} ${db-name} &lt; ${module-root-dir}/tests/codeception/tests/_data/dump.sql"
-              passthru="true"
-              checkreturn="true" />
-    </target>
-
-    <target name="dumpTestsDb"
-            description="Dumps the database for tests.">
-        <exec command="mysqldump -u${db-username} -p${db-password} ${db-name} > ${module-root-dir}/tests/codeception/tests/_data/dump.sql"
-              passthru="true"
-              checkreturn="true" />
-    </target>
-
-</project>
diff --git a/web/modules/contrib/permissions_by_term/tests/phpunit.xml.dist b/web/modules/contrib/permissions_by_term/tests/phpunit.xml.dist
new file mode 100644 (file)
index 0000000..d1d59c7
--- /dev/null
@@ -0,0 +1,34 @@
+<phpunit bootstrap="./../../../core/tests/bootstrap.php" colors="true"
+         beStrictAboutTestsThatDoNotTestAnything="true"
+         beStrictAboutOutputDuringTests="true"
+         beStrictAboutChangesToGlobalState="true"
+         printerClass="\Drupal\Tests\Listeners\HtmlOutputPrinter">
+
+  <env name="PHP_IDE_CONFIG" value="PHPSTORM"/>
+
+  <php>
+    <!-- Set error reporting to E_ALL. -->
+    <ini name="error_reporting" value="32767"/>
+    <!-- Do not limit the amount of memory tests take to run. -->
+    <ini name="memory_limit" value="-1"/>
+    <!-- Example SIMPLETEST_BASE_URL value: http://localhost -->
+    <env name="SIMPLETEST_BASE_URL" value="http://pbt"/>
+    <!-- Example SIMPLETEST_DB value: mysql://username:password@localhost/databasename#table_prefix -->
+    <env name="SIMPLETEST_DB" value="sqlite://localhost//home/jepster/PhpstormProjects/permissions-by-term-behat/sites/default/db.sqlite"/>
+    <!-- Example BROWSERTEST_OUTPUT_DIRECTORY value: /path/to/webroot/sites/simpletest/browser_output -->
+    <env name="BROWSERTEST_OUTPUT_DIRECTORY" value="/tmp"/>
+  </php>
+
+  <testsuites>
+    <testsuite name="Unit Test Suite">
+      <directory>./src/Unit</directory>
+    </testsuite>
+  </testsuites>
+
+  <testsuites>
+    <testsuite name="Kernel Test Suite">
+      <directory>./src/Kernel</directory>
+    </testsuite>
+  </testsuites>
+
+</phpunit>
\ No newline at end of file
diff --git a/web/modules/contrib/permissions_by_term/tests/src/Behat/Context/PermissionsByTermContext.php b/web/modules/contrib/permissions_by_term/tests/src/Behat/Context/PermissionsByTermContext.php
new file mode 100644 (file)
index 0000000..4b2539c
--- /dev/null
@@ -0,0 +1,227 @@
+<?php
+
+namespace Drupal\Tests\permissions_by_term\Behat\Context;
+
+use Behat\Gherkin\Node\TableNode;
+use Drupal\Driver\DrupalDriver;
+use Drupal\DrupalExtension\Context\RawDrupalContext;
+use Drupal\taxonomy\Entity\Vocabulary;
+
+/**
+ * Class PermissionsByTermContext
+ *
+ * @package PermissionsByTerm
+ */
+class PermissionsByTermContext extends RawDrupalContext {
+
+  public function __construct() {
+    $driver = new DrupalDriver(DRUPAL_ROOT, '');
+    $driver->setCoreFromVersion();
+
+    // Bootstrap Drupal.
+    $driver->bootstrap();
+  }
+
+  /**
+   * @AfterSuite
+   */
+  public static function cleanDB() {
+    $module_path = \Drupal::service('module_handler')->getModule('permissions_by_term')->getPath();
+
+    $defaultSitesDirPath = \Drupal::service('stream_wrapper_manager')->getViaScheme(file_default_scheme())->realpath() . '/';
+    unlink($defaultSitesDirPath . 'db.sqlite');
+    copy($module_path . '/tests/src/Behat/fixtures/db.sqlite', $defaultSitesDirPath . 'db.sqlite');
+    chmod($defaultSitesDirPath . '/db.sqlite', 0777);
+  }
+
+  /**
+   * Creates one or more terms on an existing vocabulary.
+   *
+   * Provide term data in the following format:
+   *
+   * | name  | parent | description | weight | taxonomy_field_image | access_user | access_role |
+   * | Snook | Fish   | Marine fish | 10     | snook-123.jpg        | Bob         | editor      |
+   * | ...   | ...    | ...         | ...    | ...                  | ...         | ...         |
+   *
+   * Only the 'name' field is required.
+   *
+   * @Given restricted :vocabulary terms:
+   */
+  public function createTerms($vocabulary, TableNode $termsTable) {
+    foreach ($termsTable->getHash() as $termsHash) {
+      $term = (object) $termsHash;
+      $term->vocabulary_machine_name = $vocabulary;
+      $this->termCreate($term);
+
+      $accessStorage = \Drupal::Service('permissions_by_term.access_storage');
+      if (!empty($termsHash['access_user'])) {
+        $userNames = explode(', ', $termsHash['access_user']);
+        foreach ($userNames as $userName) {
+          $accessStorage->addTermPermissionsByUserIds([$accessStorage->getUserIdByName($userName)['uid']], $term->tid);
+        }
+      }
+
+      if (!empty($termsHash['access_role'])) {
+        $rolesIds = explode(', ', $termsHash['access_role']);
+        $accessStorage->addTermPermissionsByRoleIds($rolesIds, $term->tid);
+      }
+    }
+  }
+
+  /**
+   * @Given /^I create vocabulary with name "([^"]*)" and vid "([^"]*)"$/
+   */
+  public function createVocabulary($name, $vid) {
+    $vocabulary = \Drupal::entityQuery('taxonomy_vocabulary')
+      ->condition('vid', $vid)
+      ->execute();
+
+    if (empty($vocabulary)) {
+      $vocabulary = Vocabulary::create([
+        'name' => $name,
+        'vid' => $vid,
+      ]);
+      $vocabulary->save();
+    }
+  }
+
+  /**
+   * @Then I open open Permissions By Term advanced info
+   */
+  public function iOpenOpenPermissionsByTermAdvancedInfo()
+  {
+    $this->getSession()->evaluateScript("jQuery('#edit-permissions-by-term-info').attr('open', true);");
+  }
+
+  /**
+   * @Given /^I create (\d+) nodes of type "([^"]*)"$/
+   */
+  public function iCreateNodesOfType($number, $type)
+  {
+    for ($i = 0; $i <= $number; $i++) {
+      $node = new \stdClass();
+      $node->type = $type;
+      $node->title = $this->createRandomString();
+      $node->body = $this->createRandomString();
+      $this->nodeCreate($node);
+    }
+  }
+
+  private function createRandomString($length = 10) {
+    return substr(str_shuffle(str_repeat("0123456789abcdefghijklmnopqrstuvwxyz", $length)), 0, $length);
+  }
+
+  /**
+   * @Given Node access records are rebuild.
+   */
+  public function nodeAccessRecordsAreRebuild()
+  {
+    node_access_rebuild();
+  }
+
+  /**
+   * @Then /^wait (\d+) seconds$/
+   */
+  public function waitSeconds($secondsNumber)
+  {
+    $this->getSession()->wait($secondsNumber * 1000);
+  }
+
+  /**
+   * @Then /^I select index (\d+) in dropdown named "([^"]*)"$/
+   */
+  public function selectIndexInDropdown($index, $name)
+  {
+    $this->getSession()->evaluateScript('document.getElementsByName("' . $name . '")[0].selectedIndex = ' . $index . ';');
+  }
+
+  /**
+   * @Then /^I open node edit form by node title "([^"]*)"$/
+   * @param string $title
+   */
+  public function openNodeEditFormByTitle($title)
+  {
+    $query = \Drupal::service('database')->select('node_field_data', 'nfd')
+      ->fields('nfd', ['nid'])
+      ->condition('nfd.title', $title);
+
+    $this->visitPath('/node/' . $query->execute()->fetchField() . '/edit');
+  }
+
+  /**
+   * @Then /^I open node view by node title "([^"]*)"$/
+   * @param string $title
+   */
+  public function openNodeViewByTitle($title)
+  {
+    $query = \Drupal::service('database')->select('node_field_data', 'nfd')
+      ->fields('nfd', ['nid'])
+      ->condition('nfd.title', $title);
+
+    $this->visitPath('/node/' . $query->execute()->fetchField());
+  }
+
+  /**
+   * @Then /^I scroll to element with id "([^"]*)"$/
+   * @param string $id
+   */
+  public function iScrollToElementWithId($id)
+  {
+    $this->getSession()->executeScript(
+      "
+                var element = document.getElementById('" . $id . "');
+                element.scrollIntoView( true );
+            "
+    );
+  }
+
+  /**
+   * @Then /^I check checkbox with id "([^"]*)" by JavaScript$/
+   * @param string $id
+   */
+  public function checkCheckboxWithJS($id)
+  {
+    $this->getSession()->executeScript(
+      "
+                document.getElementById('" . $id . "').checked = true;
+            "
+    );
+  }
+
+  /**
+   * @Then /^I check checkbox with id "([^"]*)"$/
+   * @param string $id
+   */
+  public function checkCheckbox($id)
+  {
+    $page          = $this->getSession()->getPage();
+    $selectElement = $page->find('xpath', '//input[@id = "' . $id . '"]');
+
+    $selectElement->check();
+  }
+
+  /**
+   * @Then /^I uncheck checkbox with id "([^"]*)"$/
+   * @param string $id
+   */
+  public function uncheckCheckbox($id)
+  {
+    $page          = $this->getSession()->getPage();
+    $selectElement = $page->find('xpath', '//input[@id = "' . $id . '"]');
+
+    $selectElement->uncheck();
+  }
+
+  /**
+   * @Then /^I select "([^"]*)" in "([^"]*)"$/
+   * @param string $label
+   * @param string $id
+   */
+  public function selectOption($label, $id)
+  {
+    $page          = $this->getSession()->getPage();
+    $selectElement = $page->find('xpath', '//select[@id = "' . $id . '"]');
+    $selectElement->selectOption($label);
+  }
+
+}
diff --git a/web/modules/contrib/permissions_by_term/tests/src/Behat/Features/access.feature b/web/modules/contrib/permissions_by_term/tests/src/Behat/Features/access.feature
new file mode 100644 (file)
index 0000000..7949e14
--- /dev/null
@@ -0,0 +1,155 @@
+@api @drupal
+Feature: Access
+  Several automated tests for the Permissions by Term Drupal 8 module.
+
+  Background:
+    Given restricted "tags" terms:
+      | name          | access_user   | access_role                             |
+      | Tag one       |               | administrator                           |
+      | Tag two       |               | authenticated                           |
+      | Tag three     |               |                                         |
+      | Tag admin     | admin         |                                         |
+      | Tag anonymous |               | anonymous, administrator, authenticated |
+    Given article content:
+      | title                          | author     | status | created           | field_tags    | alias                 |
+      | Only admin can access          | Admin      | 1      | 2014-10-17 8:00am | Tag one       | only-admin-can-access |
+      | Everybody can access           | Admin      | 1      | 2014-10-17 8:00am |               | no-term               |
+      | Term accessible                | Admin      | 1      | 2014-10-17 8:00am | Tag three     | term-no-restriction   |
+      | Unpublished node               | Admin      | 0      | 2014-10-17 8:00am |               | unpublished           |
+      | Only admin user can edit       | Admin      | 0      | 2014-10-17 8:00am | Tag admin     | unpublished           |
+      | Authenticated user can access  | Admin      | 0      | 2014-10-17 8:00am | Tag two       | unpublished           |
+      | Anonymous user can access      | Admin      | 1      | 2014-10-17 8:00am | Tag anonymous | anonymous             |
+    Given users:
+      | name          | mail            | pass     |
+      | Joe           | joe@example.com | password |
+    Given Node access records are rebuild.
+
+  Scenario: Anonymous users cannot see restricted node
+    Given I open node view by node title "Authenticated user can access"
+    Then I should see text matching "Access denied"
+
+  Scenario: Anonymous users can see allowed node with term with multiple user role relation in view
+    Given I am on "/"
+    And the cache has been cleared
+    Then I should see text matching "Anonymous user can access"
+
+#@TODO: Test needs to be fixed. Implement a method, which waits for HTML tags.
+#  Scenario: Anonymous users can see node, which is not connected to any permission.
+#    Given I am logged in as a user with the "administrator" role
+#    Then I am on "/admin/config/search/pages"
+#    And I press "edit-wipe"
+#    And I run cron
+#    And I am on "/user/logout"
+#    Then I am on "node/search"
+#    And I fill in "edit-keys" with "Everybody can"
+#    And I press "edit-submit--2"
+#    Then I should not see text matching "Your search yielded no results."
+
+  Scenario: Anonymous users do not see unpublished nodes.
+    Given I am on "node/search"
+    And I fill in "edit-keys" with "Unpublished node"
+    And I press "edit-submit--2"
+    Then I should see text matching "Your search yielded no results."
+
+#  Scenario: Anonymous users see nodes with term and no restriction
+#    Given I run cron
+#    Given I am on "/"
+#    Given I am on "node/search"
+#    And I fill in "edit-keys" with "Term accessible"
+#    And I press "edit-submit--2"
+#    Then I should not see text matching "Your search yielded no results."
+
+#@TODO: Test needs to be fixed. Implement a method, which waits for HTML tags.
+#  Scenario: Users cannot access restricted terms in taxonomy term field widgets.
+#    Given I am on "/"
+#    Then I am logged in as a user with the "administrator" role
+#    And I am on "/admin/structure/types/manage/article/form-display"
+#    And I select index 3 in dropdown named "fields[field_tags][type]"
+#    And I scroll to element with id "edit-submit"
+#    And I press "edit-submit"
+#    Then I am on "/node/add/article"
+#    Then I should not see "Tag admin" in the "#edit-field-tags" element
+#    Then I should see "Tag three" in the "#edit-field-tags" element
+
+  Scenario: Users cannot access node edit forms without having access to related terms.
+    Given I am on "/"
+    Then I am logged in as a user with the "administrator" role
+    And I am on "/admin/people/roles/add"
+    And I fill in "edit-label" with "Editor"
+    And I fill in "edit-id" with "editor"
+    Then I press "edit-submit"
+    Then I am on "/admin/people/permissions"
+    And I check checkbox with id "edit-editor-access-content-overview" by JavaScript
+    And I check checkbox with id "edit-editor-administer-nodes" by JavaScript
+    And I check checkbox with id "edit-editor-administer-content-types" by JavaScript
+    And I check checkbox with id "edit-editor-create-article-content" by JavaScript
+    And I check checkbox with id "edit-editor-delete-any-article-content" by JavaScript
+    And I check checkbox with id "edit-editor-delete-own-article-content" by JavaScript
+    And I check checkbox with id "edit-editor-edit-any-article-content" by JavaScript
+    And I check checkbox with id "edit-editor-edit-own-article-content" by JavaScript
+    And I scroll to element with id "edit-submit"
+    And I press "edit-submit"
+    Then I am on "/admin/people/create"
+    And I fill in "edit-name" with "editor"
+    And I fill in "edit-pass-pass1" with "password"
+    And I fill in "edit-pass-pass2" with "password"
+    And I check checkbox with id "edit-roles-editor" by JavaScript
+    And I scroll to element with id "edit-submit"
+    And I press "edit-submit"
+    Then I am on "/user/logout"
+    Then I am on "/user/login"
+    And I fill in "edit-name" with "editor"
+    And I fill in "edit-pass" with "password"
+    And I scroll to element with id "edit-submit"
+    And I press "edit-submit"
+    Then I am on "/admin/content"
+    And I should not see text matching "Only admin user can edit"
+    And I should see text matching "Term accessible"
+    And I should see text matching "Everybody can access"
+    Then I open node edit form by node title "Only admin user can edit"
+    And I should see text matching "Access denied"
+
+#@TODO: Test needs to be fixed. Implement a method, which waits for HTML tags.
+#  Scenario: Users are accessing an node directly
+#    Given I am logged in as a user with the "administrator" role
+#    Then I am on "only-admin-can-access"
+#    Then I should see text matching "Only admin can access"
+#    Given I am logged in as "Joe"
+#    Then I am on "only-admin-can-access"
+#    Then I should see text matching "Access denied"
+
+#@TODO: Test needs to be fixed. Implement a method, which waits for HTML tags.
+#  Scenario: Users search for an node
+#    Given I create 1000 nodes of type "article"
+#    Given I am logged in as a user with the "administrator" role
+#    And I am on "admin/config/system/cron"
+#    And I press "edit-run"
+#    Then I am on "node/search"
+#    And I fill in "edit-keys" with "Only admin can access"
+#    And I press "edit-submit"
+#    Then I should see text matching "Only admin can access"
+#    Given I am logged in as "Joe"
+#    Then I am on "node/search"
+#    And I fill in "edit-keys" with "Only admin can access"
+#    And I press "edit-submit"
+#    Then I should see text matching "Your search yielded no results."
+
+  Scenario: Users access an node by menu
+    Given I am logged in as a user with the "administrator" role
+    And I am on "admin/structure/menu/manage/main"
+    And I click "Add link"
+    And I fill in "edit-title-0-value" with "Only admin can access"
+    And I fill in "edit-link-0-uri" with "Only admin can access (1)"
+    And I press "edit-submit"
+    Then I click "Home"
+    Then I should see "Only admin can access" in the ".region-primary-menu" element
+    Given I am logged in as "Joe"
+    Then I should not see "Only admin can access" in the ".region-primary-menu" element
+
+  Scenario: Users access an nodes by view
+    Given I am logged in as a user with the "administrator" role
+    Then I am on "/"
+    And I should see text matching "Only admin can access"
+    Given I am logged in as "Joe"
+    Then I am on "/"
+    And I should not see text matching "Only admin can access"
diff --git a/web/modules/contrib/permissions_by_term/tests/src/Behat/Features/entityMetaInfo.feature b/web/modules/contrib/permissions_by_term/tests/src/Behat/Features/entityMetaInfo.feature
new file mode 100644 (file)
index 0000000..4a86ba2
--- /dev/null
@@ -0,0 +1,102 @@
+@api @drupal
+Feature: Entity Meta Info
+  Several automated tests for the Permissions by Term Drupal 8 module.
+
+  Background:
+    Given users:
+      | name          | mail               | pass     |
+      | Joe           | joe@example.com    | password |
+      | George        | george@example.com | password |
+      | Andy          | andy@example.com   | password |
+      | Tom           | tom@example.com    | password |
+    Given restricted "tags" terms:
+      | name          | access_user   | access_role                             |
+      | Tag one       |               | administrator                           |
+      | Tag two       |               | authenticated                           |
+      | Tag three     |               |                                         |
+      | Tag admin     | admin         |                                         |
+      | Tag anonymous |               | anonymous, administrator, authenticated |
+    Given I create vocabulary with name "tags2" and vid "tags2"
+    Given I create vocabulary with name "tags3" and vid "tags3"
+    Given restricted "tags2" terms:
+      | name              | access_user | access_role                           |
+      | Tag administrator | Joe, George | administrator                         |
+      | Tag authenticated | Andy        | authenticated                         |
+    Given restricted "tags3" terms:
+      | name          | access_user   | access_role                             |
+      | Tag tom       | Tom           | administrator                           |
+    Given article content:
+      | title                          | author     | status | created           | field_tags    | alias                 |
+      | Only admin can access          | Admin      | 1      | 2014-10-17 8:00am | Tag one       | only-admin-can-access |
+      | Everybody can access           | Admin      | 1      | 2014-10-17 8:00am |               | no-term               |
+      | Term accessible                | Admin      | 1      | 2014-10-17 8:00am | Tag three     | term-no-restriction   |
+      | Unpublished node               | Admin      | 0      | 2014-10-17 8:00am |               | unpublished           |
+      | Only admin user can edit       | Admin      | 0      | 2014-10-17 8:00am | Tag admin     | unpublished           |
+      | Authenticated user can access  | Admin      | 0      | 2014-10-17 8:00am | Tag two       | unpublished           |
+      | Anonymous user can access      | Admin      | 1      | 2014-10-17 8:00am | Tag anonymous | anonymous             |
+    Given Node access records are rebuild.
+
+#@TODO: Test needs to be fixed. Implement a method, which waits for HTML tags. Field ids has changed. Do not rely on fixed id's with numeric suffix.
+#  Scenario: Users see permissions tab in node edit form
+#    Given I am on "/"
+#    Given I am logged in as a user with the "administrator" role
+#    Then I am on "/admin/structure/types/manage/article/fields/add-field"
+#    And I select index 15 in dropdown named "new_storage_type"
+#    And I press "edit-submit"
+#    Then I fill in "edit-label" with "Tags2"
+#    Then I fill in "edit-field-name" with "tags2"
+#    And I press "edit-submit"
+#    And I select index 1 in dropdown named "cardinality"
+#    And I press "edit-submit"
+#    Then I scroll to element with id "edit-submit"
+#    And I check checkbox with id "edit-settings-handler-settings-target-bundles-tags2" by JavaScript
+#    And I press "edit-submit"
+#    Then I am on "/admin/structure/types/manage/article/fields/add-field"
+#    And I select index 15 in dropdown named "new_storage_type"
+#    And I press "edit-submit"
+#    Then I fill in "edit-label" with "Tags3"
+#    Then I fill in "edit-field-name" with "tags3"
+#    And I press "edit-submit"
+#    And I select index 1 in dropdown named "cardinality"
+#    And I press "edit-submit"
+#    And I check checkbox with id "edit-settings-handler-settings-target-bundles-tags3" by JavaScript
+#    And I scroll to element with id "edit-submit"
+#    And I press "edit-submit"
+#    Then I am on "/admin/structure/types/manage/article/form-display"
+#    And I scroll to element with id "edit-submit"
+#    And I select index 0 in dropdown named "fields[field_tags2][type]"
+#    And I select index 3 in dropdown named "fields[field_tags3][type]"
+#    And I press "edit-submit"
+#    Then I am on "/admin/content"
+#    And I scroll to element with id "edit-submit"
+#    And I click "Only admin can access"
+#    And I click "Edit"
+#    Then I should see "Permissions by Term" in the "#edit-advanced" element
+#    And I open open Permissions By Term advanced info
+#    And I should see "Administrator" in the "#edit-permissions-by-term-info" element
+#    And I should see "Allowed Users: No user restrictions." in the "#edit-permissions-by-term-info" element
+#    And I scroll to element with id "edit-field-tags2"
+#    And I check checkbox with id "edit-field-tags2"
+#    And I uncheck checkbox with id "edit-field-tags2"
+#    And I scroll to element with id "edit-permissions-by-term-info"
+#    Then I should see "Allowed roles: Administrator" in the "#edit-permissions-by-term-info" element
+#    Then I fill in "edit-field-tags-target-id" with "Tag one (5), Tag two (6)"
+#    And I should see "Allowed users: Joe, George" in the "#edit-permissions-by-term-info" element
+#    Then I select "Tag tom" in "edit-field-tags3"
+#    And I should see "Allowed users: Joe, George, Tom" in the "#edit-permissions-by-term-info" element
+
+#@TODO: Test needs to be fixed. Implement a method, which waits for HTML tags.
+#  Scenario: Users see permissions tab in node add form
+#    Given I am on "/"
+#    Given I am logged in as a user with the "administrator" role
+#    Then I am on "/node/add/article"
+#    And I open open Permissions By Term advanced info
+#    And I should see "Allowed users: No user restrictions." in the "#edit-permissions-by-term-info" element
+#    And I should see "Allowed roles: No role restrictions." in the "#edit-permissions-by-term-info" element
+#    Then I select "Tag tom" in "edit-field-tags3"
+#    And I should see "Allowed users: Tom" in the "#edit-permissions-by-term-info" element
+#    Then I check checkbox with id "edit-field-tags2-14"
+#    And I should see "Allowed users: Tom, Joe, George" in the "#edit-permissions-by-term-info" element
+#    And I should see "Allowed roles: Administrator" in the "#edit-permissions-by-term-info" element
+#    Then I uncheck checkbox with id "edit-field-tags2-14"
+#    And I should see "Allowed users: Tom" in the "#edit-permissions-by-term-info" element
diff --git a/web/modules/contrib/permissions_by_term/tests/src/Behat/behat.yml.dist b/web/modules/contrib/permissions_by_term/tests/src/Behat/behat.yml.dist
new file mode 100644 (file)
index 0000000..f8eeaf6
--- /dev/null
@@ -0,0 +1,27 @@
+default:
+  suites:
+    default:
+      contexts:
+        - Drupal\DrupalExtension\Context\DrupalContext
+        - Drupal\DrupalExtension\Context\MinkContext
+        - Drupal\DrupalExtension\Context\MessageContext
+        - Drupal\DrupalExtension\Context\DrushContext
+        - Drupal\Tests\permissions_by_term\Behat\Context\PermissionsByTermContext
+      paths:
+        features: '/home/jepster/PhpstormProjects/permissions-by-term-behat/modules/permissions_by_term/tests/src/Behat/Features'
+  extensions:
+    Behat\MinkExtension:
+      javascript_session: 'selenium2'
+      browser_name: 'chrome'
+      show_cmd: "open %s"
+      selenium2:
+        wd_host: 'http://localhost:4444/wd/hub'
+        browser: 'chrome'
+      base_url: http://pbt
+    Drupal\DrupalExtension:
+      blackbox: ~
+      api_driver: 'drupal'
+      drush:
+        alias: 'local'
+      drupal:
+        drupal_root: '/home/jepster/PhpstormProjects/permissions-by-term-behat'
\ No newline at end of file
diff --git a/web/modules/contrib/permissions_by_term/tests/src/Behat/composer.json b/web/modules/contrib/permissions_by_term/tests/src/Behat/composer.json
new file mode 100644 (file)
index 0000000..9902e4c
--- /dev/null
@@ -0,0 +1,27 @@
+{
+    "name": "jepster/permissions-by-term-behat",
+    "description": "A PHP package for the Permissions by Term Drupal 8 module which provides a Behat context and examples.",
+    "type": "library",
+    "license": "BSD-2-Clause",
+    "authors": [
+        {
+            "name": "Peter Majmesku",
+            "email": "p.majmesku@gmail.com"
+        }
+    ],
+    "require": {
+        "drupal/drupal-extension": "~3.0",
+        "guzzlehttp/guzzle" : "^6.0@dev",
+        "drupal/drupal-driver": "~1.0",
+        "behat/behat": "^3.1",
+        "behat/mink": "^1.7",
+        "behat/mink-extension": "^2.2",
+        "behat/mink-selenium2-driver": "^1.3",
+        "behat/mink-goutte-driver": "^1.2"
+    },
+    "autoload": {
+        "psr-4": {
+            "PermissionsByTerm\\": "src/"
+        }
+    }
+}
diff --git a/web/modules/contrib/permissions_by_term/tests/src/Behat/fixtures/db.sqlite b/web/modules/contrib/permissions_by_term/tests/src/Behat/fixtures/db.sqlite
new file mode 100755 (executable)
index 0000000..656cd08
Binary files /dev/null and b/web/modules/contrib/permissions_by_term/tests/src/Behat/fixtures/db.sqlite differ
diff --git a/web/modules/contrib/permissions_by_term/tests/src/Kernel/AccessCheckTest.php b/web/modules/contrib/permissions_by_term/tests/src/Kernel/AccessCheckTest.php
new file mode 100644 (file)
index 0000000..21d2b15
--- /dev/null
@@ -0,0 +1,128 @@
+<?php
+
+namespace Drupal\Tests\permissions_by_term\Kernel;
+
+use Drupal\permissions_by_term\Service\AccessStorage;
+
+/**
+ * Class AccessCheckTest
+ *
+ * @package Drupal\Tests\permissions_by_term\Kernel
+ * @group permissions_by_term
+ */
+class AccessCheckTest extends PBTKernelTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+  }
+
+  /**
+   * @return void
+   */
+  public function testDisabledSingleTermRestriction() {
+    $database = $this->container->get('database');
+    $database->truncate('node_access')->execute();
+    $this->createRelationOneGrantedTerm();
+    $this->createRelationAllGrantedTerms();
+
+    \Drupal::configFactory()->getEditable('permissions_by_term.settings.single_term_restriction')->set('value', FALSE)->save();
+    $this->assertTrue($this->accessCheck->canUserAccessByNodeId($this->getNidOneGrantedTerm()));
+
+    node_access_rebuild();
+
+    $gids = $this->accessStorage->getGids(\Drupal::service('current_user'));
+
+    $nodeAccess = $database->select('node_access', 'na')
+      ->fields('na', ['nid'])
+      ->condition('na.gid', $gids['permissions_by_term'], 'IN')
+      ->condition('na.realm', AccessStorage::NODE_ACCESS_REALM);
+    $permittedNids = $nodeAccess
+      ->execute()
+      ->fetchCol();
+
+    $this->assertCount(2, $permittedNids);
+  }
+
+  /**
+   * @return void
+   */
+  public function testNoGrantedTermRestriction() {
+    $database = $this->container->get('database');
+    $database->truncate('node_access')->execute();
+    $this->createRelationNoGrantedTerm();
+
+    \Drupal::configFactory()->getEditable('permissions_by_term.settings.single_term_restriction')->set('value', FALSE)->save();
+    $this->assertFalse($this->accessCheck->canUserAccessByNodeId($this->getNidNoGrantedTerm()));
+
+    node_access_rebuild();
+
+    $gids = $this->accessStorage->getGids(\Drupal::service('current_user'));
+
+    $nodeAccess = $database->select('node_access', 'na')
+      ->fields('na', ['nid'])
+      ->condition('na.gid', $gids['permissions_by_term'], 'IN')
+      ->condition('na.realm', AccessStorage::NODE_ACCESS_REALM);
+    $permittedNids = $nodeAccess
+      ->execute()
+      ->fetchCol();
+
+    $this->assertCount(0, $permittedNids);
+  }
+
+  /**
+   * @return void
+   */
+  public function testNoTermRestriction() {
+    $database = $this->container->get('database');
+    $database->truncate('node_access')->execute();
+    $this->createRelationNoTerms();
+
+    \Drupal::configFactory()->getEditable('permissions_by_term.settings.single_term_restriction')->set('value', FALSE)->save();
+    $this->assertTrue($this->accessCheck->canUserAccessByNodeId($this->getNidNoTerms()));
+
+    node_access_rebuild();
+
+    $gids = $this->accessStorage->getGids(\Drupal::service('current_user'));
+
+    $nodeAccess = $database->select('node_access', 'na')
+      ->fields('na', ['nid'])
+      ->condition('na.gid', $gids['permissions_by_term'], 'IN')
+      ->condition('na.realm', AccessStorage::NODE_ACCESS_REALM);
+    $permittedNids = $nodeAccess
+      ->execute()
+      ->fetchCol();
+
+    $this->assertCount(1, $permittedNids);
+  }
+
+  /**
+   * @return void
+   */
+  public function testEnabledSingleTermRestriction() {
+    $database = $this->container->get('database');
+    $database->truncate('node_access')->execute();
+    $this->createRelationOneGrantedTerm();
+    $this->createRelationAllGrantedTerms();
+
+    \Drupal::configFactory()->getEditable('permissions_by_term.settings.single_term_restriction')->set('value', TRUE)->save();
+    $this->assertFalse($this->accessCheck->canUserAccessByNodeId($this->getNidOneGrantedTerm()));
+
+    node_access_rebuild();
+
+    $gids = $this->accessStorage->getGids(\Drupal::service('current_user'));
+
+    $nodeAccess = $database->select('node_access', 'na')
+      ->fields('na', ['nid'])
+      ->condition('na.gid', $gids['permissions_by_term'], 'IN')
+      ->condition('na.realm', AccessStorage::NODE_ACCESS_REALM);
+    $permittedNids = $nodeAccess
+      ->execute()
+      ->fetchCol();
+
+    $this->assertCount(1, $permittedNids);
+  }
+
+}
\ No newline at end of file
diff --git a/web/modules/contrib/permissions_by_term/tests/src/Kernel/NodeEntityBundleInfoTest.php b/web/modules/contrib/permissions_by_term/tests/src/Kernel/NodeEntityBundleInfoTest.php
new file mode 100644 (file)
index 0000000..1a51d89
--- /dev/null
@@ -0,0 +1,100 @@
+<?php
+
+namespace Drupal\Tests\permissions_by_term\Kernel;
+
+use Drupal\taxonomy\Entity\Term;
+use Drupal\user\Entity\Role;
+use Drupal\user\Entity\User;
+use Drupal\permissions_by_term\Service\NodeEntityBundleInfo;
+
+/**
+ * Class AccessStorageTest
+ *
+ * @package Drupal\Tests\permissions_by_term\Kernel
+ * @group permissions_by_term
+ */
+class NodeEntityBundleInfoTest extends PBTKernelTestBase {
+
+  /**
+   * @var NodeEntityBundleInfo
+   */
+  private $nodeEntityBundleInfo;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+    $this->nodeEntityBundleInfo = $this->container->get('permissions_by_term.node_entity_bundle_info');
+  }
+
+  /**
+   * @return void
+   */
+  public function testGetPermissionsByTids() {
+    $testUser1 = User::create([
+      'uid' => 5,
+      'name' => 'testUser1',
+      'mail' => 'foobar@example.com',
+    ]);
+    $testUser1->save();
+
+    $role = Role::create([
+      'id' => 'first-role',
+      'label' => 'First Role'
+    ]);
+    $role->save();
+
+    $testUser2 = User::create([
+      'uid' => 6,
+      'name' => 'testUser2',
+      'mail' => 'foobar@example.com',
+    ]);
+    $testUser2->save();
+
+    $role = Role::create([
+      'id' => 'second-role',
+      'label' => 'Second Role'
+    ]);
+    $role->save();
+
+    $testUser3 = User::create([
+      'uid' => 7,
+      'name' => 'testUser3',
+      'mail' => 'foobar@example.com',
+    ]);
+    $testUser3->save();
+
+    $role = Role::create([
+      'id' => 'third-role',
+      'label' => 'Third Role'
+    ]);
+    $role->save();
+
+    $firstTerm = Term::create([
+      'name' => 'term2',
+      'vid' => 'test',
+    ]);
+    $firstTerm->save();
+
+    $secondTerm = Term::create([
+      'name' => 'term3',
+      'vid' => 'test',
+    ]);
+    $secondTerm->save();
+
+    $this->accessStorage->addTermPermissionsByUserIds([5, 6, 7], $firstTerm->id());
+    $this->accessStorage->addTermPermissionsByRoleIds(['first-role', 'second-role', 'third-role'], $firstTerm->id());
+    $this->accessStorage->addTermPermissionsByRoleIds(['second-role', 'third-role'], $secondTerm->id());
+
+    $permissions = $this->nodeEntityBundleInfo->getPermissions();
+
+    $expectedPermissions = [
+      'roleLabels' => [1 => ['First Role', 'Second Role', 'Third Role'], 2 => ['Second Role', 'Third Role']],
+      'userDisplayNames' => [1 => ['testUser1', 'testUser2', 'testUser3']]
+    ];
+
+    $this->assertArraySubset($expectedPermissions, $permissions);
+  }
+
+}
\ No newline at end of file
diff --git a/web/modules/contrib/permissions_by_term/tests/src/Kernel/PBTKernelTestBase.php b/web/modules/contrib/permissions_by_term/tests/src/Kernel/PBTKernelTestBase.php
new file mode 100644 (file)
index 0000000..dee4134
--- /dev/null
@@ -0,0 +1,318 @@
+<?php
+
+namespace Drupal\Tests\permissions_by_term\Kernel;
+
+use Drupal\Core\Field\FieldStorageDefinitionInterface;
+use Drupal\field\Entity\FieldConfig;
+use Drupal\field\Entity\FieldStorageConfig;
+use Drupal\KernelTests\KernelTestBase;
+use Drupal\node\Entity\Node;
+use Drupal\node\Entity\NodeType;
+use Drupal\taxonomy\Entity\Vocabulary;
+use Drupal\user\Entity\User;
+use Drupal\permissions_by_term\Service\AccessCheck;
+use Drupal\taxonomy\Entity\Term;
+use Drupal\permissions_by_term\Service\AccessStorage;
+
+/**
+ * Class PBTKernelTestBase
+ *
+ * @package Drupal\Tests\permissions_by_term\Kernel
+ */
+abstract class PBTKernelTestBase extends KernelTestBase {
+
+  /**
+   * @var int
+   */
+  protected $nidOneGrantedTerm;
+
+  /**
+   * @var int
+   */
+  protected $nidNoGrantedTerm;
+
+  /**
+   * @var int
+   */
+  protected $nidAllGrantedTerms;
+
+  /**
+   * @var int
+   */
+  protected $nidNoTerms;
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['taxonomy', 'node', 'user', 'text', 'field', 'system', 'permissions_by_term'];
+
+  /**
+   * @var AccessStorage
+   */
+  protected $accessStorage;
+
+  /**
+   * @var AccessCheck
+   */
+  protected $accessCheck;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    $this->installEntitySchema('user');
+    $this->installSchema('system', ['key_value_expire', 'sequences']);
+    $this->installEntitySchema('node');
+    $this->installEntitySchema('taxonomy_term');
+    $this->installConfig(['permissions_by_term']);
+    $this->installSchema('node', 'node_access');
+    $this->installSchema('permissions_by_term', 'permissions_by_term_user');
+    $this->installSchema('permissions_by_term', 'permissions_by_term_role');
+    $this->accessStorage = $this->container->get('permissions_by_term.access_storage');
+    $this->accessCheck = $this->container->get('permissions_by_term.access_check');
+    \Drupal::configFactory()->getEditable('taxonomy.settings')->set('maintain_index_table', TRUE)->save();
+    $this->createTestVocabulary();
+    $this->createPageNodeType();
+    $this->createCurrentUser();
+  }
+
+  protected function createTestVocabulary() {
+    Vocabulary::create([
+      'name' => 'test',
+      'vid' => 'test',
+    ])->save();
+  }
+
+  protected function createPageNodeType() {
+    NodeType::create([
+      'type' => 'page',
+    ])->save();
+    FieldStorageConfig::create([
+      'entity_type' => 'node',
+      'field_name' => 'field_tags',
+      'type' => 'entity_reference',
+      'settings' => [
+        'target_type' => 'taxonomy_term',
+      ],
+      'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED,
+    ])->save();
+
+    FieldConfig::create([
+      'field_name' => 'field_tags',
+      'entity_type' => 'node',
+      'bundle' => 'page',
+    ])->save();
+  }
+
+  protected function createCurrentUser() {
+    $testUser = User::create([
+      'uid' => 2,
+      'name' => 'foobar',
+      'mail' => 'foobar@example.com',
+    ]);
+
+    $testUser->save();
+    \Drupal::service('current_user')->setAccount($testUser);
+  }
+
+  /**
+   * @return int
+   */
+  protected function createRelationOneGrantedTerm() {
+    $term = Term::create([
+      'name' => 'term1',
+      'vid' => 'test',
+    ]);
+    $term->save();
+    $tids[] = $term->id();
+
+    $this->accessStorage->addTermPermissionsByUserIds([\Drupal::service('current_user')->id()], $term->id());
+
+    $term = Term::create([
+      'name' => 'term2',
+      'vid' => 'test',
+    ]);
+    $term->save();
+    $tids[] = $term->id();
+
+    $this->accessStorage->addTermPermissionsByUserIds([99], $term->id());
+
+    $node = Node::create([
+      'type' => 'page',
+      'title' => 'test_title',
+      'field_tags' => [
+        [
+          'target_id' => $tids[0]
+        ],
+        [
+          'target_id' => $tids[1]
+        ],
+      ]
+    ]);
+    $node->save();
+    $this->setNidOneGrantedTerm($node->id());
+  }
+
+  /**
+   * @return int
+   */
+  protected function createRelationNoGrantedTerm() {
+    $term = Term::create([
+      'name' => 'term2',
+      'vid' => 'test',
+    ]);
+    $term->save();
+    $tids[] = $term->id();
+
+    $this->accessStorage->addTermPermissionsByUserIds([1], $term->id());
+
+    $node = Node::create([
+      'type' => 'page',
+      'title' => 'test_title',
+      'field_tags' => [
+        [
+          'target_id' => $tids[0]
+        ],
+      ]
+    ]);
+    $node->save();
+    $this->setNidNoGrantedTerm($node->id());
+  }
+
+  protected function createRelationAllGrantedTerms() {
+    $term = Term::create([
+      'name' => 'term1',
+      'vid' => 'test',
+    ]);
+    $term->save();
+    $tids[] = $term->id();
+
+    $this->accessStorage->addTermPermissionsByUserIds([\Drupal::service('current_user')->id()], $term->id());
+
+    $term = Term::create([
+      'name' => 'term2',
+      'vid' => 'test',
+    ]);
+    $term->save();
+    $tids[] = $term->id();
+
+    $this->accessStorage->addTermPermissionsByUserIds([\Drupal::service('current_user')->id()], $term->id());
+
+    $node = Node::create([
+      'type' => 'page',
+      'title' => 'test_title',
+      'field_tags' => [
+        [
+          'target_id' => $tids[0]
+        ],
+        [
+          'target_id' => $tids[1]
+        ],
+      ]
+    ]);
+    $node->save();
+    $this->setNidAllGrantedTerms($node->id());
+  }
+
+  protected function createRelationNoTerms() {
+    $term = Term::create([
+      'name' => 'term1',
+      'vid' => 'test',
+    ]);
+    $term->save();
+    $tids[] = $term->id();
+
+    $this->accessStorage->addTermPermissionsByUserIds([\Drupal::service('current_user')->id()], $term->id());
+
+    $term = Term::create([
+      'name' => 'term2',
+      'vid' => 'test',
+    ]);
+    $term->save();
+    $tids[] = $term->id();
+
+    $this->accessStorage->addTermPermissionsByUserIds([\Drupal::service('current_user')->id()], $term->id());
+
+    $node = Node::create([
+      'type' => 'page',
+      'title' => 'test_title',
+      'field_tags' => [
+        [
+          'target_id' => $tids[0]
+        ],
+        [
+          'target_id' => $tids[1]
+        ],
+      ]
+    ]);
+    $node->save();
+    $this->setNidNoTerms($node->id());
+  }
+
+
+  protected function getTaxonomyIndex() {
+    return \Drupal::database()->select('taxonomy_index', 'ti')
+      ->fields('ti', ['tid'])
+      ->execute()
+      ->fetchCol();
+  }
+
+  /**
+   * @return int
+   */
+  protected function getNidOneGrantedTerm() {
+    return $this->nidOneGrantedTerm;
+  }
+
+  /**
+   * @param int $nidOneGrantedTerm
+   */
+  protected function setNidOneGrantedTerm($nidOneGrantedTerm) {
+    $this->nidOneGrantedTerm = $nidOneGrantedTerm;
+  }
+
+  /**
+   * @return int
+   */
+  protected function getNidAllGrantedTerms() {
+    return $this->nidAllGrantedTerms;
+  }
+
+  /**
+   * @param int $nidAllGrantedTerms
+   */
+  protected function setNidAllGrantedTerms($nidAllGrantedTerms) {
+    $this->nidAllGrantedTerms = $nidAllGrantedTerms;
+  }
+
+  /**
+   * @return int
+   */
+  protected function getNidNoGrantedTerm() {
+    return $this->nidNoGrantedTerm;
+  }
+
+  /**
+   * @param int $nidNoGrantedTerm
+   */
+  protected function setNidNoGrantedTerm($nidNoGrantedTerm) {
+    $this->nidNoGrantedTerm = $nidNoGrantedTerm;
+  }
+
+  /**
+   * @return int
+   */
+  protected function getNidNoTerms() {
+    return $this->nidNoTerms;
+  }
+
+  /**
+   * @param int $nidNoTerms
+   */
+  protected function setNidNoTerms($nidNoTerms) {
+    $this->nidNoTerms = $nidNoTerms;
+  }
+
+}
\ No newline at end of file
diff --git a/web/modules/contrib/permissions_by_term/tests/src/Unit/Base.php b/web/modules/contrib/permissions_by_term/tests/src/Unit/Base.php
deleted file mode 100644 (file)
index 65fa6c4..0000000
+++ /dev/null
@@ -1,138 +0,0 @@
-<?php
-
-namespace Drupal\Tests\permissions_by_term\Unit;
-
-use \Symfony\Component\DependencyInjection\ContainerInterface;
-
-trait Base
-{
-
-  /**
-   * @param string $namespace
-   * @param array $methodsReturnMap
-   *
-   * @return mixed
-   */
-  public function createMock($namespace, array $methodsReturnMap = [])
-  {
-    $methodNames = array_keys($methodsReturnMap);
-    $mock = $this
-      ->getMockBuilder($namespace);
-
-    $mock->disableOriginalConstructor();
-
-    $mockedClass = $mock
-      ->setMethods($methodNames)
-      ->getMock();
-
-    foreach ($methodsReturnMap as $methodName => $methodReturn) {
-      $mockedClass
-        ->method($methodName)
-        ->will(
-          $this->returnValue($methodReturn)
-        );
-    }
-
-    return $mockedClass;
-  }
-
-  /**
-   * @param string $class
-   * @param string $propertyName
-   * @param mixed $value
-   */
-  public function modifyPropertyByReflection($class, $propertyName, $value)
-  {
-    $reflection = $this->makePropertyAccessible($class, $propertyName);
-    $reflection->setValue($class, $value);
-  }
-
-  /**
-   * @param string $class
-   * @param string $propertyName
-   * @return \ReflectionProperty
-   */
-  public function makePropertyAccessible($class, $propertyName)
-  {
-    $reflection = new \ReflectionProperty(get_class($class), $propertyName);
-    $reflection->setAccessible(true);
-
-    return $reflection;
-  }
-
-  /**
-   * @param null|array $methodReturnValues
-   * @param null|array $methodReturnValuesMap
-   *
-   * @return mixed
-   */
-  public function getContainerMock($methodReturnValues = null, $methodReturnValuesMap = null)
-  {
-    if (!is_array($methodReturnValues)) {
-      $methodReturnValues = [];
-    }
-
-    if (!is_array($methodReturnValuesMap)) {
-      $methodReturnValuesMap = [];
-    }
-
-    $container = $this->getMockBuilder(Container::class)->disableOriginalConstructor()->setMethods(array_merge(array_keys($methodReturnValues), array_keys($methodReturnValuesMap)))->getMock();
-
-    foreach ($methodReturnValues as $methodName => $returnValue) {
-      $container->method($methodName)->will($this->returnValue($returnValue));
-    }
-
-    foreach ($methodReturnValuesMap as $methodName => $returnValueMap) {
-      $container->method($methodName)->will($this->returnValueMap($returnValueMap));
-    }
-
-    return $container;
-  }
-
-  /**
-   * @param string $string
-   * @return bool
-   */
-  public function containsHtml($string)
-  {
-    if ($string != strip_tags($string)) {
-      return true;
-    }
-
-    return false;
-  }
-
-  protected function collectServices($defaultServiceContainers, $testSpecificServices)
-  {
-    $serviceContainers = $defaultServiceContainers;
-
-    if (!empty($testSpecificServices)) {
-      $testSpecificServiceKeys = $this->extractTestSpecificContainerKeys($testSpecificServices);
-      $uniqueDefaultServiceContainers = $this->collectUndefinedServicesByDefaultStack($defaultServiceContainers, $testSpecificServiceKeys);
-      $serviceContainers = array_merge($uniqueDefaultServiceContainers, $testSpecificServices);
-    }
-
-    return $serviceContainers;
-  }
-
-  protected function extractTestSpecificContainerKeys($testSpecificServices)
-  {
-    foreach ($testSpecificServices as $testSpecificService) {
-      $testSpecificServiceKeys[] = $testSpecificService['0'];
-    }
-
-    return $testSpecificServiceKeys;
-  }
-
-  protected function collectUndefinedServicesByDefaultStack($defaultServiceContainers, $testSpecificServiceKeys)
-  {
-    foreach ($defaultServiceContainers as $serviceContainer) {
-      if (!in_array($serviceContainer['0'], $testSpecificServiceKeys)) {
-        $uniqueServiceContainers[] = $serviceContainer;
-      }
-    }
-
-    return $uniqueServiceContainers;
-  }
-
-}
\ No newline at end of file
diff --git a/web/modules/contrib/permissions_by_term/tests/src/Unit/NodeAccessTest.php b/web/modules/contrib/permissions_by_term/tests/src/Unit/NodeAccessTest.php
deleted file mode 100644 (file)
index 934ed7d..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-<?php
-
-namespace Drupal\Tests\permissions_by_term\Unit;
-
-use Drupal\permissions_by_term\NodeAccess;
-use \Drupal\permissions_by_term\Factory\NodeAccessRecordFactory;
-
-/**
- * Class NodeAccess
- *
- * @group permissions_by_term
- */
-class NodeAccessTest extends \PHPUnit_Framework_TestCase {
-
-  use Base;
-
-  public function testCreateRealms() {
-    $accessStorage = $this->createMock('Drupal\permissions_by_term\AccessStorage',
-      [
-        'fetchUidsByRid' => [999, 87, 44],
-        'getNidsByTid' => [64, 826, 91, 21],
-        'getAllNids' => [12, 55, 88, 3, 5],
-        'getAllUids' => [6, 84, 2, 99, 2],
-        'getNodeType' => 'article',
-        'getLangCode' => 'en'
-      ]
-    );
-    $nodeAccessStorageFactory = new NodeAccessRecordFactory();
-
-    $entityManager = $this->createMock('Drupal\Core\Entity\EntityManager',
-      [
-        'getStorage' => $this->createMock('Storage', [
-          'load' => $this->createMock('Entity', [
-            'hasPermission' => true
-        ]),
-      ])]
-    );
-
-    $accessCheck = $this->createMock('Drupal\permissions_by_term\AccessCheck',
-      [
-        'canUserAccessByNodeId' => TRUE
-      ]
-    );
-
-    $database = $this->createMock('Drupal\Core\Database\Driver\mysql\Connection');
-
-    $nodeAccess = new NodeAccess($accessStorage, $nodeAccessStorageFactory, $entityManager, $accessCheck, $database);
-
-    $this->assertTrue($this->propertiesHaveValues($nodeAccess->createGrants(1)));
-    $this->assertTrue($this->realmContainsNumber($nodeAccess->createGrants(1)));
-  }
-
-  private function realmContainsNumber($objectStack) {
-    foreach ($objectStack as $object) {
-      foreach ($object as $propertyName => $propertyValue) {
-        if ($propertyName == 'realm') {
-          if ($this->stringContainsOneNumbers($propertyValue) === FALSE) {
-            throw new \Exception('The realm does not contain two numbers. It must contain the UID and TID.');
-          }
-        }
-      }
-    }
-
-    return TRUE;
-  }
-
-  private function stringContainsOneNumbers($string) {
-    $numOfNumbers = 0;
-    $elements = explode('_', $string);
-    foreach ($elements as $element) {
-      if (is_numeric($element)) {
-        $numOfNumbers++;
-      }
-    }
-
-    if ($numOfNumbers == 1) {
-      return TRUE;
-    }
-
-    return FALSE;
-  }
-
-  private function propertiesHaveValues($objectStack) {
-    foreach ($objectStack as $object) {
-      foreach ($object as $propertyName => $propertyValue) {
-        if ($propertyValue == '' && $propertyValue != 0) {
-          throw new \Exception('Property with name ' . $propertyName . ' does not contain any value.');
-          return FALSE;
-        }
-      }
-    }
-
-    return TRUE;
-  }
-
-}
diff --git a/web/modules/contrib/permissions_by_term/tests/src/Unit/README.md b/web/modules/contrib/permissions_by_term/tests/src/Unit/README.md
new file mode 100644 (file)
index 0000000..63e624a
--- /dev/null
@@ -0,0 +1 @@
+There are currently no unit tests needed. Feel free to write them, if you need those.
\ No newline at end of file