Skip to content
Permalink
Browse files

Unit testing the mapReduce() method and chanigng the implementation of

the ResultSetDecorator, as IteratorIterator is segfaulty
  • Loading branch information...
lorenzo committed Aug 20, 2013
1 parent f97e490 commit 262c412f538927ddae7c7357f5675b26124a8fd2
Showing with 130 additions and 9 deletions.
  1. +4 −2 lib/Cake/ORM/Query.php
  2. +11 −7 lib/Cake/ORM/ResultSetDecorator.php
  3. +115 −0 lib/Cake/Test/TestCase/ORM/QueryTest.php
@@ -390,9 +390,11 @@ public function execute() {
return $this->_results;
}
if ($this->_useBufferedResults) {
return $this->_applyFormatters(new BufferedResultSet($this, parent::execute()));
return $this->_applyFormatters(
new BufferedResultSet($this, $this->executeStatement())
);
}
return $this->_applyFormatters(new ResultSet($this, parent::execute()));
return $this->_applyFormatters(new ResultSet($this, $this->executeStatement()));
}
/**
@@ -16,7 +16,7 @@
*/
namespace Cake\ORM;
use \IteratorIterator;
use \IteratorAggregate;
use \JsonSerializable;
use \Serializable;
@@ -26,7 +26,7 @@
*
* @return void
*/
class ResultSetDecorator extends IteratorIterator implements Serializable, JsonSerializable {
class ResultSetDecorator implements IteratorAggregate, Serializable, JsonSerializable {
use ResultCollectionTrait;
@@ -37,16 +37,20 @@ class ResultSetDecorator extends IteratorIterator implements Serializable, JsonS
*/
protected $_results;
public function __construct(\Traversable $results) {
$this->_results = $results;
}
/**
* Returns the inner iterator this decorator is wrapping
*
* @return void
* @return \Iterator
*/
public function getInnerIterator() {
if ($this->_results) {
return new IteratorIterator($this->_results);
public function getIterator() {
if (is_array($this->_results)) {
$this->_results = new \ArrayIterator($this->_results);
}
return parent::getInnerIterator();
return $this->_results;
}
}
@@ -31,9 +31,19 @@
*/
class QueryTest extends TestCase {
/**
* Fixture to be used
*
* @var array
*/
public $fixtures = ['core.article', 'core.author', 'core.tag',
'core.articles_tag', 'core.post'];
/**
* setUp method
*
* @return void
*/
public function setUp() {
parent::setUp();
$this->connection = ConnectionManager::getDataSource('test');
@@ -67,6 +77,11 @@ public function setUp() {
$companies->belongsTo('category');
}
/**
* tearDown method
*
* @return void
*/
public function tearDown() {
parent::tearDown();
Table::clearRegistry();
@@ -888,4 +903,104 @@ public function testApplyOptions() {
$this->assertEquals($expected, $query->contain());
}
/**
* Tests registering mappers with mapReduce()
*
* @return void
*/
public function testMapReduceOnlyMapper() {
$mapper1 = function() {};
$mapper2 = function() {};
$query = new Query($this->connection, $this->table);
$this->assertSame($query, $query->mapReduce($mapper1));
$this->assertSame([['mapper' => $mapper1]], $query->mapReduce());
$this->assertSame($query, $query->mapReduce($mapper1));
$result = $query->mapReduce();
$this->assertEquals([['mapper' => $mapper1], ['mapper' => $mapper2]], $result);
}
/**
* Tests registering mappers and reducers with mapReduce()
*
* @return void
*/
public function testMapReduceBothMethods() {
$mapper1 = function() {};
$mapper2 = function() {};
$reducer1 = function() {};
$reducer2 = function() {};
$query = new Query($this->connection, $this->table);
$this->assertSame($query, $query->mapReduce($mapper1, $reducer1));
$this->assertSame(
[['mapper' => $mapper1, 'reducer' => $reducer1]],
$query->mapReduce()
);
$this->assertSame($query, $query->mapReduce($mapper2, $reducer2));
$this->assertSame(
[
['mapper' => $mapper1, 'reducer' => $reducer1],
['mapper' => $mapper2, 'reducer' => $reducer2]
],
$query->mapReduce()
);
}
/**
* Tests that it is possible to overwrite previous map reducers
*
* @return void
*/
public function testOverwriteMapReduce() {
$mapper1 = function() {};
$mapper2 = function() {};
$reducer1 = function() {};
$reducer2 = function() {};
$query = new Query($this->connection, $this->table);
$this->assertSame($query, $query->mapReduce($mapper1, $reducer1));
$this->assertSame(
[['mapper' => $mapper1, 'reducer' => $reducer1]],
$query->mapReduce()
);
$this->assertSame($query, $query->mapReduce($mapper2, $reducer2, true));
$this->assertSame(
[['mapper' => $mapper2, 'reducer' => $reducer2]],
$query->mapReduce()
);
}
/**
* Tests that multiple map reducers can be stacked
*
* @return void
*/
public function testResultsAreWrappedInMapReduce() {
$params = [$this->connection, $this->table];
$query = $this->getMock('\Cake\ORM\Query', ['executeStatement'], $params);
$statement = $this->getMock('\Database\StatementInterface', ['fetch']);
$statement->expects($this->at(0))
->method('fetch')
->will($this->returnValue(['a' => 1]));
$statement->expects($this->at(1))
->method('fetch')
->will($this->returnValue(['a' => 2]));
$statement->expects($this->at(2))
->method('fetch')
->will($this->returnValue(false));
$query->expects($this->once())
->method('executeStatement')
->will($this->returnValue($statement));
$query->mapReduce(function($k, $v, $mr) { $mr->emit($v['a']); });
$query->mapReduce(
function($k, $v, $mr) { $mr->emitIntermediate($k, $v); },
function($k, $v, $mr) { $mr->emit($v[0] + 1); }
);
$this->assertEquals([2, 3], iterator_to_array($query->execute()));
}
}

0 comments on commit 262c412

Please sign in to comment.
You can’t perform that action at this time.