From: krakjoe Date: Thu, 5 Dec 2013 02:42:04 +0000 (+0000) Subject: tests X-Git-Tag: php-5.6.0alpha1~110^2~29^2~27 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=11b3a5ec05db9d694d567c39d4b513aefcb59ff9;p=php tests --- diff --git a/tests/basic.test b/tests/basic.test new file mode 100644 index 0000000000..79db6aa8a8 --- /dev/null +++ b/tests/basic.test @@ -0,0 +1,7 @@ +####################################################### +# name: basic +# purpose: check basic functionality of phpdbg console +# expect: TEST::EXACT +####################################################### +# [Nothing to execute!] +####################################################### diff --git a/tests/phpdbg.php b/tests/phpdbg.php new file mode 100644 index 0000000000..e63777320c --- /dev/null +++ b/tests/phpdbg.php @@ -0,0 +1,476 @@ +config = array_shift($argv); + $this->message = vsprintf( + array_shift($argv), $argv); + } + } + } + + /** + * 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(&$config, $cmd) { + 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': + $config[$key] = $value; + break; + + default: { + if (isset($config[$key])) { + if (is_array($config[$key])) { + $config[$key][] = $value; + } else { + $config[$key] = array($config[$key], $value); + } + } else { + $config[$key] = $value; + } + } + } + + } + } break; + + default: + $config['flags'][] = substr($key, 1); + } break; + } + } + + if (!is_executable($config['phpdbg'])) { + throw new TestConfigurationException( + $config, 'phpdbg could not be found at the specified path (%s)', $config['phpdbg']); + } else $config['phpdbg'] = realpath($config['phpdbg']); + + $conifg['width'] = (integer) $config['width']; + + /* display properly, all the time */ + if ($config['width'] < 50) { + $config['width'] = 50; + } + + /* calculate column widths */ + $config['lwidth'] = ceil($config['width'] / 3); + $config['rwidth'] = ceil($config['width'] - $config['lwidth']) - 5; + + $this->config = &$config; + + if (in_array('help', $this->config['flags'])|| + in_array('h', $this->config['flags'])) { + $this->logUsage(); + 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) { + $total = array_sum($this->stats[$path]); + + @$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 logUsage() { + 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-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)) { + yield new Test($this->config, $test); + } + } + } + + /** + * + * @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); + } + + 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; + + /** + * Constructs a new Test object given a specilized phpdbginit file + * + * @param array configuration + * @param string file + */ + public function __construct(&$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; + + 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: { + $this->match[] = ltrim(substr($trim, 1)); + } + } + } break; + + default: + break 2; + } + } + fclose($handle); + + $this->config = &$config; + $this->file = &$file; + } + } + + /** + * Obvious !! + * + */ + public function getResult() { + $options = sprintf( + '-i%s -rrqb', $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; + } + } + } + + $this->writeLog($result); + $this->writeDiff(); + + return (count($this->diff) == 0); + } + + /** + * Write diff to disk if configuration allows it + * + */ + protected function writeDiff() { + $diff = sprintf( + '%s/%s.diff', + dirname($this->file), basename($this->file)); + + if (count($this->diff['wants'])) { + if (!in_array('nodiff', $this->config['flags'])) { + if (($diff = fopen($diff, '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; + public $match; + + protected $diff; + protected $stats; + protected $totals; + } +} + +namespace { + use \phpdbg\Testing\Test; + use \phpdbg\Testing\Tests; + + $cwd = dirname(__FILE__); + $cmd = $_SERVER['argv']; + { + $config = array( + 'exec' => realpath(array_shift($cmd)), + 'phpdbg' => realpath(sprintf( + '%s/../phpdbg', $cwd + )), + 'path' => array( + realpath(dirname(__FILE__)) + ), + 'flags' => array(), + 'width' => 75 + ); + + $tests = new Tests($config, $cmd); + + foreach ($tests->findPaths() as $path) { + $tests->logPath($path); + + foreach ($tests->findTests($path) as $test) { + $tests->logTest($path, $test); + } + + $tests->logPathStats($path); + } + + $tests->logStats(); + } +} +?> diff --git a/tests/set.test b/tests/set.test new file mode 100644 index 0000000000..e85cacc321 --- /dev/null +++ b/tests/set.test @@ -0,0 +1,22 @@ +################################################# +# name: set +# purpose: tests for set commands +# expect: TEST::CISTRING +################################################# +# setting prompt color +# setting error color +# setting notice color +# Failed to find breakpoint #0 +# oplog disabled +# not enabled +# 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 0 +set oplog test.log