This commit is contained in:
2020-10-06 14:27:47 +07:00
commit 586be80cf6
16613 changed files with 3274099 additions and 0 deletions

View File

@@ -0,0 +1,75 @@
<?php
namespace Tests\Behat\Gherkin\Cache;
use Behat\Gherkin\Cache\FileCache;
use Behat\Gherkin\Node\FeatureNode;
use Behat\Gherkin\Node\ScenarioNode;
use Behat\Gherkin\Gherkin;
class FileCacheTest extends \PHPUnit_Framework_TestCase
{
private $path;
private $cache;
public function testIsFreshWhenThereIsNoFile()
{
$this->assertFalse($this->cache->isFresh('unexisting', time() + 100));
}
public function testIsFreshOnFreshFile()
{
$feature = new FeatureNode(null, null, array(), null, array(), null, null, null, null);
$this->cache->write('some_path', $feature);
$this->assertFalse($this->cache->isFresh('some_path', time() + 100));
}
public function testIsFreshOnOutdated()
{
$feature = new FeatureNode(null, null, array(), null, array(), null, null, null, null);
$this->cache->write('some_path', $feature);
$this->assertTrue($this->cache->isFresh('some_path', time() - 100));
}
public function testCacheAndRead()
{
$scenarios = array(new ScenarioNode('Some scenario', array(), array(), null, null));
$feature = new FeatureNode('Some feature', 'some description', array(), null, $scenarios, null, null, null, null);
$this->cache->write('some_feature', $feature);
$featureRead = $this->cache->read('some_feature');
$this->assertEquals($feature, $featureRead);
}
public function testBrokenCacheRead()
{
$this->setExpectedException('Behat\Gherkin\Exception\CacheException');
touch($this->path . '/v' . Gherkin::VERSION . '/' . md5('broken_feature') . '.feature.cache');
$this->cache->read('broken_feature');
}
public function testUnwriteableCacheDir()
{
$this->setExpectedException('Behat\Gherkin\Exception\CacheException');
new FileCache('/dev/null/gherkin-test');
}
protected function setUp()
{
$this->cache = new FileCache($this->path = sys_get_temp_dir() . '/gherkin-test');
}
protected function tearDown()
{
foreach (glob($this->path . '/*.feature.cache') as $file) {
unlink((string) $file);
}
}
}

View File

@@ -0,0 +1,51 @@
<?php
namespace Tests\Behat\Gherkin\Cache;
use Behat\Gherkin\Cache\MemoryCache;
use Behat\Gherkin\Node\FeatureNode;
use Behat\Gherkin\Node\ScenarioNode;
class MemoryCacheTest extends \PHPUnit_Framework_TestCase
{
private $cache;
public function testIsFreshWhenThereIsNoFile()
{
$this->assertFalse($this->cache->isFresh('unexisting', time() + 100));
}
public function testIsFreshOnFreshFile()
{
$feature = new FeatureNode(null, null, array(), null, array(), null, null, null, null);
$this->cache->write('some_path', $feature);
$this->assertFalse($this->cache->isFresh('some_path', time() + 100));
}
public function testIsFreshOnOutdated()
{
$feature = new FeatureNode(null, null, array(), null, array(), null, null, null, null);
$this->cache->write('some_path', $feature);
$this->assertTrue($this->cache->isFresh('some_path', time() - 100));
}
public function testCacheAndRead()
{
$scenarios = array(new ScenarioNode('Some scenario', array(), array(), null, null));
$feature = new FeatureNode('Some feature', 'some description', array(), null, $scenarios, null, null, null, null);
$this->cache->write('some_feature', $feature);
$featureRead = $this->cache->read('some_feature');
$this->assertEquals($feature, $featureRead);
}
protected function setUp()
{
$this->cache = new MemoryCache();
}
}

View File

@@ -0,0 +1,64 @@
<?php
namespace Tests\Behat\Gherkin\Filter;
use Behat\Gherkin\Keywords\ArrayKeywords;
use Behat\Gherkin\Lexer;
use Behat\Gherkin\Parser;
abstract class FilterTest extends \PHPUnit_Framework_TestCase
{
protected function getParser()
{
return new Parser(
new Lexer(
new ArrayKeywords(array(
'en' => array(
'feature' => 'Feature',
'background' => 'Background',
'scenario' => 'Scenario',
'scenario_outline' => 'Scenario Outline|Scenario Template',
'examples' => 'Examples|Scenarios',
'given' => 'Given',
'when' => 'When',
'then' => 'Then',
'and' => 'And',
'but' => 'But'
)
))
)
);
}
protected function getGherkinFeature()
{
return <<<GHERKIN
Feature: Long feature with outline
Scenario: Scenario#1
Given initial step
When action occurs
Then outcomes should be visible
Scenario: Scenario#2
Given initial step
And another initial step
When action occurs
Then outcomes should be visible
Scenario Outline: Scenario#3
When <action> occurs
Then <outcome> should be visible
Examples:
| action | outcome |
| act#1 | out#1 |
| act#2 | out#2 |
| act#3 | out#3 |
GHERKIN;
}
protected function getParsedFeature()
{
return $this->getParser()->parse($this->getGherkinFeature());
}
}

View File

@@ -0,0 +1,103 @@
<?php
namespace Tests\Behat\Gherkin\Filter;
use Behat\Gherkin\Filter\LineFilter;
use Behat\Gherkin\Node\ExampleTableNode;
use Behat\Gherkin\Node\FeatureNode;
use Behat\Gherkin\Node\OutlineNode;
use Behat\Gherkin\Node\ScenarioNode;
class LineFilterTest extends FilterTest
{
public function testIsFeatureMatchFilter()
{
$feature = new FeatureNode(null, null, array(), null, array(), null, null, null, 1);
$filter = new LineFilter(1);
$this->assertTrue($filter->isFeatureMatch($feature));
$filter = new LineFilter(2);
$this->assertFalse($filter->isFeatureMatch($feature));
$filter = new LineFilter(3);
$this->assertFalse($filter->isFeatureMatch($feature));
}
public function testIsScenarioMatchFilter()
{
$scenario = new ScenarioNode(null, array(), array(), null, 2);
$filter = new LineFilter(2);
$this->assertTrue($filter->isScenarioMatch($scenario));
$filter = new LineFilter(1);
$this->assertFalse($filter->isScenarioMatch($scenario));
$filter = new LineFilter(5);
$this->assertFalse($filter->isScenarioMatch($scenario));
$outline = new OutlineNode(null, array(), array(), new ExampleTableNode(array(), null), null, 20);
$filter = new LineFilter(5);
$this->assertFalse($filter->isScenarioMatch($outline));
$filter = new LineFilter(20);
$this->assertTrue($filter->isScenarioMatch($outline));
}
public function testFilterFeatureScenario()
{
$filter = new LineFilter(2);
$feature = $filter->filterFeature($this->getParsedFeature());
$this->assertCount(1, $scenarios = $feature->getScenarios());
$this->assertSame('Scenario#1', $scenarios[0]->getTitle());
$filter = new LineFilter(7);
$feature = $filter->filterFeature($this->getParsedFeature());
$this->assertCount(1, $scenarios = $feature->getScenarios());
$this->assertSame('Scenario#2', $scenarios[0]->getTitle());
$filter = new LineFilter(5);
$feature = $filter->filterFeature($this->getParsedFeature());
$this->assertCount(0, $scenarios = $feature->getScenarios());
}
public function testFilterFeatureOutline()
{
$filter = new LineFilter(13);
$feature = $filter->filterFeature($this->getParsedFeature());
$this->assertCount(1, $scenarios = $feature->getScenarios());
$this->assertSame('Scenario#3', $scenarios[0]->getTitle());
$this->assertCount(4, $scenarios[0]->getExampleTable()->getRows());
$filter = new LineFilter(19);
$feature = $filter->filterFeature($this->getParsedFeature());
$this->assertCount(1, $scenarios = $feature->getScenarios());
$this->assertSame('Scenario#3', $scenarios[0]->getTitle());
$this->assertCount(2, $scenarios[0]->getExampleTable()->getRows());
$this->assertSame(array(
array('action', 'outcome'),
array('act#1', 'out#1'),
), $scenarios[0]->getExampleTable()->getRows());
$filter = new LineFilter(21);
$feature = $filter->filterFeature($this->getParsedFeature());
$this->assertCount(1, $scenarios = $feature->getScenarios());
$this->assertSame('Scenario#3', $scenarios[0]->getTitle());
$this->assertCount(2, $scenarios[0]->getExampleTable()->getRows());
$this->assertSame(array(
array('action', 'outcome'),
array('act#3', 'out#3'),
), $scenarios[0]->getExampleTable()->getRows());
$filter = new LineFilter(18);
$feature = $filter->filterFeature($this->getParsedFeature());
$this->assertCount(1, $scenarios = $feature->getScenarios());
$this->assertSame('Scenario#3', $scenarios[0]->getTitle());
$this->assertCount(1, $scenarios[0]->getExampleTable()->getRows());
$this->assertSame(array(
array('action', 'outcome'),
), $scenarios[0]->getExampleTable()->getRows());
}
}

View File

@@ -0,0 +1,101 @@
<?php
namespace Tests\Behat\Gherkin\Filter;
use Behat\Gherkin\Filter\LineRangeFilter;
use Behat\Gherkin\Node\ExampleTableNode;
use Behat\Gherkin\Node\FeatureNode;
use Behat\Gherkin\Node\OutlineNode;
use Behat\Gherkin\Node\ScenarioNode;
class LineRangeFilterTest extends FilterTest
{
public function featureLineRangeProvider()
{
return array(
array('1', '1', true),
array('1', '2', true),
array('1', '*', true),
array('2', '2', false),
array('2', '*', false)
);
}
/**
* @dataProvider featureLineRangeProvider
*/
public function testIsFeatureMatchFilter($filterMinLine, $filterMaxLine, $expected)
{
$feature = new FeatureNode(null, null, array(), null, array(), null, null, null, 1);
$filter = new LineRangeFilter($filterMinLine, $filterMaxLine);
$this->assertSame($expected, $filter->isFeatureMatch($feature));
}
public function scenarioLineRangeProvider()
{
return array(
array('1', '2', 1),
array('1', '*', 2),
array('2', '2', 1),
array('2', '*', 2),
array('3', '3', 1),
array('3', '*', 1),
array('1', '1', 0),
array('4', '4', 0),
array('4', '*', 0)
);
}
/**
* @dataProvider scenarioLineRangeProvider
*/
public function testIsScenarioMatchFilter($filterMinLine, $filterMaxLine, $expectedNumberOfMatches)
{
$scenario = new ScenarioNode(null, array(), array(), null, 2);
$outline = new OutlineNode(null, array(), array(), new ExampleTableNode(array(), null), null, 3);
$filter = new LineRangeFilter($filterMinLine, $filterMaxLine);
$this->assertEquals(
$expectedNumberOfMatches,
intval($filter->isScenarioMatch($scenario)) + intval($filter->isScenarioMatch($outline))
);
}
public function testFilterFeatureScenario()
{
$filter = new LineRangeFilter(1, 3);
$feature = $filter->filterFeature($this->getParsedFeature());
$this->assertCount(1, $scenarios = $feature->getScenarios());
$this->assertSame('Scenario#1', $scenarios[0]->getTitle());
$filter = new LineRangeFilter(5, 9);
$feature = $filter->filterFeature($this->getParsedFeature());
$this->assertCount(1, $scenarios = $feature->getScenarios());
$this->assertSame('Scenario#2', $scenarios[0]->getTitle());
$filter = new LineRangeFilter(5, 6);
$feature = $filter->filterFeature($this->getParsedFeature());
$this->assertCount(0, $scenarios = $feature->getScenarios());
}
public function testFilterFeatureOutline()
{
$filter = new LineRangeFilter(12, 14);
$feature = $filter->filterFeature($this->getParsedFeature());
$this->assertCount(1, $scenarios = $feature->getScenarios());
$this->assertSame('Scenario#3', $scenarios[0]->getTitle());
$this->assertCount(1, $scenarios[0]->getExampleTable()->getRows());
$filter = new LineRangeFilter(15, 20);
$feature = $filter->filterFeature($this->getParsedFeature());
$this->assertCount(1, $scenarios = $feature->getScenarios());
$this->assertSame('Scenario#3', $scenarios[0]->getTitle());
$this->assertCount(3, $scenarios[0]->getExampleTable()->getRows());
$this->assertSame(array(
array('action', 'outcome'),
array('act#1', 'out#1'),
array('act#2', 'out#2'),
), $scenarios[0]->getExampleTable()->getRows());
}
}

View File

@@ -0,0 +1,79 @@
<?php
namespace Tests\Behat\Gherkin\Filter;
use Behat\Gherkin\Filter\NameFilter;
use Behat\Gherkin\Node\FeatureNode;
use Behat\Gherkin\Node\ScenarioNode;
class NameFilterTest extends \PHPUnit_Framework_TestCase
{
public function testFilterFeature()
{
$feature = new FeatureNode('feature1', null, array(), null, array(), null, null, null, 1);
$filter = new NameFilter('feature1');
$this->assertSame($feature, $filter->filterFeature($feature));
$scenarios = array(
new ScenarioNode('scenario1', array(), array(), null, 2),
$matchedScenario = new ScenarioNode('scenario2', array(), array(), null, 4)
);
$feature = new FeatureNode('feature1', null, array(), null, $scenarios, null, null, null, 1);
$filter = new NameFilter('scenario2');
$filteredFeature = $filter->filterFeature($feature);
$this->assertSame(array($matchedScenario), $filteredFeature->getScenarios());
}
public function testIsFeatureMatchFilter()
{
$feature = new FeatureNode('random feature title', null, array(), null, array(), null, null, null, 1);
$filter = new NameFilter('feature1');
$this->assertFalse($filter->isFeatureMatch($feature));
$feature = new FeatureNode('feature1', null, array(), null, array(), null, null, null, 1);
$this->assertTrue($filter->isFeatureMatch($feature));
$feature = new FeatureNode('feature1 title', null, array(), null, array(), null, null, null, 1);
$this->assertTrue($filter->isFeatureMatch($feature));
$feature = new FeatureNode('some feature1 title', null, array(), null, array(), null, null, null, 1);
$this->assertTrue($filter->isFeatureMatch($feature));
$feature = new FeatureNode('some feature title', null, array(), null, array(), null, null, null, 1);
$this->assertFalse($filter->isFeatureMatch($feature));
$filter = new NameFilter('/fea.ure/');
$this->assertTrue($filter->isFeatureMatch($feature));
$feature = new FeatureNode('some feaSure title', null, array(), null, array(), null, null, null, 1);
$this->assertTrue($filter->isFeatureMatch($feature));
$feature = new FeatureNode('some feture title', null, array(), null, array(), null, null, null, 1);
$this->assertFalse($filter->isFeatureMatch($feature));
}
public function testIsScenarioMatchFilter()
{
$filter = new NameFilter('scenario1');
$scenario = new ScenarioNode('UNKNOWN', array(), array(), null, 2);
$this->assertFalse($filter->isScenarioMatch($scenario));
$scenario = new ScenarioNode('scenario1', array(), array(), null, 2);
$this->assertTrue($filter->isScenarioMatch($scenario));
$scenario = new ScenarioNode('scenario1 title', array(), array(), null, 2);
$this->assertTrue($filter->isScenarioMatch($scenario));
$scenario = new ScenarioNode('some scenario title', array(), array(), null, 2);
$this->assertFalse($filter->isScenarioMatch($scenario));
$filter = new NameFilter('/sce.ario/');
$this->assertTrue($filter->isScenarioMatch($scenario));
$filter = new NameFilter('/scen.rio/');
$this->assertTrue($filter->isScenarioMatch($scenario));
}
}

View File

@@ -0,0 +1,34 @@
<?php
namespace Tests\Behat\Gherkin\Filter;
use Behat\Gherkin\Filter\NarrativeFilter;
use Behat\Gherkin\Node\FeatureNode;
class NarrativeFilterTest extends FilterTest
{
public function testIsFeatureMatchFilter()
{
$description = <<<NAR
In order to be able to read news in my own language
As a french user
I need to be able to switch website language to french
NAR;
$feature = new FeatureNode(null, $description, array(), null, array(), null, null, null, 1);
$filter = new NarrativeFilter('/as (?:a|an) french user/');
$this->assertFalse($filter->isFeatureMatch($feature));
$filter = new NarrativeFilter('/as (?:a|an) french user/i');
$this->assertTrue($filter->isFeatureMatch($feature));
$filter = new NarrativeFilter('/french .*/');
$this->assertTrue($filter->isFeatureMatch($feature));
$filter = new NarrativeFilter('/^french/');
$this->assertFalse($filter->isFeatureMatch($feature));
$filter = new NarrativeFilter('/user$/');
$this->assertFalse($filter->isFeatureMatch($feature));
}
}

View File

@@ -0,0 +1,58 @@
<?php
namespace Tests\Behat\Gherkin\Filter;
use Behat\Gherkin\Filter\PathsFilter;
use Behat\Gherkin\Node\FeatureNode;
class PathsFilterTest extends FilterTest
{
public function testIsFeatureMatchFilter()
{
$feature = new FeatureNode(null, null, array(), null, array(), null, null, __FILE__, 1);
$filter = new PathsFilter(array(__DIR__));
$this->assertTrue($filter->isFeatureMatch($feature));
$filter = new PathsFilter(array('/abc', '/def', dirname(__DIR__)));
$this->assertTrue($filter->isFeatureMatch($feature));
$filter = new PathsFilter(array('/abc', '/def', __DIR__));
$this->assertTrue($filter->isFeatureMatch($feature));
$filter = new PathsFilter(array('/abc', __DIR__, '/def'));
$this->assertTrue($filter->isFeatureMatch($feature));
$filter = new PathsFilter(array('/abc', '/def', '/wrong/path'));
$this->assertFalse($filter->isFeatureMatch($feature));
}
public function testItDoesNotMatchPartialPaths()
{
$fixtures = __DIR__ . DIRECTORY_SEPARATOR . 'Fixtures' . DIRECTORY_SEPARATOR;
$feature = new FeatureNode(null, null, array(), null, array(), null, null, $fixtures . 'full_path' . DIRECTORY_SEPARATOR . 'file1', 1);
$filter = new PathsFilter(array($fixtures . 'full'));
$this->assertFalse($filter->isFeatureMatch($feature));
$filter = new PathsFilter(array($fixtures . 'full' . DIRECTORY_SEPARATOR));
$this->assertFalse($filter->isFeatureMatch($feature));
$filter = new PathsFilter(array($fixtures . 'full_path' . DIRECTORY_SEPARATOR));
$this->assertTrue($filter->isFeatureMatch($feature));
$filter = new PathsFilter(array($fixtures . 'full_path'));
$this->assertTrue($filter->isFeatureMatch($feature));
}
public function testItDoesNotMatchIfFileWithSameNameButNotPathExistsInFolder()
{
$fixtures = __DIR__ . DIRECTORY_SEPARATOR . 'Fixtures' . DIRECTORY_SEPARATOR;
$feature = new FeatureNode(null, null, array(), null, array(), null, null, $fixtures . 'full_path' . DIRECTORY_SEPARATOR . 'file1', 1);
$filter = new PathsFilter(array($fixtures . 'full'));
$this->assertFalse($filter->isFeatureMatch($feature));
}
}

View File

@@ -0,0 +1,73 @@
<?php
namespace Tests\Behat\Gherkin\Filter;
use Behat\Gherkin\Filter\RoleFilter;
use Behat\Gherkin\Node\FeatureNode;
class RoleFilterTest extends FilterTest
{
public function testIsFeatureMatchFilter()
{
$description = <<<NAR
In order to be able to read news in my own language
As a french user
I need to be able to switch website language to french
NAR;
$feature = new FeatureNode(null, $description, array(), null, array(), null, null, null, 1);
$filter = new RoleFilter('french user');
$this->assertTrue($filter->isFeatureMatch($feature));
$filter = new RoleFilter('french *');
$this->assertTrue($filter->isFeatureMatch($feature));
$filter = new RoleFilter('french');
$this->assertFalse($filter->isFeatureMatch($feature));
$filter = new RoleFilter('user');
$this->assertFalse($filter->isFeatureMatch($feature));
$filter = new RoleFilter('*user');
$this->assertTrue($filter->isFeatureMatch($feature));
$filter = new RoleFilter('French User');
$this->assertTrue($filter->isFeatureMatch($feature));
$feature = new FeatureNode(null, null, array(), null, array(), null, null, null, 1);
$filter = new RoleFilter('French User');
$this->assertFalse($filter->isFeatureMatch($feature));
}
public function testFeatureRolePrefixedWithAn()
{
$description = <<<NAR
In order to be able to read news in my own language
As an american user
I need to be able to switch website language to french
NAR;
$feature = new FeatureNode(null, $description, array(), null, array(), null, null, null, 1);
$filter = new RoleFilter('american user');
$this->assertTrue($filter->isFeatureMatch($feature));
$filter = new RoleFilter('american *');
$this->assertTrue($filter->isFeatureMatch($feature));
$filter = new RoleFilter('american');
$this->assertFalse($filter->isFeatureMatch($feature));
$filter = new RoleFilter('user');
$this->assertFalse($filter->isFeatureMatch($feature));
$filter = new RoleFilter('*user');
$this->assertTrue($filter->isFeatureMatch($feature));
$filter = new RoleFilter('American User');
$this->assertTrue($filter->isFeatureMatch($feature));
$feature = new FeatureNode(null, null, array(), null, array(), null, null, null, 1);
$filter = new RoleFilter('American User');
$this->assertFalse($filter->isFeatureMatch($feature));
}
}

View File

@@ -0,0 +1,144 @@
<?php
namespace Tests\Behat\Gherkin\Filter;
use Behat\Gherkin\Filter\TagFilter;
use Behat\Gherkin\Node\FeatureNode;
use Behat\Gherkin\Node\ScenarioNode;
class TagFilterTest extends \PHPUnit_Framework_TestCase
{
public function testFilterFeature()
{
$feature = new FeatureNode(null, null, array('wip'), null, array(), null, null, null, 1);
$filter = new TagFilter('@wip');
$this->assertEquals($feature, $filter->filterFeature($feature));
$scenarios = array(
new ScenarioNode(null, array(), array(), null, 2),
$matchedScenario = new ScenarioNode(null, array('wip'), array(), null, 4)
);
$feature = new FeatureNode(null, null, array(), null, $scenarios, null, null, null, 1);
$filteredFeature = $filter->filterFeature($feature);
$this->assertSame(array($matchedScenario), $filteredFeature->getScenarios());
$filter = new TagFilter('~@wip');
$scenarios = array(
$matchedScenario = new ScenarioNode(null, array(), array(), null, 2),
new ScenarioNode(null, array('wip'), array(), null, 4)
);
$feature = new FeatureNode(null, null, array(), null, $scenarios, null, null, null, 1);
$filteredFeature = $filter->filterFeature($feature);
$this->assertSame(array($matchedScenario), $filteredFeature->getScenarios());
}
public function testIsFeatureMatchFilter()
{
$feature = new FeatureNode(null, null, array(), null, array(), null, null, null, 1);
$filter = new TagFilter('@wip');
$this->assertFalse($filter->isFeatureMatch($feature));
$feature = new FeatureNode(null, null, array('wip'), null, array(), null, null, null, 1);
$this->assertTrue($filter->isFeatureMatch($feature));
$filter = new TagFilter('~@done');
$this->assertTrue($filter->isFeatureMatch($feature));
$feature = new FeatureNode(null, null, array('wip', 'done'), null, array(), null, null, null, 1);
$this->assertFalse($filter->isFeatureMatch($feature));
$feature = new FeatureNode(null, null, array('tag1', 'tag2', 'tag3'), null, array(), null, null, null, 1);
$filter = new TagFilter('@tag5,@tag4,@tag6');
$this->assertFalse($filter->isFeatureMatch($feature));
$feature = new FeatureNode(null, null, array(
'tag1',
'tag2',
'tag3',
'tag5'
), null, array(), null, null, null, 1);
$this->assertTrue($filter->isFeatureMatch($feature));
$filter = new TagFilter('@wip&&@vip');
$feature = new FeatureNode(null, null, array('wip', 'done'), null, array(), null, null, null, 1);
$this->assertFalse($filter->isFeatureMatch($feature));
$feature = new FeatureNode(null, null, array('wip', 'done', 'vip'), null, array(), null, null, null, 1);
$this->assertTrue($filter->isFeatureMatch($feature));
$filter = new TagFilter('@wip,@vip&&@user');
$feature = new FeatureNode(null, null, array('wip'), null, array(), null, null, null, 1);
$this->assertFalse($filter->isFeatureMatch($feature));
$feature = new FeatureNode(null, null, array('vip'), null, array(), null, null, null, 1);
$this->assertFalse($filter->isFeatureMatch($feature));
$feature = new FeatureNode(null, null, array('wip', 'user'), null, array(), null, null, null, 1);
$this->assertTrue($filter->isFeatureMatch($feature));
$feature = new FeatureNode(null, null, array('vip', 'user'), null, array(), null, null, null, 1);
$this->assertTrue($filter->isFeatureMatch($feature));
}
public function testIsScenarioMatchFilter()
{
$feature = new FeatureNode(null, null, array('feature-tag'), null, array(), null, null, null, 1);
$scenario = new ScenarioNode(null, array(), array(), null, 2);
$filter = new TagFilter('@wip');
$this->assertFalse($filter->isScenarioMatch($feature, $scenario));
$filter = new TagFilter('~@done');
$this->assertTrue($filter->isScenarioMatch($feature, $scenario));
$scenario = new ScenarioNode(null, array(
'tag1',
'tag2',
'tag3'
), array(), null, 2);
$filter = new TagFilter('@tag5,@tag4,@tag6');
$this->assertFalse($filter->isScenarioMatch($feature, $scenario));
$scenario = new ScenarioNode(null, array(
'tag1',
'tag2',
'tag3',
'tag5'
), array(), null, 2);
$this->assertTrue($filter->isScenarioMatch($feature, $scenario));
$filter = new TagFilter('@wip&&@vip');
$scenario = new ScenarioNode(null, array('wip', 'not-done'), array(), null, 2);
$this->assertFalse($filter->isScenarioMatch($feature, $scenario));
$scenario = new ScenarioNode(null, array(
'wip',
'not-done',
'vip'
), array(), null, 2);
$this->assertTrue($filter->isScenarioMatch($feature, $scenario));
$filter = new TagFilter('@wip,@vip&&@user');
$scenario = new ScenarioNode(null, array(
'wip'
), array(), null, 2);
$this->assertFalse($filter->isScenarioMatch($feature, $scenario));
$scenario = new ScenarioNode(null, array('vip'), array(), null, 2);
$this->assertFalse($filter->isScenarioMatch($feature, $scenario));
$scenario = new ScenarioNode(null, array('wip', 'user'), array(), null, 2);
$this->assertTrue($filter->isScenarioMatch($feature, $scenario));
$filter = new TagFilter('@feature-tag&&@user');
$scenario = new ScenarioNode(null, array('wip', 'user'), array(), null, 2);
$this->assertTrue($filter->isScenarioMatch($feature, $scenario));
$filter = new TagFilter('@feature-tag&&@user');
$scenario = new ScenarioNode(null, array('wip'), array(), null, 2);
$this->assertFalse($filter->isScenarioMatch($feature, $scenario));
}
}

View File

@@ -0,0 +1,29 @@
feature:
title: Addition
language: en
line: 2
description: |-
In order to avoid silly mistakes
As a math idiot
I want to be told the sum of two numbers
scenarios:
-
type: scenario
title: Add two numbers
line: 7
steps:
- { keyword_type: 'Given', type: 'Given', text: 'I have entered 11 into the calculator', line: 8 }
- { keyword_type: 'Given', type: 'And', text: 'I have entered 12 into the calculator', line: 9 }
- { keyword_type: 'When', type: 'When', text: 'I press add', line: 10 }
- { keyword_type: 'Then', type: 'Then', text: 'the result should be 23 on the screen', line: 11 }
-
type: scenario
title: Div two numbers
line: 13
steps:
- { keyword_type: 'Given', type: 'Given', text: 'I have entered 10 into the calculator', line: 14 }
- { keyword_type: 'Given', type: 'And', text: 'I have entered 2 into the calculator', line: 15 }
- { keyword_type: 'When', type: 'When', text: 'I press div', line: 16 }
- { keyword_type: 'Then', type: 'Then', text: 'the result should be 5 on the screen', line: 17 }

View File

@@ -0,0 +1,18 @@
feature:
title: Feature with background
language: en
line: 1
description: ~
background:
line: 3
steps:
- { keyword_type: Given, type: Given, text: a passing step, line: 4 }
scenarios:
-
type: scenario
title: ~
line: 6
steps:
- { keyword_type: Given, type: Given, text: a failing step, line: 7 }

View File

@@ -0,0 +1,26 @@
feature:
title: Feature with titled background
language: en
line: 1
description: ~
background:
line: 3
title: |-
Some Background
title with
couple
of
| continuous |
"""
strings
steps:
- { keyword_type: Given, type: Given, text: a passing step, line: 10 }
scenarios:
-
type: scenario
title: ~
line: 12
steps:
- { keyword_type: Given, type: Given, text: a failing step, line: 13 }

View File

@@ -0,0 +1,18 @@
feature:
line: 1
title: Big PyString
scenarios:
-
type: scenario
line: 2
steps:
-
keyword_type: Then
type: Then
text: it should fail with:
line: 3
arguments:
-
type: pystring
text: "\n# language: ru\n\nUUUUUU\n\n2 scenarios (2 undefined)\n6 steps (6 undefined)\n\nYou can implement step definitions for undefined steps with these snippets:\n\n$steps->Given('/^I have entered (\\d+)$/', function($world, $arg1) {\n throw new \\Everzet\\Behat\\Exception\\Pending();\n});\n\n$steps->Then('/^I must have (\\d+)$/', function($world, $arg1) {\n throw new \\Everzet\\Behat\\Exception\\Pending();\n});\n\n$steps->Then('/^String must be \\'([^\\']*)\\'$/', function($world, $arg1) {\n throw new \\Everzet\\Behat\\Exception\\Pending();\n});"

View File

@@ -0,0 +1,20 @@
feature:
title: Feature N4
line: 1
description: ~
scenarios:
-
type: scenario
tags: [normal]
line: 4
steps:
- { keyword_type: 'Given', type: 'Given', text: 'Some normal step N41', line: 5 }
- { keyword_type: 'Given', type: 'And', text: 'Some fast step N42', line: 6 }
-
type: scenario
tags: [fast]
line: 9
steps:
- { keyword_type: 'Given', type: 'Given', text: 'Some slow step N43', line: 10 }

View File

@@ -0,0 +1,10 @@
feature:
title: Fibonacci
language: en
line: 1
description: |-
In order to calculate super fast fibonacci series
As a pythonista
I want to use Python for that
scenarios: ~

View File

@@ -0,0 +1,21 @@
feature:
title: Using the Console Formatter
language: en
line: 3
description: |-
In order to verify this error # comment
I want to run this feature using the progress format#comment
So that it can be fixed
scenarios:
-
type: scenario
title: "A normal feature #comment in scenario title"
line: 19
steps:
- { keyword_type: 'Given', type: 'Given', text: 'I have a pending step #comment', line: 21 }
- { keyword_type: 'When', type: 'When', text: 'I run this feature with the progress format #comment', line: 24 }
- { keyword_type: 'Then', type: 'Then', text: "I should get a no method error for 'backtrace_line'", line: 31 }

View File

@@ -0,0 +1,26 @@
feature:
title: Complex descriptions
language: en
line: 7
description: |-
Some description with
| table | row|
and
"""
"""
scenarios:
-
type: scenario
title: |-
Some
| complex | description |
"""
hell yeah
"""
line: 16
steps:
- { keyword_type: 'Given', type: 'Given', text: 'one two three', line: 22 }

View File

@@ -0,0 +1,7 @@
feature:
title: Some feature
language: en
line: 1
description: ~
scenarios: []

View File

@@ -0,0 +1,13 @@
feature:
title: Cucumber command line
language: en
line: 1
description: |-
In order to write better software
Developers should be able to execute requirements as tests
scenarios:
-
type: scenario
title: Pending Scenario at the end of a file with whitespace after it
line: 6

View File

@@ -0,0 +1,13 @@
feature:
title: Cucumber command line
language: en
line: 1
description: |-
In order to write better software
Developers should be able to execute requirements as tests
scenarios:
-
type: scenario
title: Pending Scenario at the end of a file with whitespace after it
line: 6

View File

@@ -0,0 +1,30 @@
feature:
title: Math
language: en
line: 1
description: |-
In order to avoid silly mistakes
As a math idiot
I want to be told the calculation of two numbers
scenarios:
-
type: scenario
title: Add two numbers
line: 6
steps: []
-
type: scenario
title: Div two numbers
line: 7
steps: []
-
type: scenario
title: Multiply two numbers
line: 9
steps: []
-
type: scenario
title: Sub two numbers
line: 12
steps: []

View File

@@ -0,0 +1,27 @@
feature:
title: Fibonacci
language: en
line: 1
description: |-
In order to calculate super fast fibonacci series
As a pythonista
I want to use Python for that
scenarios:
-
type: outline
title: Series
line: 6
steps:
- { keyword_type: 'When', type: 'When', text: 'I ask python to calculate fibonacci up to <n>', line: 7 }
- { keyword_type: 'Then', type: 'Then', text: 'it should give me <series>', line: 8 }
examples:
11: [ n , series ]
12: [ 1 , '[]' ]
13: [ 2 , '[1, 1]' ]
14: [ 3 , '[1, 1, 2]' ]
15: [ 4 , '[1, 1, 2, 3]' ]
16: [ 6 , '[1, 1, 2, 3, 5]' ]
17: [ 9 , '[1, 1, 2, 3, 5, 8]' ]
18: [ 100 , '[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]' ]

View File

@@ -0,0 +1,29 @@
feature:
title: "Some '#quoted' string"
language: en
line: 2
description: |-
In order to avoid silly mistakes
As a "#math" idiot
I want to be told the sum of two numbers
scenarios:
-
type: scenario
title: Add two numbers
line: 7
steps:
- { keyword_type: 'Given', type: 'Given', text: 'I have entered 11 into the calculator', line: 8 }
- { keyword_type: 'Given', type: 'And', text: 'I have entered 12 into the calculator', line: 9 }
- { keyword_type: 'When', type: 'When', text: 'I press "#add"', line: 10 }
- { keyword_type: 'Then', type: 'Then', text: 'the result should be 23 on the screen', line: 11 }
-
type: scenario
title: 'Div "#two" numbers # as'
line: 13
steps:
- { keyword_type: 'Given', type: 'Given', text: 'I have entered 10 into the calculator', line: 14 }
- { keyword_type: 'Given', type: 'And', text: 'I have entered # 2 into the calculator', line: 15 }
- { keyword_type: 'When', type: 'When', text: 'I press div', line: 16 }
- { keyword_type: 'Then', type: 'Then', text: 'the result should be 5 on the screen', line: 17 }

View File

@@ -0,0 +1,49 @@
feature:
title: test pystring
description: second line
language: en
line: 1
scenarios:
-
type: scenario
title: |-
testing py string in scenario
second line
line: 4
steps:
-
keyword_type: Given
type: Given
text: the pystring is
line: 7
arguments:
-
type: pystring
text: |-
Test store name
Denmark, Kolding
6000
-
type: outline
title: |-
testing py string in scenario outline
second line
line: 14
steps:
-
keyword_type: Given
type: Given
text: the pystring is
line: 17
arguments:
arguments:
-
type: pystring
text: |-
Test store name
Denmark, Kolding
6000
examples:
24: ['']

View File

@@ -0,0 +1,21 @@
feature:
title: '加算'
keyword: 'フィーチャ'
language: ja
line: 2
description: |-
バカな間違いを避けるために
数学オンチとして
2つの数の合計を知りたい
scenarios:
-
type: scenario
keyword: 'シナリオ'
title: '2つの数の加算について'
line: 7
steps:
- { keyword_type: 'Given', type: '前提', text: '50 を入力', line: 8 }
- { keyword_type: 'Given', type: 'かつ', text: '70 を入力', line: 9 }
- { keyword_type: 'When', type: 'もし', text: 'add ボタンを押した', line: 10 }
- { keyword_type: 'Then', type: 'ならば', text: '結果は 120 を表示', line: 11 }

View File

@@ -0,0 +1,13 @@
feature:
title: https://rspec.lighthouseapp.com/projects/16211/tickets/246-distorted-console-output-for-slightly-complicated-step-regexp-match
language: en
line: 1
description: ~
scenarios:
-
type: scenario
title: See "No Record(s) Found" for Zero Existing
line: 3
steps:
- { keyword_type: Given, type: Given, text: no public holiday exists in the system, line: 4 }

View File

@@ -0,0 +1,44 @@
feature:
title: multiline
language: en
line: 1
description: ~
background:
line: 3
steps:
- { keyword_type: Given, type: Given, text: passing without a table, line: 4 }
scenarios:
-
type: scenario
title: |-
I'm a multiline name
which goes on and on and on for three lines
yawn
line: 6
steps:
- { keyword_type: Given, type: Given, text: passing without a table, line: 9 }
-
type: outline
title: |-
I'm a multiline name
which goes on and on and on for three lines
yawn
line: 11
steps:
- { keyword_type: Given, type: 'Given', text: '<state> without a table', line: 14 }
examples:
16: [state]
17: [passing]
-
type: outline
title: name
line: 19
steps:
- { keyword_type: Given, type: 'Given', text: '<state> without a table', line: 20 }
examples:
22: [state]
23: [passing]

View File

@@ -0,0 +1,65 @@
feature:
title: multiline
language: en
line: 1
description: |-
Feature description
With etc.
background:
line: 8
steps:
- { keyword_type: Given, type: Given, text: passing without a table, line: 11 }
scenarios:
-
type: scenario
title: |-
I'm a multiline name
which goes on and on and on for three lines
yawn
line: 13
steps:
- { keyword_type: Given, type: Given, text: passing without a table, line: 19 }
-
type: outline
title: |-
I'm a multiline name
which goes on and on and on for three lines
yawn
line: 21
steps:
- { keyword_type: 'Given', type: 'Given', text: '<state> without a table', line: 28 }
examples:
34: [state]
35: [passing]
-
type: outline
title: name
line: 37
steps:
- { keyword_type: 'Given', type: 'Given', text: '<state> without a table', line: 40 }
examples:
45: [state]
46: [passing]
-
type: outline
title: |-
I'm a multiline name
which goes on and on and on for three lines
yawn
line: 48
steps:
- { keyword_type: 'Given', type: 'Given', text: '<state> without a table', line: 55 }
examples:
60: [state]
61: [passing]

View File

@@ -0,0 +1,47 @@
feature:
title: A multiple py string feature
line: 1
language: en
description: ~
scenarios:
-
type: scenario
title: ~
line: 3
steps:
-
keyword_type: When
type: When
text: I enter a string
line: 4
arguments:
-
type: pystring
text: |-
-
a string
with something
be
a
u
ti
ful
-
keyword_type: Then
type: Then
text: String must be
line: 15
arguments:
-
type: pystring
text: |-
-
a string
with something
be
a
u
ti
ful

View File

@@ -0,0 +1,33 @@
feature:
title: Login
language: en
line: 1
description: |-
To ensure the safety of the application
A regular user of the system
Must authenticate before using the app
scenarios:
-
type: outline
title: Failed Login
line: 7
steps:
- { keyword_type: 'Given', type: 'Given', text: 'the user "known_user"', line: 8 }
- { keyword_type: 'When', type: 'When', text: 'I go to the main page', line: 10 }
- { keyword_type: 'Then', type: 'Then', text: 'I should see the login form', line: 11 }
- { keyword_type: 'When', type: 'When', text: 'I fill in "login" with "<login>"', line: 13 }
- { keyword_type: 'When', type: 'And', text: 'I fill in "password" with "<password>"', line: 14 }
- { keyword_type: 'When', type: 'And', text: 'I press "Log In"', line: 15 }
- { keyword_type: 'Then', type: 'Then', text: 'the login request should fail', line: 16 }
- { keyword_type: 'Then', type: 'And', text: 'I should see the error message "Login or Password incorrect"', line: 17 }
examples:
20: [login, password]
21: ['', '']
22: [unknown_user, '']
23: [known_user, '']
24: ['', wrong_password]
25: ['', known_userpass]
26: [unknown_user, wrong_password]
27: [unknown_user, known_userpass]
28: [known_user, wrong_password]

View File

@@ -0,0 +1,29 @@
feature:
title: Unsubstituted argument placeholder
language: en
line: 1
description: ~
scenarios:
-
type: outline
title: 'See Annual Leave Details (as Management & Human Resource)'
line: 3
steps:
-
keyword_type: Given
type: Given
text: the following users exist in the system
line: 4
arguments:
-
type: table
rows:
5: [ name, email, role_assignments, group_memberships ]
6: [ Jane, jane@fmail.com, <role>, Sales (manager) ]
7: [ Max, max@fmail.com, '', Sales (member) ]
8: [ Carol, carol@fmail.com, '', Sales (member) ]
9: [ Cat, cat@fmail.com, '', '' ]
examples:
12: [ role ]
13: [ HUMAN RESOURCE ]

View File

@@ -0,0 +1,22 @@
feature:
title: A py string feature
language: en
line: 1
description: ~
scenarios:
-
type: scenario
title: ~
line: 3
steps:
-
keyword_type: Then
type: Then
text: I should see
line: 4
arguments:
-
type: pystring
swallow: 6
text: "a string with #something"

View File

@@ -0,0 +1,21 @@
feature:
title: Сложение чисел
keyword: Функционал
language: ru
line: 2
description: |-
Чтобы не складывать в уме
Все, у кого с этим туго
Хотят автоматическое сложение целых чисел
scenarios:
-
type: scenario
keyword: Сценарий
title: Сложение двух целых чисел
line: 7
steps:
- { keyword_type: 'Given', type: 'Допустим', text: 'я ввожу число 50', line: 8 }
- { keyword_type: 'Given', type: 'И', text: 'затем ввожу число 70', line: 9 }
- { keyword_type: 'Then', type: 'Если', text: 'я нажимаю "+"', line: 10 }
- { keyword_type: 'When', type: 'То', text: 'результатом должно быть число 120', line: 11 }

View File

@@ -0,0 +1,11 @@
feature:
title: Тест комментов
keyword: Функционал
language: ru
line: 7
description: |-
i18n должен правильно считываться
Даже если в начале файла 1000
комментов!
scenarios: ~

View File

@@ -0,0 +1,34 @@
feature:
title: Последовательные вычисления
keyword: Функционал
language: ru
line: 2
description: |-
Чтобы вычислять сложные выражения
Пользователи хотят проводить вычисления над результатом предыдущей операций
background:
keyword: Предыстория
line: 6
steps:
- { keyword_type: Given, type: Допустим, text: я сложил 3 и 5, line: 7 }
scenarios:
-
type: scenario
keyword: Сценарий
title: сложение с результатом последней операций
line: 9
steps:
- { keyword_type: Then, type: Если, text: 'я ввожу число 4', line: 10 }
- { keyword_type: Then, type: И, text: 'нажимаю "+"', line: 11 }
- { keyword_type: When, type: То, text: 'результатом должно быть число 12', line: 12 }
-
type: scenario
keyword: Сценарий
title: деление результата последней операции
line: 14
steps:
- { keyword_type: Then, type: Если, text: 'я ввожу число 2', line: 15 }
- { keyword_type: Then, type: И, text: 'нажимаю "/"', line: 16 }
- { keyword_type: When, type: То, text: 'результатом должно быть число 4', line: 17 }

View File

@@ -0,0 +1,27 @@
feature:
title: Деление чисел
keyword: Функционал
language: ru
line: 2
description: |-
Поскольку деление сложный процесс и люди часто допускают ошибки
Нужно дать им возможность делить на калькуляторе
scenarios:
-
type: outline
keyword: Структура сценария
title: Целочисленное деление
line: 6
steps:
- { keyword_type: Given, type: 'Допустим', text: 'я ввожу число <делимое>', line: 7 }
- { keyword_type: Given, type: 'И', text: 'затем ввожу число <делитель>', line: 8 }
- { keyword_type: Then, type: 'Если', text: 'я нажимаю "/"', line: 9 }
- { keyword_type: When, type: 'То', text: 'результатом должно быть число <частное>', line: 10 }
examples:
keyword: Значения
13: [делимое, делитель, частное]
14: [100, 2, 50]
15: [28, 7, 4]
16: [0, 5, 0]

View File

@@ -0,0 +1,18 @@
feature:
title: Using the Console Formatter
language: en
line: 3
description: |-
In order to verify this error
I want to run this feature using the progress format
So that it can be fixed
scenarios:
-
type: scenario
title: A normal feature
line: 8
steps:
- { keyword_type: 'Given', type: 'Given', text: 'I have a pending step', line: 9 }
- { keyword_type: 'When', type: 'When', text: 'I run this feature with the progress format', line: 10 }
- { keyword_type: 'Then', type: 'Then', text: "I should get a no method error for 'backtrace_line'", line: 11 }

View File

@@ -0,0 +1,42 @@
feature:
title: A scenario outline
language: en
line: 1
description: ~
scenarios:
-
type: outline
title: ~
line: 3
steps:
- { keyword_type: Given, type: Given, text: I add <a> and <b>, line: 4 }
-
keyword_type: When
type: When
text: I pass a table argument
line: 6
arguments:
-
type: table
rows:
7: [foo, bar]
8: [bar, baz]
- { keyword_type: Then, type: Then, text: I the result should be <c>, line: 10 }
-
keyword_type: Then
type: And
text: the table should be properly escaped:
line: 12
arguments:
-
type: table
rows:
13: ['|a', b, c]
14: [1, '|2', 3]
15: [2, 3, '|4']
examples:
18: [ a, b, c ]
19: [ 1, '|2', 3 ]
20: [ 2, 3, 4 ]

View File

@@ -0,0 +1,35 @@
feature:
title: Tag samples
language: en
tags: [sample_one]
line: 2
description: ~
scenarios:
-
type: scenario
title: Passing
tags: [sample_two, sample_four]
line: 5
steps:
- { keyword_type: 'Given', type: 'Given', text: 'missing', line: 6 }
-
type: outline
title: ~
tags: [sample_three]
line: 9
steps:
- { keyword_type: 'Given', type: 'Given', text: '<state>', line: 10 }
examples:
12: [state]
13: [missing]
-
type: scenario
title: Skipped
tags: [sample_three, sample_four]
line: 16
steps:
- { keyword_type: 'Given', type: 'Given', text: 'missing', line: 17 }

View File

@@ -0,0 +1,18 @@
feature:
title: Test::Unit
language: en
line: 1
description: |-
In order to please people who like Test::Unit
As a Cucumber user
I want to be able to use assert* in my step definitions
scenarios:
-
type: scenario
title: assert_equal
line: 6
steps:
- { keyword_type: 'Given', type: 'Given', text: 'x = 5', line: 7 }
- { keyword_type: 'Given', type: 'And', text: 'y = 5', line: 8 }
- { keyword_type: 'Then', type: 'Then', text: 'I can assert that x == y', line: 9 }

View File

@@ -0,0 +1,29 @@
feature:
title: A py string feature
language: en
line: 1
description: ~
scenarios:
-
type: scenario
title: ~
line: 3
steps:
-
keyword_type: Then
type: Then
text: String must be
line: 4
arguments:
-
type: pystring
text: |-
-
a string
with something
be
a
u
ti
ful

View File

@@ -0,0 +1,38 @@
feature:
title: undefined multiline args
language: en
line: 1
description: ~
scenarios:
-
type: scenario
title: pystring
line: 3
steps:
-
keyword_type: Given
type: Given
text: a pystring
line: 4
arguments:
-
type: pystring
text: ' example'
-
type: scenario
title: table
line: 9
steps:
-
keyword_type: Given
type: Given
text: a table
line: 10
arguments:
-
type: table
rows:
11: [table]
12: [example]

View File

@@ -0,0 +1,17 @@
# language: en
Feature: Addition
In order to avoid silly mistakes
As a math idiot
I want to be told the sum of two numbers
Scenario: Add two numbers
Given I have entered 11 into the calculator
And I have entered 12 into the calculator
When I press add
Then the result should be 23 on the screen
Scenario: Div two numbers
Given I have entered 10 into the calculator
And I have entered 2 into the calculator
When I press div
Then the result should be 5 on the screen

View File

@@ -0,0 +1,7 @@
Feature: Feature with background
Background:
Given a passing step
Scenario:
Given a failing step

View File

@@ -0,0 +1,13 @@
Feature: Feature with titled background
Background: Some Background
title with
couple
of
| continuous |
"""
strings
Given a passing step
Scenario:
Given a failing step

View File

@@ -0,0 +1,26 @@
Feature: Big PyString
Scenario:
Then it should fail with:
"""
# language: ru
UUUUUU
2 scenarios (2 undefined)
6 steps (6 undefined)
You can implement step definitions for undefined steps with these snippets:
$steps->Given('/^I have entered (\d+)$/', function($world, $arg1) {
throw new \Everzet\Behat\Exception\Pending();
});
$steps->Then('/^I must have (\d+)$/', function($world, $arg1) {
throw new \Everzet\Behat\Exception\Pending();
});
$steps->Then('/^String must be \'([^\']*)\'$/', function($world, $arg1) {
throw new \Everzet\Behat\Exception\Pending();
});
"""

View File

@@ -0,0 +1,10 @@
Feature: Feature N4
@normal
Scenario:
Given Some normal step N41
And Some fast step N42
@fast
Scenario:
Given Some slow step N43

View File

@@ -0,0 +1,34 @@
Feature: Fibonacci
In order to calculate super fast fibonacci series
As a pythonista
I want to use Python for that
#
# Background:
# Given passing without a table
#
# Scenario: I'm a multiline name
# which goes on and on and on for three lines
# yawn
# Given passing without a table
#
# Scenario:
# Then I should see
# """
# a string with #something
# """
#
# Scenario Outline: Series
# When I ask python to calculate fibonacci up to <n>
# Then it should give me <series>
#
# Examples:
# | n | series |
# | 1 | [] |
# | 2 | [1, 1] |
# | 3 | [1, 1, 2] |
# | 4 | [1, 1, 2, 3] |
# | 6 | [1, 1, 2, 3, 5] |
# | 9 | [1, 1, 2, 3, 5, 8] |
# | 100 | [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89] |
#

View File

@@ -0,0 +1,32 @@
# Users want to use cucumber, so tests are necessary to verify
# it is all working as expected
Feature: Using the Console Formatter
# com
# comment
#com
In order to verify this error # comment
I want to run this feature using the progress format#comment
# COMMENT
# COMMENT
# COMMENT
# COMMENT
So that it can be fixed
#comment
Scenario: A normal feature #comment in scenario title
#comment
Given I have a pending step #comment
#comment
#comment
When I run this feature with the progress format #comment
#comment
#comment
#comment
Then I should get a no method error for 'backtrace_line'

View File

@@ -0,0 +1,22 @@
# language: en
# multiline
# comment
# YEAH
Feature: Complex descriptions
Some description with
| table | row|
and
"""
"""
Scenario: Some
| complex | description |
"""
hell yeah
"""
Given one two three

View File

@@ -0,0 +1,2 @@
Feature: Some feature
#

View File

@@ -0,0 +1,7 @@
Feature: Cucumber command line
In order to write better software
Developers should be able to execute requirements as tests
Scenario: Pending Scenario at the end of a file with whitespace after it

View File

@@ -0,0 +1,7 @@
Feature: Cucumber command line
In order to write better software
Developers should be able to execute requirements as tests
Scenario: Pending Scenario at the end of a file with whitespace after it
#

View File

@@ -0,0 +1,12 @@
Feature: Math
In order to avoid silly mistakes
As a math idiot
I want to be told the calculation of two numbers
Scenario: Add two numbers
Scenario: Div two numbers
Scenario: Multiply two numbers
Scenario: Sub two numbers

View File

@@ -0,0 +1,19 @@
Feature: Fibonacci
In order to calculate super fast fibonacci series
As a pythonista
I want to use Python for that
Scenario Outline: Series
When I ask python to calculate fibonacci up to <n>
Then it should give me <series>
Examples:
| n | series |
| 1 | [] |
| 2 | [1, 1] |
| 3 | [1, 1, 2] |
| 4 | [1, 1, 2, 3] |
| 6 | [1, 1, 2, 3, 5] |
| 9 | [1, 1, 2, 3, 5, 8] |
| 100 | [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89] |

View File

@@ -0,0 +1,17 @@
# language: en
Feature: Some '#quoted' string
In order to avoid silly mistakes
As a "#math" idiot
I want to be told the sum of two numbers
Scenario: Add two numbers
Given I have entered 11 into the calculator
And I have entered 12 into the calculator
When I press "#add"
Then the result should be 23 on the screen
Scenario: Div "#two" numbers # as
Given I have entered 10 into the calculator
And I have entered # 2 into the calculator
When I press div
Then the result should be 5 on the screen

View File

@@ -0,0 +1,24 @@
Feature: test pystring
second line
Scenario: testing py string in scenario
second line
Given the pystring is
"""
Test store name
Denmark, Kolding
6000
"""
Scenario Outline: testing py string in scenario outline
second line
Given the pystring is
"""
Test store name
Denmark, Kolding
6000
"""
Examples:
||

View File

@@ -0,0 +1,11 @@
# language: ja
フィーチャ: 加算
2
シナリオ: 2つの数の加算について
前提 50
かつ 70
もし add
ならば 120

View File

@@ -0,0 +1,4 @@
Feature: https://rspec.lighthouseapp.com/projects/16211/tickets/246-distorted-console-output-for-slightly-complicated-step-regexp-match
Scenario: See "No Record(s) Found" for Zero Existing
Given no public holiday exists in the system

View File

@@ -0,0 +1,23 @@
Feature: multiline
Background:
Given passing without a table
Scenario: I'm a multiline name
which goes on and on and on for three lines
yawn
Given passing without a table
Scenario Outline: I'm a multiline name
which goes on and on and on for three lines
yawn
Given <state> without a table
Examples:
| state |
|passing|
Scenario Outline: name
Given <state> without a table
Examples:
| state |
|passing|

View File

@@ -0,0 +1,61 @@
Feature: multiline
Feature description
With etc.
Background:
Given passing without a table
Scenario:
I'm a multiline name
which goes on and on and on for three lines
yawn
Given passing without a table
Scenario Outline: I'm a multiline name
which goes on and on and on for three lines
yawn
Given <state> without a table
Examples:
| state |
|passing|
Scenario Outline: name
Given <state> without a table
Examples:
| state |
|passing|
Scenario Outline:
I'm a multiline name
which goes on and on and on for three lines
yawn
Given <state> without a table
Examples:
| state |
|passing|

View File

@@ -0,0 +1,25 @@
Feature: A multiple py string feature
Scenario:
When I enter a string
"""
-
a string
with something
be
a
u
ti
ful
"""
Then String must be
"""
-
a string
with something
be
a
u
ti
ful
"""

View File

@@ -0,0 +1,28 @@
Feature: Login
To ensure the safety of the application
A regular user of the system
Must authenticate before using the app
Scenario Outline: Failed Login
Given the user "known_user"
When I go to the main page
Then I should see the login form
When I fill in "login" with "<login>"
And I fill in "password" with "<password>"
And I press "Log In"
Then the login request should fail
And I should see the error message "Login or Password incorrect"
Examples:
| login | password |
| | |
| unknown_user | |
| known_user | |
| | wrong_password |
| | known_userpass |
| unknown_user | wrong_password |
| unknown_user | known_userpass |
| known_user | wrong_password |

View File

@@ -0,0 +1,13 @@
Feature: Unsubstituted argument placeholder
Scenario Outline: See Annual Leave Details (as Management & Human Resource)
Given the following users exist in the system
| name | email | role_assignments | group_memberships |
| Jane | jane@fmail.com | <role> | Sales (manager) |
| Max | max@fmail.com | | Sales (member) |
| Carol | carol@fmail.com | | Sales (member) |
| Cat | cat@fmail.com | | |
Examples:
| role |
| HUMAN RESOURCE |

View File

@@ -0,0 +1,8 @@
Feature: A py string feature
Scenario:
Then I should see
"""
a string with #something
"""

View File

@@ -0,0 +1,11 @@
# language: ru
Функционал: Сложение чисел
Чтобы не складывать в уме
Все, у кого с этим туго
Хотят автоматическое сложение целых чисел
Сценарий: Сложение двух целых чисел
Допустим я ввожу число 50
И затем ввожу число 70
Если я нажимаю "+"
То результатом должно быть число 120

View File

@@ -0,0 +1,10 @@
# Comments
# comments
# COOOOOMMEEEENTS
#
# language: ru
Функционал: Тест комментов
i18n должен правильно считываться
Даже если в начале файла 1000
комментов!

View File

@@ -0,0 +1,17 @@
# language: ru
Функционал: Последовательные вычисления
Чтобы вычислять сложные выражения
Пользователи хотят проводить вычисления над результатом предыдущей операций
Предыстория:
Допустим я сложил 3 и 5
Сценарий: сложение с результатом последней операций
Если я ввожу число 4
И нажимаю "+"
То результатом должно быть число 12
Сценарий: деление результата последней операции
Если я ввожу число 2
И нажимаю "/"
То результатом должно быть число 4

View File

@@ -0,0 +1,16 @@
# language: ru
Функционал: Деление чисел
Поскольку деление сложный процесс и люди часто допускают ошибки
Нужно дать им возможность делить на калькуляторе
Структура сценария: Целочисленное деление
Допустим я ввожу число <делимое>
И затем ввожу число <делитель>
Если я нажимаю "/"
То результатом должно быть число <частное>
Значения:
| делимое | делитель | частное |
| 100 | 2 | 50 |
| 28 | 7 | 4 |
| 0 | 5 | 0 |

View File

@@ -0,0 +1,12 @@
# Users want to use cucumber, so tests are necessary to verify
# it is all working as expected
Feature: Using the Console Formatter
In order to verify this error
I want to run this feature using the progress format
So that it can be fixed
Scenario: A normal feature
Given I have a pending step
When I run this feature with the progress format
Then I should get a no method error for 'backtrace_line'

View File

@@ -0,0 +1,20 @@
Feature: A scenario outline
# COMMENT
Scenario Outline:
Given I add <a> and <b>
# comment
When I pass a table argument
| foo | bar |
| bar | baz |
#comment
Then I the result should be <c>
# comment
And the table should be properly escaped:
| \|a | b | c |
| 1 | \|2 | 3 |
| 2 | 3 | \|4 |
#comment
Examples:
| a | b | c |
| 1 | \|2 | 3 |
| 2 | 3 | 4 |

View File

@@ -0,0 +1,17 @@
@sample_one
Feature: Tag samples
@sample_two @sample_four
Scenario: Passing
Given missing
@sample_three
Scenario Outline:
Given <state>
Examples:
|state|
|missing|
@sample_three @sample_four
Scenario: Skipped
Given missing

View File

@@ -0,0 +1,9 @@
Feature: Test::Unit
In order to please people who like Test::Unit
As a Cucumber user
I want to be able to use assert* in my step definitions
Scenario: assert_equal
Given x = 5
And y = 5
Then I can assert that x == y

View File

@@ -0,0 +1,14 @@
Feature: A py string feature
Scenario:
Then String must be
"""
-
a string
with something
be
a
u
ti
ful
"""

View File

@@ -0,0 +1,12 @@
Feature: undefined multiline args
Scenario: pystring
Given a pystring
"""
example
"""
Scenario: table
Given a table
| table |
|example|

View File

@@ -0,0 +1,606 @@
#
# !!! DON'T TOUCH THIS FILE, IT WAS AUTODOWNLOADED FROM:
# https://github.com/cucumber/gherkin/blob/master/lib/gherkin/i18n.yml
#
# encoding: UTF-8
#
# We use ISO 639-1 (language) and ISO 3166 alpha-2 (region - if applicable):
# http://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
# http://en.wikipedia.org/wiki/ISO_3166-1
#
# If you want several aliases for a keyword, just separate them
# with a | character. The * is a step keyword alias for all translations.
#
# If you do *not* want a trailing space after a keyword, end it with a < character.
# (See Chinese for examples).
#
"en":
name: English
native: English
feature: Feature
background: Background
scenario: Scenario
scenario_outline: Scenario Outline|Scenario Template
examples: Examples|Scenarios
given: "*|Given"
when: "*|When"
then: "*|Then"
and: "*|And"
but: "*|But"
# Please keep the grammars in alphabetical order by name from here and down.
"ar":
name: Arabic
native: العربية
feature: خاصية
background: الخلفية
scenario: سيناريو
scenario_outline: سيناريو مخطط
examples: امثلة
given: "*|بفرض"
when: "*|متى|عندما"
then: "*|اذاً|ثم"
and: "*|و"
but: "*|لكن"
"bg":
name: Bulgarian
native: български
feature: Функционалност
background: Предистория
scenario: Сценарий
scenario_outline: Рамка на сценарий
examples: Примери
given: "*|Дадено"
when: "*|Когато"
then: "*|То"
and: "*|И"
but: "*|Но"
"ca":
name: Catalan
native: català
background: Rerefons|Antecedents
feature: Característica|Funcionalitat
scenario: Escenari
scenario_outline: Esquema de l'escenari
examples: Exemples
given: "*|Donat|Donada|Atès|Atesa"
when: "*|Quan"
then: "*|Aleshores|Cal"
and: "*|I"
but: "*|Però"
"cy-GB":
name: Welsh
native: Cymraeg
background: Cefndir
feature: Arwedd
scenario: Scenario
scenario_outline: Scenario Amlinellol
examples: Enghreifftiau
given: "*|Anrhegedig a"
when: "*|Pryd"
then: "*|Yna"
and: "*|A"
but: "*|Ond"
"cs":
name: Czech
native: Česky
feature: Požadavek
background: Pozadí|Kontext
scenario: Scénář
scenario_outline: Náčrt Scénáře|Osnova scénáře
examples: Příklady
given: "*|Pokud"
when: "*|Když"
then: "*|Pak"
and: "*|A také|A"
but: "*|Ale"
"da":
name: Danish
native: dansk
feature: Egenskab
background: Baggrund
scenario: Scenarie
scenario_outline: Abstrakt Scenario
examples: Eksempler
given: "*|Givet"
when: "*|Når"
then: "*|Så"
and: "*|Og"
but: "*|Men"
"de":
name: German
native: Deutsch
feature: Funktionalität
background: Grundlage
scenario: Szenario
scenario_outline: Szenariogrundriss
examples: Beispiele
given: "*|Angenommen|Gegeben sei"
when: "*|Wenn"
then: "*|Dann"
and: "*|Und"
but: "*|Aber"
"en-au":
name: Australian
native: Australian
feature: Crikey
background: Background
scenario: Mate
scenario_outline: Blokes
examples: Cobber
given: "*|Ya know how"
when: "*|When"
then: "*|Ya gotta"
and: "*|N"
but: "*|Cept"
"en-lol":
name: LOLCAT
native: LOLCAT
feature: OH HAI
background: B4
scenario: MISHUN
scenario_outline: MISHUN SRSLY
examples: EXAMPLZ
given: "*|I CAN HAZ"
when: "*|WEN"
then: "*|DEN"
and: "*|AN"
but: "*|BUT"
"en-pirate":
name: Pirate
native: Pirate
feature: Ahoy matey!
background: Yo-ho-ho
scenario: Heave to
scenario_outline: Shiver me timbers
examples: Dead men tell no tales
given: "*|Gangway!"
when: "*|Blimey!"
then: "*|Let go and haul"
and: "*|Aye"
but: "*|Avast!"
"en-Scouse":
name: Scouse
native: Scouse
feature: Feature
background: "Dis is what went down"
scenario: "The thing of it is"
scenario_outline: "Wharrimean is"
examples: Examples
given: "*|Givun|Youse know when youse got"
when: "*|Wun|Youse know like when"
then: "*|Dun|Den youse gotta"
and: "*|An"
but: "*|Buh"
"en-tx":
name: Texan
native: Texan
feature: Feature
background: Background
scenario: Scenario
scenario_outline: All y'all
examples: Examples
given: "*|Given y'all"
when: "*|When y'all"
then: "*|Then y'all"
and: "*|And y'all"
but: "*|But y'all"
"eo":
name: Esperanto
native: Esperanto
feature: Trajto
background: Fono
scenario: Scenaro
scenario_outline: Konturo de la scenaro
examples: Ekzemploj
given: "*|Donitaĵo"
when: "*|Se"
then: "*|Do"
and: "*|Kaj"
but: "*|Sed"
"es":
name: Spanish
native: español
background: Antecedentes
feature: Característica
scenario: Escenario
scenario_outline: Esquema del escenario
examples: Ejemplos
given: "*|Dado|Dada|Dados|Dadas"
when: "*|Cuando"
then: "*|Entonces"
and: "*|Y"
but: "*|Pero"
"et":
name: Estonian
native: eesti keel
feature: Omadus
background: Taust
scenario: Stsenaarium
scenario_outline: Raamstsenaarium
examples: Juhtumid
given: "*|Eeldades"
when: "*|Kui"
then: "*|Siis"
and: "*|Ja"
but: "*|Kuid"
"fi":
name: Finnish
native: suomi
feature: Ominaisuus
background: Tausta
scenario: Tapaus
scenario_outline: Tapausaihio
examples: Tapaukset
given: "*|Oletetaan"
when: "*|Kun"
then: "*|Niin"
and: "*|Ja"
but: "*|Mutta"
"fr":
name: French
native: français
feature: Fonctionnalité
background: Contexte
scenario: Scénario
scenario_outline: Plan du scénario|Plan du Scénario
examples: Exemples
given: "*|Soit|Etant donné|Etant donnée|Etant donnés|Etant données|Étant donné|Étant donnée|Étant donnés|Étant données"
when: "*|Quand|Lorsque|Lorsqu'<"
then: "*|Alors"
and: "*|Et"
but: "*|Mais"
"he":
name: Hebrew
native: עברית
feature: תכונה
background: רקע
scenario: תרחיש
scenario_outline: תבנית תרחיש
examples: דוגמאות
given: "*|בהינתן"
when: "*|כאשר"
then: "*|אז|אזי"
and: "*|וגם"
but: "*|אבל"
"hr":
name: Croatian
native: hrvatski
feature: Osobina|Mogućnost|Mogucnost
background: Pozadina
scenario: Scenarij
scenario_outline: Skica|Koncept
examples: Primjeri|Scenariji
given: "*|Zadan|Zadani|Zadano"
when: "*|Kada|Kad"
then: "*|Onda"
and: "*|I"
but: "*|Ali"
"hu":
name: Hungarian
native: magyar
feature: Jellemző
background: Háttér
scenario: Forgatókönyv
scenario_outline: Forgatókönyv vázlat
examples: Példák
given: "*|Amennyiben|Adott"
when: "*|Majd|Ha|Amikor"
then: "*|Akkor"
and: "*|És"
but: "*|De"
"id":
name: Indonesian
native: Bahasa Indonesia
feature: Fitur
background: Dasar
scenario: Skenario
scenario_outline: Skenario konsep
examples: Contoh
given: "*|Dengan"
when: "*|Ketika"
then: "*|Maka"
and: "*|Dan"
but: "*|Tapi"
"is":
name: Icelandic
native: Íslenska
feature: Eiginleiki
background: Bakgrunnur
scenario: Atburðarás
scenario_outline: Lýsing Atburðarásar|Lýsing Dæma
examples: Dæmi|Atburðarásir
given: "*|Ef"
when: "*|Þegar"
then: "*|Þá"
and: "*|Og"
but: "*|En"
"it":
name: Italian
native: italiano
feature: Funzionalità
background: Contesto
scenario: Scenario
scenario_outline: Schema dello scenario
examples: Esempi
given: "*|Dato|Data|Dati|Date"
when: "*|Quando"
then: "*|Allora"
and: "*|E"
but: "*|Ma"
"ja":
name: Japanese
native: 日本語
feature: フィーチャ|機能
background: 背景
scenario: シナリオ
scenario_outline: シナリオアウトライン|シナリオテンプレート|テンプレ|シナリオテンプレ
examples: 例|サンプル
given: "*|前提<"
when: "*|もし<"
then: "*|ならば<"
and: "*|かつ<"
but: "*|しかし<|但し<|ただし<"
"ko":
name: Korean
native: 한국어
background: 배경
feature: 기능
scenario: 시나리오
scenario_outline: 시나리오 개요
examples:
given: "*|조건<|먼저<"
when: "*|만일<|만약<"
then: "*|그러면<"
and: "*|그리고<"
but: "*|하지만<|단<"
"lt":
name: Lithuanian
native: lietuvių kalba
feature: Savybė
background: Kontekstas
scenario: Scenarijus
scenario_outline: Scenarijaus šablonas
examples: Pavyzdžiai|Scenarijai|Variantai
given: "*|Duota"
when: "*|Kai"
then: "*|Tada"
and: "*|Ir"
but: "*|Bet"
"lu":
name: Luxemburgish
native: Lëtzebuergesch
feature: Funktionalitéit
background: Hannergrond
scenario: Szenario
scenario_outline: Plang vum Szenario
examples: Beispiller
given: "*|ugeholl"
when: "*|wann"
then: "*|dann"
and: "*|an|a"
but: "*|awer|mä"
"lv":
name: Latvian
native: latviešu
feature: Funkcionalitāte|Fīča
background: Konteksts|Situācija
scenario: Scenārijs
scenario_outline: Scenārijs pēc parauga
examples: Piemēri|Paraugs
given: "*|Kad"
when: "*|Ja"
then: "*|Tad"
and: "*|Un"
but: "*|Bet"
"nl":
name: Dutch
native: Nederlands
feature: Functionaliteit
background: Achtergrond
scenario: Scenario
scenario_outline: Abstract Scenario
examples: Voorbeelden
given: "*|Gegeven|Stel"
when: "*|Als"
then: "*|Dan"
and: "*|En"
but: "*|Maar"
"no":
name: Norwegian
native: norsk
feature: Egenskap
background: Bakgrunn
scenario: Scenario
scenario_outline: Scenariomal|Abstrakt Scenario
examples: Eksempler
given: "*|Gitt"
when: "*|Når"
then: "*|Så"
and: "*|Og"
but: "*|Men"
"pl":
name: Polish
native: polski
feature: Właściwość
background: Założenia
scenario: Scenariusz
scenario_outline: Szablon scenariusza
examples: Przykłady
given: "*|Zakładając|Mając"
when: "*|Jeżeli|Jeśli"
then: "*|Wtedy"
and: "*|Oraz|I"
but: "*|Ale"
"pt":
name: Portuguese
native: português
background: Contexto
feature: Funcionalidade
scenario: Cenário|Cenario
scenario_outline: Esquema do Cenário|Esquema do Cenario
examples: Exemplos
given: "*|Dado|Dada|Dados|Dadas"
when: "*|Quando"
then: "*|Então|Entao"
and: "*|E"
but: "*|Mas"
"ro":
name: Romanian
native: română
background: Context
feature: Functionalitate|Funcționalitate|Funcţionalitate
scenario: Scenariu
scenario_outline: Structura scenariu|Structură scenariu
examples: Exemple
given: "*|Date fiind|Dat fiind|Dati fiind|Dați fiind|Daţi fiind"
when: "*|Cand|Când"
then: "*|Atunci"
and: "*|Si|Și|Şi"
but: "*|Dar"
"ru":
name: Russian
native: русский
feature: Функция|Функционал|Свойство
background: Предыстория|Контекст
scenario: Сценарий
scenario_outline: Структура сценария
examples: Примеры
given: "*|Допустим|Дано|Пусть"
when: "*|Если|Когда"
then: "*|То|Тогда"
and: "*|И|К тому же"
but: "*|Но|А"
"sv":
name: Swedish
native: Svenska
feature: Egenskap
background: Bakgrund
scenario: Scenario
scenario_outline: Abstrakt Scenario|Scenariomall
examples: Exempel
given: "*|Givet"
when: "*|När"
then: "*|Så"
and: "*|Och"
but: "*|Men"
"sk":
name: Slovak
native: Slovensky
feature: Požiadavka
background: Pozadie
scenario: Scenár
scenario_outline: Náčrt Scenáru
examples: Príklady
given: "*|Pokiaľ"
when: "*|Keď"
then: "*|Tak"
and: "*|A"
but: "*|Ale"
"sr-Latn":
name: Serbian (Latin)
native: Srpski (Latinica)
feature: Funkcionalnost|Mogućnost|Mogucnost|Osobina
background: Kontekst|Osnova|Pozadina
scenario: Scenario|Primer
scenario_outline: Struktura scenarija|Skica|Koncept
examples: Primeri|Scenariji
given: "*|Zadato|Zadate|Zatati"
when: "*|Kada|Kad"
then: "*|Onda"
and: "*|I"
but: "*|Ali"
"sr-Cyrl":
name: Serbian
native: Српски
feature: Функционалност|Могућност|Особина
background: Контекст|Основа|Позадина
scenario: Сценарио|Пример
scenario_outline: Структура сценарија|Скица|Концепт
examples: Примери|Сценарији
given: "*|Задато|Задате|Задати"
when: "*|Када|Кад"
then: "*|Онда"
and: "*|И"
but: "*|Али"
"tr":
name: Turkish
native: Türkçe
feature: Özellik
background: Geçmiş
scenario: Senaryo
scenario_outline: Senaryo taslağı
examples: Örnekler
given: "*|Diyelim ki"
when: "*|Eğer ki"
then: "*|O zaman"
and: "*|Ve"
but: "*|Fakat|Ama"
"uk":
name: Ukrainian
native: Українська
feature: Функціонал
background: Передумова
scenario: Сценарій
scenario_outline: Структура сценарію
examples: Приклади
given: "*|Припустимо|Припустимо, що|Нехай|Дано"
when: "*|Якщо|Коли"
then: "*|То|Тоді"
and: "*|І|А також|Та"
but: "*|Але"
"uz":
name: Uzbek
native: Узбекча
feature: Функционал
background: Тарих
scenario: Сценарий
scenario_outline: Сценарий структураси
examples: Мисоллар
given: "*|Агар"
when: "*|Агар"
then: "*|Унда"
and: "*|Ва"
but: "*|Лекин|Бирок|Аммо"
"vi":
name: Vietnamese
native: Tiếng Việt
feature: Tính năng
background: Bối cảnh
scenario: Tình huống|Kịch bản
scenario_outline: Khung tình huống|Khung kịch bản
examples: Dữ liệu
given: "*|Biết|Cho"
when: "*|Khi"
then: "*|Thì"
and: "*|Và"
but: "*|Nhưng"
"zh-CN":
name: Chinese simplified
native: 简体中文
feature: 功能
background: 背景
scenario: 场景
scenario_outline: 场景大纲
examples: 例子
given: "*|假如<"
when: "*|当<"
then: "*|那么<"
and: "*|而且<"
but: "*|但是<"
"zh-TW":
name: Chinese traditional
native: 繁體中文
feature: 功能
background: 背景
scenario: 場景|劇本
scenario_outline: 場景大綱|劇本大綱
examples: 例子
given: "*|假設<"
when: "*|當<"
then: "*|那麼<"
and: "*|而且<|並且<"
but: "*|但是<"

View File

@@ -0,0 +1,184 @@
<?php
namespace Tests\Behat\Gherkin;
use Behat\Gherkin\Gherkin;
use Behat\Gherkin\Node\FeatureNode;
use Behat\Gherkin\Node\ScenarioNode;
class GherkinTest extends \PHPUnit_Framework_TestCase
{
public function testLoader()
{
$customFilter1 = $this->getCustomFilterMock();
$customFilter2 = $this->getCustomFilterMock();
$gherkin = new Gherkin();
$gherkin->addLoader($loader = $this->getLoaderMock());
$gherkin->addFilter($nameFilter = $this->getNameFilterMock());
$gherkin->addFilter($tagFilter = $this->getTagFilterMock());
$scenario = new ScenarioNode(null, array(), array(), null, null);
$feature = new FeatureNode(null, null, array(), null, array($scenario), null, null, null, null);
$loader
->expects($this->once())
->method('supports')
->with($resource = 'some/feature/resource')
->will($this->returnValue(true));
$loader
->expects($this->once())
->method('load')
->with($resource)
->will($this->returnValue(array($feature)));
$nameFilter
->expects($this->once())
->method('filterFeature')
->with($this->identicalTo($feature))
->will($this->returnValue($feature));
$tagFilter
->expects($this->once())
->method('filterFeature')
->with($this->identicalTo($feature))
->will($this->returnValue($feature));
$customFilter1
->expects($this->once())
->method('filterFeature')
->with($this->identicalTo($feature))
->will($this->returnValue($feature));
$customFilter2
->expects($this->once())
->method('filterFeature')
->with($this->identicalTo($feature))
->will($this->returnValue($feature));
$features = $gherkin->load($resource, array($customFilter1, $customFilter2));
$this->assertEquals(1, count($features));
$scenarios = $features[0]->getScenarios();
$this->assertEquals(1, count($scenarios));
$this->assertSame($scenario, $scenarios[0]);
}
public function testNotFoundLoader()
{
$gherkin = new Gherkin();
$this->assertEquals(array(), $gherkin->load('some/feature/resource'));
}
public function testLoaderFiltersFeatures()
{
$gherkin = new Gherkin();
$gherkin->addLoader($loader = $this->getLoaderMock());
$gherkin->addFilter($nameFilter = $this->getNameFilterMock());
$feature = new FeatureNode(null, null, array(), null, array(), null, null, null, null);
$loader
->expects($this->once())
->method('supports')
->with($resource = 'some/feature/resource')
->will($this->returnValue(true));
$loader
->expects($this->once())
->method('load')
->with($resource)
->will($this->returnValue(array($feature)));
$nameFilter
->expects($this->once())
->method('filterFeature')
->with($this->identicalTo($feature))
->will($this->returnValue($feature));
$nameFilter
->expects($this->once())
->method('isFeatureMatch')
->with($this->identicalTo($feature))
->will($this->returnValue(false));
$features = $gherkin->load($resource);
$this->assertEquals(0, count($features));
}
public function testSetFiltersOverridesAllFilters()
{
$gherkin = new Gherkin();
$gherkin->addLoader($loader = $this->getLoaderMock());
$gherkin->addFilter($nameFilter = $this->getNameFilterMock());
$gherkin->setFilters(array());
$feature = new FeatureNode(null, null, array(), null, array(), null, null, null, null);
$loader
->expects($this->once())
->method('supports')
->with($resource = 'some/feature/resource')
->will($this->returnValue(true));
$loader
->expects($this->once())
->method('load')
->with($resource)
->will($this->returnValue(array($feature)));
$nameFilter
->expects($this->never())
->method('filterFeature');
$nameFilter
->expects($this->never())
->method('isFeatureMatch');
$features = $gherkin->load($resource);
$this->assertEquals(1, count($features));
}
public function testSetBasePath()
{
$gherkin = new Gherkin();
$gherkin->addLoader($loader1 = $this->getLoaderMock());
$gherkin->addLoader($loader2 = $this->getLoaderMock());
$loader1
->expects($this->once())
->method('setBasePath')
->with($basePath = '/base/path')
->will($this->returnValue(null));
$loader2
->expects($this->once())
->method('setBasePath')
->with($basePath = '/base/path')
->will($this->returnValue(null));
$gherkin->setBasePath($basePath);
}
protected function getLoaderMock()
{
return $this->getMockBuilder('Behat\Gherkin\Loader\GherkinFileLoader')
->disableOriginalConstructor()
->getMock();
}
protected function getCustomFilterMock()
{
return $this->getMockBuilder('Behat\Gherkin\Filter\FilterInterface')
->disableOriginalConstructor()
->getMock();
}
protected function getNameFilterMock()
{
return $this->getMockBuilder('Behat\Gherkin\Filter\NameFilter')
->disableOriginalConstructor()
->getMock();
}
protected function getTagFilterMock()
{
return $this->getMockBuilder('Behat\Gherkin\Filter\TagFilter')
->disableOriginalConstructor()
->getMock();
}
}

View File

@@ -0,0 +1,48 @@
<?php
namespace Tests\Behat\Gherkin\Keywords;
use Behat\Gherkin\Keywords\ArrayKeywords;
use Behat\Gherkin\Node\StepNode;
class ArrayKeywordsTest extends KeywordsTest
{
protected function getKeywords()
{
return new ArrayKeywords($this->getKeywordsArray());
}
protected function getKeywordsArray()
{
return array(
'with_special_chars' => array(
'and' => 'And/foo',
'background' => 'Background.',
'but' => 'But[',
'examples' => 'Examples|Scenarios',
'feature' => 'Feature|Business Need|Ability',
'given' => 'Given',
'name' => 'English',
'native' => 'English',
'scenario' => 'Scenario',
'scenario_outline' => 'Scenario Outline|Scenario Template',
'then' => 'Then',
'when' => 'When',
),
);
}
protected function getSteps($keywords, $text, &$line, $keywordType)
{
$steps = array();
foreach (explode('|', $keywords) as $keyword) {
if (false !== mb_strpos($keyword, '<')) {
$keyword = mb_substr($keyword, 0, -1);
}
$steps[] = new StepNode($keyword, $text, array(), $line++, $keywordType);
}
return $steps;
}
}

View File

@@ -0,0 +1,37 @@
<?php
namespace Tests\Behat\Gherkin\Keywords;
use Behat\Gherkin\Keywords\CachedArrayKeywords;
use Behat\Gherkin\Node\StepNode;
class CachedArrayKeywordsTest extends KeywordsTest
{
protected function getKeywords()
{
return new CachedArrayKeywords(__DIR__ . '/../../../../i18n.php');
}
protected function getKeywordsArray()
{
return include(__DIR__ . '/../../../../i18n.php');
}
protected function getSteps($keywords, $text, &$line, $keywordType)
{
$steps = array();
foreach (explode('|', $keywords) as $keyword) {
if ('*' === $keyword) {
continue;
}
if (false !== mb_strpos($keyword, '<')) {
$keyword = mb_substr($keyword, 0, -1);
}
$steps[] = new StepNode($keyword, $text, array(), $line++, $keywordType);
}
return $steps;
}
}

View File

@@ -0,0 +1,34 @@
<?php
namespace Tests\Behat\Gherkin\Keywords;
use Behat\Gherkin\Keywords\CucumberKeywords;
use Behat\Gherkin\Node\StepNode;
use Symfony\Component\Yaml\Yaml;
class CucumberKeywordsTest extends KeywordsTest
{
protected function getKeywords()
{
return new CucumberKeywords(__DIR__ . '/../Fixtures/i18n.yml');
}
protected function getKeywordsArray()
{
return Yaml::parse(file_get_contents(__DIR__ . '/../Fixtures/i18n.yml'));
}
protected function getSteps($keywords, $text, &$line, $keywordType)
{
$steps = array();
foreach (explode('|', mb_substr($keywords, 2)) as $keyword) {
if (false !== mb_strpos($keyword, '<')) {
$keyword = mb_substr($keyword, 0, -1);
}
$steps[] = new StepNode($keyword, $text, array(), $line++, $keywordType);
}
return $steps;
}
}

View File

@@ -0,0 +1,270 @@
<?php
namespace Tests\Behat\Gherkin\Keywords;
use Behat\Gherkin\Keywords\ArrayKeywords;
use Behat\Gherkin\Keywords\KeywordsDumper;
class KeywordsDumperTest extends \PHPUnit_Framework_TestCase
{
private $keywords;
protected function setUp()
{
$this->keywords = new ArrayKeywords(array(
'en' => array(
'feature' => 'Feature',
'background' => 'Background',
'scenario' => 'Scenario',
'scenario_outline' => 'Scenario Outline|Scenario Template',
'examples' => 'Examples|Scenarios',
'given' => 'Given',
'when' => 'When',
'then' => 'Then',
'and' => 'And',
'but' => 'But'
),
'ru' => array(
'feature' => 'Функционал|Фича',
'background' => 'Предыстория|Бэкграунд',
'scenario' => 'Сценарий|История',
'scenario_outline' => 'Структура сценария|Аутлайн',
'examples' => 'Значения',
'given' => 'Допустим',
'when' => 'Если|@',
'then' => 'То',
'and' => 'И',
'but' => 'Но'
)
));
}
public function testEnKeywordsDumper()
{
$dumper = new KeywordsDumper($this->keywords);
$dumped = $dumper->dump('en');
$etalon = <<<GHERKIN
Feature: Internal operations
In order to stay secret
As a secret organization
We need to be able to erase past agents' memory
Background:
Given there is agent A
And there is agent B
Scenario: Erasing agent memory
Given there is agent J
And there is agent K
When I erase agent K's memory
Then there should be agent J
But there should not be agent K
(Scenario Outline|Scenario Template): Erasing other agents' memory
Given there is agent <agent1>
And there is agent <agent2>
When I erase agent <agent2>'s memory
Then there should be agent <agent1>
But there should not be agent <agent2>
(Examples|Scenarios):
| agent1 | agent2 |
| D | M |
GHERKIN;
$this->assertEquals($etalon, $dumped);
}
public function testRuKeywordsDumper()
{
$dumper = new KeywordsDumper($this->keywords);
$dumped = $dumper->dump('ru');
$etalon = <<<GHERKIN
# language: ru
(Функционал|Фича): Internal operations
In order to stay secret
As a secret organization
We need to be able to erase past agents' memory
(Предыстория|Бэкграунд):
Допустим there is agent A
И there is agent B
(Сценарий|История): Erasing agent memory
Допустим there is agent J
И there is agent K
(Если|@) I erase agent K's memory
То there should be agent J
Но there should not be agent K
(Структура сценария|Аутлайн): Erasing other agents' memory
Допустим there is agent <agent1>
И there is agent <agent2>
(Если|@) I erase agent <agent2>'s memory
То there should be agent <agent1>
Но there should not be agent <agent2>
Значения:
| agent1 | agent2 |
| D | M |
GHERKIN;
$this->assertEquals($etalon, $dumped);
}
public function testRuKeywordsCustomKeywordsDumper()
{
$dumper = new KeywordsDumper($this->keywords);
$dumper->setKeywordsDumperFunction(function ($keywords) {
return '<keyword>'.implode(', ', $keywords).'</keyword>';
});
$dumped = $dumper->dump('ru');
$etalon = <<<GHERKIN
# language: ru
<keyword>Функционал, Фича</keyword>: Internal operations
In order to stay secret
As a secret organization
We need to be able to erase past agents' memory
<keyword>Предыстория, Бэкграунд</keyword>:
<keyword>Допустим</keyword> there is agent A
<keyword>И</keyword> there is agent B
<keyword>Сценарий, История</keyword>: Erasing agent memory
<keyword>Допустим</keyword> there is agent J
<keyword>И</keyword> there is agent K
<keyword>Если, @</keyword> I erase agent K's memory
<keyword>То</keyword> there should be agent J
<keyword>Но</keyword> there should not be agent K
<keyword>Структура сценария, Аутлайн</keyword>: Erasing other agents' memory
<keyword>Допустим</keyword> there is agent <agent1>
<keyword>И</keyword> there is agent <agent2>
<keyword>Если, @</keyword> I erase agent <agent2>'s memory
<keyword>То</keyword> there should be agent <agent1>
<keyword>Но</keyword> there should not be agent <agent2>
<keyword>Значения</keyword>:
| agent1 | agent2 |
| D | M |
GHERKIN;
$this->assertEquals($etalon, $dumped);
}
public function testExtendedVersionDumper()
{
$dumper = new KeywordsDumper($this->keywords);
$dumped = $dumper->dump('ru', false);
$etalon = array(
<<<GHERKIN
# language: ru
Функционал: Internal operations
In order to stay secret
As a secret organization
We need to be able to erase past agents' memory
Предыстория:
Допустим there is agent A
И there is agent B
Сценарий: Erasing agent memory
Допустим there is agent J
И there is agent K
Если I erase agent K's memory
@ I erase agent K's memory
То there should be agent J
Но there should not be agent K
История: Erasing agent memory
Допустим there is agent J
И there is agent K
Если I erase agent K's memory
@ I erase agent K's memory
То there should be agent J
Но there should not be agent K
Структура сценария: Erasing other agents' memory
Допустим there is agent <agent1>
И there is agent <agent2>
Если I erase agent <agent2>'s memory
@ I erase agent <agent2>'s memory
То there should be agent <agent1>
Но there should not be agent <agent2>
Значения:
| agent1 | agent2 |
| D | M |
Аутлайн: Erasing other agents' memory
Допустим there is agent <agent1>
И there is agent <agent2>
Если I erase agent <agent2>'s memory
@ I erase agent <agent2>'s memory
То there should be agent <agent1>
Но there should not be agent <agent2>
Значения:
| agent1 | agent2 |
| D | M |
GHERKIN
, <<<GHERKIN
# language: ru
Фича: Internal operations
In order to stay secret
As a secret organization
We need to be able to erase past agents' memory
Предыстория:
Допустим there is agent A
И there is agent B
Сценарий: Erasing agent memory
Допустим there is agent J
И there is agent K
Если I erase agent K's memory
@ I erase agent K's memory
То there should be agent J
Но there should not be agent K
История: Erasing agent memory
Допустим there is agent J
И there is agent K
Если I erase agent K's memory
@ I erase agent K's memory
То there should be agent J
Но there should not be agent K
Структура сценария: Erasing other agents' memory
Допустим there is agent <agent1>
И there is agent <agent2>
Если I erase agent <agent2>'s memory
@ I erase agent <agent2>'s memory
То there should be agent <agent1>
Но there should not be agent <agent2>
Значения:
| agent1 | agent2 |
| D | M |
Аутлайн: Erasing other agents' memory
Допустим there is agent <agent1>
И there is agent <agent2>
Если I erase agent <agent2>'s memory
@ I erase agent <agent2>'s memory
То there should be agent <agent1>
Но there should not be agent <agent2>
Значения:
| agent1 | agent2 |
| D | M |
GHERKIN
);
$this->assertEquals($etalon, $dumped);
}
}

View File

@@ -0,0 +1,139 @@
<?php
namespace Tests\Behat\Gherkin\Keywords;
use Behat\Gherkin\Keywords\KeywordsDumper;
use Behat\Gherkin\Lexer;
use Behat\Gherkin\Node\BackgroundNode;
use Behat\Gherkin\Node\ExampleTableNode;
use Behat\Gherkin\Node\FeatureNode;
use Behat\Gherkin\Node\OutlineNode;
use Behat\Gherkin\Node\ScenarioNode;
use Behat\Gherkin\Parser;
abstract class KeywordsTest extends \PHPUnit_Framework_TestCase
{
abstract protected function getKeywords();
abstract protected function getKeywordsArray();
abstract protected function getSteps($keywords, $text, &$line, $keywordType);
public function translationTestDataProvider()
{
$keywords = $this->getKeywords();
$lexer = new Lexer($keywords);
$parser = new Parser($lexer);
$dumper = new KeywordsDumper($keywords);
$keywordsArray = $this->getKeywordsArray();
// Remove languages with repeated keywords
unset($keywordsArray['en-old'], $keywordsArray['uz']);
$data = array();
foreach ($keywordsArray as $lang => $i18nKeywords) {
$features = array();
foreach (explode('|', $i18nKeywords['feature']) as $transNum => $featureKeyword) {
$line = 1;
if ('en' !== $lang) {
$line = 2;
}
$featureLine = $line;
$line += 5;
$keywords = explode('|', $i18nKeywords['background']);
$backgroundLine = $line;
$line += 1;
$background = new BackgroundNode(null, array_merge(
$this->getSteps($i18nKeywords['given'], 'there is agent A', $line, 'Given'),
$this->getSteps($i18nKeywords['and'], 'there is agent B', $line, 'Given')
), $keywords[0], $backgroundLine);
$line += 1;
$scenarios = array();
foreach (explode('|', $i18nKeywords['scenario']) as $scenarioKeyword) {
$scenarioLine = $line;
$line += 1;
$steps = array_merge(
$this->getSteps($i18nKeywords['given'], 'there is agent J', $line, 'Given'),
$this->getSteps($i18nKeywords['and'], 'there is agent K', $line, 'Given'),
$this->getSteps($i18nKeywords['when'], 'I erase agent K\'s memory', $line, 'When'),
$this->getSteps($i18nKeywords['then'], 'there should be agent J', $line, 'Then'),
$this->getSteps($i18nKeywords['but'], 'there should not be agent K', $line, 'Then')
);
$scenarios[] = new ScenarioNode('Erasing agent memory', array(), $steps, $scenarioKeyword, $scenarioLine);
$line += 1;
}
foreach (explode('|', $i18nKeywords['scenario_outline']) as $outlineKeyword) {
$outlineLine = $line;
$line += 1;
$steps = array_merge(
$this->getSteps($i18nKeywords['given'], 'there is agent <agent1>', $line, 'Given'),
$this->getSteps($i18nKeywords['and'], 'there is agent <agent2>', $line, 'Given'),
$this->getSteps($i18nKeywords['when'], 'I erase agent <agent2>\'s memory', $line, 'When'),
$this->getSteps($i18nKeywords['then'], 'there should be agent <agent1>', $line, 'Then'),
$this->getSteps($i18nKeywords['but'], 'there should not be agent <agent2>', $line, 'Then')
);
$line += 1;
$keywords = explode('|', $i18nKeywords['examples']);
$table = new ExampleTableNode(array(
++$line => array('agent1', 'agent2'),
++$line => array('D', 'M')
), $keywords[0]);
$line += 1;
$scenarios[] = new OutlineNode('Erasing other agents\' memory', array(), $steps, $table, $outlineKeyword, $outlineLine);
$line += 1;
}
$features[] = new FeatureNode(
'Internal operations',
<<<DESC
In order to stay secret
As a secret organization
We need to be able to erase past agents' memory
DESC
,
array(),
$background,
$scenarios,
$featureKeyword,
$lang,
$lang . '_' . ($transNum + 1) . '.feature',
$featureLine
);
}
$dumped = $dumper->dump($lang, false, true);
$parsed = array();
try {
foreach ($dumped as $num => $dumpedFeature) {
$parsed[] = $parser->parse($dumpedFeature, $lang . '_' . ($num + 1) . '.feature');
}
} catch (\Exception $e) {
throw new \Exception($e->getMessage() . ":\n" . json_encode($dumped), 0, $e);
}
$data[] = array($lang, $features, $parsed);
}
return $data;
}
/**
* @dataProvider translationTestDataProvider
*
* @param string $language language name
* @param array $etalon etalon features (to test against)
* @param array $features array of parsed feature(s)
*/
public function testTranslation($language, array $etalon, array $features)
{
$this->assertEquals($etalon, $features);
}
}

View File

@@ -0,0 +1,379 @@
<?php
namespace Tests\Behat\Gherkin\Loader;
use Behat\Gherkin\Loader\ArrayLoader;
class ArrayLoaderTest extends \PHPUnit_Framework_TestCase
{
private $loader;
protected function setUp()
{
$this->loader = new ArrayLoader();
}
public function testSupports()
{
$this->assertFalse($this->loader->supports(__DIR__));
$this->assertFalse($this->loader->supports(__FILE__));
$this->assertFalse($this->loader->supports('string'));
$this->assertFalse($this->loader->supports(array('wrong_root')));
$this->assertFalse($this->loader->supports(array('features')));
$this->assertTrue($this->loader->supports(array('features' => array())));
$this->assertTrue($this->loader->supports(array('feature' => array())));
}
public function testLoadEmpty()
{
$this->assertEquals(array(), $this->loader->load(array('features' => array())));
}
public function testLoadFeatures()
{
$features = $this->loader->load(array(
'features' => array(
array(
'title' => 'First feature',
'line' => 3,
),
array(
'description' => 'Second feature description',
'language' => 'ru',
'tags' => array('some', 'tags')
)
),
));
$this->assertEquals(2, count($features));
$this->assertEquals(3, $features[0]->getLine());
$this->assertEquals('First feature', $features[0]->getTitle());
$this->assertNull($features[0]->getDescription());
$this->assertNull($features[0]->getFile());
$this->assertEquals('en', $features[0]->getLanguage());
$this->assertFalse($features[0]->hasTags());
$this->assertEquals(1, $features[1]->getLine());
$this->assertNull($features[1]->getTitle());
$this->assertEquals('Second feature description', $features[1]->getDescription());
$this->assertNull($features[1]->getFile());
$this->assertEquals('ru', $features[1]->getLanguage());
$this->assertEquals(array('some', 'tags'), $features[1]->getTags());
}
public function testLoadScenarios()
{
$features = $this->loader->load(array(
'features' => array(
array(
'title' => 'Feature',
'scenarios' => array(
array(
'title' => 'First scenario',
'line' => 2
),
array(
'tags' => array('second', 'scenario', 'tags')
),
array(
'tags' => array('third', 'scenario'),
'line' => 3
)
)
)
),
));
$this->assertEquals(1, count($features));
$scenarios = $features[0]->getScenarios();
$this->assertEquals(3, count($scenarios));
$this->assertInstanceOf('Behat\Gherkin\Node\ScenarioNode', $scenarios[0]);
$this->assertEquals('First scenario', $scenarios[0]->getTitle());
$this->assertFalse($scenarios[0]->hasTags());
$this->assertEquals(2, $scenarios[0]->getLine());
$this->assertInstanceOf('Behat\Gherkin\Node\ScenarioNode', $scenarios[1]);
$this->assertNull($scenarios[1]->getTitle());
$this->assertEquals(array('second', 'scenario', 'tags'), $scenarios[1]->getTags());
$this->assertEquals(1, $scenarios[1]->getLine());
$this->assertInstanceOf('Behat\Gherkin\Node\ScenarioNode', $scenarios[2]);
$this->assertNull($scenarios[2]->getTitle());
$this->assertEquals(array('third', 'scenario'), $scenarios[2]->getTags());
$this->assertEquals(3, $scenarios[2]->getLine());
}
public function testLoadOutline()
{
$features = $this->loader->load(array(
'features' => array(
array(
'title' => 'Feature',
'scenarios' => array(
array(
'type' => 'outline',
'title' => 'First outline',
'line' => 2
),
array(
'type' => 'outline',
'tags' => array('second', 'outline', 'tags')
)
)
)
),
));
$this->assertEquals(1, count($features));
$outlines = $features[0]->getScenarios();
$this->assertEquals(2, count($outlines));
$this->assertInstanceOf('Behat\Gherkin\Node\OutlineNode', $outlines[0]);
$this->assertEquals('First outline', $outlines[0]->getTitle());
$this->assertFalse($outlines[0]->hasTags());
$this->assertEquals(2, $outlines[0]->getLine());
$this->assertInstanceOf('Behat\Gherkin\Node\OutlineNode', $outlines[1]);
$this->assertNull($outlines[1]->getTitle());
$this->assertEquals(array('second', 'outline', 'tags'), $outlines[1]->getTags());
$this->assertEquals(1, $outlines[1]->getLine());
}
public function testOutlineExamples()
{
$features = $this->loader->load(array(
'features' => array(
array(
'title' => 'Feature',
'scenarios' => array(
array(
'type' => 'outline',
'title' => 'First outline',
'line' => 2,
'examples' => array(
array('user', 'pass'),
array('ever', 'sdsd'),
array('anto', 'fdfd')
)
),
array(
'type' => 'outline',
'tags' => array('second', 'outline', 'tags')
)
)
)
),
));
$this->assertEquals(1, count($features));
$scenarios = $features[0]->getScenarios();
$scenario = $scenarios[0];
$this->assertEquals(
array(array('user' => 'ever', 'pass' => 'sdsd'), array('user' => 'anto', 'pass' => 'fdfd')),
$scenario->getExampleTable()->getHash()
);
}
public function testLoadBackground()
{
$features = $this->loader->load(array(
'features' => array(
array(
),
array(
'background' => array()
),
array(
'background' => array(
'line' => 2
)
),
)
));
$this->assertEquals(3, count($features));
$this->assertFalse($features[0]->hasBackground());
$this->assertTrue($features[1]->hasBackground());
$this->assertEquals(0, $features[1]->getBackground()->getLine());
$this->assertTrue($features[2]->hasBackground());
$this->assertEquals(2, $features[2]->getBackground()->getLine());
}
public function testLoadSteps()
{
$features = $this->loader->load(array(
'features' => array(
array(
'background' => array(
'steps' => array(
array('type' => 'Gangway!', 'keyword_type' => 'Given', 'text' => 'bg step 1', 'line' => 3),
array('type' => 'Blimey!', 'keyword_type' => 'When', 'text' => 'bg step 2')
)
),
'scenarios' => array(
array(
'title' => 'Scenario',
'steps' => array(
array('type' => 'Gangway!', 'keyword_type' => 'Given', 'text' => 'sc step 1'),
array('type' => 'Blimey!', 'keyword_type' => 'When', 'text' => 'sc step 2')
)
),
array(
'title' => 'Outline',
'type' => 'outline',
'steps' => array(
array('type' => 'Gangway!', 'keyword_type' => 'Given', 'text' => 'out step 1'),
array('type' => 'Blimey!', 'keyword_type' => 'When', 'text' => 'out step 2')
)
)
)
)
)
));
$background = $features[0]->getBackground();
$this->assertTrue($background->hasSteps());
$this->assertEquals(2, count($background->getSteps()));
$steps = $background->getSteps();
$this->assertEquals('Gangway!', $steps[0]->getType());
$this->assertEquals('Gangway!', $steps[0]->getKeyword());
$this->assertEquals('Given', $steps[0]->getKeywordType());
$this->assertEquals('bg step 1', $steps[0]->getText());
$this->assertEquals(3, $steps[0]->getLine());
$this->assertEquals('Blimey!', $steps[1]->getType());
$this->assertEquals('Blimey!', $steps[1]->getKeyword());
$this->assertEquals('When', $steps[1]->getKeywordType());
$this->assertEquals('bg step 2', $steps[1]->getText());
$this->assertEquals(1, $steps[1]->getLine());
$scenarios = $features[0]->getScenarios();
$scenario = $scenarios[0];
$this->assertTrue($scenario->hasSteps());
$this->assertEquals(2, count($scenario->getSteps()));
$steps = $scenario->getSteps();
$this->assertEquals('Gangway!', $steps[0]->getType());
$this->assertEquals('Gangway!', $steps[0]->getKeyword());
$this->assertEquals('Given', $steps[0]->getKeywordType());
$this->assertEquals('sc step 1', $steps[0]->getText());
$this->assertEquals(0, $steps[0]->getLine());
$this->assertEquals('Blimey!', $steps[1]->getType());
$this->assertEquals('Blimey!', $steps[1]->getKeyword());
$this->assertEquals('When', $steps[1]->getKeywordType());
$this->assertEquals('sc step 2', $steps[1]->getText());
$this->assertEquals(1, $steps[1]->getLine());
$outline = $scenarios[1];
$this->assertTrue($outline->hasSteps());
$this->assertEquals(2, count($outline->getSteps()));
$steps = $outline->getSteps();
$this->assertEquals('Gangway!', $steps[0]->getType());
$this->assertEquals('Gangway!', $steps[0]->getKeyword());
$this->assertEquals('Given', $steps[0]->getKeywordType());
$this->assertEquals('out step 1', $steps[0]->getText());
$this->assertEquals(0, $steps[0]->getLine());
$this->assertEquals('Blimey!', $steps[1]->getType());
$this->assertEquals('Blimey!', $steps[1]->getKeyword());
$this->assertEquals('When', $steps[1]->getKeywordType());
$this->assertEquals('out step 2', $steps[1]->getText());
$this->assertEquals(1, $steps[1]->getLine());
}
public function testLoadStepArguments()
{
$features = $this->loader->load(array(
'features' => array(
array(
'background' => array(
'steps' => array(
array(
'type' => 'Gangway!', 'keyword_type' => 'Given', 'text' => 'step with table argument',
'arguments' => array(
array(
'type' => 'table',
'rows' => array(
array('key', 'val'),
array(1, 2),
array(3, 4)
)
)
)
),
array(
'type' => 'Blimey!', 'keyword_type' => 'When', 'text' => 'step with pystring argument',
'arguments' => array(
array(
'type' => 'pystring',
'text' => ' some text',
)
)
),
array(
'type' => 'Let go and haul', 'keyword_type' => 'Then', 'text' => '2nd step with pystring argument',
'arguments' => array(
array(
'type' => 'pystring',
'text' => 'some text',
)
)
)
)
)
)
)
));
$background = $features[0]->getBackground();
$this->assertTrue($background->hasSteps());
$steps = $background->getSteps();
$this->assertEquals(3, count($steps));
$arguments = $steps[0]->getArguments();
$this->assertEquals('Gangway!', $steps[0]->getType());
$this->assertEquals('Gangway!', $steps[0]->getKeyword());
$this->assertEquals('Given', $steps[0]->getKeywordType());
$this->assertEquals('step with table argument', $steps[0]->getText());
$this->assertInstanceOf('Behat\Gherkin\Node\TableNode', $arguments[0]);
$this->assertEquals(array(array('key'=>1, 'val'=>2), array('key'=>3,'val'=>4)), $arguments[0]->getHash());
$arguments = $steps[1]->getArguments();
$this->assertEquals('Blimey!', $steps[1]->getType());
$this->assertEquals('Blimey!', $steps[1]->getKeyword());
$this->assertEquals('When', $steps[1]->getKeywordType());
$this->assertEquals('step with pystring argument', $steps[1]->getText());
$this->assertInstanceOf('Behat\Gherkin\Node\PyStringNode', $arguments[0]);
$this->assertEquals(' some text', (string) $arguments[0]);
$arguments = $steps[2]->getArguments();
$this->assertEquals('Let go and haul', $steps[2]->getType());
$this->assertEquals('Let go and haul', $steps[2]->getKeyword());
$this->assertEquals('Then', $steps[2]->getKeywordType());
$this->assertEquals('2nd step with pystring argument', $steps[2]->getText());
$this->assertInstanceOf('Behat\Gherkin\Node\PyStringNode', $arguments[0]);
$this->assertEquals('some text', (string) $arguments[0]);
}
public function testSingleFeatureArray()
{
$features = $this->loader->load(array(
'feature' => array(
'title' => 'Some feature'
)
));
$this->assertEquals(1, count($features));
$this->assertEquals('Some feature', $features[0]->getTitle());
}
}

