00001 <?php
00002
00003
00004
00037 class TLNetwork
00038 {
00044 public static function netmaskDot2Bit($nmDot) {
00045 $netmask_full = 0; $netmask_full = ~$netmask_full;
00046 $bitnetmask = $netmask_full - ip2long($nmDot);
00047 return (32-strlen(decbin($bitnetmask)));
00048 }
00049
00055 public static function netmaskBit2Dot ($nmBit) {
00056 $bitnetmask_inv = pow(2, (int)(32-$nmBit)) - 1;
00057 $netmask_full = 0; $netmask_full = ~$netmask_full;
00058
00059 return (long2ip($netmask_full - $bitnetmask_inv));
00060 }
00061 }
00062
00068 class TLString
00069 {
00086 public static function explodeAssign($string, $seperator, $vars)
00087 {
00088 $temp = explode($seperator, $string);
00089 if (count($temp) != count($vars)) {
00090 return(false);
00091 } else {
00092 for ($i = 0; $i != count($temp); $i++) {
00093 $vars[$i] = $temp[$i];
00094 }
00095 return(true);
00096 }
00097 }
00098
00113 public static function arrayAssign($array, $vars)
00114 {
00115 if (count($array) != count($vars)) {
00116 return(false);
00117 } else {
00118 for ($i = 0; $i != count($array); $i++) {
00119 $vars[$i] = $array[$i];
00120 }
00121 return(true);
00122 }
00123 }
00124
00133 public static function isOfChars($string, $chars)
00134 {
00135 return(!preg_match("/[^".preg_quote($chars, '/')."]/", $string));
00136 }
00137
00145 public static function startsWith($string, $start)
00146 {
00147 if (strlen($string) >= strlen($start)) {
00148 if (substr($string, 0, strlen($start)) == $start) {
00149 return(true);
00150 }
00151 }
00152 return(false);
00153 }
00154
00162 public static function endsWith($string, $end)
00163 {
00164 if (strlen($string) >= strlen($end)) {
00165 if (substr($string, strlen($string)-strlen($end)) == $end) {
00166 return(true);
00167 }
00168 }
00169 return(false);
00170 }
00171 }
00172
00178 class TLVars
00179 {
00191 public static function isEmpty($var = null)
00192 {
00193 if ($var === "" || $var === null || $var === false || $var === 0 || $var === array()) {
00194 return(true);
00195 }
00196 return(false);
00197 }
00198
00228 public static function import($varName, $from, $default = "") {
00229 $i = $c = "";
00230 $varValue = FALSE;
00231
00232 for ($i = 0; $i < strlen($from); $i++) {
00233
00234 $c = $from[$i];
00235
00236 switch ($c) {
00237 case 'F' : if (isset($_FILES) && array_key_exists($varName, $_FILES)) { $varValue = $_FILES[$varName]; } break;
00238 case 'S' : if (isset($_SESSION) && array_key_exists($varName, $_SESSION)) { $varValue = $_SESSION[$varName]; } break;
00239 case 'P' : if (isset($_POST) && array_key_exists($varName, $_POST)) { $varValue = $_POST[$varName]; } break;
00240 case 'G' : if (isset($_GET) && array_key_exists($varName, $_GET)) { $varValue = $_GET[$varName]; } break;
00241 case 'C' : if (isset($_COOKIE) && array_key_exists($varName, $_COOKIE)) { $varValue = $_COOKIE[$varName]; } break;
00242 default: break;
00243 }
00244 }
00245
00246 if ($varValue === FALSE) {
00247 if ($default != "") {
00248 return ($default);
00249 } else {
00250 return(null);
00251 }
00252 } else {
00253 return ($varValue);
00254 }
00255 }
00256 }
00257
00261 class TLControlStruct
00262 {
00268 public static function isMain($from)
00269 {
00270 if ($from == realpath($_SERVER["SCRIPT_FILENAME"])) {
00271 return(true);
00272 } else {
00273 return(false);
00274 }
00275 }
00276 }
00277
00356 class TLUnitTest {
00357
00358 private $appName = "";
00359 private $cnt = 1;
00360 private $testOutput = array();
00361 private $testResults = array();
00362 private $currentTest = array();
00363 private $otherErros = "";
00364
00365 private $prevErrorReporting = 0;
00372 public function __construct($appName, $testClass) {
00373 $this->prevErrorReporting = error_reporting(E_ALL);
00374 set_error_handler(array(&$this, "errorHandler"));
00375 $this->appName = $appName;
00376 $this->testClass = $testClass;
00377 $this->run($this->testClass);
00378 }
00379
00380
00381
00382
00383 public function __destruct() {
00384 restore_error_handler();
00385 error_reporting($this->prevErrorReporting);
00386 }
00387
00392 public function errorHandler($errno, $errmsg, $filename, $linenum, $vars) {
00393 if ($this->currentTest == array()) {
00394
00395 $this->otherErrors .= "$filename($linenum): Error $errno: '$errmsg'\n";
00396 } else {
00397 $e = new Exception($errmsg, $errno);
00398 $this->failed($e);
00399 }
00400 }
00401
00406 public function exceptionHandler($e) {
00407 $this->failed($e);
00408 }
00409
00410 private function run($testClass) {
00411 $props = get_object_vars($this->testClass);
00412 if (array_key_exists("testNames", $props)) {
00413 $hasNames = true;
00414 } else {
00415 $hasNames = false;
00416 }
00417 foreach(get_class_methods($this->testClass) as $method) {
00418 if (!TLString::explodeAssign($method, "_", array(&$group, &$name))) {
00419 $group = "";
00420 $name = $method;
00421 }
00422 if ($hasNames && array_key_exists($method, $this->testClass->testNames)) {
00423 $name = $this->testClass->testNames[$method];
00424 }
00425
00426
00427 $this->start($group, $name);
00428 try {
00429 call_user_func(array($testClass, $method), $this);
00430 } catch(Exception $e) {
00431 $this->exceptionHandler($e);
00432 }
00433 $this->end();
00434 }
00435 }
00436
00437 private function start($testGroup, $testName) {
00438 $this->currentTest = array(
00439 "group" => $testGroup,
00440 "nr" => $this->cnt++,
00441 "name" => $testName,
00442 "result" => "",
00443 "dump" => "",
00444 );
00445 $this->passed();
00446 }
00447
00451 public function passed() {
00452 $this->currentTest["passed"] = true;
00453 $this->currentTest["result"] = "";
00454 $this->currentTest["dump"] = "";
00455
00456 $this->currentTest = array_merge($this->currentTest, array(
00457 "passed" => true,
00458 )
00459 );
00460 }
00461
00468 public function failed($e) {
00469 $this->currentTest["passed"] = false;
00470 $this->currentTest["result"] .= $e->getMessage()."\n";
00471 $this->currentTest["dump"] .= $e->getMessage()."\n";
00472 foreach($e->getTrace() as $stackFrame) {
00473 if (array_key_exists("file", $stackFrame)) {
00474 $this->currentTest["dump"] .= " ".
00475 $stackFrame["file"] . ":".$stackFrame["line"]." - ";
00476 if (array_key_exists("class", $stackFrame)) {
00477 $this->currentTest["dump"] .= $stackFrame["class"];
00478 }
00479 if (array_key_exists("type", $stackFrame)) {
00480 $this->currentTest["dump"] .= " ".$stackFrame["type"]." ";
00481 }
00482 if (array_key_exists("function", $stackFrame)) {
00483 $this->currentTest["dump"] .= $stackFrame["function"]."(";
00484 }
00485 if (array_key_exists("args", $stackFrame) && count($stackFrame["args"] > 0)) {
00486 foreach($stackFrame["args"] as $arg) {
00487 $this->currentTest["dump"] .= $arg.", ";
00488 }
00489 if (substr($this->currentTest["dump"], -2) == ", ") {
00490 $this->currentTest["dump"] = substr($this->currentTest["dump"], 0, -2);
00491 }
00492 }
00493 if (array_key_exists("function", $stackFrame)) {
00494 $this->currentTest["dump"] .= ")";
00495 }
00496 $this->currentTest["dump"] .= "\n";
00497 }
00498 }
00499 $this->currentTest["dump"] .= "\n";
00500 }
00501
00506 public function assert($bool) {
00507 if ($bool) {
00508 $this->passed();
00509 } else {
00510 throw new Exception("Assertion failed");
00511 }
00512 }
00513
00514 private function end() {
00515 $this->testResults[] = $this->currentTest;
00516 $this->currentTest = array();
00517 }
00518
00519 private function sortResultsByGroup() {
00520 $cmp = create_function('$a,$b', '
00521 if ($a["group"] == $b["group"]) {
00522 return (0);
00523 };
00524 return($a["group"] > $b["group"] ? -1 : 1);
00525 ');
00526 usort($this->testResults, $cmp);
00527 }
00528
00534 public function dumpHtml($hidePassed = false, $sortGroups = false) {
00535 if ($sortGroups) {
00536 $this->sortResultsByGroup();
00537 }
00538 $out = "
00539 <html>
00540 <body>
00541 <style>
00542 body { font-family: sans-serif; }
00543 table { border: 1px solid #000000; }
00544 th { empty-cells: show; font-family: sans-serif; border-left: 1px solid #FFFFFF; border-top: 1px solid #FFFFFF; border-bottom: 1px solid #000000; border-right: 1px solid #000000; margin: 0px; font-size: x-small; color: #FFFFFF; background-color: #404040; padding: 2px 4px 2px 4px; }
00545 td { empty-cells: show; font-family: sans-serif; border-bottom: 1px solid #909090; margin: 0px; padding: 2px 4px 2px 4px; border-left: 1px solid #E0E0E0; font-size: x-small; }
00546 div.dump { background-color: #F0F0F0; }
00547 a.dump { text-decoration: underline; cursor: pointer; }
00548 </style>
00549 </body>
00550 <h1>Test results for ".$this->appName."</h1>
00551 <h2>Test results</h2>
00552 <table cellspacing='0' cellpadding='0'>
00553 ";
00554 $prevResult = $this->testResults[0];
00555 $nrOfPassed = 0;
00556 $nrOfFailed = 0;
00557 foreach ($this->testResults as $result) {
00558 if ($result["passed"] == false) {
00559 $nrOfFailed++;
00560 $textResult = "FAILED";
00561 $rowColor = "#FF0000";
00562 $dump = "<a class='dump' onclick='document.getElementById(\"dump_".$result["nr"]."\").style.display=\"block\"'>Dump</a><div style='border: 1px solid #000000; background-color: #F0F0F0; display:none;' class='dump' id='dump_".$result["nr"]."'><pre>".$result["dump"]."</pre></div>";
00563 } else {
00564 $nrOfPassed++;
00565 if ($hidePassed) {
00566 continue;
00567 }
00568 $textResult = "passed";
00569 $rowColor = "#50FF00";
00570 $dump = "";
00571 }
00572 if ($result["group"] != $prevResult["group"]) {
00573 $out .= "
00574 <tr valign='top' align='left'>
00575 <td colspan='6'></td>
00576 </tr>\n";
00577 }
00578 $out .= "
00579 <tr valign='top' align='left'>
00580 <th>".$result["nr"]."</th>
00581 <th>".$result["group"]."</th>
00582 <th>".$result["name"]."</th>
00583 <td bgcolor='".$rowColor."'>".$textResult."</td>
00584 <td>".str_replace("\n", "<br />\n", $result["result"])."</td>
00585 <td>".$dump."</td>
00586 </tr>\n";
00587
00588 $prevResult = $result;
00589 }
00590 $out .= "
00591 </table>
00592 <h2>Total results</h2>
00593 <table cellspacing='0' cellpadding='0'>
00594 <tr><th>Passed:</th><td>".$nrOfPassed."</td></tr>
00595 <tr><th>Failed:</th><td>".$nrOfFailed."</td></tr>
00596 </table>
00597 <h2>Non-testcase errors</h2>
00598 <pre>\n".$this->otherErrors."
00599 </pre>
00600 </html>
00601 ";
00602
00603 return($out);
00604 }
00605
00610 public function dumpPrettyText($hidePassed = false) {
00611 $fmt = "%3s | %-60s | %-6s | %s\n";
00612 $sep = "%3s-+-%-60s-+-%-6s-+-%s\n";
00613
00614 $out = "";
00615 $out .= sprintf($fmt, "Nr", "Test", "Passed", "Result");
00616 $out .= sprintf($sep, str_repeat('-', 3), str_repeat('-', 60), str_repeat('-', 6), str_repeat('-', 40));
00617 foreach ($this->testResults as $result) {
00618 if ($result["passed"] == false) {
00619 $textResult = "FAILED";
00620 } else {
00621 if ($hidePassed) {
00622 continue;
00623 }
00624 $textResult = "passed";
00625 }
00626 $out .= sprintf($fmt, $result["nr"], $result["group"].":".$result["name"], $textResult, $result["result"]);
00627 }
00628 return($out);
00629 }
00630 }
00631
00637 class TLDebug {
00638
00650 static function backtraceString($relative = True) {
00651 $out = "";
00652
00653 if ($relative) {
00654 $docRootLen = strlen($_SERVER["DOCUMENT_ROOT"]);
00655 } else {
00656 $docRootLen = 0;
00657 }
00658
00659 $trace = debug_backtrace();
00660 if (is_array($trace)) {
00661 for ($i = 0; $i != count($trace); $i++) {
00662 $stackFrame = $trace[$i];
00663
00664
00665 if (array_key_exists("class", $stackFrame) && $stackFrame["class"] == __CLASS__) {
00666 continue;
00667 }
00668
00669 if (array_key_exists("file", $stackFrame)) {
00670 $out .= substr($stackFrame["file"], $docRootLen, strlen($stackFrame["file"]) - $docRootLen).":";
00671 } else {
00672 $out .= "??:";
00673 }
00674 if (array_key_exists("line", $stackFrame)) {
00675 $out .= $stackFrame["line"]." ";
00676 } else {
00677 $out .= "?? ";
00678 }
00679 if (array_key_exists("class", $stackFrame)) {
00680 $out .= $stackFrame["class"].$stackFrame["type"];
00681 }
00682 if (array_key_exists("function", $stackFrame)) {
00683 $out .= $stackFrame["function"]."(";
00684 $args = array();
00685 if (array_key_exists("args", $stackFrame)) {
00686 foreach($stackFrame["args"] as $arg) {
00687 if (gettype($arg) == "array") {
00688 $args[] = "Array(".@implode(", ", $arg).")";
00689 } else {
00690 $args[] = $arg;
00691 }
00692 }
00693 $out .= implode(", ", $args);
00694 }
00695 $out .= ")";
00696 }
00697 $out .= "\n";
00698 }
00699 }
00700
00701 return($out);
00702 }
00703
00713 static function backtraceSingleLine($relative = True) {
00714 $out = TLDebug::backtraceString($relative);
00715 $out = str_replace("\n", "; ", $out);
00716 return($out);
00717 }
00718
00722 static function startPedantic() {
00723 assert_options(ASSERT_ACTIVE, 1);
00724 assert_options(ASSERT_WARNING, 1);
00725 assert_options(ASSERT_BAIL, 1);
00726 if (defined("E_STRICT")) {
00727 error_reporting(E_ALL | E_STRICT);
00728 } else {
00729 error_reporting(E_ALL);
00730 }
00731 ini_set("display_errors", "1");
00732 }
00733 }
00734
00764 class TLTypeException extends Exception {
00765
00772 public function __construct($expectedType, $gotVar, $varName = null) {
00773
00774 $this->expectedType = $expectedType;
00775 $this->type = gettype($gotVar);
00776 if ($varName != null) {
00777 $this->name = $varName;
00778 }
00779 if (is_object($gotVar)) {
00780 $this->value = get_class($gotVar);
00781 $this->class = get_class($gotVar);
00782 } else {
00783 $this->value = $gotVar;
00784 }
00785
00786 if (isset($this->name)) {
00787 $message = sprintf("Expected \"%s\", got \"%s(%s)\" for variable \"%s\"", $this->expectedType, $this->type, $this->value, $this->name);
00788 } else {
00789 $message = sprintf("Expected \"%s\", got \"%s(%s)\"", $this->expectedType, $this->type, $this->value);
00790 }
00791
00792 parent::__construct($message);
00793 }
00794 }
00795
00823 class TLValueException extends Exception {
00824
00831 public function __construct($message, $gotVar, $varName) {
00832 $message = sprintf("\"$%s(%s)\": %s", $varName, $gotVar, $message);
00833 parent::__construct($message);
00834 }
00835 }
00836
00848 class TLSQLException extends Exception {
00849
00855 public function __construct($message, $query = "") {
00856 $this->message = $message;
00857 $this->query = $query;
00858 }
00859
00864 public function getQuery() {
00865 return($this->query);
00866 }
00867 }
00868
00869
00904 class TLSelfURL {
00905
00906 public $type = "";
00907 public $host = "";
00908 public $port = "";
00909 public $path = "";
00910 public $script = "";
00911 public $params = null;
00916 public function __construct() {
00917 if (array_key_exists("HTTPS", $_SERVER)) {
00918 $this->type = "https";
00919 } else {
00920 $this->type = "http";
00921 }
00922
00923
00924 if (!array_key_exists("HTTP_HOST", $_SERVER)) {
00925 throw new Exception("Not running on a HTTP server");
00926 }
00927
00928 $this->host = $_SERVER["HTTP_HOST"];
00929 $this->port = $_SERVER["SERVER_PORT"];
00930 $this->path = dirname($_SERVER["PHP_SELF"]);
00931 $this->script = basename($_SERVER["PHP_SELF"]);
00932
00933 $this->params = $_REQUEST;
00934 if (array_key_exists("PHPSESSID", $this->params)) {
00935
00936 unset($this->params["PHPSESSID"]);
00937 }
00938
00939
00940 if (strlen($this->path) == 0 || $this->path[0] != '/') {
00941 $this->path = '/'.$this->path;
00942 }
00943 if ($this->path[strlen($this->path) - 1] == '/') {
00944 $this->path = substr($this->path, 0, strlen($this->path) - 1);
00945 }
00946
00947 assert($this->self_check());
00948 }
00949
00956 public function getServerURL() {
00957 $serverURL = $this->type."://".$this->host;
00958 if ($this->port != "80" && $this->port != "443") {
00959 $serverURL .= ":" . $this->port;
00960 }
00961 return($serverURL);
00962 }
00963
00970 public function getAbsolutePathURL() {
00971 $pathURL = $this->getServerURL();
00972 $pathURL .= $this->path;
00973 return($pathURL);
00974 }
00975
00982 public function getRelativePathURL() {
00983 $pathURL = $this->path;
00984 return($pathURL);
00985 }
00986
00992 public function getAbsoluteScriptURL() {
00993 $scriptURL = $this->getServerURL();
00994 $scriptURL .= $this->path . '/' . $this->script;
00995 return($scriptURL);
00996 }
00997
01003 public function getRelativeScriptURL() {
01004 $scriptURL = $this->path . '/' . $this->script;
01005 return($scriptURL);
01006 }
01007
01016 public function getParams($stripVarsPrefix = null) {
01017 $paramsString = "";
01018
01019
01020 if (count($this->params) > 0) {
01021
01022 if ($stripVarsPrefix != null) {
01023 $vars = $this->params;
01024 $prefixLen = strlen($stripVarsPrefix);
01025 foreach(array_keys($vars) as $key) {
01026 if (substr($key, 0, $prefixLen) == $stripVarsPrefix) {
01027 unset($vars[$key]);
01028 }
01029 }
01030 $paramsString .= "?".http_build_query($vars);
01031 } else {
01032 $paramsString .= "?".http_build_query($this->params);
01033 }
01034 }
01035
01036 return($paramsString);
01037 }
01038
01044 public function getAbsoluteFullURL($stripVarsPrefix = null) {
01045 $fullURL = $this->getAbsoluteScriptURL();
01046 $fullURL .= $this->getParams($stripVarsPrefix);
01047
01048 return($fullURL);
01049 }
01050
01057 public function getRelativeFullURL($stripVarsPrefix = null) {
01058 $fullURL = $this->getRelativeScriptURL();
01059 $fullURL .= $this->getParams($stripVarsPrefix);
01060 return($fullURL);
01061 }
01062
01068 private function self_check() {
01069 if (
01070 $this->type == "" ||
01071 $this->host == "" ||
01072 $this->port == "" ||
01073 $this->path == "" ||
01074 $this->script == "" ||
01075 $this->params == "") {
01076 return(false);
01077 } else {
01078 return(true);
01079 }
01080 }
01081 }
01082
01083 TLDebug::startPedantic();
01084
01085
01086 if (TLControlStruct::isMain(__FILE__)) {
01087
01088
01089
01090
01091 print (TLNetwork::netmaskDot2Bit("255.255.254.0")."\n");
01092
01093
01094 print (TLNetwork::netmaskBit2Dot(24)."\n");
01095
01096
01097
01098
01099
01100 if (!TLString::explodeAssign("Peterson:Pete:25", ':', array(&$last,&$first,&$age))) {
01101 $last = "Doe";
01102 $first = "John";
01103 $age = "38";
01104 }
01105 print ("Hello $first $last. You are $age years old.\n");
01106
01107
01108 $username = "-^myusername102^-";
01109 if (!TLString::isOfChars($username, "a-z0-9")) {
01110 print ("Invalid username\n");
01111 }
01112
01113
01114 if (TLString::startsWith("Hello", "He")) {
01115 print ("'Hello' starts with 'He'\n");
01116 }
01117
01118
01119 if (TLString::endsWith("Hello", "lo")) {
01120 print ("'Hello' ends with 'lo'\n");
01121 }
01122
01123
01124
01125
01126
01127 if (@TLVars::isEmpty(false)) { print ("Empty\n"); }
01128 if (@TLVars::isEmpty($ape)) { print ("Empty\n"); }
01129
01130
01131 $foo = TLVars::import("foo", "GP", "default value");
01132 print($foo."\n");
01133
01134
01135
01136
01137
01138 if (TLControlStruct::isMain(__FILE__)) {
01139 print ("We are the main script!\n");
01140 } else {
01141 print ("We are merely being included\n");
01142 }
01143
01144
01145
01146
01147 class TestMe {
01148 public $testNames = array(
01149 "User_Load" => "Load user",
01150 "Group_AddUser" => "Add user to group",
01151 "FailingCase" => "Deliberitely fail",
01152 );
01153
01154 public function User_Load($test) {
01155 $this->user = "john";
01156 $test->assert($this->user == "john");
01157 }
01158 public function Group_AddUser($test) {
01159 $this->group[] = $this->user;
01160 }
01161 public function FailingCase($test) {
01162 throw new Exception("This testcase will fail");
01163 }
01164 }
01165 $cases = new TestMe();
01166 $test = new TLUnitTest("ExampleTest", $cases);
01167 print($test->dumpPrettyText());
01168 $test->__destruct();
01169
01170
01171
01172
01173
01174 function TLTypeExceptionTest($name) {
01175 if (!is_string($name)) {
01176 throw new TLTypeException("string", $name, "name");
01177 }
01178 }
01179 try {
01180 TLTypeExceptionTest("ferry");
01181 TLTypeExceptionTest(26);
01182 } catch (TLTypeException $e) {
01183 print($e->getMessage()."\n");
01184 }
01185
01186
01187
01188
01189
01190 function TLValueExceptionTest($age) {
01191 if (!($age > -1 and $age < 200)) {
01192 throw new TLValueException("Age should be between 0 and 200", $age, "age");
01193 }
01194 }
01195 try {
01196 TLValueExceptionTest(50);
01197 TLValueExceptionTest(230);
01198 } catch (TLValueException $e) {
01199 print($e->getMessage()."\n");
01200 }
01201
01202
01203
01204
01205
01206 try {
01207 $s = new TLSelfURL();
01208 print ($s->getServerURL());
01209 print ($s->getAbsolutePathURL());
01210 print ($s->getAbsoluteScriptURL());
01211 print ($s->getAbsoluteFullURL());
01212 print ($s->getAbsoluteFullURL("strip_"));
01213 print ($s->getRelativePathURL());
01214 print ($s->getRelativeScriptURL());
01215 print ($s->getRelativeFullURL());
01216 print ($s->getRelativeFullURL("strip_"));
01217 } catch (Exception $e) {
01218
01219 ;
01220 }
01221 }
01222 ?>