Commit 970fdb9e authored by catch's avatar catch

Issue #2032453 by alexpott, tsphethean: Fixed WebTestBase::randomString...

Issue #2032453 by alexpott, tsphethean: Fixed WebTestBase::randomString returning a string containing a $ followed by a number causes assertLink() to fail it's xpath match.
parent 42ca6403
......@@ -27,14 +27,14 @@ class Random {
*
* @var array
*/
static protected $strings = array();
protected $strings = array();
/**
* A list of unique names generated by name().
*
* @var array
*/
static protected $names = array();
protected $names = array();
/**
* Generates a random string of ASCII characters of codes 32 to 126.
......@@ -48,15 +48,20 @@ class Random {
* @param bool $unique
* (optional) If TRUE ensures that the random string returned is unique.
* Defaults to FALSE.
* @param callable $validator
* (optional) A callable to validate the the string. Defaults to NULL.
*
* @return string
* Randomly generated string.
*
* @see \Drupal\Component\Utility\Random::name()
*/
public static function string($length = 8, $unique = FALSE) {
public function string($length = 8, $unique = FALSE, $validator = NULL) {
$counter = 0;
// Continue to loop if $unique is TRUE and the generated string is not
// unique or if $validator is a callable that returns FALSE. To generate a
// random string this loop must be carried out at least once.
do {
if ($counter == static::MAXIMUM_TRIES) {
throw new \RuntimeException('Unable to generate a unique random name');
......@@ -66,10 +71,20 @@ public static function string($length = 8, $unique = FALSE) {
$str .= chr(mt_rand(32, 126));
}
$counter++;
} while ($unique && isset(static::$strings[$str]));
$continue = FALSE;
if ($unique) {
$continue = isset($this->strings[$str]);
}
if (!$continue && is_callable($validator)) {
// If the validator callback returns FALSE generate another random
// string.
$continue = !call_user_func($validator, $str);
}
} while ($continue);
if ($unique) {
static::$strings[$str] = TRUE;
$this->strings[$str] = TRUE;
}
return $str;
......@@ -95,7 +110,7 @@ public static function string($length = 8, $unique = FALSE) {
*
* @see \Drupal\Component\Utility\Random::string()
*/
public static function name($length = 8, $unique = FALSE) {
public function name($length = 8, $unique = FALSE) {
$values = array_merge(range(65, 90), range(97, 122), range(48, 57));
$max = count($values) - 1;
$counter = 0;
......@@ -109,10 +124,10 @@ public static function name($length = 8, $unique = FALSE) {
$str .= chr($values[mt_rand(0, $max)]);
}
$counter++;
} while ($unique && isset(static::$names[$str]));
} while ($unique && isset($this->names[$str]));
if ($unique) {
static::$names[$str] = TRUE;
$this->names[$str] = TRUE;
}
return $str;
......@@ -128,11 +143,11 @@ public static function name($length = 8, $unique = FALSE) {
* The generated object, with the specified number of random keys. Each key
* has a random string value.
*/
public static function object($size = 4) {
public function object($size = 4) {
$object = new \stdClass();
for ($i = 0; $i < $size; $i++) {
$random_key = static::name();
$random_value = static::string();
$random_key = $this->name();
$random_value = $this->string();
$object->{$random_key} = $random_value;
}
return $object;
......
......@@ -180,6 +180,13 @@
*/
protected $configImporter;
/**
* The random generator.
*
* @var \Drupal\Component\Utility\Random
*/
protected $randomGenerator;
/**
* Constructor for Test.
*
......@@ -1194,7 +1201,38 @@ protected function settingsSet($name, $value) {
* @see \Drupal\Component\Utility\Random::string()
*/
public function randomString($length = 8) {
return Random::string($length, TRUE);
return $this->getRandomGenerator()->string($length, TRUE, array($this, 'randomStringValidate'));
}
/**
* Callback for random string validation.
*
* @see \Drupal\Component\Utility\Random::string()
*
* @param string $string
* The random string to validate.
*
* @return bool
* TRUE if the random string is valid, FALSE if not.
*/
public function randomStringValidate($string) {
// Consecutive spaces causes issues for
// Drupal\simpletest\WebTestBase::assertLink().
if (preg_match('/\s{2,}/', $string)) {
return FALSE;
}
// Starting with a space means that length might not be what is expected.
if (preg_match('/^\s/', $string)) {
return FALSE;
}
// Ending with a space means that length might not be what is expected.
if (preg_match('/\s$/', $string)) {
return FALSE;
}
return TRUE;
}
/**
......@@ -1212,7 +1250,7 @@ public function randomString($length = 8) {
* @see \Drupal\Component\Utility\Random::name()
*/
public function randomName($length = 8) {
return Random::name($length, TRUE);
return $this->getRandomGenerator()->name($length, TRUE);
}
/**
......@@ -1228,7 +1266,20 @@ public function randomName($length = 8) {
* @see \Drupal\Component\Utility\Random::object()
*/
public function randomObject($size = 4) {
return Random::object($size);
return $this->getRandomGenerator()->object($size);
}
/**
* Gets the random generator for the utility methods.
*
* @return \Drupal\Component\Utility\Random
* The random generator
*/
protected function getRandomGenerator() {
if (!is_object($this->randomGenerator)) {
$this->randomGenerator = new Random();
}
return $this->randomGenerator;
}
/**
......
<?php
/**
* @file
* Contains \Drupal\simpletest\TestBaseTest.
*/
namespace Drupal\simpletest\Tests;
use Drupal\Tests\UnitTestCase;
/**
* Tests helper methods provided by the abstract TestBase class.
*/
class TestBaseTest extends UnitTestCase {
/**
* A stub built using the TestBase class.
*
* @var \PHPUnit_Framework_MockObject_MockObject
*/
protected $stub;
public static function getInfo() {
return array(
'name' => 'TestBase helper functions test',
'description' => 'Test helper functions provided by the TestBase abstract class.',
'group' => 'Simpletest',
);
}
protected function setUp() {
$this->stub = $this->getMockForAbstractClass('Drupal\simpletest\TestBase');
}
/**
* Provides data for the random string validation test.
*
* @return array
* An array of values passed to the test method.
*/
public function randomStringValidateProvider () {
return array(
array(' curry paste', FALSE),
array('curry paste ', FALSE),
array('curry paste', FALSE),
array('curry paste', FALSE),
array('curry paste', TRUE),
array('thai green curry paste', TRUE),
);
}
/**
* Tests the random strings validation rules.
*
* @param string $string
* The string to validate.
* @param bool $expected
* The expected result of the validation.
*
* @see \Drupal\simpletest\TestBase::randomStringValidate().
*
* @dataProvider randomStringValidateProvider
*/
public function testRandomStringValidate($string, $expected) {
$actual = $this->stub->randomStringValidate($string);
$this->assertEquals($expected, $actual);
}
}
......@@ -18,6 +18,15 @@
*/
class RandomTest extends UnitTestCase {
/**
* The first random string passed to the test callback.
*
* @see \Drupal\Tests\Component\Utility\RandomTest::_RandomStringValidate()
*
* @var string
*/
protected $firstStringGenerated = '';
public static function getInfo() {
return array(
'name' => 'Random data generation tests',
......@@ -27,28 +36,30 @@ public static function getInfo() {
}
/**
* Tests unique random name generation.
* Tests unique random string generation.
*
* @see \Drupal\Component\Utility\Random::name()
* @see \Drupal\Component\Utility\Random::string()
*/
public function testRandomStringUniqueness() {
$strings = array();
$random = new Random();
for ($i = 0; $i <= 50; $i++) {
$str = Random::string(1, TRUE);
$str = $random->string(1, TRUE);
$this->assertFalse(isset($strings[$str]), String::format('Generated duplicate random string !string', array('!string' => $str)));
$strings[$str] = TRUE;
}
}
/**
* Tests unique random string generation.
* Tests unique random name generation.
*
* @see \Drupal\Component\Utility\Random::string()
* @see \Drupal\Component\Utility\Random::name()
*/
public function testRandomNamesUniqueness() {
$names = array();
$random = new Random();
for ($i = 0; $i <= 10; $i++) {
$str = Random::name(1, TRUE);
$str = $random->name(1, TRUE);
$this->assertFalse(isset($names[$str]), String::format('Generated duplicate random name !name', array('!name' => $str)));
$names[$str] = TRUE;
}
......@@ -64,8 +75,9 @@ public function testRandomNamesUniqueness() {
public function testRandomNameException() {
// There are fewer than 100 possibilities so an exception should occur to
// prevent infinite loops.
$random = new Random();
for ($i = 0; $i <= 100; $i++) {
$str = Random::name(1, TRUE);
$str = $random->name(1, TRUE);
$names[$str] = TRUE;
}
}
......@@ -80,8 +92,9 @@ public function testRandomNameException() {
public function testRandomStringException() {
// There are fewer than 100 possibilities so an exception should occur to
// prevent infinite loops.
$random = new Random();
for ($i = 0; $i <= 100; $i++) {
$str = Random::string(1, TRUE);
$str = $random->string(1, TRUE);
$names[$str] = TRUE;
}
}
......@@ -94,8 +107,9 @@ public function testRandomStringException() {
public function testRandomNameNonUnique() {
// There are fewer than 100 possibilities if we were forcing uniqueness so
// exception would occur.
$random = new Random();
for ($i = 0; $i <= 100; $i++) {
Random::name(1);
$random->name(1);
}
$this->assertTrue(TRUE, 'No exception thrown when uniqueness is not enforced.');
}
......@@ -108,8 +122,9 @@ public function testRandomNameNonUnique() {
public function testRandomStringNonUnique() {
// There are fewer than 100 possibilities if we were forcing uniqueness so
// exception would occur.
$random = new Random();
for ($i = 0; $i <= 100; $i++) {
Random::string(1);
$random->string(1);
}
$this->assertTrue(TRUE, 'No exception thrown when uniqueness is not enforced.');
}
......@@ -122,10 +137,42 @@ public function testRandomStringNonUnique() {
public function testRandomObject() {
// For values of 0 and 1 \Drupal\Component\Utility\Random::object() will
// have different execution paths.
$random = new Random();
for ($i = 0; $i <= 1; $i++) {
$obj = Random::object($i);
$obj = $random->object($i);
$this->assertEquals($i, count(get_object_vars($obj)), 'Generated random object has expected number of properties');
}
}
/**
* Tests random string validation callbacks.
*
* @see \Drupal\Component\Utility\Random::name()
*/
public function testRandomStringValidator() {
$random = new Random();
$this->firstStringGenerated = '';
$str = $random->string(1, TRUE, array($this, '_RandomStringValidate'));
$this->assertNotEquals($this->firstStringGenerated, $str);
}
/**
* Callback for random string validation.
*
* @see \Drupal\Component\Utility\Random::name()
* @see \Drupal\Tests\Component\Utility\RandomTest::testRandomStringValidator()
*
* @param string $string
* The random string to validate.
*
* @return bool
* TRUE if the random string is valid, FALSE if not.
*/
public function _RandomStringValidate($string) {
if (empty($this->firstStringGenerated)) {
$this->firstStringGenerated = $string;
return FALSE;
}
return TRUE;
}
}
......@@ -14,6 +14,13 @@
*/
abstract class UnitTestCase extends \PHPUnit_Framework_TestCase {
/**
* The random generator.
*
* @var \Drupal\Component\Utility\Random
*/
protected $randomGenerator;
/**
* This method exists to support the simpletest UI runner.
*
......@@ -43,12 +50,26 @@ public static function getInfo() {
* @return string
* Randomly generated unique string.
*
* @see \Drupal\Component\Utility::string()
* @see \Drupal\Component\Utility\Random::name()
*/
public function randomName($length = 8) {
return Random::name($length, TRUE);
return $this->getRandomGenerator()->name($length, TRUE);
}
/**
* Gets the random generator for the utility methods.
*
* @return \Drupal\Component\Utility\Random
* The random generator
*/
protected function getRandomGenerator() {
if (!is_object($this->randomGenerator)) {
$this->randomGenerator = new Random();
}
return $this->randomGenerator;
}
/**
* Returns a stub config factory that behaves according to the passed in array.
*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment