/** * Visits & tests OutlineNode example. * * @param OutlineNode $outline outline instance * @param integer $row row number * @param array $tokens step replacements for tokens * * @return integer */ private function visitOutlineExample(OutlineNode $outline, $row, array $tokens = array()) { $context = $this->container->get('behat.context.dispatcher')->createContext(); $itResult = 0; $skip = false; $this->dispatcher->dispatch('beforeOutlineExample', new OutlineExampleEvent($outline, $row, $context)); // Visit & test background if has one if ($outline->getFeature()->hasBackground()) { $bgResult = $this->visitBackground($outline->getFeature()->getBackground(), $outline, $context); if (0 !== $bgResult) { $skip = true; } $itResult = max($itResult, $bgResult); } // Visit & test steps foreach ($outline->getSteps() as $step) { $stResult = $this->visitStep($step, $outline, $context, $tokens, $skip); if (0 !== $stResult) { $skip = true; } $itResult = max($itResult, $stResult); } $this->dispatcher->dispatch('afterOutlineExample', new OutlineExampleEvent($outline, $row, $context, $itResult, $skip)); return $itResult; }
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()); }
/** * @param OutlineNode $scenario * * @return string */ public function format(OutlineNode $scenario) { if (!$scenario->hasExamples()) { return; } // TODO: refactor this part return implode(array_merge([$this->indent(self::INDENTATION * 2) . rtrim($scenario->getExampleTable()->getKeyword()) . ":\n"], array_map(function ($arguments) { return $this->indent(self::INDENTATION * 2 + 2) . trim($arguments) . "\n"; }, explode("\n", $scenario->getExampleTable()->getTableAsString())))); }
public function testExamplesIncludesTheOutlineNode() { $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('user1', '*****@*****.**'), array('user2', '*****@*****.**')), 'Examples'); $outline = new OutlineNode('outline test title', array(), $steps, $table, null, null); $examples = $outline->getExamples(); for ($i = 0; $i < count($examples); $i++) { $this->assertTrue($examples[$i]->getOutline() instanceof OutlineNode); $this->assertEquals('outline test title', $examples[$i]->getOutline()->getTitle()); } }
public function createFilename(FeatureNode $feature, ScenarioInterface $scenario, OutlineNode $outline = null) { $filename = Transliterator::transliterate($feature->getTitle(), $this->separator) . DIRECTORY_SEPARATOR; if ($outline) { $filename .= Transliterator::transliterate($outline->getTitle(), $this->separator) . DIRECTORY_SEPARATOR . $this->separator; } $filename .= Transliterator::transliterate($scenario->getTitle(), $this->separator); if ($outline) { $filename .= $this->separator; } return $filename; }
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', '*****@*****.**', 'homepage'), array('example', '*****@*****.**', '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()); }
/** * {@inheritdoc} */ public function test(Environment $env, FeatureNode $feature, OutlineNode $outline, $skip = false) { $results = array(); foreach ($outline->getExamples() as $example) { $setup = $this->scenarioTester->setUp($env, $feature, $example, $skip); $localSkip = !$setup->isSuccessful() || $skip; $testResult = $this->scenarioTester->test($env, $feature, $example, $localSkip); $teardown = $this->scenarioTester->tearDown($env, $feature, $example, $localSkip, $testResult); $integerResult = new IntegerTestResult($testResult->getResultCode()); $results[] = new TestWithSetupResult($setup, $integerResult, $teardown); } return new TestResults($results); }
/** * Creates wrapper-closure for the example table. * * @param OutlineNode $outline * @param ExampleNode $example * @param AfterStepTested[] $stepEvents * * @return callable */ private function getWrapperClosure(OutlineNode $outline, ExampleNode $example, array $stepEvents) { $resultConverter = $this->resultConverter; return function ($value, $column) use($outline, $example, $stepEvents, $resultConverter) { $results = array(); foreach ($stepEvents as $event) { $index = array_search($event->getStep(), $example->getSteps()); $header = $outline->getExampleTable()->getRow(0); $steps = $outline->getSteps(); $outlineStepText = $steps[$index]->getText(); if (false !== strpos($outlineStepText, '<' . $header[$column] . '>')) { $results[] = $event->getTestResult(); } } $result = new TestResults($results); $style = $resultConverter->convertResultToString($result); return sprintf('{+%s}%s{-%s}', $style, $value, $style); }; }
/** * 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()); }
public function translationTestDataProvider() { $data = array(); $translator = $this->getTranslator(); $parser = $this->getParser(); $finder = new Finder(); $i18ns = $finder->files()->name('*.xliff')->in(__DIR__ . '/../Fixtures/i18n'); foreach ($i18ns as $i18n) { $language = basename($i18n, '.xliff'); $translator->addResource('xliff', $i18n, $language, 'gherkin'); $etalon = array(); $features = array(); foreach ($this->getTranslatedKeywords('Feature', $language) as $featureNum => $featureKeyword) { $gherkin = "# language: {$language}"; $lineNum = 1; $feature = new Node\FeatureNode(null, null, null, ++$lineNum); $feature->setLanguage($language); $feature->setKeyword($featureKeyword); $feature->setTitle($title = "title of the feature N{$featureNum}"); $feature->setDescription($description = "some\nfeature\ndescription"); $gherkin .= "\n{$featureKeyword}: {$title}"; $gherkin .= "\n{$description}"; $lineNum += 3; $stepKeywords = $this->getTranslatedKeywords('Given|When|Then|And|But', $language); $backgroundKeywords = $this->getTranslatedKeywords('Background', $language); $examplesKeywords = $this->getTranslatedKeywords('Examples', $language); // Background $backgroundKeyword = $backgroundKeywords[0]; $background = new Node\BackgroundNode(null, ++$lineNum); $background->setKeyword($backgroundKeyword); $feature->setBackground($background); $gherkin .= "\n{$backgroundKeyword}:"; foreach ($stepKeywords as $stepNum => $stepKeyword) { $step = new Node\StepNode($stepKeyword, $text = "text of the step N{$stepNum}", ++$lineNum); $background->addStep($step); $gherkin .= "\n{$stepKeyword} {$text}"; } // Scenarios foreach ($this->getTranslatedKeywords('Scenario', $language) as $scenarioNum => $scenarioKeyword) { $scenario = new Node\ScenarioNode($title = "title of the scenario N{$scenarioNum}", ++$lineNum); $scenario->setKeyword($scenarioKeyword); $feature->addScenario($scenario); $gherkin .= "\n{$scenarioKeyword}: {$title}"; foreach ($stepKeywords as $stepNum => $stepKeyword) { $step = new Node\StepNode($stepKeyword, $text = "text of the step N{$stepNum}", ++$lineNum); $scenario->addStep($step); $gherkin .= "\n{$stepKeyword} {$text}"; } } // Scenario Outlines foreach ($this->getTranslatedKeywords('Scenario Outline', $language) as $outlineNum => $outlineKeyword) { $outline = new Node\OutlineNode($title = "title of the outline N{$outlineNum}", ++$lineNum); $outline->setKeyword($outlineKeyword); $feature->addScenario($outline); $gherkin .= "\n{$outlineKeyword}: {$title}"; $stepKeyword = $stepKeywords[0]; $step = new Node\StepNode($stepKeyword, $text = "text of the step <num>", ++$lineNum); $outline->addStep($step); $gherkin .= "\n{$stepKeyword} {$text}"; $examplesKeyword = $examplesKeywords[0]; $examples = new Node\TableNode(); $examples->setKeyword($examplesKeyword); $examples->addRow(array('num')); $examples->addRow(array(2)); $outline->setExamples($examples); $gherkin .= "\n{$examplesKeyword}:"; $gherkin .= "\n | num |"; $gherkin .= "\n | 2 |"; $lineNum += 3; } $etalon[] = $feature; $features[] = $this->getParser()->parse($gherkin); } $data[] = array($language, $etalon, $features); } return $data; }
/** * 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) { $outline = new Node\OutlineNode(null, isset($hash['line']) ? $hash['line'] : $line); $outline->setKeyword(isset($hash['keyword']) ? $hash['keyword'] : 'Scenario Outline'); if (isset($hash['title'])) { $outline->setTitle($hash['title']); } if (isset($hash['tags'])) { $outline->setTags($hash['tags']); } if (isset($hash['examples'])) { if (isset($hash['examples']['keyword'])) { $keyword = $hash['examples']['keyword']; unset($hash['examples']['keyword']); } else { $keyword = 'Examples'; } $table = $this->loadTableHash($hash['examples']); $table->setKeyword($keyword); $outline->setExamples($table); } if (isset($hash['steps'])) { foreach ($hash['steps'] as $stepIterator => $stepHash) { $outline->addStep($this->loadStepHash($stepHash, $stepIterator)); } } return $outline; }
public function translationTestDataProvider() { $keywords = $this->getKeywords(); $lexer = new Lexer($keywords); $parser = new Parser($lexer); $dumper = new KeywordsDumper($keywords); $data = array(); foreach ($this->getKeywordsArray() as $lang => $i18nKeywords) { $features = array(); foreach (explode('|', $i18nKeywords['feature']) as $transNum => $featureKeyword) { $line = 1; if ('en' !== $lang) { $line = 2; } $feature = new Node\FeatureNode('Internal operations', <<<DESC In order to stay secret As a secret organization We need to be able to erase past agents' memory DESC , $lang . '_' . ($transNum + 1) . '.feature', $line); $feature->setLanguage($lang); $feature->setKeyword($featureKeyword); $line += 5; $background = new Node\BackgroundNode(null, $line); $keywords = explode('|', $i18nKeywords['background']); $background->setKeyword($keywords[0]); $line += 1; $line = $this->addSteps($background, $i18nKeywords['given'], 'there is agent A', $line); $line = $this->addSteps($background, $i18nKeywords['and'], 'there is agent B', $line); $feature->setBackground($background); $line += 1; foreach (explode('|', $i18nKeywords['scenario']) as $scenarioKeyword) { $scenario = new Node\ScenarioNode('Erasing agent memory', $line); $scenario->setKeyword($scenarioKeyword); $line += 1; $line = $this->addSteps($scenario, $i18nKeywords['given'], 'there is agent J', $line); $line = $this->addSteps($scenario, $i18nKeywords['and'], 'there is agent K', $line); $line = $this->addSteps($scenario, $i18nKeywords['when'], 'I erase agent K\'s memory', $line); $line = $this->addSteps($scenario, $i18nKeywords['then'], 'there should be agent J', $line); $line = $this->addSteps($scenario, $i18nKeywords['but'], 'there should not be agent K', $line); $feature->addScenario($scenario); $line += 1; } foreach (explode('|', $i18nKeywords['scenario_outline']) as $outlineKeyword) { $outline = new Node\OutlineNode('Erasing other agents\' memory', $line); $outline->setKeyword($outlineKeyword); $line += 1; $line = $this->addSteps($outline, $i18nKeywords['given'], 'there is agent <agent1>', $line); $line = $this->addSteps($outline, $i18nKeywords['and'], 'there is agent <agent2>', $line); $line = $this->addSteps($outline, $i18nKeywords['when'], 'I erase agent <agent2>\'s memory', $line); $line = $this->addSteps($outline, $i18nKeywords['then'], 'there should be agent <agent1>', $line); $line = $this->addSteps($outline, $i18nKeywords['but'], 'there should not be agent <agent2>', $line); $line += 1; $outline->setExamples($examples = new Node\TableNode(<<<TABLE | agent1 | agent2 | | D | M | TABLE )); $keywords = explode('|', $i18nKeywords['examples']); $examples->setKeyword($keywords[0]); $line += 3; $feature->addScenario($outline); $line += 1; } $features[] = $feature; } $dumped = $dumper->dump($lang, false); $parsed = array(); try { foreach ($dumped as $num => $dumpedFeature) { $parsed[] = $parser->parse($dumpedFeature, $lang . '_' . ($num + 1) . '.feature'); } } catch (\Exception $e) { throw new \Exception($e->getMessage() . ":\n" . $dumped, 0, $e); } $data[] = array($lang, $features, $parsed); } return $data; }
/** * Parses scenario outline token & returns it's node. * * @return Behat\Gherkin\Node\OutlineNode */ protected function parseOutline() { $token = $this->expectTokenType('Outline'); $node = new Node\OutlineNode(trim($token->value) ?: null, $token->line); $node->setKeyword($token->keyword); // Parse tags $this->parseNodeTags($node); // Parse title $this->parseNodeDescription($node, $token->indent + 2); // Parse steps while ('Step' === $this->predictTokenType()) { $node->addStep($this->parseExpression()); } // Examples block $examplesToken = $this->expectTokenType('Examples'); $this->skipExtraChars(); // Parse examples table $table = $this->parseTable(); $table->setKeyword($examplesToken->keyword); $node->setExamples($table); return $node; }
public function testTags() { $outline = new OutlineNode(); $this->assertFalse($outline->hasTags()); $this->assertInternalType('array', $outline->getTags()); $this->assertEquals(0, count($outline->getTags())); $outline->setTags($tags = array('tag1', 'tag2')); $this->assertEquals($tags, $outline->getTags()); $outline->addTag('tag3'); $this->assertEquals(array('tag1', 'tag2', 'tag3'), $outline->getTags()); $this->assertFalse($outline->hasTag('tag4')); $this->assertTrue($outline->hasTag('tag2')); $this->assertTrue($outline->hasTag('tag3')); }
protected function outlineExampleEventMock($tag) { $outline = new OutlineNode(); $outline->addTag($tag); return new OutlineExampleEvent($outline, 0, $this->getMock('Behat\\Behat\\Context\\ContextInterface')); }
public function testDumpOutlineScenarioReturnsContentAndTableNode() { $dumper = new Dumper($this->keywords); $scenario = new OutlineNode('my scenario'); $scenario->addStep(new StepNode('Given', 'my example1')); // complete table $examples = new TableNode(); $examples->addRow(array('lib1', 'lib2', 'lib3')); $examples->addRow(array(1, 2, 3)); $examples->addRow(array(4, 5, 6)); $scenario->setExamples($examples); $expected = ' Scenario Outline: my scenario Given my example1 Examples: | lib1 | lib2 | lib3 | | 1 | 2 | 3 | | 4 | 5 | 6 |'; $this->assertEquals($expected, $dumper->dumpScenario($scenario)); }