Skip to content
Permalink
Browse files

Moving some tests to EagerLoaderTest

  • Loading branch information...
lorenzo committed Jan 30, 2014
1 parent 927ac68 commit 3f05982598f2dd4a7308190dddf30ef332071c0a
Showing with 350 additions and 257 deletions.
  1. +350 −0 tests/TestCase/ORM/EagerLoaderTest.php
  2. +0 −257 tests/TestCase/ORM/QueryTest.php
@@ -0,0 +1,350 @@
<?php
/**
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @since CakePHP(tm) v 3.0.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
namespace Cake\Test\TestCase\ORM;
use Cake\Database\ConnectionManager;
use Cake\Database\Expression\IdentifierExpression;
use Cake\Database\Expression\QueryExpression;
use Cake\ORM\EagerLoader;
use Cake\ORM\Query;
use Cake\ORM\Table;
use Cake\ORM\TableRegistry;
use Cake\TestSuite\TestCase;
/**
* Tests EagerLoader
*
*/
class EagerLoaderTest extends TestCase {
/**
* setUp method
*
* @return void
*/
public function setUp() {
parent::setUp();
$this->connection = ConnectionManager::get('test');
$schema = [
'id' => ['type' => 'integer'],
'_constraints' => [
'primary' => ['type' => 'primary', 'columns' => ['id']]
]
];
$schema1 = [
'id' => ['type' => 'integer'],
'name' => ['type' => 'string'],
'phone' => ['type' => 'string'],
'_constraints' => [
'primary' => ['type' => 'primary', 'columns' => ['id']]
]
];
$schema2 = [
'id' => ['type' => 'integer'],
'total' => ['type' => 'string'],
'placed' => ['type' => 'datetime'],
'_constraints' => [
'primary' => ['type' => 'primary', 'columns' => ['id']]
]
];
$this->table = $table = TableRegistry::get('foo', ['schema' => $schema]);
$clients = TableRegistry::get('clients', ['schema' => $schema1]);
$orders = TableRegistry::get('orders', ['schema' => $schema2]);
$companies = TableRegistry::get('companies', ['schema' => $schema, 'table' => 'organizations']);
$orderTypes = TableRegistry::get('orderTypes', ['schema' => $schema]);
$stuff = TableRegistry::get('stuff', ['schema' => $schema, 'table' => 'things']);
$stuffTypes = TableRegistry::get('stuffTypes', ['schema' => $schema]);
$categories = TableRegistry::get('categories', ['schema' => $schema]);
$table->belongsTo('clients');
$clients->hasOne('orders');
$clients->belongsTo('companies');
$orders->belongsTo('orderTypes');
$orders->hasOne('stuff');
$stuff->belongsTo('stuffTypes');
$companies->belongsTo('categories');
}
/**
* tearDown method
*
* @return void
*/
public function tearDown() {
parent::tearDown();
TableRegistry::clear();
}
/**
* Tests that fully defined belongsTo and hasOne relationships are joined correctly
*
* @return void
**/
public function testContainToJoinsOneLevel() {
$contains = [
'clients' => [
'orders' => [
'orderTypes',
'stuff' => ['stuffTypes']
],
'companies' => [
'foreignKey' => 'organization_id',
'categories'
]
]
];
$query = $this->getMock('\Cake\ORM\Query', ['join'], [$this->connection, $this->table]);
$query->expects($this->at(0))->method('join')
->with(['clients' => [
'table' => 'clients',
'type' => 'LEFT',
'conditions' => new QueryExpression([
['clients.id' => new IdentifierExpression('foo.client_id')]
])
]])
->will($this->returnValue($query));
$query->expects($this->at(1))->method('join')
->with(['orders' => [
'table' => 'orders',
'type' => 'INNER',
'conditions' => new QueryExpression([
['clients.id' => new IdentifierExpression('orders.client_id')]
])
]])
->will($this->returnValue($query));
$query->expects($this->at(2))->method('join')
->with(['orderTypes' => [
'table' => 'order_types',
'type' => 'LEFT',
'conditions' => new QueryExpression([
['orderTypes.id' => new IdentifierExpression('orders.order_type_id')]
])
]])
->will($this->returnValue($query));
$query->expects($this->at(3))->method('join')
->with(['stuff' => [
'table' => 'things',
'type' => 'INNER',
'conditions' => new QueryExpression([
['orders.id' => new IdentifierExpression('stuff.order_id')]
])
]])
->will($this->returnValue($query));
$query->expects($this->at(4))->method('join')
->with(['stuffTypes' => [
'table' => 'stuff_types',
'type' => 'LEFT',
'conditions' => new QueryExpression([
['stuffTypes.id' => new IdentifierExpression('stuff.stuff_type_id')]
])
]])
->will($this->returnValue($query));
$query->expects($this->at(5))->method('join')
->with(['companies' => [
'table' => 'organizations',
'type' => 'LEFT',
'conditions' => new QueryExpression([
['companies.id' => new IdentifierExpression('clients.organization_id')]
])
]])
->will($this->returnValue($query));
$query->expects($this->at(6))->method('join')
->with(['categories' => [
'table' => 'categories',
'type' => 'LEFT',
'conditions' => new QueryExpression([
['categories.id' => new IdentifierExpression('companies.category_id')]
])
]])
->will($this->returnValue($query));
$loader = new EagerLoader;
$loader->contain($contains);
$query->select('foo.id')->eagerLoader($loader)->sql();
}
/**
* Tests setting containments using dot notation, additionally proves that options
* are not overwritten when combining dot notation and array notation
*
* @return void
*/
public function testContainDotNotation() {
$loader = new EagerLoader;
$loader->contain([
'clients.orders.stuff',
'clients.companies.categories' => ['conditions' => ['a >' => 1]]
]);
$expected = [
'clients' => [
'orders' => [
'stuff' => []
],
'companies' => [
'categories' => [
'conditions' => ['a >' => 1]
]
]
]
];
$this->assertEquals($expected, $loader->contain());
$loader->contain([
'clients.orders' => ['fields' => ['a', 'b']],
'clients' => ['sort' => ['a' => 'desc']],
]);
$expected['clients']['orders'] += ['fields' => ['a', 'b']];
$expected['clients'] += ['sort' => ['a' => 'desc']];
$this->assertEquals($expected, $loader->contain());
}
/**
* Tests that it is possible to pass a function as the array value for contain
*
* @return void
*/
public function testContainClosure() {
$builder = function($query) {
};
$loader = new EagerLoader;
$loader->contain([
'clients.orders.stuff' => ['fields' => ['a']],
'clients' => $builder
]);
$expected = [
'clients' => [
'orders' => [
'stuff' => ['fields' => ['a']]
],
'queryBuilder' => $builder
]
];
$this->assertEquals($expected, $loader->contain());
$loader = new EagerLoader;
$loader->contain([
'clients.orders.stuff' => ['fields' => ['a']],
'clients' => ['queryBuilder' => $builder]
]);
$this->assertEquals($expected, $loader->contain());
}
/**
* Test that fields for contained models are aliased and added to the select clause
*
* @return void
**/
public function testContainToFieldsPredefined() {
$contains = [
'clients' => [
'fields' => ['name', 'company_id', 'clients.telephone'],
'orders' => [
'fields' => ['total', 'placed']
]
]
];
$table = TableRegistry::get('foo');
$query = new Query($this->connection, $table);
$loader = new EagerLoader;
$loader->contain($contains);
$query->select('foo.id')->sql();
$loader->attachAssociations($query, true);
$select = $query->clause('select');
$expected = [
'foo__id' => 'foo.id', 'clients__name' => 'clients.name',
'clients__company_id' => 'clients.company_id',
'clients__telephone' => 'clients.telephone',
'orders__total' => 'orders.total', 'orders__placed' => 'orders.placed'
];
$expected = $this->_quoteArray($expected);
$this->assertEquals($expected, $select);
}
/**
* Tests that default fields for associations are added to the select clause when
* none is specified
*
* @return void
**/
public function testContainToFieldsDefault() {
$contains = ['clients' => ['orders']];
$query = new Query($this->connection, $this->table);
$query->select()->contain($contains)->sql();
$select = $query->clause('select');
$expected = [
'foo__id' => 'foo.id', 'clients__name' => 'clients.name',
'clients__id' => 'clients.id', 'clients__phone' => 'clients.phone',
'orders__id' => 'orders.id', 'orders__total' => 'orders.total',
'orders__placed' => 'orders.placed'
];
$expected = $this->_quoteArray($expected);
$this->assertEquals($expected, $select);
$contains['clients']['fields'] = ['name'];
$query = new Query($this->connection, $this->table);
$query->select('foo.id')->contain($contains)->sql();
$select = $query->clause('select');
$expected = ['foo__id' => 'foo.id', 'clients__name' => 'clients.name'];
$expected = $this->_quoteArray($expected);
$this->assertEquals($expected, $select);
$contains['clients']['fields'] = [];
$contains['clients']['orders']['fields'] = false;
$query = new Query($this->connection, $this->table);
$query->select()->contain($contains)->sql();
$select = $query->clause('select');
$expected = [
'foo__id' => 'foo.id',
'clients__id' => 'clients.id',
'clients__name' => 'clients.name',
'clients__phone' => 'clients.phone',
];
$expected = $this->_quoteArray($expected);
$this->assertEquals($expected, $select);
}
/**
* Helper function sued to quoted both keys and values in an array in case
* the test suite is running with auto quoting enabled
*
* @param array $elements
* @return array
*/
protected function _quoteArray($elements) {
if ($this->connection->driver()->autoQuoting()) {
$quoter = function($e) {
return $this->connection->driver()->quoteIdentifier($e);
};
return array_combine(
array_map($quoter, array_keys($elements)),
array_map($quoter, array_values($elements))
);
}
return $elements;
}
}
Oops, something went wrong.

0 comments on commit 3f05982

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