Commit: b2511a2d4161f1de776d41dc74adf9a7995ab063

Author: Jon Adams | Date: 2009-12-09 11:13:21 -0800
slight model and controller refactoring / updated config files to enable testing / model test written, controller test in progress
diff --git a/config/bootstrap.php b/config/bootstrap.php index dad85c4..f2c6eff 100644 --- a/config/bootstrap.php +++ b/config/bootstrap.php @@ -2,7 +2,7 @@ /** * Lithium: the most rad php framework * - * @copyright Copyright 2009, Union of Rad, Inc. (http://union-of-rad.org) + * @copyright Copyright 2009, Union of RAD (http://union-of-rad.org) * @license http://opensource.org/licenses/bsd-license.php The BSD License */ @@ -38,12 +38,6 @@ if (!include LITHIUM_LIBRARY_PATH . '/lithium/core/Libraries.php') { } /** - * Add the Lithium core library. This sets default paths and initializes the autoloader. You - * generally should not need to override any settings. - */ -Libraries::add('lithium'); - -/** * Optimize default request cycle by loading common classes. If you're implementing custom * request/response or dispatch classes, you can safely remove these. Actually, you can safely * remove them anyway, they're just there to give slightly you better out-of-the-box performance. @@ -69,6 +63,12 @@ require LITHIUM_LIBRARY_PATH . '/lithium/template/View.php'; require LITHIUM_LIBRARY_PATH . '/lithium/template/view/Renderer.php'; /** + * Add the Lithium core library. This sets default paths and initializes the autoloader. You + * generally should not need to override any settings. + */ +Libraries::add('lithium'); + +/** * Add the application. You can pass a `'path'` key here if this bootstrap file is outside of * your main application, but generally you should not need to change any settings. */ diff --git a/config/routes.php b/config/routes.php index 8e639cc..6512c18 100644 --- a/config/routes.php +++ b/config/routes.php @@ -2,6 +2,15 @@ use \lithium\http\Router; +/** + * Connect the testing routes. + */ +Router::connect('/test/{:args}', array('controller' => '\lithium\test\Controller')); +Router::connect('/test', array('controller' => '\lithium\test\Controller')); + +/** + * Anologue application routes + */ Router::connect('/', array('controller' => 'anologue', 'action' => 'index')); Router::connect('/add', array('controller' => 'anologue', 'action' => 'add')); Router::connect('/say/{:id}', array('controller' => 'anologue', 'action' => 'say')); diff --git a/config/switchboard.php b/config/switchboard.php index 856f610..bd5adcf 100644 --- a/config/switchboard.php +++ b/config/switchboard.php @@ -2,7 +2,7 @@ /** * Lithium: the most rad php framework * - * @copyright Copyright 2009, Union of Rad, Inc. (http://union-of-rad.org) + * @copyright Copyright 2009, Union of RAD (http://union-of-rad.org) * @license http://opensource.org/licenses/bsd-license.php The BSD License */ @@ -10,23 +10,10 @@ * Welcome to the switchboard. This file contains a series of method filters that allow you to * intercept different parts of Lithium's request cycle as they happen. You can apply filters to * any object method that has a `@filter` flag in its API documentation. - * - * When applying a filter, you need the name of the method you want to call, along with a *closure*, - * that defines what you want the filter to do. All filters take the same 3 parameters: `$self`, - * `$params`, and `$chain`. - * - * - `$self`: If the filter is applied on an object instance, then `$self` will be that instance. If - * applied to a static class, then `$self` will be a string containing the fully-namespaced class - * name. - * - * - `$params`: Contains an associative array of the parameters that are passed into the method. You - * can modify or inspect these parameters before allowing the method to continue. - * - * - `$chain`: Finally, `$chain` contains the list of filters in line to be executed. At the bottom - * of `$chain` is the method itself. This is why most filters contain a line that looks like - * `return $chain->next($self, $params, $chain);`. This passes control to the next filter in the - * chain, and finally, to the method itself. This allows you to interact with the return value as - * well as the parameters. + * + * For more information on in the filters system, see `lithium\util\collection\Filters`. + * + * @see lithium\util\collection\Filters */ use \lithium\http\Router; diff --git a/controllers/AnologueController.php b/controllers/AnologueController.php index 67c6b6e..e4db6c5 100644 --- a/controllers/AnologueController.php +++ b/controllers/AnologueController.php @@ -3,7 +3,6 @@ namespace app\controllers; use \app\models\Anologue; -use \lithium\http\Media; /** * The core controller for Anologue. @@ -35,8 +34,8 @@ class AnologueController extends \lithium\action\Controller { $status = (!empty($data)) ? 'success' : 'fail'; } - if (!empty($data->error)) { - $this->redirect(array('controller' => 'anologue', 'action' => 'index')); + if (!empty($data->error) || empty($this->request->params['id'])) { + $this->redirect('/'); } if (!empty($this->request->params['type'])) { diff --git a/models/Anologue.php b/models/Anologue.php index f8a30ec..e4f46d4 100644 --- a/models/Anologue.php +++ b/models/Anologue.php @@ -61,8 +61,13 @@ class Anologue extends \lithium\data\Model { */ public static function addMessage($id, $message = array()) { $anologue = static::find($id); - $message['email'] = md5($message['email']); + + if (!empty($message['email'])) { + $message['email'] = md5($message['email']); + } + $message = $message + array('timestamp' => time()) + static::$_defaultMessage; + if (!$anologue->messages) { $anologue->messages = array($message); } else { diff --git a/tests/cases/controllers/AnologueControllerTest.php b/tests/cases/controllers/AnologueControllerTest.php new file mode 100644 index 0000000..9267ad8 --- /dev/null +++ b/tests/cases/controllers/AnologueControllerTest.php @@ -0,0 +1,38 @@ +<?php + +namespace app\tests\cases\controllers; + +use \app\controllers\AnologueController; + +class AnologueControllerTest extends \lithium\test\Unit { + + public function testIndex() { + $anologueController = new AnologueController(array('classes' => array( + 'media' => '\lithium\tests\mocks\action\MockMediaClass' + ))); + $response = $anologueController->__invoke(null, array('action' => 'index')); + + $expected = 'index'; + $this->assertEqual($expected, $response->options['template']); + $this->assertTrue($response->data['index']); + } + + public function testView() { + $anologueController = new AnologueController(array('classes' => array( + 'media' => '\lithium\tests\mocks\action\MockMediaClass', + 'response' => '\lithium\tests\mocks\action\MockControllerResponse' + ))); + $anologueController->__invoke(null, array('action' => 'view')); + //print_r($response); + } + + public function testAdd() { + + } + + public function testSay() { + } + +} + +?> diff --git a/tests/cases/models/AnologueTest.php b/tests/cases/models/AnologueTest.php new file mode 100644 index 0000000..43c2daa --- /dev/null +++ b/tests/cases/models/AnologueTest.php @@ -0,0 +1,76 @@ +<?php + +namespace app\tests\cases\models; + +use \lithium\data\Connections; +use \app\models\Anologue; + +class AnologueTest extends \lithium\test\Unit { + + public static function __init() { + if (!Connections::get(Anologue::meta('connection'))) { + $this->skip(); + } + + Anologue::__init(array('source' => 'test')); + } + + public function testCreate() { + $anologue = Anologue::create(); + $result = $anologue->save(); + $this->assertTrue($result, 'Cannot save document. Make sure `test` database exists.'); + } + + public function testAddEmptyMessage() { + $anologue = Anologue::create(); + $anologue->save(); + $result = Anologue::addMessage($anologue->id); + $this->assertTrue($result); + + $anologue = Anologue::find($anologue->id); + $expected = '\lithium\data\model\Document'; + $result = '\\' . get_class($anologue->messages); + $this->assertEqual($expected, $result); + } + + public function testEmailEncryption() { + $anologue = Anologue::create(); + $anologue->save(); + $message = array('email' => 'danny.tanner@wake-up-san-francisco.com'); + Anologue::addMessage($anologue->id, $message); + $anologue = Anologue::find($anologue->id); + $messages = $anologue->messages->to('array'); + + $notExpected = 'danny.tanner@wake-up-san-francisco.com'; + $this->assertNotEqual($notExpected, $messages[0]['email']); + + $expected = 'c6c33ded09cbbf21d6fa20d7c4514567'; + $this->assertEqual($expected, $messages[0]['email']); + } + + public function testMessageTimestamp() { + $anologue = Anologue::create(); + $anologue->save(); + Anologue::addMessage($anologue->id); + $anologue = Anologue::find($anologue->id); + $messages = $anologue->messages->to('array'); + + $this->assertFalse(empty($messages[0]['timestamp'])); + + $this->assertTrue(date('m/d/y', $messages[0]['timestamp'])); + } + + public function testAppendMessageToExistingMessages() { + $anologue = Anologue::create(); + $anologue->save(); + Anologue::addMessage($anologue->id); + Anologue::addMessage($anologue->id); + $anologue = Anologue::find($anologue->id); + $messages = $anologue->messages->to('array'); + $expected = 2; + $this->assertEqual($expected, count($messages)); + } + +} + +?> diff --git a/webroot/css/debug.css b/webroot/css/debug.css new file mode 100644 index 0000000..b51e403 --- /dev/null +++ b/webroot/css/debug.css @@ -0,0 +1,300 @@ +/** + * Lithium: the most rad php framework + * + * @copyright Copyright 2009, Union of RAD (http://union-of-rad.org) + * @license http://opensource.org/licenses/bsd-license.php The BSD License + */ +* { + margin: 0; + padding: 0; +} + +body.test-dashboard { + font-family: Helvetica, Arial, sans-serif; + font-size: 90%; + margin: 0; +} + +body.test-dashboard a { + color: #333; +} + +body.test-dashboard ul { + margin: 0.2em 0.5em; +} + +body.test-dashboard li { + margin: 0.4em 1em; +} + +body.test-dashboard h1 { + margin: 0; + padding: 8px 0 4px 14px; + background: #B5B4A4; +} + +/*--- Benchmarking ---*/ +table.metrics { + border: 0; + border-top: 1px solid #ccc; +} + +td.metric-name { + text-align: left; + white-space: nowrap; + padding: 6px 8px; + background: #f4f4f4; + width: 35%; +} +td.metric { + border: 0; + font-family: 'Courier New', Courier; + font-weight: bold; + padding: 6px 8px; + text-align: right; + width: 65%; +} + +ul.classes, ul.files { + list-style-type: none; + font-family: 'Andale Mono'; +} + +/*--- Test Results ---*/ +div.test-result { + margin: 0 0 15px 0; + padding: 8px 10px; + color: #FFFFFF; + border: 2px solid #000000; + font-family: Helvetica, Arial, sans-serif; + font-weight: bold; + font-size: 16px; +} + +div.test-result-success { + background-color: #33CC66; + border-color: #009933; +} + +div.test-result-fail { + background-color: #CC0033; + border-color: #990000; +} + +div.test-assert, div.test-exception { + margin: 4px 0; + padding: 4px 8px; + color: #000000; + border: 1px solid #000000; + font-family: 'Monaco', 'Andale Mono', Helvetica, Arial, sans-serif; + line-height: 20px; + font-size: 12px; +} + +div.test-assert-passed { + border-color: #339966; + background-color: #D0F9E0; +} + +div.test-assert-failed, div.test-exception { + border-color: #993366; + background-color: #F9D0E0; +} + +div.test-assert span.content, div.test-exception span.content, div.test-exception span.trace { + display: block; + clear: both; + white-space: pre; +} + +div.test-exception span.content { + font-style: italic; +} + +div.test-exception span.trace { + padding: 0 0 0 5px; + margin: 2px 0 2px 3px; + border-left: 1px solid #C09090; +} + +/*--- SQL Dumps ---*/ +.lithium-sql-log table { + background: #f4f4f4; +} + +.lithium-sql-log td { + padding: 4px 8px; + text-align: left; +} + + +/*--- Debugger Dumps ---*/ +pre { + color: #000; + background: #f0f0f0; + padding: 1em; +} + +pre.lithium-debug { + background: #ffcc00; + font-size: 120%; + line-height: 140%; + margin-top: 1em; + overflow: auto; + position: relative; +} + +div.lithium-stack-trace { + background: #fff; + border: 4px dotted #ffcc00; + color: #333; + margin: 0px; + padding: 6px; + font-size: 120%; + line-height: 140%; + overflow: auto; + position: relative; +} + +/*--- Code Highlighting ---*/ +div.lithium-code-dump pre { + position: relative; + overflow: auto; +} + +div.lithium-stack-trace pre, div.lithium-code-dump pre { + color: #000; + background-color: #F0F0F0; + margin: 0px; + padding: 1em; + overflow: auto; +} + +div.lithium-code-dump pre, div.lithium-code-dump pre code { + clear: both; + font-size: 12px; + line-height: 15px; + margin: 4px 2px; + padding: 4px; + overflow: auto; +} + +div.lithium-code-dump span.code-highlight { + background-color: #ff0; + padding: 4px; +} + +/*--- Code Coverage Analysis ---*/ +span.filters { + float: right; + margin-top: -17px; +} + +div.code-coverage-results { + color: #000000; + font-size: 11px; + font-family: 'Andale Mono'; + background-color: #F0F0F0; + border: 1px solid #CCCCCC; +} + +h4.coverage { + color: #000000; + background-color: #FFFFFF; + font-family: Helvetica, Arial; + font-weight: bold; + margin: 6px 0 3px 3px; + padding: 0; +} + +div.code-coverage-results h4.name { + color: #666; + background-color: #F0F0F0; + border-bottom: 1px solid #999; + padding: 3px 0; + font-size: 12px; +} + +div.code-coverage-results div.code-line { + display: block; + float: none; + clear: both; + padding-left: 5px; + margin-left: 10px; +} + +div.code-coverage-results span.content { + display: block; + clear: right; + white-space: pre; + line-height: 20px; +} + +div.code-coverage-results div.uncovered span.content { + color: #B00; + background-color: #FEE; +} + +div.code-coverage-results div.covered span.content { + color: #080; + background-color: #DFD; +} + +div.code-coverage-results div.ignored span.content { + color: #aaa; +} + +div.code-coverage-results span.line-num { + display: block; + float: left; + font-family: Helvetica, Arial, sans-serif; + width: 20px; + color: #A9A9A9; + text-align: right; + background-color: #ECECEC; + border-right: 1px solid #DDDDDD; + padding-right: 2px; + margin-right: 5px; + line-height: 20px; +} + +div.code-coverage-results span.line-num strong { + color: #666; +} + +div.code-coverage-results div.start { + margin-top: 30px; + padding-top: 5px; + border: 1px solid #aaa; + border-width: 1px 1px 0px 1px; +} + +div.code-coverage-results div.end { + margin-bottom: 30px; + padding-bottom: 5px; + border: 1px solid #aaa; + border-width: 0px 1px 1px 1px; +} + +div.code-coverage-results div.realstart { + margin-top: 0px; +} + +div.code-coverage-results p.note { + color: #bbb; + padding: 5px; + margin: 5px 0 10px; + font-size: 10px; +} + +div.code-coverage-results span.result-bad { + color: #a00; +} + +div.code-coverage-results span.result-ok { + color: #fa0; +} + +div.code-coverage-results span.result-good { + color: #0a0; +} diff --git a/webroot/test.php b/webroot/test.php deleted file mode 100644 index ae29d26..0000000 --- a/webroot/test.php +++ /dev/null @@ -1,134 +0,0 @@ -<?php -/** - * Lithium: the most rad php framework - * - * @copyright Copyright 2009, Union of Rad, Inc. (http://union-of-rad.org) - * @license http://opensource.org/licenses/bsd-license.php The BSD License - */ - -use \lithium\core\Libraries; -use \lithium\test\Group; -use \lithium\test\Dispatcher; -use \lithium\util\Inflector; -use \lithium\util\reflection\Inspector; - -$startBenchmark = microtime(true); - -error_reporting(E_ALL | E_STRICT | E_DEPRECATED); - -require dirname(__DIR__) . '/config/bootstrap.php'; -$core = dirname(dirname(__DIR__)) . '/libraries/lithium'; - -$testRun = Dispatcher::run(null, $_GET); -$stats = Dispatcher::process($testRun['results']); - -?> -<!doctype html> -<html> - <head> - <title>Lithium Unit Test Dashboard</title> - <link rel="stylesheet" href="css/debug.css" /> - </head> - <body class="test-dashboard"> - <h1>Lithium Unit Test Dashboard</h1> - - <div style="float: left; padding: 10px 0 20px 20px; width: 20%;"> - <h2><a href="?group=\">Tests</a></h2> - <?php echo Dispatcher::menu('html'); ?> - </div> - - <div style="float:left; padding: 10px; width: 75%"> - <h2>Stats for <?php echo $testRun['title']; ?></h2> - - <h3>Test results</h3> - - <span class="filters"> - <?php - $filters = Libraries::locate('testFilters'); - $base = $_SERVER['REQUEST_URI']; - - foreach ($filters as $i => $class) { - $url = $base . "&amp;filters[]={$class}"; - $name = join('', array_slice(explode("\\", $class), -1)); - $key = Inflector::underscore($name); - - echo "<a class=\"{$key}\" href=\"{$url}\">{$name}</a>"; - - if ($i < count($filters) - 1) { - echo ' | '; - } - } - ?> - </span> - - <?php - $passes = count($stats['passes']); - $fails = count($stats['fails']); - $errors = count($stats['errors']); - $exceptions = count($stats['exceptions']); - $success = ($passes === $stats['asserts'] && $errors === 0); - - echo '<div class="test-result test-result-' . ($success ? 'success' : 'fail') . '"'; - echo ">{$passes} / {$stats['asserts']} passes, {$fails} "; - echo ((intval($stats['fails']) == 1) ? 'fail' : 'fails') . " and {$exceptions} "; - echo ((intval($exceptions) == 1) ? 'exceptions' : 'exceptions'); - echo '</div>'; - - foreach ((array)$stats['errors'] as $error) { - switch ($error['result']) { - case 'fail': - $error += array('class' => 'unknown', 'method' => 'unknown'); - echo '<div class="test-assert test-assert-failed">'; - echo "Assertion '{$error['assertion']}' failed in "; - echo "{$error['class']}::{$error['method']}() on line "; - echo "{$error['line']}: "; - echo "<span class=\"content\">{$error['message']}</span>"; - break; - case 'exception': - echo '<div class="test-exception">'; - echo "Exception thrown in {$error['class']}::{$error['method']}() "; - echo "on line {$error['line']}: "; - echo "<span class=\"content\">{$error['message']}</span>"; - if (isset($error['trace']) && !empty($error['trace'])) { - echo "Trace:<span class=\"trace\">{$error['trace']}</span>"; - } - break; - } - echo '</div>'; - } - - foreach ((array)$testRun['filters'] as $class => $data) { - echo $class::output('html', $data); - } - - $tests = Group::all(array('transform' => true)); - $exclude = '/\w+Test$|webroot|index$|^app\\\\config|^\w+\\\\views\/|\./'; - $options = compact('exclude') + array('recursive' => true); - $classes = array_diff(Libraries::find('lithium', $options), $tests); - sort($classes); - ?> - <h3>Classes with no test case (<?php echo count($classes); ?>)</h3> - <ul class="classes"> - <?php - foreach ($classes as $class) { - echo "<li>{$class}</li>"; - } - ?> - </ul> - - <h3>Included files (<?php echo count(get_included_files()); ?>)</h3> - <ul class="files"> - <?php - $base = dirname(dirname($core)); - $files = str_replace($base, '', get_included_files()); - sort($files); - - foreach ($files as $file) { - echo "<li>{$file}</li>"; - } - ?> - </ul> - </div> - <div style="clear:both"></div> - </body> -</html> \ No newline at end of file