mirror of
https://github.com/twigphp/Twig.git
synced 2026-09-13 19:06:40 +00:00
merged branch Tobion/patch-4 (PR #614)
Commits -------a15e8f7typo again2561aa2typofaa90c9updated doc for random functionfe66358added tests for random function6f5ceeeMade the random function more versatile Discussion ---------- Made the random function more versatile The point is to meet user expectations and to make it more versatile, so it works under more circumstances. At the moment the random function does only return the supplied parameter when it's not an array. That is not very useful. With this PR it will behave like random() => integer as with mt_rand() random(5) => integer between 0 and 5 as with mt_rand(0, 5) random('foobar') => random character from 'foobar' random(array(...)) => random element I will add tests and documentation if you accept this PR. --------------------------------------------------------------------------- by fabpot at 2012-01-26T07:29:35Z Looks good to me. Can you update the docs and add some unit tests? --------------------------------------------------------------------------- by Tobion at 2012-01-26T11:50:17Z ready
This commit is contained in:
@@ -10,6 +10,7 @@
|
||||
* added a date function to ease date comparison
|
||||
* fixed unary operators precedence
|
||||
* added recursive parsing support in the parser
|
||||
* added string and integer handling for the random function
|
||||
|
||||
* 1.5.1 (2012-01-05)
|
||||
|
||||
|
||||
@@ -4,8 +4,20 @@
|
||||
.. versionadded:: 1.5
|
||||
The random function was added in Twig 1.5.
|
||||
|
||||
The ``random`` function returns a random item from a sequence:
|
||||
.. versionadded:: 1.6
|
||||
String and integer handling was added in Twig 1.6.
|
||||
|
||||
The ``random`` function returns a random value depending on the supplied parameter type:
|
||||
|
||||
* a random item from a Traversable or array
|
||||
* a random character from a string
|
||||
* a random integer between 0 and the integer parameter (inclusive)
|
||||
|
||||
.. code-block:: jinja
|
||||
|
||||
{{ random(['apple', 'orange', 'citrus']) }}
|
||||
{{ random(['apple', 'orange', 'citrus']) }} {# example output: orange #}
|
||||
{{ random('ABC') }} {# example output: C #}
|
||||
{{ random() }} {# example output: 15386094 (works as native PHP `mt_rand`_ function) #}
|
||||
{{ random(5) }} {# example output: 3 #}
|
||||
|
||||
.. _`mt_rand`: http://php.net/mt_rand
|
||||
|
||||
@@ -283,20 +283,35 @@ function twig_cycle($values, $i)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a random item from sequence.
|
||||
* Returns a random value depending on the supplied parameter type:
|
||||
* - a random item from a Traversable or array
|
||||
* - a random character from a string
|
||||
* - a random integer between 0 and the integer parameter
|
||||
*
|
||||
* @param Iterator|array $values An array or an ArrayAccess instance
|
||||
* @param Traversable|array|int|string $values The values to pick a random item from
|
||||
*
|
||||
* @return mixed A random value from the given sequence
|
||||
*/
|
||||
function twig_random($values)
|
||||
function twig_random($values = null)
|
||||
{
|
||||
if (!is_array($values) && !$values instanceof Traversable) {
|
||||
return $values;
|
||||
if (null === $values) {
|
||||
return mt_rand();
|
||||
}
|
||||
|
||||
if (is_object($values)) {
|
||||
if (is_int($values) || is_float($values)) {
|
||||
return mt_rand(0, $values);
|
||||
}
|
||||
|
||||
if ($values instanceof Traversable) {
|
||||
$values = iterator_to_array($values);
|
||||
} elseif (is_string($values)) {
|
||||
// unicode version of str_split()
|
||||
// split at all positions, but not after the start and not before the end
|
||||
$values = preg_split('/(?<!^)(?!$)/u', $values);
|
||||
}
|
||||
|
||||
if (!is_array($values)) {
|
||||
return $values;
|
||||
}
|
||||
|
||||
if (0 === count($values)) {
|
||||
|
||||
@@ -11,17 +11,61 @@
|
||||
|
||||
class Twig_Tests_Extension_CoreTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testRandomFunction()
|
||||
/**
|
||||
* @dataProvider getRandomFunctionTestData
|
||||
*/
|
||||
public function testRandomFunction($value, $expectedInArray)
|
||||
{
|
||||
$items = array('apple', 'orange', 'citrus');
|
||||
$values = array(
|
||||
$items,
|
||||
new ArrayObject($items),
|
||||
);
|
||||
foreach ($values as $value) {
|
||||
for ($i = 0; $i < 100; $i++) {
|
||||
$this->assertTrue(in_array(twig_random($value), $items));
|
||||
}
|
||||
for ($i = 0; $i < 100; $i++) {
|
||||
$this->assertTrue(in_array(twig_random($value), $expectedInArray, true)); // assertContains() would not consider the type
|
||||
}
|
||||
}
|
||||
|
||||
public function getRandomFunctionTestData()
|
||||
{
|
||||
return array(
|
||||
array( // array
|
||||
array('apple', 'orange', 'citrus'),
|
||||
array('apple', 'orange', 'citrus'),
|
||||
),
|
||||
array( // Traversable
|
||||
new ArrayObject(array('apple', 'orange', 'citrus')),
|
||||
array('apple', 'orange', 'citrus'),
|
||||
),
|
||||
array( // unicode string
|
||||
'Ä€é',
|
||||
array('Ä', '€', 'é'),
|
||||
),
|
||||
array( // numeric but string
|
||||
'123',
|
||||
array('1', '2', '3'),
|
||||
),
|
||||
array( // integer
|
||||
5,
|
||||
range(0, 5, 1),
|
||||
),
|
||||
array( // float
|
||||
5.9,
|
||||
range(0, 5, 1),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
public function testRandomFunctionWithoutParameter()
|
||||
{
|
||||
$max = mt_getrandmax();
|
||||
|
||||
for ($i = 0; $i < 100; $i++) {
|
||||
$val = twig_random();
|
||||
$this->assertTrue(is_int($val) && $val >= 0 && $val <= $max);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException Twig_Error_Runtime
|
||||
*/
|
||||
public function testRandomFunctionOfEmptyArrayThrowsException()
|
||||
{
|
||||
twig_random(array());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user