数组 单元测试

pull/1/head
韩天峰 8 months ago
parent 257cc2d796
commit 204908f6e9
  1. 3
      run-tests.php
  2. 89
      src/Php/Translator.php
  3. 6
      tests/core/func/001.phpt
  4. 24
      tests/core/func/002.phpt
  5. 287
      tests/core/func/003.phpt
  6. 62
      tests/core/func/004.phpt
  7. 19
      tests/core/func/005.phpt
  8. 35
      tests/core/func/005a.phpt
  9. 26
      tests/core/func/006.phpt
  10. 22
      tests/core/func/007.phpt
  11. 16
      tests/core/func/008.phpt
  12. 16
      tests/core/func/009.phpt
  13. 78
      tests/core/func/010.phpt
  14. 9
      tests/core/func/011.phpt
  15. 12
      tests/core/func/bug64523.phpt
  16. 18
      tests/core/func/ini_alter.phpt
  17. 223
      tests/core/strings/001.phpt
  18. 89
      tests/core/strings/002.phpt
  19. 17
      tests/core/strings/004.phpt
  20. 9
      tests/core/strings/offsets_chaining_1.phpt
  21. 80
      tests/zend/add_001.phpt
  22. 122
      tests/zend/array_unpack/basic.phpt
  23. 23
      tests/zend/concat/concat_002.phpt
  24. 40
      tests/zend/concat/concat_003.phpt
  25. 21
      tests/zend/foreach/foreach_002.phpt
  26. 73
      tests/zend/foreach/foreach_003.phpt
  27. 22
      tests/zend/foreach/foreach_005.phpt
  28. 20
      tests/zend/foreach/foreach_006.phpt
  29. 13
      tests/zend/foreach/foreach_007.phpt

@ -2467,8 +2467,6 @@ COMMAND $cmd
$stdin = $test->hasSection('STDIN') ? $test->getSection('STDIN') : null;
$out = system_with_timeout($cmd, $env, $stdin, $captureStdIn, $captureStdOut, $captureStdErr);
unlink('./' . $bin_file);
$junit->stopTimer($shortname);
$hrtime = hrtime();
$time = $hrtime[0] * 1000000000 + $hrtime[1] - $startTime;
@ -2628,6 +2626,7 @@ COMMAND $cmd
$file = substr($test_file, 0, strlen($test_file) - 4);
@unlink($file . '.cc');
@unlink($file . '.cc.o');
@unlink('./' . $bin_file);
}
@unlink($tmp_post);

