1, 'depth' => 2, 'format' => 'array')); $file = str_replace(dirname(dirname(dirname(__FILE__))) . '/', '', $trace[0]['file']); $line = $trace[0]['line']; echo PHP_EOL . $file . ' (line ' . $line . ')' . PHP_EOL; echo '########## DEBUG ##########' . PHP_EOL; var_dump($var); echo '###########################' . PHP_EOL . PHP_EOL; } require_once(__DIR__ . "/DiTestColor.php"); require_once(__DIR__ . "/DiTestMessage.php"); class DiTest { const StepSkip = true; public $errorCount = 0; private $__stepSkip = false; private $__stepBusy = false; private $__startCounter; private $__step; private $__stepCounter = 0; private $__testname = ""; private $__stepCount = 0; /* Total tests run */ private $__passCount = 0; /* Total tests passed */ private $__skipCount = 0; /* Total tests skipped */ private $__finishedAlready = false; /* Prevent double print of summary */ private $__qpdGen = false; private $__report = null; private function incSteps() { $this->__stepCount++; } private function incSkip() { $this->__skipCount++; } private function array_diff_recursive($aArray1, $aArray2) { $aReturn = array(); foreach ($aArray1 as $mKey => $mValue) { if (array_key_exists($mKey, $aArray2)) { if (is_array($mValue)) { $aRecursiveDiff = $this->array_diff_recursive($mValue, $aArray2[$mKey]); if (count($aRecursiveDiff)) { $aReturn[$mKey] = $aRecursiveDiff; } } else { if ($mValue != $aArray2[$mKey]) { $aReturn[$mKey] = $mValue; } } } else { $aReturn[$mKey] = $mValue; } } return $aReturn; } private function fail($msg, $depthIncr = 0, $trace = true) { if ($this->__stepSkip) { $this->skip($msg); return; } DiTestMsg::fail($msg); if ($trace) { $trace = DiTest::trace(array('start' => 2 + $depthIncr, 'depth' => 3 + $depthIncr, 'format' => 'array')); $file = str_replace(dirname(dirname(dirname(__FILE__))) . '/', '', $trace[0]['file']); $line = $trace[0]['line']; echo ' Occurred in: ' . $file . ' (line ' . $line . ')' . PHP_EOL; } $this->errorCount++; $this->assert($this->__assert); } private function assert($assert = false) { if ($assert) { $this->__assert = false; $ret = $this->finish(true); } } private function pass($msg) { if ($this->__stepSkip) { $this->skip($msg); return; } $this->__passCount++; DiTestMsg::pass($msg); } private function skip($msg) { $this->incSkip(); DiTestMsg::skip($msg); } private function __urlSafe($string) { return preg_replace('/^-+|-+$/', '', strtolower(preg_replace('/[^a-zA-Z0-9\.]+/', '-', $string))); } public function __construct($testname = false, $assert = false, $reportGen = true) { if ($testname) { $this->__testname = $testname; DiTestMsg::info(""); DiTestMsg::info(str_repeat("=", strlen($testname))); DiTestMsg::info($testname); DiTestMsg::info(str_repeat("=", strlen($testname))); DiTestMsg::info(""); if ($reportGen) { $this->__qpdGen = fopen($this->__urlSafe($testname) . '.txt', "w"); $this->__report = new TestReport($testname, $this->__urlSafe($testname)); } } $this->__assert = $assert; $this->errorCount = 0; } public function __destruct() { $this->finish(); } public function info($msg) { DiTestMsg::info($msg); } public function goal($goalStr) { if (!is_null($this->__report) && strlen($goalStr)) { $this->__report->goal($goalStr); } DiTestMsg::info(""); DiTestMsg::info("Goal:"); DiTestMsg::info($goalStr); DiTestMsg::info(""); } public function stepToQpd($str) { if ($this->__qpdGen !== false) { fwrite($this->__qpdGen, $this->__stepCounter . ". " . trim(preg_replace('/^([0-9]*)\./', '', $str)) . "\n"); } } public function step($str, $skip = false) { if ($this->__stepBusy) $this->endStep('', true); $this->__step = $str; $this->__stepCounter++; $this->__startCounter = $this->errorCount; $this->__stepBusy = true; $this->__stepSkip = $skip; DiTestMsg::run($this->__step); $this->stepToQpd($this->__step); } public function endStep($str = '', $autoEnd = false) { $str = $str; $this->__stepBusy = false; if ($this->__startCounter == $this->errorCount) { if ($this->__report !== null) $this->__report->stepFinish($this->__step, true); DiTestMsg::pass($this->__step); } else { if ($this->__report !== null) $this->__report->stepFinish($this->__step, false); DiTestMsg::fail(($this->errorCount - $this->__startCounter) . ' failure(s) for test "' . $this->__step . '"', 0, false); } } public function rpcSend($identified, $request, $json = true) { if (isset ($request['req'])){ DiTestMsg::run("Request '" . $request['req'] . "'"); } elseif (isset($request['rep'])) { DiTestMsg::run("Reply '" . $request['rep'] . "'"); } if ($json) { $identified->send(json_encode($request)); } else { $identified->send($request); } } public function rpcRecv($identified) { DiTestMsg::run("Receiving message..."); while (true) { $r = $identified->recv(); if (!$identified->getSockOpt(ZMQ::SOCKOPT_RCVMORE)) { break; } } $message = json_decode($r, true); print_r($message); return $message; } public function rpcRepOk($identified, $request = null, $replyMsg = false) { if ($request !== null) { DiTestMsg::run("Perform '" . $request['req'] . "'"); $identified->send(json_encode($request)); } $message = json_decode($identified->recv(), true); if (isset($message['error'])) { $this->fail("Error occurred, error member found"); return false; } $this->__passCount++; if (!$replyMsg) { print_r($message); return $this->errorCount; } return $message; } public function rpcRepError($identified, $request = null, $expectedError, $json = true) { $errorCnt = 0; if ($request !== null) { DiTestMsg::run("Perform '" . (isset($request['req']) ? $request['req'] : '') . "'"); if ($json) $identified->send(json_encode($request)); else $identified->send($request); } $message = json_decode($identified->recv(), true); if (!isset($message['error'])) { $this->errorCount++; $this->fail("Error occurred, error member NOT found"); } elseif($message['error']['code'] != $expectedError) { $this->errorCount++; $this->fail("Error occurred, expected code " . $expectedError . ", got " . $message['error']['code']); } else { print_r($message); $this->__passCount++; } return $message; } public function confirm($question, $positive = 'y', $negative = 'n') { $handle = fopen ("php://stdin","r"); DiTestMsg::user($question . " [".$positive."/".$negative."]: "); $exitLoop = false; while (!$exitLoop && $line = fgets($handle)) { $line = trim($line); switch($line) { case $negative: $this->fail("Invalid confirm: \"$line\""); case $positive: $exitLoop = true; break; default: DiTestMsg::user("Please type '".$positive."' or '".$negative."' [".$positive."/".$negative."]: "); break; } } fclose($handle); } public function anykey($msg) { $handle = fopen("php://stdin","r"); DiTestMsg::user($msg . ", press a key to continue..."); fgets($handle); } public function passed($msg) { DiTestMsg::pass($msg); } public function failed($msg) { DiTestMsg::fail($msg); } public function msleep($msg, $ms) { DiTestMsg::wait("[$ms ms] " . $msg); usleep($ms * 1000); } public function sleep($msg, $seconds) { return $this->msleep($msg, $seconds * 1000); } public function reset() { DiTestMsg::run("Resetting Test-statistics"); $this->__stepCount = 0; $this->__passCount = 0; $this->errorCount = 0; $this->__skipCount = 0; } public function isTrue($actual) { $this->incSteps(); if ($actual) { $this->__passCount++; return true; } $this->fail("Expected true, got '" . (($actual) ? 'true' : 'false') . "'"); return false; } public function isFalse($actual) { $this->incSteps(); if (!$actual) { $this->__passCount++; return true; } $this->fail("Expected false, got '" . (($actual) ? 'true' : 'false') . "'"); return false; } public function failure($msg) { $this->incSteps(); $this->fail($msg); } public function equal($expected, $actual, $assert = false) { $this->incSteps(); if (is_array($expected)) { if (is_array($actual)) { $diff = $this->array_diff_recursive($expected, $actual); $diff += $this->array_diff_recursive($actual, $expected); if (count($diff)) { $this->fail("Expected and actual array differ, expected:"); var_dump($expected); $this->failed("got:"); var_dump($actual); $this->assert($assert); return false; } $this->__passCount++; return true; } $this->fail("Expected array, got '" . $actual . "'"); $this->assert($assert); return false; } if ($expected == $actual) { $this->__passCount++; return true; } if (is_bool($actual)) { $actual = ($actual) ? 'true' : 'false'; } if (is_bool($expected)) { $expected = ($expected) ? 'true' : 'false'; } $this->fail("Expected '" . $expected . "', got '" . $actual . "'"); $this->assert($assert); return false; } public function notEqual($expected, $actual) { $this->incSteps(); if (is_array($expected)) { if (is_array($actual)) { $diff = $this->array_diff_recursive($expected, $actual); $diff += $this->array_diff_recursive($actual, $expected); if (count($diff)) { $this->__passCount++; return true; } $this->fail("Arrays are identical"); return false; } $this->__passCount++; return true; } if ($expected != $actual) { $this->__passCount++; return true; } $this->fail("Expected something else then '" . $expected . "', got '" . $actual . "'"); return false; } public function range($actual, $min, $max) { $this->incSteps(); if (($actual >= $min) && ($actual <= $max)) { $this->__passCount++; return true; } else { if ($actual < $min) { $delta = $actual - $min; $sign = ""; } else if ($actual > $max) { $delta = $actual - $max; $sign = "+"; } else { $delta = "?"; $sign = "?"; } $this->fail("Expect >= $min && <= $max, got $actual (delta: $sign$delta)"); return false; } } /** * Outputs a stack trace based on the supplied options. * * ### Options * * - `depth` - The number of stack frames to return. Defaults to 999 * - `format` - The format you want the return. Defaults to the currently selected format. If * format is 'array' or 'points' the return will be an array. * - `args` - Should arguments for functions be shown? If true, the arguments for each method call * will be displayed. * - `start` - The stack frame to start generating a trace from. Defaults to 0 * * @param array $options Format for outputting stack trace * @return mixed Formatted stack trace * @link http://book.cakephp.org/2.0/en/development/debugging.html#Debugger::trace */ public static function trace($options = array()) { $_templates = array( 'log' => array( 'trace' => '{:reference} - {:path}, line {:line}', 'error' => "{:error} ({:code}): {:description} in [{:file}, line {:line}]" ), 'js' => array( 'error' => '', 'info' => '', 'trace' => '
{:trace}
', 'code' => '', 'context' => '', 'links' => array(), 'escapeContext' => true, ), 'html' => array( 'trace' => '
Trace 

{:trace}

', 'context' => '
Context 

{:context}

', 'escapeContext' => true, ), 'txt' => array( 'error' => "{:error}: {:code} :: {:description} on line {:line} of {:path}\n{:info}", 'code' => '', 'info' => '' ), 'base' => array( 'traceLine' => '{:reference} - {:path}, line {:line}', 'trace' => "Trace:\n{:trace}\n", 'context' => "Context:\n{:context}\n", ) ); $defaults = array( 'depth' => 999, 'format' => 'txt', 'args' => false, 'start' => 0, 'scope' => null, 'exclude' => array('call_user_func_array', 'trigger_error') ); foreach ($options as $k => $option) { $defaults[$k] = $option; } $options = $defaults; $backtrace = debug_backtrace(); $count = count($backtrace); $back = array(); $_trace = array( 'line' => '??', 'file' => '[internal]', 'class' => null, 'function' => '[main]' ); for ($i = $options['start']; $i < $count && $i < $options['depth']; $i++) { $trace = array_merge(array('file' => '[internal]', 'line' => '??'), $backtrace[$i]); $signature = $reference = '[main]'; if (isset($backtrace[$i + 1])) { $next = array_merge($_trace, $backtrace[$i + 1]); $signature = $reference = $next['function']; if (!empty($next['class'])) { $signature = $next['class'] . '::' . $next['function']; $reference = $signature . '('; if ($options['args'] && isset($next['args'])) { $args = array(); foreach ($next['args'] as $arg) { $args[] = Debugger::exportVar($arg); } $reference .= implode(', ', $args); } $reference .= ')'; } } if (in_array($signature, $options['exclude'])) { continue; } if ($options['format'] === 'points' && $trace['file'] !== '[internal]') { $back[] = array('file' => $trace['file'], 'line' => $trace['line']); } elseif ($options['format'] === 'array') { $back[] = $trace; } else { if (isset($_templates[$options['format']]['traceLine'])) { $tpl = $_templates[$options['format']]['traceLine']; } else { $tpl = $_templates['base']['traceLine']; } $trace['path'] = static::trimPath($trace['file']); $trace['reference'] = $reference; unset($trace['object'], $trace['args']); $back[] = CakeText::insert($tpl, $trace, array('before' => '{:', 'after' => '}')); } } if ($options['format'] === 'array' || $options['format'] === 'points') { return $back; } return implode("\n", $back); } private function exitTestSummary() { $summary = DiTestColor::set("[ Summary ]", "bold"); DiTestMsg::info(""); DiTestMsg::info($summary . " [ PASS ] : $this->__passCount"); DiTestMsg::info($summary . " [ FAIL ] : $this->errorCount"); DiTestMsg::info($summary . " [ SKIP ] : $this->__skipCount"); DiTestMsg::info($summary . " Total compares: $this->__stepCount"); if ($this->errorCount > 0) { DiTestMsg::fail($summary . " Test \"$this->__testname\" has $this->errorCount error(s)", 0, false); } else { DiTestMsg::pass($summary . " Test \"$this->__testname\" has no errors reported"); } } /* Get summary of tests */ public function summary() { return array( "pass" => $this->__passCount, "fail" => $this->errorCount, "skip" => $this->__skipCount); } public function finish($exit = true) { $ret = ($this->errorCount > 0) ? 1 : 0; if ($this->__finishedAlready == true) return $ret; $this->__finishedAlready = true; $this->__assert = false; // This prevents calling ourselfs to many times... if ($this->__stepBusy) $this->endStep('', true); if ($this->__report !== null) $this->__report->writeReport($this->summary()); if ($this->__qpdGen) fclose($this->__qpdGen); $this->exitTestSummary(); usleep(50 * 1000); if ($ret) exit($ret); else return $ret; } } require_once(__DIR__ . "/TestReport.php"); require_once(__DIR__ . "/predis-1.0.3/src/Autoloader.php"); require_once(__DIR__ . "/websocket_client.php"); require_once(__DIR__ . "/equipment/can.php"); require_once(__DIR__ . "/equipment/psu_cpx400.php"); require_once(__DIR__ . "/equipment/psu_labps3005d.php"); if (extension_loaded("zmq")) { require_once(__DIR__ . "/rpc/RequestSocket.php"); require_once(__DIR__ . "/rpc/ReplySocket.php"); require_once(__DIR__ . "/rpc/PublishSocket.php"); require_once(__DIR__ . "/rpc/PairSocket.php"); } require_once(__DIR__ . "/rpc/constants.php"); Predis\Autoloader::register();