Skip to content

Commit

Permalink
Unit testing the mapReduce() method and chanigng the implementation of
Browse files Browse the repository at this point in the history
the ResultSetDecorator, as IteratorIterator is segfaulty
  • Loading branch information
lorenzo committed Aug 20, 2013
1 parent f97e490 commit 262c412
Show file tree
Hide file tree
Showing 3 changed files with 130 additions and 9 deletions.
6 changes: 4 additions & 2 deletions lib/Cake/ORM/Query.php
Expand Up @@ -390,9 +390,11 @@ public function execute() {
return $this->_results; return $this->_results;
} }
if ($this->_useBufferedResults) { 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()));
} }


/** /**
Expand Down
18 changes: 11 additions & 7 deletions lib/Cake/ORM/ResultSetDecorator.php
Expand Up @@ -16,7 +16,7 @@
*/ */
namespace Cake\ORM; namespace Cake\ORM;


use \IteratorIterator; use \IteratorAggregate;
use \JsonSerializable; use \JsonSerializable;
use \Serializable; use \Serializable;


Expand All @@ -26,7 +26,7 @@
* *
* @return void * @return void
*/ */
class ResultSetDecorator extends IteratorIterator implements Serializable, JsonSerializable { class ResultSetDecorator implements IteratorAggregate, Serializable, JsonSerializable {


use ResultCollectionTrait; use ResultCollectionTrait;


Expand All @@ -37,16 +37,20 @@ class ResultSetDecorator extends IteratorIterator implements Serializable, JsonS
*/ */
protected $_results; protected $_results;


public function __construct(\Traversable $results) {
$this->_results = $results;
}

/** /**
* Returns the inner iterator this decorator is wrapping * Returns the inner iterator this decorator is wrapping
* *
* @return void * @return \Iterator
*/ */
public function getInnerIterator() { public function getIterator() {
if ($this->_results) { if (is_array($this->_results)) {
return new IteratorIterator($this->_results); $this->_results = new \ArrayIterator($this->_results);
} }
return parent::getInnerIterator(); return $this->_results;
} }


} }
115 changes: 115 additions & 0 deletions lib/Cake/Test/TestCase/ORM/QueryTest.php
Expand Up @@ -31,9 +31,19 @@
*/ */
class QueryTest extends TestCase { class QueryTest extends TestCase {


/**
* Fixture to be used
*
* @var array
*/
public $fixtures = ['core.article', 'core.author', 'core.tag', public $fixtures = ['core.article', 'core.author', 'core.tag',
'core.articles_tag', 'core.post']; 'core.articles_tag', 'core.post'];


/**
* setUp method
*
* @return void
*/
public function setUp() { public function setUp() {
parent::setUp(); parent::setUp();
$this->connection = ConnectionManager::getDataSource('test'); $this->connection = ConnectionManager::getDataSource('test');
Expand Down Expand Up @@ -67,6 +77,11 @@ public function setUp() {
$companies->belongsTo('category'); $companies->belongsTo('category');
} }


/**
* tearDown method
*
* @return void
*/
public function tearDown() { public function tearDown() {
parent::tearDown(); parent::tearDown();
Table::clearRegistry(); Table::clearRegistry();
Expand Down Expand Up @@ -888,4 +903,104 @@ public function testApplyOptions() {
$this->assertEquals($expected, $query->contain()); $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.