@ -356,6 +356,8 @@ class Translator extends \PhpAot\Core\Translator
var_dump($expr);
}
switch ($type) {
case 'Expr_Isset':
return $this->parseIsset($expr);
case 'Expr_Assign':
return $this->parseAssign($expr);
case 'Expr_Print':
@ -400,6 +402,8 @@ class Translator extends \PhpAot\Core\Translator
return $this->parseAssignOpDiv($expr);
case 'Expr_AssignOp_Mod':
return $this->parseAssignOpMod($expr);
case 'Expr_AssignOp_Concat':
return $this->parseAssignOpConcat($expr);
case 'Expr_AssignOp_ShiftRight':
return $this->parseAssignOpShiftRight($expr);
case 'Expr_BinaryOp_Mul':
@ -708,22 +712,44 @@ class Translator extends \PhpAot\Core\Translator
if (count($items) === 0) {
return self::TYPE_ARRAY .'{}';
}
$list = [];
$this->indentLevel++;
// 检查一下数组的赋值方式,是否为索引数组或关联数组,若是混杂模式,需要改为多行插入
$assocArray = (bool)$items[0]->key;
$mixed = false;
foreach ($items as $item) {
if ($item->key) {
$list[] = $this->getIndent() . '{ ' . $this->parseIdentifier($item->key) . ', ' .
self::TYPE_VAR . '(' . $this->parseIdentifier($item->value) . ') }';
if (!$assocArray) {
$mixed = true;
break;
}
} else {
$value = $this->parseIdentifier($item->value);
$list[] = $this->getIndent() . self::TYPE_VAR . '(' . $value . ')';
if ($assocArray) {
$mixed = true;
break;
}
}
}
$this->indentLevel--;
return self::TYPE_ARRAY . '{' . PHP_EOL .
implode(', ' . PHP_EOL, $list) . PHP_EOL .
$this->getIndent() .
'}';
if ($mixed) {
abort($node);
} else {
$list = [];
$this->indentLevel++;
foreach ($items as $item) {
if ($item->key) {
$list[] = $this->getIndent() . '{ ' . $this->parseIdentifier($item->key) . ', ' .
self::TYPE_VAR . '(' . $this->parseIdentifier($item->value) . ') }';
} else {
$value = $this->parseIdentifier($item->value);
$list[] = $this->getIndent() . self::TYPE_VAR . '(' . $value . ')';
}
}
$this->indentLevel--;
return self::TYPE_ARRAY . '{' . PHP_EOL .
implode(', ' . PHP_EOL, $list) . PHP_EOL .
$this->getIndent() .
'}';
}
}
private function parseType($type)
@ -809,6 +835,13 @@ class Translator extends \PhpAot\Core\Translator
return 'php::concat(' . $left . ', ' . $right . ')';
}
private function parseAssignOpConcat(mixed $expr): string
{
$var = $this->parseIdentifier($expr->var);
$value = $this->parseIdentifier($expr->expr);
return $var . '.append(' . $value . ')';
}
private function parseFor(mixed $v): string
{
$init = $v->init;
@ -1367,9 +1400,8 @@ class Translator extends \PhpAot\Core\Translator
return '"' . $this->escapeString($this->file) . '"';
}
private function parseForeach(Node $node)
private function parseForeach(Node $node): string
{
$expr = $this->parseIdentifier($node->expr);
if ($node->keyVar) {
$keyVar = $this->parseIdentifier($node->keyVar);
}
@ -1380,6 +1412,14 @@ class Translator extends \PhpAot\Core\Translator
$stmts = $node->stmts;
$code = '';
$this->regressionDetection = true;
$expr = $this->parseIdentifier($node->expr);
$this->regressionDetection = false;
if ($this->beforeStmtLines) {
foreach ($this->beforeStmtLines as $line) {
$code .= $line . PHP_EOL;
}
}
$code .= self::TYPE_ARRAY . " $iteratorVar = " . $expr . ';' . PHP_EOL;
$code .= 'for (auto iter = ' . $iteratorVar . '.begin(); iter != ' . $iteratorVar . '.end(); ++iter) {' . PHP_EOL;
@ -1528,12 +1568,27 @@ class Translator extends \PhpAot\Core\Translator
private function parseScalarFloat(Node $expr): string
{
if (is_nan($expr->value)) {
$value = $expr->value;
if (is_nan($value)) {
return self::VALUE_NAN;
} elseif (is_infinite($expr->value)) {
return $expr->value > 0 ? self::VALUE_INF : '-' . self::VALUE_INF;
} elseif (is_infinite($value)) {
return $value > 0 ? self::VALUE_INF : '-' . self::VALUE_INF;
} else if (floor($value) == $value && abs($value) < 1e15) {
return number_format($value, 1, '.', '');
} else {
return number_format($expr->value, 1, '.', '');
return $value;
}
}
private function parseIsset(mixed $expr)
{
$vars = $expr->vars;
foreach($vars as $var) {
if ($var->getType() === 'Expr_Variable') {
return $this->hasVar($var->name) ? 'true' : 'false';
} else {
abort($var);
}
}
}
}

@ -0,0 +1,6 @@
--TEST--
Strlen() function test
--FILE--
<?php echo strlen("abcdef");?>
--EXPECT--
6

@ -0,0 +1,24 @@
--TEST--
Static variables in functions
--FILE--
<?php
function blah()
{
static $hey=0,$yo=0;
echo "hey=".$hey++.", ",$yo--."\n";
}
function main() {
blah();
blah();
blah();
if (isset($hey) || isset($yo)) {
echo "Local variables became global :(\n";
}
}
?>
--EXPECT--
hey=0, 0
hey=1, -1
hey=2, -2

@ -0,0 +1,287 @@
--TEST--
General function test
--FILE--
<?php
function a()
{
echo "hey\n";
}
function b($i)
{
echo "$i\n";
}
function c($i, $j)
{
echo "Counting from $i to $j\n";
for ($k=$i; $k<=$j; $k++) {
echo "$k\n";
}
}
function factorial($n)
{
if ($n==0 || $n==1) {
return 1;
} else {
return factorial($n-1)*$n;
}
}
function factorial2($start, $n)
{
if ($n<=$start) {
return $start;
} else {
return factorial2($start,$n-1)*$n;
}
}
function call_fact()
{
echo "(it should break at 5...)\n";
for ($i=0; $i<=10; $i++) {
if ($i == 5) break;
$n=factorial($i);
echo "factorial($i) = $n\n";
}
}
function return4() { return 4; }
function return7() { return 7; }
function andi($i, $j)
{
for ($k=$i ; $k<=$j ; $k++) {
if ($k >5) continue;
echo "$k\n";
}
}
function main() {
a();
b("blah");
a();
b("blah");
c(7,14);
a();
for ($k=0; $k<10; $k++) {
for ($i=0; $i<=10; $i++) {
$n=factorial($i);
echo "factorial($i) = $n\n";
}
}
echo "and now, from a function...\n";
for ($k=0; $k<10; $k++) {
call_fact();
}
echo "------\n";
$result = factorial(factorial(3));
echo "$result\n";
$result = factorial2(return4(),return7());
echo "$result\n";
andi (3,10);
}
?>
--EXPECT--
hey
blah
hey
blah
Counting from 7 to 14
7
8
9
10
11
12
13
14
hey
factorial(0) = 1
factorial(1) = 1
factorial(2) = 2
factorial(3) = 6
factorial(4) = 24
factorial(5) = 120
factorial(6) = 720
factorial(7) = 5040
factorial(8) = 40320
factorial(9) = 362880
factorial(10) = 3628800
factorial(0) = 1
factorial(1) = 1
factorial(2) = 2
factorial(3) = 6
factorial(4) = 24
factorial(5) = 120
factorial(6) = 720
factorial(7) = 5040
factorial(8) = 40320
factorial(9) = 362880
factorial(10) = 3628800
factorial(0) = 1
factorial(1) = 1
factorial(2) = 2
factorial(3) = 6
factorial(4) = 24
factorial(5) = 120
factorial(6) = 720
factorial(7) = 5040
factorial(8) = 40320
factorial(9) = 362880
factorial(10) = 3628800
factorial(0) = 1
factorial(1) = 1
factorial(2) = 2
factorial(3) = 6
factorial(4) = 24
factorial(5) = 120
factorial(6) = 720
factorial(7) = 5040
factorial(8) = 40320
factorial(9) = 362880
factorial(10) = 3628800
factorial(0) = 1
factorial(1) = 1
factorial(2) = 2
factorial(3) = 6
factorial(4) = 24
factorial(5) = 120
factorial(6) = 720
factorial(7) = 5040
factorial(8) = 40320
factorial(9) = 362880
factorial(10) = 3628800
factorial(0) = 1
factorial(1) = 1
factorial(2) = 2
factorial(3) = 6
factorial(4) = 24
factorial(5) = 120
factorial(6) = 720
factorial(7) = 5040
factorial(8) = 40320
factorial(9) = 362880
factorial(10) = 3628800
factorial(0) = 1
factorial(1) = 1
factorial(2) = 2
factorial(3) = 6
factorial(4) = 24
factorial(5) = 120
factorial(6) = 720
factorial(7) = 5040
factorial(8) = 40320
factorial(9) = 362880
factorial(10) = 3628800
factorial(0) = 1
factorial(1) = 1
factorial(2) = 2
factorial(3) = 6
factorial(4) = 24
factorial(5) = 120
factorial(6) = 720
factorial(7) = 5040
factorial(8) = 40320
factorial(9) = 362880
factorial(10) = 3628800
factorial(0) = 1
factorial(1) = 1
factorial(2) = 2
factorial(3) = 6
factorial(4) = 24
factorial(5) = 120
factorial(6) = 720
factorial(7) = 5040
factorial(8) = 40320
factorial(9) = 362880
factorial(10) = 3628800
factorial(0) = 1
factorial(1) = 1
factorial(2) = 2
factorial(3) = 6
factorial(4) = 24
factorial(5) = 120
factorial(6) = 720
factorial(7) = 5040
factorial(8) = 40320
factorial(9) = 362880
factorial(10) = 3628800
and now, from a function...
(it should break at 5...)
factorial(0) = 1
factorial(1) = 1
factorial(2) = 2
factorial(3) = 6
factorial(4) = 24
(it should break at 5...)
factorial(0) = 1
factorial(1) = 1
factorial(2) = 2
factorial(3) = 6
factorial(4) = 24
(it should break at 5...)
factorial(0) = 1
factorial(1) = 1
factorial(2) = 2
factorial(3) = 6
factorial(4) = 24
(it should break at 5...)
factorial(0) = 1
factorial(1) = 1
factorial(2) = 2
factorial(3) = 6
factorial(4) = 24
(it should break at 5...)
factorial(0) = 1
factorial(1) = 1
factorial(2) = 2
factorial(3) = 6
factorial(4) = 24
(it should break at 5...)
factorial(0) = 1
factorial(1) = 1
factorial(2) = 2
factorial(3) = 6
factorial(4) = 24
(it should break at 5...)
factorial(0) = 1
factorial(1) = 1
factorial(2) = 2
factorial(3) = 6
factorial(4) = 24
(it should break at 5...)
factorial(0) = 1
factorial(1) = 1
factorial(2) = 2
factorial(3) = 6
factorial(4) = 24
(it should break at 5...)
factorial(0) = 1
factorial(1) = 1
factorial(2) = 2
factorial(3) = 6
factorial(4) = 24
(it should break at 5...)
factorial(0) = 1
factorial(1) = 1
factorial(2) = 2
factorial(3) = 6
factorial(4) = 24
------
720
840
3
4
5

@ -0,0 +1,62 @@
--TEST--
General function test
--FILE--
<?php
function print_something_multiple_times($something,$times)
{
echo "----\nIn function, printing the string \"$something\" $times times\n";
for ($i=0; $i<$times; $i++) {
echo "$i) $something\n";
}
echo "Done with function...\n-----\n";
}
function some_other_function()
{
echo "This is some other function, to ensure more than just one function works fine...\n";
}
function main() {
echo "Before function declaration...\n";
echo "After function declaration...\n";
echo "Calling function for the first time...\n";
print_something_multiple_times("This works!",10);
echo "Returned from function call...\n";
echo "Calling the function for the second time...\n";
print_something_multiple_times("This like, really works and stuff...",3);
echo "Returned from function call...\n";
some_other_function();
}
?>
--EXPECT--
Before function declaration...
After function declaration...
Calling function for the first time...
----
In function, printing the string "This works!" 10 times
0) This works!
1) This works!
2) This works!
3) This works!
4) This works!
5) This works!
6) This works!
7) This works!
8) This works!
9) This works!
Done with function...
-----
Returned from function call...
Calling the function for the second time...
----
In function, printing the string "This like, really works and stuff..." 3 times
0) This like, really works and stuff...
1) This like, really works and stuff...
2) This like, really works and stuff...
Done with function...
-----
Returned from function call...
This is some other function, to ensure more than just one function works fine...

@ -0,0 +1,19 @@
--TEST--
Testing register_shutdown_function()
--SKIPIF--
<?php die("skip");?>
--FILE--
<?php
function foo()
{
print "foo";
}
function main() {
register_shutdown_function("foo");
print "foo() will be called on shutdown...\n";
}
?>
--EXPECT--
foo() will be called on shutdown...
foo

@ -0,0 +1,35 @@
--TEST--
Testing register_shutdown_function() with timeout. (Bug: #21513)
--SKIPIF--
<?php die("skip");?>
<?php
if (PHP_OS_FAMILY === 'Windows' && version_compare(PHP_VERSION, '8.4', '<')) {
die("xfail fails on Windows Server 2022 and newer.");
}
if (getenv("SKIP_SLOW_TESTS")) die("skip slow test");
?>
--FILE--
<?php
echo "Start\n";
function boo()
{
echo "Shutdown\n";
}
register_shutdown_function("boo");
set_time_limit(1);
/* infinite loop to simulate long processing */
for (;;) {}
echo "End\n";
?>
--EXPECTF--
Start
Fatal error: Maximum execution time of 1 second exceeded in %s on line %d
Shutdown

@ -0,0 +1,26 @@
--TEST--
Output buffering tests
--INI--
output_buffering=0
output_handler=
zlib.output_compression=0
zlib.output_handler=
--FILE--
<?php
ob_start();
echo ob_get_level();
echo 'A';
ob_start();
echo ob_get_level();
echo 'B';
$b = ob_get_contents();
ob_end_clean();
$a = ob_get_contents();
ob_end_clean();
var_dump( $b ); // 2B
var_dump( $a ); // 1A
?>
--EXPECT--
string(2) "2B"
string(2) "1A"

@ -0,0 +1,22 @@
--TEST--
INI functions test
--FILE--
<?php
$ini1 = ini_get('include_path');
ini_set('include_path','ini_set_works');
echo ini_get('include_path')."\n";
ini_restore('include_path');
$ini2 = ini_get('include_path');
if ($ini1 !== $ini2) {
echo "ini_restore() does not work.\n";
}
else {
echo "ini_restore_works\n";
}
?>
--EXPECT--
ini_set_works
ini_restore_works

@ -0,0 +1,16 @@
--TEST--
Test for buffering in core functions with implicit flush off
--INI--
implicit_flush=0
--FILE--
<?php
$res = var_export("foo1");
echo "\n";
$res = var_export("foo2", TRUE);
echo "\n";
echo $res."\n";
?>
--EXPECT--
'foo1'
'foo2'

@ -0,0 +1,16 @@
--TEST--
Test for buffering in core functions with implicit flush on
--INI--
implicit_flush=1
--FILE--
<?php
$res = var_export("foo1");
echo "\n";
$res = var_export("foo2", TRUE);
echo "\n";
echo $res."\n";
?>
--EXPECT--
'foo1'
'foo2'

@ -0,0 +1,78 @@
--TEST--
function with many parameters
--SKIPIF--
<?php die("skip");?>
<?php
if (getenv("SKIP_SLOW_TESTS")) die("skip slow test");
?>
--FILE--
<?php
function test($a,$b)
{
var_dump($a === $b);
test2($a,$b);
}
function test2($a, $b)
{
if ($a !== $b) {
var_dump("something went wrong: $a !== $b");
}
}
function main() {
// the stack size + some random constant
$boundary = 16*1024-16;
$limit = $boundary+42;
// generate the function
$str = "<?php\nfunction x(";
for($i=0; $i < $limit; ++$i) {
$str .= '$v'.dechex($i).($i===($limit-1) ? '' : ',');
}
$str .= ') {
test($v42, \'42\');
test(\'4000\', $v4000);
test2($v300, \'300\');
test($v0, \'0\'); // first
test($v'.dechex($limit-1).", '".dechex($limit-1).'\'); // last
test($v'.dechex($boundary).", '".dechex($boundary).'\'); //boundary
test($v'.dechex($boundary+1).", '".dechex($boundary+1).'\'); //boundary+1
test($v'.dechex($boundary-1).", '".dechex($boundary-1).'\'); //boundary-1
}';
// generate the function call
$str .= "\n\nx(";
for($i=0; $i< $limit; ++$i) {
$str .= "'".dechex($i)."'".($i===($limit-1) ? '' : ',');
}
$str .= ");\n";
$filename = __DIR__.'/010-file.php';
file_put_contents(__DIR__.'/010-file.php', $str);
unset($str);
include($filename);
echo "Done\n";
}
?>
--CLEAN--
<?php
@unlink(__DIR__.'/010-file.php');
?>
--EXPECT--
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
Done

@ -0,0 +1,9 @@
--TEST--
Test bitwise AND, OR, XOR, NOT and logical NOT in INI via error_reporting
--INI--
error_reporting = E_ALL & E_NOTICE | E_PARSE ^ E_DEPRECATED & ~E_WARNING | !E_ERROR
--FILE--
<?php
assert(ini_get('error_reporting') > 0);
?>
--EXPECT--

@ -0,0 +1,12 @@
--TEST--
Bug #64523: XOR not parsed in INI
--SKIPIF--
<?php die("skip");?>
--INI--
error_reporting = E_ALL ^ E_NOTICE ^ E_WARNING ^ E_DEPRECATED
--FILE--
<?php
echo ini_get('error_reporting');
?>
--EXPECT--
22517

@ -0,0 +1,18 @@
--TEST--
ini_alter() check
--CREDITS--
Sebastian Schürmann
sebs@php.net
Testfest 2009 Munich
--FILE--
<?php
ini_alter('error_reporting', 1);
$var = ini_get('error_reporting');
var_dump($var);
ini_alter('error_reporting', 0);
$var = ini_get('error_reporting');
var_dump($var);
?>
--EXPECT--
string(1) "1"
string(1) "0"

@ -0,0 +1,223 @@
--TEST--
String functions
--FILE--
<?php
echo "Testing strtok: ";
$str = "testing 1/2\\3";
$tok1 = strtok($str, " ");
$tok2 = strtok("/");
$tok3 = strtok("\\");
$tok4 = strtok(".");
if ($tok1 != "testing") {
echo("failed 1\n");
} elseif ($tok2 != "1") {
echo("failed 2\n");
} elseif ($tok3 != "2") {
echo("failed 3\n");
} elseif ($tok4 != "3") {
echo("failed 4\n");
} else {
echo("passed\n");
}
echo "Testing strstr: ";
$test = "This is a test";
$found1 = strstr($test, chr(32));
$found2 = strstr($test, "a ");
if ($found1 != " is a test") {
echo("failed 1\n");
} elseif ($found2 != "a test") {
echo("failed 2\n");
} else {
echo("passed\n");
}
echo "Testing strrchr: ";
$test = "fola fola blakken";
$found1 = strrchr($test, "b");
$found2 = strrchr($test, chr(102));
if ($found1 != "blakken") {
echo("failed 1\n");
} elseif ($found2 != "fola blakken") {
echo("failed 2\n");
}
else {
echo("passed\n");
}
echo "Testing strtoupper: ";
$test = "abCdEfg";
$upper = strtoupper($test);
if ($upper == "ABCDEFG") {
echo("passed\n");
} else {
echo("failed!\n");
}
echo "Testing strtolower: ";
$test = "ABcDeFG";
$lower = strtolower($test);
if ($lower == "abcdefg") {
echo("passed\n");
} else {
echo("failed!\n");
}
echo "Testing substr: ";
$tests = $ok = 0;
$string = "string12345";
$tests++; if (substr($string, 2, 10) == "ring12345") { $ok++; }
$tests++; if (substr($string, 4, 7) == "ng12345") { $ok++; }
$tests++; if (substr($string, 4) == "ng12345") { $ok++; }
$tests++; if (substr($string, 10, 2) == "5") { $ok++; }
$tests++; if (substr($string, 6, 0) == "") { $ok++; }
$tests++; if (substr($string, -2, 2) == "45") { $ok++; }
$tests++; if (substr($string, 1, -1) == "tring1234") { $ok++; }
$tests++; if (substr($string, -1, -2) == "") { $ok++; }
$tests++; if (substr($string, -3, -2) == "3") { $ok++; }
if ($tests == $ok) {
echo("passed\n");
} else {
echo("failed!\n");
}
$raw = ' !"#$%&\'()*+,-./0123456789:;<=>?'
. '@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_'
. '`abcdefghijklmnopqrstuvwxyz{|}~'
. "";
echo "Testing rawurlencode: ";
$encoded = rawurlencode($raw);
$correct = '%20%21%22%23%24%25%26%27%28%29%2A%2B%2C-.%2F0123456789%3A%3B%3C%3D%3E%3F'
. '%40ABCDEFGHIJKLMNOPQRSTUVWXYZ%5B%5C%5D%5E_'
. '%60abcdefghijklmnopqrstuvwxyz%7B%7C%7D~'
. '';
if ($encoded == $correct) {
echo("passed\n");
} else {
echo("failed!\n");
}
echo "Testing rawurldecode: ";
$decoded = rawurldecode($correct);
if ($decoded == $raw) {
echo("passed\n");
} else {
echo("failed!\n");
}
echo "Testing urlencode: ";
$encoded = urlencode($raw);
$correct = '+%21%22%23%24%25%26%27%28%29%2A%2B%2C-.%2F0123456789%3A%3B%3C%3D%3E%3F'
. '%40ABCDEFGHIJKLMNOPQRSTUVWXYZ%5B%5C%5D%5E_'
. '%60abcdefghijklmnopqrstuvwxyz%7B%7C%7D%7E'
. '';
if ($encoded == $correct) {
echo("passed\n");
} else {
echo("failed!\n");
}
echo "Testing urldecode: ";
$decoded = urldecode($correct);
if ($decoded == $raw) {
echo("passed\n");
} else {
echo("failed!\n");
}
echo "Testing quotemeta: ";
$raw = "a.\\+*?" . chr(91) . "^" . chr(93) . "b\$c";
$quoted = quotemeta($raw);
if ($quoted == "a\\.\\\\\\+\\*\\?\\[\\^\\]b\\\$c") {
echo("passed\n");
} else {
echo("failed!\n");
}
echo "Testing ufirst: ";
$str = "fahrvergnuegen";
$uc = ucfirst($str);
if ($uc == "Fahrvergnuegen") {
echo("passed\n");
} else {
echo("failed!\n");
}
echo "Testing strtr: ";
$str = "test abcdefgh";
$tr = strtr($str, "def", "456");
if ($tr == "t5st abc456gh") {
echo("passed\n");
} else {
echo("failed!\n");
}
echo "Testing addslashes: ";
$str = "\"\\'";
$as = addslashes($str);
if ($as == "\\\"\\\\\\'") {
echo("passed\n");
} else {
echo("failed!\n");
}
echo "Testing stripslashes: ";
$str = "\$\\'";
$ss = stripslashes($str);
if ($ss == "\$'") {
echo("passed\n");
} else {
echo("failed!\n");
}
echo "Testing uniqid(true): ";
$str = "prefix";
$ui1 = uniqid($str, true);
$ui2 = uniqid($str, true);
$len = 29;
if (strlen($ui1) == strlen($ui2) && strlen($ui1) == $len && $ui1 != $ui2) {
echo("passed\n");
} else {
echo("failed!\n");
}
echo "Testing uniqid(false): ";
$str = "prefix";
$ui1 = uniqid($str);
usleep( 1 );
$ui2 = uniqid($str);
$len = strncasecmp(PHP_OS, 'CYGWIN', 6) ? 19 : 29;
if (strlen($ui1) == strlen($ui2) && strlen($ui1) == $len && $ui1 != $ui2) {
echo("passed\n");
} else {
echo("failed!\n");
}
?>
--EXPECT--
Testing strtok: passed
Testing strstr: passed
Testing strrchr: passed
Testing strtoupper: passed
Testing strtolower: passed
Testing substr: passed
Testing rawurlencode: passed
Testing rawurldecode: passed
Testing urlencode: passed
Testing urldecode: passed
Testing quotemeta: passed
Testing ufirst: passed
Testing strtr: passed
Testing addslashes: passed
Testing stripslashes: passed
Testing uniqid(true): passed
Testing uniqid(false): passed

@ -0,0 +1,89 @@
--TEST--
Formatted print functions
--FILE--
<?php
$fp = fopen("php://stdout", "w");
$x = fprintf($fp, "fprintf test 1:%.5s", "abcdefghij");
echo "\n";
var_dump($x);
printf("printf test 1:%s\n", "simple string");
printf("printf test 2:%d\n", 42);
printf("printf test 3:%f\n", 10.0/3);
printf("printf test 4:%.10f\n", 10.0/3);
printf("printf test 5:%-10.2f\n", 2.5);
printf("printf test 6:%-010.2f\n", 2.5);
printf("printf test 7:%010.2f\n", 2.5);
printf("printf test 8:<%20s>\n", "foo");
printf("printf test 9:<%-20s>\n", "bar");
printf("printf test 10: 123456789012345\n");
printf("printf test 10:<%15s>\n", "hoyesterettsjustitiarius");
printf("printf test 11: 123456789012345678901234567890\n");
printf("printf test 11:<%30s>\n", "hoyesterettsjustitiarius");
printf("printf test 12:%5.2f\n", -12.34);
printf("printf test 13:%5d\n", -12);
printf("printf test 14:%c\n", 64);
printf("printf test 15:%b\n", 170);
printf("printf test 16:%x\n", 170);
printf("printf test 17:%X\n", 170);
printf("printf test 18:%16b\n", 170);
printf("printf test 19:%16x\n", 170);
printf("printf test 20:%16X\n", 170);
printf("printf test 21:%016b\n", 170);
printf("printf test 22:%016x\n", 170);
printf("printf test 23:%016X\n", 170);
printf("printf test 24:%.5s\n", "abcdefghij");
printf("printf test 25:%-2s\n", "gazonk");
printf("printf test 26:%2\$d %1\$d\n", 1, 2);
printf("printf test 27:%3\$d %d %d\n", 1, 2, 3);
printf("printf test 28:%2\$02d %1\$2d\n", 1, 2);
printf("printf test 29:%2\$-2d %1\$2d\n", 1, 2);
//try {
// print("printf test 30:"); printf("%0\$s", 1); print("x\n");
//} catch(\ValueError $e) {
// print('Error found: '.$e->getMessage()."\n");
//}
printf("printf test 31:%.17g\n", INF);
printf("printf test 32:%.17g\n", -INF);
vprintf("vprintf test 1:%2\$-2d %1\$2d\n", array(1, 2));
?>
--EXPECT--
fprintf test 1:abcde
int(20)
printf test 1:simple string
printf test 2:42
printf test 3:3.333333
printf test 4:3.3333333333
printf test 5:2.50
printf test 6:2.50000000
printf test 7:0000002.50
printf test 8:< foo>
printf test 9:<bar >
printf test 10: 123456789012345
printf test 10:<hoyesterettsjustitiarius>
printf test 11: 123456789012345678901234567890
printf test 11:< hoyesterettsjustitiarius>
printf test 12:-12.34
printf test 13: -12
printf test 14:@
printf test 15:10101010
printf test 16:aa
printf test 17:AA
printf test 18: 10101010
printf test 19: aa
printf test 20: AA
printf test 21:0000000010101010
printf test 22:00000000000000aa
printf test 23:00000000000000AA
printf test 24:abcde
printf test 25:gazonk
printf test 26:2 1
printf test 27:3 1 2
printf test 28:02 1
printf test 29:2 1
printf test 31:INF
printf test 32:-INF
vprintf test 1:2 1

@ -0,0 +1,17 @@
--TEST--
highlight_string() buffering
--INI--
highlight.string=#DD0000
highlight.comment=#FF9900
highlight.keyword=#007700
highlight.default=#0000BB
highlight.html=#000000
--FILE--
<?php
$var = highlight_string("<br /><?php echo \"foo\"; ?><br />");
$var = highlight_string("<br /><?php echo \"bar\"; ?><br />", TRUE);
echo "\n[$var]\n";
?>
--EXPECT--
<pre><code style="color: #000000">&lt;br /&gt;<span style="color: #0000BB">&lt;?php </span><span style="color: #007700">echo </span><span style="color: #DD0000">"foo"</span><span style="color: #007700">; </span><span style="color: #0000BB">?&gt;</span>&lt;br /&gt;</code></pre>
[<pre><code style="color: #000000">&lt;br /&gt;<span style="color: #0000BB">&lt;?php </span><span style="color: #007700">echo </span><span style="color: #DD0000">"bar"</span><span style="color: #007700">; </span><span style="color: #0000BB">?&gt;</span>&lt;br /&gt;</code></pre>]

@ -0,0 +1,9 @@
--TEST--
testing the behavior of string offset chaining
--FILE--
<?php
$string = "foobar";
var_dump($string[0][0][0][0]);
?>
--EXPECT--
string(1) "f"

@ -0,0 +1,80 @@
--TEST--
adding arrays
--FILE--
<?php
$a = array(1,2,3);
$b = array("str", "here");
$c = $a + $b;
var_dump($c);
$a = array(1,2,3);
$b = array(1,2,4);
$c = $a + $b;
var_dump($c);
$a = array();
$a["a"] = "aaa";
$a[] = 2;
$a[] = 3;
$b = array();
$b[] = 1;
$b[] = 2;
$b["a"] = "bbbbbb";
$c = $a + $b;
var_dump($c);
$a += $b;
var_dump($c);
$a += $a;
var_dump($c);
echo "Done\n";
?>
--EXPECT--
array(3) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
}
array(3) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
}
array(3) {
["a"]=>
string(3) "aaa"
[0]=>
int(2)
[1]=>
int(3)
}
array(3) {
["a"]=>
string(3) "aaa"
[0]=>
int(2)
[1]=>
int(3)
}
array(3) {
["a"]=>
string(3) "aaa"
[0]=>
int(2)
[1]=>
int(3)
}
Done

@ -0,0 +1,122 @@
--TEST--
Basic array unpacking
--SKIPIF--
<?php die("skip");?>
--FILE--
<?php
function getArr() {
return [4, 5];
}
function arrGen() {
for($i = 11; $i < 15; $i++) {
yield $i;
}
}
function main() {
$array = [1, 2, 3];
var_dump([...[]]);
var_dump([...[1, 2, 3]]);
var_dump([...$array]);
var_dump([...getArr()]);
var_dump([...arrGen()]);
var_dump([...new ArrayIterator(['a', 'b', 'c'])]);
var_dump([0, ...$array, ...getArr(), 6, 7, 8, 9, 10, ...arrGen()]);
var_dump([0, ...$array, ...$array, 'end']);
}
?>
--EXPECT--
array(0) {
}
array(3) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
}
array(3) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
}
array(2) {
[0]=>
int(4)
[1]=>
int(5)
}
array(4) {
[0]=>
int(11)
[1]=>
int(12)
[2]=>
int(13)
[3]=>
int(14)
}
array(3) {
[0]=>
string(1) "a"
[1]=>
string(1) "b"
[2]=>
string(1) "c"
}
array(15) {
[0]=>
int(0)
[1]=>
int(1)
[2]=>
int(2)
[3]=>
int(3)
[4]=>
int(4)
[5]=>
int(5)
[6]=>
int(6)
[7]=>
int(7)
[8]=>
int(8)
[9]=>
int(9)
[10]=>
int(10)
[11]=>
int(11)
[12]=>
int(12)
[13]=>
int(13)
[14]=>
int(14)
}
array(8) {
[0]=>
int(0)
[1]=>
int(1)
[2]=>
int(2)
[3]=>
int(3)
[4]=>
int(1)
[5]=>
int(2)
[6]=>
int(3)
[7]=>
string(3) "end"
}

@ -0,0 +1,23 @@
--TEST--
Stress test $x .= $x
--FILE--
<?php
/*
* Test case for a concat_function() change that broke a test outside of Zend
*
* @see https://github.com/php/php-src/commit/29397f8fd2b4bc8d95e18448ca2d27a62241a407
**/
$result = 'f';
for ($i = 0; $i < 25; ++$i) {
$result .= $result;
}
var_dump(strlen($result));
echo "Done\n";
?>
--EXPECT--
int(33554432)
Done

@ -0,0 +1,40 @@
--TEST--
Concatenating many small strings should not slowdown allocations
--SKIPIF--
<?php
//if (PHP_DEBUG) { die ("skip debug version is slow"); }
//if (getenv('SKIP_PERF_SENSITIVE')) die("skip performance sensitive test");
?>
--FILE--
<?php
$time = microtime(TRUE);
/* This might vary on Linux/Windows, so the worst case and also count in slow machines. */
$t_max = 1.0;
$datas = array_fill(0, 220000, [
'000.000.000.000',
'000.255.255.255',
'保留地址',
'保留地址',
'保留地址',
'保留地址',
'保留地址',
'保留地址',
]);
$time = microtime(TRUE);
$texts = '';
foreach ($datas AS $data)
{
$texts .= implode("\t", $data) . "\r\n";
}
$t = microtime(TRUE) - $time;
var_dump($t < $t_max);
echo "+++DONE+++\n";
?>
--EXPECT--
bool(true)
+++DONE+++

@ -0,0 +1,21 @@
--TEST--
Creating recursive array on foreach using same variable
--INI--
zend.enable_gc=1
--SKIPIF--
<?php die("skip");?>
--FILE--
<?php
error_reporting(E_ALL);
foreach (($a = array('a' => array('a' => &$a))) as $a) {
var_dump($a);
}
?>
--EXPECT--
array(1) {
["a"]=>
*RECURSION*
}

@ -0,0 +1,73 @@
--TEST--
Iterator exceptions in foreach by value
--SKIPIF--
<?php die("skip");?>
--FILE--
<?php
class IT implements Iterator {
private $n = 0;
private $count = 0;
private $trap = null;
function __construct($count, $trap = null) {
$this->count = $count;
$this->trap = $trap;
}
function trap($trap) {
if ($trap === $this->trap) {
throw new Exception($trap);
}
}
function rewind(): void {$this->trap(__FUNCTION__); $this->n = 0;}
function valid(): bool {$this->trap(__FUNCTION__); return $this->n < $this->count;}
function key(): mixed {$this->trap(__FUNCTION__); return $this->n;}
function current(): mixed {$this->trap(__FUNCTION__); return $this->n;}
function next(): void {$this->trap(__FUNCTION__); $this->n++;}
}
foreach(['rewind', 'valid', 'key', 'current', 'next'] as $trap) {
$obj = new IT(3, $trap);
try {
// IS_CV
foreach ($obj as $key => $val) echo "$val\n";
} catch (Exception $e) {
echo $e->getMessage() . "\n";
}
unset($obj);
try {
// IS_VAR
foreach (new IT(3, $trap) as $key => $val) echo "$val\n";
} catch (Exception $e) {
echo $e->getMessage() . "\n";
}
try {
// IS_TMP_VAR
foreach ((object)new IT(2, $trap) as $key => $val) echo "$val\n";
} catch (Exception $e) {
echo $e->getMessage() . "\n";
}
}
?>
--EXPECT--
rewind
rewind
rewind
valid
valid
valid
key
key
key
current
current
current
0
next
0
next
0
next

@ -0,0 +1,22 @@
--TEST--
Nested foreach by reference on the same array
--FILE--
<?php
$a = [1,2,3];
foreach($a as &$x) {
foreach($a as &$y) {
echo "$x-$y\n";
$y++;
}
}
?>
--EXPECT--
1-1
2-2
2-3
3-2
3-3
4-4
5-3
5-4
5-5

@ -0,0 +1,20 @@
--TEST--
Foreach by reference on constant
--FILE--
<?php
for ($i = 0; $i < 3; $i++) {
foreach ([1,2,3] as &$val) {
echo "$val\n";
}
}
?>
--EXPECT--
1
2
3
1
2
3
1
2
3

@ -0,0 +1,13 @@
--TEST--
Foreach by reference and inserting new element when we are already at the end
--FILE--
<?php
$a = [1];
foreach($a as &$v) {
echo "$v\n";
$a[1]=2;
}
?>
--EXPECT--
1
2
Loading…
Cancel
Save