View File

@@ -0,0 +1,92 @@
<?php
namespace Tests\Behat\Gherkin\Loader;
use Behat\Gherkin\Loader\DirectoryLoader;
class DirectoryLoaderTest extends \PHPUnit_Framework_TestCase
{
private $gherkin;
private $loader;
private $featuresPath;
protected function setUp()
{
$this->gherkin = $this->createGherkinMock();
$this->loader = new DirectoryLoader($this->gherkin);
$this->featuresPath = realpath(__DIR__ . '/../Fixtures/directories');
}
protected function createGherkinMock()
{
$gherkin = $this->getMockBuilder('Behat\Gherkin\Gherkin')
->disableOriginalConstructor()
->getMock();
return $gherkin;
}
protected function createGherkinFileLoaderMock()
{
$loader = $this->getMockBuilder('Behat\Gherkin\Loader\GherkinFileLoader')
->disableOriginalConstructor()
->getMock();
return $loader;
}
public function testSupports()
{
$this->assertFalse($this->loader->supports('non-existent path'));
$this->assertFalse($this->loader->supports('non-existent path:2'));
$this->assertFalse($this->loader->supports(__DIR__ . ':d'));
$this->assertFalse($this->loader->supports(__DIR__ . '/../Fixtures/features/pystring.feature'));
$this->assertTrue($this->loader->supports(__DIR__));
$this->assertTrue($this->loader->supports(__DIR__ . '/../Fixtures/features'));
}
public function testUndefinedFileLoad()
{
$this->gherkin
->expects($this->once())
->method('resolveLoader')
->with($this->featuresPath.DIRECTORY_SEPARATOR.'phps'.DIRECTORY_SEPARATOR.'some_file.php')
->will($this->returnValue(null));
$this->assertEquals(array(), $this->loader->load($this->featuresPath . '/phps'));
}
public function testBasePath()
{
$this->gherkin
->expects($this->once())
->method('resolveLoader')
->with($this->featuresPath.DIRECTORY_SEPARATOR.'phps'.DIRECTORY_SEPARATOR.'some_file.php')
->will($this->returnValue(null));
$this->loader->setBasePath($this->featuresPath);
$this->assertEquals(array(), $this->loader->load('phps'));
}
public function testDefinedFileLoad()
{
$loaderMock = $this->createGherkinFileLoaderMock();
$this->gherkin
->expects($this->once())
->method('resolveLoader')
->with($this->featuresPath.DIRECTORY_SEPARATOR.'phps'.DIRECTORY_SEPARATOR.'some_file.php')
->will($this->returnValue($loaderMock));
$loaderMock
->expects($this->once())
->method('load')
->with($this->featuresPath.DIRECTORY_SEPARATOR.'phps'.DIRECTORY_SEPARATOR.'some_file.php')
->will($this->returnValue(array('feature1', 'feature2')));
$this->assertEquals(array('feature1', 'feature2'), $this->loader->load($this->featuresPath . '/phps'));
}
}

View File

@@ -0,0 +1,111 @@
<?php
namespace Tests\Behat\Gherkin\Loader;
use Behat\Gherkin\Keywords\CucumberKeywords;
use Behat\Gherkin\Lexer;
use Behat\Gherkin\Loader\GherkinFileLoader;
use Behat\Gherkin\Parser;
class GherkinFileLoaderTest extends \PHPUnit_Framework_TestCase
{
/**
* @var GherkinFileLoader
*/
private $loader;
private $featuresPath;
public function testSupports()
{
$this->assertFalse($this->loader->supports('non-existent path'));
$this->assertFalse($this->loader->supports('non-existent path:2'));
$this->assertFalse($this->loader->supports(__DIR__));
$this->assertFalse($this->loader->supports(__DIR__ . ':d'));
$this->assertFalse($this->loader->supports(__FILE__));
$this->assertTrue($this->loader->supports(__DIR__ . '/../Fixtures/features/pystring.feature'));
}
public function testLoad()
{
$features = $this->loader->load($this->featuresPath . '/pystring.feature');
$this->assertEquals(1, count($features));
$this->assertEquals('A py string feature', $features[0]->getTitle());
$this->assertEquals($this->featuresPath . DIRECTORY_SEPARATOR . 'pystring.feature', $features[0]->getFile());
$features = $this->loader->load($this->featuresPath . '/multiline_name.feature');
$this->assertEquals(1, count($features));
$this->assertEquals('multiline', $features[0]->getTitle());
$this->assertEquals($this->featuresPath . DIRECTORY_SEPARATOR . 'multiline_name.feature', $features[0]->getFile());
}
public function testParsingUncachedFeature()
{
$cache = $this->getMockBuilder('Behat\Gherkin\Cache\CacheInterface')->getMock();
$this->loader->setCache($cache);
$cache->expects($this->once())
->method('isFresh')
->with($path = $this->featuresPath . DIRECTORY_SEPARATOR . 'pystring.feature', filemtime($path))
->will($this->returnValue(false));
$cache->expects($this->once())
->method('write');
$features = $this->loader->load($this->featuresPath . '/pystring.feature');
$this->assertEquals(1, count($features));
}
public function testParsingCachedFeature()
{
$cache = $this->getMockBuilder('Behat\Gherkin\Cache\CacheInterface')->getMock();
$this->loader->setCache($cache);
$cache->expects($this->once())
->method('isFresh')
->with($path = $this->featuresPath . DIRECTORY_SEPARATOR . 'pystring.feature', filemtime($path))
->will($this->returnValue(true));
$cache->expects($this->once())
->method('read')
->with($path)
->will($this->returnValue('cache'));
$cache->expects($this->never())
->method('write');
$features = $this->loader->load($this->featuresPath . '/pystring.feature');
$this->assertEquals('cache', $features[0]);
}
public function testBasePath()
{
$this->assertFalse($this->loader->supports('features'));
$this->assertFalse($this->loader->supports('tables.feature'));
$this->loader->setBasePath($this->featuresPath . '/../');
$this->assertFalse($this->loader->supports('features'));
$this->assertFalse($this->loader->supports('tables.feature'));
$this->assertTrue($this->loader->supports('features/tables.feature'));
$features = $this->loader->load('features/pystring.feature');
$this->assertEquals(1, count($features));
$this->assertEquals('A py string feature', $features[0]->getTitle());
$this->assertEquals('features' . DIRECTORY_SEPARATOR . 'pystring.feature', $features[0]->getFile());
$this->loader->setBasePath($this->featuresPath);
$features = $this->loader->load('multiline_name.feature');
$this->assertEquals(1, count($features));
$this->assertEquals('multiline', $features[0]->getTitle());
$this->assertEquals('multiline_name.feature', $features[0]->getFile());
}
protected function setUp()
{
$keywords = new CucumberKeywords(__DIR__ . '/../Fixtures/i18n.yml');
$parser = new Parser(new Lexer($keywords));
$this->loader = new GherkinFileLoader($parser);
$this->featuresPath = realpath(__DIR__ . '/../Fixtures/features');
}
}

View File

@@ -0,0 +1,67 @@
<?php
namespace Tests\Behat\Gherkin\Loader;
use Behat\Gherkin\Loader\YamlFileLoader;
class YamlFileLoaderTest extends \PHPUnit_Framework_TestCase
{
private $loader;
protected function setUp()
{
$this->loader = new YamlFileLoader();
}
public function testSupports()
{
$this->assertFalse($this->loader->supports(__DIR__));
$this->assertFalse($this->loader->supports(__FILE__));
$this->assertFalse($this->loader->supports('string'));
$this->assertFalse($this->loader->supports(__DIR__ . '/file.yml'));
$this->assertTrue($this->loader->supports(__DIR__ . '/../Fixtures/etalons/addition.yml'));
}
public function testLoadAddition()
{
$this->loader->setBasePath(__DIR__ . '/../Fixtures');
$features = $this->loader->load('etalons/addition.yml');
$this->assertEquals(1, count($features));
$this->assertEquals('etalons'.DIRECTORY_SEPARATOR.'addition.yml', $features[0]->getFile());
$this->assertEquals('Addition', $features[0]->getTitle());
$this->assertEquals(2, $features[0]->getLine());
$this->assertEquals('en', $features[0]->getLanguage());
$expectedDescription = <<<EOS
In order to avoid silly mistakes
As a math idiot
I want to be told the sum of two numbers
EOS;
$this->assertEquals($expectedDescription, $features[0]->getDescription());
$scenarios = $features[0]->getScenarios();
$this->assertEquals(2, count($scenarios));
$this->assertInstanceOf('Behat\Gherkin\Node\ScenarioNode', $scenarios[0]);
$this->assertEquals(7, $scenarios[0]->getLine());
$this->assertEquals('Add two numbers', $scenarios[0]->getTitle());
$steps = $scenarios[0]->getSteps();
$this->assertEquals(4, count($steps));
$this->assertEquals(9, $steps[1]->getLine());
$this->assertEquals('And', $steps[1]->getType());
$this->assertEquals('And', $steps[1]->getKeyword());
$this->assertEquals('Given', $steps[1]->getKeywordType());
$this->assertEquals('I have entered 12 into the calculator', $steps[1]->getText());
$this->assertInstanceOf('Behat\Gherkin\Node\ScenarioNode', $scenarios[1]);
$this->assertEquals(13, $scenarios[1]->getLine());
$this->assertEquals('Div two numbers', $scenarios[1]->getTitle());
$steps = $scenarios[1]->getSteps();
$this->assertEquals(4, count($steps));
$this->assertEquals(16, $steps[2]->getLine());
$this->assertEquals('When', $steps[2]->getType());
$this->assertEquals('When', $steps[2]->getKeyword());
$this->assertEquals('When', $steps[2]->getKeywordType());
$this->assertEquals('I press div', $steps[2]->getText());
}
}

View File

@@ -0,0 +1,92 @@
<?php
namespace Tests\Behat\Gherkin\Node;
use Behat\Gherkin\Node\ExampleTableNode;
use Behat\Gherkin\Node\OutlineNode;
use Behat\Gherkin\Node\PyStringNode;
use Behat\Gherkin\Node\StepNode;
use Behat\Gherkin\Node\TableNode;
class ExampleNodeTest extends \PHPUnit_Framework_TestCase
{
public function testCreateExampleSteps()
{
$steps = array(
$step1 = new StepNode('Gangway!', 'I am <name>', array(), null, 'Given'),
$step2 = new StepNode('Aye!', 'my email is <email>', array(), null, 'And'),
$step3 = new StepNode('Blimey!', 'I open homepage', array(), null, 'When'),
$step4 = new StepNode('Let go and haul', 'website should recognise me', array(), null, 'Then'),
);
$table = new ExampleTableNode(array(
array('name', 'email'),
array('everzet', 'ever.zet@gmail.com'),
array('example', 'example@example.com')
), 'Examples');
$outline = new OutlineNode(null, array(), $steps, $table, null, null);
$examples = $outline->getExamples();
$this->assertCount(4, $steps = $examples[0]->getSteps());
$this->assertEquals('Gangway!', $steps[0]->getType());
$this->assertEquals('Gangway!', $steps[0]->getKeyword());
$this->assertEquals('Given', $steps[0]->getKeywordType());
$this->assertEquals('I am everzet', $steps[0]->getText());
$this->assertEquals('Aye!', $steps[1]->getType());
$this->assertEquals('Aye!', $steps[1]->getKeyword());
$this->assertEquals('And', $steps[1]->getKeywordType());
$this->assertEquals('my email is ever.zet@gmail.com', $steps[1]->getText());
$this->assertEquals('Blimey!', $steps[2]->getType());
$this->assertEquals('Blimey!', $steps[2]->getKeyword());
$this->assertEquals('When', $steps[2]->getKeywordType());
$this->assertEquals('I open homepage', $steps[2]->getText());
$this->assertCount(4, $steps = $examples[1]->getSteps());
$this->assertEquals('Gangway!', $steps[0]->getType());
$this->assertEquals('Gangway!', $steps[0]->getKeyword());
$this->assertEquals('Given', $steps[0]->getKeywordType());
$this->assertEquals('I am example', $steps[0]->getText());
$this->assertEquals('Aye!', $steps[1]->getType());
$this->assertEquals('Aye!', $steps[1]->getKeyword());
$this->assertEquals('And', $steps[1]->getKeywordType());
$this->assertEquals('my email is example@example.com', $steps[1]->getText());
$this->assertEquals('Blimey!', $steps[2]->getType());
$this->assertEquals('Blimey!', $steps[2]->getKeyword());
$this->assertEquals('When', $steps[2]->getKeywordType());
$this->assertEquals('I open homepage', $steps[2]->getText());
}
public function testCreateExampleStepsWithArguments()
{
$steps = array(
$step1 = new StepNode('Gangway!', 'I am <name>', array(), null, 'Given'),
$step2 = new StepNode('Aye!', 'my email is <email>', array(), null, 'And'),
$step3 = new StepNode('Blimey!', 'I open:', array(
new PyStringNode(array('page: <url>'), null)
), null, 'When'),
$step4 = new StepNode('Let go and haul', 'website should recognise me', array(
new TableNode(array(array('page', '<url>')))
), null, 'Then'),
);
$table = new ExampleTableNode(array(
array('name', 'email', 'url'),
array('everzet', 'ever.zet@gmail.com', 'homepage'),
array('example', 'example@example.com', 'other page')
), 'Examples');
$outline = new OutlineNode(null, array(), $steps, $table, null, null);
$examples = $outline->getExamples();
$steps = $examples[0]->getSteps();
$args = $steps[2]->getArguments();
$this->assertEquals('page: homepage', $args[0]->getRaw());
$args = $steps[3]->getArguments();
$this->assertEquals('| page | homepage |', $args[0]->getTableAsString());
}
}

View File

