Commit f017ba35 by Carsten Brandt

refactored unit tests. put common AR tests in trait

parent 983b2286
......@@ -1169,7 +1169,7 @@ class ActiveRecord extends Model
return false;
}
foreach ($this->attributes() as $name) {
$this->_attributes[$name] = $record->_attributes[$name];
$this->_attributes[$name] = isset($record->_attributes[$name]) ? $record->_attributes[$name] : null;
}
$this->_oldAttributes = $this->_attributes;
$this->_related = [];
......
......@@ -39,11 +39,7 @@ class ActiveRelation extends ActiveQuery implements ActiveRelationInterface
{
if ($this->primaryModel !== null) {
// lazy loading
if ($this->via instanceof ActiveRelationInterface) {
// via pivot table
$viaModels = $this->via->findPivotRows([$this->primaryModel]);
$this->filterByModels($viaModels);
} elseif (is_array($this->via)) {
if (is_array($this->via)) {
// via relation
/** @var ActiveRelation $viaQuery */
list($viaName, $viaQuery) = $this->via;
......
......@@ -73,13 +73,16 @@ class QueryBuilder extends \yii\base\Object
$parts['query'] = ["match_all" => (object)[]];
}
$options = [];
if ($query->timeout !== null) {
$options['timeout'] = $query->timeout;
}
return [
'queryParts' => $parts,
'index' => $query->index,
'type' => $query->type,
'options' => [
'timeout' => $query->timeout
],
'options' => $options,
];
}
......
<?php
namespace yiiunit\data\ar;
use yiiunit\framework\db\ActiveRecordTest;
/**
* Class Customer
*
......@@ -17,9 +19,6 @@ class Customer extends ActiveRecord
public $status2;
public static $afterSaveInsert = null;
public static $afterSaveNewRecord = null;
public static function tableName()
{
return 'tbl_customer';
......@@ -37,8 +36,8 @@ class Customer extends ActiveRecord
public function afterSave($insert)
{
static::$afterSaveInsert = $insert;
static::$afterSaveNewRecord = $this->isNewRecord;
ActiveRecordTest::$afterSaveInsert = $insert;
ActiveRecordTest::$afterSaveNewRecord = $this->isNewRecord;
parent::afterSave($insert);
}
}
<?php
namespace yiiunit\data\ar\elasticsearch;
use yiiunit\framework\elasticsearch\ActiveRecordTest;
/**
* Class Customer
*
......@@ -31,4 +33,11 @@ class Customer extends ActiveRecord
{
$query->andWhere(array('status' => 1));
}
public function afterSave($insert)
{
ActiveRecordTest::$afterSaveInsert = $insert;
ActiveRecordTest::$afterSaveNewRecord = $this->isNewRecord;
parent::afterSave($insert);
}
}
......@@ -2,6 +2,8 @@
namespace yiiunit\data\ar\redis;
use yiiunit\framework\redis\ActiveRecordTest;
class Customer extends ActiveRecord
{
const STATUS_ACTIVE = 1;
......@@ -26,4 +28,11 @@ class Customer extends ActiveRecord
{
$query->andWhere(['status' => 1]);
}
public function afterSave($insert)
{
ActiveRecordTest::$afterSaveInsert = $insert;
ActiveRecordTest::$afterSaveNewRecord = $this->isNewRecord;
parent::afterSave($insert);
}
}
\ No newline at end of file
......@@ -23,7 +23,7 @@ CREATE TABLE `tbl_constraints`
CREATE TABLE `tbl_customer` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`email` varchar(128) NOT NULL,
`name` varchar(128) NOT NULL,
`name` varchar(128),
`address` string,
`status` int (11) DEFAULT 0,
PRIMARY KEY (`id`)
......
......@@ -9,7 +9,7 @@ IF OBJECT_ID('[dbo].[tbl_null_values]', 'U') IS NOT NULL DROP TABLE [dbo].[tbl_n
CREATE TABLE [dbo].[tbl_customer] (
[id] [int] IDENTITY(1,1) NOT NULL,
[email] [varchar](128) NOT NULL,
[name] [varchar](128) NOT NULL,
[name] [varchar](128),
[address] [text],
[status] [int] DEFAULT 0,
CONSTRAINT [PK_customer] PRIMARY KEY CLUSTERED (
......
......@@ -23,7 +23,7 @@ CREATE TABLE `tbl_constraints`
CREATE TABLE `tbl_customer` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`email` varchar(128) NOT NULL,
`name` varchar(128) NOT NULL,
`name` varchar(128),
`address` text,
`status` int (11) DEFAULT 0,
PRIMARY KEY (`id`)
......
......@@ -22,7 +22,7 @@ CREATE TABLE tbl_constraints
CREATE TABLE tbl_customer (
id serial not null primary key,
email varchar(128) NOT NULL,
name varchar(128) NOT NULL,
name varchar(128),
address text,
status integer DEFAULT 0
);
......
......@@ -15,7 +15,7 @@ DROP TABLE IF EXISTS tbl_null_values;
CREATE TABLE tbl_customer (
id INTEGER NOT NULL,
email varchar(128) NOT NULL,
name varchar(128) NOT NULL,
name varchar(128),
address text,
status INTEGER DEFAULT 0,
PRIMARY KEY (id)
......
<?php
/**
*
*
* @author Carsten Brandt <mail@cebe.cc>
*/
namespace yiiunit\framework\ar;
use yii\db\ActiveQueryInterface;
use yiiunit\TestCase;
use yiiunit\data\ar\Customer;
use yiiunit\data\ar\Order;
/**
* This trait provides unit tests shared by the differen AR implementations
*
* @var TestCase $this
*/
trait ActiveRecordTestTrait
{
/**
* This method should call Customer::find($q)
* @param $q
* @return mixed
*/
public abstract function callCustomerFind($q = null);
/**
* This method should call Order::find($q)
* @param $q
* @return mixed
*/
public abstract function callOrderFind($q = null);
/**
* This method should call OrderItem::find($q)
* @param $q
* @return mixed
*/
public abstract function callOrderItemFind($q = null);
/**
* This method should call Item::find($q)
* @param $q
* @return mixed
*/
public abstract function callItemFind($q = null);
/**
* This method should return the classname of Customer class
* @return string
*/
public abstract function getCustomerClass();
/**
* This method should return the classname of Order class
* @return string
*/
public abstract function getOrderClass();
/**
* This method should return the classname of OrderItem class
* @return string
*/
public abstract function getOrderItemClass();
/**
* This method should return the classname of Item class
* @return string
*/
public abstract function getItemClass();
/**
* can be overridden to do things after save()
*/
public function afterSave()
{
}
public function testFind()
{
$customerClass = $this->getCustomerClass();
/** @var TestCase|ActiveRecordTestTrait $this */
// find one
$result = $this->callCustomerFind();
$this->assertTrue($result instanceof ActiveQueryInterface);
$customer = $result->one();
$this->assertTrue($customer instanceof $customerClass);
// find all
$customers = $this->callCustomerFind()->all();
$this->assertEquals(3, count($customers));
$this->assertTrue($customers[0] instanceof $customerClass);
$this->assertTrue($customers[1] instanceof $customerClass);
$this->assertTrue($customers[2] instanceof $customerClass);
// find all asArray
$customers = $this->callCustomerFind()->asArray()->all();
$this->assertEquals(3, count($customers));
$this->assertArrayHasKey('id', $customers[0]);
$this->assertArrayHasKey('name', $customers[0]);
$this->assertArrayHasKey('email', $customers[0]);
$this->assertArrayHasKey('address', $customers[0]);
$this->assertArrayHasKey('status', $customers[0]);
$this->assertArrayHasKey('id', $customers[1]);
$this->assertArrayHasKey('name', $customers[1]);
$this->assertArrayHasKey('email', $customers[1]);
$this->assertArrayHasKey('address', $customers[1]);
$this->assertArrayHasKey('status', $customers[1]);
$this->assertArrayHasKey('id', $customers[2]);
$this->assertArrayHasKey('name', $customers[2]);
$this->assertArrayHasKey('email', $customers[2]);
$this->assertArrayHasKey('address', $customers[2]);
$this->assertArrayHasKey('status', $customers[2]);
// find by a single primary key
$customer = $this->callCustomerFind(2);
$this->assertTrue($customer instanceof $customerClass);
$this->assertEquals('user2', $customer->name);
$customer = $this->callCustomerFind(5);
$this->assertNull($customer);
$customer = $this->callCustomerFind(['id' => [5, 6, 1]]);
$this->assertEquals(1, count($customer));
$customer = $this->callCustomerFind()->where(['id' => [5, 6, 1]])->one();
$this->assertNotNull($customer);
// find by column values
$customer = $this->callCustomerFind(['id' => 2, 'name' => 'user2']);
$this->assertTrue($customer instanceof $customerClass);
$this->assertEquals('user2', $customer->name);
$customer = $this->callCustomerFind(['id' => 2, 'name' => 'user1']);
$this->assertNull($customer);
$customer = $this->callCustomerFind(['id' => 5]);
$this->assertNull($customer);
// find by attributes
$customer = $this->callCustomerFind()->where(['name' => 'user2'])->one();
$this->assertTrue($customer instanceof $customerClass);
$this->assertEquals(2, $customer->id);
// scope
$this->assertEquals(2, $this->callCustomerFind()->active()->count());
// asArray
$customer = $this->callCustomerFind()->where(['id' => 2])->asArray()->one();
$this->assertEquals([
'id' => '2',
'email' => 'user2@example.com',
'name' => 'user2',
'address' => 'address2',
'status' => '1',
], $customer);
}
public function testFindScalar()
{
/** @var TestCase|ActiveRecordTestTrait $this */
// query scalar
$customerName = $this->callCustomerFind()->where(array('id' => 2))->scalar('name');
$this->assertEquals('user2', $customerName);
}
public function testFindColumn()
{
/** @var TestCase|ActiveRecordTestTrait $this */
$this->assertEquals(['user1', 'user2', 'user3'], Customer::find()->column('name'));
$this->assertEquals(['user3', 'user2', 'user1'], Customer::find()->orderBy(['name' => SORT_DESC])->column('name'));
}
public function testfindIndexBy()
{
$customerClass = $this->getCustomerClass();
/** @var TestCase|ActiveRecordTestTrait $this */
// indexBy
$customers = $this->callCustomerFind()->indexBy('name')->orderBy('id')->all();
$this->assertEquals(3, count($customers));
$this->assertTrue($customers['user1'] instanceof $customerClass);
$this->assertTrue($customers['user2'] instanceof $customerClass);
$this->assertTrue($customers['user3'] instanceof $customerClass);
// indexBy callable
$customers = $this->callCustomerFind()->indexBy(function ($customer) {
return $customer->id . '-' . $customer->name;
})->orderBy('id')->all();
$this->assertEquals(3, count($customers));
$this->assertTrue($customers['1-user1'] instanceof $customerClass);
$this->assertTrue($customers['2-user2'] instanceof $customerClass);
$this->assertTrue($customers['3-user3'] instanceof $customerClass);
}
public function testRefresh()
{
$customerClass = $this->getCustomerClass();
/** @var TestCase|ActiveRecordTestTrait $this */
$customer = new $customerClass();
$this->assertFalse($customer->refresh());
$customer = $this->callCustomerFind(1);
$customer->name = 'to be refreshed';
$this->assertTrue($customer->refresh());
$this->assertEquals('user1', $customer->name);
}
public function testEquals()
{
$customerClass = $this->getCustomerClass();
$itemClass = $this->getItemClass();
/** @var TestCase|ActiveRecordTestTrait $this */
$customerA = new $customerClass();
$customerB = new $customerClass();
$this->assertFalse($customerA->equals($customerB));
$customerA = new $customerClass();
$customerB = new $itemClass();
$this->assertFalse($customerA->equals($customerB));
$customerA = $this->callCustomerFind(1);
$customerB = $this->callCustomerFind(2);
$this->assertFalse($customerA->equals($customerB));
$customerB = $this->callCustomerFind(1);
$this->assertTrue($customerA->equals($customerB));
$customerA = $this->callCustomerFind(1);
$customerB = $this->callItemFind(1);
$this->assertFalse($customerA->equals($customerB));
}
public function testFindCount()
{
/** @var TestCase|ActiveRecordTestTrait $this */
$this->assertEquals(3, $this->callCustomerFind()->count());
// TODO should limit have effect on count()
// $this->assertEquals(1, $this->callCustomerFind()->limit(1)->count());
// $this->assertEquals(2, $this->callCustomerFind()->limit(2)->count());
// $this->assertEquals(1, $this->callCustomerFind()->offset(2)->limit(2)->count());
}
public function testFindLimit()
{
/** @var TestCase|ActiveRecordTestTrait $this */
// all()
$customers = $this->callCustomerFind()->all();
$this->assertEquals(3, count($customers));
$customers = $this->callCustomerFind()->limit(1)->all();
$this->assertEquals(1, count($customers));
$this->assertEquals('user1', $customers[0]->name);
$customers = $this->callCustomerFind()->limit(1)->offset(1)->all();
$this->assertEquals(1, count($customers));
$this->assertEquals('user2', $customers[0]->name);
$customers = $this->callCustomerFind()->limit(1)->offset(2)->all();
$this->assertEquals(1, count($customers));
$this->assertEquals('user3', $customers[0]->name);
$customers = $this->callCustomerFind()->limit(2)->offset(1)->all();
$this->assertEquals(2, count($customers));
$this->assertEquals('user2', $customers[0]->name);
$this->assertEquals('user3', $customers[1]->name);
$customers = $this->callCustomerFind()->limit(2)->offset(3)->all();
$this->assertEquals(0, count($customers));
// one()
$customer = $this->callCustomerFind()->one();
$this->assertEquals('user1', $customer->name);
$customer = $this->callCustomerFind()->offset(0)->one();
$this->assertEquals('user1', $customer->name);
$customer = $this->callCustomerFind()->offset(1)->one();
$this->assertEquals('user2', $customer->name);
$customer = $this->callCustomerFind()->offset(2)->one();
$this->assertEquals('user3', $customer->name);
$customer = $this->callCustomerFind()->offset(3)->one();
$this->assertNull($customer);
}
public function testFindComplexCondition()
{
/** @var TestCase|ActiveRecordTestTrait $this */
$this->assertEquals(2, $this->callCustomerFind()->where(['OR', ['name' => 'user1'], ['name' => 'user2']])->count());
$this->assertEquals(2, count($this->callCustomerFind()->where(['OR', ['name' => 'user1'], ['name' => 'user2']])->all()));
$this->assertEquals(2, $this->callCustomerFind()->where(['name' => ['user1','user2']])->count());
$this->assertEquals(2, count($this->callCustomerFind()->where(['name' => ['user1','user2']])->all()));
$this->assertEquals(1, $this->callCustomerFind()->where(['AND', ['name' => ['user2','user3']], ['BETWEEN', 'status', 2, 4]])->count());
$this->assertEquals(1, count($this->callCustomerFind()->where(['AND', ['name' => ['user2','user3']], ['BETWEEN', 'status', 2, 4]])->all()));
}
public function testFindNullValues()
{
/** @var TestCase|ActiveRecordTestTrait $this */
$customer = $this->callCustomerFind(2);
$customer->name = null;
$customer->save(false);
$this->afterSave();
$result = $this->callCustomerFind()->where(['name' => null])->all();
$this->assertEquals(1, count($result));
$this->assertEquals(2, reset($result)->primaryKey);
}
public function testExists()
{
/** @var TestCase|ActiveRecordTestTrait $this */
$this->assertTrue($this->callCustomerFind()->where(['id' => 2])->exists());
$this->assertFalse($this->callCustomerFind()->where(['id' => 5])->exists());
$this->assertTrue($this->callCustomerFind()->where(['name' => 'user1'])->exists());
$this->assertFalse($this->callCustomerFind()->where(['name' => 'user5'])->exists());
}
public function testFindLazy()
{
/** @var TestCase|ActiveRecordTestTrait $this */
$customer = $this->callCustomerFind(2);
$this->assertFalse($customer->isRelationPopulated('orders'));
$orders = $customer->orders;
$this->assertTrue($customer->isRelationPopulated('orders'));
$this->assertEquals(2, count($orders));
$this->assertEquals(1, count($customer->populatedRelations));
/** @var Customer $customer */
$customer = $this->callCustomerFind(2);
$this->assertFalse($customer->isRelationPopulated('orders'));
$orders = $customer->getOrders()->where(['id' => 3])->all();
$this->assertFalse($customer->isRelationPopulated('orders'));
$this->assertEquals(0, count($customer->populatedRelations));
$this->assertEquals(1, count($orders));
$this->assertEquals(3, $orders[0]->id);
}
public function testFindEager()
{
/** @var TestCase|ActiveRecordTestTrait $this */
$customers = $this->callCustomerFind()->with('orders')->all();
$this->assertEquals(3, count($customers));
$this->assertTrue($customers[0]->isRelationPopulated('orders'));
$this->assertTrue($customers[1]->isRelationPopulated('orders'));
$this->assertEquals(1, count($customers[0]->orders));
$this->assertEquals(2, count($customers[1]->orders));
$customer = $this->callCustomerFind()->with('orders')->one();
$this->assertTrue($customer->isRelationPopulated('orders'));
$this->assertEquals(1, count($customer->orders));
$this->assertEquals(1, count($customer->populatedRelations));
}
public function testFindLazyVia()
{
/** @var TestCase|ActiveRecordTestTrait $this */
/** @var Order $order */
$order = $this->callOrderFind(1);
$this->assertEquals(1, $order->id);
$this->assertEquals(2, count($order->items));
$this->assertEquals(1, $order->items[0]->id);
$this->assertEquals(2, $order->items[1]->id);
$order = $this->callOrderFind(1);
$order->id = 100;
$this->assertEquals([], $order->items);
}
public function testFindEagerViaRelation()
{
/** @var TestCase|ActiveRecordTestTrait $this */
$orders = $this->callOrderFind()->with('items')->orderBy('id')->all();
$this->assertEquals(3, count($orders));
$order = $orders[0];
$this->assertEquals(1, $order->id);
$this->assertEquals(2, count($order->items));
$this->assertEquals(1, $order->items[0]->id);
$this->assertEquals(2, $order->items[1]->id);
}
public function testFindNestedRelation()
{
/** @var TestCase|ActiveRecordTestTrait $this */
$customers = $this->callCustomerFind()->with('orders', 'orders.items')->all();
$this->assertEquals(3, count($customers));
$this->assertEquals(1, count($customers[0]->orders));
$this->assertEquals(2, count($customers[1]->orders)); // TODO check is populated
$this->assertEquals(0, count($customers[2]->orders));
$this->assertEquals(2, count($customers[0]->orders[0]->items));
$this->assertEquals(3, count($customers[1]->orders[0]->items));
$this->assertEquals(1, count($customers[1]->orders[1]->items));
}
public function testLink()
{
$orderClass = $this->getOrderClass();
$orderItemClass = $this->getOrderItemClass();
/** @var TestCase|ActiveRecordTestTrait $this */
$customer = $this->callCustomerFind(2);
$this->assertEquals(2, count($customer->orders));
// has many
$order = new $orderClass;
$order->total = 100;
$this->assertTrue($order->isNewRecord);
$customer->link('orders', $order);
$this->afterSave();
$this->assertEquals(3, count($customer->orders));
$this->assertFalse($order->isNewRecord);
$this->assertEquals(3, count($customer->getOrders()->all()));
$this->assertEquals(2, $order->customer_id);
// belongs to
$order = new $orderClass;
$order->total = 100;
$this->assertTrue($order->isNewRecord);
$customer = $this->callCustomerFind(1);
$this->assertNull($order->customer);
$order->link('customer', $customer);
$this->assertFalse($order->isNewRecord);
$this->assertEquals(1, $order->customer_id);
$this->assertEquals(1, $order->customer->primaryKey);
// via model
$order = $this->callOrderFind(1);
$this->assertEquals(2, count($order->items));
$this->assertEquals(2, count($order->orderItems));
$orderItem = $this->callOrderItemFind(['order_id' => 1, 'item_id' => 3]);
$this->assertNull($orderItem);
$item = $this->callItemFind(3);
$order->link('items', $item, ['quantity' => 10, 'subtotal' => 100]);
$this->afterSave();
$this->assertEquals(3, count($order->items));
$this->assertEquals(3, count($order->orderItems));
$orderItem = $this->callOrderItemFind(['order_id' => 1, 'item_id' => 3]);
$this->assertTrue($orderItem instanceof $orderItemClass);
$this->assertEquals(10, $orderItem->quantity);
$this->assertEquals(100, $orderItem->subtotal);
}
public function testUnlink()
{
/** @var TestCase|ActiveRecordTestTrait $this */
// has many
$customer = $this->callCustomerFind(2);
$this->assertEquals(2, count($customer->orders));
$customer->unlink('orders', $customer->orders[1], true);
$this->afterSave();
$this->assertEquals(1, count($customer->orders));
$this->assertNull($this->callOrderFind(3));
// via model
$order = $this->callOrderFind(2);
$this->assertEquals(3, count($order->items));
$this->assertEquals(3, count($order->orderItems));
$order->unlink('items', $order->items[2], true);
$this->afterSave();
$this->assertEquals(2, count($order->items));
$this->assertEquals(2, count($order->orderItems));
}
public static $afterSaveNewRecord;
public static $afterSaveInsert;
public function testInsert()
{
$customerClass = $this->getCustomerClass();
/** @var TestCase|ActiveRecordTestTrait $this */
$customer = new $customerClass;
$customer->email = 'user4@example.com';
$customer->name = 'user4';
$customer->address = 'address4';
$this->assertNull($customer->id);
$this->assertTrue($customer->isNewRecord);
static::$afterSaveNewRecord = null;
static::$afterSaveInsert = null;
$customer->save();
$this->afterSave();
$this->assertEquals(4, $customer->id);
$this->assertFalse(static::$afterSaveNewRecord);
$this->assertTrue(static::$afterSaveInsert);
$this->assertFalse($customer->isNewRecord);
}
public function testUpdate()
{
$customerClass = $this->getCustomerClass();
/** @var TestCase|ActiveRecordTestTrait $this */
// save
$customer = $this->callCustomerFind(2);
$this->assertTrue($customer instanceof $customerClass);
$this->assertEquals('user2', $customer->name);
$this->assertFalse($customer->isNewRecord);
static::$afterSaveNewRecord = null;
static::$afterSaveInsert = null;
$customer->name = 'user2x';
$customer->save();
$this->afterSave();
$this->assertEquals('user2x', $customer->name);
$this->assertFalse($customer->isNewRecord);
$this->assertFalse(static::$afterSaveNewRecord);
$this->assertFalse(static::$afterSaveInsert);
$customer2 = $this->callCustomerFind(2);
$this->assertEquals('user2x', $customer2->name);
// updateAll
$customer = $this->callCustomerFind(3);
$this->assertEquals('user3', $customer->name);
$ret = $customerClass::updateAll(['name' => 'temp'], ['id' => 3]);
$this->afterSave();
$this->assertEquals(1, $ret);
$customer = $this->callCustomerFind(3);
$this->assertEquals('temp', $customer->name);
$ret = $customerClass::updateAll(['name' => 'tempX']);
$this->afterSave();
$this->assertEquals(3, $ret);
$ret = $customerClass::updateAll(['name' => 'temp'], ['name' => 'user6']);
$this->afterSave();
$this->assertEquals(0, $ret);
}
public function testUpdateCounters()
{
$orderItemClass = $this->getOrderItemClass();
/** @var TestCase|ActiveRecordTestTrait $this */
// updateCounters
$pk = ['order_id' => 2, 'item_id' => 4];
$orderItem = $this->callOrderItemFind($pk);
$this->assertEquals(1, $orderItem->quantity);
$ret = $orderItem->updateCounters(['quantity' => -1]);
$this->afterSave();
$this->assertTrue($ret);
$this->assertEquals(0, $orderItem->quantity);
$orderItem = $this->callOrderItemFind($pk);
$this->assertEquals(0, $orderItem->quantity);
// updateAllCounters
$pk = ['order_id' => 1, 'item_id' => 2];
$orderItem = $this->callOrderItemFind($pk);
$this->assertEquals(2, $orderItem->quantity);
$ret = $orderItemClass::updateAllCounters([
'quantity' => 3,
'subtotal' => -10,
], $pk);
$this->afterSave();
$this->assertEquals(1, $ret);
$orderItem = $this->callOrderItemFind($pk);
$this->assertEquals(5, $orderItem->quantity);
$this->assertEquals(30, $orderItem->subtotal);
}
public function testDelete()
{
$customerClass = $this->getCustomerClass();
/** @var TestCase|ActiveRecordTestTrait $this */
// delete
$customer = $this->callCustomerFind(2);
$this->assertTrue($customer instanceof $customerClass);
$this->assertEquals('user2', $customer->name);
$customer->delete();
$this->afterSave();
$customer = $this->callCustomerFind(2);
$this->assertNull($customer);
// deleteAll
$customers = $this->callCustomerFind()->all();
$this->assertEquals(2, count($customers));
$ret = $customerClass::deleteAll();
$this->afterSave();
$this->assertEquals(2, $ret);
$customers = $this->callCustomerFind()->all();
$this->assertEquals(0, count($customers));
$ret = $customerClass::deleteAll();
$this->afterSave();
$this->assertEquals(0, $ret);
}
/**
* Some PDO implementations(e.g. cubrid) do not support boolean values.
* Make sure this does not affect AR layer.
*/
public function testBooleanAttribute()
{
$customerClass = $this->getCustomerClass();
/** @var TestCase|ActiveRecordTestTrait $this */
$customer = new $customerClass();
$customer->name = 'boolean customer';
$customer->email = 'mail@example.com';
$customer->status = true;
$customer->save(false);
$customer->refresh();
$this->assertEquals(1, $customer->status);
$customer->status = false;
$customer->save(false);
$customer->refresh();
$this->assertEquals(0, $customer->status);
$customers = $this->callCustomerFind()->where(['status' => true])->all();
$this->assertEquals(2, count($customers));
$customers = $this->callCustomerFind()->where(['status' => false])->all();
$this->assertEquals(1, count($customers));
}
}
\ No newline at end of file
......@@ -8,6 +8,7 @@ use yiiunit\data\ar\NullValues;
use yiiunit\data\ar\OrderItem;
use yiiunit\data\ar\Order;
use yiiunit\data\ar\Item;
use yiiunit\framework\ar\ActiveRecordTestTrait;
/**
* @group db
......@@ -15,126 +16,57 @@ use yiiunit\data\ar\Item;
*/
class ActiveRecordTest extends DatabaseTestCase
{
use ActiveRecordTestTrait;
protected function setUp()
{
parent::setUp();
ActiveRecord::$db = $this->getConnection();
}
public function testFind()
{
// find one
$result = Customer::find();
$this->assertTrue($result instanceof ActiveQuery);
$customer = $result->one();
$this->assertTrue($customer instanceof Customer);
// find all
$customers = Customer::find()->all();
$this->assertEquals(3, count($customers));
$this->assertTrue($customers[0] instanceof Customer);
$this->assertTrue($customers[1] instanceof Customer);
$this->assertTrue($customers[2] instanceof Customer);
// find by a single primary key
$customer = Customer::find(2);
$this->assertTrue($customer instanceof Customer);
$this->assertEquals('user2', $customer->name);
$customer = Customer::find(5);
$this->assertNull($customer);
// query scalar
$customerName = Customer::find()->where(array('id' => 2))->select('name')->scalar();
$this->assertEquals('user2', $customerName);
// find by column values
$customer = Customer::find(['id' => 2, 'name' => 'user2']);
$this->assertTrue($customer instanceof Customer);
$this->assertEquals('user2', $customer->name);
$customer = Customer::find(['id' => 2, 'name' => 'user1']);
$this->assertNull($customer);
public function callCustomerFind($q = null) { return Customer::find($q); }
public function callOrderFind($q = null) { return Order::find($q); }
public function callOrderItemFind($q = null) { return OrderItem::find($q); }
public function callItemFind($q = null) { return Item::find($q); }
// find by attributes
$customer = Customer::find()->where(['name' => 'user2'])->one();
$this->assertTrue($customer instanceof Customer);
$this->assertEquals(2, $customer->id);
public function getCustomerClass() { return Customer::className(); }
public function getItemClass() { return Item::className(); }
public function getOrderClass() { return Order::className(); }
public function getOrderItemClass() { return OrderItem::className(); }
public function testCustomColumns()
{
// find custom column
$customer = Customer::find()->select(['*', '(status*2) AS status2'])
$customer = $this->callCustomerFind()->select(['*', '(status*2) AS status2'])
->where(['name' => 'user3'])->one();
$this->assertEquals(3, $customer->id);
$this->assertEquals(4, $customer->status2);
}
public function testSatisticalFind()
{
// find count, sum, average, min, max, scalar
$this->assertEquals(3, Customer::find()->count());
$this->assertEquals(2, Customer::find()->where('id=1 OR id=2')->count());
$this->assertEquals(6, Customer::find()->sum('id'));
$this->assertEquals(2, Customer::find()->average('id'));
$this->assertEquals(1, Customer::find()->min('id'));
$this->assertEquals(3, Customer::find()->max('id'));
$this->assertEquals(3, Customer::find()->select('COUNT(*)')->scalar());
// scope
$this->assertEquals(2, Customer::find()->active()->count());
// asArray
$customer = Customer::find()->where('id=2')->asArray()->one();
$this->assertEquals([
'id' => '2',
'email' => 'user2@example.com',
'name' => 'user2',
'address' => 'address2',
'status' => '1',
], $customer);
// indexBy
$customers = Customer::find()->indexBy('name')->orderBy('id')->all();
$this->assertEquals(3, count($customers));
$this->assertTrue($customers['user1'] instanceof Customer);
$this->assertTrue($customers['user2'] instanceof Customer);
$this->assertTrue($customers['user3'] instanceof Customer);
// indexBy callable
$customers = Customer::find()->indexBy(function ($customer) {
return $customer->id . '-' . $customer->name;
})->orderBy('id')->all();
$this->assertEquals(3, count($customers));
$this->assertTrue($customers['1-user1'] instanceof Customer);
$this->assertTrue($customers['2-user2'] instanceof Customer);
$this->assertTrue($customers['3-user3'] instanceof Customer);
$this->assertEquals(3, $this->callCustomerFind()->count());
$this->assertEquals(2, $this->callCustomerFind()->where('id=1 OR id=2')->count());
$this->assertEquals(6, $this->callCustomerFind()->sum('id'));
$this->assertEquals(2, $this->callCustomerFind()->average('id'));
$this->assertEquals(1, $this->callCustomerFind()->min('id'));
$this->assertEquals(3, $this->callCustomerFind()->max('id'));
$this->assertEquals(3, $this->callCustomerFind()->select('COUNT(*)')->scalar());
}
public function testRefresh()
public function testFindScalar()
{
$customer = new Customer();
$this->assertFalse($customer->refresh());
$customer = Customer::find(1);
$customer->name = 'to be refreshed';
$this->assertTrue($customer->refresh());
$this->assertEquals('user1', $customer->name);
// query scalar
$customerName = $this->callCustomerFind()->where(array('id' => 2))->select('name')->scalar();
$this->assertEquals('user2', $customerName);
}
public function testEquals()
public function testFindColumn()
{
$customerA = new Customer();
$customerB = new Customer();
$this->assertFalse($customerA->equals($customerB));
$customerA = new Customer();
$customerB = new Item();
$this->assertFalse($customerA->equals($customerB));
$customerA = Customer::find(1);
$customerB = Customer::find(2);
$this->assertFalse($customerA->equals($customerB));
$customerB = Customer::find(1);
$this->assertTrue($customerA->equals($customerB));
$customerA = Customer::find(1);
$customerB = Item::find(1);
$this->assertFalse($customerA->equals($customerB));
/** @var TestCase|ActiveRecordTestTrait $this */
$this->assertEquals(['user1', 'user2', 'user3'], Customer::find()->select('name')->column());
$this->assertEquals(['user3', 'user2', 'user1'], Customer::find()->orderBy(['name' => SORT_DESC])->select('name')->column());
}
public function testFindBySql()
......@@ -154,67 +86,6 @@ class ActiveRecordTest extends DatabaseTestCase
$this->assertEquals('user2', $customer->name);
}
public function testFindLazy()
{
/** @var Customer $customer */
$customer = Customer::find(2);
$this->assertFalse($customer->isRelationPopulated('orders'));
$orders = $customer->orders;
$this->assertTrue($customer->isRelationPopulated('orders'));
$this->assertEquals(2, count($orders));
$this->assertEquals(1, count($customer->populatedRelations));
/** @var Customer $customer */
$customer = Customer::find(2);
$this->assertFalse($customer->isRelationPopulated('orders'));
$orders = $customer->getOrders()->where('id=3')->all();
$this->assertFalse($customer->isRelationPopulated('orders'));
$this->assertEquals(0, count($customer->populatedRelations));
$this->assertEquals(1, count($orders));
$this->assertEquals(3, $orders[0]->id);
}
public function testFindEager()
{
$customers = Customer::find()->with('orders')->all();
$this->assertEquals(3, count($customers));
$this->assertTrue($customers[0]->isRelationPopulated('orders'));
$this->assertTrue($customers[1]->isRelationPopulated('orders'));
$this->assertEquals(1, count($customers[0]->orders));
$this->assertEquals(2, count($customers[1]->orders));
$customer = Customer::find()->with('orders')->one();
$this->assertTrue($customer->isRelationPopulated('orders'));
$this->assertEquals(1, count($customer->orders));
$this->assertEquals(1, count($customer->populatedRelations));
}
public function testFindLazyVia()
{
/** @var Order $order */
$order = Order::find(1);
$this->assertEquals(1, $order->id);
$this->assertEquals(2, count($order->items));
$this->assertEquals(1, $order->items[0]->id);
$this->assertEquals(2, $order->items[1]->id);
$order = Order::find(1);
$order->id = 100;
$this->assertEquals([], $order->items);
}
public function testFindEagerViaRelation()
{
$orders = Order::find()->with('items')->orderBy('id')->all();
$this->assertEquals(3, count($orders));
$order = $orders[0];
$this->assertEquals(1, $order->id);
$this->assertEquals(2, count($order->items));
$this->assertEquals(1, $order->items[0]->id);
$this->assertEquals(2, $order->items[1]->id);
}
public function testFindLazyViaTable()
{
/** @var Order $order */
......@@ -250,187 +121,6 @@ class ActiveRecordTest extends DatabaseTestCase
$this->assertEquals(2, $order->books[0]->id);
}
public function testFindNestedRelation()
{
$customers = Customer::find()->with('orders', 'orders.items')->all();
$this->assertEquals(3, count($customers));
$this->assertEquals(1, count($customers[0]->orders));
$this->assertEquals(2, count($customers[1]->orders));
$this->assertEquals(0, count($customers[2]->orders));
$this->assertEquals(2, count($customers[0]->orders[0]->items));
$this->assertEquals(3, count($customers[1]->orders[0]->items));
$this->assertEquals(1, count($customers[1]->orders[1]->items));
}
public function testLink()
{
$customer = Customer::find(2);
$this->assertEquals(2, count($customer->orders));
// has many
$order = new Order;
$order->total = 100;
$this->assertTrue($order->isNewRecord);
$customer->link('orders', $order);
$this->assertEquals(3, count($customer->orders));
$this->assertFalse($order->isNewRecord);
$this->assertEquals(3, count($customer->getOrders()->all()));
$this->assertEquals(2, $order->customer_id);
// belongs to
$order = new Order;
$order->total = 100;
$this->assertTrue($order->isNewRecord);
$customer = Customer::find(1);
$this->assertNull($order->customer);
$order->link('customer', $customer);
$this->assertFalse($order->isNewRecord);
$this->assertEquals(1, $order->customer_id);
$this->assertEquals(1, $order->customer->id);
// via table
$order = Order::find(2);
$this->assertEquals(0, count($order->books));
$orderItem = OrderItem::find(['order_id' => 2, 'item_id' => 1]);
$this->assertNull($orderItem);
$item = Item::find(1);
$order->link('books', $item, ['quantity' => 10, 'subtotal' => 100]);
$this->assertEquals(1, count($order->books));
$orderItem = OrderItem::find(['order_id' => 2, 'item_id' => 1]);
$this->assertTrue($orderItem instanceof OrderItem);
$this->assertEquals(10, $orderItem->quantity);
$this->assertEquals(100, $orderItem->subtotal);
// via model
$order = Order::find(1);
$this->assertEquals(2, count($order->items));
$this->assertEquals(2, count($order->orderItems));
$orderItem = OrderItem::find(['order_id' => 1, 'item_id' => 3]);
$this->assertNull($orderItem);
$item = Item::find(3);
$order->link('items', $item, ['quantity' => 10, 'subtotal' => 100]);
$this->assertEquals(3, count($order->items));
$this->assertEquals(3, count($order->orderItems));
$orderItem = OrderItem::find(['order_id' => 1, 'item_id' => 3]);
$this->assertTrue($orderItem instanceof OrderItem);
$this->assertEquals(10, $orderItem->quantity);
$this->assertEquals(100, $orderItem->subtotal);
}
public function testUnlink()
{
// has many
$customer = Customer::find(2);
$this->assertEquals(2, count($customer->orders));
$customer->unlink('orders', $customer->orders[1], true);
$this->assertEquals(1, count($customer->orders));
$this->assertNull(Order::find(3));
// via model
$order = Order::find(2);
$this->assertEquals(3, count($order->items));
$this->assertEquals(3, count($order->orderItems));
$order->unlink('items', $order->items[2], true);
$this->assertEquals(2, count($order->items));
$this->assertEquals(2, count($order->orderItems));
// via table
$order = Order::find(1);
$this->assertEquals(2, count($order->books));
$order->unlink('books', $order->books[1], true);
$this->assertEquals(1, count($order->books));
$this->assertEquals(1, count($order->orderItems));
}
public function testInsert()
{
$customer = new Customer;
$customer->email = 'user4@example.com';
$customer->name = 'user4';
$customer->address = 'address4';
$this->assertNull($customer->id);
$this->assertTrue($customer->isNewRecord);
Customer::$afterSaveNewRecord = null;
Customer::$afterSaveInsert = null;
$customer->save();
$this->assertEquals(4, $customer->id);
$this->assertFalse(Customer::$afterSaveNewRecord);
$this->assertTrue(Customer::$afterSaveInsert);
$this->assertFalse($customer->isNewRecord);
}
public function testUpdate()
{
// save
$customer = Customer::find(2);
$this->assertTrue($customer instanceof Customer);
$this->assertEquals('user2', $customer->name);
$this->assertFalse($customer->isNewRecord);
Customer::$afterSaveNewRecord = null;
Customer::$afterSaveInsert = null;
$customer->name = 'user2x';
$customer->save();
$this->assertEquals('user2x', $customer->name);
$this->assertFalse($customer->isNewRecord);
$this->assertFalse(Customer::$afterSaveNewRecord);
$this->assertFalse(Customer::$afterSaveInsert);
$customer2 = Customer::find(2);
$this->assertEquals('user2x', $customer2->name);
// updateCounters
$pk = ['order_id' => 2, 'item_id' => 4];
$orderItem = OrderItem::find($pk);
$this->assertEquals(1, $orderItem->quantity);
$ret = $orderItem->updateCounters(['quantity' => -1]);
$this->assertTrue($ret);
$this->assertEquals(0, $orderItem->quantity);
$orderItem = OrderItem::find($pk);
$this->assertEquals(0, $orderItem->quantity);
// updateAll
$customer = Customer::find(3);
$this->assertEquals('user3', $customer->name);
$ret = Customer::updateAll(['name' => 'temp'], ['id' => 3]);
$this->assertEquals(1, $ret);
$customer = Customer::find(3);
$this->assertEquals('temp', $customer->name);
// updateCounters
$pk = ['order_id' => 1, 'item_id' => 2];
$orderItem = OrderItem::find($pk);
$this->assertEquals(2, $orderItem->quantity);
$ret = OrderItem::updateAllCounters([
'quantity' => 3,
'subtotal' => -10,
], $pk);
$this->assertEquals(1, $ret);
$orderItem = OrderItem::find($pk);
$this->assertEquals(5, $orderItem->quantity);
$this->assertEquals(30, $orderItem->subtotal);
}
public function testDelete()
{
// delete
$customer = Customer::find(2);
$this->assertTrue($customer instanceof Customer);
$this->assertEquals('user2', $customer->name);
$customer->delete();
$customer = Customer::find(2);
$this->assertNull($customer);
// deleteAll
$customers = Customer::find()->all();
$this->assertEquals(2, count($customers));
$ret = Customer::deleteAll();
$this->assertEquals(2, $ret);
$customers = Customer::find()->all();
$this->assertEquals(0, count($customers));
}
public function testStoreNull()
{
......@@ -501,34 +191,6 @@ class ActiveRecordTest extends DatabaseTestCase
$this->assertTrue($record->var2 === $record->var3);
}
/**
* Some PDO implementations(e.g. cubrid) do not support boolean values.
* Make sure this does not affect AR layer.
*/
public function testBooleanAttribute()
{
$customer = new Customer();
$customer->name = 'boolean customer';
$customer->email = 'mail@example.com';
$customer->status = true;
$customer->save(false);
$customer->refresh();
$this->assertEquals(1, $customer->status);
$customer->status = false;
$customer->save(false);
$customer->refresh();
$this->assertEquals(0, $customer->status);
$customers = Customer::find()->where(['status' => true])->all();
$this->assertEquals(2, count($customers));
$customers = Customer::find()->where(['status' => false])->all();
$this->assertEquals(1, count($customers));
}
public function testIsPrimaryKey()
{
$this->assertFalse(Customer::isPrimaryKey([]));
......
......@@ -4,7 +4,7 @@ namespace yiiunit\framework\elasticsearch;
use yii\elasticsearch\Connection;
use yii\elasticsearch\ActiveQuery;
use yii\helpers\Json;
use yiiunit\framework\ar\ActiveRecordTestTrait;
use yiiunit\data\ar\elasticsearch\ActiveRecord;
use yiiunit\data\ar\elasticsearch\Customer;
use yiiunit\data\ar\elasticsearch\OrderItem;
......@@ -13,6 +13,26 @@ use yiiunit\data\ar\elasticsearch\Item;
class ActiveRecordTest extends ElasticSearchTestCase
{
use ActiveRecordTestTrait;
public function callCustomerFind($q = null) { return Customer::find($q); }
public function callOrderFind($q = null) { return Order::find($q); }
public function callOrderItemFind($q = null) { return OrderItem::find($q); }
public function callItemFind($q = null) { return Item::find($q); }
public function getCustomerClass() { return Customer::className(); }
public function getItemClass() { return Item::className(); }
public function getOrderClass() { return Order::className(); }
public function getOrderItemClass() { return OrderItem::className(); }
/**
* can be overridden to do things after save()
*/
public function afterSave()
{
$this->getConnection()->createCommand()->flushIndex();
}
public function setUp()
{
parent::setUp();
......@@ -110,6 +130,25 @@ class ActiveRecordTest extends ElasticSearchTestCase
$this->assertTrue($customers[1] instanceof Customer);
$this->assertTrue($customers[2] instanceof Customer);
// find all asArray
$customers = Customer::find()->asArray()->all();
$this->assertEquals(3, count($customers));
$this->assertArrayHasKey('primaryKey', $customers[0]);
$this->assertArrayHasKey('name', $customers[0]);
$this->assertArrayHasKey('email', $customers[0]);
$this->assertArrayHasKey('address', $customers[0]);
$this->assertArrayHasKey('status', $customers[0]);
$this->assertArrayHasKey('primaryKey', $customers[1]);
$this->assertArrayHasKey('name', $customers[1]);
$this->assertArrayHasKey('email', $customers[1]);
$this->assertArrayHasKey('address', $customers[1]);
$this->assertArrayHasKey('status', $customers[1]);
$this->assertArrayHasKey('primaryKey', $customers[2]);
$this->assertArrayHasKey('name', $customers[2]);
$this->assertArrayHasKey('email', $customers[2]);
$this->assertArrayHasKey('address', $customers[2]);
$this->assertArrayHasKey('status', $customers[2]);
// find by a single primary key
$customer = Customer::find(2);
$this->assertTrue($customer instanceof Customer);
......@@ -120,12 +159,16 @@ class ActiveRecordTest extends ElasticSearchTestCase
// query scalar
$customerName = Customer::find()->where(['status' => 2])->scalar('name');
$this->assertEquals('user3', $customerName);
$customerName = Customer::find()->where(['status' => 2])->scalar('noname');
$this->assertNull($customerName);
$customerId = Customer::find()->where(['status' => 2])->scalar('primaryKey');
$this->assertEquals(3, $customerId);
// find by column values
$customer = Customer::find(['name' => 'user2']);
$this->assertTrue($customer instanceof Customer);
$this->assertEquals('user2', $customer->name);
$customer = Customer::find(['name' => 'user1', 'id' => 2]);
$customer = Customer::find(['name' => 'user1', 'primaryKey' => 2]);
$this->assertNull($customer);
$customer = Customer::find(['primaryKey' => 5]);
$this->assertNull($customer);
......@@ -137,8 +180,9 @@ class ActiveRecordTest extends ElasticSearchTestCase
$this->assertTrue($customer instanceof Customer);
$this->assertEquals('user2', $customer->name);
// find count, sum, average, min, max, scalar
// find count
$this->assertEquals(3, Customer::find()->count());
$this->assertEquals(2, Customer::find()->where(['or', ['primaryKey' => 1], ['primaryKey' => 2]])->count());
// $this->assertEquals(6, Customer::find()->sum('id'));
// $this->assertEquals(2, Customer::find()->average('id'));
// $this->assertEquals(1, Customer::find()->min('id'));
......@@ -168,14 +212,19 @@ class ActiveRecordTest extends ElasticSearchTestCase
// indexBy callable
$customers = Customer::find()->indexBy(function ($customer) {
return $customer->status . '-' . $customer->name;
// })->orderBy('id')->all();
})->all();
})->orderBy('name')->all();
$this->assertEquals(3, count($customers));
$this->assertTrue($customers['1-user1'] instanceof Customer);
$this->assertTrue($customers['1-user2'] instanceof Customer);
$this->assertTrue($customers['2-user3'] instanceof Customer);
}
public function testGetDb()
{
$this->mockApplication(['components' => ['elasticsearch' => Connection::className()]]);
$this->assertInstanceOf(Connection::className(), ActiveRecord::getDb());
}
public function testGet()
{
$this->assertInstanceOf(Customer::className(), Customer::get(1));
......@@ -199,127 +248,6 @@ class ActiveRecordTest extends ElasticSearchTestCase
$this->assertInstanceOf(Customer::className(), $records[1]);
}
public function testRefresh()
{
$customer = new Customer();
$this->assertFalse($customer->refresh());
$customer = Customer::get(1);
$customer->name = 'to be refreshed';
$this->assertTrue($customer->refresh());
$this->assertEquals('user1', $customer->name);
}
public function testEquals()
{
$customerA = new Customer();
$customerB = new Customer();
$this->assertFalse($customerA->equals($customerB));
$customerA = new Customer();
$customerB = new Item();
$this->assertFalse($customerA->equals($customerB));
$customerA = Customer::find(1);
$customerB = Customer::find(2);
$this->assertFalse($customerA->equals($customerB));
$customerB = Customer::find(1);
$this->assertTrue($customerA->equals($customerB));
$customerA = Customer::find(1);
$customerB = Item::find(1);
$this->assertFalse($customerA->equals($customerB));
}
public function testFindCount()
{
$this->assertEquals(3, Customer::find()->count());
$this->assertEquals(1, Customer::find()->limit(1)->count());
$this->assertEquals(2, Customer::find()->limit(2)->count());
$this->assertEquals(1, Customer::find()->offset(2)->limit(2)->count());
}
public function testFindLimit()
{
// all()
$customers = Customer::find()->all();
$this->assertEquals(3, count($customers));
$customers = Customer::find()->limit(1)->all();
$this->assertEquals(1, count($customers));
$this->assertEquals('user1', $customers[0]->name);
$customers = Customer::find()->limit(1)->offset(1)->all();
$this->assertEquals(1, count($customers));
$this->assertEquals('user2', $customers[0]->name);
$customers = Customer::find()->limit(1)->offset(2)->all();
$this->assertEquals(1, count($customers));
$this->assertEquals('user3', $customers[0]->name);
$customers = Customer::find()->limit(2)->offset(1)->all();
$this->assertEquals(2, count($customers));
$this->assertEquals('user2', $customers[0]->name);
$this->assertEquals('user3', $customers[1]->name);
$customers = Customer::find()->limit(2)->offset(3)->all();
$this->assertEquals(0, count($customers));
// one()
$customer = Customer::find()->one();
$this->assertEquals('user1', $customer->name);
$customer = Customer::find()->offset(0)->one();
$this->assertEquals('user1', $customer->name);
$customer = Customer::find()->offset(1)->one();
$this->assertEquals('user2', $customer->name);
$customer = Customer::find()->offset(2)->one();
$this->assertEquals('user3', $customer->name);
$customer = Customer::find()->offset(3)->one();
$this->assertNull($customer);
}
public function testFindComplexCondition()
{
$this->assertEquals(2, Customer::find()->where(['OR', ['name' => 'user1'], ['name' => 'user2']])->count());
$this->assertEquals(2, count(Customer::find()->where(['OR', ['name' => 'user1'], ['name' => 'user2']])->all()));
$this->assertEquals(2, Customer::find()->where(['name' => ['user1','user2']])->count());
$this->assertEquals(2, count(Customer::find()->where(['name' => ['user1','user2']])->all()));
$this->assertEquals(1, Customer::find()->where(['AND', ['name' => ['user2','user3']], ['BETWEEN', 'status', 2, 4]])->count());
$this->assertEquals(1, count(Customer::find()->where(['AND', ['name' => ['user2','user3']], ['BETWEEN', 'status', 2, 4]])->all()));
}
public function testFindNullValues()
{
$customer = Customer::find(2);
$customer->name = null;
$customer->save(false);
Customer::getDb()->createCommand()->flushIndex('customers');
$result = Customer::find()->where(['name' => null])->all();
$this->assertEquals(1, count($result));
$this->assertEquals(2, reset($result)->primaryKey);
}
public function testFindColumn()
{
$this->assertEquals(['user1', 'user2', 'user3'], Customer::find()->column('name'));
$this->assertEquals(['user3', 'user2', 'user1'], Customer::find()->orderBy(['name' => SORT_DESC])->column('name'));
}
public function testExists()
{
$this->assertTrue(Customer::find()->where(['name' => 'user1'])->exists());
$this->assertFalse(Customer::find()->where(['name' => 'user5'])->exists());
}
public function testFindLazy()
{
/** @var $customer Customer */
......@@ -332,114 +260,18 @@ class ActiveRecordTest extends ElasticSearchTestCase
$this->assertEquals(2, $orders[0]->primaryKey);
}
public function testFindEager()
{
$customers = Customer::find()->with('orders')->all();
$this->assertEquals(3, count($customers));
$this->assertEquals(1, count($customers[0]->orders));
$this->assertEquals(2, count($customers[1]->orders));
}
public function testFindLazyVia()
{
/** @var $order Order */
$order = Order::find(1);
$this->assertEquals(1, $order->primaryKey);
$this->assertEquals(2, count($order->items));
$this->assertEquals(2, $order->items[0]->primaryKey);
$this->assertEquals(1, $order->items[1]->primaryKey);
$order = new Order();
$order->primaryKey = 100;
$this->assertEquals([], $order->items);
}
public function testFindEagerViaRelation()
{
$orders = Order::find()->with('items')->all();
// this test is currently failing randomly because of https://github.com/yiisoft/yii2/issues/1310
$orders = Order::find()->with('items')->orderBy('create_time')->all();
$this->assertEquals(3, count($orders));
$order = $orders[0];
$this->assertEquals(1, $order->primaryKey);
$this->assertEquals(2, count($order->items));
$this->assertEquals(2, $order->items[0]->primaryKey);
$this->assertEquals(1, $order->items[1]->primaryKey);
$this->assertEquals(1, $order->items[0]->primaryKey);
$this->assertEquals(2, $order->items[1]->primaryKey);
}
public function testFindNestedRelation()
{
$customers = Customer::find()->with('orders', 'orders.items')->all();
$this->assertEquals(3, count($customers));
$this->assertEquals(1, count($customers[0]->orders));
$this->assertEquals(2, count($customers[1]->orders));
$this->assertEquals(0, count($customers[2]->orders));
$this->assertEquals(2, count($customers[0]->orders[0]->items));
$this->assertEquals(3, count($customers[1]->orders[0]->items));
$this->assertEquals(1, count($customers[1]->orders[1]->items));
}
public function testLink()
{
$customer = Customer::find(2);
$this->assertEquals(2, count($customer->orders));
// has many
$order = new Order;
$order->total = 100;
$this->assertTrue($order->isNewRecord);
$customer->link('orders', $order);
$this->assertEquals(3, count($customer->orders));
$this->assertFalse($order->isNewRecord);
Customer::getDb()->createCommand()->flushIndex();
$this->assertEquals(3, count($customer->getOrders()->all()));
$this->assertEquals(2, $order->customer_id);
// belongs to
$order = new Order;
$order->total = 100;
$this->assertTrue($order->isNewRecord);
$customer = Customer::find(1);
$this->assertNull($order->customer);
$order->link('customer', $customer);
$this->assertFalse($order->isNewRecord);
$this->assertEquals(1, $order->customer_id);
$this->assertEquals(1, $order->customer->primaryKey);
// via model
$order = Order::find(1);
$this->assertEquals(2, count($order->items));
$this->assertEquals(2, count($order->orderItems));
$orderItem = OrderItem::find(['order_id' => 1, 'item_id' => 3]);
$this->assertNull($orderItem);
$item = Item::find(3);
$order->link('items', $item, ['quantity' => 10, 'subtotal' => 100]);
Customer::getDb()->createCommand()->flushIndex();
$this->assertEquals(3, count($order->items));
$this->assertEquals(3, count($order->orderItems));
$orderItem = OrderItem::find(['order_id' => 1, 'item_id' => 3]);
$this->assertTrue($orderItem instanceof OrderItem);
$this->assertEquals(10, $orderItem->quantity);
$this->assertEquals(100, $orderItem->subtotal);
}
public function testUnlink()
{
// has many
$customer = Customer::find(2);
$this->assertEquals(2, count($customer->orders));
$customer->unlink('orders', $customer->orders[1], true);
Customer::getDb()->createCommand()->flushIndex();
$this->assertEquals(1, count($customer->orders));
$this->assertNull(Order::find(3));
// via model
$order = Order::find(2);
$this->assertEquals(3, count($order->items));
$this->assertEquals(3, count($order->orderItems));
$order->unlink('items', $order->items[2], true);
Customer::getDb()->createCommand()->flushIndex();
$this->assertEquals(2, count($order->items));
$this->assertEquals(2, count($order->orderItems));
}
public function testInsertNoPk()
{
......@@ -451,11 +283,14 @@ class ActiveRecordTest extends ElasticSearchTestCase
$customer->address = 'address4';
$this->assertNull($customer->primaryKey);
$this->assertNull($customer->oldPrimaryKey);
$this->assertTrue($customer->isNewRecord);
$customer->save();
$this->assertNotNull($customer->primaryKey);
$this->assertNotNull($customer->oldPrimaryKey);
$this->assertEquals($customer->primaryKey, $customer->oldPrimaryKey);
$this->assertFalse($customer->isNewRecord);
}
......@@ -475,70 +310,14 @@ class ActiveRecordTest extends ElasticSearchTestCase
$this->assertFalse($customer->isNewRecord);
}
public function testUpdate()
{
// save
$customer = Customer::find(2);
$this->assertTrue($customer instanceof Customer);
$this->assertEquals('user2', $customer->name);
$this->assertFalse($customer->isNewRecord);
$customer->name = 'user2x';
$customer->save();
$this->assertEquals('user2x', $customer->name);
$this->assertFalse($customer->isNewRecord);
$customer2 = Customer::find(2);
$this->assertEquals('user2x', $customer2->name);
// updateAll
$customer = Customer::find(3);
$this->assertEquals('user3', $customer->name);
$ret = Customer::updateAll([
'name' => 'temp',
], ['name' => 'user3']);
$this->assertEquals(1, $ret);
$customer = Customer::find(3);
$this->assertEquals('temp', $customer->name);
$ret = Customer::updateAll(['name' => 'temp']);
$this->assertEquals(3, $ret);
}
public function testUpdatePk()
{
$this->setExpectedException('yii\base\InvalidCallException');
$pk = ['primaryKey' => 2];
$orderItem = Order::find($pk);
$this->assertEquals(2, $orderItem->primaryKey);
$this->setExpectedException('yii\base\InvalidCallException');
$orderItem->primaryKey = 13;
$orderItem->save();
}
public function testDelete()
{
// delete
$customer = Customer::find(2);
$this->assertTrue($customer instanceof Customer);
$this->assertEquals('user2', $customer->name);
$customer->delete();
$customer = Customer::find(2);
$this->assertNull($customer);
Customer::getDb()->createCommand()->flushIndex('customers');
// deleteAll
$customers = Customer::find()->all();
$this->assertEquals(2, count($customers));
$ret = Customer::deleteAll(['name' => ['user1','user3']]);
$this->assertEquals(2, $ret);
Customer::getDb()->createCommand()->flushIndex('customers');
$customers = Customer::find()->all();
$this->assertEquals(0, count($customers));
$ret = Customer::deleteAll();
$this->assertEquals(0, $ret);
}
}
\ No newline at end of file
......@@ -146,6 +146,9 @@ class QueryTest extends ElasticSearchTestCase
}
// TODO test facets
// TODO test complex where() every edge of QueryBuilder
public function testOrder()
{
......
......@@ -9,12 +9,26 @@ use yiiunit\data\ar\redis\Customer;
use yiiunit\data\ar\redis\OrderItem;
use yiiunit\data\ar\redis\Order;
use yiiunit\data\ar\redis\Item;
use yiiunit\framework\ar\ActiveRecordTestTrait;
/**
* @group redis
*/
class ActiveRecordTest extends RedisTestCase
{
use ActiveRecordTestTrait;
public function callCustomerFind($q = null) { return Customer::find($q); }
public function callOrderFind($q = null) { return Order::find($q); }
public function callOrderItemFind($q = null) { return OrderItem::find($q); }
public function callItemFind($q = null) { return Item::find($q); }
public function getCustomerClass() { return Customer::className(); }
public function getItemClass() { return Item::className(); }
public function getOrderClass() { return Order::className(); }
public function getOrderItemClass() { return OrderItem::className(); }
public function setUp()
{
parent::setUp();
......@@ -79,50 +93,21 @@ class ActiveRecordTest extends RedisTestCase
$orderItem->save(false);
}
public function testFind()
public function testFindNullValues()
{
// find one
$result = Customer::find();
$this->assertTrue($result instanceof ActiveQuery);
$customer = $result->one();
$this->assertTrue($customer instanceof Customer);
// find all
$customers = Customer::find()->all();
$this->assertEquals(3, count($customers));
$this->assertTrue($customers[0] instanceof Customer);
$this->assertTrue($customers[1] instanceof Customer);
$this->assertTrue($customers[2] instanceof Customer);
// find by a single primary key
$customer = Customer::find(2);
$this->assertTrue($customer instanceof Customer);
$this->assertEquals('user2', $customer->name);
$customer = Customer::find(5);
$this->assertNull($customer);
$customer = Customer::find(['id' => [5, 6, 1]]);
$this->assertEquals(1, count($customer));
$customer = Customer::find()->where(['id' => [5, 6, 1]])->one();
$this->assertNotNull($customer);
// query scalar
$customerName = Customer::find()->where(['id' => 2])->scalar('name');
$this->assertEquals('user2', $customerName);
// https://github.com/yiisoft/yii2/issues/1311
$this->markTestSkipped('Redis does not store/find null values correctly.');
}
// find by column values
$customer = Customer::find(['id' => 2, 'name' => 'user2']);
$this->assertTrue($customer instanceof Customer);
$this->assertEquals('user2', $customer->name);
$customer = Customer::find(['id' => 2, 'name' => 'user1']);
$this->assertNull($customer);
$customer = Customer::find(['id' => 5]);
$this->assertNull($customer);
public function testBooleanAttribute()
{
// https://github.com/yiisoft/yii2/issues/1311
$this->markTestSkipped('Redis does not store/find boolean values correctly.');
}
// find by attributes
$customer = Customer::find()->where(['name' => 'user2'])->one();
$this->assertTrue($customer instanceof Customer);
$this->assertEquals(2, $customer->id);
public function testSatisticalFind()
{
// find count, sum, average, min, max, scalar
$this->assertEquals(3, Customer::find()->count());
$this->assertEquals(6, Customer::find()->sum('id'));
......@@ -130,68 +115,41 @@ class ActiveRecordTest extends RedisTestCase
$this->assertEquals(1, Customer::find()->min('id'));
$this->assertEquals(3, Customer::find()->max('id'));
// scope
$this->assertEquals(2, Customer::find()->active()->count());
// asArray
$customer = Customer::find()->where(['id' => 2])->asArray()->one();
$this->assertEquals(array(
'id' => '2',
'email' => 'user2@example.com',
'name' => 'user2',
'address' => 'address2',
'status' => '1',
), $customer);
$this->assertEquals(6, OrderItem::find()->count());
$this->assertEquals(7, OrderItem::find()->sum('quantity'));
}
public function testfindIndexBy()
{
$customerClass = $this->getCustomerClass();
/** @var TestCase|ActiveRecordTestTrait $this */
// indexBy
$customers = Customer::find()->indexBy('name')->all();
$customers = $this->callCustomerFind()->indexBy('name')/*->orderBy('id')*/->all();
$this->assertEquals(3, count($customers));
$this->assertTrue($customers['user1'] instanceof Customer);
$this->assertTrue($customers['user2'] instanceof Customer);
$this->assertTrue($customers['user3'] instanceof Customer);
$this->assertTrue($customers['user1'] instanceof $customerClass);
$this->assertTrue($customers['user2'] instanceof $customerClass);
$this->assertTrue($customers['user3'] instanceof $customerClass);
// indexBy callable
$customers = Customer::find()->indexBy(function ($customer) {
$customers = $this->callCustomerFind()->indexBy(function ($customer) {
return $customer->id . '-' . $customer->name;
// })->orderBy('id')->all();
})->all();
})/*->orderBy('id')*/->all(); // TODO this test is duplicated because of missing orderBy support in redis
$this->assertEquals(3, count($customers));
$this->assertTrue($customers['1-user1'] instanceof Customer);
$this->assertTrue($customers['2-user2'] instanceof Customer);
$this->assertTrue($customers['3-user3'] instanceof Customer);
}
public function testRefresh()
{
$customer = new Customer();
$this->assertFalse($customer->refresh());
$customer = Customer::find(1);
$customer->name = 'to be refreshed';
$this->assertTrue($customer->refresh());
$this->assertEquals('user1', $customer->name);
$this->assertTrue($customers['1-user1'] instanceof $customerClass);
$this->assertTrue($customers['2-user2'] instanceof $customerClass);
$this->assertTrue($customers['3-user3'] instanceof $customerClass);
}
public function testEquals()
public function testFindEagerViaRelation()
{
$customerA = new Customer();
$customerB = new Customer();
$this->assertFalse($customerA->equals($customerB));
$customerA = new Customer();
$customerB = new Item();
$this->assertFalse($customerA->equals($customerB));
$customerA = Customer::find(1);
$customerB = Customer::find(2);
$this->assertFalse($customerA->equals($customerB));
$customerB = Customer::find(1);
$this->assertTrue($customerA->equals($customerB));
$customerA = Customer::find(1);
$customerB = Item::find(1);
$this->assertFalse($customerA->equals($customerB));
/** @var TestCase|ActiveRecordTestTrait $this */
$orders = $this->callOrderFind()->with('items')/*->orderBy('id')*/->all(); // TODO this test is duplicated because of missing orderBy support in redis
$this->assertEquals(3, count($orders));
$order = $orders[0];
$this->assertEquals(1, $order->id);
$this->assertEquals(2, count($order->items));
$this->assertEquals(1, $order->items[0]->id);
$this->assertEquals(2, $order->items[1]->id);
}
public function testFindCount()
......@@ -202,266 +160,14 @@ class ActiveRecordTest extends RedisTestCase
$this->assertEquals(1, Customer::find()->offset(2)->limit(2)->count());
}
public function testFindLimit()
{
// all()
$customers = Customer::find()->all();
$this->assertEquals(3, count($customers));
$customers = Customer::find()->limit(1)->all();
$this->assertEquals(1, count($customers));
$this->assertEquals('user1', $customers[0]->name);
$customers = Customer::find()->limit(1)->offset(1)->all();
$this->assertEquals(1, count($customers));
$this->assertEquals('user2', $customers[0]->name);
$customers = Customer::find()->limit(1)->offset(2)->all();
$this->assertEquals(1, count($customers));
$this->assertEquals('user3', $customers[0]->name);
$customers = Customer::find()->limit(2)->offset(1)->all();
$this->assertEquals(2, count($customers));
$this->assertEquals('user2', $customers[0]->name);
$this->assertEquals('user3', $customers[1]->name);
$customers = Customer::find()->limit(2)->offset(3)->all();
$this->assertEquals(0, count($customers));
// one()
$customer = Customer::find()->one();
$this->assertEquals('user1', $customer->name);
$customer = Customer::find()->offset(0)->one();
$this->assertEquals('user1', $customer->name);
$customer = Customer::find()->offset(1)->one();
$this->assertEquals('user2', $customer->name);
$customer = Customer::find()->offset(2)->one();
$this->assertEquals('user3', $customer->name);
$customer = Customer::find()->offset(3)->one();
$this->assertNull($customer);
}
public function testFindComplexCondition()
{
$this->assertEquals(2, Customer::find()->where(['OR', ['id' => 1], ['id' => 2]])->count());
$this->assertEquals(2, count(Customer::find()->where(['OR', ['id' => 1], ['id' => 2]])->all()));
$this->assertEquals(2, Customer::find()->where(['id' => [1,2]])->count());
$this->assertEquals(2, count(Customer::find()->where(['id' => [1,2]])->all()));
$this->assertEquals(1, Customer::find()->where(['AND', ['id' => [2,3]], ['BETWEEN', 'status', 2, 4]])->count());
$this->assertEquals(1, count(Customer::find()->where(['AND', ['id' => [2,3]], ['BETWEEN', 'status', 2, 4]])->all()));
}
public function testSum()
{
$this->assertEquals(6, OrderItem::find()->count());
$this->assertEquals(7, OrderItem::find()->sum('quantity'));
}
public function testFindColumn()
{
$this->assertEquals(['user1', 'user2', 'user3'], Customer::find()->column('name'));
// TODO $this->assertEquals(['user3', 'user2', 'user1'], Customer::find()->orderBy(['name' => SORT_DESC])->column('name'));
}
public function testExists()
{
$this->assertTrue(Customer::find()->where(['id' => 2])->exists());
$this->assertFalse(Customer::find()->where(['id' => 5])->exists());
}
public function testFindLazy()
{
/** @var $customer Customer */
$customer = Customer::find(2);
$orders = $customer->orders;
$this->assertEquals(2, count($orders));
$orders = $customer->getOrders()->where(['id' => 3])->all();
$this->assertEquals(1, count($orders));
$this->assertEquals(3, $orders[0]->id);
}
public function testFindEager()
{
$customers = Customer::find()->with('orders')->all();
$this->assertEquals(3, count($customers));
$this->assertEquals(1, count($customers[0]->orders));
$this->assertEquals(2, count($customers[1]->orders));
}
public function testFindLazyVia()
{
/** @var $order Order */
$order = Order::find(1);
$this->assertEquals(1, $order->id);
$this->assertEquals(2, count($order->items));
$this->assertEquals(1, $order->items[0]->id);
$this->assertEquals(2, $order->items[1]->id);
$order = Order::find(1);
$order->id = 100;
$this->assertEquals([], $order->items);
}
public function testFindEagerViaRelation()
{
$orders = Order::find()->with('items')->all();
$this->assertEquals(3, count($orders));
$order = $orders[0];
$this->assertEquals(1, $order->id);
$this->assertEquals(2, count($order->items));
$this->assertEquals(1, $order->items[0]->id);
$this->assertEquals(2, $order->items[1]->id);
}
public function testFindNestedRelation()
{
$customers = Customer::find()->with('orders', 'orders.items')->all();
$this->assertEquals(3, count($customers));
$this->assertEquals(1, count($customers[0]->orders));
$this->assertEquals(2, count($customers[1]->orders));
$this->assertEquals(0, count($customers[2]->orders));
$this->assertEquals(2, count($customers[0]->orders[0]->items));
$this->assertEquals(3, count($customers[1]->orders[0]->items));
$this->assertEquals(1, count($customers[1]->orders[1]->items));
}
public function testLink()
{
$customer = Customer::find(2);
$this->assertEquals(2, count($customer->orders));
// has many
$order = new Order;
$order->total = 100;
$this->assertTrue($order->isNewRecord);
$customer->link('orders', $order);
$this->assertEquals(3, count($customer->orders));
$this->assertFalse($order->isNewRecord);
$this->assertEquals(3, count($customer->getOrders()->all()));
$this->assertEquals(2, $order->customer_id);
// belongs to
$order = new Order;
$order->total = 100;
$this->assertTrue($order->isNewRecord);
$customer = Customer::find(1);
$this->assertNull($order->customer);
$order->link('customer', $customer);
$this->assertFalse($order->isNewRecord);
$this->assertEquals(1, $order->customer_id);
$this->assertEquals(1, $order->customer->id);
// via model
$order = Order::find(1);
$this->assertEquals(2, count($order->items));
$this->assertEquals(2, count($order->orderItems));
$orderItem = OrderItem::find(['order_id' => 1, 'item_id' => 3]);
$this->assertNull($orderItem);
$item = Item::find(3);
$order->link('items', $item, ['quantity' => 10, 'subtotal' => 100]);
$this->assertEquals(3, count($order->items));
$this->assertEquals(3, count($order->orderItems));
$orderItem = OrderItem::find(['order_id' => 1, 'item_id' => 3]);
$this->assertTrue($orderItem instanceof OrderItem);
$this->assertEquals(10, $orderItem->quantity);
$this->assertEquals(100, $orderItem->subtotal);
}
public function testUnlink()
{
// has many
$customer = Customer::find(2);
$this->assertEquals(2, count($customer->orders));
$customer->unlink('orders', $customer->orders[1], true);
$this->assertEquals(1, count($customer->orders));
$this->assertNull(Order::find(3));
// via model
$order = Order::find(2);
$this->assertEquals(3, count($order->items));
$this->assertEquals(3, count($order->orderItems));
$order->unlink('items', $order->items[2], true);
$this->assertEquals(2, count($order->items));
$this->assertEquals(2, count($order->orderItems));
}
public function testInsert()
{
$customer = new Customer;
$customer->email = 'user4@example.com';
$customer->name = 'user4';
$customer->address = 'address4';
$this->assertNull($customer->id);
$this->assertTrue($customer->isNewRecord);
$customer->save();
$this->assertEquals(4, $customer->id);
$this->assertFalse($customer->isNewRecord);
}
// TODO test serial column incr
public function testUpdate()
{
// save
$customer = Customer::find(2);
$this->assertTrue($customer instanceof Customer);
$this->assertEquals('user2', $customer->name);
$this->assertFalse($customer->isNewRecord);
$customer->name = 'user2x';
$customer->save();
$this->assertEquals('user2x', $customer->name);
$this->assertFalse($customer->isNewRecord);
$customer2 = Customer::find(2);
$this->assertEquals('user2x', $customer2->name);
// updateAll
$customer = Customer::find(3);
$this->assertEquals('user3', $customer->name);
$ret = Customer::updateAll(array(
'name' => 'temp',
), ['id' => 3]);
$this->assertEquals(1, $ret);
$customer = Customer::find(3);
$this->assertEquals('temp', $customer->name);
}
public function testUpdateCounters()
{
// updateCounters
$pk = ['order_id' => 2, 'item_id' => 4];
$orderItem = OrderItem::find($pk);
$this->assertEquals(1, $orderItem->quantity);
$ret = $orderItem->updateCounters(['quantity' => -1]);
$this->assertTrue($ret);
$this->assertEquals(0, $orderItem->quantity);
$orderItem = OrderItem::find($pk);
$this->assertEquals(0, $orderItem->quantity);
// updateAllCounters
$pk = ['order_id' => 1, 'item_id' => 2];
$orderItem = OrderItem::find($pk);
$this->assertEquals(2, $orderItem->quantity);
$ret = OrderItem::updateAllCounters(array(
'quantity' => 3,
'subtotal' => -10,
), $pk);
$this->assertEquals(1, $ret);
$orderItem = OrderItem::find($pk);
$this->assertEquals(5, $orderItem->quantity);
$this->assertEquals(30, $orderItem->subtotal);
}
public function testUpdatePk()
{
// updateCounters
......@@ -477,23 +183,4 @@ class ActiveRecordTest extends RedisTestCase
$this->assertNull(OrderItem::find($pk));
$this->assertNotNull(OrderItem::find(['order_id' => 2, 'item_id' => 10]));
}
public function testDelete()
{
// delete
$customer = Customer::find(2);
$this->assertTrue($customer instanceof Customer);
$this->assertEquals('user2', $customer->name);
$customer->delete();
$customer = Customer::find(2);
$this->assertNull($customer);
// deleteAll
$customers = Customer::find()->all();
$this->assertEquals(2, count($customers));
$ret = Customer::deleteAll();
$this->assertEquals(2, $ret);
$customers = Customer::find()->all();
$this->assertEquals(0, count($customers));
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment