Browse Source
Move phpdbg tests to .phpt mechanism
Move phpdbg tests to .phpt mechanism
Also add a few more in-depth tests related to $argv, breakpoints and uncaught exceptionspull/1428/head
32 changed files with 991 additions and 796 deletions
-
1.travis.yml
-
123run-tests.php
-
2sapi/phpdbg/config.m4
-
150sapi/phpdbg/create-test.php
-
8sapi/phpdbg/tests/basic_run.phpt
-
33sapi/phpdbg/tests/breakpoints_001.phpt
-
40sapi/phpdbg/tests/breakpoints_002.phpt
-
33sapi/phpdbg/tests/breakpoints_003.phpt
-
41sapi/phpdbg/tests/breakpoints_004.phpt
-
28sapi/phpdbg/tests/breakpoints_005.phpt
-
26sapi/phpdbg/tests/breakpoints_006.phpt
-
25sapi/phpdbg/tests/breakpoints_007.phpt
-
34sapi/phpdbg/tests/breakpoints_008.phpt
-
58sapi/phpdbg/tests/clean_001.phpt
-
42sapi/phpdbg/tests/clear_001.phpt
-
8sapi/phpdbg/tests/commands/0001_basic.test
-
21sapi/phpdbg/tests/commands/0002_set.test
-
19sapi/phpdbg/tests/commands/0101_info.test
-
27sapi/phpdbg/tests/commands/0102_print.test
-
28sapi/phpdbg/tests/commands/0103_register.test
-
14sapi/phpdbg/tests/commands/0104_clean.test
-
18sapi/phpdbg/tests/commands/0105_clear.test
-
18sapi/phpdbg/tests/commands/0106_compile.test
-
17sapi/phpdbg/tests/commands/0107_compile.test
-
46sapi/phpdbg/tests/exceptions_001.phpt
-
51sapi/phpdbg/tests/exceptions_002.phpt
-
78sapi/phpdbg/tests/info_001.phpt
-
31sapi/phpdbg/tests/info_002.phpt
-
65sapi/phpdbg/tests/print_001.phpt
-
49sapi/phpdbg/tests/print_002.phpt
-
597sapi/phpdbg/tests/run-tests.php
-
56sapi/phpdbg/tests/run_001.phpt
@ -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); |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
--TEST-- |
|||
Basic run |
|||
--PHPDBG-- |
|||
r |
|||
q |
|||
--EXPECTF-- |
|||
prompt> [Nothing to execute!] |
|||
prompt> |
|||
@ -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; |
|||
|
|||
@ -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; |
|||
|
|||
@ -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; |
|||
|
|||
@ -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; |
|||
@ -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"); |
|||
|
|||
@ -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"); |
|||
|
|||
@ -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"); |
|||
|
|||
@ -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"); |
|||
} |
|||
|
|||
@ -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; |
|||
} |
|||
@ -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; |
|||
} |
|||
@ -1,8 +0,0 @@ |
|||
####################################################### |
|||
# name: basic |
|||
# purpose: check basic functionality of phpdbg console |
|||
# expect: TEST::EXACT |
|||
# options: -rr |
|||
####################################################### |
|||
# [Nothing to execute!] |
|||
####################################################### |
|||
@ -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 |
|||
@ -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 |
|||
@ -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 |
|||
@ -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 |
|||
@ -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 |
|||
@ -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 |
|||
@ -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 |
|||
@ -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 |
|||
@ -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); |
|||
} |
|||
})(); |
|||
@ -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); |
|||
} |
|||
})(); |
|||
@ -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"); |
|||
} |
|||
@ -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; |
|||
@ -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"); |
|||
} |
|||
@ -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"); |
|||
} |
|||
@ -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); |
|||
} |
|||
?>
|
|||
@ -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); |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue