- Sponsor
-
Notifications
You must be signed in to change notification settings - Fork 192
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #481 from jhedstrom/293-random-generator
Adds a RandomContext for generating random strings in steps.
Showing
5 changed files
with
131 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
@api @d8 @random | ||
Feature: RandomContext functionality | ||
In order to prove the RandomContext is functional at transforming variables | ||
As a developer | ||
I need to use random variables in scenarios | ||
|
||
# This will fail on the second scenario if random transforms are not functional. | ||
Scenario: Create a first user | ||
Given I am at "/user/register" | ||
And I fill in "Email address" with "<?user>@example.com" | ||
And I fill in "Username" with "<?user>" | ||
When I press "Create new account" | ||
Then an email has been sent to "<?user>@example.com" with the subject "Account details for <?user>" | ||
|
||
Scenario: Create the second user | ||
Given I am at "/user/register" | ||
And I fill in "Email address" with "<?user>@example.com" | ||
And I fill in "Username" with "<?user>" | ||
When I press "Create new account" | ||
Then an email has been sent to "<?user>@example.com" with the subject "Account details for <?user>" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<?php | ||
|
||
namespace spec\Drupal\DrupalExtension\Context; | ||
|
||
use Drupal\DrupalExtension\Context\RandomContext; | ||
use PhpSpec\ObjectBehavior; | ||
use Prophecy\Argument; | ||
|
||
class RandomContextSpec extends ObjectBehavior | ||
{ | ||
function it_is_initializable() | ||
{ | ||
$this->shouldHaveType(RandomContext::class); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
<?php | ||
|
||
namespace Drupal\DrupalExtension\Context; | ||
|
||
use Behat\Behat\Hook\Scope\AfterScenarioScope; | ||
use Behat\Behat\Hook\Scope\BeforeScenarioScope; | ||
|
||
/** | ||
* Class RandomContext | ||
* @package Drupal\DrupalExtension\Context | ||
* | ||
* Transform tokens into random variables. | ||
*/ | ||
class RandomContext extends RawDrupalContext | ||
{ | ||
/** | ||
* Tracks variable names for consistent replacement during a given scenario. | ||
* | ||
* @var array | ||
*/ | ||
protected $values = []; | ||
|
||
/** | ||
* The regex to use for variable replacement. | ||
* | ||
* This matches placeholders in steps of the form `Given a string <?random>`. | ||
*/ | ||
const VARIABLE_REGEX = '#(\<\?.*?\>)#'; | ||
|
||
/** | ||
* Transform random variables. | ||
* | ||
* @Transform #([^<]*\<\?.*\>[^>]*)# | ||
*/ | ||
public function transformVariables($message) | ||
{ | ||
$patterns = []; | ||
$replacements = []; | ||
|
||
preg_match_all(static::VARIABLE_REGEX, $message, $matches); | ||
foreach ($matches[0] as $variable) { | ||
$replacements[] = $this->values[$variable]; | ||
$patterns[] = '#' . preg_quote($variable) . '#'; | ||
} | ||
$message = preg_replace($patterns, $replacements, $message); | ||
|
||
return $message; | ||
} | ||
|
||
/** | ||
* Set values for each random variable found in the current scenario. | ||
* | ||
* @BeforeScenario | ||
*/ | ||
public function beforeScenarioSetVariables(BeforeScenarioScope $scope) | ||
{ | ||
$steps = []; | ||
if ($scope->getFeature()->hasBackground()) { | ||
$steps = $scope->getFeature()->getBackground()->getSteps(); | ||
} | ||
$steps = array_merge($steps, $scope->getScenario()->getSteps()); | ||
foreach ($steps as $step) { | ||
preg_match_all(static::VARIABLE_REGEX, $step->getText(), $matches); | ||
$variables_found = $matches[0]; | ||
// Find variables in are TableNodes or PyStringNodes. | ||
$step_argument = $step->getArguments(); | ||
if (!empty($step_argument) && $step_argument[0] instanceof TableNode) { | ||
preg_match_all(static::VARIABLE_REGEX, $step_argument[0]->getTableAsString(), $matches); | ||
$variables_found = array_filter(array_merge($variables_found, $matches[0])); | ||
} | ||
foreach ($variables_found as $variable_name) { | ||
if (!isset($this->values[$variable_name])) { | ||
$value = $this->getDriver()->getRandom()->name(10); | ||
// Value forced to lowercase to ensure it is machine-readable. | ||
$this->values[$variable_name] = strtolower($value); | ||
} | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* Reset variables after the scenario. | ||
* | ||
* @AfterScenario | ||
*/ | ||
public function afterScenarioResetVariables(AfterScenarioScope $scope) | ||
{ | ||
$this->values = []; | ||
} | ||
} |