diff --git a/Load.php b/Load.php index a765c2b..9312873 100644 --- a/Load.php +++ b/Load.php @@ -16,6 +16,8 @@ class Load static protected $exclude = array(); + static protected $builder = null; + /** * Add exclude path for autoload. Should be called before setAutoloadFrom * @static @@ -24,12 +26,12 @@ class Load */ static public function setExclude($exclude = array()) { - if(!is_array($exclude)) { + if (!is_array($exclude)) { $exclude = array($exclude); } self::$exclude = array_merge(self::$exclude, $exclude); } - + static public function setAutoloadFrom($file) { self::$file = $file; @@ -72,12 +74,14 @@ class Load } $scan = array(PATH . '/' . APP . '/src', PATH . '/lib'); - $exclude = array_merge(self::$exclude, array(PATH . '/.git', PATH . '/lib/core/tests', PATH . '/lib/core/.git')); + $exclude = array_merge(self::$exclude, array(PATH . '/.git', PATH . '/lib/core/tests', PATH . '/lib/core/.git')); - require_once(PATH . '/lib/core/util/AutoloadBuilder.php'); - $builder = new AutoloadBuilder(self::$file, $scan, $exclude); - $builder->build(); + if (!self::$builder) { + require_once(PATH . '/lib/core/util/AutoloadBuilder.php'); + self::$builder = new AutoloadBuilder(self::$file, $scan, $exclude); + } + self::$builder->build(); ignore_user_abort(false); } } \ No newline at end of file diff --git a/Registry.php b/Registry.php index 89fee9f..ed61adf 100644 --- a/Registry.php +++ b/Registry.php @@ -42,7 +42,7 @@ class Registry extends ArrayObject } /** - * @codeCoverageIgnoreStart + * @codeCoverageIgnoreEnd */ /** diff --git a/app/ErrorAction.php b/app/ErrorAction.php index f85a8d6..057a272 100644 --- a/app/ErrorAction.php +++ b/app/ErrorAction.php @@ -25,11 +25,12 @@ class ErrorAction extends Action protected function execute() { - $this->template = 500; if ($this->exception instanceof Error404Exception) { $this->template = 404; } elseif ($this->exception instanceof ErrorHTTPException) { $this->template = 'HTTP'; + } else { + $this->template = 500; } $this->logError(); $this->sendHTTPCode(); @@ -50,42 +51,17 @@ class ErrorAction extends Action protected function sendHttpCode() { - switch ($this->template) { - case 404: - case 'HTTP': - header($this->exception->getHTTPHeader()); - break; - default: - header('HTTP/1.0 500 Internal Server Error'); + if ($this->exception instanceof ErrorHTTPException) { + header($this->exception->getHTTPHeader()); + } else { + header('HTTP/1.0 500 Internal Server Error'); } } protected function logError() { - if ($this->template == 500) { - $error = 0; - $ex = $this->exception; - if ($ex instanceof ErrorException) { - $error = $ex->getSeverity(); - } - - switch ($error) { - case E_NOTICE: - $error = 'Notice'; - break; - case E_WARNING: - $error = 'Warning'; - break; - case E_ERROR: - $error = 'Fatal Error'; - break; - default: - $error = 'Unknown Error'; - break; - } - $message = 'PHP ' . $error . ': ' . $ex->getMessage() . ' in ' . $ex->getFile() - . ' on line ' . $ex->getLine(); - error_log($message); + if (!$this->exception instanceof Error404Exception) { + ErrorHandler::logError($this->exception); } } diff --git a/app/FrontController.php b/app/FrontController.php index 2fe5889..dc0e79a 100644 --- a/app/FrontController.php +++ b/app/FrontController.php @@ -143,6 +143,7 @@ class FrontController header('HTTP/1.0 500 Internal Server Error'); } } + ErrorHandler::logError($e); return ErrorHandler::showDebug($e); } $layout_class = $this->getRouter()->getErrorLayout(); diff --git a/exception/ErrorHandler.php b/exception/ErrorHandler.php index d38714b..0773a4a 100644 --- a/exception/ErrorHandler.php +++ b/exception/ErrorHandler.php @@ -27,6 +27,45 @@ class ErrorHandler return true; } + static public function logError($exception) + { + $error = 0; + $exception_name = ''; + if ($exception instanceof ErrorException) { + $error = $exception->getSeverity(); + } else { + $exception_name = get_class($exception) . ': '; + } + + switch ($error) { + case E_NOTICE: + $error = 'Notice'; + break; + case E_WARNING: + $error = 'Warning'; + break; + case E_ERROR: + $error = 'Fatal Error'; + break; + default: + $error = 'Unknown Error'; + break; + } + $message = 'PHP ' . $error . ': ' . $exception_name . $exception->getMessage() . ' in ' . $exception->getFile() . ':' . $exception->getLine() . ' \nStack trace:\n' . $exception->getTraceAsString() . self::getHTTPErrorConditions(); + // PHP Fatal error: Uncaught exception 'LogicException' in /www/test.tfs/face/htdocs/index.php:11\nStack trace:\n#0 {main}\n thrown in /www/test.tfs/face/htdocs/index.php on line 11, referer: http://test.tfs.manekeno.netmonsters.ru/news/create + error_log($message); + } + + static public function getHTTPErrorConditions() + { + $text = null; + if (!is_null(Env::Server('REQUEST_METHOD')) && !is_null(Env::Server('REQUEST_URI'))) { + $text = ', URL: ' . Env::Server('REQUEST_METHOD') . ' ' . Env::Server('REQUEST_URI'); + $text .= ', referrer: ' . Env::Server('HTTP_REFERER'); + } + return $text; + } + static protected function getSource($file, $hiline) { $code = array(); diff --git a/tests/LoadTest.php b/tests/LoadTest.php index c0a1d1a..28fe9ef 100644 --- a/tests/LoadTest.php +++ b/tests/LoadTest.php @@ -36,7 +36,6 @@ class LoadTest extends PHPUnit_Framework_TestCase /** * @TODO: Load->buildAutoload() should recieve AutoloadBuilder as a parameter - * @TODO: Load->buildAutoload() - uses two paths - PATH . '/' . APP . '/src' and PATH . '/lib' those are not checked. Can cause error. */ public function setUp() { @@ -113,7 +112,6 @@ class LoadTest extends PHPUnit_Framework_TestCase /** * @runInSeparateProcess - * @TODO: Load - check if input file returns array */ public function testFileForArray() { @@ -142,7 +140,6 @@ class LoadTest extends PHPUnit_Framework_TestCase } /** - * @TODO: Load::getFilePath - check for wrong index * @runInSeparateProcess */ public function testAutoloadGetFilePathNullIndex() @@ -160,6 +157,7 @@ class LoadTest extends PHPUnit_Framework_TestCase public function testDebugAutoload() { $this->setConstants(); + unlink(self::$file); Load::setAutoloadFrom(self::$file); $autoload = require(self::$file); diff --git a/tests/app/FrontControllerTest.php b/tests/app/FrontControllerTest.php index 1d13571..654d733 100644 --- a/tests/app/FrontControllerTest.php +++ b/tests/app/FrontControllerTest.php @@ -28,6 +28,7 @@ require_once dirname(__FILE__) . '/../../app/AjaxAction.php'; class FrontControllerTest extends PHPUnit_Framework_TestCase { + protected $log_file_name = 'error_log_file'; public function run(PHPUnit_Framework_TestResult $result = NULL) { @@ -132,8 +133,6 @@ class FrontControllerTest extends PHPUnit_Framework_TestCase { $this->setConstants(false); $controller = FrontController::getInstance(); - $result = $controller->execute(); - $controller = FrontController::getInstance(); $this->assertNull($controller->execute()); } @@ -143,11 +142,14 @@ class FrontControllerTest extends PHPUnit_Framework_TestCase public function testExecuteNoRouteDebug() { $this->setConstants(true); + ini_set('error_log', $this->log_file_name); $controller = FrontController::getInstance(); $result = $controller->execute(); $this->assertNotEmpty($result); $this->assertContains('Route for "" not found', $result); $this->assertContains('Error404Exception', $result); + $error = file_get_contents($this->log_file_name); + $this->assertContains('PHP Unknown Error: Error404Exception: Route for "" not found in ', $error); } /** @@ -157,11 +159,14 @@ class FrontControllerTest extends PHPUnit_Framework_TestCase { $_SERVER['REQUEST_URI'] = '/user/account/213'; $this->setConstants(true); + ini_set('error_log', $this->log_file_name); $controller = FrontController::getInstance(); $router = $controller->getRouter(); $router->add('user', 'user/account/:id', 'user'); $result = $controller->execute(); $this->assertContains('Action class "userAction" not found.', $result); + $error = file_get_contents($this->log_file_name); + $this->assertContains('PHP Unknown Error: GeneralException: Action class "userAction" not found. in ', $error); } /** @@ -172,11 +177,14 @@ class FrontControllerTest extends PHPUnit_Framework_TestCase $this->getMock('userAction'); $_SERVER['REQUEST_URI'] = '/user/account/213'; $this->setConstants(true); + ini_set('error_log', $this->log_file_name); $controller = FrontController::getInstance(); $router = $controller->getRouter(); $router->add('user', 'user/account/:id', 'user'); $result = $controller->execute(); $this->assertContains('Layout class "DefaultLayout" not found.', $result); + $error = file_get_contents($this->log_file_name); + $this->assertContains('PHP Unknown Error: GeneralException: Layout class "DefaultLayout" not found. in ', $error); } /** @@ -269,6 +277,10 @@ class FrontControllerTest extends PHPUnit_Framework_TestCase public function tearDown() { unset_new_overload(); + if (file_exists($this->log_file_name) && is_writable($this->log_file_name)) { + unlink($this->log_file_name); + } + ini_set('error_log', 'php://stderr'); } protected function newCallback($className) diff --git a/tests/exception/ErrorHandlerTest.php b/tests/exception/ErrorHandlerTest.php index 4789eaf..47c7990 100644 --- a/tests/exception/ErrorHandlerTest.php +++ b/tests/exception/ErrorHandlerTest.php @@ -17,13 +17,15 @@ require_once dirname(__FILE__) . '/../../exception/ErrorHandler.php'; class ErrorHandlerTest extends PHPUnit_Framework_TestCase { public $old_eh = array('PHPUnit_Util_ErrorHandler', 'handleError'); - + + protected $log_file_name = 'error_log_file'; + public function setUp() - { + { set_error_handler(array('ErrorHandler', 'error_handler')); ob_start(); } - + public function testErrorHandlerInit() { $my_eh = array('ErrorHandler', 'error_handler'); @@ -59,13 +61,14 @@ class ErrorHandlerTest extends PHPUnit_Framework_TestCase { try { throw new ErrorException("test error", E_USER_ERROR); - } catch (ErrorException $e) { + } + catch (ErrorException $e) { $_SESSION['some'] = 'value'; $result = ErrorHandler::showDebug($e); $this->assertNotEmpty($result); $this->assertStringStartsWith('', $result); $this->assertStringEndsWith('', $result); - } + } } /** @@ -84,10 +87,93 @@ class ErrorHandlerTest extends PHPUnit_Framework_TestCase $result = $method->invoke(null, "first line\r\n\r\nsecond line"); $this->assertSame("first line
\r\n
\r\nsecond line
", $result); } - + + /** + * @runInSeparateProcess + */ + public function testLogErrorDefaultException() + { + $ex = new Exception('message', 123); + ini_set('error_log', $this->log_file_name); + ErrorHandler::logError($ex); + $log = file_get_contents($this->log_file_name); + $this->assertContains('PHP Unknown Error: Exception: message in ', $log); + } + + /** + * @runInSeparateProcess + */ + public function testLogErrorDefaultExceptionWithHTTP() + { + $_SERVER['REQUEST_METHOD'] = 'GET'; + $_SERVER['REQUEST_URI'] = '/somelongurl'; + $_SERVER['HTTP_REFERER'] = 'http://referrer/url'; + $this->assertEquals('GET', ENV::Server('REQUEST_METHOD')); + $this->assertEquals('/somelongurl', ENV::Server('REQUEST_URI')); + $this->assertEquals('http://referrer/url', ENV::Server('HTTP_REFERER')); + + $ex = new Exception('message', 123); + ini_set('error_log', $this->log_file_name); + ErrorHandler::logError($ex); + $log = file_get_contents($this->log_file_name); + $this->assertContains('PHP Unknown Error: Exception: message in ', $log); + $this->assertContains('URL: GET /somelongurl, referrer: http://referrer/url', $log); + } + + /** + * @runInSeparateProcess + */ + public function testLogErrorCustomException() + { + $ex = new LogicException('Logic', 333); + ini_set('error_log', $this->log_file_name); + ErrorHandler::logError($ex); + $log = file_get_contents($this->log_file_name); + $this->assertContains('PHP Unknown Error: LogicException: Logic in ', $log); + } + + /** + * @runInSeparateProcess + */ + public function testLogErrorErrorExceptionNotice() + { + $ex = new ErrorException('message', 321, E_NOTICE); + ini_set('error_log', $this->log_file_name); + ErrorHandler::logError($ex); + $log = file_get_contents($this->log_file_name); + $this->assertContains('PHP Notice: message in ', $log); + } + + /** + * @runInSeparateProcess + */ + public function testLogErrorErrorExceptionWarning() + { + $ex = new ErrorException('message', 321, E_WARNING); + ini_set('error_log', $this->log_file_name); + ErrorHandler::logError($ex); + $log = file_get_contents($this->log_file_name); + $this->assertContains('PHP Warning: message in ', $log); + } + + /** + * @runInSeparateProcess + */ + public function testLogErrorErrorExceptionFatal() + { + $ex = new ErrorException('message', 321, E_ERROR); + ini_set('error_log', $this->log_file_name); + ErrorHandler::logError($ex); + $log = file_get_contents($this->log_file_name); + $this->assertContains('PHP Fatal Error: message in ', $log); + } + public function tearDown() { + if (file_exists($this->log_file_name) && is_writable($this->log_file_name)) { + unlink($this->log_file_name); + } + ini_set('error_log', 'php://stderr'); set_error_handler($this->old_eh); } - } \ No newline at end of file diff --git a/tests/model/MongoModelTest.php b/tests/model/MongoModelTest.php index 9f3abb0..90e5bfc 100644 --- a/tests/model/MongoModelTest.php +++ b/tests/model/MongoModelTest.php @@ -333,6 +333,42 @@ class MongoModelTest extends PHPUnit_Framework_TestCase $this->assertSame(1, $this->method_count->invoke($this->model, array('name' => 'testbread'))); } + /** + * @runInSeparateProcess + * @group Mongo + */ + public function testAddCondition() + { + Config::set('DEBUG', false); + + $model = new ReflectionClass('MongoModel'); + $method = $model->getMethod('addCondition'); + $method->setAccessible(true); + + $query = array(); + $result = $method->invokeArgs($this->model, array(&$query, 'name', 'tony')); + $this->assertSame(array('name' => 'tony'), $query); + $this->assertSame($this->model, $result); + } + + /** + * @runInSeparateProcess + * @group Mongo + */ + public function testAddConditionEmptyValue() + { + Config::set('DEBUG', false); + + $model = new ReflectionClass('MongoModel'); + $method = $model->getMethod('addCondition'); + $method->setAccessible(true); + + $query = array(); + $method->invokeArgs($this->model, array(&$query, 'name', false)); + $this->assertEmpty($query); + $method->invokeArgs($this->model, array(&$query, 'name', null)); + $this->assertEmpty($query); + } public function tearDown() { $conf = array('driver' => 'MongoDriver', 'hostname' => 'localhost', 'database' => 'test', 'username' => 'test', 'password' => '1234', 'port' => 27017); diff --git a/tests/util/AutoloadBuilderTest.php b/tests/util/AutoloadBuilderTest.php index c31000a..92ffcc4 100644 --- a/tests/util/AutoloadBuilderTest.php +++ b/tests/util/AutoloadBuilderTest.php @@ -24,6 +24,8 @@ class AutoloadBuilderTest extends PHPUnit_Framework_TestCase private static $path; + private static $lib_path; + private static $app; public function run(PHPUnit_Framework_TestResult $result = NULL) @@ -38,13 +40,14 @@ class AutoloadBuilderTest extends PHPUnit_Framework_TestCase public static function setUpBeforeClass() { self::$path = realpath(dirname(__FILE__) . '/../../../..'); + self::$lib_path = realpath(dirname(__FILE__) . '/../..'); self::$app = 'lib/core/tests/face'; self::$file = self::$path . '/' . self::$app . '/cache/autoload.php'; self::$inc_dirs[self::$path . '/' . self::$app . '/src'] = true; self::$inc_dirs[self::$path . '/' . self::$app . '/cache'] = true; - self::$inc_dirs[self::$path . '/lib'] = true; + self::$inc_dirs[self::$lib_path . '/'] = true; foreach (self::$inc_dirs as $dir => &$is_exist) { if (!file_exists($dir)) { @@ -83,6 +86,7 @@ class AutoloadBuilderTest extends PHPUnit_Framework_TestCase $this->assertFileExists(self::$file); $array = require self::$file; + $this->assertFileExists(self::$file); $this->assertInternalType('array', $array); $this->assertNotEmpty($array); $this->assertArrayHasKey('AutoloadBuilder', $array); @@ -95,7 +99,7 @@ class AutoloadBuilderTest extends PHPUnit_Framework_TestCase public function testBuildWithExcluded() { $this->setConstants(); - $builder = new AutoloadBuilder(self::$file, array_keys(self::$inc_dirs), array(self::$path . '/lib/core/app/')); + $builder = new AutoloadBuilder(self::$file, array_keys(self::$inc_dirs), array(self::$lib_path . '/app/')); $this->assertFileNotExists(self::$file); $builder->build(); diff --git a/util/profiler/Profiler.php b/util/profiler/Profiler.php index 8f062fa..37db682 100644 --- a/util/profiler/Profiler.php +++ b/util/profiler/Profiler.php @@ -43,7 +43,7 @@ class Profiler } /** - * @codeCoverageIgnoreStart + * @codeCoverageIgnoreEnd */ /**