]> granicus.if.org Git - php/commitdiff
Move phpdbg tests to .phpt mechanism
authorBob Weinand <bobwei9@hotmail.com>
Mon, 20 Jul 2015 16:00:32 +0000 (18:00 +0200)
committerBob Weinand <bobwei9@hotmail.com>
Mon, 20 Jul 2015 16:00:43 +0000 (18:00 +0200)
Also add a few more in-depth tests related to $argv, breakpoints and uncaught exceptions

32 files changed:
.travis.yml
run-tests.php
sapi/phpdbg/config.m4
sapi/phpdbg/create-test.php [new file with mode: 0644]
sapi/phpdbg/tests/basic_run.phpt [new file with mode: 0644]
sapi/phpdbg/tests/breakpoints_001.phpt [new file with mode: 0644]
sapi/phpdbg/tests/breakpoints_002.phpt [new file with mode: 0644]
sapi/phpdbg/tests/breakpoints_003.phpt [new file with mode: 0644]
sapi/phpdbg/tests/breakpoints_004.phpt [new file with mode: 0644]
sapi/phpdbg/tests/breakpoints_005.phpt [new file with mode: 0644]
sapi/phpdbg/tests/breakpoints_006.phpt [new file with mode: 0644]
sapi/phpdbg/tests/breakpoints_007.phpt [new file with mode: 0644]
sapi/phpdbg/tests/breakpoints_008.phpt [new file with mode: 0644]
sapi/phpdbg/tests/clean_001.phpt [new file with mode: 0644]
sapi/phpdbg/tests/clear_001.phpt [new file with mode: 0644]
sapi/phpdbg/tests/commands/0001_basic.test [deleted file]
sapi/phpdbg/tests/commands/0002_set.test [deleted file]
sapi/phpdbg/tests/commands/0101_info.test [deleted file]
sapi/phpdbg/tests/commands/0102_print.test [deleted file]
sapi/phpdbg/tests/commands/0103_register.test [deleted file]
sapi/phpdbg/tests/commands/0104_clean.test [deleted file]
sapi/phpdbg/tests/commands/0105_clear.test [deleted file]
sapi/phpdbg/tests/commands/0106_compile.test [deleted file]
sapi/phpdbg/tests/commands/0107_compile.test [deleted file]
sapi/phpdbg/tests/exceptions_001.phpt [new file with mode: 0644]
sapi/phpdbg/tests/exceptions_002.phpt [new file with mode: 0644]
sapi/phpdbg/tests/info_001.phpt [new file with mode: 0644]
sapi/phpdbg/tests/info_002.phpt [new file with mode: 0644]
sapi/phpdbg/tests/print_001.phpt [new file with mode: 0644]
sapi/phpdbg/tests/print_002.phpt [new file with mode: 0644]
sapi/phpdbg/tests/run-tests.php [deleted file]
sapi/phpdbg/tests/run_001.phpt [new file with mode: 0644]

index 86ae36afd5364d3b16462c595f93d5ee9dab2ac2..94056f4ca9570ec07c8b316d32f5dc7600d7c668 100644 (file)
@@ -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
index 1251d3f96da7616ced9f0df9eeaed81e2698ab9e..ba44ce54643c3e1a29c0441d9207095c50f8d25f 100755 (executable)
@@ -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 {
 
index 87d38ea8c518f91f018a15a285c5f015b879616b..1e4714e77a724d163aa3344ddc6817170ac27fbf 100644 (file)
@@ -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 (file)
index 0000000..3bda976
--- /dev/null
@@ -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 (file)
index 0000000..beb19b5
--- /dev/null
@@ -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 (file)
index 0000000..934f0d3
--- /dev/null
@@ -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 (file)
index 0000000..18aaef1
--- /dev/null
@@ -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 (file)
index 0000000..8caa646
--- /dev/null
@@ -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 (file)
index 0000000..27ebd0b
--- /dev/null
@@ -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 (file)
index 0000000..653dab9
--- /dev/null
@@ -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 (file)
index 0000000..fa6f0cd
--- /dev/null
@@ -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 (file)
index 0000000..f921c25
--- /dev/null
@@ -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 (file)
index 0000000..cbe5042
--- /dev/null
@@ -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 (file)
index 0000000..00771c6
--- /dev/null
@@ -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 (file)
index 0000000..7acd842
--- /dev/null
@@ -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 (file)
index 08aa9ab..0000000
+++ /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 (file)
index 6a14a15..0000000
+++ /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 (file)
index 397a45c..0000000
+++ /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 (file)
index 7078b13..0000000
+++ /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 (file)
index 703a12f..0000000
+++ /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 (file)
index 2c7660a..0000000
+++ /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 (file)
index 8ce1002..0000000
+++ /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 (file)
index b4d8016..0000000
+++ /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 (file)
index 4842cb7..0000000
+++ /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 (file)
index 0000000..fca94f5
--- /dev/null
@@ -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 (file)
index 0000000..9d3d805
--- /dev/null
@@ -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 (file)
index 0000000..a1adb9a
--- /dev/null
@@ -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 (file)
index 0000000..faeca0e
--- /dev/null
@@ -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 (file)
index 0000000..f6ade94
--- /dev/null
@@ -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 (file)
index 0000000..eede270
--- /dev/null
@@ -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 (file)
index 4afb645..0000000
+++ /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 (file)
index 0000000..c6a7ee8
--- /dev/null
@@ -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);