@@ -0,0 +1,68 @@
<?php
namespace Tests\Behat\Gherkin\Node;
use Behat\Gherkin\Node\ExampleTableNode;
use Behat\Gherkin\Node\OutlineNode;
use Behat\Gherkin\Node\StepNode;
class OutlineNodeTest extends \PHPUnit_Framework_TestCase
{
public function testCreatesExamplesForExampleTable()
{
$steps = array(
new StepNode('Gangway!', 'I am <name>', array(), null, 'Given'),
new StepNode('Aye!', 'my email is <email>', array(), null, 'And'),
new StepNode('Blimey!', 'I open homepage', array(), null, 'When'),
new StepNode('Let go and haul', 'website should recognise me', array(), null, 'Then'),
);
$table = new ExampleTableNode(array(
array('name', 'email'),
array('everzet', 'ever.zet@gmail.com'),
array('example', 'example@example.com')
), 'Examples');
$outline = new OutlineNode(null, array(), $steps, $table, null, null);
$this->assertCount(2, $examples = $outline->getExamples());
$this->assertEquals(1, $examples[0]->getLine());
$this->assertEquals(2, $examples[1]->getLine());
$this->assertEquals(array('name' => 'everzet', 'email' => 'ever.zet@gmail.com'), $examples[0]->getTokens());
$this->assertEquals(array('name' => 'example', 'email' => 'example@example.com'), $examples[1]->getTokens());
}
public function testCreatesEmptyExamplesForEmptyExampleTable()
{
$steps = array(
new StepNode('Gangway!', 'I am <name>', array(), null, 'Given'),
new StepNode('Aye!', 'my email is <email>', array(), null, 'And'),
new StepNode('Blimey!', 'I open homepage', array(), null, 'When'),
new StepNode('Let go and haul', 'website should recognise me', array(), null, 'Then'),
);
$table = new ExampleTableNode(array(
array('name', 'email')
), 'Examples');
$outline = new OutlineNode(null, array(), $steps, $table, null, null);
$this->assertCount(0, $examples = $outline->getExamples());
}
public function testCreatesEmptyExamplesForNoExampleTable()
{
$steps = array(
new StepNode('Gangway!', 'I am <name>', array(), null, 'Given'),
new StepNode('Aye!', 'my email is <email>', array(), null, 'And'),
new StepNode('Blimey!', 'I open homepage', array(), null, 'When'),
new StepNode('Let go and haul', 'website should recognise me', array(), null, 'Then'),
);
$table = new ExampleTableNode(array(), 'Examples');
$outline = new OutlineNode(null, array(), $steps, $table, null, null);
$this->assertCount(0, $examples = $outline->getExamples());
}
}

View File

@@ -0,0 +1,27 @@
<?php
namespace Tests\Behat\Gherkin\Node;
use Behat\Gherkin\Node\PyStringNode;
class PyStringNodeTest extends \PHPUnit_Framework_TestCase
{
public function testGetStrings()
{
$str = new PyStringNode(array('line1', 'line2', 'line3'), 0);
$this->assertEquals(array('line1', 'line2', 'line3'), $str->getStrings());
}
public function testGetRaw()
{
$str = new PyStringNode(array('line1', 'line2', 'line3'), 0);
$expected = <<<STR
line1
line2
line3
STR;
$this->assertEquals($expected, $str->getRaw());
}
}

View File

@@ -0,0 +1,20 @@
<?php
namespace Tests\Behat\Gherkin\Node;
use Behat\Gherkin\Node\PyStringNode;
use Behat\Gherkin\Node\StepNode;
use Behat\Gherkin\Node\TableNode;
class StepNodeTest extends \PHPUnit_Framework_TestCase
{
public function testThatStepCanHaveOnlyOneArgument()
{
$this->setExpectedException('Behat\Gherkin\Exception\NodeException');
new StepNode('Gangway!', 'I am on the page:', array(
new PyStringNode(array('one', 'two'), 11),
new TableNode(array(array('one', 'two'))),
), 10, 'Given');
}
}

View File

@@ -0,0 +1,269 @@
<?php
namespace Tests\Behat\Gherkin\Node;
use Behat\Gherkin\Node\TableNode;
class TableNodeTest extends \PHPUnit_Framework_TestCase
{
/**
* @expectedException \Behat\Gherkin\Exception\NodeException
*/
public function testConstructorExpectsSameNumberOfColumnsInEachRow()
{
new TableNode(array(
array('username', 'password'),
array('everzet'),
array('antono', 'pa$sword')
));
}
public function constructorTestDataProvider() {
return array(
'One-dimensional array' => array(
array('everzet', 'antono')
),
'Three-dimensional array' => array(
array(array(array('everzet', 'antono')))
)
);
}
/**
* @dataProvider constructorTestDataProvider
* @expectedException \Behat\Gherkin\Exception\NodeException
* @expectedExceptionMessage Table is not two-dimensional.
*/
public function testConstructorExpectsTwoDimensionalArrays($table)
{
new TableNode($table);
}
public function testHashTable()
{
$table = new TableNode(array(
array('username', 'password'),
array('everzet', 'qwerty'),
array('antono', 'pa$sword')
));
$this->assertEquals(
array(
array('username' => 'everzet', 'password' => 'qwerty')
, array('username' => 'antono', 'password' => 'pa$sword')
),
$table->getHash()
);
$table = new TableNode(array(
array('username', 'password'),
array('', 'qwerty'),
array('antono', ''),
array('', '')
));
$this->assertEquals(
array(
array('username' => '', 'password' => 'qwerty'),
array('username' => 'antono', 'password' => ''),
array('username' => '', 'password' => ''),
),
$table->getHash()
);
}
public function testIterator()
{
$table = new TableNode(array(
array('username', 'password'),
array('', 'qwerty'),
array('antono', ''),
array('', ''),
));
$this->assertEquals(
array(
array('username' => '', 'password' => 'qwerty'),
array('username' => 'antono', 'password' => ''),
array('username' => '', 'password' => ''),
),
iterator_to_array($table)
);
}
public function testRowsHashTable()
{
$table = new TableNode(array(
array('username', 'everzet'),
array('password', 'qwerty'),
array('uid', '35'),
));
$this->assertEquals(
array('username' => 'everzet', 'password' => 'qwerty', 'uid' => '35'),
$table->getRowsHash()
);
}
public function testLongRowsHashTable()
{
$table = new TableNode(array(
array('username', 'everzet', 'marcello'),
array('password', 'qwerty', '12345'),
array('uid', '35', '22')
));
$this->assertEquals(array(
'username' => array('everzet', 'marcello'),
'password' => array('qwerty', '12345'),
'uid' => array('35', '22')
), $table->getRowsHash());
}
public function testGetRows()
{
$table = new TableNode(array(
array('username', 'password'),
array('everzet', 'qwerty'),
array('antono', 'pa$sword')
));
$this->assertEquals(array(
array('username', 'password'),
array('everzet', 'qwerty'),
array('antono', 'pa$sword')
), $table->getRows());
}
public function testGetLines()
{
$table = new TableNode(array(
5 => array('username', 'password'),
10 => array('everzet', 'qwerty'),
13 => array('antono', 'pa$sword')
));
$this->assertEquals(array(5, 10, 13), $table->getLines());
}
public function testGetRow()
{
$table = new TableNode(array(
array('username', 'password'),
array('everzet', 'qwerty'),
array('antono', 'pa$sword')
));
$this->assertEquals(array('username', 'password'), $table->getRow(0));
$this->assertEquals(array('antono', 'pa$sword'), $table->getRow(2));
}
public function testGetColumn()
{
$table = new TableNode(array(
array('username', 'password'),
array('everzet', 'qwerty'),
array('antono', 'pa$sword')
));
$this->assertEquals(array('username', 'everzet', 'antono'), $table->getColumn(0));
$this->assertEquals(array('password', 'qwerty', 'pa$sword'), $table->getColumn(1));
$table = new TableNode(array(
array('username'),
array('everzet'),
array('antono')
));
$this->assertEquals(array('username', 'everzet', 'antono'), $table->getColumn(0));
}
public function testGetRowWithLineNumbers()
{
$table = new TableNode(array(
5 => array('username', 'password'),
10 => array('everzet', 'qwerty'),
13 => array('antono', 'pa$sword')
));
$this->assertEquals(array('username', 'password'), $table->getRow(0));
$this->assertEquals(array('antono', 'pa$sword'), $table->getRow(2));
}
public function testGetTable()
{
$table = new TableNode($a = array(
5 => array('username', 'password'),
10 => array('everzet', 'qwerty'),
13 => array('antono', 'pa$sword')
));
$this->assertEquals($a, $table->getTable());
}
public function testGetRowLine()
{
$table = new TableNode(array(
5 => array('username', 'password'),
10 => array('everzet', 'qwerty'),
13 => array('antono', 'pa$sword')
));
$this->assertEquals(5, $table->getRowLine(0));
$this->assertEquals(13, $table->getRowLine(2));
}
public function testGetRowAsString()
{
$table = new TableNode(array(
5 => array('username', 'password'),
10 => array('everzet', 'qwerty'),
13 => array('antono', 'pa$sword')
));
$this->assertEquals('| username | password |', $table->getRowAsString(0));
$this->assertEquals('| antono | pa$sword |', $table->getRowAsString(2));
}
public function testGetTableAsString()
{
$table = new TableNode(array(
5 => array('id', 'username', 'password'),
10 => array('42', 'everzet', 'qwerty'),
13 => array('2', 'antono', 'pa$sword')
));
$expected = <<<TABLE
| id | username | password |
| 42 | everzet | qwerty |
| 2 | antono | pa\$sword |
TABLE;
$this->assertEquals($expected, $table->getTableAsString());
}
public function testFromList()
{
$table = TableNode::fromList(array(
'everzet',
'antono'
));
$expected = new TableNode(array(
array('everzet'),
array('antono'),
));
$this->assertEquals($expected, $table);
}
/**
* @expectedException \Behat\Gherkin\Exception\NodeException
*/
public function testGetTableFromListWithMultidimensionalArrayArgument()
{
TableNode::fromList(array(
array(1, 2, 3),
array(4, 5, 6)
));
}
}

View File

@@ -0,0 +1,291 @@
<?php
namespace Tests\Behat\Gherkin;
use Behat\Gherkin\Lexer;
use Behat\Gherkin\Parser;
use Behat\Gherkin\Keywords\ArrayKeywords;
class ParserExceptionsTest extends \PHPUnit_Framework_TestCase
{
/**
* @var Parser
*/
private $gherkin;
protected function setUp()
{
$keywords = new ArrayKeywords(array(
'en' => array(
'feature' => 'Feature',
'background' => 'Background',
'scenario' => 'Scenario',
'scenario_outline' => 'Scenario Outline',
'examples' => 'Examples',
'given' => 'Given',
'when' => 'When',
'then' => 'Then',
'and' => 'And',
'but' => 'But'
),
'ru' => array(
'feature' => 'Функционал',
'background' => 'Предыстория',
'scenario' => 'Сценарий',
'scenario_outline' => 'Структура сценария',
'examples' => 'Значения',
'given' => 'Допустим',
'when' => 'То',
'then' => 'Если',
'and' => 'И',
'but' => 'Но'
)
));
$this->gherkin = new Parser(new Lexer($keywords));
}
public function testStepRightAfterFeature()
{
$feature = <<<GHERKIN
Feature: Some feature
Given some step-like line
GHERKIN;
$parsed = $this->gherkin->parse($feature);
$this->assertEquals("\n Given some step-like line", $parsed->getDescription());
}
public function testTextInBackground()
{
$feature = <<<GHERKIN
Feature: Behat bug test
Background: remove X to couse bug
Step is red form is not valid
asd
asd
as
da
sd
as
das
d
Scenario: bug user edit date
GHERKIN;
$this->gherkin->parse($feature);
}
public function testTextInScenario()
{
$feature = <<<GHERKIN
Feature: Behat bug test
Scenario: remove X to cause bug
Step is red form is not valid
asd
asd
as
da
sd
as
das
d
Scenario Outline: bug user edit date
Step is red form is not valid
asd
asd
as
da
sd
as
das
d
Examples:
||
GHERKIN;
$feature = $this->gherkin->parse($feature);
$this->assertCount(2, $scenarios = $feature->getScenarios());
$firstTitle = <<<TEXT
remove X to cause bug
Step is red form is not valid
asd
asd
as
da
sd
as
das
d
TEXT;
$this->assertEquals($firstTitle, $scenarios[0]->getTitle());
$secondTitle = <<<TEXT
bug user edit date
Step is red form is not valid
asd
asd
as
da
sd
as
das
d
TEXT;
$this->assertEquals($secondTitle, $scenarios[1]->getTitle());
}
/**
* @expectedException \Behat\Gherkin\Exception\ParserException
*/
public function testAmbigiousLanguage()
{
$feature = <<<GHERKIN
# language: en
# language: ru
Feature: Some feature
Given something wrong
GHERKIN;
$this->gherkin->parse($feature);
}
/**
* @expectedException \Behat\Gherkin\Exception\ParserException
*/
public function testEmptyOutline()
{
$feature = <<<GHERKIN
Feature: Some feature
Scenario Outline:
GHERKIN;
$this->gherkin->parse($feature);
}
/**
* @expectedException \Behat\Gherkin\Exception\ParserException
*/
public function testWrongTagPlacement()
{
$feature = <<<GHERKIN
Feature: Some feature
Scenario:
Given some step
@some_tag
Then some additional step
GHERKIN;
$this->gherkin->parse($feature);
}
/**
* @expectedException \Behat\Gherkin\Exception\ParserException
*/
public function testBackgroundWithTag()
{
$feature = <<<GHERKIN
Feature: Some feature
@some_tag
Background:
Given some step
GHERKIN;
$this->gherkin->parse($feature);
}
/**
* @expectedException \Behat\Gherkin\Exception\ParserException
*/
public function testEndlessPyString()
{
$feature = <<<GHERKIN
Feature:
Scenario:
Given something with:
"""
some text
GHERKIN;
$this->gherkin->parse($feature);
}
/**
* @expectedException \Behat\Gherkin\Exception\ParserException
*/
public function testWrongStepType()
{
$feature = <<<GHERKIN
Feature:
Scenario:
Given some step
Aaand some step
GHERKIN;
$this->gherkin->parse($feature);
}
/**
* @expectedException \Behat\Gherkin\Exception\ParserException
*/
public function testMultipleBackgrounds()
{
$feature = <<<GHERKIN
Feature:
Background:
Given some step
Background:
Aaand some step
GHERKIN;
$this->gherkin->parse($feature);
}
/**
* @expectedException \Behat\Gherkin\Exception\ParserException
*/
public function testMultipleFeatures()
{
$feature = <<<GHERKIN
Feature:
Feature:
GHERKIN;
$this->gherkin->parse($feature);
}
/**
* @expectedException \Behat\Gherkin\Exception\ParserException
*/
public function testTableWithoutRightBorder()
{
$feature = <<<GHERKIN
Feature:
Scenario:
Given something with:
| foo | bar
| 42 | 42
GHERKIN;
$this->gherkin->parse($feature);
}
}

View File

@@ -0,0 +1,147 @@
<?php
namespace Tests\Behat\Gherkin;
use Behat\Gherkin\Node\FeatureNode;
use Behat\Gherkin\Lexer;
use Behat\Gherkin\Parser;
use Behat\Gherkin\Keywords\ArrayKeywords;
use Behat\Gherkin\Loader\YamlFileLoader;
class ParserTest extends \PHPUnit_Framework_TestCase
{
private $gherkin;
private $yaml;
public function parserTestDataProvider()
{
$data = array();
foreach (glob(__DIR__ . '/Fixtures/etalons/*.yml') as $file) {
$testname = basename($file, '.yml');
$data[] = array($testname);
}
return $data;
}
/**
* @dataProvider parserTestDataProvider
*
* @param string $fixtureName name of the fixture
*/
public function testParser($fixtureName)
{
$etalon = $this->parseEtalon($fixtureName . '.yml');
$features = $this->parseFixture($fixtureName . '.feature');
$this->assertInternalType('array', $features);
$this->assertEquals(1, count($features));
$fixture = $features[0];
$this->assertEquals($etalon, $fixture);
}
public function testParserResetsTagsBetweenFeatures()
{
$parser = $this->getGherkinParser();
$parser->parse(<<<FEATURE
Feature:
Scenario:
Given step
@skipped
FEATURE
);
$feature2 = $parser->parse(<<<FEATURE
Feature:
Scenario:
Given step
FEATURE
);
$this->assertFalse($feature2->hasTags());
}
protected function getGherkinParser()
{
if (null === $this->gherkin) {
$keywords = new ArrayKeywords(array(
'en' => array(
'feature' => 'Feature',
'background' => 'Background',
'scenario' => 'Scenario',
'scenario_outline' => 'Scenario Outline',
'examples' => 'Examples',
'given' => 'Given',
'when' => 'When',
'then' => 'Then',
'and' => 'And',
'but' => 'But'
),
'ru' => array(
'feature' => 'Функционал',
'background' => 'Предыстория',
'scenario' => 'Сценарий',
'scenario_outline' => 'Структура сценария',
'examples' => 'Значения',
'given' => 'Допустим',
'when' => 'То',
'then' => 'Если',
'and' => 'И',
'but' => 'Но'
),
'ja' => array (
'feature' => 'フィーチャ',
'background' => '背景',
'scenario' => 'シナリオ',
'scenario_outline' => 'シナリオアウトライン',
'examples' => '例|サンプル',
'given' => '前提<',
'when' => 'もし<',
'then' => 'ならば<',
'and' => 'かつ<',
'but' => 'しかし<'
)
));
$this->gherkin = new Parser(new Lexer($keywords));
}
return $this->gherkin;
}
protected function getYamlParser()
{
if (null === $this->yaml) {
$this->yaml = new YamlFileLoader();
}
return $this->yaml;
}
protected function parseFixture($fixture)
{
$file = __DIR__ . '/Fixtures/features/' . $fixture;
return array($this->getGherkinParser()->parse(file_get_contents($file), $file));
}
protected function parseEtalon($etalon)
{
$features = $this->getYamlParser()->load(__DIR__ . '/Fixtures/etalons/' . $etalon);
$feature = $features[0];
return new FeatureNode(
$feature->getTitle(),
$feature->getDescription(),
$feature->getTags(),
$feature->getBackground(),
$feature->getScenarios(),
$feature->getKeyword(),
$feature->getLanguage(),
__DIR__ . '/Fixtures/features/' . basename($etalon, '.yml') . '.feature',
$feature->getLine()
);
}
}