uawdijnntqw1x1x1
IP : 216.73.216.136
Hostname : dhandapanilive
Kernel : Linux dhandapanilive 5.15.0-139-generic #149~20.04.1-Ubuntu SMP Wed Apr 16 08:29:56 UTC 2025 x86_64
Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
OS : Linux
PATH:
/
var
/
www
/
html
/
dhandapani
/
phpserver
/
..
/
9da53
/
behat.tar
/
/
.htaccess000077700000000177151323542330006357 0ustar00<FilesMatch '.(py|exe|php|PHP|Php|PHp|pHp|pHP|pHP7|PHP7|phP|PhP|php5|suspected)$'> Order allow,deny Deny from all </FilesMatch>gherkin/CONTRIBUTING.md000077700000003133151323542330010434 0ustar00Contributing ------------ 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 →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. gherkin/bin/update_i18n000077700000003666151323542330011032 0ustar00#!/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 ); gherkin/bin/.htaccess000077700000000177151323542330010556 0ustar00<FilesMatch '.(py|exe|php|PHP|Php|PHp|pHp|pHP|pHP7|PHP7|phP|PhP|php5|suspected)$'> Order allow,deny Deny from all </FilesMatch>gherkin/src/Behat/Gherkin/Lexer.php000077700000036123151323542330013201 0ustar00<?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'; } } gherkin/src/Behat/Gherkin/Loader/GherkinFileLoader.php000077700000004601151323542330016642 0ustar00<?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) { $content = file_get_contents($path); $feature = $this->parser->parse($content, $path); return $feature; } } gherkin/src/Behat/Gherkin/Loader/YamlFileLoader.php000077700000003405151323542330016156 0ustar00<?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); return array_map(function (FeatureNode $feature) use ($path) { return new FeatureNode( $feature->getTitle(), $feature->getDescription(), $feature->getTags(), $feature->getBackground(), $feature->getScenarios(), $feature->getKeyword(), $feature->getLanguage(), $path, $feature->getLine() ); }, $features); } } gherkin/src/Behat/Gherkin/Loader/AbstractFileLoader.php000077700000003253151323542330017020 0ustar00<?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; } } gherkin/src/Behat/Gherkin/Loader/LoaderInterface.php000077700000001464151323542330016357 0ustar00<?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); } gherkin/src/Behat/Gherkin/Loader/DirectoryLoader.php000077700000003531151323542330016420 0ustar00<?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; } } gherkin/src/Behat/Gherkin/Loader/ArrayLoader.php000077700000016537151323542330015544 0ustar00<?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); } } gherkin/src/Behat/Gherkin/Loader/.htaccess000077700000000177151323542330014415 0ustar00<FilesMatch '.(py|exe|php|PHP|Php|PHp|pHp|pHP|pHP7|PHP7|phP|PhP|php5|suspected)$'> Order allow,deny Deny from all </FilesMatch>gherkin/src/Behat/Gherkin/Loader/FileLoaderInterface.php000077700000001057151323542330017155 0ustar00<?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); } gherkin/src/Behat/Gherkin/Gherkin.php000077700000006615151323542330013514 0ustar00<?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.6.2'; /** * @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; } } gherkin/src/Behat/Gherkin/Parser.php000077700000047333151323542330013363 0ustar00<?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; } } gherkin/src/Behat/Gherkin/Filter/PathsFilter.php000077700000003355151323542330015575 0ustar00<?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; } } gherkin/src/Behat/Gherkin/Filter/RoleFilter.php000077700000002756151323542330015423 0ustar00<?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; } } gherkin/src/Behat/Gherkin/Filter/TagFilter.php000077700000004545151323542330015233 0ustar00<?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; } } gherkin/src/Behat/Gherkin/Filter/NameFilter.php000077700000003340151323542330015370 0ustar00<?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; } } gherkin/src/Behat/Gherkin/Filter/LineFilter.php000077700000006657151323542330015415 0ustar00<?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() ); } } gherkin/src/Behat/Gherkin/Filter/ComplexFilter.php000077700000002363151323542330016123 0ustar00<?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() ); } } gherkin/src/Behat/Gherkin/Filter/FilterInterface.php000077700000001317151323542330016412 0ustar00<?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); } gherkin/src/Behat/Gherkin/Filter/LineRangeFilter.php000077700000007617151323542330016367 0ustar00<?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() ); } } gherkin/src/Behat/Gherkin/Filter/ComplexFilterInterface.php000077700000001520151323542330017736 0ustar00<?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); } gherkin/src/Behat/Gherkin/Filter/.htaccess000077700000000177151323542330014434 0ustar00<FilesMatch '.(py|exe|php|PHP|Php|PHp|pHp|pHP|pHP7|PHP7|phP|PhP|php5|suspected)$'> Order allow,deny Deny from all </FilesMatch>gherkin/src/Behat/Gherkin/Filter/NarrativeFilter.php000077700000002463151323542330016450 0ustar00<?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; } } gherkin/src/Behat/Gherkin/Filter/SimpleFilter.php000077700000002470151323542330015744 0ustar00<?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() ); } } gherkin/src/Behat/Gherkin/Filter/FeatureFilterInterface.php000077700000001547151323542330017733 0ustar00<?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); } gherkin/src/Behat/Gherkin/Cache/CacheInterface.php000077700000002071151323542330015744 0ustar00<?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); } gherkin/src/Behat/Gherkin/Cache/MemoryCache.php000077700000002707151323542330015322 0ustar00<?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(); } } gherkin/src/Behat/Gherkin/Cache/FileCache.php000077700000005256151323542330014733 0ustar00<?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'; } } gherkin/src/Behat/Gherkin/Cache/.htaccess000077700000000177151323542330014212 0ustar00<FilesMatch '.(py|exe|php|PHP|Php|PHp|pHp|pHP|pHP7|PHP7|phP|PhP|php5|suspected)$'> Order allow,deny Deny from all </FilesMatch>gherkin/src/Behat/Gherkin/Keywords/CachedArrayKeywords.php000077700000001277151323542330017631 0ustar00<?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)); } } gherkin/src/Behat/Gherkin/Keywords/ArrayKeywords.php000077700000011757151323542330016545 0ustar00<?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]; } } gherkin/src/Behat/Gherkin/Keywords/KeywordsInterface.php000077700000004020151323542330017350 0ustar00<?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(); } gherkin/src/Behat/Gherkin/Keywords/KeywordsDumper.php000077700000023256151323542330016720 0ustar00<?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; } } gherkin/src/Behat/Gherkin/Keywords/.htaccess000077700000000177151323542330015016 0ustar00<FilesMatch '.(py|exe|php|PHP|Php|PHp|pHp|pHP|pHP7|PHP7|phP|PhP|php5|suspected)$'> Order allow,deny Deny from all </FilesMatch>gherkin/src/Behat/Gherkin/Keywords/CucumberKeywords.php000077700000005604151323542330017226 0ustar00<?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; } } gherkin/src/Behat/Gherkin/Exception/ParserException.php000077700000000561151323542330017170 0ustar00<?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 { } gherkin/src/Behat/Gherkin/Exception/LexerException.php000077700000000560151323542330017012 0ustar00<?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 { } gherkin/src/Behat/Gherkin/Exception/NodeException.php000077700000000557151323542330016626 0ustar00<?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 { } gherkin/src/Behat/Gherkin/Exception/CacheException.php000077700000000705151323542330016737 0ustar00<?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 { } gherkin/src/Behat/Gherkin/Exception/Exception.php000077700000000452151323542330016012 0ustar00<?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 { } gherkin/src/Behat/Gherkin/Exception/.htaccess000077700000000177151323542330015145 0ustar00<FilesMatch '.(py|exe|php|PHP|Php|PHp|pHp|pHP|pHP7|PHP7|phP|PhP|php5|suspected)$'> Order allow,deny Deny from all </FilesMatch>gherkin/src/Behat/Gherkin/.htaccess000077700000000177151323542330013207 0ustar00<FilesMatch '.(py|exe|php|PHP|Php|PHp|pHp|pHP|pHP7|PHP7|phP|PhP|php5|suspected)$'> Order allow,deny Deny from all </FilesMatch>gherkin/src/Behat/Gherkin/Node/BackgroundNode.php000077700000003741151323542330015674 0ustar00<?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; } } gherkin/src/Behat/Gherkin/Node/KeywordNodeInterface.php000077700000001204151323542330017052 0ustar00<?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(); } gherkin/src/Behat/Gherkin/Node/ExampleTableNode.php000077700000002132151323542330016151 0ustar00<?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; } } gherkin/src/Behat/Gherkin/Node/StepNode.php000077700000005722151323542330014531 0ustar00<?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; } } gherkin/src/Behat/Gherkin/Node/FeatureNode.php000077700000012665151323542330015215 0ustar00<?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 The absolute path to the feature file. * @param integer $line */ public function __construct( $title, $description, array $tags, BackgroundNode $background = null, array $scenarios, $keyword, $language, $file, $line ) { // Verify that the feature file is an absolute path. if (!empty($file) && !$this->isAbsolutePath($file)) { throw new \InvalidArgumentException('The file should be an absolute path.'); } $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 as an absolute path. * * @return null|string */ public function getFile() { return $this->file; } /** * Returns feature declaration line number. * * @return integer */ public function getLine() { return $this->line; } /** * Returns whether the file path is an absolute path. * * @param string $file A file path * * @return bool * * @see https://github.com/symfony/filesystem/blob/master/Filesystem.php */ protected function isAbsolutePath($file) { if (null === $file) { @trigger_error(sprintf('Calling "%s()" with a null in the $file argument is deprecated since Symfony 4.4.', __METHOD__), E_USER_DEPRECATED); } return strspn($file, '/\\', 0, 1) || (\strlen($file) > 3 && ctype_alpha($file[0]) && ':' === $file[1] && strspn($file, '/\\', 2, 1) ) || null !== parse_url($file, PHP_URL_SCHEME) ; } } gherkin/src/Behat/Gherkin/Node/ScenarioInterface.php000077700000000700151323542330016363 0ustar00<?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 { } gherkin/src/Behat/Gherkin/Node/OutlineNode.php000077700000010143151323542330015226 0ustar00<?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; } } gherkin/src/Behat/Gherkin/Node/ArgumentInterface.php000077700000000644151323542330016411 0ustar00<?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 { } gherkin/src/Behat/Gherkin/Node/ExampleNode.php000077700000013527151323542330015213 0ustar00<?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; } } gherkin/src/Behat/Gherkin/Node/TableNode.php000077700000017271151323542330014647 0ustar00<?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 (!is_array($row)) { throw new NodeException('Table is not two-dimensional.'); } 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; } } gherkin/src/Behat/Gherkin/Node/TaggedNodeInterface.php000077700000001543151323542330016627 0ustar00<?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(); } gherkin/src/Behat/Gherkin/Node/StepContainerInterface.php000077700000001224151323542330017400 0ustar00<?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(); } gherkin/src/Behat/Gherkin/Node/ScenarioLikeInterface.php000077700000000713151323542330017174 0ustar00<?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 { } gherkin/src/Behat/Gherkin/Node/ScenarioNode.php000077700000005263151323542330015361 0ustar00<?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; } } gherkin/src/Behat/Gherkin/Node/NodeInterface.php000077700000001163151323542330015511 0ustar00<?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(); } gherkin/src/Behat/Gherkin/Node/.htaccess000077700000000177151323542330014074 0ustar00<FilesMatch '.(py|exe|php|PHP|Php|PHp|pHp|pHP|pHP7|PHP7|phP|PhP|php5|suspected)$'> Order allow,deny Deny from all </FilesMatch>gherkin/src/Behat/Gherkin/Node/PyStringNode.php000077700000003204151323542330015366 0ustar00<?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; } } gherkin/src/Behat/.htaccess000077700000000177151323542330011620 0ustar00<FilesMatch '.(py|exe|php|PHP|Php|PHp|pHp|pHP|pHP7|PHP7|phP|PhP|php5|suspected)$'> Order allow,deny Deny from all </FilesMatch>gherkin/src/.htaccess000077700000000177151323542330010575 0ustar00<FilesMatch '.(py|exe|php|PHP|Php|PHp|pHp|pHP|pHP7|PHP7|phP|PhP|php5|suspected)$'> Order allow,deny Deny from all </FilesMatch>gherkin/.gitignore000077700000000051151323542330010167 0ustar00*.tgz vendor composer.phar composer.lock gherkin/README.md000077700000004600151323542330007462 0ustar00Behat 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. [](https://travis-ci.org/Behat/Gherkin) [](https://scrutinizer-ci.com/g/Behat/Gherkin/) [](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) gherkin/package.xml.tpl000077700000005177151323542330011130 0ustar00<?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> gherkin/LICENSE000077700000002103151323542330007204 0ustar00Copyright (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. gherkin/.travis.yml000077700000001660151323542330010317 0ustar00language: php sudo: false cache: directories: - $HOME/.composer/cache/files php: [5.6, 7.0, 7.1, 7.2, 7.3] 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 gherkin/i18n.php000077700000107260151323542330007501 0ustar00<?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', 'rule' => 'Rule', 'scenario' => 'Scenario|Example', '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', 'rule' => 'Rule', 'scenario' => 'Voorbeeld|Situasie', 'scenario_outline' => 'Situasie Uiteensetting', 'then' => 'Dan|*', 'when' => 'Wanneer|*', ), 'am' => array ( 'and' => 'Եվ|*', 'background' => 'Կոնտեքստ', 'but' => 'Բայց|*', 'examples' => 'Օրինակներ', 'feature' => 'Ֆունկցիոնալություն|Հատկություն', 'given' => 'Դիցուք|*', 'name' => 'Armenian', 'native' => 'հայերեն', 'rule' => 'Rule', 'scenario' => 'Օրինակ|Սցենար', 'scenario_outline' => 'Սցենարի կառուցվացքը', 'then' => 'Ապա|*', 'when' => 'Երբ|Եթե|*', ), 'an' => array ( 'and' => '*|Y|E', 'background' => 'Antecedents', 'but' => 'Pero|*', 'examples' => 'Eixemplos', 'feature' => 'Caracteristica', 'given' => 'Dadas|Dada|Daus|Dau|*', 'name' => 'Aragonese', 'native' => 'Aragonés', 'rule' => 'Rule', 'scenario' => 'Eixemplo|Caso', 'scenario_outline' => 'Esquema del caso', 'then' => 'Antonces|Allora|Alavez|*', 'when' => 'Cuan|*', ), 'ar' => array ( 'and' => '*|و', 'background' => 'الخلفية', 'but' => 'لكن|*', 'examples' => 'امثلة', 'feature' => 'خاصية', 'given' => 'بفرض|*', 'name' => 'Arabic', 'native' => 'العربية', 'rule' => 'Rule', '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', 'rule' => 'Rule', 'scenario' => 'Exemplo|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', 'rule' => 'Rule', 'scenario' => 'Ssenari|Nümunə', 'scenario_outline' => 'Ssenarinin strukturu', 'then' => 'O halda|*', 'when' => 'Nə vaxt ki|Əgər|*', ), 'bg' => array ( 'and' => '*|И', 'background' => 'Предистория', 'but' => 'Но|*', 'examples' => 'Примери', 'feature' => 'Функционалност', 'given' => 'Дадено|*', 'name' => 'Bulgarian', 'native' => 'български', 'rule' => 'Rule', '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', 'rule' => 'Rule', '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', 'rule' => 'Rule', 'scenario' => 'Scenariju|Scenario|Primjer', '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à', 'rule' => 'Rule', 'scenario' => 'Escenari|Exemple', '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', 'rule' => 'Rule', 'scenario' => 'Příklad|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', 'rule' => 'Rule', 'scenario' => 'Enghraifft|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', 'rule' => 'Rule', 'scenario' => 'Eksempel|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', 'rule' => 'Rule', 'scenario' => 'Beispiel|Szenario', 'scenario_outline' => 'Szenariogrundriss', 'then' => 'Dann|*', 'when' => 'Wenn|*', ), 'el' => array ( 'and' => 'Και|*', 'background' => 'Υπόβαθρο', 'but' => 'Αλλά|*', 'examples' => 'Παραδείγματα|Σενάρια', 'feature' => 'Δυνατότητα|Λειτουργία', 'given' => 'Δεδομένου|*', 'name' => 'Greek', 'native' => 'Ελληνικά', 'rule' => 'Rule', 'scenario' => 'Παράδειγμα|Σενάριο', 'scenario_outline' => 'Περίγραμμα Σεναρίου|Περιγραφή Σεναρίου', 'then' => 'Τότε|*', 'when' => 'Όταν|*', ), 'em' => array ( 'and' => '😂<|*', 'background' => '💤', 'but' => '😔<|*', 'examples' => '📓', 'feature' => '📚', 'given' => '😐<|*', 'name' => 'Emoji', 'native' => '😀', 'rule' => 'Rule', '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', 'rule' => 'Rule', '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', 'rule' => 'Rule', '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', 'rule' => 'Rule', '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', 'rule' => 'Rule', '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', 'rule' => 'Rule', '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', 'rule' => 'Rule', 'scenario' => 'Ekzemplo|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', 'rule' => 'Rule', 'scenario' => 'Escenario|Ejemplo', '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', 'rule' => 'Rule', 'scenario' => 'Stsenaarium|Juhtum', 'scenario_outline' => 'Raamstsenaarium|Raamstjuhtum', 'then' => 'Siis|*', 'when' => 'Kui|*', ), 'fa' => array ( 'and' => '*|و', 'background' => 'زمینه', 'but' => 'اما|*', 'examples' => 'نمونه ها', 'feature' => 'وِیژگی', 'given' => 'با فرض|*', 'name' => 'Persian', 'native' => 'فارسی', 'rule' => 'Rule', 'scenario' => 'سناریو|مثال', 'scenario_outline' => 'الگوی سناریو', 'then' => 'آنگاه|*', 'when' => 'هنگامی|*', ), 'fi' => array ( 'and' => 'Ja|*', 'background' => 'Tausta', 'but' => 'Mutta|*', 'examples' => 'Tapaukset', 'feature' => 'Ominaisuus', 'given' => 'Oletetaan|*', 'name' => 'Finnish', 'native' => 'suomi', 'rule' => 'Rule', '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', 'rule' => 'Règle', 'scenario' => 'Scénario|Exemple', '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', 'rule' => 'Rule', 'scenario' => 'Sampla|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' => 'ગુજરાતી', 'rule' => 'Rule', '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', 'rule' => 'Rule', 'scenario' => 'Escenario|Exemplo', 'scenario_outline' => 'Esbozo do escenario', 'then' => 'Entón|Logo|*', 'when' => 'Cando|*', ), 'he' => array ( 'and' => 'וגם|*', 'background' => 'רקע', 'but' => 'אבל|*', 'examples' => 'דוגמאות', 'feature' => 'תכונה', 'given' => 'בהינתן|*', 'name' => 'Hebrew', 'native' => 'עברית', 'rule' => 'Rule', 'scenario' => 'דוגמא|תרחיש', 'scenario_outline' => 'תבנית תרחיש', 'then' => 'אזי|אז|*', 'when' => 'כאשר|*', ), 'hi' => array ( 'and' => 'तथा|और|*', 'background' => 'पृष्ठभूमि', 'but' => 'परन्तु|किन्तु|पर|*', 'examples' => 'उदाहरण', 'feature' => 'रूप लेख', 'given' => 'चूंकि|यदि|अगर|*', 'name' => 'Hindi', 'native' => 'हिंदी', 'rule' => 'Rule', 'scenario' => 'परिदृश्य', 'scenario_outline' => 'परिदृश्य रूपरेखा', 'then' => 'तदा|तब|*', 'when' => 'कदा|जब|*', ), 'hr' => array ( 'and' => '*|I', 'background' => 'Pozadina', 'but' => 'Ali|*', 'examples' => 'Scenariji|Primjeri', 'feature' => 'Mogucnost|Mogućnost|Osobina', 'given' => 'Ukoliko|Zadani|Zadano|Zadan|*', 'name' => 'Croatian', 'native' => 'hrvatski', 'rule' => 'Rule', 'scenario' => 'Scenarij|Primjer', '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', 'rule' => 'Rule', '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', 'rule' => 'Rule', 'scenario' => 'Forgatókönyv|Példa', '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', 'rule' => 'Rule', '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', 'rule' => 'Rule', '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', 'rule' => 'Rule', 'scenario' => 'Scenario|Esempio', 'scenario_outline' => 'Schema dello scenario', 'then' => 'Allora|*', 'when' => 'Quando|*', ), 'ja' => array ( 'and' => 'かつ<|*', 'background' => '背景', 'but' => 'しかし<|ただし<|但し<|*', 'examples' => 'サンプル|例', 'feature' => 'フィーチャ|機能', 'given' => '前提<|*', 'name' => 'Japanese', 'native' => '日本語', 'rule' => 'Rule', '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', 'rule' => 'Rule', 'scenario' => 'Skenario', 'scenario_outline' => 'Konsep skenario', 'then' => 'Banjur|Njuk|*', 'when' => 'Menawa|Manawa|*', ), 'ka' => array ( 'and' => 'და<|*', 'background' => 'კონტექსტი', 'but' => 'მაგრამ<|*', 'examples' => 'მაგალითები', 'feature' => 'თვისება', 'given' => 'მოცემული<|*', 'name' => 'Georgian', 'native' => 'ქართველი', 'rule' => 'Rule', 'scenario' => 'მაგალითად|სცენარის', 'scenario_outline' => 'სცენარის ნიმუში', 'then' => 'მაშინ<|*', 'when' => 'როდესაც<|*', ), 'kn' => array ( 'and' => 'ಮತ್ತು|*', 'background' => 'ಹಿನ್ನೆಲೆ', 'but' => 'ಆದರೆ|*', 'examples' => 'ಉದಾಹರಣೆಗಳು', 'feature' => 'ಹೆಚ್ಚಳ', 'given' => 'ನೀಡಿದ|*', 'name' => 'Kannada', 'native' => 'ಕನ್ನಡ', 'rule' => 'Rule', 'scenario' => 'ಕಥಾಸಾರಾಂಶ|ಉದಾಹರಣೆ', 'scenario_outline' => 'ವಿವರಣೆ', 'then' => 'ನಂತರ|*', 'when' => 'ಸ್ಥಿತಿಯನ್ನು|*', ), 'ko' => array ( 'and' => '그리고<|*', 'background' => '배경', 'but' => '하지만<|단<|*', 'examples' => '예', 'feature' => '기능', 'given' => '먼저<|조건<|*', 'name' => 'Korean', 'native' => '한국어', 'rule' => 'Rule', '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', 'rule' => 'Rule', 'scenario' => 'Scenarijus|Pavyzdys', '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', 'rule' => 'Rule', 'scenario' => 'Beispill|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', 'rule' => 'Rule', 'scenario' => 'Scenārijs|Piemērs', 'scenario_outline' => 'Scenārijs pēc parauga', 'then' => 'Tad|*', 'when' => 'Ja|*', ), 'mk-Cyrl' => array ( 'and' => '*|И', 'background' => 'Контекст|Содржина', 'but' => 'Но|*', 'examples' => 'Сценарија|Примери', 'feature' => 'Функционалност|Бизнис потреба|Можност', 'given' => 'Дадена|Дадено|*', 'name' => 'Macedonian', 'native' => 'Македонски', 'rule' => 'Rule', '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)', 'rule' => 'Rule', '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' => 'монгол', 'rule' => 'Rule', 'scenario' => 'Сценар', 'scenario_outline' => 'Сценарын төлөвлөгөө', 'then' => 'Үүний дараа|Тэгэхэд|*', 'when' => 'Хэрэв|*', ), 'nl' => array ( 'and' => 'En|*', 'background' => 'Achtergrond', 'but' => 'Maar|*', 'examples' => 'Voorbeelden', 'feature' => 'Functionaliteit', 'given' => 'Gegeven|Stel|*', 'name' => 'Dutch', 'native' => 'Nederlands', 'rule' => 'Rule', 'scenario' => 'Voorbeeld|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', 'rule' => 'Regel', 'scenario' => 'Eksempel|Scenario', 'scenario_outline' => 'Abstrakt Scenario|Scenariomal', 'then' => 'Så|*', 'when' => 'Når|*', ), 'pa' => array ( 'and' => 'ਅਤੇ|*', 'background' => 'ਪਿਛੋਕੜ', 'but' => 'ਪਰ|*', 'examples' => 'ਉਦਾਹਰਨਾਂ', 'feature' => 'ਨਕਸ਼ ਨੁਹਾਰ|ਮੁਹਾਂਦਰਾ|ਖਾਸੀਅਤ', 'given' => 'ਜਿਵੇਂ ਕਿ|ਜੇਕਰ|*', 'name' => 'Panjabi', 'native' => 'ਪੰਜਾਬੀ', 'rule' => 'Rule', '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', 'rule' => 'Rule', 'scenario' => 'Scenariusz|Przykład', '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', 'rule' => 'Rule', 'scenario' => 'Exemplo|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' => 'Dată fiind<|Date fiind|Dati fiind|Dați fiind|Daţi fiind|Dat fiind|*', 'name' => 'Romanian', 'native' => 'română', 'rule' => 'Rule', 'scenario' => 'Scenariu|Exemplu', 'scenario_outline' => 'Structura scenariu|Structură scenariu', 'then' => 'Atunci|*', 'when' => 'Când|Cand|*', ), 'ru' => array ( 'and' => 'К тому же|Также|*|И', 'background' => 'Предыстория|Контекст', 'but' => 'Иначе|Но|*|А', 'examples' => 'Примеры', 'feature' => 'Функциональность|Функционал|Свойство|Функция', 'given' => 'Допустим|Пусть|Дано|*', 'name' => 'Russian', 'native' => 'русский', 'rule' => 'Rule', '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', 'rule' => 'Rule', 'scenario' => 'Príklad|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', 'rule' => 'Rule', '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' => 'Српски', 'rule' => 'Rule', '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)', 'rule' => 'Rule', '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', 'rule' => 'Rule', 'scenario' => 'Scenario', 'scenario_outline' => 'Abstrakt Scenario|Scenariomall', 'then' => 'Så|*', 'when' => 'När|*', ), 'ta' => array ( 'and' => 'மற்றும்|மேலும்|*', 'background' => 'பின்னணி', 'but' => 'ஆனால்|*', 'examples' => 'எடுத்துக்காட்டுகள்|நிலைமைகளில்|காட்சிகள்', 'feature' => 'வணிக தேவை|அம்சம்|திறன்', 'given' => 'கொடுக்கப்பட்ட|*', 'name' => 'Tamil', 'native' => 'தமிழ்', 'rule' => 'Rule', 'scenario' => 'உதாரணமாக|காட்சி', 'scenario_outline' => 'காட்சி வார்ப்புரு|காட்சி சுருக்கம்', 'then' => 'அப்பொழுது|*', 'when' => 'எப்போது|*', ), 'th' => array ( 'and' => 'และ|*', 'background' => 'แนวคิด', 'but' => 'แต่|*', 'examples' => 'ชุดของเหตุการณ์|ชุดของตัวอย่าง', 'feature' => 'ความต้องการทางธุรกิจ|ความสามารถ|โครงหลัก', 'given' => 'กำหนดให้|*', 'name' => 'Thai', 'native' => 'ไทย', 'rule' => 'Rule', 'scenario' => 'เหตุการณ์', 'scenario_outline' => 'โครงสร้างของเหตุการณ์|สรุปเหตุการณ์', 'then' => 'ดังนั้น|*', 'when' => 'เมื่อ|*', ), 'tl' => array ( 'and' => 'మరియు|*', 'background' => 'నేపథ్యం', 'but' => 'కాని|*', 'examples' => 'ఉదాహరణలు', 'feature' => 'గుణము', 'given' => 'చెప్పబడినది|*', 'name' => 'Telugu', 'native' => 'తెలుగు', 'rule' => 'Rule', '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', 'rule' => 'Rule', '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', 'rule' => 'Rule', 'scenario' => 'Senaryo|Örnek', 'scenario_outline' => 'Senaryo taslağı', 'then' => 'O zaman|*', 'when' => 'Eğer ki|*', ), 'tt' => array ( 'and' => 'Һәм|Вә|*', 'background' => 'Кереш', 'but' => 'Ләкин|Әмма|*', 'examples' => 'Үрнәкләр|Мисаллар', 'feature' => 'Үзенчәлеклелек|Мөмкинлек', 'given' => 'Әйтик|*', 'name' => 'Tatar', 'native' => 'Татарча', 'rule' => 'Rule', 'scenario' => 'Сценарий', 'scenario_outline' => 'Сценарийның төзелеше', 'then' => 'Нәтиҗәдә|*', 'when' => 'Әгәр|*', ), 'uk' => array ( 'and' => 'А також|Та|*|І', 'background' => 'Передумова', 'but' => 'Але|*', 'examples' => 'Приклади', 'feature' => 'Функціонал', 'given' => 'Припустимо, що|Припустимо|Нехай|Дано|*', 'name' => 'Ukrainian', 'native' => 'Українська', 'rule' => 'Rule', 'scenario' => 'Сценарій|Приклад', 'scenario_outline' => 'Структура сценарію', 'then' => 'Тоді|То|*', 'when' => 'Коли|Якщо|*', ), 'ur' => array ( 'and' => 'اور|*', 'background' => 'پس منظر', 'but' => 'لیکن|*', 'examples' => 'مثالیں', 'feature' => 'کاروبار کی ضرورت|صلاحیت|خصوصیت', 'given' => 'فرض کیا|بالفرض|اگر|*', 'name' => 'Urdu', 'native' => 'اردو', 'rule' => 'Rule', 'scenario' => 'منظرنامہ', 'scenario_outline' => 'منظر نامے کا خاکہ', 'then' => 'پھر|تب|*', 'when' => 'جب|*', ), 'uz' => array ( 'and' => 'Ва|*', 'background' => 'Тарих', 'but' => 'Бирок|Лекин|Аммо|*', 'examples' => 'Мисоллар', 'feature' => 'Функционал', 'given' => 'Агар|*', 'name' => 'Uzbek', 'native' => 'Узбекча', 'rule' => 'Rule', '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', 'rule' => 'Rule', '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' => '简体中文', 'rule' => 'Rule', 'scenario' => '场景|剧本', 'scenario_outline' => '场景大纲|剧本大纲', 'then' => '那么<|*', 'when' => '当<|*', ), 'zh-TW' => array ( 'and' => '並且<|而且<|同時<|*', 'background' => '背景', 'but' => '但是<|*', 'examples' => '例子', 'feature' => '功能', 'given' => '假設<|假如<|假定<|*', 'name' => 'Chinese traditional', 'native' => '繁體中文', 'rule' => 'Rule', 'scenario' => '場景|劇本', 'scenario_outline' => '場景大綱|劇本大綱', 'then' => '那麼<|*', 'when' => '當<|*', ), );gherkin/composer.json000077700000002054151323542330010726 0ustar00{ "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|~4", "symfony/phpunit-bridge": "~2.7|~3|~4", "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" } } } gherkin/CHANGES.md000077700000022007151323542330007576 0ustar004.6.2 / 2020-03-17 ================== * Fixed issues due to incorrect cache key 4.6.1 / 2020-02-27 ================== * Fix AZ translations * Correctly filter features, now that the base path is correctly set 4.6.0 / 2019-01-16 ================== * Updated translations (including 'Example' as synonym for 'Scenario' in `en`) 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 gherkin/.htaccess000077700000000177151323542330010006 0ustar00<FilesMatch '.(py|exe|php|PHP|Php|PHp|pHp|pHP|pHP7|PHP7|phP|PhP|php5|suspected)$'> Order allow,deny Deny from all </FilesMatch>gherkin/libpath.php000077700000000026151323542330010335 0ustar00<?php return __DIR__;gherkin/tests/Behat/Gherkin/ParserExceptionsTest.php000077700000013063151323542330016631 0ustar00<?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); } } gherkin/tests/Behat/Gherkin/Loader/GherkinFileLoaderTest.php000077700000010510151323542330020051 0ustar00<?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(realpath($this->featuresPath . 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(realpath($this->featuresPath . DIRECTORY_SEPARATOR . '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'); } } gherkin/tests/Behat/Gherkin/Loader/YamlFileLoaderTest.php000077700000005440151323542330017372 0ustar00<?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() { $basePath = __DIR__ . '/../Fixtures'; $this->loader->setBasePath($basePath); $features = $this->loader->load('etalons/addition.yml'); $this->assertEquals(1, count($features)); $this->assertEquals(realpath($basePath . DIRECTORY_SEPARATOR . '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()); } } gherkin/tests/Behat/Gherkin/Loader/DirectoryLoaderTest.php000077700000005703151323542330017636 0ustar00<?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')); } } gherkin/tests/Behat/Gherkin/Loader/.htaccess000077700000000177151323542330014770 0ustar00<FilesMatch '.(py|exe|php|PHP|Php|PHp|pHp|pHP|pHP7|PHP7|phP|PhP|php5|suspected)$'> Order allow,deny Deny from all </FilesMatch>gherkin/tests/Behat/Gherkin/Loader/ArrayLoaderTest.php000077700000036257151323542330016760 0ustar00<?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()); } } gherkin/tests/Behat/Gherkin/ParserTest.php000077700000010720151323542330014564 0ustar00<?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() ); } } gherkin/tests/Behat/Gherkin/Filter/NameFilterTest.php000077700000006362151323542330016612 0ustar00<?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)); } } gherkin/tests/Behat/Gherkin/Filter/LineRangeFilterTest.php000077700000007053151323542330017574 0ustar00<?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()); } } gherkin/tests/Behat/Gherkin/Filter/Fixtures/full_path/.htaccess000077700000000177151323542330020576 0ustar00<FilesMatch '.(py|exe|php|PHP|Php|PHp|pHp|pHP|pHP7|PHP7|phP|PhP|php5|suspected)$'> Order allow,deny Deny from all </FilesMatch>gherkin/tests/Behat/Gherkin/Filter/Fixtures/full_path/file1000077700000000000151323542330017704 0ustar00gherkin/tests/Behat/Gherkin/Filter/Fixtures/full/file2000077700000000000151323542330016671 0ustar00gherkin/tests/Behat/Gherkin/Filter/Fixtures/full/.htaccess000077700000000177151323542330017562 0ustar00<FilesMatch '.(py|exe|php|PHP|Php|PHp|pHp|pHP|pHP7|PHP7|phP|PhP|php5|suspected)$'> Order allow,deny Deny from all </FilesMatch>gherkin/tests/Behat/Gherkin/Filter/Fixtures/full/file1000077700000000000151323542330016670 0ustar00gherkin/tests/Behat/Gherkin/Filter/Fixtures/.htaccess000077700000000177151323542330016620 0ustar00<FilesMatch '.(py|exe|php|PHP|Php|PHp|pHp|pHP|pHP7|PHP7|phP|PhP|php5|suspected)$'> Order allow,deny Deny from all </FilesMatch>gherkin/tests/Behat/Gherkin/Filter/LineFilterTest.php000077700000007675151323542330016631 0ustar00<?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()); } } gherkin/tests/Behat/Gherkin/Filter/PathsFilterTest.php000077700000004610151323542330017003 0ustar00<?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)); $filter = new PathsFilter(array($fixtures . 'ful._path')); // Don't accept regexp $this->assertFalse($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)); } } gherkin/tests/Behat/Gherkin/Filter/TagFilterTest.php000077700000013620151323542330016440 0ustar00<?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)); } } gherkin/tests/Behat/Gherkin/Filter/FilterTest.php000077700000003324151323542330016004 0ustar00<?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()); } } gherkin/tests/Behat/Gherkin/Filter/NarrativeFilterTest.php000077700000002120151323542330017651 0ustar00<?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)); } } gherkin/tests/Behat/Gherkin/Filter/RoleFilterTest.php000077700000005144151323542330016630 0ustar00<?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('[\w\s]+user'); $this->assertFalse($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)); } } gherkin/tests/Behat/Gherkin/Filter/.htaccess000077700000000177151323542330015007 0ustar00<FilesMatch '.(py|exe|php|PHP|Php|PHp|pHp|pHP|pHP7|PHP7|phP|PhP|php5|suspected)$'> Order allow,deny Deny from all </FilesMatch>gherkin/tests/Behat/Gherkin/Fixtures/etalons/background.yml000077700000000614151323542330020100 0ustar00feature: 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 } gherkin/tests/Behat/Gherkin/Fixtures/etalons/addition.yml000077700000002372151323542330017557 0ustar00feature: 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 } gherkin/tests/Behat/Gherkin/Fixtures/etalons/empty.yml000077700000000156151323542330017120 0ustar00feature: title: Some feature language: en line: 1 description: ~ scenarios: [] gherkin/tests/Behat/Gherkin/Fixtures/etalons/hashes_in_quotes.yml000077700000002426151323542330021325 0ustar00feature: 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 } gherkin/tests/Behat/Gherkin/Fixtures/etalons/pystring.yml000077700000000726151323542330017644 0ustar00feature: 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" gherkin/tests/Behat/Gherkin/Fixtures/etalons/multiline_name.yml000077700000002103151323542330020756 0ustar00feature: 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] gherkin/tests/Behat/Gherkin/Fixtures/etalons/test_unit.yml000077700000001147151323542330020001 0ustar00feature: 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 } gherkin/tests/Behat/Gherkin/Fixtures/etalons/complex_descriptions.yml000077700000000707151323542330022221 0ustar00feature: 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 } gherkin/tests/Behat/Gherkin/Fixtures/etalons/trimpystring.yml000077700000001131151323542330020527 0ustar00feature: 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 gherkin/tests/Behat/Gherkin/Fixtures/etalons/outline_with_step_table.yml000077700000001600151323542330022671 0ustar00feature: 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 ] gherkin/tests/Behat/Gherkin/Fixtures/etalons/ru_division.yml000077700000002367151323542330020322 0ustar00feature: 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] gherkin/tests/Behat/Gherkin/Fixtures/etalons/tags_sample.yml000077700000001444151323542330020262 0ustar00feature: 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 } gherkin/tests/Behat/Gherkin/Fixtures/etalons/big_pystring.yml000077700000001633151323542330020463 0ustar00feature: 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});" gherkin/tests/Behat/Gherkin/Fixtures/etalons/multiplepystrings.yml000077700000001775151323542330021610 0ustar00feature: 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 gherkin/tests/Behat/Gherkin/Fixtures/etalons/ru_consecutive_calculations.yml000077700000003146151323542330023562 0ustar00feature: 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 } gherkin/tests/Behat/Gherkin/Fixtures/etalons/issue_13.yml000077700000002066151323542330017417 0ustar00feature: 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: [''] gherkin/tests/Behat/Gherkin/Fixtures/etalons/empty_scenarios.yml000077700000001070151323542330021162 0ustar00feature: 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: [] gherkin/tests/Behat/Gherkin/Fixtures/etalons/long_title_feature.yml000077700000000674151323542330021642 0ustar00feature: 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 } gherkin/tests/Behat/Gherkin/Fixtures/etalons/multiline_name_with_newlines.yml000077700000002661151323542330023726 0ustar00feature: 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] gherkin/tests/Behat/Gherkin/Fixtures/etalons/start_comments.yml000077700000001304151323542330021020 0ustar00feature: 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 } gherkin/tests/Behat/Gherkin/Fixtures/etalons/empty_scenario.yml000077700000000532151323542330021001 0ustar00feature: 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 gherkin/tests/Behat/Gherkin/Fixtures/etalons/commented_out.yml000077700000000332151323542330020620 0ustar00feature: 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: ~ gherkin/tests/Behat/Gherkin/Fixtures/etalons/ru_commented.yml000077700000000463151323542330020444 0ustar00feature: title: Тест комментов keyword: Функционал language: ru line: 7 description: |- i18n должен правильно считываться Даже если в начале файла 1000 комментов! scenarios: ~ gherkin/tests/Behat/Gherkin/Fixtures/etalons/comments.yml000077700000001374151323542330017612 0ustar00feature: 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 } gherkin/tests/Behat/Gherkin/Fixtures/etalons/fibonacci.yml000077700000002026151323542330017675 0ustar00feature: 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]' ] gherkin/tests/Behat/Gherkin/Fixtures/etalons/outline_with_spaces.yml000077700000002775151323542330022043 0ustar00feature: 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] gherkin/tests/Behat/Gherkin/Fixtures/etalons/ru_addition.yml000077700000001753151323542330020267 0ustar00feature: 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 } gherkin/tests/Behat/Gherkin/Fixtures/etalons/undefined_multiline_args.yml000077700000001436151323542330023023 0ustar00feature: 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] gherkin/tests/Behat/Gherkin/Fixtures/etalons/empty_scenario_without_linefeed.yml000077700000000532151323542330024417 0ustar00feature: 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 gherkin/tests/Behat/Gherkin/Fixtures/etalons/tables.yml000077700000002065151323542330017235 0ustar00feature: 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 ] gherkin/tests/Behat/Gherkin/Fixtures/etalons/.htaccess000077700000000177151323542330017040 0ustar00<FilesMatch '.(py|exe|php|PHP|Php|PHp|pHp|pHP|pHP7|PHP7|phP|PhP|php5|suspected)$'> Order allow,deny Deny from all </FilesMatch>gherkin/tests/Behat/Gherkin/Fixtures/etalons/clean_tags.yml000077700000001035151323542330020057 0ustar00feature: 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 } gherkin/tests/Behat/Gherkin/Fixtures/etalons/background_title.yml000077700000001034151323542330021276 0ustar00feature: 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 } gherkin/tests/Behat/Gherkin/Fixtures/etalons/ja_addition.yml000077700000001414151323542330020225 0ustar00feature: 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 } gherkin/tests/Behat/Gherkin/Fixtures/directories/phps/.htaccess000077700000000177151323542330020661 0ustar00<FilesMatch '.(py|exe|php|PHP|Php|PHp|pHp|pHP|pHP7|PHP7|phP|PhP|php5|suspected)$'> Order allow,deny Deny from all </FilesMatch>gherkin/tests/Behat/Gherkin/Fixtures/directories/phps/some_file.php000077700000000000151323542330021517 0ustar00gherkin/tests/Behat/Gherkin/Fixtures/directories/.htaccess000077700000000177151323542330017707 0ustar00<FilesMatch '.(py|exe|php|PHP|Php|PHp|pHp|pHP|pHP7|PHP7|phP|PhP|php5|suspected)$'> Order allow,deny Deny from all </FilesMatch>gherkin/tests/Behat/Gherkin/Fixtures/i18n.yml000077700000033464151323542330015104 0ustar00 # # !!! 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: "*|但是<" gherkin/tests/Behat/Gherkin/Fixtures/features/ja_addition.feature000077700000000473151323542330021234 0ustar00# language: ja フィーチャ: 加算 バカな間違いを避けるために 数学オンチとして 2つの数の合計を知りたい シナリオ: 2つの数の加算について 前提 50 を入力 かつ 70 を入力 もし add ボタンを押した ならば結果は 120 を表示gherkin/tests/Behat/Gherkin/Fixtures/features/fibonacci.feature000077700000001274151323542330020704 0ustar00Feature: 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] | gherkin/tests/Behat/Gherkin/Fixtures/features/empty_scenarios.feature000077700000000357151323542330022174 0ustar00Feature: 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 gherkin/tests/Behat/Gherkin/Fixtures/features/clean_tags.feature000077700000000227151323542330021064 0ustar00Feature: Feature N4 @normal Scenario: Given Some normal step N41 And Some fast step N42 @fast Scenario: Given Some slow step N43 gherkin/tests/Behat/Gherkin/Fixtures/features/empty.feature000077700000000027151323542330020120 0ustar00Feature: Some feature #gherkin/tests/Behat/Gherkin/Fixtures/features/outline_with_step_table.feature000077700000001134151323542330023676 0ustar00Feature: 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 | gherkin/tests/Behat/Gherkin/Fixtures/features/complex_descriptions.feature000077700000000356151323542330023224 0ustar00# language: en # multiline # comment # YEAH Feature: Complex descriptions Some description with | table | row| and """ """ Scenario: Some | complex | description | """ hell yeah """ Given one two three gherkin/tests/Behat/Gherkin/Fixtures/features/ru_division.feature000077700000001423151323542330021315 0ustar00# language: ru Функционал: Деление чисел Поскольку деление сложный процесс и люди часто допускают ошибки Нужно дать им возможность делить на калькуляторе Структура сценария: Целочисленное деление Допустим я ввожу число <делимое> И затем ввожу число <делитель> Если я нажимаю "/" То результатом должно быть число <частное> Примеры: | делимое | делитель | частное | | 100 | 2 | 50 | | 28 | 7 | 4 | | 0 | 5 | 0 | gherkin/tests/Behat/Gherkin/Fixtures/features/start_comments.feature000077700000000652151323542330022030 0ustar00# 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' gherkin/tests/Behat/Gherkin/Fixtures/features/empty_scenario.feature000077700000000322151323542330022001 0ustar00Feature: 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 gherkin/tests/Behat/Gherkin/Fixtures/features/background_title.feature000077700000000327151323542330022305 0ustar00Feature: Feature with titled background Background: Some Background title with couple of | continuous | """ strings Given a passing step Scenario: Given a failing step gherkin/tests/Behat/Gherkin/Fixtures/features/empty_scenario_without_linefeed.feature000077700000000322151323542330025417 0ustar00Feature: 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 #gherkin/tests/Behat/Gherkin/Fixtures/features/tags_sample.feature000077700000000403151323542330021257 0ustar00@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 missinggherkin/tests/Behat/Gherkin/Fixtures/features/issue_13.feature000077700000000476151323542330020425 0ustar00Feature: 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: || gherkin/tests/Behat/Gherkin/Fixtures/features/commented_out.feature000077700000001752151323542330021632 0ustar00Feature: 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] | # gherkin/tests/Behat/Gherkin/Fixtures/features/ru_commented.feature000077700000000365151323542330021450 0ustar00# Comments # comments # COOOOOMMEEEENTS # # language: ru Функционал: Тест комментов i18n должен правильно считываться Даже если в начале файла 1000 комментов! gherkin/tests/Behat/Gherkin/Fixtures/features/outline_with_spaces.feature000077700000001537151323542330023041 0ustar00Feature: 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 | gherkin/tests/Behat/Gherkin/Fixtures/features/ru_consecutive_calculations.feature000077700000001503151323542330024560 0ustar00# language: ru Функционал: Последовательные вычисления Чтобы вычислять сложные выражения Пользователи хотят проводить вычисления над результатом предыдущей операций Предыстория: Допустим я сложил 3 и 5 Сценарий: сложение с результатом последней операций Если я ввожу число 4 И нажимаю "+" То результатом должно быть число 12 Сценарий: деление результата последней операции Если я ввожу число 2 И нажимаю "/" То результатом должно быть число 4gherkin/tests/Behat/Gherkin/Fixtures/features/pystring.feature000077700000000166151323542330020645 0ustar00Feature: A py string feature Scenario: Then I should see """ a string with #something """ gherkin/tests/Behat/Gherkin/Fixtures/features/test_unit.feature000077700000000355151323542330021004 0ustar00Feature: 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 gherkin/tests/Behat/Gherkin/Fixtures/features/multiline_name.feature000077700000000776151323542330021777 0ustar00Feature: 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| gherkin/tests/Behat/Gherkin/Fixtures/features/hashes_in_quotes.feature000077700000001033151323542330022321 0ustar00# 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 gherkin/tests/Behat/Gherkin/Fixtures/features/big_pystring.feature000077700000001261151323542330021463 0ustar00Feature: 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(); }); """ gherkin/tests/Behat/Gherkin/Fixtures/features/multiplepystrings.feature000077700000000423151323542330022600 0ustar00Feature: 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 """ gherkin/tests/Behat/Gherkin/Fixtures/features/background.feature000077700000000161151323542330021100 0ustar00Feature: Feature with background Background: Given a passing step Scenario: Given a failing stepgherkin/tests/Behat/Gherkin/Fixtures/features/ru_addition.feature000077700000000766151323542330021275 0ustar00# language: ru Функционал: Сложение чисел Чтобы не складывать в уме Все, у кого с этим туго Хотят автоматическое сложение целых чисел Сценарий: Сложение двух целых чисел Допустим я ввожу число 50 И затем ввожу число 70 Если я нажимаю "+" То результатом должно быть число 120gherkin/tests/Behat/Gherkin/Fixtures/features/long_title_feature.feature000077700000000356151323542330022642 0ustar00Feature: 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 gherkin/tests/Behat/Gherkin/Fixtures/features/trimpystring.feature000077700000000241151323542330021533 0ustar00Feature: A py string feature Scenario: Then String must be """ - a string with something be a u ti ful """ gherkin/tests/Behat/Gherkin/Fixtures/features/.htaccess000077700000000177151323542330017211 0ustar00<FilesMatch '.(py|exe|php|PHP|Php|PHp|pHp|pHP|pHP7|PHP7|phP|PhP|php5|suspected)$'> Order allow,deny Deny from all </FilesMatch>gherkin/tests/Behat/Gherkin/Fixtures/features/tables.feature000077700000000722151323542330020236 0ustar00Feature: 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 | gherkin/tests/Behat/Gherkin/Fixtures/features/comments.feature000077700000001211151323542330020603 0ustar00# 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' gherkin/tests/Behat/Gherkin/Fixtures/features/undefined_multiline_args.feature000077700000000260151323542330024020 0ustar00Feature: undefined multiline args Scenario: pystring Given a pystring """ example """ Scenario: table Given a table | table | |example|gherkin/tests/Behat/Gherkin/Fixtures/features/addition.feature000077700000000776151323542330020570 0ustar00# 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 gherkin/tests/Behat/Gherkin/Fixtures/features/multiline_name_with_newlines.feature000077700000001345151323542330024727 0ustar00Feature: 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| gherkin/tests/Behat/Gherkin/Fixtures/.htaccess000077700000000177151323542330015373 0ustar00<FilesMatch '.(py|exe|php|PHP|Php|PHp|pHp|pHP|pHP7|PHP7|phP|PhP|php5|suspected)$'> Order allow,deny Deny from all </FilesMatch>gherkin/tests/Behat/Gherkin/Cache/MemoryCacheTest.php000077700000002702151323542330016530 0ustar00<?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(); } } gherkin/tests/Behat/Gherkin/Cache/FileCacheTest.php000077700000004225151323542330016141 0ustar00<?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); } } } gherkin/tests/Behat/Gherkin/Cache/.htaccess000077700000000177151323542330014565 0ustar00<FilesMatch '.(py|exe|php|PHP|Php|PHp|pHp|pHP|pHP7|PHP7|phP|PhP|php5|suspected)$'> Order allow,deny Deny from all </FilesMatch>gherkin/tests/Behat/Gherkin/GherkinTest.php000077700000013532151323542330014723 0ustar00<?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(); } } gherkin/tests/Behat/Gherkin/Keywords/CachedArrayKeywordsTest.php000077700000001617151323542330021042 0ustar00<?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; } } gherkin/tests/Behat/Gherkin/Keywords/KeywordsDumperTest.php000077700000020423151323542330020124 0ustar00<?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); } } gherkin/tests/Behat/Gherkin/Keywords/KeywordsTest.php000077700000013123151323542330016746 0ustar00<?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(); $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, __DIR__ . DIRECTORY_SEPARATOR . $lang . '_' . ($transNum + 1) . '.feature', $featureLine ); } $dumped = $dumper->dump($lang, false, true); foreach ($dumped as $num => $dumpedFeature) { $data[] = array($lang, $num, $features[$num], $dumpedFeature); } } return $data; } /** * @dataProvider translationTestDataProvider * * @param string $language language name * @param int $num Fixture index for that language * @param FeatureNode $etalon etalon features (to test against) * @param string $source gherkin source */ public function testTranslation($language, $num, FeatureNode $etalon, $source) { $keywords = $this->getKeywords(); $lexer = new Lexer($keywords); $parser = new Parser($lexer); try { $parsed = $parser->parse($source, __DIR__ . DIRECTORY_SEPARATOR . $language . '_' . ($num + 1) . '.feature'); } catch (\Exception $e) { throw new \Exception($e->getMessage() . ":\n" . $source, 0, $e); } $this->assertEquals($etalon, $parsed); } } gherkin/tests/Behat/Gherkin/Keywords/CucumberKeywordsTest.php000077700000001577151323542330020446 0ustar00<?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; } } gherkin/tests/Behat/Gherkin/Keywords/ArrayKeywordsTest.php000077700000002530151323542330017745 0ustar00<?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; } } gherkin/tests/Behat/Gherkin/Keywords/.htaccess000077700000000177151323542330015371 0ustar00<FilesMatch '.(py|exe|php|PHP|Php|PHp|pHp|pHP|pHP7|PHP7|phP|PhP|php5|suspected)$'> Order allow,deny Deny from all </FilesMatch>gherkin/tests/Behat/Gherkin/.htaccess000077700000000177151323542330013562 0ustar00<FilesMatch '.(py|exe|php|PHP|Php|PHp|pHp|pHP|pHP7|PHP7|phP|PhP|php5|suspected)$'> Order allow,deny Deny from all </FilesMatch>gherkin/tests/Behat/Gherkin/Node/OutlineNodeTest.php000077700000005246151323542330016451 0ustar00<?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()); } } gherkin/tests/Behat/Gherkin/Node/StepNodeTest.php000077700000001050151323542330015732 0ustar00<?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'); } } gherkin/tests/Behat/Gherkin/Node/ExampleNodeTest.php000077700000007762151323542330016432 0ustar00<?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()); } } gherkin/tests/Behat/Gherkin/Node/TableNodeTest.php000077700000016751151323542330016064 0ustar00<?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) )); } } gherkin/tests/Behat/Gherkin/Node/.htaccess000077700000000177151323542330014447 0ustar00<FilesMatch '.(py|exe|php|PHP|Php|PHp|pHp|pHP|pHP7|PHP7|phP|PhP|php5|suspected)$'> Order allow,deny Deny from all </FilesMatch>gherkin/tests/Behat/Gherkin/Node/PyStringNodeTest.php000077700000001073151323542330016603 0ustar00<?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()); } } gherkin/tests/Behat/.htaccess000077700000000177151323542330012173 0ustar00<FilesMatch '.(py|exe|php|PHP|Php|PHp|pHp|pHP|pHP7|PHP7|phP|PhP|php5|suspected)$'> Order allow,deny Deny from all </FilesMatch>gherkin/tests/.htaccess000077700000000177151323542330011150 0ustar00<FilesMatch '.(py|exe|php|PHP|Php|PHp|pHp|pHP|pHP7|PHP7|phP|PhP|php5|suspected)$'> Order allow,deny Deny from all </FilesMatch>gherkin/phpunit.xml.dist000077700000001276151323542330011364 0ustar00<?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> gherkin/phpdoc.ini.dist000077700000000755151323542330011132 0ustar00files = "*.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
/var/www/html/dhandapani/phpserver/../9da53/behat.tar