Skip to content
This repository
  • 12 commits
  • 10 files changed
  • 0 comments
  • 5 contributors
Dec 19, 2012
Blaine Schmeisser blainesch Add documentation for the mocker class d69563f
Dec 20, 2012
Blaine Schmeisser blainesch Delete README.md and leave readme.md - Fixes #759 614f732
Nate Abele nateabele Merge pull request #760 from BlaineSch/bug/dupReadme
Delete README.md and leave readme.md - Fixes #759
753ea17
Blaine Schmeisser blainesch Fix bug with how results are rendered.
The issue was we were rendering results BEFORE the filter, passing it in and returning it. This is bad since the results may modify the existing class and being a filter you may choose never to get that far in  your chain.

The fix is a bit complex but covers my bases.

You create a class 'Mock' which extends the class you wish to mock, this will be directly accessed by the consumer, but it doesnt interact with itself, it sends all its responsibilities to another class we create 'MockDelegate'.

MockDelegate which, if called from the Mock class will pass it along to the real mocked class, or if called from the extended class, will submit it back out through the client Mock class. Now all methods are filtered.

A known issue is not something I can really fix.
~~~ php
<?php
class Foo {
	public static function doSomething() {
		return self::doSomethingElse();
	}
	public static function doSomethingElse() {
		return false;
	}
}
?>
~~~
If you are Mocking this class the `doSomething` methods NEVER goes to the extending 'MockDelegate' to be re-filtered so this method would NOT be filtered even if you have set a filter for this method.
0803c88
Nate Abele nateabele Merge pull request #762 from BlaineSch/feature/autoloadMockerWithFilters
Feature/autoload mocker with filters
dda0ddf
Dec 21, 2012
Simon JAILLET jails Some refactoring of `data\model\Query::alias()`. c189f74
Dec 26, 2012
John Coggeshall coogle Making Unit return the value of the asserted Expresion consistently 386e5ea
GWoo gwoo Merge pull request #768 from coogle/return-asserts
Making Unit return the value of the asserted Expresion consistently
204b797
Nate Abele nateabele Merge pull request #763 from jails/pr2
Some refactoring of `data\model\Query::alias()`.
8a8fe88
Dec 27, 2012
Blaine Schmeisser blainesch Update parser to recognize newlines when PHP does not provide a line
For instance the content '}' has no PHP token, so if it is the only thing on a line it'll inherit the line of it's parent line which would be incorrect.
d7d8da3
Nate Abele nateabele Merge pull request #770 from BlaineSch/bug/parserLineFix
Update parser to recognize newlines when PHP does not provide a line
7f6da57
Nate Abele nateabele Merge branch 'dev' 505c158
38 README.md
Source Rendered
... ... @@ -1,38 +0,0 @@
1   -You asked for a better framework. Here it is.
2   ----------------------------------------------
3   -
4   -Lithium is the fast, flexible and most RAD development framework for PHP 5.3 and up.
5   -
6   -A framework of firsts
7   ----------------------
8   -
9   -Lithium is the first and only major PHP framework built from the ground up for PHP 5.3+, and the first to break ground into major new technologies, including bridging the gap between relational and non-relational databases through a single, unified API.
10   -
11   -Promiscuously opinionated
12   --------------------------
13   -
14   -Some frameworks give you a solid set of classes, but little or no default project organization, leaving you to fend for yourself on each project you create, and spend time wiring up framework classes that should just work together. Others provide you with great organizational conventions, but no way to break out of those conventions if you need to, and too often, no way to override or replace core framework classes.
15   -
16   -Lithium is the first framework to give you the best of both worlds, without compromising either. In fact, Lithium's API is intentionally designed to allow you to "grow out of" the framework and into your own custom code over the course of your application's lifecycle, if your needs require.
17   -
18   -Technology
19   -----------
20   -
21   -Lithium takes full advantage of the latest PHP 5.3 features, including namespaces, late static binding and closures. Lithium's innovative [method filter system](http://lithify.me/docs/lithium/util/collection/Filters) makes extensive use of closures and anonymous functions to allow application developers to "wrap" framework method calls, intercepting parameters before, and return values after.
22   -
23   -Lithium also complies with the PHP 5.3 namespacing standard, allowing you to easily integrate other PHP 5.3 standard libraries and frameworks with Lithium applications, and vice-versa.
24   -
25   -Lithium integrates the latest storage technologies, including MongoDB, CouchDB and Redis, with plugin support for Cassandra, ElasticSearch and others.
26   -
27   -Flexibility
28   ------------
29   -
30   -Lithium gives you full control over your application, from filters to dynamically modify framework internals, to dynamic dependencies to extend and replace core classes with application or plugin classes, to heavy use of adapter-oriented configurations, to make it seamless to move between different technologies and options.
31   -
32   -Every component of the Lithium framework stack is replaceable through the robust plugin architecture. Swap out the default ORM / ODM implementation for [Doctrine 2](https://github.com/mariano/li3_doctrine2/) or [PHP ActiveRecord](http://dev.lithify.me/li3_activerecord). Don't like the templating? Use [ Twig](http://dev.lithify.me/li3_twig), [ Mustache](https://github.com/bobthecow/mustache.php), or roll your own.
33   -
34   -If you don't even need to write a full application, build a micro-app in a single file using the routing system, without giving up the maintainability of the framework's structure.
35   -
36   -Build status
37   ------------
38   -[![Build Status](https://secure.travis-ci.org/UnionOfRAD/lithium.png?branch=master)](http://travis-ci.org/UnionOfRAD/lithium)
4 analysis/Parser.php
@@ -74,6 +74,10 @@ public static function tokenize($code, array $options = array()) {
74 74 }
75 75 }
76 76 $tokens[] = array('id' => $id, 'name' => $name, 'content' => $content, 'line' => $line);
  77 +
  78 + if ($id === T_WHITESPACE) {
  79 + $line += count(preg_split('/\r\n|\r|\n/', $content)) - 1;
  80 + }
77 81 }
78 82
79 83 if ($options['wrap'] && empty($options['include'])) {
65 data/model/Query.php
@@ -11,6 +11,7 @@
11 11 use lithium\util\Set;
12 12 use lithium\data\Source;
13 13 use lithium\core\ConfigException;
  14 +use InvalidArgumentException;
14 15
15 16 /**
16 17 * The `Query` class acts as a container for all information necessary to perform a particular
@@ -107,15 +108,6 @@ class Query extends \lithium\core\Object {
107 108 protected $_paths = array();
108 109
109 110 /**
110   - * Map beetween relation paths and their corresponding fieldname paths
111   - *
112   - * @see lithium\data\model\Query::alias()
113   - *
114   - * @var array
115   - */
116   - protected $_relationNames = array();
117   -
118   - /**
119 111 * Map beetween generated aliases and corresponding models.
120 112 *
121 113 * @see lithium\data\model\Query::alias()
@@ -518,11 +510,15 @@ public function data($data = array()) {
518 510 * @param array $config the config array to set.
519 511 * @return mixed The relationships array or a relationship array if `$relpath` is set. Returns
520 512 * `null` if a join doesn't exist.
  513 + * @throws InvalidArgumentException
521 514 */
522 515 public function relationships($relpath = null, $config = null) {
523 516 if ($config) {
524 517 if (!$relpath) {
525   - throw new ConfigException("The relation dotted path is empty.");
  518 + throw new InvalidArgumentException("The relation dotted path is empty.");
  519 + }
  520 + if (isset($config['model']) && isset($config['alias'])) {
  521 + $this->_models[$config['alias']] = $config['model'];
526 522 }
527 523 $this->_config['relationships'][$relpath] = $config;
528 524 return $this;
@@ -699,26 +695,20 @@ public function alias($alias = true, $relpath = null) {
699 695 return $return ?: null;
700 696 }
701 697
702   - if ($relpath) {
703   - $oldAlias = array_search($relpath, $this->_paths);
704   - } else {
705   - $oldAlias = array_search('', $this->_paths);
  698 + if ($relpath === null) {
  699 + $this->_config['alias'] = $alias;
706 700 }
707   - unset($this->_models[$oldAlias]);
708   - unset($this->_paths[$oldAlias]);
709   -
710   - $model = $this->_config['model'];
711 701
712   - if (!$relpath) {
713   - $this->_alias[$alias] = 1;
  702 + if ($relpath === null && ($model = $this->_config['model'])) {
714 703 $this->_models[$alias] = $model;
715   - $this->_paths[$alias] = '';
716   - return $this->_config['alias'] = $alias;
717 704 }
718 705
719   - $paths = explode('.', $relpath);
720   - if (!$alias) {
721   - $alias = end($paths);
  706 + $relpath = (string) $relpath;
  707 + unset($this->_paths[array_search($relpath, $this->_paths)]);
  708 +
  709 + if (!$alias && $relpath) {
  710 + $last = strrpos($relpath, '.');
  711 + $alias = $last ? substr($relpath, $last + 1) : $relpath;
722 712 }
723 713
724 714 if (isset($this->_alias[$alias])) {
@@ -729,35 +719,10 @@ public function alias($alias = true, $relpath = null) {
729 719 }
730 720
731 721 $this->_paths[$alias] = $relpath;
732   - $fieldname = array();
733   - foreach ($paths as $path) {
734   - if (!$relation = $model::relations($path)) {
735   - $model = null;
736   - break;
737   - }
738   - $fieldname[] = $relation->fieldName();
739   - $model = $relation->to();
740   - }
741   - $this->_models[$alias] = $model;
742   - $this->_relationNames[$relpath] = join('.', $fieldname);
743 722 return $alias;
744 723 }
745 724
746 725 /**
747   - * Return the relation paths mapped to their corredponding fieldname paths.
748   - *
749   - * @param object $source Instance of the data source (`lithium\data\Source`) to use for
750   - * conversion.
751   - * @return array Map between relation paths and their corresponding fieldname paths.
752   - */
753   - public function relationNames(Source $source = null) {
754   - if ($source) {
755   - $this->applyStrategy($source);
756   - }
757   - return $this->_relationNames;
758   - }
759   -
760   - /**
761 726 * Return the generated aliases mapped to their relation path
762 727 *
763 728 * @param object $source Instance of the data source (`lithium\data\Source`) to use for
8 data/source/Database.php
@@ -213,8 +213,7 @@ public function __construct(array $config = array()) {
213 213 'type' => $rel->type(),
214 214 'model' => $rel->to(),
215 215 'fieldName' => $rel->fieldName(),
216   - 'fromAlias' => $from,
217   - 'toAlias' => $to
  216 + 'alias' => $to
218 217 ));
219 218 $self->join($context, $rel, $from, $to, $constraints);
220 219 }
@@ -473,11 +472,10 @@ public function read($query, array $options = array()) {
473 472 case 'array':
474 473 $columns = $args['schema'] ?: $self->schema($query, $result);
475 474
476   - if (!isset($columns['']) || !is_array($columns[''])) {
  475 + if (!is_array(reset($columns))) {
477 476 $columns = array('' => $columns);
478 477 }
479 478
480   - $relationNames = is_object($query) ? $query->relationNames($self) : array();
481 479 $i = 0;
482 480 $records = array();
483 481 foreach ($result as $data) {
@@ -487,7 +485,7 @@ public function read($query, array $options = array()) {
487 485 $len = count($cols);
488 486 $values = array_combine($cols, array_slice($data, $offset, $len));
489 487 if ($path) {
490   - $records[$i][$relationNames[$path]] = $values;
  488 + $records[$i][$path] = $values;
491 489 } else {
492 490 $records[$i] += $values;
493 491 }
213 test/Mocker.php
@@ -14,39 +14,167 @@
14 14 use Reflection;
15 15
16 16 /**
17   - * The Mocker class aids in the creation of Mocks on the fly.
  17 + * The Mocker class aids in the creation of Mocks on the fly, allowing you to
  18 + * use Lithium filters on most methods in the class.
  19 + *
  20 + * To enable the autoloading of mocks you simply need to make a simple method
  21 + * call.
  22 + * {{{
  23 + * use lithium\core\Environment;
  24 + * use lithium\test\Mocker;
  25 + * if(!Environment::is('production')) {
  26 + * Mocker::register();
  27 + * }
  28 + * }}}
  29 + *
  30 + * You can also enable autoloading inside the setup of a unit test class. This
  31 + * method can be called redundantly.
  32 + * {{{
  33 + * use lithium\test\Mocker;
  34 + * class MockerTest extends \lithium\test\Unit {
  35 + * public function setUp() {
  36 + * Mocker::register();
  37 + * }
  38 + * }
  39 + * }}}
  40 + *
  41 + * Using Mocker is the fun magical part, it's autoloaded so simply call the
  42 + * class you want to mock with the '\Mock' at the end. The autoloader will
  43 + * detect you want to autoload it, and create it for you. Now you can filter
  44 + * any method.
  45 + * {{{
  46 + * use lithium\console\dispatcher\Mock as DispatcherMock;
  47 + * $dispatcher = new DispatcherMock();
  48 + * $dispatcher->applyFilter('config', function($self, $params, $chain) {
  49 + * return array();
  50 + * });
  51 + * $results = $dispatcher->config();
  52 + * }}}
  53 + * {{{
  54 + * use lithium\analysis\parser\Mock as ParserMock;
  55 + * $code = 'echo "foobar";';
  56 + * ParserMock::applyFilter('config', function($self, $params, $chain) {
  57 + * return array();
  58 + * });
  59 + * $tokens = ParserMock::tokenize($code, array('wrap' => true));
  60 + * }}}
18 61 */
19 62 class Mocker {
20 63
21 64 /**
22   - * A list of code to be generated based on the type.
  65 + * A list of code to be generated for the delegator.
  66 + *
  67 + * The MockDelgate directly extends the mocker and makes all methods
  68 + * publically available to other classes but should not be accessed directly
  69 + * by any other application. This should be called only by the mocker and
  70 + * the mockee and never by the consumer.
23 71 *
24 72 * @var array
25 73 */
26   - protected static $_dynamicCode = array(
  74 + protected static $_mockDelegateIngredients = array(
27 75 'startClass' => array(
28 76 'namespace {:namespace};',
29   - 'class {:mockee} extends \{:mocker} {'
  77 + 'class MockDelegate extends \{:mocker} {'
  78 + ),
  79 + 'constructor' => array(
  80 + '{:modifiers} function __construct({:args}) {',
  81 + ' $args = func_get_args();',
  82 + ' $this->parent = array_pop($args);',
  83 + ' $this->parent->mocker = $this;',
  84 + ' call_user_func_array("parent::__construct", $args);',
  85 + '}',
  86 + ),
  87 + 'method' => array(
  88 + '{:modifiers} function {:method}({:args}) {',
  89 + ' $args = func_get_args();',
  90 + ' $token = spl_object_hash($this);',
  91 + ' $id = count($args) - 1;',
  92 + ' if (!isset($args[$id]) || $args[$id] !== $token) {',
  93 + ' $method = array($this->parent, "{:method}");',
  94 + ' return call_user_func_array($method, $args);',
  95 + ' }',
  96 + ' array_pop($args);',
  97 + ' return call_user_func_array("parent::{:method}", $args);',
  98 + '}',
  99 + ),
  100 + 'staticMethod' => array(
  101 + '{:modifiers} function {:method}({:args}) {',
  102 + ' $args = func_get_args();',
  103 + ' $token = "1f3870be274f6c49b3e31a0c6728957f";',
  104 + ' $id = count($args) - 1;',
  105 + ' if (!isset($args[$id]) || $args[$id] !== $token) {',
  106 + ' $method = \'{:namespace}\Mock::{:method}\';',
  107 + ' return call_user_func_array($method, $args);',
  108 + ' }',
  109 + ' array_pop($args);',
  110 + ' return call_user_func_array("parent::{:method}", $args);',
  111 + '}',
  112 + ),
  113 + 'endClass' => array(
  114 + '}',
  115 + ),
  116 + );
  117 +
  118 + /**
  119 + * A list of code to be generated for the mocker.
  120 + *
  121 + * The Mock class directly extends the mock class but only directly
  122 + * interacts with the MockDelegate directly. This class is the actual
  123 + * interface for consumers, instantiation or static method calls, and can
  124 + * have most of its methods filtered.
  125 + *
  126 + * @var array
  127 + */
  128 + protected static $_mockIngredients = array(
  129 + 'startClass' => array(
  130 + 'namespace {:namespace};',
  131 + 'class Mock extends \{:mocker} {',
  132 + ' public $mocker;',
  133 + ' protected $_safeVars = array(',
  134 + ' "_classes",',
  135 + ' "_methodFilters",',
  136 + ' "mocker",',
  137 + ' "_safeVars"',
  138 + ' );',
  139 + ),
  140 + 'get' => array(
  141 + 'public function __get($key) {',
  142 + ' return $this->mocker->$key;',
  143 + '}',
  144 + ),
  145 + 'constructor' => array(
  146 + '{:modifiers} function __construct({:args}) {',
  147 + ' $args = array_values(get_defined_vars());',
  148 + ' array_push($args, $this);',
  149 + ' foreach ($this as $key => $value) {',
  150 + ' if (!in_array($key, $this->_safeVars)) {',
  151 + ' unset($this->$key);',
  152 + ' }',
  153 + ' }',
  154 + ' $class = new \ReflectionClass(\'{:namespace}\MockDelegate\');',
  155 + ' $class->newInstanceArgs($args);',
  156 + '}',
  157 + ),
  158 + 'destructor' => array(
  159 + 'public function __destruct() {}',
30 160 ),
31 161 'staticMethod' => array(
32   - '{:modifiers} function {:name}({:params}) {',
33   - ' $params = func_get_args();',
34   - ' list($class, $method) = explode(\'::\', __METHOD__, 2);',
35   - ' $parent = \'parent::\' . $method;',
36   - ' $result = call_user_func_array($parent, $params);',
37   - ' return self::_filter($method, $params, function($self, $params) use(&$result) {',
38   - ' return $result;',
  162 + '{:modifiers} function {:method}({:args}) {',
  163 + ' $args = func_get_args();',
  164 + ' array_push($args, "1f3870be274f6c49b3e31a0c6728957f");',
  165 + ' $method = \'{:namespace}\MockDelegate::{:method}\';',
  166 + ' return self::_filter("{:method}", $args, function($self, $args) use(&$method) {',
  167 + ' return call_user_func_array($method, $args);',
39 168 ' });',
40 169 '}',
41 170 ),
42 171 'method' => array(
43   - '{:modifiers} function {:name}({:params}) {',
44   - ' $params = func_get_args();',
45   - ' list($class, $method) = explode(\'::\', __METHOD__, 2);',
46   - ' $parent = \'parent::\' . $method;',
47   - ' $result = call_user_func_array($parent, $params);',
48   - ' return $this->_filter($parent, $params, function($self, $params) use(&$result) {',
49   - ' return $result;',
  172 + '{:modifiers} function {:method}({:args}) {',
  173 + ' $args = func_get_args();',
  174 + ' array_push($args, spl_object_hash($this->mocker));',
  175 + ' $method = array($this->mocker, "{:method}");',
  176 + ' return $this->_filter(__METHOD__, $args, function($self, $args) use(&$method) {',
  177 + ' return call_user_func_array($method, $args);',
50 178 ' });',
51 179 '}',
52 180 ),
@@ -61,12 +189,11 @@ class Mocker {
61 189 * @var array
62 190 */
63 191 protected static $_blackList = array(
64   - '__construct', '__destruct', '__call', '__callStatic',
  192 + '__destruct', '__call', '__callStatic', '_parents',
65 193 '__get', '__set', '__isset', '__unset', '__sleep',
66 194 '__wakeup', '__toString', '__clone', '__invoke',
67   - '__construct', '_init', 'applyFilter', 'invokeMethod',
68   - '__set_state', '_instance', '_filter', '_parents',
69   - '_stop',
  195 + '_stop', '_init', 'applyFilter', 'invokeMethod',
  196 + '__set_state', '_instance', '_filter',
70 197 );
71 198
72 199 /**
@@ -91,29 +218,38 @@ public static function create($mockee) {
91 218
92 219 $mocker = self::_mocker($mockee);
93 220
94   - $code = self::_dynamicCode('startClass', array(
  221 + $tokens = array(
95 222 'namespace' => self::_namespace($mockee),
96 223 'mocker' => $mocker,
97   - 'mockee' => 'Mock',
98   - ));
  224 + 'mockee' => 'MockDelegate',
  225 + );
  226 + $mockDelegate = self::_dynamicCode('mockDelegate', 'startClass', $tokens);
  227 + $mock = self::_dynamicCode('mock', 'startClass', $tokens);
99 228
100 229 $reflectedClass = new ReflectionClass($mocker);
101 230 $reflecedMethods = $reflectedClass->getMethods();
102 231 foreach ($reflecedMethods as $method) {
103 232 if (!in_array($method->name, self::$_blackList)) {
104 233 $key = $method->isStatic() ? 'staticMethod' : 'method';
105   - $code .= self::_dynamicCode($key, array(
106   - 'name' => $method->name,
  234 + $key = $method->name === '__construct' ? 'constructor' : $key;
  235 + $tokens = array(
  236 + 'namespace' => self::_namespace($mockee),
  237 + 'method' => $method->name,
107 238 'modifiers' => self::_methodModifiers($method),
108   - 'params' => self::_methodParams($method),
109   - 'visibility' => 'public',
110   - ));
  239 + 'args' => self::_methodParams($method),
  240 + 'mocker' => $mocker,
  241 + );
  242 + $mockDelegate .= self::_dynamicCode('mockDelegate', $key, $tokens);
  243 + $mock .= self::_dynamicCode('mock', $key, $tokens);
111 244 }
112 245 }
113 246
114   - $code .= self::_dynamicCode('endClass');
  247 + $mockDelegate .= self::_dynamicCode('mockDelegate', 'endClass');
  248 + $mock .= self::_dynamicCode('mock', 'get');
  249 + $mock .= self::_dynamicCode('mock', 'destructor');
  250 + $mock .= self::_dynamicCode('mock', 'endClass');
115 251
116   - eval($code);
  252 + eval($mockDelegate . $mock);
117 253 }
118 254
119 255 /**
@@ -127,7 +263,8 @@ public static function create($mockee) {
127 263 protected static function _methodModifiers(ReflectionMethod $method) {
128 264 $modifierKey = $method->getModifiers();
129 265 $modifierArray = Reflection::getModifierNames($modifierKey);
130   - return implode(' ', $modifierArray);
  266 + $modifiers = implode(' ', $modifierArray);
  267 + return str_replace(array('private', 'protected'), 'public', $modifiers);
131 268 }
132 269
133 270 /**
@@ -152,12 +289,16 @@ protected static function _methodParams(ReflectionMethod $method) {
152 289 /**
153 290 * Will generate the code you are wanting.
154 291 *
155   - * @param string $key The key from self::$_dynamicCode
  292 + * This pulls from $_mockDelegateIngredients and $_mockIngredients.
  293 + *
  294 + * @param string $type The name of the array of ingredients to use
  295 + * @param string $key The key from the array of ingredients
156 296 * @param array $tokens Tokens, if any, that should be inserted
157 297 * @return string
158 298 */
159   - protected static function _dynamicCode($key, $tokens = array()) {
160   - $code = implode("\n", self::$_dynamicCode[$key]);
  299 + protected static function _dynamicCode($type, $key, $tokens = array()) {
  300 + $name = '_' . $type . 'Ingredients';
  301 + $code = implode("\n", self::${$name}[$key]);
161 302 return String::insert($code, $tokens) . "\n";
162 303 }
163 304
22 test/Unit.php
@@ -270,7 +270,7 @@ protected function _normalizeLineEndings($expected, $result) {
270 270 public function assertEqual($expected, $result, $message = false) {
271 271 list($expected, $result) = $this->_normalizeLineEndings($expected, $result);
272 272 $data = ($expected != $result) ? $this->_compare('equal', $expected, $result) : null;
273   - $this->assert($expected == $result, $message, $data);
  273 + return $this->assert($expected == $result, $message, $data);
274 274 }
275 275
276 276 /**
@@ -282,7 +282,7 @@ public function assertEqual($expected, $result, $message = false) {
282 282 */
283 283 public function assertNotEqual($expected, $result, $message = false) {
284 284 list($expected, $result) = $this->_normalizeLineEndings($expected, $result);
285   - $this->assert($result != $expected, $message, compact('expected', 'result'));
  285 + return $this->assert($result != $expected, $message, compact('expected', 'result'));
286 286 }
287 287
288 288 /**
@@ -294,7 +294,7 @@ public function assertNotEqual($expected, $result, $message = false) {
294 294 */
295 295 public function assertIdentical($expected, $result, $message = false) {
296 296 $data = ($expected !== $result) ? $this->_compare('identical', $expected, $result) : null;
297   - $this->assert($expected === $result, $message, $data);
  297 + return $this->assert($expected === $result, $message, $data);
298 298 }
299 299
300 300 /**
@@ -317,7 +317,7 @@ public function assertIdentical($expected, $result, $message = false) {
317 317 */
318 318 public function assertTrue($result, $message = '{:message}') {
319 319 $expected = true;
320   - $this->assert(!empty($result), $message, compact('expected', 'result'));
  320 + return $this->assert(!empty($result), $message, compact('expected', 'result'));
321 321 }
322 322
323 323 /**
@@ -342,7 +342,7 @@ public function assertTrue($result, $message = '{:message}') {
342 342 */
343 343 public function assertFalse($result, $message = '{:message}') {
344 344 $expected = false;
345   - $this->assert(empty($result), $message, compact('expected', 'result'));
  345 + return $this->assert(empty($result), $message, compact('expected', 'result'));
346 346 }
347 347
348 348 /**
@@ -353,7 +353,7 @@ public function assertFalse($result, $message = '{:message}') {
353 353 */
354 354 public function assertNull($result, $message = '{:message}') {
355 355 $expected = null;
356   - $this->assert($result === null, $message, compact('expected', 'result'));
  356 + return $this->assert($result === null, $message, compact('expected', 'result'));
357 357 }
358 358
359 359 /**
@@ -365,7 +365,7 @@ public function assertNull($result, $message = '{:message}') {
365 365 */
366 366 public function assertNoPattern($expected, $result, $message = '{:message}') {
367 367 list($expected, $result) = $this->_normalizeLineEndings($expected, $result);
368   - $this->assert(!preg_match($expected, $result), $message, compact('expected', 'result'));
  368 + return $this->assert(!preg_match($expected, $result), $message, compact('expected', 'result'));
369 369 }
370 370
371 371 /**
@@ -377,7 +377,7 @@ public function assertNoPattern($expected, $result, $message = '{:message}') {
377 377 */
378 378 public function assertPattern($expected, $result, $message = '{:message}') {
379 379 list($expected, $result) = $this->_normalizeLineEndings($expected, $result);
380   - $this->assert(!!preg_match($expected, $result), $message, compact('expected', 'result'));
  380 + return $this->assert(!!preg_match($expected, $result), $message, compact('expected', 'result'));
381 381 }
382 382
383 383 /**
@@ -600,8 +600,7 @@ public function assertCookie($expected, $headers = null) {
600 600 $matched = $this->_cookieMatch($expected, $headers);
601 601 if (!$matched['match']) {
602 602 $message = sprintf('%s - Cookie not found in headers.', $matched['pattern']);
603   - $this->assert(false, $message, compact('expected', 'result'));
604   - return false;
  603 + return $this->assert(false, $message, compact('expected', 'result'));
605 604 }
606 605 return $this->assert(true, '%s');
607 606 }
@@ -625,8 +624,7 @@ public function assertNoCookie($expected, $headers = null) {
625 624 $matched = $this->_cookieMatch($expected, $headers);
626 625 if ($matched['match']) {
627 626 $message = sprintf('%s - Cookie found in headers.', $matched['pattern']);
628   - $this->assert(false, $message, compact('expected', 'result'));
629   - return false;
  627 + return $this->assert(false, $message, compact('expected', 'result'));
630 628 }
631 629 return $this->assert(true, '%s');
632 630 }
25 tests/cases/analysis/ParserTest.php
@@ -56,7 +56,12 @@ public function testFullTokenization() {
56 56 $result = Parser::tokenize('$foo = function() {};');
57 57 $this->assertEqual(11, count($result));
58 58
59   - $expected = array('id' => 309, 'name' => 'T_VARIABLE', 'content' => '$foo', 'line' => 1);
  59 + $expected = array(
  60 + 'id' => T_VARIABLE,
  61 + 'name' => 'T_VARIABLE',
  62 + 'content' => '$foo',
  63 + 'line' => 1
  64 + );
60 65 $this->assertEqual($expected, $result[0]);
61 66
62 67 $expected = array('id' => null, 'name' => ';', 'content' => ';', 'line' => 1);
@@ -99,9 +104,9 @@ public function testFilteredTokenization() {
99 104
100 105 $result = Parser::tokenize($code, array('include' => array('T_IF', 'T_WHILE', 'T_CATCH')));
101 106 $expected = array(
102   - array('id' => 318, 'name' => 'T_WHILE', 'content' => 'while', 'line' => 1),
103   - array('id' => 301, 'name' => 'T_IF', 'content' => 'if', 'line' => 1),
104   - array('id' => 338, 'name' => 'T_CATCH', 'content' => 'catch', 'line' => 3)
  107 + array('id' => T_WHILE, 'name' => 'T_WHILE', 'content' => 'while', 'line' => 1),
  108 + array('id' => T_IF, 'name' => 'T_IF', 'content' => 'if', 'line' => 1),
  109 + array('id' => T_CATCH, 'name' => 'T_CATCH', 'content' => 'catch', 'line' => 3)
105 110 );
106 111 $this->assertEqual($expected, $result);
107 112 }
@@ -136,6 +141,18 @@ function ($i) { return join('', $i); },
136 141 $expected = array('ClassName', 'method');
137 142 $this->assertEqual($expected, $results);
138 143 }
  144 +
  145 + public function testParserGuessesLineBleed() {
  146 + $code = <<<EOD
  147 +if (false) {
  148 + return true;
  149 +}
  150 +EOD;
  151 + $tokens = Parser::tokenize($code);
  152 + $this->assertIdentical('}', $tokens[13]['content']);
  153 + $this->assertIdentical(3, $tokens[13]['line']);
  154 + }
  155 +
139 156 }
140 157
141 158 ?>
59 tests/cases/data/model/QueryTest.php
@@ -38,6 +38,11 @@ public function setUp() {
38 38 MockQueryComment::$connection = $this->db;
39 39 }
40 40
  41 + public function tearDown() {
  42 + MockQueryPost::reset();
  43 + MockQueryComment::reset();
  44 + }
  45 +
41 46 /**
42 47 * Tests that configuration settings are delegating to matching method names
43 48 */
@@ -391,9 +396,7 @@ public function testJoins() {
391 396 public function testWithAssociation() {
392 397 $model = $this->_model;
393 398 $model::meta('source', 'foo');
394   - $model::bind('hasMany', 'MockQueryComment', array(
395   - 'class' => 'lithium\tests\mocks\data\model\MockQueryComment'
396   - ));
  399 + $model::bind('hasMany', 'MockQueryComment');
397 400
398 401 $query = new Query(compact('model') + array('with' => 'MockQueryComment'));
399 402 $export = $query->export(new MockDatabase());
@@ -402,8 +405,7 @@ public function testWithAssociation() {
402 405 'type' => 'hasMany',
403 406 'model' => 'lithium\tests\mocks\data\model\MockQueryComment',
404 407 'fieldName' => 'mock_query_comments',
405   - 'fromAlias' => 'MockQueryPost',
406   - 'toAlias' => 'MockQueryComment'
  408 + 'alias' => 'MockQueryComment'
407 409 ));
408 410 $keyExists = isset($export['relationships']);
409 411 $this->assertTrue($keyExists);
@@ -612,8 +614,10 @@ public function testAliasAndPaths() {
612 614
613 615 public function testModels() {
614 616 $model = 'lithium\tests\mocks\data\model\MockQueryPost';
615   - $query = new Query(compact('model'));
616   - $query->alias(null, 'MockQueryComment');
  617 + $query = new Query(array(
  618 + 'model' => $model,
  619 + 'with' => 'MockQueryComment'
  620 + ));
617 621
618 622 $expected = array(
619 623 'MockQueryPost' => 'lithium\tests\mocks\data\model\MockQueryPost',
@@ -621,9 +625,14 @@ public function testModels() {
621 625 );
622 626 $this->assertEqual($expected, $query->models($this->db));
623 627
624   - $query->alias('Post');
625   - $query->alias('Comment', 'MockQueryComment');
626   - $query->alias('Post2', 'MockQueryComment.MockQueryPost');
  628 + $query = new Query(array(
  629 + 'model' => $model,
  630 + 'alias' => 'Post',
  631 + 'with' => array(
  632 + 'MockQueryComment' => array('alias' => 'Comment'),
  633 + 'MockQueryComment.MockQueryPost' => array('alias' => 'Post2'),
  634 + )
  635 + ));
627 636
628 637 $expected = array(
629 638 'Post' => 'lithium\tests\mocks\data\model\MockQueryPost',
@@ -633,27 +642,6 @@ public function testModels() {
633 642 $this->assertEqual($expected, $query->models($this->db));
634 643 }
635 644
636   - public function testRelationNames() {
637   - $model = 'lithium\tests\mocks\data\model\MockQueryPost';
638   - $query = new Query(compact('model'));
639   - $query->alias(null, 'MockQueryComment');
640   -
641   - $expected = array(
642   - 'MockQueryComment' => 'mock_query_comments'
643   - );
644   - $this->assertEqual($expected, $query->relationNames($this->db));
645   -
646   - $query->alias('Post');
647   - $query->alias('Comment', 'MockQueryComment');
648   - $query->alias('Post2', 'MockQueryComment.MockQueryPost');
649   -
650   - $expected = array(
651   - 'MockQueryComment' => 'mock_query_comments',
652   - 'MockQueryComment.MockQueryPost' => 'mock_query_comments.mock_query_post'
653   - );
654   - $this->assertEqual($expected, $query->relationNames($this->db));
655   - }
656   -
657 645 public function testExportWithJoinedStrategy() {
658 646 $query = new Query(array(
659 647 'alias' => 'MyAlias',
@@ -702,22 +690,19 @@ public function testExportWithJoinedStrategy() {
702 690 'type' => 'hasMany',
703 691 'model' => 'lithium\tests\mocks\data\model\MockImage',
704 692 'fieldName' => 'images',
705   - 'fromAlias' => 'MyAlias',
706   - 'toAlias' => 'Image'
  693 + 'alias' => 'Image'
707 694 ),
708 695 'Image.ImageTag' => array(
709 696 'type' => 'hasMany',
710 697 'model' => 'lithium\tests\mocks\data\model\MockImageTag',
711 698 'fieldName' => 'image_tags',
712   - 'fromAlias' => 'Image',
713   - 'toAlias' => 'ImageTag'
  699 + 'alias' => 'ImageTag'
714 700 ),
715 701 'Image.ImageTag.Tag' => array(
716 702 'type' => 'belongsTo',
717 703 'model' => 'lithium\tests\mocks\data\model\MockTag',
718 704 'fieldName' => 'tag',
719   - 'fromAlias' => 'ImageTag',
720   - 'toAlias' => 'Tag'
  705 + 'alias' => 'Tag'
721 706 )
722 707 )
723 708 );
4 tests/cases/data/source/DatabaseTest.php
@@ -1584,13 +1584,13 @@ public function testReturnArrayOnReadWithQuery() {
1584 1584 'author_id' => '2',
1585 1585 'title' => 'Post title',
1586 1586 'created' => '2012-12-17 17:04:00',
1587   - 'mock_database_comments' => array(
  1587 + 'MockDatabaseComment' => array(
1588 1588 'id' => '3',
1589 1589 'post_id' => '1',
1590 1590 'author_id' => '2',
1591 1591 'body' => 'Very good post',
1592 1592 'created' => '2012-12-17 17:05:00',
1593   - 'mock_database_post' => array(
  1593 + 'MockDatabasePost' => array(
1594 1594 'id' => '1',
1595 1595 'author_id' => '2',
1596 1596 'title' => 'Post title',
26 tests/cases/test/MockerTest.php
@@ -113,6 +113,32 @@ public function testFilteringStaticClassCanReturnOriginal() {
113 113 $this->assertEqual($filteredResult, $originalResult);
114 114 }
115 115
  116 + public function testOriginalMethodNotCalled() {
  117 + $http = new \lithium\tests\mocks\security\auth\adapter\mockHttp\Mock;
  118 +
  119 + $this->assertEqual(0, count($http->headers));
  120 +
  121 + $http->_writeHeader('Content-type: text/html');
  122 +
  123 + $this->assertEqual(1, count($http->headers));
  124 +
  125 + $http->applyFilter('_writeHeader', function($self, $params, $chain) {
  126 + return false;
  127 + });
  128 +
  129 + $http->_writeHeader('Content-type: application/pdf');
  130 +
  131 + $this->assertEqual(1, count($http->headers));
  132 + }
  133 +
  134 + public function testFilteringAFilteredMethod() {
  135 + $adapt = 'lithium\core\adaptable\Mock';
  136 + $adapt::applyFilter('_initAdapter', function($self, $params, $chain) {
  137 + return false;
  138 + });
  139 + $this->assertFalse($adapt::_initAdapter('foo', array()));
  140 + }
  141 +
116 142 }
117 143
118 144 ?>

No commit comments for this range

Something went wrong with that request. Please try again.