summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBob Weinand <bobwei9@hotmail.com>2015-07-20 18:00:32 +0200
committerBob Weinand <bobwei9@hotmail.com>2015-07-20 18:00:43 +0200
commit378a05f0de7ff8874a2b97cdc78851eba748d91f (patch)
tree0919f5e7845bb9762248b7ddd4e8c4716f2bef6a
parent75a3de0cd8b79e2f813eaa663d90bb57edc7a146 (diff)
downloadphp-git-378a05f0de7ff8874a2b97cdc78851eba748d91f.tar.gz
Move phpdbg tests to .phpt mechanism
Also add a few more in-depth tests related to $argv, breakpoints and uncaught exceptions
-rw-r--r--.travis.yml1
-rwxr-xr-xrun-tests.php123
-rw-r--r--sapi/phpdbg/config.m42
-rw-r--r--sapi/phpdbg/create-test.php150
-rw-r--r--sapi/phpdbg/tests/basic_run.phpt8
-rw-r--r--sapi/phpdbg/tests/breakpoints_001.phpt33
-rw-r--r--sapi/phpdbg/tests/breakpoints_002.phpt40
-rw-r--r--sapi/phpdbg/tests/breakpoints_003.phpt33
-rw-r--r--sapi/phpdbg/tests/breakpoints_004.phpt41
-rw-r--r--sapi/phpdbg/tests/breakpoints_005.phpt28
-rw-r--r--sapi/phpdbg/tests/breakpoints_006.phpt26
-rw-r--r--sapi/phpdbg/tests/breakpoints_007.phpt25
-rw-r--r--sapi/phpdbg/tests/breakpoints_008.phpt34
-rw-r--r--sapi/phpdbg/tests/clean_001.phpt58
-rw-r--r--sapi/phpdbg/tests/clear_001.phpt42
-rw-r--r--sapi/phpdbg/tests/commands/0001_basic.test8
-rw-r--r--sapi/phpdbg/tests/commands/0002_set.test21
-rw-r--r--sapi/phpdbg/tests/commands/0101_info.test19
-rw-r--r--sapi/phpdbg/tests/commands/0102_print.test27
-rw-r--r--sapi/phpdbg/tests/commands/0103_register.test28
-rw-r--r--sapi/phpdbg/tests/commands/0104_clean.test14
-rw-r--r--sapi/phpdbg/tests/commands/0105_clear.test18
-rw-r--r--sapi/phpdbg/tests/commands/0106_compile.test18
-rw-r--r--sapi/phpdbg/tests/commands/0107_compile.test17
-rw-r--r--sapi/phpdbg/tests/exceptions_001.phpt46
-rw-r--r--sapi/phpdbg/tests/exceptions_002.phpt51
-rw-r--r--sapi/phpdbg/tests/info_001.phpt78
-rw-r--r--sapi/phpdbg/tests/info_002.phpt31
-rw-r--r--sapi/phpdbg/tests/print_001.phpt65
-rw-r--r--sapi/phpdbg/tests/print_002.phpt49
-rw-r--r--sapi/phpdbg/tests/run-tests.php597
-rw-r--r--sapi/phpdbg/tests/run_001.phpt56
32 files changed, 991 insertions, 796 deletions
diff --git a/.travis.yml b/.travis.yml
index 86ae36afd5..94056f4ca9 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -50,4 +50,3 @@ before_script:
# Run PHPs run-tests.php
script:
- ./sapi/cli/php run-tests.php -p `pwd`/sapi/cli/php $(if [ $ENABLE_DEBUG == 1 ]; then echo "-d opcache.enable_cli=1 -d zend_extension=`pwd`/modules/opcache.so"; fi) -g "FAIL,XFAIL,BORK,WARN,LEAK,SKIP" --offline --show-diff --set-timeout 120
- - ./sapi/cli/php sapi/phpdbg/tests/run-tests.php -diff2stdout --phpdbg sapi/phpdbg/phpdbg
diff --git a/run-tests.php b/run-tests.php
index 1251d3f96d..ba44ce5464 100755
--- a/run-tests.php
+++ b/run-tests.php
@@ -141,6 +141,7 @@ if ((substr(PHP_OS, 0, 3) == "WIN") && empty($environment["SystemRoot"])) {
$php = null;
$php_cgi = null;
+$phpdbg = null;
if (getenv('TEST_PHP_EXECUTABLE')) {
$php = getenv('TEST_PHP_EXECUTABLE');
@@ -158,6 +159,16 @@ if (getenv('TEST_PHP_EXECUTABLE')) {
$php_cgi = null;
}
}
+
+ if (!getenv('TEST_PHPDBG_EXECUTABLE')) {
+ $phpdbg = $cwd . '/sapi/phpdbg/phpdbg';
+
+ if (file_exists($phpdbg)) {
+ putenv("TEST_PHP_CGI_EXECUTABLE=$phpdbg");
+ } else {
+ $phpdbg = null;
+ }
+ }
}
$environment['TEST_PHP_EXECUTABLE'] = $php;
}
@@ -173,6 +184,17 @@ if (getenv('TEST_PHP_CGI_EXECUTABLE')) {
$environment['TEST_PHP_CGI_EXECUTABLE'] = $php_cgi;
}
+if (getenv('TEST_PHPDBG_EXECUTABLE')) {
+ $phpdbg = getenv('TEST_PHPDBG_EXECUTABLE');
+
+ if ($phpdbg=='auto') {
+ $phpdbg = $cwd . '/sapi/phpdbg/phpdbg';
+ putenv("TEST_PHPDBG_EXECUTABLE=$phpdbg");
+ }
+
+ $environment['TEST_PHPDBG_EXECUTABLE'] = $phpdbg;
+}
+
function verify_config()
{
global $php;
@@ -247,7 +269,7 @@ $no_file_cache = '-d opcache.file_cache= -d opcache.file_cache_only=0';
function write_information($show_html)
{
- global $cwd, $php, $php_cgi, $php_info, $user_tests, $ini_overwrites, $pass_options, $exts_to_test, $leak_check, $valgrind_header, $no_file_cache;
+ global $cwd, $php, $php_cgi, $phpdbg, $php_info, $user_tests, $ini_overwrites, $pass_options, $exts_to_test, $leak_check, $valgrind_header, $no_file_cache;
// Get info from php
$info_file = __DIR__ . '/run-test-info.php';
@@ -274,6 +296,14 @@ More .INIs : " , (function_exists(\'php_ini_scanned_files\') ? str_replace("\n"
$php_cgi_info = '';
}
+ if ($phpdbg) {
+ $phpdbg_info = `$phpdbg $pass_options $info_params $no_file_cache -qrr "$info_file"`;
+ $php_info_sep = "\n---------------------------------------------------------------------";
+ $phpdbg_info = "$php_info_sep\nPHP : $phpdbg $phpdbg_info$php_info_sep";
+ } else {
+ $phpdbg_info = '';
+ }
+
@unlink($info_file);
// load list of enabled extensions
@@ -299,7 +329,7 @@ More .INIs : " , (function_exists(\'php_ini_scanned_files\') ? str_replace("\n"
// Write test context information.
echo "
=====================================================================
-PHP : $php $php_info $php_cgi_info
+PHP : $php $php_info $php_cgi_info $phpdbg_info
CWD : $cwd
Extra dirs : ";
foreach ($user_tests as $test_dir) {
@@ -1205,6 +1235,10 @@ function run_test($php, $file, $env)
$php_cgi = $env['TEST_PHP_CGI_EXECUTABLE'];
}
+ if (isset($env['TEST_PHPDBG_EXECUTABLE'])) {
+ $phpdbg = $env['TEST_PHPDBG_EXECUTABLE'];
+ }
+
if (is_array($file)) {
$file = $file[0];
}
@@ -1290,7 +1324,7 @@ TEST $file
} else {
- if (@count($section_text['FILE']) + @count($section_text['FILEEOF']) + @count($section_text['FILE_EXTERNAL']) != 1) {
+ if (!isset($section_text['PHPDBG']) && @count($section_text['FILE']) + @count($section_text['FILEEOF']) + @count($section_text['FILE_EXTERNAL']) != 1) {
$bork_info = "missing section --FILE--";
$borked = true;
}
@@ -1372,6 +1406,38 @@ TEST $file
}
}
+ /* For phpdbg tests, check if phpdbg sapi is available and if it is, use it. */
+ if (array_key_exists('PHPDBG', $section_text)) {
+ if (!isset($section_text['STDIN'])) {
+ $section_text['STDIN'] = $section_text['PHPDBG']."\n";
+ }
+
+ if (isset($phpdbg)) {
+ $old_php = $php;
+ $php = $phpdbg . ' -qIb';
+ } else if (!strncasecmp(PHP_OS, "win", 3) && file_exists(dirname($php) . "/phpdbg.exe")) {
+ $old_php = $php;
+ $php = realpath(dirname($php) . "/phpdbg.exe") . ' -qIb ';
+ } else {
+ if (file_exists(dirname($php) . "/../../sapi/phpdbg/phpdbg")) {
+ $old_php = $php;
+ $php = realpath(dirname($php) . "/../../sapi/phpdbg/phpdbg") . ' -qIb ';
+ } else if (file_exists("./sapi/phpdbg/phpdbg")) {
+ $old_php = $php;
+ $php = realpath("./sapi/phpdbg/phpdbg") . ' -qIb ';
+ } else if (file_exists(dirname($php) . "/phpdbg")) {
+ $old_php = $php;
+ $php = realpath(dirname($php) . "/phpdbg") . ' -qIb ';
+ } else {
+ show_result('SKIP', $tested, $tested_file, "reason: phpdbg not available");
+
+ junit_init_suite(junit_get_suitename_for($shortname));
+ junit_mark_test_as('SKIP', $shortname, $tested, 0, 'phpdbg not available');
+ return 'SKIPPED';
+ }
+ }
+ }
+
if (!$SHOW_ONLY_GROUPS) {
show_test($test_idx, $shortname);
}
@@ -1652,8 +1718,12 @@ TEST $file
}
// We've satisfied the preconditions - run the test!
- show_file_block('php', $section_text['FILE'], 'TEST');
- save_text($test_file, $section_text['FILE'], $temp_file);
+ if (isset($section_text['FILE'])) {
+ show_file_block('php', $section_text['FILE'], 'TEST');
+ save_text($test_file, $section_text['FILE'], $temp_file);
+ } else {
+ $test_file = $temp_file = "";
+ }
if (array_key_exists('GET', $section_text)) {
$query_string = trim($section_text['GET']);
@@ -1741,7 +1811,7 @@ TEST $file
$env['REQUEST_METHOD'] = 'PUT';
if (empty($request)) {
- junit_mark_test_as('BORK', $shortname, $tested, null, 'empty $request');
+ junit_mark_test_as('BORK', $shortname, $tested, null, 'empty $request');
return 'BORKED';
}
@@ -1765,34 +1835,33 @@ TEST $file
$cmd = "$php $pass_options $ini_settings -f \"$test_file\" 2>&1 < \"$tmp_post\"";
- } else if (array_key_exists('GZIP_POST', $section_text) && !empty($section_text['GZIP_POST'])) {
-
- $post = trim($section_text['GZIP_POST']);
- $post = gzencode($post, 9, FORCE_GZIP);
- $env['HTTP_CONTENT_ENCODING'] = 'gzip';
+ } else if (array_key_exists('GZIP_POST', $section_text) && !empty($section_text['GZIP_POST'])) {
- save_text($tmp_post, $post);
- $content_length = strlen($post);
+ $post = trim($section_text['GZIP_POST']);
+ $post = gzencode($post, 9, FORCE_GZIP);
+ $env['HTTP_CONTENT_ENCODING'] = 'gzip';
- $env['REQUEST_METHOD'] = 'POST';
- $env['CONTENT_TYPE'] = 'application/x-www-form-urlencoded';
- $env['CONTENT_LENGTH'] = $content_length;
+ save_text($tmp_post, $post);
+ $content_length = strlen($post);
- $cmd = "$php $pass_options $ini_settings -f \"$test_file\" 2>&1 < \"$tmp_post\"";
+ $env['REQUEST_METHOD'] = 'POST';
+ $env['CONTENT_TYPE'] = 'application/x-www-form-urlencoded';
+ $env['CONTENT_LENGTH'] = $content_length;
- } else if (array_key_exists('DEFLATE_POST', $section_text) && !empty($section_text['DEFLATE_POST'])) {
- $post = trim($section_text['DEFLATE_POST']);
- $post = gzcompress($post, 9);
- $env['HTTP_CONTENT_ENCODING'] = 'deflate';
- save_text($tmp_post, $post);
- $content_length = strlen($post);
+ $cmd = "$php $pass_options $ini_settings -f \"$test_file\" 2>&1 < \"$tmp_post\"";
- $env['REQUEST_METHOD'] = 'POST';
- $env['CONTENT_TYPE'] = 'application/x-www-form-urlencoded';
- $env['CONTENT_LENGTH'] = $content_length;
+ } else if (array_key_exists('DEFLATE_POST', $section_text) && !empty($section_text['DEFLATE_POST'])) {
+ $post = trim($section_text['DEFLATE_POST']);
+ $post = gzcompress($post, 9);
+ $env['HTTP_CONTENT_ENCODING'] = 'deflate';
+ save_text($tmp_post, $post);
+ $content_length = strlen($post);
- $cmd = "$php $pass_options $ini_settings -f \"$test_file\" 2>&1 < \"$tmp_post\"";
+ $env['REQUEST_METHOD'] = 'POST';
+ $env['CONTENT_TYPE'] = 'application/x-www-form-urlencoded';
+ $env['CONTENT_LENGTH'] = $content_length;
+ $cmd = "$php $pass_options $ini_settings -f \"$test_file\" 2>&1 < \"$tmp_post\"";
} else {
diff --git a/sapi/phpdbg/config.m4 b/sapi/phpdbg/config.m4
index 87d38ea8c5..1e4714e77a 100644
--- a/sapi/phpdbg/config.m4
+++ b/sapi/phpdbg/config.m4
@@ -3,7 +3,7 @@ dnl $Id$
dnl
PHP_ARG_ENABLE(phpdbg, for phpdbg support,
-[ --enable-phpdbg Build phpdbg], no, no)
+[ --enable-phpdbg Build phpdbg], yes, yes)
PHP_ARG_ENABLE(phpdbg-webhelper, for phpdbg web SAPI support,
[ --enable-phpdbg-webhelper Build phpdbg web SAPI support], yes, yes)
diff --git a/sapi/phpdbg/create-test.php b/sapi/phpdbg/create-test.php
new file mode 100644
index 0000000000..3bda97670f
--- /dev/null
+++ b/sapi/phpdbg/create-test.php
@@ -0,0 +1,150 @@
+#!/usr/bin/env php
+<?php
+
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 7 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2015 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Bob Weinand <bwoebi@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+#####
+## This is just a helper for intercepting stdin/stdout and the file and create a half-finished test.
+## The output still may need adapting to match file names etc.
+#####
+
+error_reporting(-1);
+
+$phpdbg = getenv('TEST_PHPDBG_EXECUTABLE') ?: null;
+$pass_options = " -qbI";
+$file = "";
+$cmdargv = "";
+
+if (isset($argc) && $argc > 1) {
+ $post_ddash = false;
+ for ($i = 1; $i < $argc; $i++) {
+ if ($argv[$i][0] == "-" && !$post_ddash) {
+ switch (substr($argv[$i], 1)) {
+ case "p":
+ $phpdbg = $argv[++$i];
+ break;
+ case "n":
+ $pass_options .= " -n";
+ break;
+ case "d":
+ $pass_options .= " -d ".escapeshellarg($argv[++$i]);
+ $ini[] = $argv[$i];
+ break;
+ case "-":
+ $post_ddash = true;
+ break;
+ }
+ } else {
+ $real_argv[] = $argv[$i];
+ }
+ }
+ if (isset($real_argv[0])) {
+ $file = realpath($real_argv[0]);
+ $cmdargv = implode(" ", array_map("escapeshellarg", array_slice($real_argv, 1)));
+ }
+}
+
+$proc = proc_open("$phpdbg $pass_options $file -- $cmdargv", [["pipe", "r"], ["pipe", "w"], ["pipe", "w"]], $pipes);
+if (!$proc) {
+ die("Couldn't start phpdbg\n");
+}
+
+$input = $output = "";
+
+stream_set_blocking(STDIN, false);
+
+do {
+ $r = [$pipes[1], STDIN];
+ $w = $e = null;
+ $n = @stream_select($r, $w, $e, null);
+
+ if ($n > 0) {
+ if ("" != $in = fread(STDIN, 1024)) {
+ $input .= $in;
+ fwrite($pipes[0], $in);
+ continue;
+ }
+
+ if (feof(STDIN)) {
+ die("stdin closed?!\n");
+ }
+
+ if (feof($pipes[1])) {
+ $n = false;
+ } else {
+ $output .= $c = fgetc($pipes[1]);
+ echo $c;
+ }
+ }
+} while ($n !== false);
+
+stream_set_blocking(STDIN, true);
+
+print "\n";
+if (!isset($name)) {
+ print "Specifiy the test description: ";
+ $desc = trim(fgets(STDIN));
+}
+while (!isset($testfile)) {
+ print "Specifiy the test file name (leave empty to write to stderr): ";
+ $testfile = trim(fgets(STDIN));
+ if ($testfile != "" && file_exists($testfile)) {
+ print "That file already exists. Type y or yes to overwrite: ";
+ $y = trim(fgets(STDIN));
+ if ($y !== "y" && $y !== "yes") {
+ unset($testfile);
+ }
+ }
+}
+
+$output = str_replace("string(".strlen($file).") \"$file\"", 'string(%d) "%s"', $output);
+$output = str_replace($file, "%s", $output);
+$input = trim($input);
+
+$testdata = <<<TEST
+--TEST--
+$desc
+--PHPDBG--
+$input
+--EXPECTF--
+$output
+TEST;
+
+if (!empty($ini)) {
+ $testdata .= "\n--INI--\n".implode("\n", $ini);
+}
+if ($cmdargv != "") {
+ $testdata .= "\n--ARGS--\n$cmdargv";
+}
+if ($file != "") {
+ $testdata .= "\n--FILE--\n".file_get_contents($file);
+}
+
+if ($testfile == "") {
+ print "\n";
+} elseif (file_put_contents($testfile, $testdata)) {
+ print "Test saved to $testfile\n";
+} else {
+ print "The test could not be saved to $testfile; outputting on stderr now\n";
+ $testfile = "";
+}
+
+if ($testfile == "") {
+ fwrite(STDERR, $testdata);
+}
diff --git a/sapi/phpdbg/tests/basic_run.phpt b/sapi/phpdbg/tests/basic_run.phpt
new file mode 100644
index 0000000000..beb19b535a
--- /dev/null
+++ b/sapi/phpdbg/tests/basic_run.phpt
@@ -0,0 +1,8 @@
+--TEST--
+Basic run
+--PHPDBG--
+r
+q
+--EXPECTF--
+prompt> [Nothing to execute!]
+prompt>
diff --git a/sapi/phpdbg/tests/breakpoints_001.phpt b/sapi/phpdbg/tests/breakpoints_001.phpt
new file mode 100644
index 0000000000..934f0d3554
--- /dev/null
+++ b/sapi/phpdbg/tests/breakpoints_001.phpt
@@ -0,0 +1,33 @@
+--TEST--
+Fundamental breakpoints functionality
+--PHPDBG--
+b 3
+r
+b 4
+c
+
+q
+--EXPECTF--
+[Successful compilation of %s]
+prompt> [Breakpoint #0 added at %s:3]
+prompt> [Breakpoint #0 at %s:3, hits: 1]
+>00003: echo 1;
+ 00004: echo 2;
+ 00005: echo 3;
+prompt> [Breakpoint #1 added at %s:4]
+prompt> 1
+[Breakpoint #1 at %s:4, hits: 1]
+>00004: echo 2;
+ 00005: echo 3;
+ 00006: echo 4;
+prompt> 234
+[Script ended normally]
+prompt>
+--FILE--
+<?php
+
+echo 1;
+echo 2;
+echo 3;
+echo 4;
+
diff --git a/sapi/phpdbg/tests/breakpoints_002.phpt b/sapi/phpdbg/tests/breakpoints_002.phpt
new file mode 100644
index 0000000000..18aaef1f36
--- /dev/null
+++ b/sapi/phpdbg/tests/breakpoints_002.phpt
@@ -0,0 +1,40 @@
+--TEST--
+Preserve breakpoints on restart
+--PHPDBG--
+b breakpoints_002.php:4
+r
+b 3
+r
+y
+c
+
+q
+--EXPECTF--
+[Successful compilation of %s]
+prompt> [Breakpoint #0 added at %s:4]
+prompt> 1
+[Breakpoint #0 at %s:4, hits: 1]
+>00004: echo 2;
+ 00005: echo 3;
+ 00006: echo 4;
+prompt> [Breakpoint #1 added at %s:3]
+prompt> Do you really want to restart execution? (type y or n): [Breakpoint #1 at %s:3, hits: 1]
+>00003: echo 1;
+ 00004: echo 2;
+ 00005: echo 3;
+prompt> 1
+[Breakpoint #0 at %s:4, hits: 1]
+>00004: echo 2;
+ 00005: echo 3;
+ 00006: echo 4;
+prompt> 234
+[Script ended normally]
+prompt>
+--FILE--
+<?php
+
+echo 1;
+echo 2;
+echo 3;
+echo 4;
+
diff --git a/sapi/phpdbg/tests/breakpoints_003.phpt b/sapi/phpdbg/tests/breakpoints_003.phpt
new file mode 100644
index 0000000000..8caa64632b
--- /dev/null
+++ b/sapi/phpdbg/tests/breakpoints_003.phpt
@@ -0,0 +1,33 @@
+--TEST--
+Test deleting breakpoints
+--PHPDBG--
+b 4
+b del 0
+b 5
+r
+b del 1
+r
+y
+q
+--EXPECTF--
+[Successful compilation of %s]
+prompt> [Breakpoint #0 added at %s:4]
+prompt> [Deleted breakpoint #0]
+prompt> [Breakpoint #1 added at %s:5]
+prompt> 12
+[Breakpoint #1 at %s:5, hits: 1]
+>00005: echo 3;
+ 00006: echo 4;
+ 00007:
+prompt> [Deleted breakpoint #1]
+prompt> Do you really want to restart execution? (type y or n): 1234
+[Script ended normally]
+prompt>
+--FILE--
+<?php
+
+echo 1;
+echo 2;
+echo 3;
+echo 4;
+
diff --git a/sapi/phpdbg/tests/breakpoints_004.phpt b/sapi/phpdbg/tests/breakpoints_004.phpt
new file mode 100644
index 0000000000..27ebd0bea2
--- /dev/null
+++ b/sapi/phpdbg/tests/breakpoints_004.phpt
@@ -0,0 +1,41 @@
+--TEST--
+Test opcode breakpoints
+--PHPDBG--
+b ZEND_ECHO
+r
+c
+
+
+
+q
+--EXPECTF--
+[Successful compilation of %s]
+prompt> [Breakpoint #0 added at ZEND_ECHO]
+prompt> [Breakpoint #0 in ZEND_ECHO at %s:3, hits: 1]
+>00003: echo 1;
+ 00004: echo 2;
+ 00005: echo 3;
+prompt> 1
+[Breakpoint #0 in ZEND_ECHO at %s:4, hits: 2]
+>00004: echo 2;
+ 00005: echo 3;
+ 00006: echo 4;
+prompt> 2
+[Breakpoint #0 in ZEND_ECHO at %s:5, hits: 3]
+>00005: echo 3;
+ 00006: echo 4;
+ 00007:
+prompt> 3
+[Breakpoint #0 in ZEND_ECHO at %s:6, hits: 4]
+>00006: echo 4;
+ 00007:
+prompt> 4
+[Script ended normally]
+prompt>
+--FILE--
+<?php
+
+echo 1;
+echo 2;
+echo 3;
+echo 4;
diff --git a/sapi/phpdbg/tests/breakpoints_005.phpt b/sapi/phpdbg/tests/breakpoints_005.phpt
new file mode 100644
index 0000000000..653dab9fcc
--- /dev/null
+++ b/sapi/phpdbg/tests/breakpoints_005.phpt
@@ -0,0 +1,28 @@
+--TEST--
+Test breakpoint into function context
+--PHPDBG--
+b breakpoints_005.php:4
+r
+ev $bar
+c
+q
+--EXPECTF--
+[Successful compilation of %s]
+prompt> [Breakpoint #0 added at %s:4]
+prompt> [Breakpoint #0 at %s:4, hits: 1]
+>00004: var_dump($bar);
+ 00005: }
+ 00006:
+prompt> test
+prompt> string(4) "test"
+[Script ended normally]
+prompt>
+--FILE--
+<?php
+
+function foo($bar) {
+ var_dump($bar);
+}
+
+foo("test");
+
diff --git a/sapi/phpdbg/tests/breakpoints_006.phpt b/sapi/phpdbg/tests/breakpoints_006.phpt
new file mode 100644
index 0000000000..fa6f0cdc5b
--- /dev/null
+++ b/sapi/phpdbg/tests/breakpoints_006.phpt
@@ -0,0 +1,26 @@
+--TEST--
+Basic function breakpoints
+--PHPDBG--
+b foo
+r
+c
+q
+--EXPECTF--
+[Successful compilation of %s]
+prompt> [Breakpoint #0 added at foo]
+prompt> [Breakpoint #0 in foo() at %s:4, hits: 1]
+>00004: var_dump($bar);
+ 00005: }
+ 00006:
+prompt> string(4) "test"
+[Script ended normally]
+prompt>
+--FILE--
+<?php
+
+function foo($bar) {
+ var_dump($bar);
+}
+
+foo("test");
+
diff --git a/sapi/phpdbg/tests/breakpoints_007.phpt b/sapi/phpdbg/tests/breakpoints_007.phpt
new file mode 100644
index 0000000000..f921c257c5
--- /dev/null
+++ b/sapi/phpdbg/tests/breakpoints_007.phpt
@@ -0,0 +1,25 @@
+--TEST--
+Basic method breakpoints
+--PHPDBG--
+b bar::foo
+r
+q
+--EXPECTF--
+[Successful compilation of %s]
+prompt> [Breakpoint #0 added at bar::foo]
+prompt> [Breakpoint #0 in bar::foo() at %s:5, hits: 1]
+>00005: var_dump($bar);
+ 00006: }
+ 00007: }
+prompt>
+--FILE--
+<?php
+
+class bar {
+ function foo($bar) {
+ var_dump($bar);
+ }
+}
+
+(new bar)->foo("test");
+
diff --git a/sapi/phpdbg/tests/breakpoints_008.phpt b/sapi/phpdbg/tests/breakpoints_008.phpt
new file mode 100644
index 0000000000..cbe5042c2b
--- /dev/null
+++ b/sapi/phpdbg/tests/breakpoints_008.phpt
@@ -0,0 +1,34 @@
+--TEST--
+Test namespaced and non-lowercase breakpoint names
+--PHPDBG--
+b foo\bar::foo
+b \Foo\Bar::Foo
+r
+c
+q
+--EXPECTF--
+[Successful compilation of %s]
+prompt> [Breakpoint #0 added at foo\bar::foo]
+prompt> [Breakpoint exists at Foo\Bar::Foo]
+prompt> [Breakpoint #0 in foo\bar::foo() at %s:6, hits: 1]
+>00006: var_dump($bar);
+ 00007: }
+ 00008: }
+prompt> string(4) "test"
+[Script ended normally]
+prompt>
+--FILE--
+<?php
+
+namespace Foo {
+ class Bar {
+ function Foo($bar) {
+ var_dump($bar);
+ }
+ }
+}
+
+namespace {
+ (new \Foo\Bar)->Foo("test");
+}
+
diff --git a/sapi/phpdbg/tests/clean_001.phpt b/sapi/phpdbg/tests/clean_001.phpt
new file mode 100644
index 0000000000..00771c6860
--- /dev/null
+++ b/sapi/phpdbg/tests/clean_001.phpt
@@ -0,0 +1,58 @@
+--TEST--
+Cleaning must preserve breakpoints
+--PHPDBG--
+b 4
+b foo
+r
+c
+clean
+y
+c
+r
+c
+
+q
+--EXPECTF--
+[Successful compilation of %s]
+prompt> [Breakpoint #0 added at %s:4]
+prompt> [Breakpoint #1 added at foo]
+prompt> 1
+[Breakpoint #0 at %s:4, hits: 1]
+>00004: echo 2;
+ 00005: echo 3;
+ 00006: foo();
+prompt> 23
+[Breakpoint #1 in foo() at %s:9, hits: 1]
+>00009: echo 4;
+ 00010: }
+ 00011:
+prompt> Do you really want to clean your current environment? (type y or n): Cleaning Execution Environment
+Classes %d
+Functions %d
+Constants %d
+Includes 0
+prompt> [Not running]
+prompt> 1
+[Breakpoint #0 at %s:4, hits: 1]
+>00004: echo 2;
+ 00005: echo 3;
+ 00006: foo();
+prompt> 23
+[Breakpoint #1 in foo() at %s:9, hits: 1]
+>00009: echo 4;
+ 00010: }
+ 00011:
+prompt> 4
+[Script ended normally]
+prompt>
+--FILE--
+<?php
+
+echo 1;
+echo 2;
+echo 3;
+foo();
+
+function foo() {
+ echo 4;
+}
diff --git a/sapi/phpdbg/tests/clear_001.phpt b/sapi/phpdbg/tests/clear_001.phpt
new file mode 100644
index 0000000000..7acd842ef2
--- /dev/null
+++ b/sapi/phpdbg/tests/clear_001.phpt
@@ -0,0 +1,42 @@
+--TEST--
+Test clearing breakpoints
+--PHPDBG--
+b 4
+b foo
+r
+clear
+c
+i b
+q
+--EXPECTF--
+[Successful compilation of %s]
+prompt> [Breakpoint #0 added at %s:4]
+prompt> [Breakpoint #1 added at foo]
+prompt> 1
+[Breakpoint #0 at %s:4, hits: 1]
+>00004: echo 2;
+ 00005: echo 3;
+ 00006: foo();
+prompt> Clearing Breakpoints
+File 1
+Functions 1
+Methods 0
+Oplines 0
+File oplines 0
+Function oplines 0
+Method oplines 0
+Conditionals 0
+prompt> 234
+[Script ended normally]
+prompt> prompt>
+--FILE--
+<?php
+
+echo 1;
+echo 2;
+echo 3;
+foo();
+
+function foo() {
+ echo 4;
+}
diff --git a/sapi/phpdbg/tests/commands/0001_basic.test b/sapi/phpdbg/tests/commands/0001_basic.test
deleted file mode 100644
index 08aa9ab664..0000000000
--- a/sapi/phpdbg/tests/commands/0001_basic.test
+++ /dev/null
@@ -1,8 +0,0 @@
-#######################################################
-# name: basic
-# purpose: check basic functionality of phpdbg console
-# expect: TEST::EXACT
-# options: -rr
-#######################################################
-# [Nothing to execute!]
-#######################################################
diff --git a/sapi/phpdbg/tests/commands/0002_set.test b/sapi/phpdbg/tests/commands/0002_set.test
deleted file mode 100644
index 6a14a15adc..0000000000
--- a/sapi/phpdbg/tests/commands/0002_set.test
+++ /dev/null
@@ -1,21 +0,0 @@
-#################################################
-# name: set
-# purpose: tests for set commands
-# expect: TEST::CISTRING
-# options: -rr
-#################################################
-# setting prompt color
-# setting error color
-# setting notice color
-# Failed to find breakpoint #0
-# [Oplog off]
-# opened oplog test.log
-# nothing
-#################################################
-set color prompt none
-set color error none
-set color notice none
-set prompt promot>
-set break 0
-set oplog
-set oplog test.log
diff --git a/sapi/phpdbg/tests/commands/0101_info.test b/sapi/phpdbg/tests/commands/0101_info.test
deleted file mode 100644
index 397a45c992..0000000000
--- a/sapi/phpdbg/tests/commands/0101_info.test
+++ /dev/null
@@ -1,19 +0,0 @@
-#################################################
-# name: info
-# purpose: test info commands
-# expect: TEST::FORMAT
-# options: -rr
-#################################################
-#[User Classes (%d)]
-#User Class test (3)
-#|---- in phpdbginit code on line %d
-#################################################
-<:
-class test {
- public function testMethod(){}
- private function testPrivateMethod(){}
- protected function testProtectedMethod(){}
-}
-:>
-info classes
-q
diff --git a/sapi/phpdbg/tests/commands/0102_print.test b/sapi/phpdbg/tests/commands/0102_print.test
deleted file mode 100644
index 7078b13ea2..0000000000
--- a/sapi/phpdbg/tests/commands/0102_print.test
+++ /dev/null
@@ -1,27 +0,0 @@
-#################################################
-# name: print
-# purpose: test print commands
-# expect: TEST::FORMAT
-# options: -rr
-#################################################
-#[User Class: test (3 methods)]
-#L%d-%d test::testMethod() %s - 0x%s + 1 ops
-# L%d #0 RETURN null
-#L%d-%d test::testPrivateMethod() %s - 0x%s + 1 ops
-# L%d #0 RETURN null
-#L%d-%d test::testProtectedMethod() %s - 0x%s + 1 ops
-# L%d #0 RETURN null
-#[User Method testMethod (1 ops)]
-#L%d-%d test::testMethod() %s - 0x%s + 1 ops
-# L%d #0 RETURN null
-#################################################
-<:
-class test {
- public function testMethod(){}
- private function testPrivateMethod(){}
- protected function testProtectedMethod(){}
-}
-:>
-print class test
-print method test::testMethod
-q
diff --git a/sapi/phpdbg/tests/commands/0103_register.test b/sapi/phpdbg/tests/commands/0103_register.test
deleted file mode 100644
index 703a12f771..0000000000
--- a/sapi/phpdbg/tests/commands/0103_register.test
+++ /dev/null
@@ -1,28 +0,0 @@
-#################################################
-# name: register
-# purpose: test registration functions
-# expect: TEST::FORMAT
-# options: -rr
-#################################################
-#[Registered test_function]
-#array(5) {
-# [0]=>
-# int(1)
-# [1]=>
-# int(2)
-# [2]=>
-# int(3)
-# [3]=>
-# int(4)
-# [4]=>
-# int(5)
-#}
-#################################################
-<:
-function test_function() {
- var_dump(func_get_args());
-}
-:>
-R test_function
-test_function 1 2 3 4 5
-q
diff --git a/sapi/phpdbg/tests/commands/0104_clean.test b/sapi/phpdbg/tests/commands/0104_clean.test
deleted file mode 100644
index 2c7660ad60..0000000000
--- a/sapi/phpdbg/tests/commands/0104_clean.test
+++ /dev/null
@@ -1,14 +0,0 @@
-#################################################
-# name: clean
-# purpose: test cleaning environment
-# expect: TEST::FORMAT
-# options: -rr
-#################################################
-#Cleaning Execution Environment
-#Classes %d
-#Functions %d
-#Constants %d
-#Includes %d
-#################################################
-clean
-quit
diff --git a/sapi/phpdbg/tests/commands/0105_clear.test b/sapi/phpdbg/tests/commands/0105_clear.test
deleted file mode 100644
index 8ce1002491..0000000000
--- a/sapi/phpdbg/tests/commands/0105_clear.test
+++ /dev/null
@@ -1,18 +0,0 @@
-#################################################
-# name: clear
-# purpose: test clearing breakpoints
-# expect: TEST::FORMAT
-# options: -rr
-#################################################
-#Clearing Breakpoints
-#File%w%d
-#Functions%w%d
-#Methods%w%d
-#Oplines%w%d
-#File oplines%w%d
-#Function oplines%w%d
-#Method oplines%w%d
-#Conditionals%w%d
-#################################################
-clear
-quit
diff --git a/sapi/phpdbg/tests/commands/0106_compile.test b/sapi/phpdbg/tests/commands/0106_compile.test
deleted file mode 100644
index b4d801670b..0000000000
--- a/sapi/phpdbg/tests/commands/0106_compile.test
+++ /dev/null
@@ -1,18 +0,0 @@
-#################################################
-# name: compile
-# purpose: test compiling code
-# expect: TEST::FORMAT
-# options: -rr
-#################################################
-#[Successful compilation of %s]
-#Hello World
-#[Script ended normally]
-#################################################
-<:
-define('OUT',
- tempnam(null, "phpdbg"));
-file_put_contents(OUT, "<?php echo \"Hello World\"; ?>");
-phpdbg_exec(OUT);
-:>
-run
-quit
diff --git a/sapi/phpdbg/tests/commands/0107_compile.test b/sapi/phpdbg/tests/commands/0107_compile.test
deleted file mode 100644
index 4842cb74f1..0000000000
--- a/sapi/phpdbg/tests/commands/0107_compile.test
+++ /dev/null
@@ -1,17 +0,0 @@
-#################################################
-# name: compile
-# purpose: test compiling error code
-# expect: TEST::FORMAT
-# options: -rr
-#################################################
-#[PHP Parse error: syntax error, unexpected 'echo' (T_ECHO) in %s on line %s]
-#[Could not find information about included file...]
-#################################################
-<:
-define('OUT',
- tempnam(null, "phpdbg"));
-file_put_contents(OUT, "<?error echo \"Hello World\"; ?>");
-phpdbg_exec(OUT);
-:>
-run
-quit
diff --git a/sapi/phpdbg/tests/exceptions_001.phpt b/sapi/phpdbg/tests/exceptions_001.phpt
new file mode 100644
index 0000000000..fca94f512c
--- /dev/null
+++ b/sapi/phpdbg/tests/exceptions_001.phpt
@@ -0,0 +1,46 @@
+--TEST--
+Properly handle exceptions going to be uncaught
+--PHPDBG--
+r
+t
+ev 1 + 2
+c
+q
+--EXPECTF--
+[Successful compilation of %s]
+prompt> handle first
+[Uncaught Error in %s on line 16: Call to undefined function foo()]
+>00016: foo(); // Error
+ 00017: } catch (\Exception $e) {
+ 00018: var_dump($e);
+prompt> frame #0: {closure}() at %s:16
+frame #1: {main} at %s:18
+prompt> 3
+prompt> Uncaught Error in %s on line 16
+Error: Call to undefined function foo() in %s:16
+Stack trace:
+#0 %s(18): {closure}()
+#1 {main}
+[Script ended normally]
+prompt>
+--FILE--
+<?php
+
+(function() {
+ try {
+ foo(); // Error
+ } catch (\Exception $e) {
+ var_dump($e);
+ } finally {
+ print "handle first\n";
+ return "ok";
+ }
+})();
+
+(function() {
+ try {
+ foo(); // Error
+ } catch (\Exception $e) {
+ var_dump($e);
+ }
+})();
diff --git a/sapi/phpdbg/tests/exceptions_002.phpt b/sapi/phpdbg/tests/exceptions_002.phpt
new file mode 100644
index 0000000000..9d3d805a5f
--- /dev/null
+++ b/sapi/phpdbg/tests/exceptions_002.phpt
@@ -0,0 +1,51 @@
+--TEST--
+Test exceptions in eval during exception
+--PHPDBG--
+r
+ev next_error()
+c
+
+q
+--EXPECTF--
+[Successful compilation of %s]
+prompt> handle first
+[Uncaught Error in %s on line 16: Call to undefined function foo()]
+>00016: foo(); // Error
+ 00017: } catch (\Exception $e) {
+ 00018: var_dump($e);
+prompt>
+Fatal error: Uncaught Error: Call to undefined function next_error() in eval()'d code:1
+Stack trace:
+#0 %s(16): unknown()
+#1 %s(18): {closure}()
+#2 {main}
+ thrown in eval()'d code on line 1
+prompt> Uncaught Error in %s on line 16
+Error: Call to undefined function foo() in %s:16
+Stack trace:
+#0 %s(18): {closure}()
+#1 {main}
+[Script ended normally]
+prompt> [The stack contains nothing !]
+prompt>
+--FILE--
+<?php
+
+(function() {
+ try {
+ foo(); // Error
+ } catch (\Exception $e) {
+ var_dump($e);
+ } finally {
+ print "handle first\n";
+ return "ok";
+ }
+})();
+
+(function() {
+ try {
+ foo(); // Error
+ } catch (\Exception $e) {
+ var_dump($e);
+ }
+})();
diff --git a/sapi/phpdbg/tests/info_001.phpt b/sapi/phpdbg/tests/info_001.phpt
new file mode 100644
index 0000000000..a1adb9ad0a
--- /dev/null
+++ b/sapi/phpdbg/tests/info_001.phpt
@@ -0,0 +1,78 @@
+--TEST--
+Test basic info functionality
+--PHPDBG--
+i classes
+i funcs
+b foo
+r
+i v
+i g
+i b
+i d
+i F
+i e
+i l
+c
+i v
+q
+--EXPECTF--
+[Successful compilation of %s]
+prompt> [User Classes (1)]
+User Class Foo\Bar (2)
+|---- in %s on line 4
+prompt> [User Functions (1)]
+|-------- foo in %s on line 14
+prompt> [Breakpoint #0 added at foo]
+prompt> string(4) "test"
+[Breakpoint #0 in foo() at %s:15, hits: 1]
+>00015: var_dump(strrev($baz));
+ 00016: }
+ 00017:
+prompt> [Variables in foo() (1)]
+Address Refs Type Variable
+%s 1 string $baz
+string (4) "test"
+prompt> [Superglobal variables (8)]
+Address Refs Type Variable
+%s 2 array $_GET
+%s 2 array $_POST
+%s 2 array $_COOKIE
+%s 2 array $_FILES
+%s 1 array &$GLOBALS
+%s 2 array $_SERVER
+%s 2 array $_ENV
+%s 1 array $_REQUEST
+prompt> ------------------------------------------------
+Function Breakpoints:
+#0 foo
+prompt> [User-defined constants (0)]
+prompt> [Included files: 0]
+prompt> [No error found!]
+prompt> [Literal Constants in foo() (2)]
+|-------- C0 -------> [var_dump]
+|-------- C1 -------> [strrev]
+prompt> string(4) "tset"
+[Script ended normally]
+prompt> [No active op array!]
+prompt>
+--FILE--
+<?php
+
+namespace Foo {
+ class Bar {
+ function Foo($bar) {
+ var_dump($bar);
+ }
+
+ function baz() { }
+ }
+}
+
+namespace {
+ function foo($baz) {
+ var_dump(strrev($baz));
+ }
+
+ (new \Foo\Bar)->Foo("test");
+ foo("test");
+}
diff --git a/sapi/phpdbg/tests/info_002.phpt b/sapi/phpdbg/tests/info_002.phpt
new file mode 100644
index 0000000000..faeca0e430
--- /dev/null
+++ b/sapi/phpdbg/tests/info_002.phpt
@@ -0,0 +1,31 @@
+--TEST--
+info constants test
+--PHPDBG--
+b 10
+r
+i d
+q
+--EXPECTF--
+[Successful compilation of %s]
+prompt> [Breakpoint #0 added at %s:10]
+prompt> [Breakpoint #0 at %s:10, hits: 1]
+>00010: print B;
+ 00011:
+prompt> [User-defined constants (2)]
+Address Refs Type Constant
+%s 1 integer A
+int (10)
+%s 1 integer B
+int (100)
+prompt>
+--FILE--
+<?php
+
+const A = 10;
+const B = C::D * A;
+
+class C {
+ const D = 10;
+}
+
+print B;
diff --git a/sapi/phpdbg/tests/print_001.phpt b/sapi/phpdbg/tests/print_001.phpt
new file mode 100644
index 0000000000..f6ade94dd7
--- /dev/null
+++ b/sapi/phpdbg/tests/print_001.phpt
@@ -0,0 +1,65 @@
+--TEST--
+Basic print functionality
+--PHPDBG--
+p foo
+p class \Foo\bar
+p
+p e
+q
+--EXPECTF--
+[Successful compilation of %s]
+prompt> [User Function foo (8 ops)]
+L14-16 foo() %s - %s + 8 ops
+ L14 #0 RECV 1 $baz
+ L15 #1 INIT_FCALL 112 "var_dump"
+ L15 #2 INIT_FCALL 112 "strrev"
+ L15 #3 SEND_VAR $baz 1
+ L15 #4 DO_ICALL @0
+ L15 #5 SEND_VAR @0 1
+ L15 #6 DO_ICALL
+ L15 #7 RETURN null
+prompt> [User Class: Foo\Bar (2 methods)]
+L5-7 Foo\Bar::Foo() %s - %s + 5 ops
+ L5 #0 RECV 1 $bar
+ L6 #1 INIT_NS_FCALL_BY_NAME "Foo\\var_dump"
+ L6 #2 SEND_VAR_EX $bar 1
+ L6 #3 DO_FCALL
+ L6 #4 RETURN null
+L9-9 Foo\Bar::baz() %s - %s + 1 ops
+ L9 #0 RETURN null
+prompt> [Not Executing!]
+prompt> [Context %s (11 ops)]
+L1-19 {main}() %s - %s + 11 ops
+ L4 #0 NOP
+ L14 #1 NOP
+ L18 #2 NEW "Foo\\Bar" @1
+ L18 #3 DO_FCALL
+ L18 #4 INIT_METHOD_CALL @1 "Foo"
+ L18 #5 SEND_VAL_EX "test" 1
+ L18 #6 DO_FCALL
+ L19 #7 INIT_FCALL 144 "foo"
+ L19 #8 SEND_VAL "test" 1
+ L19 #9 DO_FCALL
+ L19 #10 RETURN 1
+prompt>
+--FILE--
+<?php
+
+namespace Foo {
+ class Bar {
+ function Foo($bar) {
+ var_dump($bar);
+ }
+
+ function baz() { }
+ }
+}
+
+namespace {
+ function foo($baz) {
+ var_dump(strrev($baz));
+ }
+
+ (new \Foo\Bar)->Foo("test");
+ foo("test");
+}
diff --git a/sapi/phpdbg/tests/print_002.phpt b/sapi/phpdbg/tests/print_002.phpt
new file mode 100644
index 0000000000..eede27050e
--- /dev/null
+++ b/sapi/phpdbg/tests/print_002.phpt
@@ -0,0 +1,49 @@
+--TEST--
+Relative print commands
+--PHPDBG--
+b foo
+r
+p
+p o
+q
+--EXPECTF--
+[Successful compilation of %s]
+prompt> [Breakpoint #0 added at foo]
+prompt> string(4) "test"
+[Breakpoint #0 in foo() at %s:15, hits: 1]
+>00015: var_dump(strrev($baz));
+ 00016: }
+ 00017:
+prompt> [Stack in foo() (8 ops)]
+L14-16 foo() %s - %s + 8 ops
+ L14 #0 RECV 1 $baz
+ L15 #1 INIT_FCALL 112 "var_dump"
+ L15 #2 INIT_FCALL 112 "strrev"
+ L15 #3 SEND_VAR $baz 1
+ L15 #4 DO_ICALL @0
+ L15 #5 SEND_VAR @0 1
+ L15 #6 DO_ICALL
+ L15 #7 RETURN null
+prompt> [L15 %s INIT_FCALL 112 "var_dump" %s]
+prompt>
+--FILE--
+<?php
+
+namespace Foo {
+ class Bar {
+ function Foo($bar) {
+ var_dump($bar);
+ }
+
+ function baz() { }
+ }
+}
+
+namespace {
+ function foo($baz) {
+ var_dump(strrev($baz));
+ }
+
+ (new \Foo\Bar)->Foo("test");
+ foo("test");
+}
diff --git a/sapi/phpdbg/tests/run-tests.php b/sapi/phpdbg/tests/run-tests.php
deleted file mode 100644
index 4afb64561c..0000000000
--- a/sapi/phpdbg/tests/run-tests.php
+++ /dev/null
@@ -1,597 +0,0 @@
-<?php
-namespace phpdbg\testing {
-
- /*
- * Workaround ...
- */
- if (!defined('DIR_SEP'))
- define('DIR_SEP', '\\' . DIRECTORY_SEPARATOR);
-
- /**
- * TestConfigurationExceptions are thrown
- * when the configuration prohibits tests executing
- *
- * @package phpdbg
- * @subpackage testing
- */
- class TestConfigurationException extends \Exception {
-
- /**
- *
- * @param array Tests confguration
- * @param message Exception message
- * @param ... formatting parameters
- */
- public function __construct() {
- $argv = func_get_args();
-
- if (count($argv)) {
-
- $this->config = array_shift($argv);
- $this->message = vsprintf(
- array_shift($argv), $argv);
- }
- }
- }
-
- /**
- *
- * @package phpdbg
- * @subpackage testing
- */
- class TestsConfiguration implements \ArrayAccess {
-
- /**
- *
- * @param array basic configuration
- * @param array argv
- */
- public function __construct($config, $cmd) {
- $this->options = $config;
- while (($key = array_shift($cmd))) {
- switch (substr($key, 0, 1)) {
- case '-': switch(substr($key, 1, 1)) {
- case '-': {
- $arg = substr($key, 2);
- if (($e=strpos($arg, '=')) !== false) {
- $key = substr($arg, 0, $e);
- $value = substr($arg, $e+1);
- } else {
- $key = $arg;
- $value = array_shift($cmd);
- }
-
- if (isset($key) && isset($value)) {
- switch ($key) {
- case 'phpdbg':
- case 'width':
- $this->options[$key] = $value;
- break;
-
- default: {
- if (isset($config[$key])) {
- if (is_array($config[$key])) {
- $this->options[$key][] = $value;
- } else {
- $this->options[$key] = array($config[$key], $value);
- }
- } else {
- $this->options[$key] = $value;
- }
- }
- }
-
- }
- } break;
-
- default:
- $this->flags[] = substr($key, 1);
- } break;
- }
- }
-
- if (!is_executable($this->options['phpdbg'])) {
- throw new TestConfigurationException(
- $this->options, 'phpdbg could not be found at the specified path (%s)', $this->options['phpdbg']);
- } else $this->options['phpdbg'] = realpath($this->options['phpdbg']);
-
- $this->options['width'] = (integer) $this->options['width'];
-
- /* display properly, all the time */
- if ($this->options['width'] < 50) {
- $this->options['width'] = 50;
- }
-
- /* calculate column widths */
- $this->options['lwidth'] = ceil($this->options['width'] / 3);
- $this->options['rwidth'] = ceil($this->options['width'] - $this->options['lwidth']) - 5;
- }
-
- public function hasFlag($flag) {
- return in_array(
- $flag, $this->flags);
- }
-
- public function offsetExists($offset) { return isset($this->options[$offset]); }
- public function offsetGet($offset) { return $this->options[$offset]; }
- public function offsetUnset($offset) { unset($this->options[$offset]); }
- public function offsetSet($offset, $data) { $this->options[$offset] = $data; }
-
- protected $options = array();
- protected $flags = array();
- }
-
- /**
- * Tests is the console programming API for the test suite
- *
- * @package phpdbg
- * @subpackage testing
- */
- class Tests {
-
- /**
- * Construct the console object
- *
- * @param array basic configuration
- * @param array command line
- */
- public function __construct(TestsConfiguration $config) {
- $this->config = $config;
-
- if ($this->config->hasFlag('help') ||
- $this->config->hasFlag('h')) {
- $this->showUsage();
- exit;
- }
- }
-
- /**
- * Find valid paths as specified by configuration
- *
- */
- public function findPaths($in = null) {
- $paths = array();
- $where = ($in != null) ? array($in) : $this->config['path'];
-
- foreach ($where as $path) {
- if ($path) {
- if (is_dir($path)) {
- $paths[] = $path;
- foreach (scandir($path) as $child) {
- if ($child != '.' && $child != '..') {
- $paths = array_merge(
- $paths, $this->findPaths("$path/$child"));
- }
- }
- }
- }
- }
-
- return $paths;
- }
-
- /**
- *
- * @param string the path to log
- */
- public function logPath($path) {
- printf(
- '%s [%s]%s',
- str_repeat(
- '-', $this->config['width'] - strlen($path)),
- $path, PHP_EOL);
- }
-
- /**
- *
- * @param string the path to log
- */
- public function logPathStats($path) {
- if (!isset($this->stats[$path])) {
- return;
- }
-
- $total = array_sum($this->stats[$path]);
-
- if ($total) {
- @$this->totals[true] += $this->stats[$path][true];
- @$this->totals[false] += $this->stats[$path][false];
-
- $stats = @sprintf(
- "%d/%d %%%d",
- $this->stats[$path][true],
- $this->stats[$path][false],
- (100 / $total) * $this->stats[$path][true]);
-
- printf(
- '%s [%s]%s',
- str_repeat(
- ' ', $this->config['width'] - strlen($stats)),
- $stats, PHP_EOL);
-
- printf("%s%s", str_repeat('-', $this->config['width']+3), PHP_EOL);
- printf("%s", PHP_EOL);
- }
- }
-
- /**
- *
- */
- public function logStats() {
- $total = array_sum($this->totals);
- $stats = @sprintf(
- "%d/%d %%%d",
- $this->totals[true],
- $this->totals[false],
- (100 / $total) * $this->totals[true]);
- printf(
- '%s [%s]%s',
- str_repeat(
- ' ', $this->config['width'] - strlen($stats)),
- $stats, PHP_EOL);
-
- }
-
- /**
- *
- */
- protected function showUsage() {
- printf('usage: php %s [flags] [options]%s', $this->config['exec'], PHP_EOL);
- printf('[options]:%s', PHP_EOL);
- printf("\t--path\t\tadd a path to scan outside of tests directory%s", PHP_EOL);
- printf("\t--width\t\tset line width%s", PHP_EOL);
- printf("\t--options\toptions to pass to phpdbg%s", PHP_EOL);
- printf("\t--phpdbg\tpath to phpdbg binary%s", PHP_EOL);
- printf('[flags]:%s', PHP_EOL);
- printf("\t-diff2stdout\t\twrite diff to stdout instead of files%s", PHP_EOL);
- printf("\t-nodiff\t\tdo not write diffs on failure%s", PHP_EOL);
- printf("\t-nolog\t\tdo not write logs on failure%s", PHP_EOL);
- printf('[examples]:%s', PHP_EOL);
- printf("\tphp %s --phpdbg=/usr/local/bin/phpdbg --path=/usr/src/phpdbg/tests --options -n%s",
- $this->config['exec'], PHP_EOL);
-
- }
-
- /**
- * Find valid tests at the specified path (assumed valid)
- *
- * @param string a valid path
- */
- public function findTests($path) {
- $tests = array();
-
- foreach (scandir($path) as $file) {
- if ($file == '.' || $file == '..')
- continue;
-
- $test = sprintf('%s/%s', $path, $file);
-
- if (preg_match('~\.test$~', $test)) {
- $tests[] = new Test($this->config, $test);
- }
- }
-
- return $tests;
- }
-
- /**
- *
- * @param Test the test to log
- */
- public function logTest($path, Test $test) {
- @$this->stats[$path][($result=$test->getResult())]++;
-
- printf(
- "%-{$this->config['lwidth']}s %-{$this->config['rwidth']}s [%s]%s",
- $test->name,
- $test->purpose,
- $result ? "PASS" : "FAIL",
- PHP_EOL);
-
- return $result;
- }
-
- protected $config;
- }
-
- class Test {
- /*
- * Expect exact line for line match
- */
- const EXACT = 0x00000001;
-
- /*
- * Expect strpos() !== false
- */
- const STRING = 0x00000010;
-
- /*
- * Expect stripos() !== false
- */
- const CISTRING = 0x00000100;
-
- /*
- * Formatted output
- */
- const FORMAT = 0x00001000;
-
- /**
- * Format specifiers
- */
- private static $format = array(
- 'search' => array(
- '%e',
- '%s',
- '%S',
- '%a',
- '%A',
- '%w',
- '%i',
- '%d',
- '%x',
- '%f',
- '%c',
- '%t',
- '%T'
- ),
- 'replace' => array(
- DIR_SEP,
- '[^\r\n]+',
- '[^\r\n]*',
- '.+',
- '.*',
- '\s*',
- '[+-]?\d+',
- '\d+',
- '[0-9a-fA-F]+',
- '[+-]?\.?\d+\.?\d*(?:[Ee][+-]?\d+)?',
- '.',
- '\t',
- '\t+'
- )
- );
-
- /**
- * Constructs a new Test object given a specilized phpdbginit file
- *
- * @param array configuration
- * @param string file
- */
- public function __construct(TestsConfiguration $config, $file) {
- if (($handle = fopen($file, 'r'))) {
- while (($line = fgets($handle))) {
- $trim = trim($line);
-
- switch (substr($trim, 0, 1)) {
- case '#': if (($chunks = array_map('trim', preg_split('~:~', substr($trim, 1), 2)))) {
- if (property_exists($this, $chunks[0])) {
- switch ($chunks[0]) {
- case 'expect': {
- if ($chunks[1]) {
- switch (strtoupper($chunks[1])) {
- case 'TEST::EXACT':
- case 'EXACT': { $this->expect = TEST::EXACT; } break;
-
- case 'TEST::STRING':
- case 'STRING': { $this->expect = TEST::STRING; } break;
-
- case 'TEST::CISTRING':
- case 'CISTRING': { $this->expect = TEST::CISTRING; } break;
-
- case 'TEST::FORMAT':
- case 'FORMAT': { $this->expect = TEST::FORMAT; } break;
-
- default:
- throw new TestConfigurationException(
- $this->config, "unknown type of expectation (%s)", $chunks[1]);
- }
- }
- } break;
-
- default: {
- $this->{$chunks[0]} = $chunks[1];
- }
- }
- } else switch(substr($trim, 1, 1)) {
- case '#': { /* do nothing */ } break;
-
- default: {
- $line = preg_replace(
- "~(\r\n)~", "\n", substr($trim, 1));
-
- $line = trim($line);
-
- switch ($this->expect) {
- case TEST::FORMAT:
- $this->match[] = str_replace(
- self::$format['search'],
- self::$format['replace'], preg_quote($line));
- break;
-
- default: $this->match[] = $line;
- }
- }
- }
- } break;
-
- default:
- break 2;
- }
- }
- fclose($handle);
-
- $this->config = $config;
- $this->file = $file;
- }
- }
-
- /**
- * Obvious!!
- *
- */
- public function getResult() {
- $options = sprintf('-i%s -nqb', $this->file);
-
- if ($this->options) {
- $options = sprintf(
- '%s %s %s',
- $options,
- $this->config['options'],
- $this->options
- );
- } else {
- $options = sprintf(
- '%s %s', $options, $this->config['options']
- );
- }
-
- $result = `{$this->config['phpdbg']} {$options}`;
-
- if ($result) {
- foreach (preg_split('~(\r|\n)~', $result) as $num => $line) {
- if (!$line && !isset($this->match[$num]))
- continue;
-
- switch ($this->expect) {
- case TEST::EXACT: {
- if (strcmp($line, $this->match[$num]) !== 0) {
- $this->diff['wants'][$num] = &$this->match[$num];
- $this->diff['gets'][$num] = $line;
- }
- } continue 2;
-
- case TEST::STRING: {
- if (strpos($line, $this->match[$num]) === false) {
- $this->diff['wants'][$num] = &$this->match[$num];
- $this->diff['gets'][$num] = $line;
- }
- } continue 2;
-
- case TEST::CISTRING: {
- if (stripos($line, $this->match[$num]) === false) {
- $this->diff['wants'][$num] = &$this->match[$num];
- $this->diff['gets'][$num] = $line;
- }
- } continue 2;
-
- case TEST::FORMAT: {
- $line = trim($line);
- if (!preg_match("/^{$this->match[$num]}\$/s", $line)) {
- $this->diff['wants'][$num] = &$this->match[$num];
- $this->diff['gets'][$num] = $line;
- }
- } continue 2;
- }
- }
- }
-
- $this->writeLog($result);
- $this->writeDiff();
-
- return (count($this->diff) == 0);
- }
-
- /**
- * Write diff to disk if configuration allows it
- *
- */
- protected function writeDiff() {
- if (count($this->diff['wants'])) {
- if (!$this->config->hasFlag('nodiff')) {
- if ($this->config->hasFlag('diff2stdout')) {
- $difffile = "php://stdout";
- file_put_contents($difffile, "====DIFF====\n");
- } else {
- $difffile = sprintf(
- '%s/%s.diff',
- dirname($this->file), basename($this->file));
- }
-
- if (($diff = fopen($difffile, 'w+'))) {
-
- foreach ($this->diff['wants'] as $line => $want) {
- $got = $this->diff['gets'][$line];
-
- fprintf(
- $diff, '(%d) -%s%s', $line+1, $want, PHP_EOL);
- fprintf(
- $diff, '(%d) +%s%s', $line+1, $got, PHP_EOL);
- }
-
- fclose($diff);
- }
- }
- } else unlink($diff);
- }
-
- /**
- * Write log to disk if configuration allows it
- *
- */
- protected function writeLog($result = null) {
- $log = sprintf(
- '%s/%s.log',
- dirname($this->file), basename($this->file));
-
- if (count($this->diff) && $result) {
- if (!in_array('nolog', $this->config['flags'])) {
- @file_put_contents(
- $log, $result);
- }
- } else unlink($log);
- }
-
- public $name;
- public $purpose;
- public $file;
- public $options;
- public $expect;
-
- protected $match;
- protected $diff;
- protected $stats;
- protected $totals;
- }
-}
-
-namespace {
- use \phpdbg\Testing\Test;
- use \phpdbg\Testing\Tests;
- use \phpdbg\Testing\TestsConfiguration;
-
- $cwd = dirname(__FILE__);
- $cmd = $_SERVER['argv'];
-
- $retval = 0;
-
- {
- $config = new TestsConfiguration(array(
- 'exec' => realpath(array_shift($cmd)),
- 'phpdbg' => realpath(sprintf(
- '%s/../phpdbg', $cwd
- )),
- 'path' => array(
- realpath(dirname(__FILE__))
- ),
- 'flags' => array(),
- 'width' => 75
- ), $cmd);
-
- $tests = new Tests($config);
-
- foreach ($tests->findPaths() as $path) {
- $tests->logPath($path);
-
- foreach ($tests->findTests($path) as $test) {
- $retval |= !$tests->logTest($path, $test);
- }
-
- $tests->logPathStats($path);
- }
-
- $tests->logStats();
- }
-
- die($retval);
-}
-?>
diff --git a/sapi/phpdbg/tests/run_001.phpt b/sapi/phpdbg/tests/run_001.phpt
new file mode 100644
index 0000000000..c6a7ee8c4f
--- /dev/null
+++ b/sapi/phpdbg/tests/run_001.phpt
@@ -0,0 +1,56 @@
+--TEST--
+Test argv passing
+--PHPDBG--
+r
+r 1 2 3
+r
+q
+--EXPECTF--
+[Successful compilation of %s]
+prompt> int(5)
+array(5) {
+ [0]=>
+ string(%d) "%s"
+ [1]=>
+ string(2) "--"
+ [2]=>
+ string(1) "1"
+ [3]=>
+ string(1) "2"
+ [4]=>
+ string(1) "3"
+}
+[Script ended normally]
+prompt> int(5)
+array(4) {
+ [0]=>
+ string(%d) "%s"
+ [1]=>
+ string(1) "1"
+ [2]=>
+ string(1) "2"
+ [3]=>
+ string(1) "3"
+}
+[Script ended normally]
+prompt> int(5)
+array(5) {
+ [0]=>
+ string(%d) "%s"
+ [1]=>
+ string(2) "--"
+ [2]=>
+ string(1) "1"
+ [3]=>
+ string(1) "2"
+ [4]=>
+ string(1) "3"
+}
+[Script ended normally]
+prompt>
+--ARGS--
+'1' '2' '3'
+--FILE--
+<?php
+
+var_dump($argc, $argv);