From dcff02cc64fca734e7df2779999ec1a800e55f85 Mon Sep 17 00:00:00 2001 From: mark_story Date: Wed, 5 Feb 2014 21:45:17 -0500 Subject: [PATCH] Add additional tests for various iterators. Expand documentation and tests for iterators. --- src/View/Form/EntityContext.php | 22 +++++++++++++++++++ .../TestCase/View/Form/EntityContextTest.php | 20 +++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/src/View/Form/EntityContext.php b/src/View/Form/EntityContext.php index d818cb98160..394eb4be59a 100644 --- a/src/View/Form/EntityContext.php +++ b/src/View/Form/EntityContext.php @@ -19,6 +19,8 @@ use Cake\ORM\TableRegistry; use Cake\Utility\Inflector; use Cake\Validation\Validator; +use IteratorAggregate; +use IteratorIterator; use Traversable; /** @@ -89,12 +91,31 @@ public function __construct(Request $request, array $context) { /** * Prepare some additional data from the context. * + * If the table option was provided to the constructor and it + * was a string, ORM\TableRegistry will be used to get the correct table instance. + * + * If an object is provided as the table option, it will be used as is. + * + * If no table option is provided, the table name will be derived based on + * naming conventions. This inference will work with a number of common objects + * like arrays, Collection objects and ResultSets. + * * @return void + * @throws \RuntimeException When a table object cannot be located/inferred. */ protected function _prepare() { $table = $this->_context['table']; if (empty($table)) { $entity = $this->_context['entity']; + if ($entity instanceof IteratorAggregate) { + $entity = $entity->getIterator()->current(); + } elseif ($entity instanceof IteratorIterator) { + $entity = $entity->getInnerIterator()->current(); + } elseif ($entity instanceof Traversable) { + $entity = $entity->current(); + } elseif (is_array($entity)) { + $entity = current($entity); + } if ($entity instanceof Entity) { list($ns, $entityClass) = namespaceSplit(get_class($entity)); $table = Inflector::pluralize($entityClass); @@ -103,6 +124,7 @@ protected function _prepare() { if (is_string($table)) { $table = TableRegistry::get($table); } + if (!is_object($table)) { throw new \RuntimeException( 'Unable to find table class for current entity' diff --git a/tests/TestCase/View/Form/EntityContextTest.php b/tests/TestCase/View/Form/EntityContextTest.php index ff1084a1baf..14683cc9fab 100644 --- a/tests/TestCase/View/Form/EntityContextTest.php +++ b/tests/TestCase/View/Form/EntityContextTest.php @@ -22,6 +22,7 @@ use Cake\TestSuite\TestCase; use Cake\Validation\Validator; use Cake\View\Form\EntityContext; +use ArrayIterator; use ArrayObject; /** @@ -75,6 +76,24 @@ public function testOperationsNoTableArg() { $this->assertEquals($row->errors('title'), $result); } +/** + * Test collection operations that lack a table argument. + * + * @dataProvider collectionProvider + * @return void + */ + public function testCollectionOperationsNoTableArg($collection) { + $context = new EntityContext($this->request, [ + 'entity' => $collection, + ]); + + $result = $context->val('0.title'); + $this->assertEquals('First post', $result); + + $result = $context->error('1.body'); + $this->assertEquals(['Not long enough'], $result); + } + /** * Data provider for testing collections. * @@ -98,6 +117,7 @@ public static function collectionProvider() { return [ 'array' => [[$one, $two]], 'basic iterator' => [new ArrayObject([$one, $two])], + 'array iterator' => [new ArrayIterator([$one, $two])], 'collection' => [new Collection([$one, $two])], ]; }