improved unit tests

This commit is contained in:
alexander.makarow
2011-02-18 15:25:38 +00:00
parent 29cb0059c7
commit 1f757cbf53
82 changed files with 10416 additions and 0 deletions

63
tests/TestApplication.php Normal file
View File

@@ -0,0 +1,63 @@
<?php
class TestApplication extends CWebApplication
{
public function __construct($config=null)
{
Yii::setApplication(null);
clearstatcache();
parent::__construct($config);
}
public function reset()
{
$this->removeDirectory($this->getRuntimePath());
$this->removeDirectory($this->getAssetPath());
}
protected function removeDirectory($path)
{
if(is_dir($path) && ($folder=@opendir($path))!==false)
{
while($entry=@readdir($folder))
{
if($entry[0]==='.')
continue;
$p=$path.DIRECTORY_SEPARATOR.$entry;
if(is_dir($p))
$this->removeDirectory($p);
@unlink($p);
}
@closedir($folder);
}
}
public function getAssetPath()
{
return dirname(__FILE__).DIRECTORY_SEPARATOR.'assets';
}
public function getRuntimePath()
{
return dirname(__FILE__).DIRECTORY_SEPARATOR.'runtime';
}
public function getBasePath()
{
return dirname(__FILE__);
}
public function setBasePath($value)
{
}
public function loadGlobalState()
{
parent::loadGlobalState();
}
public function saveGlobalState()
{
parent::saveGlobalState();
}
}

19
tests/bootstrap.php Normal file
View File

@@ -0,0 +1,19 @@
<?php
define('YII_ENABLE_EXCEPTION_HANDLER',false);
define('YII_ENABLE_ERROR_HANDLER',false);
$_SERVER['SCRIPT_NAME']='/'.basename(__FILE__);
$_SERVER['SCRIPT_FILENAME']=__FILE__;
require_once(dirname(__FILE__).'/../framework/yii.php');
require_once(dirname(__FILE__).'/TestApplication.php');
require_once('PHPUnit/Framework/TestCase.php');
class CTestCase extends PHPUnit_Framework_TestCase
{
}
class CActiveRecordTestCase extends CTestCase
{
}

View File

@@ -0,0 +1,13 @@
<?php
class CApplicationComponentTest extends CTestCase {
public function testInitialization() {
$c = $this->getMockForAbstractClass('CApplicationComponent',array('init','getIsInitialized'),'',NULL);
$c->expects($this->any())
->method('getIsInitialized')
->will($this->returnValue(FALSE));
$this->assertFalse($c->getIsInitialized());
$c->init();
$this->assertTrue($c->getIsInitialized());
}
}

View File

@@ -0,0 +1,51 @@
<?php
require_once dirname(__FILE__) . '/NewComponent.php';
require_once dirname(__FILE__) . '/NewBehavior.php';
require_once dirname(__FILE__) . '/NewBeforeValidateBehavior.php';
require_once dirname(__FILE__) . '/NewFormModel.php';
class CBehaviorTest extends CTestCase {
public function testAttachBehavior() {
$component=new NewComponent;
$component->attachBehavior('a',new NewBehavior);
$this->assertFalse($component->behaviorCalled);
$this->assertFalse(method_exists($component,'test'));
$this->assertEquals(2,$component->test());
$this->assertTrue($component->behaviorCalled);
$this->setExpectedException('CException');
$component->test2();
}
public function testDisableBehaviors(){
$component=new NewComponent;
$component->attachBehavior('a',new NewBehavior);
$component->disableBehaviors();
$this->setExpectedException('CException');
// test should not be called since behavior is disabled
echo $component->test();
}
/**
* Since disableBehaviors() was called, validate() should not call beforeValidate() from behavior.
* @return void
*/
public function testDisableBehaviorsAndModels(){
$model = new NewFormModel();
$model->disableBehaviors();
$model->validate();
}
/**
* enableBehaviors() should work after disableBehaviors().
* @return void
*/
public function testDisableAndEnableBehaviorsAndModels(){
$this->setExpectedException('NewBeforeValidateBehaviorException');
$model = new NewFormModel();
$model->disableBehaviors();
$model->enableBehaviors();
$model->validate();
}
}

View File

@@ -0,0 +1,223 @@
<?php
require_once dirname(__FILE__) . '/NewComponent.php';
require_once dirname(__FILE__) . '/NewBehavior.php';
function globalEventHandler($event)
{
$event->sender->eventHandled=true;
}
function globalEventHandler2($event)
{
$event->sender->eventHandled=true;
$event->handled=true;
}
class CComponentTest extends CTestCase
{
protected $component;
public function setUp()
{
$this->component = new NewComponent();
}
public function tearDown()
{
$this->component = null;
}
public function testHasProperty()
{
$this->assertTrue($this->component->hasProperty('Text'), "Component hasn't property Text");
$this->assertTrue($this->component->hasProperty('text'), "Component hasn't property text");
$this->assertFalse($this->component->hasProperty('Caption'), "Component as property Caption");
}
public function testCanGetProperty()
{
$this->assertTrue($this->component->canGetProperty('Text'));
$this->assertTrue($this->component->canGetProperty('text'));
$this->assertFalse($this->component->canGetProperty('Caption'));
}
public function testCanSetProperty()
{
$this->assertTrue($this->component->canSetProperty('Text'));
$this->assertTrue($this->component->canSetProperty('text'));
$this->assertFalse($this->component->canSetProperty('Caption'));
}
public function testGetProperty()
{
$this->assertTrue('default'===$this->component->Text);
$this->setExpectedException('CException');
$value2=$this->component->Caption;
}
public function testSetProperty()
{
$value='new value';
$this->component->Text=$value;
$text=$this->component->Text;
$this->assertTrue($value===$this->component->Text);
$this->setExpectedException('CException');
$this->component->NewMember=$value;
}
public function testIsset()
{
$this->assertTrue(isset($this->component->Text));
$this->assertTrue(!empty($this->component->Text));
unset($this->component->Text);
$this->assertFalse(isset($this->component->Text));
$this->assertFalse(!empty($this->component->Text));
$this->component->Text='';
$this->assertTrue(isset($this->component->Text));
$this->assertTrue(empty($this->component->Text));
}
public function testHasEvent()
{
$this->assertTrue($this->component->hasEvent('OnMyEvent'));
$this->assertTrue($this->component->hasEvent('onmyevent'));
$this->assertFalse($this->component->hasEvent('onYourEvent'));
}
public function testHasEventHandler()
{
$this->assertFalse($this->component->hasEventHandler('OnMyEvent'));
$this->component->attachEventHandler('OnMyEvent','foo');
$this->assertTrue($this->component->hasEventHandler('OnMyEvent'));
}
public function testGetEventHandlers()
{
$list=$this->component->getEventHandlers('OnMyEvent');
$this->assertEquals($list->getCount(),0);
$this->component->attachEventHandler('OnMyEvent','foo');
$this->assertEquals($list->getCount(),1);
$this->setExpectedException('CException');
$list=$this->component->getEventHandlers('YourEvent');
}
public function testAttachEventHandler()
{
$this->component->attachEventHandler('OnMyEvent','foo');
$this->assertTrue($this->component->getEventHandlers('OnMyEvent')->getCount()===1);
$this->setExpectedException('CException');
$this->component->attachEventHandler('YourEvent','foo');
}
public function testDettachEventHandler()
{
$this->component->attachEventHandler('OnMyEvent','foo');
$this->component->attachEventHandler('OnMyEvent',array($this->component,'myEventHandler'));
$this->assertEquals($this->component->getEventHandlers('OnMyEvent')->getCount(),2);
$this->assertTrue($this->component->detachEventHandler('OnMyEvent','foo'));
$this->assertEquals($this->component->getEventHandlers('OnMyEvent')->getCount(),1);
$this->assertFalse($this->component->detachEventHandler('OnMyEvent','foo'));
$this->assertEquals($this->component->getEventHandlers('OnMyEvent')->getCount(),1);
$this->assertTrue($this->component->detachEventHandler('OnMyEvent',array($this->component,'myEventHandler')));
$this->assertEquals($this->component->getEventHandlers('OnMyEvent')->getCount(),0);
$this->assertFalse($this->component->detachEventHandler('OnMyEvent','foo'));
}
public function testRaiseEvent()
{
$this->component->attachEventHandler('OnMyEvent',array($this->component,'myEventHandler'));
$this->assertFalse($this->component->eventHandled);
$this->component->raiseEvent('OnMyEvent',new CEvent($this));
$this->assertTrue($this->component->eventHandled);
//$this->setExpectedException('CException');
//$this->component->raiseEvent('OnUnknown',new CEvent($this));
}
public function testEventAccessor()
{
$component=new NewComponent;
$this->assertEquals($component->onMyEvent->getCount(),0);
$component->onMyEvent='globalEventHandler';
$component->onMyEvent=array($this->component,'myEventHandler');
$this->assertEquals($component->onMyEvent->getCount(),2);
$this->assertFalse($component->eventHandled);
$this->assertFalse($this->component->eventHandled);
$component->onMyEvent();
$this->assertTrue($component->eventHandled);
$this->assertTrue($this->component->eventHandled);
}
public function testStopEvent()
{
$component=new NewComponent;
$component->onMyEvent='globalEventHandler2';
$component->onMyEvent=array($this->component,'myEventHandler');
$component->onMyEvent();
$this->assertTrue($component->eventHandled);
$this->assertFalse($this->component->eventHandled);
}
public function testInvalidHandler1()
{
$this->component->onMyEvent=array(1,2,3);
$this->setExpectedException('CException');
$this->component->onMyEvent();
}
public function testInvalidHandler2()
{
$this->component->onMyEvent=array($this->component,'nullHandler');
$this->setExpectedException('CException');
$this->component->onMyEvent();
}
public function testDetachBehavior() {
$component=new NewComponent;
$behavior = new NewBehavior;
$component->attachBehavior('a',$behavior);
$this->assertSame($behavior,$component->detachBehavior('a'));
}
public function testDetachingBehaviors() {
$component=new NewComponent;
$behavior = new NewBehavior;
$component->attachBehavior('a',$behavior);
$component->detachBehaviors();
$this->setExpectedException('CException');
$component->test();
}
public function testEnablingBehavior() {
$component=new NewComponent;
$behavior = new NewBehavior;
$component->attachBehavior('a',$behavior);
$component->disableBehavior('a');
$this->assertFalse($behavior->getEnabled());
$component->enableBehavior('a');
$this->assertTrue($behavior->getEnabled());
}
public function testEnablingBehaviors() {
$component=new NewComponent;
$behavior = new NewBehavior;
$component->attachBehavior('a',$behavior);
$component->disableBehaviors();
$this->assertFalse($behavior->getEnabled());
$component->enableBehaviors();
$this->assertTrue($behavior->getEnabled());
}
public function testAsa() {
$component=new NewComponent;
$behavior = new NewBehavior;
$component->attachBehavior('a',$behavior);
$this->assertSame($behavior,$component->asa('a'));
}
public function testEvaluateExpression() {
$component = new NewComponent;
$this->assertEquals('Hello world',$component->evaluateExpression('"Hello $who"',array('who' => 'world')));
$this->assertEquals('Hello world',$component->evaluateExpression(array($component,'exprEvaluator'),array('who' => 'world')));
}
}

View File

@@ -0,0 +1,54 @@
<?php
class MyRoute extends CLogRoute
{
public $logCollected=false;
public $property=1;
protected function processLogs($logs)
{
$this->logCollected=true;
$this->property+=count($logs);
}
}
class CLogRouterTest extends CTestCase
{
public function testRoutes()
{
$app=new TestApplication;
$router=new CLogRouter;
$this->assertEquals(count($router->routes),0);
$router->routes=array(
array(
'class'=>'MyRoute',
'property'=>2,
),
array(
'class'=>'MyRoute',
'property'=>3,
),
);
$router->init($app);
$this->assertEquals(count($router->routes),2);
$route1=$router->routes[0];
$this->assertFalse($route1->logCollected);
$this->assertEquals($route1->property,2);
$route2=$router->routes[1];
$this->assertFalse($route2->logCollected);
$this->assertEquals($route2->property,3);
$logger=Yii::getLogger();
$logger->log('message1','level1','category1');
$logger->log('message2','level2','category2');
$logger->log('message3','level3','category3');
$app->onEndRequest(new CEvent($this));
$this->assertTrue($route1->logCollected);
$this->assertTrue($route1->property>2);
$this->assertTrue($route2->logCollected);
$this->assertTrue($route2->property>3);
}
}

View File

@@ -0,0 +1,49 @@
<?php
class CLoggerTest extends CTestCase
{
public function testLog()
{
$logger=new CLogger;
$logger->log('something','debug','application.test');
}
public function testGetLogs()
{
$logger=new CLogger();
$logs=array(
array('message1','debug','application.pages'),
array('message2','info','application.config'),
array('message3','info','application.pages'),
);
foreach($logs as $log)
$logger->log($log[0],$log[1],$log[2]);
$l=$logger->getLogs('debug');
$this->assertTrue($logs[0]===array_slice($l[0],0,3));
$l=$logger->getLogs('debug , Info');
$this->assertTrue($logs[0]===array_slice($l[0],0,3));
$this->assertTrue($logs[1]===array_slice($l[1],0,3));
$this->assertTrue($logs[2]===array_slice($l[2],0,3));
$l=$logger->getLogs('','application.config');
$this->assertTrue($logs[1]===array_slice($l[0],0,3));
$l=$logger->getLogs('','application.*');
$this->assertTrue($logs[0]===array_slice($l[0],0,3));
$this->assertTrue($logs[1]===array_slice($l[1],0,3));
$this->assertTrue($logs[2]===array_slice($l[2],0,3));
$l=$logger->getLogs('','application.config , Application.pages');
$this->assertTrue($logs[0]===array_slice($l[0],0,3));
$this->assertTrue($logs[1]===array_slice($l[1],0,3));
$this->assertTrue($logs[2]===array_slice($l[2],0,3));
$l=$logger->getLogs('info','application.config');
$this->assertTrue($logs[1]===array_slice($l[0],0,3));
$l=$logger->getLogs('info,debug','application.config');
$this->assertTrue($logs[1]===array_slice($l[0],0,3));
}
}

View File

@@ -0,0 +1,122 @@
<?php
require_once dirname(__FILE__).'/NewModel.php';
class CModelTest extends CTestCase
{
public function testValidate()
{
$model=new NewModel;
$this->assertFalse($model->validate());
$model->attr1=4;
$this->assertTrue($model->validate());
$model->attr1=6;
$this->assertFalse($model->validate());
$model->attr2=6;
$this->assertFalse($model->validate());
$model->attr1=4;
$this->assertFalse($model->validate());
$model->attr2=4;
$this->assertTrue($model->validate());
}
function testBeforeValidate(){
$model=new NewModel;
$model->attr1=4;
$this->assertTrue($model->validate());
$model->onBeforeValidate = array($this, 'beforeValidate');
$this->assertFalse($model->validate());
}
function beforeValidate($event){
$event->isValid = false;
}
function testIsAttributeRequired(){
$model=new NewModel;
$this->assertTrue($model->isAttributeRequired('attr1'));
$this->assertFalse($model->isAttributeRequired('attr2'));
}
function testIsAttributeSafe(){
$model=new NewModel;
$this->assertTrue($model->isAttributeSafe('attr1'));
$this->assertFalse($model->isAttributeSafe('attr3'));
$this->assertFalse($model->isAttributeSafe('attr4'));
}
function testGetSafeAttributeNames(){
$model=new NewModel;
$safeAttributes = $model->getSafeAttributeNames();
$this->assertContains('attr2', $safeAttributes);
$this->assertContains('attr1', $safeAttributes);
}
public function testModifyValidators()
{
$model=new NewModel;
$model->attr1=2;
$model->attr2=2;
$this->assertTrue($model->validate());
$model->validatorList->insertAt(0,CValidator::createValidator('numerical',$model,'attr1,attr2',array('min'=>3)));
$this->assertFalse($model->validate());
$model->attr1=6;
$model->attr2=6;
$this->assertFalse($model->validate());
$model->attr1=4;
$model->attr2=4;
$this->assertTrue($model->validate());
$model=new NewModel;
$model->attr1=3;
$model->validatorList->add(CValidator::createValidator('required',$model,'attr2',array()));
$this->assertFalse($model->validate());
$model->attr2=3;
$this->assertTrue($model->validate());
}
function testErrors(){
$model=new NewModel;
$model->attr1=3;
$model->validatorList->add(CValidator::createValidator('required',$model,'attr2',array()));
$model->validatorList->add(CValidator::createValidator('required',$model,'attr4',array()));
$model->validate();
$this->assertTrue($model->hasErrors());
$this->assertTrue($model->hasErrors('attr2'));
$this->assertFalse($model->hasErrors('attr1'));
$model->clearErrors('attr2');
$this->assertFalse($model->hasErrors('attr2'));
$model->clearErrors();
$this->assertFalse($model->hasErrors());
}
function testGetAttributes(){
$model = new NewModel();
$model->attr1 = 1;
$model->attr2 = 2;
$attributes = $model->getAttributes();
$this->assertEquals(1, $attributes['attr1']);
$this->assertEquals(2, $attributes['attr2']);
$attributes = $model->getAttributes(array('attr1', 'non_existing'));
$this->assertEquals(1, $attributes['attr1']);
$this->assertEquals(null, $attributes['non_existing']);
}
function testUnsetAttributes(){
$model = new NewModel();
$model->attr1 = 1;
$model->attr2 = 2;
$model->unsetAttributes(array('attr1'));
$this->assertEquals(null, $model->attr1);
$this->assertEquals(2, $model->attr2);
$model->unsetAttributes();
$this->assertEquals(null, $model->attr1);
$this->assertEquals(null, $model->attr2);
}
}

View File

@@ -0,0 +1,95 @@
<?php
require_once dirname(__FILE__) . '/NewModule.php';
require_once dirname(__FILE__) . '/NewApplicationComponent.php';
class CModuleTest extends CTestCase {
protected $parent;
protected $mod;
protected $d;
public function setUp() {
$this->parent = new NewModule('root',NULL);
$this->mod = new NewModule('foo',$this->parent);
$this->d = dirname(__FILE__);
}
public function tearDown() {
unset($this->parent);
unset($this->mod);
}
public function testGetId() {
$this->assertEquals('foo',$this->mod->getId());
}
public function testSetId() {
$this->mod->setId('bar');
$this->assertEquals('bar',$this->mod->getId());
}
public function testSetBasePath() {
$d = dirname($this->d.'/..');
$this->mod->setBasePath($d);
$this->assertEquals($d,$this->mod->getBasePath());
}
public function testGetBasePath() {
$this->assertEquals($this->d,$this->mod->getBasePath());
}
public function testGetParams() {
$expected = new CAttributeCollection;
$expected->caseSensitive = TRUE;
$this->assertEquals($expected,$this->mod->getParams());
}
public function testSetParams() {
$expected = array('foo' => 'bar');
$this->mod->setParams($expected);
$this->assertEquals($expected,$this->mod->getParams()->toArray());
}
public function testGetModulePath() {
$expected = $this->d.DIRECTORY_SEPARATOR.'modules';
$this->assertEquals($expected,$this->mod->getModulePath());
}
public function testSetModulePath() {
$this->mod->setModulePath($this->d);
$this->assertEquals($this->d,$this->mod->getModulePath());
}
public function testGetParentModule() {
$this->assertSame($this->parent,$this->mod->getParentModule());
}
/**
* @depends testGetId
*/
public function testGetModule() {
$p = $this->parent;
$p->setModulePath($this->d);
$p->setModules(array('foo' => array('class' => 'NewModule')));
$this->assertEquals('root/foo',$p->getModule('foo')->getId());
}
public function testGetModules() {
$p = $this->parent;
$p->setModulePath($this->d);
$expected = array('foo' => array('class' => 'NewModule'),'bar');
$p->setModules($expected);
$expected['bar'] = array('class' => 'bar.BarModule');
unset($expected[0]);
$this->assertEquals($expected,$p->getModules());
}
public function testGetComponents() {
$c = new NewApplicationComponent;
$this->mod->setComponent('foo',$c);
$this->assertSame(array('foo' => $c),$this->mod->getComponents());
}
public function testSetComponents() {
$expected = array('foo' => new NewApplicationComponent);
$this->mod->setComponents($expected);
$this->assertSame($expected,$this->mod->getComponents());
}
public function testSetComponentsViaConfig() {
$this->mod = new NewModule('foo',$this->parent,array(
'components' => array(
'bar' => array('class' => 'NewApplicationComponent')
)
));
$this->assertEquals('hello world',$this->mod->bar->getText('hello world'));
}
public function testSetAliases() {
$this->mod->setAliases(array('modules' => $this->d));
$this->assertEquals($this->d,Yii::getPathOfAlias('modules'));
}
}

View File

@@ -0,0 +1,138 @@
<?php
class TextAlign extends CEnumerable
{
const Left='Left';
const Right='Right';
}
class CPropertyValueTest extends CTestCase
{
public function testEnsureBoolean()
{
$entries=array
(
array(true,true),
array(false,false),
array(null,false),
array(0,false),
array(1,true),
array(-1,true),
array(2.1,true),
array('',false),
array('abc',false),
array('0',false),
array('1',true),
array('123',true),
array('false',false),
array('true',true),
array('tRue',true),
array(array(),false),
array(array(0),true),
array(array(1),true),
);
foreach($entries as $index=>$entry)
$this->assertTrue(CPropertyValue::ensureBoolean($entry[0])===$entry[1],
"Comparison $index: {$entry[0]}=={$entry[1]}");
}
public function testEnsureString()
{
$entries=array
(
array('',''),
array('abc','abc'),
array(null,''),
array(0,'0'),
array(1,'1'),
array(-1.1,'-1.1'),
array(true,'true'),
array(false,'false'),
array(array(),'Array'),
array(array(0),'Array'),
);
foreach($entries as $index=>$entry)
$this->assertTrue(CPropertyValue::ensureString($entry[0])===$entry[1],
"Comparison $index: {$entry[0]}=={$entry[1]}");
}
public function testEnsureInteger()
{
$entries=array
(
array(123,123),
array(1.23,1),
array(null,0),
array('',0),
array('abc',0),
array('123',123),
array('1.23',1),
array(' 1.23',1),
array(' 1.23abc',1),
array('abc1.23abc',0),
array(true,1),
array(false,0),
array(array(),0),
array(array(0),1),
);
foreach($entries as $index=>$entry)
$this->assertTrue(CPropertyValue::ensureInteger($entry[0])===$entry[1],
"Comparison $index: {$entry[0]}=={$entry[1]}");
}
public function testEnsureFloat()
{
$entries=array
(
array(123,123.0),
array(1.23,1.23),
array(null,0.0),
array('',0.0),
array('abc',0.0),
array('123',123.0),
array('1.23',1.23),
array(' 1.23',1.23),
array(' 1.23abc',1.23),
array('abc1.23abc',0.0),
array(true,1.0),
array(false,0.0),
array(array(),0.0),
array(array(0),1.0),
);
foreach($entries as $index=>$entry)
$this->assertTrue(CPropertyValue::ensureFloat($entry[0])===$entry[1],
"Comparison $index: {$entry[0]}=={$entry[1]}");
}
public function testEnsureArray()
{
$entries=array
(
array(123,array(123)),
array(null,array()),
array('',array()),
array('abc',array('abc')),
array('(1,2)',array(1,2)),
array('("key"=>"value",2=>3)',array("key"=>"value",2=>3)),
array(true,array(true)),
array(array(),array()),
array(array(0),array(0)),
);
foreach($entries as $index=>$entry)
$this->assertTrue(CPropertyValue::ensureArray($entry[0])===$entry[1],
"Comparison $index: {$entry[0]}=={$entry[1]}");
}
public function testEnsureObject()
{
$obj=new stdClass;
$this->assertTrue(CPropertyValue::ensureObject($obj)===$obj);
}
public function testEnsureEnum()
{
$this->assertTrue(CPropertyValue::ensureEnum('Left','TextAlign')==='Left');
$this->setExpectedException('CException');
$this->assertTrue(CPropertyValue::ensureEnum('left','TextAlign')==='Left');
}
}

View File

@@ -0,0 +1,79 @@
<?php
class CSecurityManagerTest extends CTestCase
{
public function setUp()
{
// clean up runtime directory
$app=new TestApplication;
$app->reset();
}
public function testValidationKey()
{
$sm=new CSecurityManager;
$key='123456';
$sm->validationKey=$key;
$this->assertEquals($key,$sm->validationKey);
$app=new TestApplication;
$key=$app->securityManager->validationKey;
$app->saveGlobalState();
$app2=new TestApplication;
$this->assertEquals($app2->securityManager->validationKey,$key);
}
public function testEncryptionKey()
{
$sm=new CSecurityManager;
$key='123456';
$sm->encryptionKey=$key;
$this->assertEquals($key,$sm->encryptionKey);
$app=new TestApplication;
$key=$app->securityManager->encryptionKey;
$app->saveGlobalState();
$app2=new TestApplication;
$this->assertEquals($app2->securityManager->encryptionKey,$key);
}
public function testValidation()
{
$sm=new CSecurityManager;
$mode='SHA1';
$sm->validation=$mode;
$this->assertEquals($mode,$sm->validation);
}
public function testValidateData()
{
$sm=new CSecurityManager;
$sm->validationKey='123456';
$sm->validation='SHA1';
$data='this is raw data';
$hashedData=$sm->hashData($data);
$this->assertEquals($data,$sm->validateData($hashedData));
$hashedData[3]='c'; // tamper the data
$this->assertTrue($sm->validateData($hashedData)===false);
$sm->validation='MD5';
$data='this is raw data';
$hashedData=$sm->hashData($data);
$this->assertEquals($data,$sm->validateData($hashedData));
$hashedData[3]='c'; // tamper the data
$this->assertTrue($sm->validateData($hashedData)===false);
}
public function testEncryptData()
{
if(!extension_loaded('mcrypt'))
$this->markTestSkipped('mcrypt extension is required to test encrypt feature.');
$sm=new CSecurityManager;
$sm->encryptionKey='123456';
$data='this is raw data';
$encryptedData=$sm->encrypt($data);
$this->assertTrue($data!==$encryptedData);
$data2=$sm->decrypt($encryptedData);
$this->assertEquals($data,$data2);
}
}

View File

@@ -0,0 +1,33 @@
<?php
class CStatePersisterTest extends CTestCase
{
public function setUp()
{
// clean up runtime directory
$app=new TestApplication;
$app->reset();
}
public function testLoadSave()
{
$app=new TestApplication;
$sp=$app->statePersister;
$data=array('123','456','a'=>443);
$sp->save($data);
$this->assertEquals($sp->load(),$data);
// TODO: test with cache on
}
public function testStateFile()
{
$sp=new CStatePersister;
$file=dirname(__FILE__).DIRECTORY_SEPARATOR.'state.bin';
$sp->stateFile=$file;
$this->assertEquals($sp->stateFile,$file);
$sp->stateFile=dirname(__FILE__).'/unknown/state.bin';
$this->setExpectedException('CException');
$sp->init();
}
}

View File

@@ -0,0 +1,13 @@
<?php
class NewApplicationComponent extends CApplicationComponent {
private $_text=NULL;
public function getText($text=NULL) {
if(NULL===$text) {
return $this->_text;
}
return $text;
}
public function setText($val) {
$this->_text = $val;
}
}

View File

@@ -0,0 +1,8 @@
<?php
class NewBeforeValidateBehaviorException extends CException {}
class NewBeforeValidateBehavior extends CModelBehavior {
public function beforeValidate($event) {
throw new NewBeforeValidateBehaviorException();
}
}

View File

@@ -0,0 +1,9 @@
<?php
class NewBehavior extends CBehavior
{
public function test()
{
$this->owner->behaviorCalled=true;
return 2;
}
}

View File

@@ -0,0 +1,41 @@
<?php
class NewComponent extends CComponent
{
private $_object = null;
private $_text = 'default';
public $eventHandled = false;
public $behaviorCalled = false;
public function getText()
{
return $this->_text;
}
public function setText($value)
{
$this->_text=$value;
}
public function getObject()
{
if(!$this->_object)
{
$this->_object=new NewComponent;
$this->_object->_text='object text';
}
return $this->_object;
}
public function onMyEvent()
{
$this->raiseEvent('OnMyEvent',new CEvent($this));
}
public function myEventHandler($event)
{
$this->eventHandled=true;
}
public function exprEvaluator($p1,$comp) {
return "Hello $p1";
}
}

View File

@@ -0,0 +1,10 @@
<?php
class NewFormModel extends CFormModel {
public function behaviors() {
return array(
'newBeforeValidateBehavior' => array(
'class' => 'NewBeforeValidateBehavior',
),
);
}
}

View File

@@ -0,0 +1,23 @@
<?php
class NewModel extends CModel
{
public $attr1;
public $attr2;
public $attr3;
public $attr4;
public function rules()
{
return array(
array('attr2,attr1','numerical','max'=>5),
array('attr1','required'),
array('attr3', 'unsafe'),
);
}
public function attributeNames()
{
return array('attr1','attr2');
}
}

View File

@@ -0,0 +1,4 @@
<?php
class NewModule extends CModule {
}

View File

@@ -0,0 +1,178 @@
<?php
if(!defined('DBCACHE_TEST_DBFILE'))
define('DBCACHE_TEST_DBFILE',dirname(__FILE__).'/temp/test2.db');
if(!defined('DBCACHE_TEST_DB'))
define('DBCACHE_TEST_DB','sqlite:'.DBCACHE_TEST_DBFILE);
class CDbCacheTest extends CTestCase
{
private $_config1=array(
'id'=>'testApp',
'components'=>array(
'cache'=>array(
'class'=>'CDbCache',
),
),
);
private $_config2=array(
'id'=>'testApp',
'components'=>array(
'db'=>array(
'connectionString'=>DBCACHE_TEST_DB,
),
'cache'=>array(
'class'=>'system.caching.CDbCache',
'connectionID'=>'db',
),
),
);
public function setUp()
{
if(!extension_loaded('pdo') || !extension_loaded('pdo_sqlite'))
$this->markTestSkipped('PDO and SQLite extensions are required.');
}
public function testKeyPrefix()
{
$cache=new CDbCache;
$this->assertEquals($cache->keyPrefix,'');
$cache->keyPrefix='key';
$this->assertEquals($cache->keyPrefix,'key');
$app=new TestApplication($this->_config1);
$app->reset();
$this->assertTrue($app->cache instanceof CDbCache);
$this->assertEquals($app->cache->keyPrefix,$app->id);
}
public function testGetAndSet()
{
$app=new TestApplication($this->_config1);
$app->reset();
$cache=$app->cache;
$data=array('abc'=>1,2=>'def');
$key='data1';
$this->assertFalse($cache->get($key));
$cache->set($key,$data);
$this->assertTrue($cache->get($key)===$data);
$app2=new TestApplication($this->_config1);
$this->assertTrue($app2->cache->get($key)===$data);
}
public function testArrayAccess()
{
$app=new TestApplication($this->_config1);
$app->reset();
$cache=$app->cache;
$data=array('abc'=>1,2=>'def');
$key='data2';
$cache[$key]=$data;
$this->assertTrue($cache->get($key)===$data);
$this->assertTrue($cache[$key]===$data);
unset($cache[$key]);
$this->assertFalse($cache[$key]);
}
public function testExpire()
{
$app=new TestApplication($this->_config1);
$app->reset();
$cache=$app->cache;
$data=array('abc'=>1,2=>'def');
$key='data3';
$cache->set($key,$data,2);
$this->assertTrue($cache->get($key)===$data);
sleep(4);
$app2=new TestApplication($this->_config1);
$this->assertFalse($app2->cache->get($key));
}
public function testUseDbConnection()
{
@unlink(DBCACHE_TEST_DBFILE);
$app=new TestApplication($this->_config2);
$cache=$app->cache;
$data=array('abc'=>1,2=>'def');
$key='data4';
$this->assertFalse($cache->get($key));
$cache->set($key,$data);
$this->assertTrue($cache->get($key)===$data);
$app2=new TestApplication($this->_config2);
$this->assertTrue($app2->cache->get($key)===$data);
}
public function testDependency()
{
@unlink(DBCACHE_TEST_DBFILE);
$app=new TestApplication($this->_config2);
$cache=$app->cache;
$data=array('abc'=>1,2=>'def');
$key='data5';
$cache->set($key,$data,0,new CFileCacheDependency(__FILE__));
$this->assertTrue($cache->get($key)===$data);
$app=new TestApplication($this->_config2);
$this->assertTrue($app->cache->get($key)===$data);
$key2='data6';
$cache->set($key2,$data,0,new CFileCacheDependency(DBCACHE_TEST_DBFILE));
sleep(2); // sleep to ensure timestamp is changed for the db file
$cache->set('data7',$data);
$app=new TestApplication($this->_config2);
$this->assertFalse($app->cache->get($key2));
}
public function testAdd()
{
@unlink(DBCACHE_TEST_DBFILE);
$app=new TestApplication($this->_config2);
$cache=$app->cache;
$data=array('abc'=>1,2=>'def');
$key='data8';
$cache->set($key,$data);
$this->assertTrue($cache->set($key,$data));
$this->assertFalse($cache->add($key,$data));
$this->assertTrue($cache->add('data9',$data));
}
public function testDelete()
{
@unlink(DBCACHE_TEST_DBFILE);
$app=new TestApplication($this->_config2);
$cache=$app->cache;
$data=array('abc'=>1,2=>'def');
$key='data10';
$cache->set($key,$data);
$cache->delete($key);
$this->assertFalse($cache->get($key));
}
public function testFlush()
{
@unlink(DBCACHE_TEST_DBFILE);
$app=new TestApplication($this->_config2);
$cache=$app->cache;
$data=array('abc'=>1,2=>'def');
$key1='data11';
$key2='data12';
$cache->set($key1,$data);
$cache->set($key2,$data);
$cache->flush();
$this->assertFalse($cache->get($key1));
$this->assertFalse($cache->get($key2));
}
}

View File

@@ -0,0 +1,61 @@
<?php
Yii::import('system.caching.dependencies.CDirectoryCacheDependency');
class CDirectoryCacheDependencyTest extends CTestCase
{
public function testDirectoryName()
{
$directory=realpath(dirname(__FILE__).'/temp');
$dependency=new CDirectoryCacheDependency($directory);
$this->assertEquals($dependency->directory,$directory);
$this->setExpectedException('CException');
$dependency=new CDirectoryCacheDependency(dirname(__FILE__).'/temp2');
$dependency->evaluateDependency();
}
public function testRecursiveLevel()
{
$directory=realpath(dirname(__FILE__).'/temp');
$dependency=new CDirectoryCacheDependency(dirname(__FILE__).'/temp');
$this->assertEquals($dependency->recursiveLevel,-1);
$dependency->recursiveLevel=5;
$this->assertEquals($dependency->recursiveLevel,5);
}
public function testHasChanged()
{
$tempFile=dirname(__FILE__).'/temp/foo.txt';
@unlink($tempFile);
$fw=fopen($tempFile,"w");
fwrite($fw,"test");
fclose($fw);
clearstatcache();
$dependency=new CDirectoryCacheDependency(dirname($tempFile));
$dependency->evaluateDependency();
$str=serialize($dependency);
// test directory not changed
sleep(2);
$dependency=unserialize($str);
$this->assertFalse($dependency->hasChanged);
// change file
$fw=fopen($tempFile,"w");
fwrite($fw,"test again");
fclose($fw);
clearstatcache();
// test file changed
sleep(2);
$dependency->evaluateDependency();
$dependency=unserialize($str);
$this->assertTrue($dependency->hasChanged);
@unlink($tempFile);
}
}
?>

View File

@@ -0,0 +1,53 @@
<?php
Yii::import('system.caching.dependencies.CFileCacheDependency');
class CFileCacheDependencyTest extends CTestCase
{
public function testFileName()
{
$dependency=new CFileCacheDependency(__FILE__);
$this->assertEquals($dependency->fileName,__FILE__);
$dependency->evaluateDependency();
$this->assertEquals($dependency->dependentData,filemtime(__FILE__));
$dependency=new CFileCacheDependency(dirname(__FILE__).'/foo.txt');
$dependency->evaluateDependency();
$this->assertFalse($dependency->dependentData);
}
public function testHasChanged()
{
$tempFile=dirname(__FILE__).'/temp/foo.txt';
@unlink($tempFile);
$fw=fopen($tempFile,"w");
fwrite($fw,"test");
fclose($fw);
clearstatcache();
$dependency=new CFileCacheDependency($tempFile);
$dependency->evaluateDependency();
$str=serialize($dependency);
// test file not changed
sleep(2);
$dependency=unserialize($str);
$this->assertFalse($dependency->hasChanged);
// change file
$fw=fopen($tempFile,"w");
fwrite($fw,"test again");
fclose($fw);
clearstatcache();
// test file changed
sleep(2);
$dependency->evaluateDependency();
$dependency=unserialize($str);
$this->assertTrue($dependency->hasChanged);
@unlink($tempFile);
}
}
?>

View File

@@ -0,0 +1,141 @@
<?php
if(!defined('MEMCACHE_TEST_HOST'))
define('MEMCACHE_TEST_HOST', '127.0.0.1');
if(!defined('MEMCACHE_TEST_PORT'))
define('MEMCACHE_TEST_PORT', 11211);
class CMemCacheTest extends CTestCase
{
private $_config=array(
'id'=>'testApp',
'components'=>array(
'cache'=>array(
'class'=>'CMemCache',
'servers'=>array(
array('host'=>MEMCACHE_TEST_HOST, 'port'=>MEMCACHE_TEST_PORT, 'weight'=>100),
),
),
),
);
public function setUp()
{
if(!extension_loaded('memcache') && !extension_loaded('memcached'))
$this->markTestSkipped('Memcache or memcached extensions are required.');
}
public function testMget()
{
$app=new TestApplication($this->_config);
$app->reset();
$cache=$app->cache;
$data1=array('abc'=>1,2=>'def');
$key1='data1';
$data2=array('xyz'=>3,4=>'whn');
$key2='data2';
$cache->delete($key1);
$cache->delete($key2);
$this->assertFalse($cache->get($key1));
$this->assertFalse($cache->get($key2));
$cache->set($key1,$data1);
$cache->set($key2,$data2);
$this->assertTrue($cache->get($key1)===$data1);
$this->assertTrue($cache->get($key2)===$data2);
$mgetResult = $cache->mget(array($key1, $key2));
$this->assertTrue(is_array($mgetResult));
$this->assertEquals($mgetResult[$key1],$data1);
$this->assertEquals($mgetResult[$key2],$data2);
$cache->delete($key2);
$mgetResult = $cache->mget(array($key1, $key2));
$this->assertTrue(is_array($mgetResult));
$this->assertEquals($mgetResult[$key1],$data1);
$this->assertFalse($mgetResult[$key2]); // data2 is removed from cache
$cache->delete($key1);
$mgetResult = $cache->mget(array($key1, $key2));
$this->assertTrue(is_array($mgetResult));
$this->assertFalse($mgetResult[$key1]); // data1 is removed from cache
$this->assertFalse($mgetResult[$key2]); // data2 is removed from cache
}
public function testKeyPrefix()
{
$cache=new CMemCache;
$this->assertEquals($cache->keyPrefix,'');
$cache->keyPrefix='key';
$this->assertEquals($cache->keyPrefix,'key');
$app=new TestApplication($this->_config);
$app->reset();
$this->assertTrue($app->cache instanceof CMemCache);
$this->assertEquals($app->cache->keyPrefix,$app->id);
}
public function testGetAndSet()
{
$app=new TestApplication($this->_config);
$app->reset();
$cache=$app->cache;
$data=array('abc'=>1,2=>'def');
$key='data1';
$cache->delete($key);
$this->assertFalse($cache->get($key));
$cache->set($key,$data);
$this->assertTrue($cache->get($key)===$data);
$app2=new TestApplication($this->_config);
$this->assertTrue($app2->cache->get($key)===$data);
}
public function testArrayAccess()
{
$app=new TestApplication($this->_config);
$app->reset();
$cache=$app->cache;
$data=array('abc'=>1,2=>'def');
$key='data2';
$cache[$key]=$data;
$this->assertTrue($cache->get($key)===$data);
$this->assertTrue($cache[$key]===$data);
unset($cache[$key]);
$this->assertFalse($cache[$key]);
}
public function testExpire()
{
$app=new TestApplication($this->_config);
$app->reset();
$cache=$app->cache;
$data=array('abc'=>1,2=>'def');
$key='data3';
$cache->set($key,$data,2);
$this->assertTrue($cache->get($key)===$data);
sleep(4);
$app2=new TestApplication($this->_config);
$this->assertFalse($app2->cache->get($key));
}
public function testDelete()
{
$app=new TestApplication($this->_config);
$cache=$app->cache;
$data=array('abc'=>1,2=>'def');
$key='data10';
$cache->set($key,$data);
$cache->delete($key);
$this->assertFalse($cache->get($key));
}
}

View File

@@ -0,0 +1,106 @@
<?php
Yii::import('system.collections.CAttributeCollection');
class CAttributeCollectionTest extends CTestCase
{
public function testCanGetProperty()
{
$collection = new CAttributeCollection();
$collection->Property = 'value';
$this->assertEquals('value', $collection->Property);
$this->assertEquals(true, $collection->canGetProperty('Property'));
}
public function testCanNotGetUndefinedProperty()
{
$collection = new CAttributeCollection(array(), true);
$this->assertEquals(false, $collection->canGetProperty('Property'));
$this->setExpectedException('CException');
$value=$collection->Property;
}
public function testCanSetProperty()
{
$collection = new CAttributeCollection();
$collection->Property = 'value';
$this->assertEquals('value', $collection->itemAt('Property'));
$this->assertEquals(true, $collection->canSetProperty('Property'));
}
public function testCanNotSetPropertyIfReadOnly()
{
$collection = new CAttributeCollection(array(), true);
$this->setExpectedException('CException');
$collection->Property = 'value';
}
public function testGetCaseSensitive()
{
$collection = new CAttributeCollection();
$collection->caseSensitive=false;
$this->assertEquals(false, $collection->caseSensitive);
$collection->caseSensitive=true;
$this->assertEquals(true, $collection->caseSensitive);
}
public function testSetCaseSensitive()
{
$collection = new CAttributeCollection();
$collection->Property = 'value';
$collection->caseSensitive=false;
$this->assertEquals('value', $collection->itemAt('property'));
}
public function testItemAt()
{
$collection = new CAttributeCollection();
$collection->Property = 'value';
$this->assertEquals('value', $collection->itemAt('Property'));
}
public function testAdd()
{
$collection = new CAttributeCollection();
$collection->add('Property', 'value');
$this->assertEquals('value', $collection->itemAt('Property'));
}
public function testRemove()
{
$collection = new CAttributeCollection();
$collection->add('Property', 'value');
$collection->remove('Property');
$this->assertEquals(0, count($collection));
}
public function testUnset(){
$collection = new CAttributeCollection();
$collection->add('Property', 'value');
unset($collection->Property);
$this->assertEquals(0, count($collection));
}
public function testIsset(){
$collection = new CAttributeCollection();
$this->assertEquals(false, isset($collection->Property));
$collection->Property = 'value';
$this->assertEquals(true, isset($collection->Property));
}
public function testContains()
{
$collection = new CAttributeCollection();
$this->assertEquals(false, $collection->contains('Property'));
$collection->Property = 'value';
$this->assertEquals(true, $collection->contains('Property'));
}
public function testHasProperty()
{
$collection = new CAttributeCollection();
$this->assertEquals(false, $collection->hasProperty('Property'));
$collection->Property = 'value';
$this->assertEquals(true, $collection->hasProperty('Property'));
}
}

View File

@@ -0,0 +1,97 @@
<?php
Yii::import('system.collections.CConfiguration');
class MyClass extends CComponent
{
public $param1;
private $_param2;
public $param3;
private $_object;
public $backquote;
public function getParam2()
{
return $this->_param2;
}
public function setParam2($value)
{
$this->_param2=$value;
}
public function getObject()
{
if($this->_object===null)
$this->_object=new MyClass;
return $this->_object;
}
}
class CConfigurationTest extends CTestCase
{
public $configFile;
public function setUp()
{
$this->configFile=dirname(__FILE__).'/data/config.php';
}
public function tearDown()
{
}
public function testLoadFromFile()
{
$config=new CConfiguration;
$this->assertTrue($config->toArray()===array());
$config->loadFromFile($this->configFile);
$data=include($this->configFile);
$this->assertTrue($config->toArray()===$data);
}
public function testSaveAsString()
{
$config=new CConfiguration($this->configFile);
$str=$config->saveAsString();
eval("\$data=$str;");
$this->assertTrue($config->toArray()===$data);
}
public function testApplyTo()
{
$config=new CConfiguration($this->configFile);
$object=new MyClass;
$config->applyTo($object);
$this->assertTrue($object->param1==='value1');
$this->assertTrue($object->param2===false);
$this->assertTrue($object->param3===123);
$this->assertTrue($object->backquote==="\\back'quote'");
/*
$this->assertTrue($object->object->param1===null);
$this->assertTrue($object->object->param2==='123');
$this->assertTrue($object->object->param3===array('param1'=>'kkk','ddd',''));
*/
}
public function testException()
{
$config=new CConfiguration(array('invalid'=>'value'));
$object=new MyClass;
$this->setExpectedException('CException');
$config->applyTo($object);
}
public function testCreateComponent()
{
$obj=Yii::createComponent(array('class'=>'MyClass','param2'=>3));
$this->assertEquals(get_class($obj),'MyClass');
$this->assertEquals($obj->param2,3);
}
public function testCreateObject(){
$obj = CConfiguration::createObject(array('class'=>'MyClass','param2'=>3));
$this->assertEquals(get_class($obj),'MyClass');
$this->assertEquals($obj->param2,3);
}
}

View File

@@ -0,0 +1,208 @@
<?php
Yii::import('system.collections.CList');
class ListItem
{
public $data='data';
}
class CListTest extends CTestCase
{
protected $list;
protected $item1, $item2, $item3;
public function setUp()
{
$this->list=new CList;
$this->item1=new ListItem;
$this->item2=new ListItem;
$this->item3=new ListItem;
$this->list->add($this->item1);
$this->list->add($this->item2);
}
public function tearDown()
{
$this->list=null;
$this->item1=null;
$this->item2=null;
$this->item3=null;
}
public function testConstruct()
{
$a=array(1,2,3);
$list=new CList($a);
$this->assertEquals(3,$list->getCount());
$list2=new CList($this->list);
$this->assertEquals(2,$list2->getCount());
}
public function testGetReadOnly()
{
$list = new CList(null, true);
$this->assertEquals(true, $list->getReadOnly(), 'List is not read-only');
$list = new CList(null, false);
$this->assertEquals(false, $list->getReadOnly(), 'List is read-only');
}
public function testGetCount()
{
$this->assertEquals(2,$this->list->getCount());
$this->assertEquals(2,$this->list->Count);
}
public function testAdd()
{
$this->list->add(null);
$this->list->add($this->item3);
$this->assertEquals(4,$this->list->getCount());
$this->assertEquals(3,$this->list->indexOf($this->item3));
}
public function testInsertAt()
{
$this->list->insertAt(0,$this->item3);
$this->assertEquals(3,$this->list->getCount());
$this->assertEquals(2,$this->list->indexOf($this->item2));
$this->assertEquals(0,$this->list->indexOf($this->item3));
$this->assertEquals(1,$this->list->indexOf($this->item1));
$this->setExpectedException('CException');
$this->list->insertAt(4,$this->item3);
}
public function testCanNotInsertWhenReadOnly()
{
$list = new CList(array(), true);
$this->setExpectedException('CException');
$list->insertAt(1, 2);
}
public function testRemove()
{
$this->list->remove($this->item1);
$this->assertEquals(1,$this->list->getCount());
$this->assertEquals(-1,$this->list->indexOf($this->item1));
$this->assertEquals(0,$this->list->indexOf($this->item2));
$this->assertEquals(false,$this->list->remove($this->item1));
}
public function testRemoveAt()
{
$this->list->add($this->item3);
$this->list->removeAt(1);
$this->assertEquals(-1,$this->list->indexOf($this->item2));
$this->assertEquals(1,$this->list->indexOf($this->item3));
$this->assertEquals(0,$this->list->indexOf($this->item1));
$this->setExpectedException('CException');
$this->list->removeAt(2);
}
public function testCanNotRemoveWhenReadOnly()
{
$list = new CList(array(1, 2, 3), true);
$this->setExpectedException('CException');
$list->removeAt(2);
}
public function testClear()
{
$this->list->clear();
$this->assertEquals(0,$this->list->getCount());
$this->assertEquals(-1,$this->list->indexOf($this->item1));
$this->assertEquals(-1,$this->list->indexOf($this->item2));
}
public function testContains()
{
$this->assertTrue($this->list->contains($this->item1));
$this->assertTrue($this->list->contains($this->item2));
$this->assertFalse($this->list->contains($this->item3));
}
public function testIndexOf()
{
$this->assertEquals(0,$this->list->indexOf($this->item1));
$this->assertEquals(1,$this->list->indexOf($this->item2));
$this->assertEquals(-1,$this->list->indexOf($this->item3));
}
public function testCopyFrom()
{
$array=array($this->item3,$this->item1);
$this->list->copyFrom($array);
$this->assertTrue(count($array)==2 && $this->list[0]===$this->item3 && $this->list[1]===$this->item1);
$this->setExpectedException('CException');
$this->list->copyFrom($this);
}
public function testMergeWith()
{
$array=array($this->item3,$this->item1);
$this->list->mergeWith($array);
$this->assertTrue($this->list->getCount()==4 && $this->list[0]===$this->item1 && $this->list[3]===$this->item1);
$this->setExpectedException('CException');
$this->list->mergeWith($this);
}
public function testToArray()
{
$array=$this->list->toArray();
$this->assertTrue(count($array)==2 && $array[0]===$this->item1 && $array[1]===$this->item2);
}
public function testArrayRead()
{
$this->assertTrue($this->list[0]===$this->item1);
$this->assertTrue($this->list[1]===$this->item2);
$this->setExpectedException('CException');
$a=$this->list[2];
}
public function testGetIterator()
{
$n=0;
$found=0;
foreach($this->list as $index=>$item)
{
foreach($this->list as $a=>$b); // test of iterator
$n++;
if($index===0 && $item===$this->item1)
$found++;
if($index===1 && $item===$this->item2)
$found++;
}
$this->assertTrue($n==2 && $found==2);
}
public function testArrayMisc()
{
$this->assertEquals($this->list->Count,count($this->list));
$this->assertTrue(isset($this->list[1]));
$this->assertFalse(isset($this->list[2]));
}
public function testOffsetSetAdd()
{
$list = new CList(array(1, 2, 3));
$list->offsetSet(null, 4);
$this->assertEquals(array(1, 2, 3, 4), $list->toArray());
}
public function testOffsetSetReplace()
{
$list = new CList(array(1, 2, 3));
$list->offsetSet(1, 4);
$this->assertEquals(array(1, 4, 3), $list->toArray());
}
public function testOffsetUnset()
{
$list = new CList(array(1, 2, 3));
$list->offsetUnset(1);
$this->assertEquals(array(1, 3), $list->toArray());
}
}

View File

@@ -0,0 +1,204 @@
<?php
Yii::import('system.collections.CMap');
class MapItem
{
public $data='data';
}
class CMapTest extends CTestCase
{
protected $map;
protected $item1,$item2,$item3;
public function setUp()
{
$this->map=new CMap;
$this->item1=new MapItem;
$this->item2=new MapItem;
$this->item3=new MapItem;
$this->map->add('key1',$this->item1);
$this->map->add('key2',$this->item2);
}
public function tearDown()
{
$this->map=null;
$this->item1=null;
$this->item2=null;
$this->item3=null;
}
public function testConstruct()
{
$a=array(1,2,'key3'=>3);
$map=new CMap($a);
$this->assertEquals(3,$map->getCount());
$map2=new CMap($this->map);
$this->assertEquals(2,$map2->getCount());
}
public function testGetReadOnly()
{
$map = new CMap(null, true);
self::assertEquals(true, $map->getReadOnly(), 'List is not read-only');
}
public function testGetCount()
{
$this->assertEquals(2,$this->map->getCount());
}
public function testGetKeys()
{
$keys=$this->map->getKeys();
$this->assertEquals(2,count($keys));
$this->assertEquals('key1',$keys[0]);
$this->assertEquals('key2',$keys[1]);
}
public function testAdd()
{
$this->map->add('key3',$this->item3);
$this->assertEquals(3,$this->map->getCount());
$this->assertTrue($this->map->contains('key3'));
}
public function testCanNotAddWhenReadOnly()
{
$map = new CMap(array(), true);
$this->setExpectedException('CException');
$map->add('key', 'value');
}
public function testRemove()
{
$this->map->remove('key1');
$this->assertEquals(1,$this->map->getCount());
$this->assertTrue(!$this->map->contains('key1'));
$this->assertTrue($this->map->remove('unknown key')===null);
}
public function testCanNotRemoveWhenReadOnly()
{
$map = new CMap(array('key' => 'value'), true);
$this->setExpectedException('CException');
$map->remove('key');
}
public function testClear()
{
$this->map->clear();
$this->assertEquals(0,$this->map->getCount());
$this->assertTrue(!$this->map->contains('key1') && !$this->map->contains('key2'));
}
public function testContains()
{
$this->assertTrue($this->map->contains('key1'));
$this->assertTrue($this->map->contains('key2'));
$this->assertFalse($this->map->contains('key3'));
}
public function testCopyFrom()
{
$array=array('key3'=>$this->item3,'key4'=>$this->item1);
$this->map->copyFrom($array);
$this->assertEquals(2, $this->map->getCount());
$this->assertEquals($this->item3, $this->map['key3']);
$this->assertEquals($this->item1, $this->map['key4']);
$this->setExpectedException('CException');
$this->map->copyFrom($this);
}
public function testMergeWith()
{
$a=array('a'=>'v1','v2',array('2'),'c'=>array('3','c'=>'a'));
$b=array('v22','a'=>'v11',array('2'),'c'=>array('c'=>'3','a'));
$c=array('a'=>'v11','v2',array('2'),'c'=>array('3','c'=>'3','a'),'v22',array('2'));
$map=new CMap($a);
$map2=new CMap($b);
$map->mergeWith($map2);
$this->assertTrue($map->toArray()===$c);
$array=array('key2'=>$this->item1,'key3'=>$this->item3);
$this->map->mergeWith($array,false);
$this->assertEquals(3,$this->map->getCount());
$this->assertEquals($this->item1,$this->map['key2']);
$this->assertEquals($this->item3,$this->map['key3']);
$this->setExpectedException('CException');
$this->map->mergeWith($this,false);
}
public function testRecursiveMergeWithTraversable(){
$map = new CMap();
$obj = new ArrayObject(array(
'k1' => $this->item1,
'k2' => $this->item2,
'k3' => new ArrayObject(array(
'k4' => $this->item3,
))
));
$map->mergeWith($obj,true);
$this->assertEquals(3, $map->getCount());
$this->assertEquals($this->item1, $map['k1']);
$this->assertEquals($this->item2, $map['k2']);
$this->assertEquals($this->item3, $map['k3']['k4']);
}
public function testArrayRead()
{
$this->assertEquals($this->item1,$this->map['key1']);
$this->assertEquals($this->item2,$this->map['key2']);
$this->assertEquals(null,$this->map['key3']);
}
public function testArrayWrite()
{
$this->map['key3']=$this->item3;
$this->assertEquals(3,$this->map->getCount());
$this->assertEquals($this->item3,$this->map['key3']);
$this->map['key1']=$this->item3;
$this->assertEquals(3,$this->map->getCount());
$this->assertEquals($this->item3,$this->map['key1']);
unset($this->map['key2']);
$this->assertEquals(2,$this->map->getCount());
$this->assertTrue(!$this->map->contains('key2'));
unset($this->map['unknown key']);
}
public function testArrayForeach()
{
$n=0;
$found=0;
foreach($this->map as $index=>$item)
{
$n++;
if($index==='key1' && $item===$this->item1)
$found++;
if($index==='key2' && $item===$this->item2)
$found++;
}
$this->assertTrue($n==2 && $found==2);
}
public function testArrayMisc()
{
$this->assertEquals($this->map->Count,count($this->map));
$this->assertTrue(isset($this->map['key1']));
$this->assertFalse(isset($this->map['unknown key']));
}
public function testToArray()
{
$map = new CMap(array('key' => 'value'));
self::assertEquals(array('key' => 'value'), $map->toArray());
}
}

View File

@@ -0,0 +1,119 @@
<?php
Yii::import('system.collections.CQueue');
class CQueueTest extends CTestCase
{
public function testConstruct()
{
$queue = new CQueue();
$this->assertEquals(array(), $queue->toArray());
$queue = new CQueue(array(1, 2, 3));
$this->assertEquals(array(1, 2, 3), $queue->toArray());
}
public function testToArray()
{
$queue = new CQueue(array(1, 2, 3));
$this->assertEquals(array(1, 2, 3), $queue->toArray());
}
public function testCopyFrom()
{
$queue = new CQueue(array(1, 2, 3));
$data = array(4, 5, 6);
$queue->copyFrom($data);
$this->assertEquals(array(4, 5, 6), $queue->toArray());
}
public function testCanNotCopyFromNonTraversableTypes()
{
$queue = new CQueue();
$data = new stdClass();
$this->setExpectedException('CException');
$queue->copyFrom($data);
}
public function testClear()
{
$queue = new CQueue(array(1, 2, 3));
$queue->clear();
$this->assertEquals(array(), $queue->toArray());
}
public function testContains()
{
$queue = new CQueue(array(1, 2, 3));
$this->assertEquals(true, $queue->contains(2));
$this->assertEquals(false, $queue->contains(4));
}
public function testPeek()
{
$queue = new CQueue(array(1));
$this->assertEquals(1, $queue->peek());
}
public function testCanNotPeekAnEmptyQueue()
{
$queue = new CQueue();
$this->setExpectedException('CException');
$item = $queue->peek();
}
public function testDequeue()
{
$queue = new CQueue(array(1, 2, 3));
$first = $queue->dequeue();
$this->assertEquals(1, $first);
$this->assertEquals(array(2, 3), $queue->toArray());
}
public function testCanNotDequeueAnEmptyQueue()
{
$queue = new CQueue();
$this->setExpectedException('CException');
$item = $queue->dequeue();
}
public function testEnqueue()
{
$queue = new CQueue();
$queue->enqueue(1);
$this->assertEquals(array(1), $queue->toArray());
}
public function testGetIterator()
{
$queue = new CQueue(array(1, 2));
$this->assertInstanceOf('CQueueIterator', $queue->getIterator());
$n = 0;
$found = 0;
foreach($queue as $index => $item)
{
foreach($queue as $a => $b); // test of iterator
$n++;
if($index === 0 && $item === 1)
$found++;
if($index === 1 && $item === 2)
$found++;
}
$this->assertTrue($n == 2 && $found == 2);
}
public function testGetCount()
{
$queue = new CQueue();
$this->assertEquals(0, $queue->getCount());
$queue = new CQueue(array(1, 2, 3));
$this->assertEquals(3, $queue->getCount());
}
public function testCountable()
{
$queue = new CQueue();
$this->assertEquals(0, count($queue));
$queue = new CQueue(array(1, 2, 3));
$this->assertEquals(3, count($queue));
}
}

View File

@@ -0,0 +1,119 @@
<?php
Yii::import('system.collections.CStack');
class CStackTest extends CTestCase
{
public function testConstruct()
{
$stack = new CStack();
$this->assertEquals(array(), $stack->toArray());
$stack = new CStack(array(1, 2, 3));
$this->assertEquals(array(1, 2, 3), $stack->toArray());
}
public function testToArray()
{
$stack = new CStack(array(1, 2, 3));
$this->assertEquals(array(1, 2, 3), $stack->toArray());
}
public function testCopyFrom()
{
$stack = new CStack(array(1, 2, 3));
$data = array(4, 5, 6);
$stack->copyFrom($data);
$this->assertEquals(array(4, 5, 6), $stack->toArray());
}
public function testCanNotCopyFromNonTraversableTypes()
{
$stack = new CStack();
$data = new stdClass();
$this->setExpectedException('CException');
$stack->copyFrom($data);
}
public function testClear()
{
$stack = new CStack(array(1, 2, 3));
$stack->clear();
$this->assertEquals(array(), $stack->toArray());
}
public function testContains()
{
$stack = new CStack(array(1, 2, 3));
$this->assertEquals(true, $stack->contains(2));
$this->assertEquals(false, $stack->contains(4));
}
public function testPeek()
{
$stack = new CStack(array(1));
$this->assertEquals(1, $stack->peek());
}
public function testCanNotPeekAnEmptyStack()
{
$stack = new CStack();
$this->setExpectedException('CException');
$item = $stack->peek();
}
public function testPop()
{
$stack = new CStack(array(1, 2, 3));
$last = $stack->pop();
$this->assertEquals(3, $last);
$this->assertEquals(array(1, 2), $stack->toArray());
}
public function testCanNotPopAnEmptyStack()
{
$stack = new CStack();
$this->setExpectedException('CException');
$item = $stack->pop();
}
public function testPush()
{
$stack = new CStack();
$stack->push(1);
$this->assertEquals(array(1), $stack->toArray());
}
public function testGetIterator()
{
$stack = new CStack(array(1, 2));
$this->assertInstanceOf('CStackIterator', $stack->getIterator());
$n = 0;
$found = 0;
foreach($stack as $index => $item)
{
foreach($stack as $a => $b); // test of iterator
$n++;
if($index === 0 && $item === 1)
$found++;
if($index === 1 && $item === 2)
$found++;
}
$this->assertTrue($n == 2 && $found == 2);
}
public function testGetCount()
{
$stack = new CStack();
$this->assertEquals(0, $stack->getCount());
$stack = new CStack(array(1, 2, 3));
$this->assertEquals(3, $stack->getCount());
}
public function testCount()
{
$stack = new CStack();
$this->assertEquals(0, count($stack));
$stack = new CStack(array(1, 2, 3));
$this->assertEquals(3, count($stack));
}
}

View File

@@ -0,0 +1,22 @@
<?php
Yii::import('system.collections.CTypedList');
class CTypedListTest extends CTestCase
{
public function testClassType()
{
$list=new CTypedList('CComponent');
$list[]=new CComponent;
$this->setExpectedException('CException');
$list[]=new stdClass;
}
public function testInterfaceType()
{
$list=new CTypedList('Traversable');
$list[]=new CList;
$this->setExpectedException('CException');
$list[]=new CComponent;
}
}

View File

@@ -0,0 +1,17 @@
<?php
return array(
'param1'=>'value1',
'param2'=>false,
'param3'=>123,
"backquote"=>"\\back'quote'",
/* 'object'=>array(
'param1'=>null,
'param2'=>'123',
'param3'=>array(
'param1'=>'kkk',
'ddd',
'',
),
),*/
);

View File

@@ -0,0 +1,388 @@
<?php
Yii::import('system.db.CDbConnection');
class CDbCommand2Test extends CTestCase
{
private $_connection;
public function setUp()
{
if(!extension_loaded('pdo') || !extension_loaded('pdo_sqlite'))
$this->markTestSkipped('PDO and SQLite extensions are required.');
$this->_connection=new CDbConnection('sqlite::memory:');
$this->_connection->active=true;
$this->_connection->pdoInstance->exec(file_get_contents(dirname(__FILE__).'/data/sqlite.sql'));
}
public function tearDown()
{
$this->_connection->active=false;
}
public function testSelect()
{
$command=$this->_connection->createCommand();
// default
$command->select();
$this->assertEquals('*', $command->select);
// string input
$command->select('id, username');
$this->assertEquals('"id", "username"', $command->select);
// string input with expression
$command->select('id, count(id) as num');
$this->assertEquals('id, count(id) as num', $command->select);
// array input
$command->select(array('id2', 'username2'));
$this->assertEquals('"id2", "username2"', $command->select);
// table prefix and expression
$command->select(array('user.id', 'count(id) as num', 'profile.*'));
$this->assertEquals('\'user\'."id", count(id) as num, \'profile\'.*', $command->select);
// alias
$command->select(array('id2 as id', 'profile.username2 AS username'));
$this->assertEquals('"id2" AS "id", \'profile\'."username2" AS "username"', $command->select);
// getter and setter
$command->select=array('id2', 'username2');
$this->assertEquals('"id2", "username2"', $command->select);
}
public function testDistinct()
{
$command=$this->_connection->createCommand();
// default value
$this->assertEquals(false, $command->distinct);
// select distinct
$command->selectDistinct('id, username');
$this->assertEquals(true, $command->distinct);
$this->assertEquals('"id", "username"', $command->select);
// getter and setter
$command->distinct=false;
$this->assertEquals(false, $command->distinct);
$command->distinct=true;
$this->assertEquals(true, $command->distinct);
}
public function testFrom()
{
$command=$this->_connection->createCommand();
// default
$this->assertEquals('', $command->from);
// string input
$command->from('user');
$this->assertEquals('\'user\'', $command->from);
$command->from('user, profile');
$this->assertEquals('\'user\', \'profile\'', $command->from);
// string input with expression
$command->from('user, (select * from profile) p');
$this->assertEquals('user, (select * from profile) p', $command->from);
// array input
$command->from(array('user', 'profile'));
$this->assertEquals('\'user\', \'profile\'', $command->from);
// table alias, expression, schema
$command->from(array('user u', '(select * from profile) p', 'public.post'));
$this->assertEquals('\'user\' \'u\', (select * from profile) p, \'public\'.\'post\'', $command->from);
// getter and setter
$command->from=array('user', 'profile');
$this->assertEquals('\'user\', \'profile\'', $command->from);
}
public function testWhere()
{
$command=$this->_connection->createCommand();
// default
$this->assertEquals('', $command->where);
$this->assertEquals(array(), $command->params);
// string input
$command->where('id=1 or id=:id2', array(':id2'=>2));
$this->assertEquals('id=1 or id=:id2', $command->where);
$this->assertEquals(array(':id2'=>2), $command->params);
// array input, and/or
$command->where(array('and', 'id=1', 'id=2'));
$this->assertEquals('(id=1) AND (id=2)', $command->where);
$command->where(array('and', 'id=1', array('or', 'id=3', 'id=4'), 'id=2'));
$this->assertEquals('(id=1) AND ((id=3) OR (id=4)) AND (id=2)', $command->where);
// empty input
$command->where(array());
$this->assertEquals('', $command->where);
// in, empty
$command->where(array('in', 'id', array()));
$this->assertEquals('0=1', $command->where);
// in
$command->where(array('in', 'id', array(1,'2',3)));
$this->assertEquals("\"id\" IN (1, '2', 3)", $command->where);
// not in, empty
$command->where(array('not in', 'id', array()));
$this->assertEquals('', $command->where);
// not in
$command->where(array('not in', 'id', array(1,'2',3)));
$this->assertEquals("\"id\" NOT IN (1, '2', 3)", $command->where);
// like, string
$command->where(array('like', 'name', '%tester'));
$this->assertEquals('"name" LIKE \'%tester\'', $command->where);
$command->where(array('like', 'name', array('%tester', '%tester2')));
$this->assertEquals('"name" LIKE \'%tester\' AND "name" LIKE \'%tester2\'', $command->where);
$command->where(array('not like', 'name', array('tester%', 'tester2%')));
$this->assertEquals('"name" NOT LIKE \'tester%\' AND "name" NOT LIKE \'tester2%\'', $command->where);
$command->where(array('or like', 'name', array('%tester', '%tester2')));
$this->assertEquals('"name" LIKE \'%tester\' OR "name" LIKE \'%tester2\'', $command->where);
$command->where(array('or not like', 'name', array('%tester', '%tester2')));
$this->assertEquals('"name" NOT LIKE \'%tester\' OR "name" NOT LIKE \'%tester2\'', $command->where);
}
public function testJoin()
{
$command=$this->_connection->createCommand();
// default
$this->assertEquals('', $command->join);
// inner join
$command->join('user', 'user.id=t.id and id=:id', array(':id'=>1));
$this->assertEquals(array('JOIN \'user\' ON user.id=t.id and id=:id'), $command->join);
$this->assertEquals(array(':id'=>1), $command->params);
// left join
$join=$command->join;
$command->leftJoin('user', 'user.id=t.id and id=:id');
$join[]='LEFT JOIN \'user\' ON user.id=t.id and id=:id';
$this->assertEquals($join, $command->join);
// right join
$command->rightJoin('user', 'user.id=t.id and id=:id');
$join[]='RIGHT JOIN \'user\' ON user.id=t.id and id=:id';
$this->assertEquals($join, $command->join);
// cross join
$command->crossJoin('user');
$join[]='CROSS JOIN \'user\'';
$this->assertEquals($join, $command->join);
// natural join
$command->naturalJoin('user');
$join[]='NATURAL JOIN \'user\'';
$this->assertEquals($join, $command->join);
}
public function testGroup()
{
$command=$this->_connection->createCommand();
// default
$this->assertEquals('', $command->group);
// string input
$command->group('id, username');
$this->assertEquals('"id", "username"', $command->group);
// string input with expression
$command->group('id, count(id)');
$this->assertEquals('id, count(id)', $command->group);
// array input
$command->group(array('id2', 'username2'));
$this->assertEquals('"id2", "username2"', $command->group);
// table prefix and expression
$command->group(array('user.id', 'count(id)'));
$this->assertEquals('\'user\'."id", count(id)', $command->group);
// getter and setter
$command->group=array('id2', 'username2');
$this->assertEquals('"id2", "username2"', $command->group);
}
public function testHaving()
{
$command=$this->_connection->createCommand();
// default
$this->assertEquals('', $command->having);
$this->assertEquals(array(), $command->params);
// string input
$command->having('id=1 or id=:id2', array(':id2'=>2));
$this->assertEquals('id=1 or id=:id2', $command->having);
$this->assertEquals(array(':id2'=>2), $command->params);
// array input, and/or
$command->having(array('and', 'id=1', 'id=2'));
$this->assertEquals('(id=1) AND (id=2)', $command->having);
$command->having(array('and', 'id=1', array('or', 'id=3', 'id=4'), 'id=2'));
$this->assertEquals('(id=1) AND ((id=3) OR (id=4)) AND (id=2)', $command->having);
}
public function testOrder()
{
$command=$this->_connection->createCommand();
// default
$this->assertEquals('', $command->order);
// string input
$command->order('id, username desc');
$this->assertEquals('"id", "username" DESC', $command->order);
// string input with expression
$command->order('id, count(id) desc');
$this->assertEquals('id, count(id) desc', $command->order);
// array input
$command->order(array('id2 asc', 'username2 DESC'));
$this->assertEquals('"id2" ASC, "username2" DESC', $command->order);
// table prefix and expression
$command->order(array('user.id asc', 'count(id)'));
$this->assertEquals('\'user\'."id" ASC, count(id)', $command->order);
// getter and setter
$command->order=array('id2 asc', 'username2');
$this->assertEquals('"id2" ASC, "username2"', $command->order);
}
public function testLimit()
{
$command=$this->_connection->createCommand();
// default
$this->assertEquals(-1, $command->limit);
$command->limit(10);
$this->assertEquals(10, $command->limit);
$command->limit(20,30);
$this->assertEquals(20, $command->limit);
$this->assertEquals(30, $command->offset);
// invalid string
$command->limit('abc');
$this->assertEquals(0, $command->limit);
}
public function testOffset()
{
$command=$this->_connection->createCommand();
// default
$this->assertEquals(-1, $command->offset);
$command->offset(10);
$this->assertEquals(10, $command->offset);
// invalid string
$command->offset('abc');
$this->assertEquals(0, $command->offset);
}
public function testUnion()
{
$command=$this->_connection->createCommand();
// default
$this->assertEquals('', $command->union);
$command->union('select * from user');
$this->assertEquals(array('select * from user'), $command->union);
$command->union('select * from post');
$this->assertEquals(array('select * from user', 'select * from post'), $command->union);
}
/*
public function testInsert()
{
$command=$this->_connection->createCommand();
$command->insert('user', array('id'=>1, 'username'=>'tester'));
$this->assertEquals('INSERT INTO \'user\' ("id", "username") VALUES (:id, :username)', $command->text);
$this->assertEquals(array(':id'=>1, ':username'=>'tester'), $command->params);
}
public function testUpdate()
{
$command=$this->_connection->createCommand();
$command->update('user', array('id'=>1, 'username'=>'tester'), 'status=:status', array(':status'=>2));
$this->assertEquals('UPDATE \'user\' SET "id"=:id, "username"=:username WHERE status=:status', $command->text);
$this->assertEquals(array(':id'=>1, ':username'=>'tester', ':status'=>2), $command->params);
}
public function testDelete()
{
$command=$this->_connection->createCommand();
$command->delete('user', 'status=:status', array(':status'=>2));
$this->assertEquals('DELETE FROM \'user\' WHERE status=:status', $command->text);
$this->assertEquals(array(':status'=>2), $command->params);
}
*/
public function testQuery()
{
// simple query
$command=$this->_connection->createCommand()
->select('username, password')
->from('users')
->where('email=:email or email=:email2', array(':email'=>'email2', ':email2'=>'email4'))
->order('username desc')
->limit(2,1);
$sql="SELECT \"username\", \"password\"\nFROM 'users'\nWHERE email=:email or email=:email2\nORDER BY \"username\" DESC LIMIT 2 OFFSET 1";
$this->assertEquals($sql, $command->text);
$rows=$command->queryAll();
$this->assertEquals(1,count($rows));
$this->assertEquals('user2',$rows[0]['username']);
$this->assertEquals('pass2',$rows[0]['password']);
}
public function testArraySyntax()
{
$command=$this->_connection->createCommand(array(
'select'=>'username, password',
'from'=>'users',
'where'=>'email=:email or email=:email2',
'params'=>array(':email'=>'email2', ':email2'=>'email4'),
'order'=>'username desc',
'limit'=>2,
'offset'=>1,
));
$sql="SELECT \"username\", \"password\"\nFROM 'users'\nWHERE email=:email or email=:email2\nORDER BY \"username\" DESC LIMIT 2 OFFSET 1";
$this->assertEquals($sql, $command->text);
$rows=$command->queryAll();
$this->assertEquals(1,count($rows));
$this->assertEquals('user2',$rows[0]['username']);
$this->assertEquals('pass2',$rows[0]['password']);
}
}

View File

@@ -0,0 +1,239 @@
<?php
Yii::import('system.db.CDbConnection');
class CDbCommandTest extends CTestCase
{
private $_connection;
public function setUp()
{
if(!extension_loaded('pdo') || !extension_loaded('pdo_sqlite'))
$this->markTestSkipped('PDO and SQLite extensions are required.');
$this->_connection=new CDbConnection('sqlite::memory:');
$this->_connection->active=true;
$this->_connection->pdoInstance->exec(file_get_contents(dirname(__FILE__).'/data/sqlite.sql'));
}
public function tearDown()
{
$this->_connection->active=false;
}
public function testGetText()
{
$sql='SELECT * FROM posts';
$command=$this->_connection->createCommand($sql);
$this->assertEquals($command->text,$sql);
}
public function testSetText()
{
$sql='SELECT title FROM posts';
$command=$this->_connection->createCommand($sql);
$this->assertEquals($command->queryScalar(),'post 1');
$newSql='SELECT id FROM posts';
$command->text=$newSql;
$this->assertEquals($command->text,$newSql);
$this->assertEquals($command->queryScalar(),1);
}
public function testConnection()
{
$sql='SELECT title FROM posts';
$command=$this->_connection->createCommand($sql);
$this->assertEquals($command->connection,$this->_connection);
}
public function testPrepare()
{
$sql='SELECT title FROM posts';
$command=$this->_connection->createCommand($sql);
$this->assertEquals($command->pdoStatement,null);
$command->prepare();
$this->assertTrue($command->pdoStatement instanceof PDOStatement);
$this->assertEquals($command->queryScalar(),'post 1');
$command->text='Bad SQL';
$this->setExpectedException('CException');
$command->prepare();
}
public function testCancel()
{
$sql='SELECT title FROM posts';
$command=$this->_connection->createCommand($sql);
$command->prepare();
$this->assertTrue($command->pdoStatement instanceof PDOStatement);
$command->cancel();
$this->assertEquals($command->pdoStatement,null);
}
public function testExecute()
{
$sql='INSERT INTO comments(content,post_id,author_id) VALUES (\'test comment\', 1, 1)';
$command=$this->_connection->createCommand($sql);
$this->assertEquals($command->execute(),1);
$this->assertEquals($command->execute(),1);
$command=$this->_connection->createCommand('SELECT * FROM comments WHERE content=\'test comment\'');
$this->assertEquals($command->execute(),0);
$command=$this->_connection->createCommand('SELECT COUNT(*) FROM comments WHERE content=\'test comment\'');
$this->assertEquals($command->queryScalar(),2);
$command=$this->_connection->createCommand('bad SQL');
$this->setExpectedException('CException');
$command->execute();
}
public function testQuery()
{
$sql='SELECT * FROM posts';
$reader=$this->_connection->createCommand($sql)->query();
$this->assertTrue($reader instanceof CDbDataReader);
$sql='SELECT * FROM posts';
$command=$this->_connection->createCommand($sql);
$command->prepare();
$reader=$command->query();
$this->assertTrue($reader instanceof CDbDataReader);
$command=$this->_connection->createCommand('bad SQL');
$this->setExpectedException('CException');
$command->query();
}
public function testBindParam()
{
$sql='INSERT INTO posts(title,create_time,author_id) VALUES (:title, :create_time, 1)';
$command=$this->_connection->createCommand($sql);
$title='test title';
$createTime=time();
$command->bindParam(':title',$title);
$command->bindParam(':create_time',$createTime);
$command->execute();
$sql='SELECT create_time FROM posts WHERE title=:title';
$command=$this->_connection->createCommand($sql);
$command->bindParam(':title',$title);
$this->assertEquals($command->queryScalar(),$createTime);
$sql='INSERT INTO types (int_col, char_col, float_col, blob_col, numeric_col, bool_col) VALUES (:int_col, :char_col, :float_col, :blob_col, :numeric_col, :bool_col)';
$command=$this->_connection->createCommand($sql);
$intCol=123;
$charCol='abc';
$floatCol=1.23;
$blobCol="\x10\x11\x12";
$numericCol='1.23';
$boolCol=false;
$command->bindParam(':int_col',$intCol);
$command->bindParam(':char_col',$charCol);
$command->bindParam(':float_col',$floatCol);
$command->bindParam(':blob_col',$blobCol);
$command->bindParam(':numeric_col',$numericCol);
$command->bindParam(':bool_col',$boolCol);
$this->assertEquals(1,$command->execute());
$sql='SELECT * FROM types';
$row=$this->_connection->createCommand($sql)->queryRow();
$this->assertEquals($row['int_col'],$intCol);
$this->assertEquals($row['char_col'],$charCol);
$this->assertEquals($row['float_col'],$floatCol);
$this->assertEquals($row['blob_col'],$blobCol);
$this->assertEquals($row['numeric_col'],$numericCol);
}
public function testBindValue()
{
$sql='INSERT INTO comments(content,post_id,author_id) VALUES (:content, 1, 1)';
$command=$this->_connection->createCommand($sql);
$command->bindValue(':content','test comment');
$command->execute();
$sql='SELECT post_id FROM comments WHERE content=:content';
$command=$this->_connection->createCommand($sql);
$command->bindValue(':content','test comment');
$this->assertEquals($command->queryScalar(),1);
}
public function testQueryAll()
{
$rows=$this->_connection->createCommand('SELECT * FROM posts')->queryAll();
$this->assertEquals(count($rows),5);
$row=$rows[2];
$this->assertEquals($row['id'],3);
$this->assertEquals($row['title'],'post 3');
$rows=$this->_connection->createCommand('SELECT * FROM posts WHERE id=10')->queryAll();
$this->assertEquals($rows,array());
}
public function testQueryRow()
{
$sql='SELECT * FROM posts';
$row=$this->_connection->createCommand($sql)->queryRow();
$this->assertEquals($row['id'],1);
$this->assertEquals($row['title'],'post 1');
$sql='SELECT * FROM posts';
$command=$this->_connection->createCommand($sql);
$command->prepare();
$row=$command->queryRow();
$this->assertEquals($row['id'],1);
$this->assertEquals($row['title'],'post 1');
$sql='SELECT * FROM posts WHERE id=10';
$command=$this->_connection->createCommand($sql);
$this->assertFalse($command->queryRow());
$command=$this->_connection->createCommand('bad SQL');
$this->setExpectedException('CException');
$command->queryRow();
}
public function testQueryColumn()
{
$sql='SELECT * FROM posts';
$column=$this->_connection->createCommand($sql)->queryColumn();
$this->assertEquals($column,range(1,5));
$command=$this->_connection->createCommand('SELECT id FROM posts WHERE id=10');
$this->assertEquals($command->queryColumn(),array());
$command=$this->_connection->createCommand('bad SQL');
$this->setExpectedException('CException');
$command->queryColumn();
}
public function testQueryScalar()
{
$sql='SELECT * FROM posts';
$this->assertEquals($this->_connection->createCommand($sql)->queryScalar(),1);
$sql='SELECT id FROM posts';
$command=$this->_connection->createCommand($sql);
$command->prepare();
$this->assertEquals($command->queryScalar(),1);
$command=$this->_connection->createCommand('SELECT id FROM posts WHERE id=10');
$this->assertFalse($command->queryScalar());
$command=$this->_connection->createCommand('bad SQL');
$this->setExpectedException('CException');
$command->queryScalar();
}
public function testFetchMode(){
$sql='SELECT * FROM posts';
$command=$this->_connection->createCommand($sql);
$result = $command->queryRow();
$this->assertTrue(is_array($result));
$sql='SELECT * FROM posts';
$command=$this->_connection->createCommand($sql);
$command->setFetchMode(PDO::FETCH_OBJ);
$result = $command->queryRow();
$this->assertTrue(is_object($result));
}
}

View File

@@ -0,0 +1,116 @@
<?php
Yii::import('system.db.CDbConnection');
class CDbConnectionTest extends CTestCase
{
private $_connection;
public function setUp()
{
if(!extension_loaded('pdo') || !extension_loaded('pdo_sqlite'))
$this->markTestSkipped('PDO and SQLite extensions are required.');
$this->_connection=new CDbConnection('sqlite::memory:');
}
public function tearDown()
{
$this->_connection->active=false;
}
public function testAutoConnect()
{
$db=new CDbConnection;
$db->connectionString='sqlite::memory:';
$this->assertFalse($db->active);
$this->assertTrue($db->autoConnect);
$db->init();
$this->assertTrue($db->active);
$db2=new CDbConnection;
$db2->connectionString='sqlite::memory:';
$db2->autoConnect=false;
$this->assertFalse($db2->autoConnect);
$this->assertFalse($db2->active);
$db->init();
$this->assertFalse($db2->active);
}
public function testInitialized()
{
$db=new CDbConnection;
$db->autoConnect=false;
$this->assertFalse($db->isInitialized);
$db->init();
$this->assertTrue($db->isInitialized);
}
public function testActive()
{
$this->assertFalse($this->_connection->active);
$this->_connection->active=true;
$this->assertTrue($this->_connection->active);
$pdo=$this->_connection->pdoInstance;
$this->assertTrue($pdo instanceof PDO);
$this->_connection->active=true;
$this->assertEquals($pdo,$this->_connection->pdoInstance);
$this->_connection->active=false;
$this->assertFalse($this->_connection->active);
$this->assertEquals($this->_connection->pdoInstance,null);
$connection=new CDbConnection('unknown::memory:');
$this->setExpectedException('CException');
$connection->active=true;
}
public function testCreateCommand()
{
$sql='SELECT * FROM posts';
$this->_connection->active=true;
$this->_connection->pdoInstance->exec(file_get_contents(dirname(__FILE__).'/data/sqlite.sql'));
$command=$this->_connection->createCommand($sql);
$this->assertTrue($command instanceof CDbCommand);
$this->_connection->active=false;
$this->setExpectedException('CException');
$this->_connection->createCommand($sql);
}
public function testLastInsertID()
{
$this->_connection->active=true;
$this->_connection->pdoInstance->exec(file_get_contents(dirname(__FILE__).'/data/sqlite.sql'));
$sql='INSERT INTO posts(title,create_time,author_id) VALUES(\'test post\',11000,1)';
$this->_connection->createCommand($sql)->execute();
$this->assertEquals($this->_connection->lastInsertID,6);
}
public function testQuoteValue()
{
$this->_connection->active=true;
$this->_connection->pdoInstance->exec(file_get_contents(dirname(__FILE__).'/data/sqlite.sql'));
$str="this is 'my' name";
$expectedStr="'this is ''my'' name'";
$this->assertEquals($expectedStr,$this->_connection->quoteValue($str));
}
public function testColumnNameCase()
{
$this->_connection->active=true;
$this->_connection->pdoInstance->exec(file_get_contents(dirname(__FILE__).'/data/sqlite.sql'));
$this->assertEquals(PDO::CASE_NATURAL,$this->_connection->ColumnCase);
$this->_connection->columnCase=PDO::CASE_LOWER;
$this->assertEquals(PDO::CASE_LOWER,$this->_connection->ColumnCase);
}
public function testNullConversion()
{
$this->_connection->active=true;
$this->_connection->pdoInstance->exec(file_get_contents(dirname(__FILE__).'/data/sqlite.sql'));
$this->assertEquals(PDO::NULL_NATURAL,$this->_connection->NullConversion);
$this->_connection->nullConversion=PDO::NULL_EMPTY_STRING;
$this->assertEquals(PDO::NULL_EMPTY_STRING,$this->_connection->NullConversion);
}
}

View File

@@ -0,0 +1,162 @@
<?php
Yii::import('system.db.CDbConnection');
class PostRecord extends CComponent
{
public $param1;
public $param2;
public $id;
private $_title;
public $content;
public $create_time;
public $author_id;
public function __construct($param1,$param2)
{
$this->param1=$param1;
$this->param2=$param2;
}
public function getTitle()
{
return $this->_title;
}
public function setTitle($value)
{
$this->_title=$value;
}
}
class CDbDataReaderTest extends CTestCase
{
private $_connection;
public function setUp()
{
if(!extension_loaded('pdo') || !extension_loaded('pdo_sqlite'))
$this->markTestSkipped('PDO and SQLite extensions are required.');
$this->_connection=new CDbConnection('sqlite::memory:');
$this->_connection->active=true;
$this->_connection->pdoInstance->exec(file_get_contents(dirname(__FILE__).'/data/sqlite.sql'));
}
public function tearDown()
{
$this->_connection->active=false;
}
public function testRead()
{
$reader=$this->_connection->createCommand('SELECT * FROM posts')->query();
for($i=1;$i<=5;++$i)
{
$row=$reader->read();
$this->assertEquals($row['id'],$i);
}
$this->assertFalse($reader->read());
}
public function testReadColumn()
{
$reader=$this->_connection->createCommand('SELECT * FROM posts')->query();
$this->assertEquals($reader->readColumn(0),1);
$this->assertEquals($reader->readColumn(1),'post 2');
$reader->readColumn(0);
$reader->readColumn(0);
$this->assertEquals($reader->readColumn(0),5);
$this->assertFalse($reader->readColumn(0));
}
public function testReadObject()
{
$reader=$this->_connection->createCommand('SELECT * FROM posts')->query();
$object=$reader->readObject('PostRecord',array(null,'v2'));
$this->assertEquals($object->id,1);
$this->assertEquals($object->title,'post 1');
$this->assertEquals($object->param1,null);
$this->assertEquals($object->param2,'v2');
}
public function testReadAll()
{
$reader=$this->_connection->createCommand('SELECT * FROM posts')->query();
$rows=$reader->readAll();
$this->assertEquals(count($rows),5);
$row=$rows[2];
$this->assertEquals($row['id'],3);
$this->assertEquals($row['title'],'post 3');
$reader=$this->_connection->createCommand('SELECT * FROM posts WHERE id=10')->query();
$this->assertEquals($reader->readAll(),array());
}
public function testClose()
{
$reader=$this->_connection->createCommand('SELECT * FROM posts')->query();
$row=$reader->read();
$row=$reader->read();
$this->assertFalse($reader->isClosed);
$reader->close();
$this->assertTrue($reader->isClosed);
}
public function testRowCount()
{
// unable to test because SQLite doesn't support row count
}
public function testColumnCount()
{
$reader=$this->_connection->createCommand('SELECT * FROM posts')->query();
$this->assertEquals($reader->columnCount,5);
$reader=$this->_connection->createCommand('SELECT * FROM posts WHERE id=11')->query();
$this->assertEquals($reader->ColumnCount,5);
}
public function testForeach()
{
$ids=array();
$reader=$this->_connection->createCommand('SELECT * FROM posts')->query();
foreach($reader as $row)
$ids[]=$row['id'];
$this->assertEquals(count($ids),5);
$this->assertEquals($ids[3],4);
$this->setExpectedException('CException');
foreach($reader as $row)
$ids[]=$row['id'];
}
public function testFetchMode()
{
$reader=$this->_connection->createCommand('SELECT * FROM posts')->query();
$reader->fetchMode=PDO::FETCH_NUM;
$row=$reader->read();
$this->assertFalse(isset($row['id']));
$this->assertTrue(isset($row[0]));
$reader->fetchMode=PDO::FETCH_ASSOC;
$row=$reader->read();
$this->assertTrue(isset($row['id']));
$this->assertFalse(isset($row[0]));
}
public function testBindColumn()
{
$reader=$this->_connection->createCommand('SELECT * FROM posts')->query();
$reader->bindColumn(1,$id);
$reader->bindColumn(2,$title);
$reader->read();
$this->assertEquals($id,1);
$this->assertEquals($title,'post 1');
$reader->read();
$this->assertEquals($id,2);
$this->assertEquals($title,'post 2');
}
}

View File

@@ -0,0 +1,63 @@
<?php
Yii::import('system.db.CDbConnection');
class CDbTransactionTest extends CTestCase
{
private $_connection;
public function setUp()
{
if(!extension_loaded('pdo') || !extension_loaded('pdo_sqlite'))
$this->markTestSkipped('PDO and SQLite extensions are required.');
$this->_connection=new CDbConnection('sqlite::memory:');
$this->_connection->active=true;
$this->_connection->pdoInstance->exec(file_get_contents(dirname(__FILE__).'/data/sqlite.sql'));
}
public function tearDown()
{
$this->_connection->active=false;
}
public function testBeginTransaction()
{
$sql='INSERT INTO posts(id,title,create_time,author_id) VALUES(10,\'test post\',11000,1)';
$transaction=$this->_connection->beginTransaction();
try
{
$this->_connection->createCommand($sql)->execute();
$this->_connection->createCommand($sql)->execute();
$this->fail('Expected exception not raised');
$transaction->commit();
}
catch(Exception $e)
{
$transaction->rollBack();
$reader=$this->_connection->createCommand('SELECT * FROM posts WHERE id=10')->query();
$this->assertFalse($reader->read());
}
}
public function testCommit()
{
$sql='INSERT INTO posts(id,title,create_time,author_id) VALUES(10,\'test post\',11000,1)';
$transaction=$this->_connection->beginTransaction();
try
{
$this->_connection->createCommand($sql)->execute();
$this->assertTrue($transaction->active);
$transaction->commit();
$this->assertFalse($transaction->active);
}
catch(Exception $e)
{
$transaction->rollBack();
$this->fail('Unexpected exception');
}
$n=$this->_connection->createCommand('SELECT COUNT(*) FROM posts WHERE id=10')->queryScalar();
$this->assertEquals($n,1);
}
}

View File

@@ -0,0 +1,596 @@
<?php
Yii::import('system.db.CDbConnection');
Yii::import('system.db.ar.CActiveRecord');
require_once(dirname(__FILE__).'/../data/models2.php');
class CActiveRecord2Test extends CTestCase
{
private $db;
public function setUp()
{
if(!extension_loaded('pdo') || !extension_loaded('pdo_pgsql'))
$this->markTestSkipped('PDO and PostgreSQL extensions are required.');
$this->db=new CDbConnection('pgsql:host=127.0.0.1;dbname=yii','test','test');
try
{
$this->db->active=true;
}
catch(Exception $e)
{
$schemaFile=realpath(dirname(__FILE__).'/../data/postgres.sql');
$this->markTestSkipped("Please read $schemaFile for details on setting up the test environment for PostgreSQL test case.");
}
try { $this->db->createCommand('DROP SCHEMA test CASCADE')->execute(); } catch(Exception $e) { }
try { $this->db->createCommand('DROP TABLE yii_types CASCADE')->execute(); } catch(Exception $e) { }
$sqls=file_get_contents(dirname(__FILE__).'/../data/postgres.sql');
foreach(explode(';',$sqls) as $sql)
{
if(trim($sql)!=='')
$this->db->createCommand($sql)->execute();
}
$this->db->active=false;
$config=array(
'basePath'=>dirname(__FILE__),
'components'=>array(
'db'=>array(
'class'=>'system.db.CDbConnection',
'connectionString'=>'pgsql:host=127.0.0.1;dbname=yii',
'username'=>'test',
'password'=>'test',
),
),
);
$app=new TestApplication($config);
$app->db->active=true;
CActiveRecord::$db=$this->db=$app->db;
}
public function tearDown()
{
$this->db->active=false;
}
public function testModel()
{
$model=Post2::model();
$this->assertTrue($model instanceof Post2);
$this->assertTrue($model->dbConnection===$this->db);
$this->assertTrue($model->dbConnection->active);
$this->assertEquals('test.posts',$model->tableName());
$this->assertEquals('id',$model->tableSchema->primaryKey);
$this->assertEquals('test.posts_id_seq',$model->tableSchema->sequenceName);
$this->assertEquals(array(),$model->attributeLabels());
$this->assertEquals('Id',$model->getAttributeLabel('id'));
$this->assertEquals('Author Id',$model->getAttributeLabel('author_id'));
$this->assertTrue($model->getActiveRelation('author') instanceof CBelongsToRelation);
$this->assertTrue($model->tableSchema instanceof CDbTableSchema);
$this->assertTrue($model->commandBuilder instanceof CDbCommandBuilder);
$this->assertTrue($model->hasAttribute('id'));
$this->assertFalse($model->hasAttribute('comments'));
$this->assertFalse($model->hasAttribute('foo'));
$this->assertEquals(array(),$model->getAttributes(false));
$post=new Post2;
$this->assertNull($post->id);
$this->assertNull($post->title);
$post->setAttributes(array('id'=>3,'title'=>'test title'));
$this->assertNull($post->id);
$this->assertEquals('test title',$post->title);
}
public function testFind()
{
// test find() with various parameters
$post=Post2::model()->find();
$this->assertTrue($post instanceof Post2);
$this->assertEquals(1,$post->id);
$post=Post2::model()->find('id=5');
$this->assertTrue($post instanceof Post2);
$this->assertEquals(5,$post->id);
$post=Post2::model()->find('id=:id',array(':id'=>2));
$this->assertTrue($post instanceof Post2);
$this->assertEquals(2,$post->id);
$post=Post2::model()->find(array('condition'=>'id=:id','params'=>array(':id'=>3)));
$this->assertTrue($post instanceof Post2);
$this->assertEquals(3,$post->id);
// test find() without result
$post=Post2::model()->find('id=6');
$this->assertNull($post);
// test findAll() with various parameters
$posts=Post2::model()->findAll();
$this->assertEquals(5,count($posts));
$this->assertTrue($posts[3] instanceof Post2);
$this->assertEquals(4,$posts[3]->id);
$posts=Post2::model()->findAll(new CDbCriteria(array('limit'=>3,'offset'=>1)));
$this->assertEquals(3,count($posts));
$this->assertTrue($posts[2] instanceof Post2);
$this->assertEquals(4,$posts[2]->id);
// test findAll() without result
$posts=Post2::model()->findAll('id=6');
$this->assertTrue($posts===array());
// test findByPk
$post=Post2::model()->findByPk(2);
$this->assertEquals(2,$post->id);
$post=Post2::model()->findByPk(array(3,2));
$this->assertEquals(2,$post->id);
$post=Post2::model()->findByPk(array());
$this->assertNull($post);
$post=Post2::model()->findByPk(6);
$this->assertNull($post);
// test findAllByPk
$posts=Post2::model()->findAllByPk(2);
$this->assertEquals(1,count($posts));
$this->assertEquals(2,$posts[0]->id);
$posts=Post2::model()->findAllByPk(array(4,3,2),'id<4');
$this->assertEquals(2,count($posts));
$this->assertEquals(2,$posts[0]->id);
$this->assertEquals(3,$posts[1]->id);
$posts=Post2::model()->findAllByPk(array());
$this->assertTrue($posts===array());
// test findByAttributes
$post=Post2::model()->findByAttributes(array('author_id'=>2),array('order'=>'id DESC'));
$this->assertEquals(4,$post->id);
// test findAllByAttributes
$posts=Post2::model()->findAllByAttributes(array('author_id'=>2));
$this->assertEquals(3,count($posts));
// test findBySql
$post=Post2::model()->findBySql('select * from test.posts where id=:id',array(':id'=>2));
$this->assertEquals(2,$post->id);
// test findAllBySql
$posts=Post2::model()->findAllBySql('select * from test.posts where id>:id',array(':id'=>2));
$this->assertEquals(3,count($posts));
// test count
$this->assertEquals(5,Post2::model()->count());
$this->assertEquals(3,Post2::model()->count(array('condition'=>'id>2')));
// test countBySql
$this->assertEquals(1,Post2::model()->countBySql('select id from test.posts limit 1'));
// test exists
$this->assertTrue(Post2::model()->exists('id=:id',array(':id'=>1)));
$this->assertFalse(Post2::model()->exists('id=:id',array(':id'=>6)));
}
public function testInsert()
{
$post=new Post2;
$this->assertEquals(array(),$post->getAttributes(false));
$post->title='test post 1';
$post->create_time='2004-10-19 10:23:54';
$post->author_id=1;
$post->content='test post content 1';
$this->assertTrue($post->isNewRecord);
$this->assertNull($post->id);
$this->assertTrue($post->save());
$this->assertEquals(array(
'id'=>6,
'title'=>'test post 1',
'create_time'=>$post->create_time,
'author_id'=>1,
'content'=>'test post content 1'),$post->getAttributes());
$this->assertFalse($post->isNewRecord);
$this->assertEquals($post->getAttributes(false),Post2::model()->findByPk($post->id)->getAttributes(false));
}
public function testUpdate()
{
// test save
$post=Post2::model()->findByPk(1);
$this->assertFalse($post->isNewRecord);
$this->assertEquals('post 1',$post->title);
$post->title='test post 1';
$this->assertTrue($post->save());
$this->assertFalse($post->isNewRecord);
$this->assertEquals('test post 1',$post->title);
$this->assertEquals('test post 1',Post2::model()->findByPk(1)->title);
// test updateByPk
$this->assertEquals(2,Post2::model()->updateByPk(array(4,5),array('title'=>'test post')));
$this->assertEquals('post 2',Post2::model()->findByPk(2)->title);
$this->assertEquals('test post',Post2::model()->findByPk(4)->title);
$this->assertEquals('test post',Post2::model()->findByPk(5)->title);
// test updateAll
$this->assertEquals(1,Post2::model()->updateAll(array('title'=>'test post'),'id=1'));
$this->assertEquals('test post',Post2::model()->findByPk(1)->title);
// test updateCounters
$this->assertEquals(2,Post2::model()->findByPk(2)->author_id);
$this->assertEquals(2,Post2::model()->findByPk(3)->author_id);
$this->assertEquals(2,Post2::model()->findByPk(4)->author_id);
$this->assertEquals(3,Post2::model()->updateCounters(array('author_id'=>-1),'id>2'));
$this->assertEquals(2,Post2::model()->findByPk(2)->author_id);
$this->assertEquals(1,Post2::model()->findByPk(3)->author_id);
$this->assertEquals(1,Post2::model()->findByPk(4)->author_id);
$this->assertEquals(2,Post2::model()->findByPk(5)->author_id);
}
public function testDelete()
{
$post=Post2::model()->findByPk(1);
$this->assertTrue($post->delete());
$this->assertNull(Post2::model()->findByPk(1));
$this->assertTrue(Post2::model()->findByPk(2) instanceof Post2);
$this->assertTrue(Post2::model()->findByPk(3) instanceof Post2);
$this->assertEquals(2,Post2::model()->deleteByPk(array(2,3)));
$this->assertNull(Post2::model()->findByPk(2));
$this->assertNull(Post2::model()->findByPk(3));
$this->assertTrue(Post2::model()->findByPk(5) instanceof Post2);
$this->assertEquals(1,Post2::model()->deleteAll('id=5'));
$this->assertNull(Post2::model()->findByPk(5));
}
public function testRefresh()
{
$post=Post2::model()->findByPk(1);
$post2=Post2::model()->findByPk(1);
$post2->title='new post';
$post2->save();
$this->assertEquals('post 1',$post->title);
$this->assertTrue($post->refresh());
$this->assertEquals('new post',$post->title);
}
public function testEquals()
{
$post=Post2::model()->findByPk(1);
$post2=Post2::model()->findByPk(1);
$post3=Post2::model()->findByPk(3);
$this->assertEquals(1,$post->primaryKey);
$this->assertTrue($post->equals($post2));
$this->assertTrue($post2->equals($post));
$this->assertFalse($post->equals($post3));
$this->assertFalse($post3->equals($post));
}
public function testValidation()
{
$user=new User2;
$user->password='passtest';
$this->assertFalse($user->hasErrors());
$this->assertEquals(array(),$user->errors);
$this->assertEquals(array(),$user->getErrors('username'));
$this->assertFalse($user->save());
$this->assertNull($user->id);
$this->assertTrue($user->isNewRecord);
$this->assertTrue($user->hasErrors());
$this->assertTrue($user->hasErrors('username'));
$this->assertTrue($user->hasErrors('email'));
$this->assertFalse($user->hasErrors('password'));
$this->assertEquals(1,count($user->getErrors('username')));
$this->assertEquals(1,count($user->getErrors('email')));
$this->assertEquals(2,count($user->errors));
$user->clearErrors();
$this->assertFalse($user->hasErrors());
$this->assertEquals(array(),$user->errors);
}
public function testCompositeKey()
{
$order=new Order2;
$this->assertEquals(array('key1','key2'),$order->tableSchema->primaryKey);
$order=Order2::model()->findByPk(array('key1'=>2,'key2'=>1));
$this->assertEquals('order 21',$order->name);
$orders=Order2::model()->findAllByPk(array(array('key1'=>2,'key2'=>1),array('key1'=>1,'key2'=>3)));
$this->assertEquals('order 13',$orders[0]->name);
$this->assertEquals('order 21',$orders[1]->name);
}
public function testDefault()
{
$type=new ComplexType2;
$this->assertEquals(1,$type->int_col2);
$this->assertEquals('something',$type->char_col2);
$this->assertEquals(1.23,$type->real_col);
$this->assertEquals(null,$type->numeric_col);
$this->assertEquals(null,$type->time);
$this->assertEquals(null,$type->bool_col);
$this->assertEquals(true,$type->bool_col2);
}
public function testPublicAttribute()
{
$post=new PostExt2;
$this->assertEquals(array('id'=>null,'title'=>'default title'),$post->getAttributes(false));
$post=Post2::model()->findByPk(1);
$this->assertEquals(array(
'id'=>1,
'title'=>'post 1',
'create_time'=>'2004-10-19 10:23:54',
'author_id'=>1,
'content'=>'content 1'),$post->getAttributes(false));
$post=new PostExt2;
$post->title='test post';
$post->create_time='2004-10-19 10:23:53';
$post->author_id=1;
$post->content='test';
$post->save();
$this->assertEquals(array(
'id'=>6,
'title'=>'test post',
'create_time'=>'2004-10-19 10:23:53',
'author_id'=>1,
'content'=>'test'),$post->getAttributes(false));
}
public function testLazyRelation()
{
// test belongsTo
$post=Post2::model()->findByPk(2);
$this->assertTrue($post->author instanceof User2);
$this->assertEquals(array(
'id'=>2,
'username'=>'user2',
'password'=>'pass2',
'email'=>'email2'),$post->author->getAttributes(false));
// test hasOne
$post=Post2::model()->findByPk(2);
$this->assertTrue($post->firstComment instanceof Comment2);
$this->assertEquals(array(
'id'=>4,
'content'=>'comment 4',
'post_id'=>2,
'author_id'=>2),$post->firstComment->getAttributes(false));
$post=Post2::model()->findByPk(4);
$this->assertNull($post->firstComment);
// test hasMany
$post=Post2::model()->findByPk(2);
$this->assertEquals(2,count($post->comments));
$this->assertEquals(array(
'id'=>5,
'content'=>'comment 5',
'post_id'=>2,
'author_id'=>2),$post->comments[0]->getAttributes(false));
$this->assertEquals(array(
'id'=>4,
'content'=>'comment 4',
'post_id'=>2,
'author_id'=>2),$post->comments[1]->getAttributes(false));
$post=Post2::model()->findByPk(4);
$this->assertEquals(array(),$post->comments);
// test manyMany
$post=Post2::model()->findByPk(2);
$this->assertEquals(2,count($post->categories));
// TODO: when joining, need to replace both placeholders for the two joinin tables
$this->assertEquals(array(
'id'=>4,
'name'=>'cat 4',
'parent_id'=>1),$post->categories[0]->getAttributes(false));
$this->assertEquals(array(
'id'=>1,
'name'=>'cat 1',
'parent_id'=>null),$post->categories[1]->getAttributes(false));
$post=Post2::model()->findByPk(4);
$this->assertEquals(array(),$post->categories);
// test self join
$category=Category2::model()->findByPk(5);
$this->assertEquals(array(),$category->posts);
$this->assertEquals(2,count($category->children));
$this->assertEquals(array(
'id'=>6,
'name'=>'cat 6',
'parent_id'=>5),$category->children[0]->getAttributes(false));
$this->assertEquals(array(
'id'=>7,
'name'=>'cat 7',
'parent_id'=>5),$category->children[1]->getAttributes(false));
$this->assertTrue($category->parent instanceof Category2);
$this->assertEquals(array(
'id'=>1,
'name'=>'cat 1',
'parent_id'=>null),$category->parent->getAttributes(false));
$category=Category2::model()->findByPk(2);
$this->assertEquals(1,count($category->posts));
$this->assertEquals(array(),$category->children);
$this->assertNull($category->parent);
// test composite key
$order=Order2::model()->findByPk(array('key1'=>1,'key2'=>2));
$this->assertEquals(2,count($order->items));
$order=Order2::model()->findByPk(array('key1'=>2,'key2'=>1));
$this->assertEquals(0,count($order->items));
$item=Item2::model()->findByPk(4);
$this->assertTrue($item->order instanceof Order2);
$this->assertEquals(array(
'key1'=>2,
'key2'=>2,
'name'=>'order 22'),$item->order->getAttributes(false));
}
public function testEagerRelation()
{
$post=Post2::model()->with('author','firstComment','comments','categories')->findByPk(2);
$this->assertEquals(array(
'id'=>2,
'username'=>'user2',
'password'=>'pass2',
'email'=>'email2'),$post->author->getAttributes(false));
$this->assertTrue($post->firstComment instanceof Comment2);
$this->assertEquals(array(
'id'=>4,
'content'=>'comment 4',
'post_id'=>2,
'author_id'=>2),$post->firstComment->getAttributes(false));
$this->assertEquals(2,count($post->comments));
$this->assertEquals(array(
'id'=>5,
'content'=>'comment 5',
'post_id'=>2,
'author_id'=>2),$post->comments[0]->getAttributes(false));
$this->assertEquals(array(
'id'=>4,
'content'=>'comment 4',
'post_id'=>2,
'author_id'=>2),$post->comments[1]->getAttributes(false));
$this->assertEquals(2,count($post->categories));
$this->assertEquals(array(
'id'=>4,
'name'=>'cat 4',
'parent_id'=>1),$post->categories[0]->getAttributes(false));
$this->assertEquals(array(
'id'=>1,
'name'=>'cat 1',
'parent_id'=>null),$post->categories[1]->getAttributes(false));
$post=Post2::model()->with('author','firstComment','comments','categories')->findByPk(4);
$this->assertEquals(array(
'id'=>2,
'username'=>'user2',
'password'=>'pass2',
'email'=>'email2'),$post->author->getAttributes(false));
$this->assertNull($post->firstComment);
$this->assertEquals(array(),$post->comments);
$this->assertEquals(array(),$post->categories);
}
public function testLazyRecursiveRelation()
{
$post=PostExt2::model()->findByPk(2);
$this->assertEquals(2,count($post->comments));
$this->assertTrue($post->comments[0]->post instanceof Post2);
$this->assertTrue($post->comments[1]->post instanceof Post2);
$this->assertTrue($post->comments[0]->author instanceof User2);
$this->assertTrue($post->comments[1]->author instanceof User2);
$this->assertEquals(3,count($post->comments[0]->author->posts));
$this->assertEquals(3,count($post->comments[1]->author->posts));
$this->assertTrue($post->comments[0]->author->posts[1]->author instanceof User2);
// test self join
$category=Category2::model()->findByPk(1);
$this->assertEquals(2,count($category->nodes));
$this->assertTrue($category->nodes[0]->parent instanceof Category2);
$this->assertTrue($category->nodes[1]->parent instanceof Category2);
$this->assertEquals(0,count($category->nodes[0]->children));
$this->assertEquals(2,count($category->nodes[1]->children));
}
public function testEagerRecursiveRelation()
{
$post=Post2::model()->with(array('comments'=>'author','categories'))->findByPk(2);
$this->assertEquals(2,count($post->comments));
$this->assertEquals(2,count($post->categories));
}
public function testRelationWithCondition()
{
$posts=Post2::model()->with('comments')->findAllByPk(array(2,3,4),array('order'=>'t.id'));
$this->assertEquals(3,count($posts));
$this->assertEquals(2,count($posts[0]->comments));
$this->assertEquals(4,count($posts[1]->comments));
$this->assertEquals(0,count($posts[2]->comments));
$post=Post2::model()->with('comments')->findByAttributes(array('id'=>2));
$this->assertTrue($post instanceof Post2);
$this->assertEquals(2,count($post->comments));
$posts=Post2::model()->with('comments')->findAllByAttributes(array('id'=>2));
$this->assertEquals(1,count($posts));
$post=Post2::model()->with('comments')->findBySql('select * from test.posts where id=:id',array(':id'=>2));
$this->assertTrue($post instanceof Post2);
$posts=Post2::model()->with('comments')->findAllBySql('select * from test.posts where id=:id1 OR id=:id2',array(':id1'=>2,':id2'=>3));
$this->assertEquals(2,count($posts));
$post=Post2::model()->with('comments','author')->find('t.id=:id',array(':id'=>2));
$this->assertTrue($post instanceof Post2);
$posts=Post2::model()->with('comments','author')->findAll(array(
'select'=>'title',
'condition'=>'t.id=:id',
'limit'=>1,
'offset'=>0,
'order'=>'t.title',
'params'=>array(':id'=>2)));
$this->assertTrue($posts[0] instanceof Post2);
$posts=Post2::model()->with('comments','author')->findAll(array(
'select'=>'title',
'condition'=>'t.id=:id',
'limit'=>1,
'offset'=>2,
'order'=>'t.title',
'params'=>array(':id'=>2)));
$this->assertTrue($posts===array());
}
public function testSelfManyMany()
{
$user=User2::model()->findByPk(1);
$this->assertTrue($user instanceof User2);
$friends=$user->friends;
$this->assertEquals(count($friends),2);
$this->assertEquals($friends[0]->id,2);
$this->assertEquals($friends[1]->id,3);
$user=User2::model()->with('friends')->findByPk(1);
$this->assertTrue($user instanceof User2);
$friends=$user->friends;
$this->assertEquals(count($friends),2);
$this->assertEquals($friends[0]->id,2);
$this->assertEquals($friends[1]->id,3);
}
public function testRelationalCount()
{
$count=Post2::model()->with('author','firstComment','comments','categories')->count();
$this->assertEquals(5,$count);
$count=Post2::model()->with('author','firstComment','comments','categories')->count('t.id=4');
$this->assertEquals(1,$count);
$count=Post2::model()->with('author','firstComment','comments','categories')->count('t.id=14');
$this->assertEquals(0,$count);
}
public function testEmptyFinding()
{
$post=Post2::model()->with('author','firstComment','comments','categories')->find('t.id=100');
$this->assertNull($post);
$posts=Post2::model()->with('author','firstComment','comments','categories')->findAll('t.id=100');
$this->assertTrue($posts===array());
$post=Post2::model()->with('author','firstComment','comments','categories')->findBySql('SELECT * FROM test.posts WHERE id=100');
$this->assertNull($post);
Post2::model()->with('author','firstComment','comments','categories')->findAllBySql('SELECT * FROM test.posts WHERE id=100');
$this->assertTrue($posts===array());
}
}

View File

@@ -0,0 +1,156 @@
<?php
Yii::import('system.db.CDbConnection');
Yii::import('system.db.ar.CActiveRecord');
require_once(dirname(__FILE__).'/../data/models.php');
class CActiveRecordEventWrappersTest extends CTestCase
{
private $_connection;
public function setUp()
{
if(!extension_loaded('pdo') || !extension_loaded('pdo_sqlite'))
$this->markTestSkipped('PDO and SQLite extensions are required.');
$this->_connection=new CDbConnection('sqlite::memory:');
$this->_connection->active=true;
$this->_connection->pdoInstance->exec(file_get_contents(dirname(__FILE__).'/../data/sqlite.sql'));
CActiveRecord::$db=$this->_connection;
UserWithWrappers::clearCounters();
PostWithWrappers::clearCounters();
CommentWithWrappers::clearCounters();
}
public function tearDown()
{
$this->_connection->active=false;
}
public function testBeforeFind()
{
UserWithWrappers::model()->find();
$this->assertEquals(UserWithWrappers::getCounter('beforeFind'),1);
UserWithWrappers::model()->findByAttributes(array('username'=>'user1'));
$this->assertEquals(UserWithWrappers::getCounter('beforeFind'),1);
UserWithWrappers::model()->findByPk(1);
$this->assertEquals(UserWithWrappers::getCounter('beforeFind'),1);
UserWithWrappers::model()->findBySql('SELECT * FROM users');
$this->assertEquals(UserWithWrappers::getCounter('beforeFind'),1);
UserWithWrappers::model()->findAll();
$this->assertEquals(UserWithWrappers::getCounter('beforeFind'),1);
UserWithWrappers::model()->findAllByAttributes(array('username'=>'user1'));
$this->assertEquals(UserWithWrappers::getCounter('beforeFind'),1);
UserWithWrappers::model()->findAllByPk(1);
$this->assertEquals(UserWithWrappers::getCounter('beforeFind'),1);
UserWithWrappers::model()->findAllBySql('SELECT * FROM users');
$this->assertEquals(UserWithWrappers::getCounter('beforeFind'),1);
}
public function testBeforeFindRelationalEager()
{
UserWithWrappers::model()->with('posts.comments')->find();
$this->assertEquals(UserWithWrappers::getCounter('beforeFind'),1);
$this->assertEquals(PostWithWrappers::getCounter('beforeFind'),1);
$this->assertEquals(CommentWithWrappers::getCounter('beforeFind'),1);
UserWithWrappers::model()->with('posts.comments')->findByAttributes(array('username'=>'user1'));
$this->assertEquals(UserWithWrappers::getCounter('beforeFind'),1);
$this->assertEquals(PostWithWrappers::getCounter('beforeFind'),1);
$this->assertEquals(CommentWithWrappers::getCounter('beforeFind'),1);
UserWithWrappers::model()->with('posts.comments')->findByPk(1);
$this->assertEquals(UserWithWrappers::getCounter('beforeFind'),1);
$this->assertEquals(PostWithWrappers::getCounter('beforeFind'),1);
$this->assertEquals(CommentWithWrappers::getCounter('beforeFind'),1);
UserWithWrappers::model()->with('posts.comments')->findBySql('SELECT * FROM users');
$this->assertEquals(UserWithWrappers::getCounter('beforeFind'),1);
$this->assertEquals(PostWithWrappers::getCounter('beforeFind'),1);
$this->assertEquals(CommentWithWrappers::getCounter('beforeFind'),1);
UserWithWrappers::model()->with('posts.comments')->findAll();
$this->assertEquals(UserWithWrappers::getCounter('beforeFind'),1);
$this->assertEquals(PostWithWrappers::getCounter('beforeFind'),1);
$this->assertEquals(CommentWithWrappers::getCounter('beforeFind'),1);
UserWithWrappers::model()->with('posts.comments')->findAllByAttributes(array('username'=>'user1'));
$this->assertEquals(UserWithWrappers::getCounter('beforeFind'),1);
$this->assertEquals(PostWithWrappers::getCounter('beforeFind'),1);
$this->assertEquals(CommentWithWrappers::getCounter('beforeFind'),1);
UserWithWrappers::model()->with('posts.comments')->findAllByPk(1);
$this->assertEquals(UserWithWrappers::getCounter('beforeFind'),1);
$this->assertEquals(PostWithWrappers::getCounter('beforeFind'),1);
$this->assertEquals(CommentWithWrappers::getCounter('beforeFind'),1);
UserWithWrappers::model()->with('posts.comments')->findAllBySql('SELECT * FROM users');
$this->assertEquals(UserWithWrappers::getCounter('beforeFind'),1);
$this->assertEquals(PostWithWrappers::getCounter('beforeFind'),1);
$this->assertEquals(CommentWithWrappers::getCounter('beforeFind'),1);
}
public function testBeforeFindRelationalLazy()
{
$user=UserWithWrappers::model()->find();
$user->posts;
$this->assertEquals(UserWithWrappers::getCounter('beforeFind'),1);
$this->assertEquals(PostWithWrappers::getCounter('beforeFind'),1);
$user=UserWithWrappers::model()->find();
$user->posts(array('with'=>'comments'));
$this->assertEquals(UserWithWrappers::getCounter('beforeFind'),1);
$this->assertEquals(PostWithWrappers::getCounter('beforeFind'),1);
$this->assertEquals(CommentWithWrappers::getCounter('beforeFind'),1);
}
public function testAfterFind()
{
UserWithWrappers::model()->find();
$this->assertEquals(UserWithWrappers::getCounter('afterFind'),1);
UserWithWrappers::model()->findByAttributes(array('username'=>'user1'));
$this->assertEquals(UserWithWrappers::getCounter('afterFind'),1);
UserWithWrappers::model()->findByPk(1);
$this->assertEquals(UserWithWrappers::getCounter('afterFind'),1);
UserWithWrappers::model()->findBySql('SELECT * FROM users');
$this->assertEquals(UserWithWrappers::getCounter('afterFind'),1);
UserWithWrappers::model()->findAll();
$this->assertEquals(UserWithWrappers::getCounter('afterFind'),4);
UserWithWrappers::model()->findAllByAttributes(array('username'=>'user1'));
$this->assertEquals(UserWithWrappers::getCounter('afterFind'),1);
UserWithWrappers::model()->findAllByPk(1);
$this->assertEquals(UserWithWrappers::getCounter('afterFind'),1);
UserWithWrappers::model()->findAllBySql('SELECT * FROM users');
$this->assertEquals(UserWithWrappers::getCounter('afterFind'),4);
}
public function testAfterFindRelational()
{
UserWithWrappers::model()->with('posts.comments')->find();
$this->assertEquals(UserWithWrappers::getCounter('afterFind'),4);
$this->assertEquals(PostWithWrappers::getCounter('afterFind'),5);
$this->assertEquals(CommentWithWrappers::getCounter('afterFind'),10);
UserWithWrappers::model()->with('posts.comments')->findByAttributes(array('username'=>'user2'));
$this->assertEquals(UserWithWrappers::getCounter('afterFind'),1);
$this->assertEquals(PostWithWrappers::getCounter('afterFind'),3);
$this->assertEquals(CommentWithWrappers::getCounter('afterFind'),6);
UserWithWrappers::model()->with('posts.comments')->findByPk(2);
$this->assertEquals(UserWithWrappers::getCounter('afterFind'),1);
$this->assertEquals(PostWithWrappers::getCounter('afterFind'),3);
$this->assertEquals(CommentWithWrappers::getCounter('afterFind'),6);
UserWithWrappers::model()->with('posts.comments')->findBySql('SELECT * FROM users WHERE id=2');
$this->assertEquals(UserWithWrappers::getCounter('afterFind'),1);
$this->assertEquals(PostWithWrappers::getCounter('afterFind'),3);
$this->assertEquals(CommentWithWrappers::getCounter('afterFind'),6);
UserWithWrappers::model()->with('posts.comments')->findAll();
$this->assertEquals(UserWithWrappers::getCounter('afterFind'),4);
$this->assertEquals(PostWithWrappers::getCounter('afterFind'),5);
$this->assertEquals(CommentWithWrappers::getCounter('afterFind'),10);
UserWithWrappers::model()->with('posts.comments')->findAllByAttributes(array('username'=>'user2'));
$this->assertEquals(UserWithWrappers::getCounter('afterFind'),1);
$this->assertEquals(PostWithWrappers::getCounter('afterFind'),3);
$this->assertEquals(CommentWithWrappers::getCounter('afterFind'),6);
UserWithWrappers::model()->with('posts.comments')->findAllByPk(2);
$this->assertEquals(UserWithWrappers::getCounter('afterFind'),1);
$this->assertEquals(PostWithWrappers::getCounter('afterFind'),3);
$this->assertEquals(CommentWithWrappers::getCounter('afterFind'),6);
UserWithWrappers::model()->with('posts.comments')->findAllBySql('SELECT * FROM users');
$this->assertEquals(UserWithWrappers::getCounter('afterFind'),4);
$this->assertEquals(PostWithWrappers::getCounter('afterFind'),5);
$this->assertEquals(CommentWithWrappers::getCounter('afterFind'),10);
}
}

View File

@@ -0,0 +1,54 @@
<?php
/**
* Models for CActiveRecordHasManyThroughTest
*/
class TestUser extends CActiveRecord {
public static function model($className=__CLASS__) {
return parent::model($className);
}
public function tableName() {
return 'tbl_user';
}
public function relations() {
return array(
'usergroups'=>array(self::HAS_MANY, 'UserGroup', 'user_id'),
'groups'=>array(self::HAS_MANY, 'TestGroup', 'through'=>'usergroups'),
);
}
}
class TestGroup extends CActiveRecord {
public static function model($className=__CLASS__) {
return parent::model($className);
}
public function tableName() {
return 'tbl_group';
}
public function relations() {
return array(
'usergroups'=>array(self::HAS_MANY, 'TestUserGroup', 'group_id'),
'users'=>array(self::HAS_MANY, 'TestUser', 'through'=>'usergroups'),
);
}
}
class TestUserGroup extends CActiveRecord {
public static function model($className=__CLASS__) {
return parent::model($className);
}
public function tableName() {
return 'tbl_user_group';
}
public function relations() {
return array(
'users'=>array(self::BELONGS_TO, 'TestUser', 'user_id'),
'groups'=>array(self::BELONGS_TO, 'TestGroup', 'group_id'),
);
}
}

View File

@@ -0,0 +1,77 @@
<?php
Yii::import('system.db.CDbConnection');
Yii::import('system.db.ar.CActiveRecord');
require dirname(__FILE__).'/CActiveRecordHasManyThroughModels.php';
/**
* AR's HAS_MANY `through` option allows to use data from relation's binding
* table.
*/
class CActiveRecordHasManyThroughTest extends CTestCase {
private $dbPath;
private $db;
public function setUp(){
if(!extension_loaded('pdo') || !extension_loaded('pdo_sqlite'))
$this->markTestSkipped('PDO and SQLite extensions are required.');
// put db into runtime
$this->dbPath = dirname(dirname(dirname(dirname(__FILE__)))).'/assets/CActiveRecordHasManyThroughTest.sqlite';
$db = new SQLiteDatabase($this->dbPath);
$db->query(file_get_contents(dirname(__FILE__).'/CActiveRecordHasManyThroughTest.sql'));
unset($db);
$config=array(
'basePath'=>dirname(__FILE__),
'components'=>array(
'db'=>array(
'class'=>'system.db.CDbConnection',
'connectionString'=>'sqlite:'.$this->dbPath,
),
),
);
$app=new TestApplication($config);
$app->db->active=true;
CActiveRecord::$db=$this->db=$app->db;
}
public function tearDown(){
if($this->db)
$this->db->active=false;
// clean up db file
unlink($this->dbPath);
}
public function testEager(){
$user = User::model()->with('groups')->findByPk(1);
$result = array();
foreach($user->groups as $group){
foreach($group->usergroups as $usergroup){
$result[] = array($user->usename, $group->name, $usergroup->role);
}
}
$this->assertEquals(array(
array('Alexander', 'Yii', 'dev'),
array('Alexander', 'Zii', 'user'),
), $result);
}
public function testLazy(){
$user = User::model()->findByPk(1);
$result = array();
foreach($user->groups as $group){
foreach($group->usergroups as $usergroup){
$result[] = array($user->usename, $group->name, $usergroup->role);
}
}
$this->assertEquals(array(
array('Alexander', 'Yii', 'dev'),
array('Alexander', 'Zii', 'user'),
), $result);
}
}

View File

@@ -0,0 +1,29 @@
BEGIN;
CREATE TABLE tbl_user (
id INTEGER PRIMARY KEY,
username VARCHAR(255)
);
CREATE TABLE tbl_group (
id INTEGER PRIMARY KEY,
name VARCHAR(255)
);
CREATE TABLE tbl_user_group (
user_id INTEGER,
group_id INTEGER,
role VARCHAR(255)
);
INSERT INTO tbl_user (id, username) VALUES(1, 'Alexander');
INSERT INTO tbl_user (id, username) VALUES(2, 'Qiang');
INSERT INTO tbl_group (id, name) VALUES(1, 'Yii');
INSERT INTO tbl_group (id, name) VALUES(2, 'Zii');
INSERT INTO tbl_user_group (user_id, group_id, role) VALUES(1, 1, 'dev');
INSERT INTO tbl_user_group (user_id, group_id, role) VALUES(1, 2, 'user');
INSERT INTO tbl_user_group (user_id, group_id, role) VALUES(2, 1, 'dev');
COMMIT;

View File

@@ -0,0 +1,878 @@
<?php
Yii::import('system.db.CDbConnection');
Yii::import('system.db.ar.CActiveRecord');
require_once(dirname(__FILE__).'/../data/models.php');
class CActiveRecordTest extends CTestCase
{
private $_connection;
protected function setUp()
{
if(!extension_loaded('pdo') || !extension_loaded('pdo_sqlite'))
$this->markTestSkipped('PDO and SQLite extensions are required.');
$this->_connection=new CDbConnection('sqlite::memory:');
$this->_connection->active=true;
$this->_connection->pdoInstance->exec(file_get_contents(dirname(__FILE__).'/../data/sqlite.sql'));
CActiveRecord::$db=$this->_connection;
}
protected function tearDown()
{
$this->_connection->active=false;
}
public function testModel()
{
$model=Post::model();
$this->assertTrue($model instanceof Post);
$this->assertTrue($model->dbConnection===$this->_connection);
$this->assertTrue($model->dbConnection->active);
$this->assertEquals('posts',$model->tableName());
$this->assertEquals('id',$model->tableSchema->primaryKey);
$this->assertTrue($model->tableSchema->sequenceName==='');
$this->assertEquals(array(),$model->attributeLabels());
$this->assertEquals('Id',$model->getAttributeLabel('id'));
$this->assertEquals('Author Id',$model->getAttributeLabel('author_id'));
$this->assertTrue($model->getActiveRelation('author') instanceof CBelongsToRelation);
$this->assertTrue($model->tableSchema instanceof CDbTableSchema);
$this->assertTrue($model->commandBuilder instanceof CDbCommandBuilder);
$this->assertTrue($model->hasAttribute('id'));
$this->assertFalse($model->hasAttribute('comments'));
$this->assertFalse($model->hasAttribute('foo'));
$this->assertEquals(array('id'=>null,'title'=>null,'create_time'=>null,'author_id'=>null,'content'=>null),$model->attributes);
$post=new Post;
$this->assertNull($post->id);
$this->assertNull($post->title);
$post->setAttributes(array('id'=>3,'title'=>'test title'));
$this->assertNull($post->id);
$this->assertEquals('test title',$post->title);
}
public function testFind()
{
// test find() with various parameters
$post=Post::model()->find();
$this->assertTrue($post instanceof Post);
$this->assertEquals(1,$post->id);
$post=Post::model()->find('id=5');
$this->assertTrue($post instanceof Post);
$this->assertEquals(5,$post->id);
$post=Post::model()->find('id=:id',array(':id'=>2));
$this->assertTrue($post instanceof Post);
$this->assertEquals(2,$post->id);
$post=Post::model()->find(array('condition'=>'id=:id','params'=>array(':id'=>3)));
$this->assertTrue($post instanceof Post);
$this->assertEquals(3,$post->id);
// test find() without result
$post=Post::model()->find('id=6');
$this->assertNull($post);
// test findAll() with various parameters
$posts=Post::model()->findAll();
$this->assertEquals(5,count($posts));
$this->assertTrue($posts[3] instanceof Post);
$this->assertEquals(4,$posts[3]->id);
$posts=Post::model()->findAll(new CDbCriteria(array('limit'=>3,'offset'=>1)));
$this->assertEquals(3,count($posts));
$this->assertTrue($posts[2] instanceof Post);
$this->assertEquals(4,$posts[2]->id);
// test findAll() without result
$posts=Post::model()->findAll('id=6');
$this->assertTrue($posts===array());
// test findByPk
$post=Post::model()->findByPk(2);
$this->assertEquals(2,$post->id);
$post=Post::model()->findByPk(array(3,2));
$this->assertEquals(2,$post->id);
$post=Post::model()->findByPk(array());
$this->assertNull($post);
$post=Post::model()->findByPk(6);
$this->assertNull($post);
// test findAllByPk
$posts=Post::model()->findAllByPk(2);
$this->assertEquals(1,count($posts));
$this->assertEquals(2,$posts[0]->id);
$posts=Post::model()->findAllByPk(array(4,3,2),'id<4');
$this->assertEquals(2,count($posts));
$this->assertEquals(2,$posts[0]->id);
$this->assertEquals(3,$posts[1]->id);
$posts=Post::model()->findAllByPk(array());
$this->assertTrue($posts===array());
// test findByAttributes
$post=Post::model()->findByAttributes(array('author_id'=>2),array('order'=>'id DESC'));
$this->assertEquals(4,$post->id);
// test findAllByAttributes
$posts=Post::model()->findAllByAttributes(array('author_id'=>2));
$this->assertEquals(3,count($posts));
// test findBySql
$post=Post::model()->findBySql('select * from posts where id=:id',array(':id'=>2));
$this->assertEquals(2,$post->id);
// test findAllBySql
$posts=Post::model()->findAllBySql('select * from posts where id>:id',array(':id'=>2));
$this->assertEquals(3,count($posts));
// test count
$this->assertEquals(5,Post::model()->count());
$this->assertEquals(3,Post::model()->count(array('condition'=>'id>2')));
// test countBySql
$this->assertEquals(1,Post::model()->countBySql('select id from posts limit 1'));
// test exists
$this->assertTrue(Post::model()->exists('id=:id',array(':id'=>1)));
$this->assertFalse(Post::model()->exists('id=:id',array(':id'=>6)));
}
public function testInsert()
{
$post=new Post;
$this->assertEquals(array('id'=>null,'title'=>null,'create_time'=>null,'author_id'=>null,'content'=>null),$post->attributes);
$post->title='test post 1';
$post->create_time=time();
$post->author_id=1;
$post->content='test post content 1';
$this->assertTrue($post->isNewRecord);
$this->assertNull($post->id);
$this->assertTrue($post->save());
$this->assertEquals(array(
'id'=>6,
'title'=>'test post 1',
'create_time'=>$post->create_time,
'author_id'=>1,
'content'=>'test post content 1'),$post->attributes);
$this->assertFalse($post->isNewRecord);
$this->assertEquals($post->attributes,Post::model()->findByPk($post->id)->attributes);
}
public function testUpdate()
{
// test save
$post=Post::model()->findByPk(1);
$this->assertFalse($post->isNewRecord);
$this->assertEquals('post 1',$post->title);
$post->title='test post 1';
$this->assertTrue($post->save());
$this->assertFalse($post->isNewRecord);
$this->assertEquals('test post 1',$post->title);
$this->assertEquals('test post 1',Post::model()->findByPk(1)->title);
// test updateByPk
$this->assertEquals(2,Post::model()->updateByPk(array(4,5),array('title'=>'test post')));
$this->assertEquals('post 2',Post::model()->findByPk(2)->title);
$this->assertEquals('test post',Post::model()->findByPk(4)->title);
$this->assertEquals('test post',Post::model()->findByPk(5)->title);
// test updateAll
$this->assertEquals(1,Post::model()->updateAll(array('title'=>'test post'),'id=1'));
$this->assertEquals('test post',Post::model()->findByPk(1)->title);
// test updateCounters
$this->assertEquals(2,Post::model()->findByPk(2)->author_id);
$this->assertEquals(2,Post::model()->findByPk(3)->author_id);
$this->assertEquals(2,Post::model()->findByPk(4)->author_id);
$this->assertEquals(3,Post::model()->updateCounters(array('author_id'=>-1),'id>2'));
$this->assertEquals(2,Post::model()->findByPk(2)->author_id);
$this->assertEquals(1,Post::model()->findByPk(3)->author_id);
}
public function testDelete()
{
$post=Post::model()->findByPk(1);
$this->assertTrue($post->delete());
$this->assertNull(Post::model()->findByPk(1));
$this->assertTrue(Post::model()->findByPk(2) instanceof Post);
$this->assertTrue(Post::model()->findByPk(3) instanceof Post);
$this->assertEquals(2,Post::model()->deleteByPk(array(2,3)));
$this->assertNull(Post::model()->findByPk(2));
$this->assertNull(Post::model()->findByPk(3));
$this->assertTrue(Post::model()->findByPk(5) instanceof Post);
$this->assertEquals(1,Post::model()->deleteAll('id=5'));
$this->assertNull(Post::model()->findByPk(5));
}
public function testRefresh()
{
$post=Post::model()->findByPk(1);
$post2=Post::model()->findByPk(1);
$post2->title='new post';
$post2->save();
$this->assertEquals('post 1',$post->title);
$this->assertTrue($post->refresh());
$this->assertEquals('new post',$post->title);
}
public function testEquals()
{
$post=Post::model()->findByPk(1);
$post2=Post::model()->findByPk(1);
$post3=Post::model()->findByPk(3);
$this->assertEquals(1,$post->primaryKey);
$this->assertTrue($post->equals($post2));
$this->assertTrue($post2->equals($post));
$this->assertFalse($post->equals($post3));
$this->assertFalse($post3->equals($post));
}
public function testValidation()
{
$user=new User;
$user->password='passtest';
$this->assertFalse($user->hasErrors());
$this->assertEquals(array(),$user->errors);
$this->assertEquals(array(),$user->getErrors('username'));
$this->assertFalse($user->save());
$this->assertNull($user->id);
$this->assertTrue($user->isNewRecord);
$this->assertTrue($user->hasErrors());
$this->assertTrue($user->hasErrors('username'));
$this->assertTrue($user->hasErrors('email'));
$this->assertFalse($user->hasErrors('password'));
$this->assertEquals(1,count($user->getErrors('username')));
$this->assertEquals(1,count($user->getErrors('email')));
$this->assertEquals(2,count($user->errors));
$user->clearErrors();
$this->assertFalse($user->hasErrors());
$this->assertEquals(array(),$user->errors);
}
public function testCompositeKey()
{
$order=new Order;
$this->assertEquals(array('key1','key2'),$order->tableSchema->primaryKey);
$order=Order::model()->findByPk(array('key1'=>2,'key2'=>1));
$this->assertEquals('order 21',$order->name);
$orders=Order::model()->findAllByPk(array(array('key1'=>2,'key2'=>1),array('key1'=>1,'key2'=>3)));
$this->assertEquals('order 13',$orders[0]->name);
$this->assertEquals('order 21',$orders[1]->name);
}
public function testDefault()
{
$type=new ComplexType;
$this->assertEquals(1,$type->int_col2);
$this->assertEquals('something',$type->char_col2);
$this->assertEquals(1.23,$type->float_col2);
$this->assertEquals(33.22,$type->numeric_col);
$this->assertEquals(123,$type->time);
$this->assertEquals(null,$type->bool_col);
$this->assertEquals(true,$type->bool_col2);
}
public function testPublicAttribute()
{
$post=new PostExt;
$this->assertEquals(array('id'=>null,'title'=>'default title','create_time'=>null,'author_id'=>null,'content'=>null),$post->attributes);
$post=Post::model()->findByPk(1);
$this->assertEquals(array(
'id'=>1,
'title'=>'post 1',
'create_time'=>100000,
'author_id'=>1,
'content'=>'content 1'),$post->attributes);
$post=new PostExt;
$post->title='test post';
$post->create_time=1000000;
$post->author_id=1;
$post->content='test';
$post->save();
$this->assertEquals(array(
'id'=>6,
'title'=>'test post',
'create_time'=>1000000,
'author_id'=>1,
'content'=>'test'),$post->attributes);
}
public function testLazyRelation()
{
// test belongsTo
$post=Post::model()->findByPk(2);
$this->assertTrue($post->author instanceof User);
$this->assertEquals(array(
'id'=>2,
'username'=>'user2',
'password'=>'pass2',
'email'=>'email2'),$post->author->attributes);
// test hasOne
$post=Post::model()->findByPk(2);
$this->assertTrue($post->firstComment instanceof Comment);
$this->assertEquals(array(
'id'=>4,
'content'=>'comment 4',
'post_id'=>2,
'author_id'=>2),$post->firstComment->attributes);
$post=Post::model()->findByPk(4);
$this->assertNull($post->firstComment);
// test hasMany
$post=Post::model()->findByPk(2);
$this->assertEquals(2,count($post->comments));
$this->assertEquals(array(
'id'=>5,
'content'=>'comment 5',
'post_id'=>2,
'author_id'=>2),$post->comments[0]->attributes);
$this->assertEquals(array(
'id'=>4,
'content'=>'comment 4',
'post_id'=>2,
'author_id'=>2),$post->comments[1]->attributes);
$post=Post::model()->findByPk(4);
$this->assertEquals(array(),$post->comments);
// test manyMany
$post=Post::model()->findByPk(2);
$this->assertEquals(2,count($post->categories));
$this->assertEquals(array(
'id'=>4,
'name'=>'cat 4',
'parent_id'=>1),$post->categories[0]->attributes);
$this->assertEquals(array(
'id'=>1,
'name'=>'cat 1',
'parent_id'=>null),$post->categories[1]->attributes);
$post=Post::model()->findByPk(4);
$this->assertEquals(array(),$post->categories);
// test self join
$category=Category::model()->findByPk(5);
$this->assertEquals(array(),$category->posts);
$this->assertEquals(2,count($category->children));
$this->assertEquals(array(
'id'=>6,
'name'=>'cat 6',
'parent_id'=>5),$category->children[0]->attributes);
$this->assertEquals(array(
'id'=>7,
'name'=>'cat 7',
'parent_id'=>5),$category->children[1]->attributes);
$this->assertTrue($category->parent instanceof Category);
$this->assertEquals(array(
'id'=>1,
'name'=>'cat 1',
'parent_id'=>null),$category->parent->attributes);
$category=Category::model()->findByPk(2);
$this->assertEquals(1,count($category->posts));
$this->assertEquals(array(),$category->children);
$this->assertNull($category->parent);
// test composite key
$order=Order::model()->findByPk(array('key1'=>1,'key2'=>2));
$this->assertEquals(2,count($order->items));
$order=Order::model()->findByPk(array('key1'=>2,'key2'=>1));
$this->assertEquals(0,count($order->items));
$item=Item::model()->findByPk(4);
$this->assertTrue($item->order instanceof Order);
$this->assertEquals(array(
'key1'=>2,
'key2'=>2,
'name'=>'order 22'),$item->order->attributes);
}
public function testEagerRelation2()
{
$post=Post::model()->with('author','firstComment','comments','categories')->findByPk(2);
}
private function checkEagerLoadedModel($post)
{
$this->assertEquals(array(
'id'=>2,
'username'=>'user2',
'password'=>'pass2',
'email'=>'email2'),$post->author->attributes);
$this->assertTrue($post->firstComment instanceof Comment);
$this->assertEquals(array(
'id'=>4,
'content'=>'comment 4',
'post_id'=>2,
'author_id'=>2),$post->firstComment->attributes);
$this->assertEquals(2,count($post->comments));
$this->assertEquals(array(
'id'=>5,
'content'=>'comment 5',
'post_id'=>2,
'author_id'=>2),$post->comments[0]->attributes);
$this->assertEquals(array(
'id'=>4,
'content'=>'comment 4',
'post_id'=>2,
'author_id'=>2),$post->comments[1]->attributes);
$this->assertEquals(2,count($post->categories));
$this->assertEquals(array(
'id'=>4,
'name'=>'cat 4',
'parent_id'=>1),$post->categories[0]->attributes);
$this->assertEquals(array(
'id'=>1,
'name'=>'cat 1',
'parent_id'=>null),$post->categories[1]->attributes);
}
public function testEagerRelation()
{
$post=Post::model()->with('author','firstComment','comments','categories')->findByPk(2);
$this->checkEagerLoadedModel($post);
$post=Post::model()->findByPk(2,array(
'with'=>array('author','firstComment','comments','categories'),
));
$this->checkEagerLoadedModel($post);
$post=Post::model()->with('author','firstComment','comments','categories')->findByPk(4);
$this->assertEquals(array(
'id'=>2,
'username'=>'user2',
'password'=>'pass2',
'email'=>'email2'),$post->author->attributes);
$this->assertNull($post->firstComment);
$this->assertEquals(array(),$post->comments);
$this->assertEquals(array(),$post->categories);
}
public function testLazyRecursiveRelation()
{
$post=PostExt::model()->findByPk(2);
$this->assertEquals(2,count($post->comments));
$this->assertTrue($post->comments[0]->post instanceof Post);
$this->assertTrue($post->comments[1]->post instanceof Post);
$this->assertTrue($post->comments[0]->author instanceof User);
$this->assertTrue($post->comments[1]->author instanceof User);
$this->assertEquals(3,count($post->comments[0]->author->posts));
$this->assertEquals(3,count($post->comments[1]->author->posts));
$this->assertTrue($post->comments[0]->author->posts[1]->author instanceof User);
// test self join
$category=Category::model()->findByPk(1);
$this->assertEquals(2,count($category->nodes));
$this->assertTrue($category->nodes[0]->parent instanceof Category);
$this->assertTrue($category->nodes[1]->parent instanceof Category);
$this->assertEquals(0,count($category->nodes[0]->children));
$this->assertEquals(2,count($category->nodes[1]->children));
}
public function testEagerRecursiveRelation()
{
//$post=Post::model()->with(array('comments'=>'author','categories'))->findByPk(2);
$post=Post::model()->with('comments.author','categories')->findByPk(2);
$this->assertEquals(2,count($post->comments));
$this->assertEquals(2,count($post->categories));
$posts=PostExt::model()->with('comments')->findAll();
$this->assertEquals(5,count($posts));
}
public function testRelationWithCondition()
{
$posts=Post::model()->with('comments')->findAllByPk(array(2,3,4),array('order'=>'t.id'));
$this->assertEquals(3,count($posts));
$this->assertEquals(2,count($posts[0]->comments));
$this->assertEquals(4,count($posts[1]->comments));
$this->assertEquals(0,count($posts[2]->comments));
$post=Post::model()->with('comments')->findByAttributes(array('id'=>2));
$this->assertTrue($post instanceof Post);
$this->assertEquals(2,count($post->comments));
$posts=Post::model()->with('comments')->findAllByAttributes(array('id'=>2));
$this->assertEquals(1,count($posts));
$post=Post::model()->with('comments')->findBySql('select * from posts where id=:id',array(':id'=>2));
$this->assertTrue($post instanceof Post);
$posts=Post::model()->with('comments')->findAllBySql('select * from posts where id=:id1 OR id=:id2',array(':id1'=>2,':id2'=>3));
$this->assertEquals(2,count($posts));
$post=Post::model()->with('comments','author')->find('t.id=:id',array(':id'=>2));
$this->assertTrue($post instanceof Post);
$posts=Post::model()->with('comments','author')->findAll(array(
'select'=>'title',
'condition'=>'t.id=:id',
'limit'=>1,
'offset'=>0,
'order'=>'t.title',
'group'=>'t.id',
'params'=>array(':id'=>2)));
$this->assertTrue($posts[0] instanceof Post);
$posts=Post::model()->with('comments','author')->findAll(array(
'select'=>'title',
'condition'=>'t.id=:id',
'limit'=>1,
'offset'=>2,
'order'=>'t.title',
'params'=>array(':id'=>2)));
$this->assertTrue($posts===array());
}
public function testRelationWithColumnAlias()
{
$users=User::model()->with('posts')->findAll(array(
'select'=>'id, username AS username2',
'order'=>'username2',
));
$this->assertEquals(4,count($users));
$this->assertEquals($users[1]->username,null);
$this->assertEquals($users[1]->username2,'user2');
}
public function testRelationalWithoutFK()
{
$users=UserNoFk::model()->with('posts')->findAll();
$this->assertEquals(4,count($users));
$this->assertEquals(3,count($users[1]->posts));
$posts=PostNoFk::model()->with('author')->findAll();
$this->assertEquals(5,count($posts));
$this->assertTrue($posts[2]->author instanceof UserNoFk);
}
public function testRelationWithNewRecord()
{
$user=new User;
$posts=$user->posts;
$this->assertTrue(is_array($posts) && empty($posts));
$post=new Post;
$author=$post->author;
$this->assertNull($author);
}
public function testRelationWithDynamicCondition()
{
$user=User::model()->with('posts')->findByPk(2);
$this->assertEquals($user->posts[0]->id,2);
$this->assertEquals($user->posts[1]->id,3);
$this->assertEquals($user->posts[2]->id,4);
$user=User::model()->with(array('posts'=>array('order'=>'posts.id DESC')))->findByPk(2);
$this->assertEquals($user->posts[0]->id,4);
$this->assertEquals($user->posts[1]->id,3);
$this->assertEquals($user->posts[2]->id,2);
}
public function testEagerTogetherRelation()
{
$post=Post::model()->with('author','firstComment','comments','categories')->findByPk(2);
$comments=$post->comments;
$this->assertEquals(array(
'id'=>2,
'username'=>'user2',
'password'=>'pass2',
'email'=>'email2'),$post->author->attributes);
$this->assertTrue($post->firstComment instanceof Comment);
$this->assertEquals(array(
'id'=>4,
'content'=>'comment 4',
'post_id'=>2,
'author_id'=>2),$post->firstComment->attributes);
$this->assertEquals(2,count($post->comments));
$this->assertEquals(array(
'id'=>5,
'content'=>'comment 5',
'post_id'=>2,
'author_id'=>2),$post->comments[0]->attributes);
$this->assertEquals(array(
'id'=>4,
'content'=>'comment 4',
'post_id'=>2,
'author_id'=>2),$post->comments[1]->attributes);
$this->assertEquals(2,count($post->categories));
$this->assertEquals(array(
'id'=>4,
'name'=>'cat 4',
'parent_id'=>1),$post->categories[0]->attributes);
$this->assertEquals(array(
'id'=>1,
'name'=>'cat 1',
'parent_id'=>null),$post->categories[1]->attributes);
$post=Post::model()->with('author','firstComment','comments','categories')->findByPk(4);
$this->assertEquals(array(
'id'=>2,
'username'=>'user2',
'password'=>'pass2',
'email'=>'email2'),$post->author->attributes);
$this->assertNull($post->firstComment);
$this->assertEquals(array(),$post->comments);
$this->assertEquals(array(),$post->categories);
}
public function testRelationalCount()
{
$count=Post::model()->with('author','firstComment','comments','categories')->count();
$this->assertEquals(5,$count);
$count=Post::model()->count(array('with'=>array('author','firstComment','comments','categories')));
$this->assertEquals(5,$count);
$count=Post::model()->with('author','firstComment','comments','categories')->count('t.id=4');
$this->assertEquals(1,$count);
$count=Post::model()->with('author','firstComment','comments','categories')->count('t.id=14');
$this->assertEquals(0,$count);
}
public function testRelationalStat()
{
$users=User::model()->with('postCount')->findAll();
$this->assertEquals(4,count($users));
$this->assertEquals(1,$users[0]->postCount);
$this->assertEquals(3,$users[1]->postCount);
$this->assertEquals(1,$users[2]->postCount);
$users=User::model()->findAll();
$this->assertEquals(4,count($users));
$this->assertEquals(1,$users[0]->postCount);
$this->assertEquals(3,$users[1]->postCount);
$this->assertEquals(1,$users[2]->postCount);
$orders=Order::model()->with('itemCount')->findAll();
$this->assertEquals(4,count($orders));
$this->assertEquals(2,$orders[0]->itemCount);
$this->assertEquals(1,$orders[1]->itemCount);
$this->assertEquals(0,$orders[2]->itemCount);
$this->assertEquals(2,$orders[3]->itemCount);
$orders=Order::model()->findAll();
$this->assertEquals(4,count($orders));
$this->assertEquals(2,$orders[0]->itemCount);
$this->assertEquals(1,$orders[1]->itemCount);
$this->assertEquals(0,$orders[2]->itemCount);
$this->assertEquals(2,$orders[3]->itemCount);
$categories=Category::model()->with('postCount')->findAll();
$this->assertEquals(7,count($categories));
$this->assertEquals(3,$categories[0]->postCount);
$this->assertEquals(1,$categories[1]->postCount);
$this->assertEquals(1,$categories[2]->postCount);
$this->assertEquals(1,$categories[3]->postCount);
$this->assertEquals(0,$categories[4]->postCount);
$this->assertEquals(0,$categories[5]->postCount);
$this->assertEquals(0,$categories[6]->postCount);
$categories=Category::model()->findAll();
$this->assertEquals(7,count($categories));
$this->assertEquals(3,$categories[0]->postCount);
$this->assertEquals(1,$categories[1]->postCount);
$this->assertEquals(1,$categories[2]->postCount);
$this->assertEquals(1,$categories[3]->postCount);
$this->assertEquals(0,$categories[4]->postCount);
$this->assertEquals(0,$categories[5]->postCount);
$this->assertEquals(0,$categories[6]->postCount);
$users=User::model()->with('postCount','posts.commentCount')->findAll();
$this->assertEquals(4,count($users));
}
public function testScopes()
{
$posts=Post::model()->post23()->findAll();
$this->assertEquals(2,count($posts));
$this->assertEquals(2,$posts[0]->id);
$this->assertEquals(3,$posts[1]->id);
$post=Post::model()->post23()->find();
$this->assertEquals(2,$post->id);
$posts=Post::model()->post23()->post3()->findAll();
$this->assertEquals(1,count($posts));
$this->assertEquals(3,$posts[0]->id);
$post=Post::model()->post23()->find();
$this->assertTrue($post instanceof Post);
$this->assertEquals(2,$post->id);
$posts=Post::model()->post23()->findAll('id=3');
$this->assertEquals(1,count($posts));
$this->assertEquals(3,$posts[0]->id);
$posts=Post::model()->recent()->with('author')->findAll();
$this->assertEquals(5,count($posts));
$this->assertEquals(5,$posts[0]->id);
$this->assertEquals(4,$posts[1]->id);
$posts=Post::model()->recent(3)->findAll();
$this->assertEquals(3,count($posts));
$this->assertEquals(5,$posts[0]->id);
$this->assertEquals(4,$posts[1]->id);
$posts=PostSpecial::model()->findAll();
$this->assertEquals(2,count($posts));
$this->assertEquals(2,$posts[0]->id);
$this->assertEquals(3,$posts[1]->id);
$posts=PostSpecial::model()->desc()->findAll();
$this->assertEquals(2,count($posts));
$this->assertEquals(3,$posts[0]->id);
$this->assertEquals(2,$posts[1]->id);
}
public function testResetScope(){
// resetting named scope
$posts=Post::model()->post23()->resetScope()->findAll();
$this->assertEquals(5,count($posts));
// resetting default scope
$posts=PostSpecial::model()->resetScope()->findAll();
$this->assertEquals(5,count($posts));
}
public function testLazyLoadingWithConditions()
{
$user=User::model()->findByPk(2);
$posts=$user->posts;
$this->assertEquals(3,count($posts));
$posts=$user->posts(array('condition'=>'posts.id>=3', 'alias'=>'posts'));
$this->assertEquals(2,count($posts));
}
public function testScopeWithRelations()
{
$user=User::model()->with('posts:post23')->findByPk(2);
$this->assertEquals(2,count($user->posts));
$this->assertEquals(2,$user->posts[0]->id);
$this->assertEquals(3,$user->posts[1]->id);
$user=UserSpecial::model()->findByPk(2);
$posts=$user->posts;
$this->assertEquals(2,count($posts));
$this->assertEquals(2,$posts[0]->id);
$this->assertEquals(3,$posts[1]->id);
$user=UserSpecial::model()->findByPk(2);
$posts=$user->posts(array('params'=>array(':id1'=>4),'order'=>'posts.id DESC'));
$this->assertEquals(2,count($posts));
$this->assertEquals(4,$posts[0]->id);
$this->assertEquals(3,$posts[1]->id);
}
public function testDuplicateLazyLoadingBug()
{
$user=User::model()->with(array(
'posts'=>array('on'=>'posts.id=-1')
))->findByPk(1);
// with the bug, an eager loading for 'posts' would be trigger in the following
// and result with non-empty posts
$this->assertTrue($user->posts===array());
}
public function testTogether()
{
// test without together
$users=UserNoTogether::model()->with('posts.comments')->findAll();
$postCount=0;
$commentCount=0;
foreach($users as $user)
{
$postCount+=count($user->posts);
foreach($posts=$user->posts as $post)
$commentCount+=count($post->comments);
}
$this->assertEquals(4,count($users));
$this->assertEquals(5,$postCount);
$this->assertEquals(10,$commentCount);
// test with together
$users=UserNoTogether::model()->with('posts.comments')->together()->findAll();
$postCount=0;
$commentCount=0;
foreach($users as $user)
{
$postCount+=count($user->posts);
foreach($posts=$user->posts as $post)
$commentCount+=count($post->comments);
}
$this->assertEquals(3,count($users));
$this->assertEquals(4,$postCount);
$this->assertEquals(10,$commentCount);
}
public function testTogetherWithOption()
{
// test with together off option
$users=User::model()->with(array(
'posts'=>array(
'with'=>array(
'comments'=>array(
'joinType'=>'INNER JOIN',
'together'=>false,
),
),
'joinType'=>'INNER JOIN',
'together'=>false,
),
))->findAll();
$postCount=0;
$commentCount=0;
foreach($users as $user)
{
$postCount+=count($user->posts);
foreach($posts=$user->posts as $post)
$commentCount+=count($post->comments);
}
$this->assertEquals(4,count($users));
$this->assertEquals(5,$postCount);
$this->assertEquals(10,$commentCount);
// test with together on option
$users=User::model()->with(array(
'posts'=>array(
'with'=>array(
'comments'=>array(
'joinType'=>'INNER JOIN',
'together'=>true,
),
),
'joinType'=>'INNER JOIN',
'together'=>true,
),
))->findAll();
$postCount=0;
$commentCount=0;
foreach($users as $user)
{
$postCount+=count($user->posts);
foreach($posts=$user->posts as $post)
$commentCount+=count($post->comments);
}
$this->assertEquals(3,count($users));
$this->assertEquals(4,$postCount);
$this->assertEquals(10,$commentCount);
}
public function testCountByAttributes()
{
$n=Post::model()->countByAttributes(array('author_id'=>2));
$this->assertEquals(3,$n);
}
}

View File

@@ -0,0 +1,596 @@
<?php
class User extends CActiveRecord
{
public $username2;
public static function model($class=__CLASS__)
{
return parent::model($class);
}
public function rules()
{
return array(
array('username, password, email', 'required'),
array('username, password', 'match', 'pattern'=>'/^[\d\w_]+$/'),
array('email', 'email'),
array('username', 'length', 'min'=>3, 'max'=>32),
array('password', 'length', 'min'=>6, 'max'=>32),
);
}
public function relations()
{
return array(
'posts'=>array(self::HAS_MANY,'Post','author_id'),
'postCount'=>array(self::STAT,'Post','author_id'),
);
}
public function tableName()
{
return 'users';
}
}
class Post extends CActiveRecord
{
public static function model($class=__CLASS__)
{
return parent::model($class);
}
public function relations()
{
return array(
'author'=>array(self::BELONGS_TO,'User','author_id'),
'firstComment'=>array(self::HAS_ONE,'Comment','post_id','order'=>'firstComment.content'),
'comments'=>array(self::HAS_MANY,'Comment','post_id','order'=>'comments.content DESC'),
'commentCount'=>array(self::STAT,'Comment','post_id'),
'categories'=>array(self::MANY_MANY,'Category','post_category(post_id,category_id)','order'=>'categories.id DESC'),
);
}
public function tableName()
{
return 'posts';
}
public function scopes()
{
return array(
'post23'=>array('condition'=>'posts.id=2 OR posts.id=3', 'alias'=>'posts', 'order'=>'posts.id'),
'post3'=>array('condition'=>'id=3'),
'postX'=>array('condition'=>'id=:id1 OR id=:id2', 'params'=>array(':id1'=>2, ':id2'=>3)),
);
}
public function rules()
{
return array(
array('title', 'required'),
);
}
public function recent($limit=5)
{
$this->getDbCriteria()->mergeWith(array(
'order'=>'create_time DESC',
'limit'=>$limit,
));
return $this;
}
}
class PostSpecial extends CActiveRecord
{
public static function model($class=__CLASS__)
{
return parent::model($class);
}
public function tableName()
{
return 'posts';
}
public function defaultScope()
{
return array(
'condition'=>'posts.id=:id1 OR posts.id=:id2',
'params'=>array(':id1'=>2, ':id2'=>3),
'alias'=>'posts',
);
}
public function scopes()
{
return array(
'desc'=>array('order'=>'id DESC'),
);
}
}
class UserSpecial extends CActiveRecord
{
public static function model($class=__CLASS__)
{
return parent::model($class);
}
public function relations()
{
return array(
'posts'=>array(self::HAS_MANY,'PostSpecial','author_id'),
);
}
public function tableName()
{
return 'users';
}
}
class PostExt extends CActiveRecord
{
public $title='default title';
public $id;
public static function model($class=__CLASS__)
{
return parent::model($class);
}
public function tableName()
{
return 'posts';
}
public function relations()
{
return array(
'comments'=>array(self::HAS_MANY,'Comment','post_id','order'=>'comments.content DESC','with'=>array('post'=>array('alias'=>'post'), 'author')),
);
}
}
class Comment extends CActiveRecord
{
public static function model($class=__CLASS__)
{
return parent::model($class);
}
public function relations()
{
return array(
'post'=>array(self::BELONGS_TO,'Post','post_id'),
'author'=>array(self::BELONGS_TO,'User','author_id'),
);
}
public function tableName()
{
return 'comments';
}
}
class Category extends CActiveRecord
{
public static function model($class=__CLASS__)
{
return parent::model($class);
}
public function tableName()
{
return 'categories';
}
public function relations()
{
return array(
'posts'=>array(self::MANY_MANY, 'Post', 'post_category(post_id,category_id)'),
'parent'=>array(self::BELONGS_TO,'Category','parent_id'),
'children'=>array(self::HAS_MANY,'Category','parent_id'),
'nodes'=>array(self::HAS_MANY,'Category','parent_id','with'=>array('parent','children')),
'postCount'=>array(self::STAT, 'Post', 'post_category(post_id,category_id)'),
);
}
}
class Order extends CActiveRecord
{
public static function model($class=__CLASS__)
{
return parent::model($class);
}
public function relations()
{
return array(
'items'=>array(self::HAS_MANY,'Item','col1, col2'),
'itemCount'=>array(self::STAT,'Item','col1, col2'),
);
}
public function tableName()
{
return 'orders';
}
}
class Item extends CActiveRecord
{
public static function model($class=__CLASS__)
{
return parent::model($class);
}
public function relations()
{
return array(
'order'=>array(self::BELONGS_TO,'Order','col1, col2','alias'=>'_order'),
);
}
public function tableName()
{
return 'items';
}
}
class ComplexType extends CActiveRecord
{
public static function model($class=__CLASS__)
{
return parent::model($class);
}
public function tableName()
{
return 'types';
}
}
class Content extends CActiveRecord
{
public static function model($class=__CLASS__)
{
return parent::model($class);
}
public function tableName()
{
return 'Content';
}
public function relations()
{
return array(
'parent'=>array(self::BELONGS_TO,'Content','parentID'),
'children'=>array(self::HAS_MANY,'Content','parentID'),
'owner'=>array(self::BELONGS_TO,'User','ownerID'),
);
}
}
class Article extends Content
{
public static function model($class=__CLASS__)
{
return parent::model($class);
}
public function tableName()
{
return 'Article';
}
public function relations()
{
return array(
'author'=>array(self::BELONGS_TO,'User','authorID'),
'comments'=>array(self::HAS_MANY,'ArticleComment','parentID'),
);
}
}
class ArticleComment extends Content
{
public static function model($class=__CLASS__)
{
return parent::model($class);
}
public function tableName()
{
return 'Comment';
}
public function relations()
{
return array(
'author'=>array(self::BELONGS_TO,'User','authorID'),
'article'=>array(self::BELONGS_TO,'Article','parentID'),
);
}
}
class UserNoFk extends CActiveRecord
{
public static function model($class=__CLASS__)
{
return parent::model($class);
}
public function relations()
{
return array(
'posts'=>array(self::HAS_MANY,'PostNoFk','author_id'),
);
}
public function tableName()
{
return 'users';
}
}
class PostNoFk extends CActiveRecord
{
public static function model($class=__CLASS__)
{
return parent::model($class);
}
public function relations()
{
return array(
'author'=>array(self::BELONGS_TO,'UserNoFk','author_id'),
);
}
public function tableName()
{
return 'posts_nofk';
}
}
class UserNoTogether extends CActiveRecord
{
public static function model($class=__CLASS__)
{
return parent::model($class);
}
public function relations()
{
return array(
'posts'=>array(self::HAS_MANY,'PostNoTogether','author_id','together'=>false,'joinType'=>'INNER JOIN'),
);
}
public function tableName()
{
return 'users';
}
}
class PostNoTogether extends CActiveRecord
{
public static function model($class=__CLASS__)
{
return parent::model($class);
}
public function relations()
{
return array(
'comments'=>array(self::HAS_MANY,'Comment','post_id','together'=>false,'joinType'=>'INNER JOIN'),
);
}
public function tableName()
{
return 'posts';
}
}
class UserWithWrappers extends CActiveRecord
{
private static $_counters=array();
public static function model($class=__CLASS__)
{
return parent::model($class);
}
public function relations()
{
return array(
'posts'=>array(self::HAS_MANY,'PostWithWrappers','author_id'),
'postCount'=>array(self::STAT,'PostWithWrappers','author_id'),
);
}
public function tableName()
{
return 'users';
}
protected function beforeFind()
{
parent::beforeFind();
$this->incrementCounter(__FUNCTION__);
}
protected function afterFind()
{
parent::afterFind();
$this->incrementCounter(__FUNCTION__);
}
protected function incrementCounter($wrapper)
{
if(isset(self::$_counters[$wrapper]))
self::$_counters[$wrapper]++;
else
self::$_counters[$wrapper]=1;
}
public static function getCounter($wrapper)
{
if(isset(self::$_counters[$wrapper]))
{
$result=self::$_counters[$wrapper];
}
else
$result=0;
self::clearCounters();
return $result;
}
public static function clearCounters()
{
self::$_counters=array();
}
}
class PostWithWrappers extends CActiveRecord
{
private static $_counters=array();
public static function model($class=__CLASS__)
{
return parent::model($class);
}
public function relations()
{
return array(
'author'=>array(self::BELONGS_TO,'UserWithWrappers','author_id'),
'comments'=>array(self::HAS_MANY,'CommentWithWrappers','post_id','order'=>'comments.content DESC'),
'commentCount'=>array(self::STAT,'CommentWithWrappers','post_id'),
);
}
public function tableName()
{
return 'posts';
}
public function rules()
{
return array(
array('title', 'required'),
);
}
protected function beforeFind()
{
parent::beforeFind();
$this->incrementCounter(__FUNCTION__);
}
protected function afterFind()
{
parent::afterFind();
$this->incrementCounter(__FUNCTION__);
}
protected function incrementCounter($wrapper)
{
if(isset(self::$_counters[$wrapper]))
self::$_counters[$wrapper]++;
else
self::$_counters[$wrapper]=1;
}
public static function getCounter($wrapper)
{
if(isset(self::$_counters[$wrapper]))
{
$result=self::$_counters[$wrapper];
}
else
$result=0;
self::clearCounters();
return $result;
}
public static function clearCounters()
{
self::$_counters=array();
}
}
class CommentWithWrappers extends CActiveRecord
{
private static $_counters=array();
public static function model($class=__CLASS__)
{
return parent::model($class);
}
public function relations()
{
return array(
'post'=>array(self::BELONGS_TO,'PostWithWrappers','post_id'),
'author'=>array(self::BELONGS_TO,'UserWithWrappers','author_id'),
);
}
public function tableName()
{
return 'comments';
}
protected function beforeFind()
{
parent::beforeFind();
$this->incrementCounter(__FUNCTION__);
}
protected function afterFind()
{
parent::afterFind();
$this->incrementCounter(__FUNCTION__);
}
protected function incrementCounter($wrapper)
{
if(isset(self::$_counters[$wrapper]))
self::$_counters[$wrapper]++;
else
self::$_counters[$wrapper]=1;
}
public static function getCounter($wrapper)
{
if(isset(self::$_counters[$wrapper]))
{
$result=self::$_counters[$wrapper];
}
else
$result=0;
self::clearCounters();
return $result;
}
public static function clearCounters()
{
self::$_counters=array();
}
}

View File

@@ -0,0 +1,185 @@
<?php
class User2 extends CActiveRecord
{
public static function model($class=__CLASS__)
{
return parent::model($class);
}
public function rules()
{
return array(
array('username, password, email', 'required'),
array('username, password', 'match', 'pattern'=>'/^[\d\w_]+$/'),
array('email', 'email'),
array('username', 'length', 'min'=>3, 'max'=>32),
array('password', 'length', 'min'=>6, 'max'=>32),
);
}
public function relations()
{
return array(
'posts'=>array(self::HAS_MANY,'Post2','author_id'),
'friends'=>array(self::MANY_MANY,'User2','test.user_friends(id,friend)'),
);
}
public function tableName()
{
return 'test.users';
}
}
class Post2 extends CActiveRecord
{
public static function model($class=__CLASS__)
{
return parent::model($class);
}
public function relations()
{
return array(
'author'=>array(self::BELONGS_TO,'User2','author_id'),
'firstComment'=>array(self::HAS_ONE,'Comment2','post_id','order'=>'"firstComment".content'),
'comments'=>array(self::HAS_MANY,'Comment2','post_id','order'=>'comments.content DESC'),
'categories'=>array(self::MANY_MANY,'Category2','test.post_category(post_id,category_id)','order'=>'categories.id DESC'),
);
}
public function rules()
{
return array(
array('title', 'required'),
);
}
public function tableName()
{
return 'test.posts';
}
}
class PostExt2 extends CActiveRecord
{
public $title='default title';
public $id;
public static function model($class=__CLASS__)
{
return parent::model($class);
}
public function tableName()
{
return 'test.posts';
}
public function relations()
{
return array(
'comments'=>array(self::HAS_MANY,'Comment2','post_id','order'=>'comments.content DESC','with'=>array('post'=>array('alias'=>'post'), 'author')),
);
}
}
class Comment2 extends CActiveRecord
{
public static function model($class=__CLASS__)
{
return parent::model($class);
}
public function relations()
{
return array(
'post'=>array(self::BELONGS_TO,'Post2','post_id'),
'author'=>array(self::BELONGS_TO,'User2','author_id'),
);
}
public function tableName()
{
return 'test.comments';
}
}
class Category2 extends CActiveRecord
{
public static function model($class=__CLASS__)
{
return parent::model($class);
}
public function tableName()
{
return 'test.categories';
}
public function relations()
{
return array(
'posts'=>array(self::MANY_MANY, 'Post2', 'test.post_category(post_id,category_id)'),
'parent'=>array(self::BELONGS_TO,'Category2','parent_id'),
'children'=>array(self::HAS_MANY,'Category2','parent_id'),
'nodes'=>array(self::HAS_MANY,'Category2','parent_id','with'=>array('parent','children')),
);
}
}
class Order2 extends CActiveRecord
{
public static function model($class=__CLASS__)
{
return parent::model($class);
}
public function relations()
{
return array(
'items'=>array(self::HAS_MANY,'Item2','col1, col2'),
);
}
public function tableName()
{
return 'test.orders';
}
}
class Item2 extends CActiveRecord
{
public static function model($class=__CLASS__)
{
return parent::model($class);
}
public function relations()
{
return array(
'order'=>array(self::BELONGS_TO,'Order2','col1, col2','alias'=>'_order'),
);
}
public function tableName()
{
return 'test.items';
}
}
class ComplexType2 extends CActiveRecord
{
public static function model($class=__CLASS__)
{
return parent::model($class);
}
public function tableName()
{
return 'yii_types';
}
}

View File

@@ -0,0 +1,306 @@
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
IF NOT EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[categories]') AND OBJECTPROPERTY(id, N'IsUserTable') = 1)
BEGIN
CREATE TABLE [dbo].[categories](
[id] [int] IDENTITY(1,1) NOT NULL,
[name] [varchar](128) NOT NULL,
[parent_id] [int] NULL,
CONSTRAINT [PK_categories] PRIMARY KEY CLUSTERED
(
[id] ASC
) ON [PRIMARY]
) ON [PRIMARY]
END
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
IF NOT EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[orders]') AND OBJECTPROPERTY(id, N'IsUserTable') = 1)
BEGIN
CREATE TABLE [dbo].[orders](
[key1] [int] NOT NULL,
[key2] [int] NOT NULL,
[name] [varchar](128) NOT NULL,
CONSTRAINT [PK_orders] PRIMARY KEY CLUSTERED
(
[key1] ASC,
[key2] ASC
) ON [PRIMARY]
) ON [PRIMARY]
END
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
IF NOT EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[types]') AND OBJECTPROPERTY(id, N'IsUserTable') = 1)
BEGIN
CREATE TABLE [dbo].[types](
[int_col] [int] NOT NULL,
[int_col2] [int] NULL CONSTRAINT [DF_types_int_col2] DEFAULT (1),
[char_col] [char](100) NOT NULL,
[char_col2] [varchar](100) NULL CONSTRAINT [DF_types_char_col2] DEFAULT ('something'),
[char_col3] [text] NULL,
[float_col] [real] NOT NULL,
[float_col2] [float] NULL CONSTRAINT [DF_types_float_col2] DEFAULT (1.23),
[blob_col] [image] NULL,
[numeric_col] [numeric](5, 2) NULL CONSTRAINT [DF_types_numeric_col] DEFAULT (33.22),
[time] [datetime] NULL CONSTRAINT [DF_types_time] DEFAULT ('2002-01-01 00:00:00'),
[bool_col] [bit] NOT NULL,
[bool_col2] [bit] NOT NULL CONSTRAINT [DF_types_bool_col2] DEFAULT (1)
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
END
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
IF NOT EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[users]') AND OBJECTPROPERTY(id, N'IsUserTable') = 1)
BEGIN
CREATE TABLE [dbo].[users](
[id] [int] IDENTITY(1,1) NOT NULL,
[username] [varchar](128) NOT NULL,
[password] [varchar](128) NOT NULL,
[email] [varchar](128) NOT NULL,
CONSTRAINT [PK_users] PRIMARY KEY CLUSTERED
(
[id] ASC
) ON [PRIMARY]
) ON [PRIMARY]
END
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
IF NOT EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[post_category]') AND OBJECTPROPERTY(id, N'IsUserTable') = 1)
BEGIN
CREATE TABLE [dbo].[post_category](
[category_id] [int] NOT NULL,
[post_id] [int] NOT NULL,
CONSTRAINT [PK_post_category] PRIMARY KEY CLUSTERED
(
[category_id] ASC,
[post_id] ASC
) ON [PRIMARY]
) ON [PRIMARY]
END
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
IF NOT EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[items]') AND OBJECTPROPERTY(id, N'IsUserTable') = 1)
BEGIN
CREATE TABLE [dbo].[items](
[id] [int] IDENTITY(1,1) NOT NULL,
[name] [varchar](128) NULL,
[col1] [int] NOT NULL,
[col2] [int] NOT NULL,
CONSTRAINT [PK_items] PRIMARY KEY CLUSTERED
(
[id] ASC
) ON [PRIMARY]
) ON [PRIMARY]
END
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
IF NOT EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[comments]') AND OBJECTPROPERTY(id, N'IsUserTable') = 1)
BEGIN
CREATE TABLE [dbo].[comments](
[id] [int] IDENTITY(1,1) NOT NULL,
[content] [text] NOT NULL,
[post_id] [int] NOT NULL,
[author_id] [int] NOT NULL,
CONSTRAINT [PK_comments] PRIMARY KEY CLUSTERED
(
[id] ASC
) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
END
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
IF NOT EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[posts]') AND OBJECTPROPERTY(id, N'IsUserTable') = 1)
BEGIN
CREATE TABLE [dbo].[posts](
[id] [int] IDENTITY(1,1) NOT NULL,
[title] [varchar](128) NOT NULL,
[create_time] [datetime] NOT NULL,
[author_id] [int] NOT NULL,
[content] [text] NULL,
CONSTRAINT [PK_posts] PRIMARY KEY CLUSTERED
(
[id] ASC
) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
END
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
IF NOT EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[profiles]') AND OBJECTPROPERTY(id, N'IsUserTable') = 1)
BEGIN
CREATE TABLE [dbo].[profiles](
[id] [int] IDENTITY(1,1) NOT NULL,
[first_name] [varchar](128) NOT NULL,
[last_name] [varchar](128) NOT NULL,
[user_id] [int] NOT NULL,
CONSTRAINT [PK_profiles] PRIMARY KEY CLUSTERED
(
[id] ASC
) ON [PRIMARY]
) ON [PRIMARY]
END
GO
IF NOT EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[FK_categories_categories]') AND type = 'F')
ALTER TABLE [dbo].[categories] WITH CHECK ADD CONSTRAINT [FK_categories_categories] FOREIGN KEY([parent_id])
REFERENCES [dbo].[categories] ([id])
GO
IF NOT EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[FK_post_category_categories]') AND type = 'F')
ALTER TABLE [dbo].[post_category] WITH CHECK ADD CONSTRAINT [FK_post_category_categories] FOREIGN KEY([category_id])
REFERENCES [dbo].[categories] ([id])
ON DELETE CASCADE
GO
IF NOT EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[FK_post_category_posts]') AND type = 'F')
ALTER TABLE [dbo].[post_category] WITH NOCHECK ADD CONSTRAINT [FK_post_category_posts] FOREIGN KEY([post_id])
REFERENCES [dbo].[posts] ([id])
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[post_category] CHECK CONSTRAINT [FK_post_category_posts]
GO
IF NOT EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[FK_items_orders]') AND type = 'F')
ALTER TABLE [dbo].[items] WITH CHECK ADD CONSTRAINT [FK_items_orders] FOREIGN KEY([col1], [col2])
REFERENCES [dbo].[orders] ([key1], [key2])
ON DELETE CASCADE
GO
IF NOT EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[FK_comments_users]') AND type = 'F')
ALTER TABLE [dbo].[comments] WITH NOCHECK ADD CONSTRAINT [FK_comments_users] FOREIGN KEY([author_id])
REFERENCES [dbo].[users] ([id])
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[comments] CHECK CONSTRAINT [FK_comments_users]
GO
IF NOT EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[FK_post_comment]') AND type = 'F')
ALTER TABLE [dbo].[comments] WITH NOCHECK ADD CONSTRAINT [FK_post_comment] FOREIGN KEY([post_id])
REFERENCES [dbo].[posts] ([id])
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[comments] CHECK CONSTRAINT [FK_post_comment]
GO
IF NOT EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[FK_posts_users]') AND type = 'F')
ALTER TABLE [dbo].[posts] WITH NOCHECK ADD CONSTRAINT [FK_posts_users] FOREIGN KEY([author_id])
REFERENCES [dbo].[users] ([id])
GO
ALTER TABLE [dbo].[posts] CHECK CONSTRAINT [FK_posts_users]
GO
IF NOT EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[FK_profile_user]') AND type = 'F')
ALTER TABLE [dbo].[profiles] WITH NOCHECK ADD CONSTRAINT [FK_profile_user] FOREIGN KEY([user_id])
REFERENCES [dbo].[users] ([id])
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[profiles] CHECK CONSTRAINT [FK_profile_user]
INSERT INTO users (username, password, email) VALUES ('user1','pass1','email1')
GO
INSERT INTO users (username, password, email) VALUES ('user2','pass2','email2')
GO
INSERT INTO users (username, password, email) VALUES ('user3','pass3','email3')
GO
INSERT INTO profiles (first_name, last_name, user_id) VALUES ('first 1','last 1',1)
GO
INSERT INTO profiles (first_name, last_name, user_id) VALUES ('first 2','last 2',2)
GO
INSERT INTO posts (title, create_time, author_id, content) VALUES ('post 1','2000-01-01',1,'content 1')
GO
INSERT INTO posts (title, create_time, author_id, content) VALUES ('post 2','2000-01-02',2,'content 2')
GO
INSERT INTO posts (title, create_time, author_id, content) VALUES ('post 3','2000-01-03',2,'content 3')
GO
INSERT INTO posts (title, create_time, author_id, content) VALUES ('post 4','2000-01-04',2,'content 4')
GO
INSERT INTO posts (title, create_time, author_id, content) VALUES ('post 5','2000-01-05',3,'content 5')
GO
INSERT INTO comments (content, post_id, author_id) VALUES ('comment 1',1, 2)
GO
INSERT INTO comments (content, post_id, author_id) VALUES ('comment 2',1, 2)
GO
INSERT INTO comments (content, post_id, author_id) VALUES ('comment 3',1, 2)
GO
INSERT INTO comments (content, post_id, author_id) VALUES ('comment 4',2, 2)
GO
INSERT INTO comments (content, post_id, author_id) VALUES ('comment 5',2, 2)
GO
INSERT INTO comments (content, post_id, author_id) VALUES ('comment 6',3, 2)
GO
INSERT INTO comments (content, post_id, author_id) VALUES ('comment 7',3, 2)
GO
INSERT INTO comments (content, post_id, author_id) VALUES ('comment 8',3, 2)
GO
INSERT INTO comments (content, post_id, author_id) VALUES ('comment 9',3, 2)
GO
INSERT INTO comments (content, post_id, author_id) VALUES ('comment 10',5, 3)
GO
INSERT INTO categories (name, parent_id) VALUES ('cat 1',NULL)
GO
INSERT INTO categories (name, parent_id) VALUES ('cat 2',NULL)
GO
INSERT INTO categories (name, parent_id) VALUES ('cat 3',NULL)
GO
INSERT INTO categories (name, parent_id) VALUES ('cat 4',1)
GO
INSERT INTO categories (name, parent_id) VALUES ('cat 5',1)
GO
INSERT INTO categories (name, parent_id) VALUES ('cat 6',5)
GO
INSERT INTO categories (name, parent_id) VALUES ('cat 7',5)
GO
INSERT INTO post_category (category_id, post_id) VALUES (1,1)
GO
INSERT INTO post_category (category_id, post_id) VALUES (2,1)
GO
INSERT INTO post_category (category_id, post_id) VALUES (3,1)
GO
INSERT INTO post_category (category_id, post_id) VALUES (4,2)
GO
INSERT INTO post_category (category_id, post_id) VALUES (1,2)
GO
INSERT INTO post_category (category_id, post_id) VALUES (1,3)
GO
INSERT INTO orders (key1,key2,name) VALUES (1,2,'order 12')
GO
INSERT INTO orders (key1,key2,name) VALUES (1,3,'order 13')
GO
INSERT INTO orders (key1,key2,name) VALUES (2,1,'order 21')
GO
INSERT INTO orders (key1,key2,name) VALUES (2,2,'order 22')
GO
INSERT INTO items (name,col1,col2) VALUES ('item 1',1,2)
GO
INSERT INTO items (name,col1,col2) VALUES ('item 2',1,2)
GO
INSERT INTO items (name,col1,col2) VALUES ('item 3',1,3)
GO
INSERT INTO items (name,col1,col2) VALUES ('item 4',2,2)
GO
INSERT INTO items (name,col1,col2) VALUES ('item 5',2,2)
GO

View File

@@ -0,0 +1,150 @@
/**
* This is the database schema for testing MySQL support of yii Active Record.
* To test this feature, you need to create a database named 'yii' on 'localhost'
* and create an account 'test/test' which owns this test database.
*/
CREATE TABLE users
(
id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(128) NOT NULL,
password VARCHAR(128) NOT NULL,
email VARCHAR(128) NOT NULL
) TYPE=INNODB;
INSERT INTO users (username, password, email) VALUES ('user1','pass1','email1');
INSERT INTO users (username, password, email) VALUES ('user2','pass2','email2');
INSERT INTO users (username, password, email) VALUES ('user3','pass3','email3');
CREATE TABLE profiles
(
id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
first_name VARCHAR(128) NOT NULL,
last_name VARCHAR(128) NOT NULL,
user_id INTEGER NOT NULL,
CONSTRAINT FK_profile_user FOREIGN KEY (user_id)
REFERENCES users (id) ON DELETE CASCADE ON UPDATE RESTRICT
) TYPE=INNODB;
INSERT INTO profiles (first_name, last_name, user_id) VALUES ('first 1','last 1',1);
INSERT INTO profiles (first_name, last_name, user_id) VALUES ('first 2','last 2',2);
CREATE TABLE posts
(
id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
title VARCHAR(128) NOT NULL,
create_time TIMESTAMP NOT NULL,
author_id INTEGER NOT NULL,
content TEXT,
CONSTRAINT FK_post_author FOREIGN KEY (author_id)
REFERENCES users (id) ON DELETE CASCADE ON UPDATE RESTRICT
) TYPE=INNODB;
INSERT INTO posts (title, create_time, author_id, content) VALUES ('post 1','2000-01-01',1,'content 1');
INSERT INTO posts (title, create_time, author_id, content) VALUES ('post 2','2000-01-02',2,'content 2');
INSERT INTO posts (title, create_time, author_id, content) VALUES ('post 3','2000-01-03',2,'content 3');
INSERT INTO posts (title, create_time, author_id, content) VALUES ('post 4','2000-01-04',2,'content 4');
INSERT INTO posts (title, create_time, author_id, content) VALUES ('post 5','2000-01-05',3,'content 5');
CREATE TABLE comments
(
id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
content TEXT NOT NULL,
post_id INTEGER NOT NULL,
author_id INTEGER NOT NULL,
CONSTRAINT FK_post_comment FOREIGN KEY (post_id)
REFERENCES posts (id) ON DELETE CASCADE ON UPDATE RESTRICT,
CONSTRAINT FK_user_comment FOREIGN KEY (author_id)
REFERENCES users (id) ON DELETE CASCADE ON UPDATE RESTRICT
) TYPE=INNODB;
INSERT INTO comments (content, post_id, author_id) VALUES ('comment 1',1, 2);
INSERT INTO comments (content, post_id, author_id) VALUES ('comment 2',1, 2);
INSERT INTO comments (content, post_id, author_id) VALUES ('comment 3',1, 2);
INSERT INTO comments (content, post_id, author_id) VALUES ('comment 4',2, 2);
INSERT INTO comments (content, post_id, author_id) VALUES ('comment 5',2, 2);
INSERT INTO comments (content, post_id, author_id) VALUES ('comment 6',3, 2);
INSERT INTO comments (content, post_id, author_id) VALUES ('comment 7',3, 2);
INSERT INTO comments (content, post_id, author_id) VALUES ('comment 8',3, 2);
INSERT INTO comments (content, post_id, author_id) VALUES ('comment 9',3, 2);
INSERT INTO comments (content, post_id, author_id) VALUES ('comment 10',5, 3);
CREATE TABLE categories
(
id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(128) NOT NULL,
parent_id INTEGER,
CONSTRAINT FK_category_category FOREIGN KEY (parent_id)
REFERENCES categories (id) ON DELETE CASCADE ON UPDATE RESTRICT
) TYPE=INNODB;
INSERT INTO categories (name, parent_id) VALUES ('cat 1',NULL);
INSERT INTO categories (name, parent_id) VALUES ('cat 2',NULL);
INSERT INTO categories (name, parent_id) VALUES ('cat 3',NULL);
INSERT INTO categories (name, parent_id) VALUES ('cat 4',1);
INSERT INTO categories (name, parent_id) VALUES ('cat 5',1);
INSERT INTO categories (name, parent_id) VALUES ('cat 6',5);
INSERT INTO categories (name, parent_id) VALUES ('cat 7',5);
CREATE TABLE post_category
(
category_id INTEGER NOT NULL,
post_id INTEGER NOT NULL,
PRIMARY KEY (category_id, post_id),
CONSTRAINT FK_post_category_post FOREIGN KEY (post_id)
REFERENCES posts (id) ON DELETE CASCADE ON UPDATE RESTRICT,
CONSTRAINT FK_post_category_category FOREIGN KEY (category_id)
REFERENCES categories (id) ON DELETE CASCADE ON UPDATE RESTRICT
) TYPE=INNODB;
INSERT INTO post_category (category_id, post_id) VALUES (1,1);
INSERT INTO post_category (category_id, post_id) VALUES (2,1);
INSERT INTO post_category (category_id, post_id) VALUES (3,1);
INSERT INTO post_category (category_id, post_id) VALUES (4,2);
INSERT INTO post_category (category_id, post_id) VALUES (1,2);
INSERT INTO post_category (category_id, post_id) VALUES (1,3);
CREATE TABLE orders
(
key1 INTEGER NOT NULL,
key2 INTEGER NOT NULL,
name VARCHAR(128),
PRIMARY KEY (key1, key2)
) TYPE=INNODB;
INSERT INTO orders (key1,key2,name) VALUES (1,2,'order 12');
INSERT INTO orders (key1,key2,name) VALUES (1,3,'order 13');
INSERT INTO orders (key1,key2,name) VALUES (2,1,'order 21');
INSERT INTO orders (key1,key2,name) VALUES (2,2,'order 22');
CREATE TABLE items
(
id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(128),
col1 INTEGER NOT NULL,
col2 INTEGER NOT NULL,
CONSTRAINT FK_order_item FOREIGN KEY (col1,col2)
REFERENCES orders (key1,key2) ON DELETE CASCADE ON UPDATE RESTRICT
) TYPE=INNODB;
INSERT INTO items (name,col1,col2) VALUES ('item 1',1,2);
INSERT INTO items (name,col1,col2) VALUES ('item 2',1,2);
INSERT INTO items (name,col1,col2) VALUES ('item 3',1,3);
INSERT INTO items (name,col1,col2) VALUES ('item 4',2,2);
INSERT INTO items (name,col1,col2) VALUES ('item 5',2,2);
CREATE TABLE types
(
int_col INT NOT NULL,
int_col2 INTEGER DEFAULT 1,
char_col CHAR(100) NOT NULL,
char_col2 VARCHAR(100) DEFAULT 'something',
char_col3 TEXT,
float_col REAL(4,3) NOT NULL,
float_col2 DOUBLE DEFAULT 1.23,
blob_col BLOB,
numeric_col NUMERIC(5,2) DEFAULT 33.22,
time TIMESTAMP DEFAULT '2002-01-01',
bool_col BOOL NOT NULL,
bool_col2 BOOLEAN DEFAULT 1
) TYPE=INNODB;

View File

@@ -0,0 +1,165 @@
/**
* This is the database schema for testing PostgreSQL support of yii Active Record.
* To test this feature, you need to create a database named 'yii' on 'localhost'
* and create an account 'test/test' which owns this test database.
*/
CREATE SCHEMA test;
CREATE TABLE test.users
(
id SERIAL NOT NULL PRIMARY KEY,
username VARCHAR(128) NOT NULL,
password VARCHAR(128) NOT NULL,
email VARCHAR(128) NOT NULL
);
INSERT INTO test.users (username, password, email) VALUES ('user1','pass1','email1');
INSERT INTO test.users (username, password, email) VALUES ('user2','pass2','email2');
INSERT INTO test.users (username, password, email) VALUES ('user3','pass3','email3');
CREATE TABLE test.user_friends
(
id INTEGER NOT NULL,
friend INTEGER NOT NULL,
PRIMARY KEY (id, friend),
CONSTRAINT FK_user_id FOREIGN KEY (id)
REFERENCES test.users (id) ON DELETE CASCADE ON UPDATE RESTRICT,
CONSTRAINT FK_friend_id FOREIGN KEY (friend)
REFERENCES test.users (id) ON DELETE CASCADE ON UPDATE RESTRICT
);
INSERT INTO test.user_friends VALUES (1,2);
INSERT INTO test.user_friends VALUES (1,3);
INSERT INTO test.user_friends VALUES (2,3);
CREATE TABLE test.profiles
(
id SERIAL NOT NULL PRIMARY KEY,
first_name VARCHAR(128) NOT NULL,
last_name VARCHAR(128) NOT NULL,
user_id INTEGER NOT NULL,
CONSTRAINT FK_profile_user FOREIGN KEY (user_id)
REFERENCES test.users (id) ON DELETE CASCADE ON UPDATE RESTRICT
);
INSERT INTO test.profiles (first_name, last_name, user_id) VALUES ('first 1','last 1',1);
INSERT INTO test.profiles (first_name, last_name, user_id) VALUES ('first 2','last 2',2);
CREATE TABLE test.posts
(
id SERIAL NOT NULL PRIMARY KEY,
title VARCHAR(128) NOT NULL,
create_time TIMESTAMP NOT NULL,
author_id INTEGER NOT NULL,
content TEXT,
CONSTRAINT FK_post_author FOREIGN KEY (author_id)
REFERENCES test.users (id) ON DELETE CASCADE ON UPDATE RESTRICT
);
INSERT INTO test.posts (title, create_time, author_id, content) VALUES ('post 1',TIMESTAMP '2004-10-19 10:23:54',1,'content 1');
INSERT INTO test.posts (title, create_time, author_id, content) VALUES ('post 2',TIMESTAMP '2004-10-19 10:23:54',2,'content 2');
INSERT INTO test.posts (title, create_time, author_id, content) VALUES ('post 3',TIMESTAMP '2004-10-19 10:23:54',2,'content 3');
INSERT INTO test.posts (title, create_time, author_id, content) VALUES ('post 4',TIMESTAMP '2004-10-19 10:23:54',2,'content 4');
INSERT INTO test.posts (title, create_time, author_id, content) VALUES ('post 5',TIMESTAMP '2004-10-19 10:23:54',3,'content 5');
CREATE TABLE test.comments
(
id SERIAL NOT NULL PRIMARY KEY,
content TEXT NOT NULL,
post_id INTEGER NOT NULL,
author_id INTEGER NOT NULL,
CONSTRAINT FK_post_comment FOREIGN KEY (post_id)
REFERENCES test.posts (id) ON DELETE CASCADE ON UPDATE RESTRICT,
CONSTRAINT FK_user_comment FOREIGN KEY (author_id)
REFERENCES test.users (id) ON DELETE CASCADE ON UPDATE RESTRICT
);
INSERT INTO test.comments (content, post_id, author_id) VALUES ('comment 1',1, 2);
INSERT INTO test.comments (content, post_id, author_id) VALUES ('comment 2',1, 2);
INSERT INTO test.comments (content, post_id, author_id) VALUES ('comment 3',1, 2);
INSERT INTO test.comments (content, post_id, author_id) VALUES ('comment 4',2, 2);
INSERT INTO test.comments (content, post_id, author_id) VALUES ('comment 5',2, 2);
INSERT INTO test.comments (content, post_id, author_id) VALUES ('comment 6',3, 2);
INSERT INTO test.comments (content, post_id, author_id) VALUES ('comment 7',3, 2);
INSERT INTO test.comments (content, post_id, author_id) VALUES ('comment 8',3, 2);
INSERT INTO test.comments (content, post_id, author_id) VALUES ('comment 9',3, 2);
INSERT INTO test.comments (content, post_id, author_id) VALUES ('comment 10',5, 3);
CREATE TABLE test.categories
(
id SERIAL NOT NULL PRIMARY KEY,
name VARCHAR(128) NOT NULL,
parent_id INTEGER,
CONSTRAINT FK_category_category FOREIGN KEY (parent_id)
REFERENCES test.categories (id) ON DELETE CASCADE ON UPDATE RESTRICT
);
INSERT INTO test.categories (name, parent_id) VALUES ('cat 1',NULL);
INSERT INTO test.categories (name, parent_id) VALUES ('cat 2',NULL);
INSERT INTO test.categories (name, parent_id) VALUES ('cat 3',NULL);
INSERT INTO test.categories (name, parent_id) VALUES ('cat 4',1);
INSERT INTO test.categories (name, parent_id) VALUES ('cat 5',1);
INSERT INTO test.categories (name, parent_id) VALUES ('cat 6',5);
INSERT INTO test.categories (name, parent_id) VALUES ('cat 7',5);
CREATE TABLE test.post_category
(
category_id INTEGER NOT NULL,
post_id INTEGER NOT NULL,
PRIMARY KEY (category_id, post_id),
CONSTRAINT FK_post_category_post FOREIGN KEY (post_id)
REFERENCES test.posts (id) ON DELETE CASCADE ON UPDATE RESTRICT,
CONSTRAINT FK_post_category_category FOREIGN KEY (category_id)
REFERENCES test.categories (id) ON DELETE CASCADE ON UPDATE RESTRICT
);
INSERT INTO test.post_category (category_id, post_id) VALUES (1,1);
INSERT INTO test.post_category (category_id, post_id) VALUES (2,1);
INSERT INTO test.post_category (category_id, post_id) VALUES (3,1);
INSERT INTO test.post_category (category_id, post_id) VALUES (4,2);
INSERT INTO test.post_category (category_id, post_id) VALUES (1,2);
INSERT INTO test.post_category (category_id, post_id) VALUES (1,3);
CREATE TABLE test.orders
(
key1 INTEGER NOT NULL,
key2 INTEGER NOT NULL,
name VARCHAR(128),
PRIMARY KEY (key1, key2)
);
INSERT INTO test.orders (key1,key2,name) VALUES (1,2,'order 12');
INSERT INTO test.orders (key1,key2,name) VALUES (1,3,'order 13');
INSERT INTO test.orders (key1,key2,name) VALUES (2,1,'order 21');
INSERT INTO test.orders (key1,key2,name) VALUES (2,2,'order 22');
CREATE TABLE test.items
(
id SERIAL NOT NULL PRIMARY KEY,
name VARCHAR(128),
col1 INTEGER NOT NULL,
col2 INTEGER NOT NULL,
CONSTRAINT FK_order_item FOREIGN KEY (col1,col2)
REFERENCES test.orders (key1,key2) ON DELETE CASCADE ON UPDATE RESTRICT
);
INSERT INTO test.items (name,col1,col2) VALUES ('item 1',1,2);
INSERT INTO test.items (name,col1,col2) VALUES ('item 2',1,2);
INSERT INTO test.items (name,col1,col2) VALUES ('item 3',1,3);
INSERT INTO test.items (name,col1,col2) VALUES ('item 4',2,2);
INSERT INTO test.items (name,col1,col2) VALUES ('item 5',2,2);
CREATE TABLE public.yii_types
(
int_col INT NOT NULL,
int_col2 INTEGER DEFAULT 1,
char_col CHAR(100) NOT NULL,
char_col2 VARCHAR(100) DEFAULT 'something',
char_col3 TEXT,
numeric_col NUMERIC(4,3) NOT NULL,
real_col REAL DEFAULT 1.23,
blob_col BYTEA,
time TIMESTAMP,
bool_col BOOL NOT NULL,
bool_col2 BOOLEAN DEFAULT TRUE
);

View File

@@ -0,0 +1,215 @@
CREATE TABLE users
(
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
username VARCHAR(128) NOT NULL,
password VARCHAR(128) NOT NULL,
email VARCHAR(128) NOT NULL
);
INSERT INTO users (username, password, email) VALUES ('user1','pass1','email1');
INSERT INTO users (username, password, email) VALUES ('user2','pass2','email2');
INSERT INTO users (username, password, email) VALUES ('user3','pass3','email3');
INSERT INTO users (username, password, email) VALUES ('user4','pass4','email4');
CREATE TABLE profiles
(
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
first_name VARCHAR(128) NOT NULL,
last_name VARCHAR(128) NOT NULL,
user_id INTEGER NOT NULL,
CONSTRAINT FK_profile_user FOREIGN KEY (user_id)
REFERENCES users (id) ON DELETE CASCADE ON UPDATE RESTRICT
);
INSERT INTO profiles (first_name, last_name, user_id) VALUES ('first 1','last 1',1);
INSERT INTO profiles (first_name, last_name, user_id) VALUES ('first 2','last 2',2);
CREATE TABLE posts
(
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
title VARCHAR(128) NOT NULL,
create_time TIMESTAMP NOT NULL,
author_id INTEGER NOT NULL,
content TEXT,
CONSTRAINT FK_post_author FOREIGN KEY (author_id)
REFERENCES users (id) ON DELETE CASCADE ON UPDATE RESTRICT
);
INSERT INTO posts (title, create_time, author_id, content) VALUES ('post 1',100000,1,'content 1');
INSERT INTO posts (title, create_time, author_id, content) VALUES ('post 2',100001,2,'content 2');
INSERT INTO posts (title, create_time, author_id, content) VALUES ('post 3',100002,2,'content 3');
INSERT INTO posts (title, create_time, author_id, content) VALUES ('post 4',100003,2,'content 4');
INSERT INTO posts (title, create_time, author_id, content) VALUES ('post 5',100004,3,'content 5');
CREATE TABLE posts_nofk
(
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
title VARCHAR(128) NOT NULL,
create_time TIMESTAMP NOT NULL,
author_id INTEGER NOT NULL,
content TEXT
);
INSERT INTO posts_nofk (title, create_time, author_id, content) VALUES ('post 1',100000,1,'content 1');
INSERT INTO posts_nofk (title, create_time, author_id, content) VALUES ('post 2',100001,2,'content 2');
INSERT INTO posts_nofk (title, create_time, author_id, content) VALUES ('post 3',100002,2,'content 3');
INSERT INTO posts_nofk (title, create_time, author_id, content) VALUES ('post 4',100003,2,'content 4');
INSERT INTO posts_nofk (title, create_time, author_id, content) VALUES ('post 5',100004,3,'content 5');
CREATE TABLE comments
(
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
content TEXT NOT NULL,
post_id INTEGER NOT NULL,
author_id INTEGER NOT NULL,
CONSTRAINT FK_post_comment FOREIGN KEY (post_id)
REFERENCES posts (id) ON DELETE CASCADE ON UPDATE RESTRICT,
CONSTRAINT FK_user_comment FOREIGN KEY (author_id)
REFERENCES users (id) ON DELETE CASCADE ON UPDATE RESTRICT
);
INSERT INTO comments (content, post_id, author_id) VALUES ('comment 1',1, 2);
INSERT INTO comments (content, post_id, author_id) VALUES ('comment 2',1, 2);
INSERT INTO comments (content, post_id, author_id) VALUES ('comment 3',1, 2);
INSERT INTO comments (content, post_id, author_id) VALUES ('comment 4',2, 2);
INSERT INTO comments (content, post_id, author_id) VALUES ('comment 5',2, 2);
INSERT INTO comments (content, post_id, author_id) VALUES ('comment 6',3, 2);
INSERT INTO comments (content, post_id, author_id) VALUES ('comment 7',3, 2);
INSERT INTO comments (content, post_id, author_id) VALUES ('comment 8',3, 2);
INSERT INTO comments (content, post_id, author_id) VALUES ('comment 9',3, 2);
INSERT INTO comments (content, post_id, author_id) VALUES ('comment 10',5, 3);
CREATE TABLE categories
(
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
name VARCHAR(128) NOT NULL,
parent_id INTEGER,
CONSTRAINT FK_category_category FOREIGN KEY (parent_id)
REFERENCES categories (id) ON DELETE CASCADE ON UPDATE RESTRICT
);
INSERT INTO categories (name, parent_id) VALUES ('cat 1',NULL);
INSERT INTO categories (name, parent_id) VALUES ('cat 2',NULL);
INSERT INTO categories (name, parent_id) VALUES ('cat 3',NULL);
INSERT INTO categories (name, parent_id) VALUES ('cat 4',1);
INSERT INTO categories (name, parent_id) VALUES ('cat 5',1);
INSERT INTO categories (name, parent_id) VALUES ('cat 6',5);
INSERT INTO categories (name, parent_id) VALUES ('cat 7',5);
CREATE TABLE post_category
(
category_id INTEGER NOT NULL,
post_id INTEGER NOT NULL,
PRIMARY KEY (category_id, post_id),
CONSTRAINT FK_post_category_post FOREIGN KEY (post_id)
REFERENCES posts (id) ON DELETE CASCADE ON UPDATE RESTRICT,
CONSTRAINT FK_post_category_category FOREIGN KEY (category_id)
REFERENCES categories (id) ON DELETE CASCADE ON UPDATE RESTRICT
);
INSERT INTO post_category (category_id, post_id) VALUES (1,1);
INSERT INTO post_category (category_id, post_id) VALUES (2,1);
INSERT INTO post_category (category_id, post_id) VALUES (3,1);
INSERT INTO post_category (category_id, post_id) VALUES (4,2);
INSERT INTO post_category (category_id, post_id) VALUES (1,2);
INSERT INTO post_category (category_id, post_id) VALUES (1,3);
CREATE TABLE orders
(
key1 INTEGER NOT NULL,
key2 INTEGER NOT NULL,
name VARCHAR(128),
PRIMARY KEY (key1, key2)
);
INSERT INTO orders (key1,key2,name) VALUES (1,2,'order 12');
INSERT INTO orders (key1,key2,name) VALUES (1,3,'order 13');
INSERT INTO orders (key1,key2,name) VALUES (2,1,'order 21');
INSERT INTO orders (key1,key2,name) VALUES (2,2,'order 22');
CREATE TABLE items
(
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
name VARCHAR(128),
col1 INTEGER NOT NULL,
col2 INTEGER NOT NULL,
CONSTRAINT FK_order_item FOREIGN KEY (col1,col2)
REFERENCES orders (key1,key2) ON DELETE CASCADE ON UPDATE RESTRICT
);
INSERT INTO items (name,col1,col2) VALUES ('item 1',1,2);
INSERT INTO items (name,col1,col2) VALUES ('item 2',1,2);
INSERT INTO items (name,col1,col2) VALUES ('item 3',1,3);
INSERT INTO items (name,col1,col2) VALUES ('item 4',2,2);
INSERT INTO items (name,col1,col2) VALUES ('item 5',2,2);
CREATE TABLE types
(
int_col INT NOT NULL,
int_col2 INTEGER DEFAULT 1,
char_col CHAR(100) NOT NULL,
char_col2 VARCHAR(100) DEFAULT 'something',
char_col3 TEXT,
float_col REAL(4,3) NOT NULL,
float_col2 DOUBLE DEFAULT 1.23,
blob_col BLOB,
numeric_col NUMERIC(5,2) DEFAULT 33.22,
time TIMESTAMP DEFAULT 123,
bool_col BOOL NOT NULL,
bool_col2 BOOLEAN DEFAULT 1,
null_col INTEGER DEFAULT NULL
);
CREATE TABLE Content
(
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
class VARCHAR(128),
parentID INTEGER NOT NULL,
ownerID INTEGER NOT NULL,
title VARCHAR(100),
CONSTRAINT FK_content_user FOREIGN KEY (ownerID)
REFERENCES users (id) ON DELETE CASCADE ON UPDATE RESTRICT
CONSTRAINT FK_content_parent FOREIGN KEY (parentID)
REFERENCES Content (id) ON DELETE CASCADE ON UPDATE RESTRICT
);
INSERT INTO Content (class,parentID,ownerID,title) VALUES ('Article',-1,1,'article 1');
INSERT INTO Content (class,parentID,ownerID,title) VALUES ('Article',-1,2,'article 2');
INSERT INTO Content (class,parentID,ownerID,title) VALUES ('Comment',1,1,'comment 1');
INSERT INTO Content (class,parentID,ownerID,title) VALUES ('Article',-1,2,'article 3');
INSERT INTO Content (class,parentID,ownerID,title) VALUES ('Comment',4,2,'comment 2');
INSERT INTO Content (class,parentID,ownerID,title) VALUES ('Comment',4,1,'comment 3');
CREATE TABLE Article
(
id INTEGER NOT NULL PRIMARY KEY,
authorID INTEGER NOT NULL,
body TEXT,
CONSTRAINT FK_article_content FOREIGN KEY (id)
REFERENCES Content (id) ON DELETE CASCADE ON UPDATE RESTRICT
CONSTRAINT FK_article_author FOREIGN KEY (authorID)
REFERENCES users (id) ON DELETE CASCADE ON UPDATE RESTRICT
);
INSERT INTO Article (id,authorID,body) VALUES (1,1,'content for article 1');
INSERT INTO Article (id,authorID,body) VALUES (2,2,'content for article 2');
INSERT INTO Article (id,authorID,body) VALUES (4,1,'content for article 3');
CREATE TABLE Comment
(
id INTEGER NOT NULL PRIMARY KEY,
authorID INTEGER NOT NULL,
body TEXT,
CONSTRAINT FK_comment_content FOREIGN KEY (id)
REFERENCES Content (id) ON DELETE CASCADE ON UPDATE RESTRICT
CONSTRAINT FK_article_author FOREIGN KEY (authorID)
REFERENCES users (id) ON DELETE CASCADE ON UPDATE RESTRICT
);
INSERT INTO Comment (id,authorID,body) VALUES (3,1,'content for comment 1');
INSERT INTO Comment (id,authorID,body) VALUES (5,1,'content for comment 2');
INSERT INTO Comment (id,authorID,body) VALUES (6,1,'content for comment 3');

View File

@@ -0,0 +1,507 @@
<?php
/**
* CDbCriteriaTest
*/
class CDbCriteriaTest extends CTestCase {
protected $backupStaticAttributes = true;
/**
* @covers CDbCriteria::addCondition
*/
function testAddCondition() {
//adding new condition to empty one
CDbCriteria::$paramCount=0;
$criteria = new CDbCriteria();
$criteria->addCondition('A');
$this->assertEquals('A', $criteria->condition);
//adding multiple conditions
$criteria = new CDbCriteria();
$criteria->addCondition('A');
$criteria->addCondition('B');
$criteria->addCondition('C', 'OR');
$this->assertEquals('((A) AND (B)) OR (C)', $criteria->condition);
//adding empty array as condition
$criteria = new CDbCriteria();
$criteria->addCondition('A');
$criteria->addCondition(array());
$this->assertEquals('A', $criteria->condition);
//adding array as condition
$criteria = new CDbCriteria();
$criteria->addCondition(array('A', 'B'));
$this->assertEquals('(A) AND (B)', $criteria->condition);
}
/**
* @depends testAddCondition
* @covers CDbCriteria::addInCondition
*/
function testAddInCondition() {
CDbCriteria::$paramCount=0;
$criteria = new CDbCriteria();
$criteria->addInCondition('A', array());
$this->assertEquals('0=1', $criteria->condition);
$this->assertTrue(empty($criteria->params));
// IN with one parameter should transform to =
$criteria = new CDbCriteria();
$criteria->addInCondition('A', array(1));
$this->assertEquals('A=:ycp0', $criteria->condition);
$this->assertEquals(1, $criteria->params[':ycp0']);
// IN with null should transform to IS NULL
$criteria = new CDbCriteria();
$criteria->addInCondition('A', array(null));
$this->assertEquals('A IS NULL', $criteria->condition);
$this->assertTrue(empty($criteria->params));
// IN with many parameters
$criteria = new CDbCriteria();
$criteria->addInCondition('B', array(1, 2, '3'));
$this->assertEquals('B IN (:ycp1, :ycp2, :ycp3)', $criteria->condition);
$this->assertEquals(1, $criteria->params[':ycp1']);
$this->assertEquals(2, $criteria->params[':ycp2']);
$this->assertEquals('3', $criteria->params[':ycp3']);
}
/**
* @depends testAddCondition
* @covers CDbCriteria::addNotInCondition
*/
function testAddNotInCondition() {
// NOT IN with empty array should not change anything
CDbCriteria::$paramCount=0;
$criteria = new CDbCriteria();
$criteria->addNotInCondition('A', array());
$this->assertEquals('', $criteria->condition);
$this->assertTrue(empty($criteria->params));
// NOT IN with one parameter should transform to !=
$criteria = new CDbCriteria();
$criteria->addNotInCondition('A', array(1));
$this->assertEquals('A!=:ycp0', $criteria->condition);
$this->assertEquals(1, $criteria->params[':ycp0']);
// NOT IN with null should transform to IS NOT NULL
$criteria = new CDbCriteria();
$criteria->addNotInCondition('A', array(null));
$this->assertEquals('A IS NOT NULL', $criteria->condition);
$this->assertTrue(empty($criteria->params));
// NOT IN with many parameters
$criteria = new CDbCriteria();
$criteria->addNotInCondition('B', array(1, 2, '3'));
$this->assertEquals('B NOT IN (:ycp1, :ycp2, :ycp3)', $criteria->condition);
$this->assertEquals(1, $criteria->params[':ycp1']);
$this->assertEquals(2, $criteria->params[':ycp2']);
$this->assertEquals('3', $criteria->params[':ycp3']);
}
/**
* @depends testAddCondition
* @covers CDbCriteria::addSearchCondition
*/
function testAddSearchCondition() {
// string escaping
CDbCriteria::$paramCount=0;
$criteria = new CDbCriteria();
$criteria->addSearchCondition('A', 'key_word%');
$this->assertEquals('A LIKE :ycp0', $criteria->condition);
$this->assertEquals('%key\_word\%%', $criteria->params[':ycp0']);
// no escaping
$criteria = new CDbCriteria();
$criteria->addSearchCondition('A', 'key_word%', false);
$this->assertEquals('A LIKE :ycp1', $criteria->condition);
$this->assertEquals('key_word%', $criteria->params[':ycp1']);
}
/**
* @depends testAddCondition
* @covers CDbCriteria::addColumnCondition
*/
function testAddColumnCondition() {
CDbCriteria::$paramCount=0;
$criteria = new CDbCriteria();
$criteria->addColumnCondition(array('A' => 1, 'B' => null, 'C' => '2'));
$this->assertEquals('A=:ycp0 AND B IS NULL AND C=:ycp1', $criteria->condition);
$this->assertEquals(1, $criteria->params[':ycp0']);
$this->assertEquals('2', $criteria->params[':ycp1']);
}
/**
* @depends testAddCondition
* @covers CDbCriteria::compare
*/
function testCompare(){
CDbCriteria::$paramCount=0;
$criteria = new CDbCriteria();
$criteria->compare('A', '');
$this->assertEquals('', $criteria->condition);
$criteria = new CDbCriteria();
$criteria->compare('A', 1);
$this->assertEquals('A=:ycp0', $criteria->condition);
$this->assertEquals(1, $criteria->params[':ycp0']);
$criteria = new CDbCriteria();
$criteria->compare('A', '>1');
$this->assertEquals('A>:ycp1', $criteria->condition);
$this->assertEquals(1, $criteria->params[':ycp1']);
$criteria = new CDbCriteria();
$criteria->compare('A', '<1');
$this->assertEquals('A<:ycp2', $criteria->condition);
$this->assertEquals(1, $criteria->params[':ycp2']);
$criteria = new CDbCriteria();
$criteria->compare('A', '<=1');
$this->assertEquals('A<=:ycp3', $criteria->condition);
$this->assertEquals(1, $criteria->params[':ycp3']);
$criteria = new CDbCriteria();
$criteria->compare('A', '>=1');
$this->assertEquals('A>=:ycp4', $criteria->condition);
$this->assertEquals(1, $criteria->params[':ycp4']);
$criteria = new CDbCriteria();
$criteria->compare('A', '<>1');
$this->assertEquals('A<>:ycp5', $criteria->condition);
$this->assertEquals(1, $criteria->params[':ycp5']);
$criteria = new CDbCriteria();
$criteria->compare('A', '=1');
$this->assertEquals('A=:ycp6', $criteria->condition);
$this->assertEquals(1, $criteria->params[':ycp6']);
$criteria = new CDbCriteria();
$criteria->compare('A', '1', true);
$this->assertEquals('A LIKE :ycp7', $criteria->condition);
$this->assertEquals('%1%', $criteria->params[':ycp7']);
$criteria = new CDbCriteria();
$criteria->compare('A', '=1', true);
$this->assertEquals('A=:ycp8', $criteria->condition);
$this->assertEquals('1', $criteria->params[':ycp8']);
$criteria = new CDbCriteria();
$criteria->compare('A', '<>1', true);
$this->assertEquals('A NOT LIKE :ycp9', $criteria->condition);
$this->assertEquals('%1%', $criteria->params[':ycp9']);
$criteria = new CDbCriteria();
$criteria->compare('A', ' value_with_spaces ');
$this->assertEquals('A=:ycp10', $criteria->condition);
$this->assertEquals(' value_with_spaces ', $criteria->params[':ycp10']);
$criteria = new CDbCriteria();
$criteria->compare('A', array());
$this->assertEquals('', $criteria->condition);
$criteria = new CDbCriteria();
$criteria->compare('A', array(1, '2'));
$this->assertEquals('A IN (:ycp11, :ycp12)', $criteria->condition);
$this->assertEquals(1, $criteria->params[':ycp11']);
$this->assertEquals('2', $criteria->params[':ycp12']);
}
/**
* @depends testCompare
* @covers CDbCriteria::mergeWith
*/
function testMergeWith() {
// merging select
// * should be replaced
CDbCriteria::$paramCount=0;
$criteria1 = new CDbCriteria;
$criteria1->select = '*';
$criteria2 = new CDbCriteria;
$criteria2->select = 'a';
$criteria1->mergeWith($criteria2);
$this->assertEquals('a', $criteria1->select);
// equal selects should be left as is
$criteria1 = new CDbCriteria;
$criteria1->select = 'a';
$criteria2 = new CDbCriteria;
$criteria2->select = 'a';
$criteria1->mergeWith($criteria2);
$this->assertEquals('a', $criteria1->select);
// not equal selects are being merged
$criteria1 = new CDbCriteria;
$criteria1->select = 'a, b, c, d';
$criteria2 = new CDbCriteria;
$criteria2->select = 'a, c, e, f';
$criteria1->mergeWith($criteria2);
$this->assertEquals(array('a', 'b', 'c', 'd', 'e', 'f'), $criteria1->select);
// conditions
// equal conditions are not merged
$criteria1 = new CDbCriteria;
$criteria1->condition = 'a';
$criteria2 = new CDbCriteria;
$criteria2->condition = 'a';
$criteria1->mergeWith($criteria2);
$this->assertEquals('a', $criteria1->condition);
// empty condition is being replaced
$criteria1 = new CDbCriteria;
$criteria1->condition = '';
$criteria2 = new CDbCriteria;
$criteria2->condition = 'a';
$criteria1->mergeWith($criteria2);
$this->assertEquals('a', $criteria1->condition);
// not empty conditions are merged
$criteria1 = new CDbCriteria;
$criteria1->condition = 'a';
$criteria2 = new CDbCriteria;
$criteria2->condition = 'b';
$criteria1->mergeWith($criteria2);
$this->assertEquals('(a) AND (b)', $criteria1->condition);
// limit, offset, distinct and alias are being replaced
$criteria1 = new CDbCriteria;
$criteria1->limit = 10;
$criteria1->offset = 5;
$criteria1->alias = 'alias1';
$criteria1->distinct = true;
$criteria2 = new CDbCriteria;
$criteria2->limit = 20;
$criteria2->offset = 6;
$criteria2->alias = 'alias2';
$criteria1->distinct = false;
$criteria1->mergeWith($criteria2);
$this->assertEquals(20, $criteria1->limit);
$this->assertEquals(6, $criteria1->offset);
$this->assertEquals('alias2', $criteria1->alias);
$this->assertEquals(false, $criteria1->distinct);
// empty order, group, join, having are being replaced
$criteria1 = new CDbCriteria;
$criteria1->order = '';
$criteria1->group = '';
$criteria1->join = '';
$criteria1->having = '';
$criteria2 = new CDbCriteria;
$criteria2->order = 'a';
$criteria1->group = 'a';
$criteria1->join = 'a';
$criteria2->having = 'a';
$criteria1->mergeWith($criteria2);
$this->assertEquals('a', $criteria1->order);
$this->assertEquals('a', $criteria1->group);
$this->assertEquals('a', $criteria1->join);
$this->assertEquals('a', $criteria1->having);
// merging with empty order, group, join ignored
$criteria1 = new CDbCriteria;
$criteria1->order = 'a';
$criteria1->group = 'a';
$criteria1->join = 'a';
$criteria1->having = 'a';
$criteria2 = new CDbCriteria;
$criteria2->order = '';
$criteria2->group = '';
$criteria2->join = '';
$criteria2->having = '';
$criteria1->mergeWith($criteria2);
$this->assertEquals('a', $criteria1->order);
$this->assertEquals('a', $criteria1->group);
$this->assertEquals('a', $criteria1->join);
$this->assertEquals('a', $criteria1->having);
// not empty order, group, join are being merged
$criteria1 = new CDbCriteria;
$criteria1->order = 'a';
$criteria1->group = 'a';
$criteria1->join = 'a';
$criteria1->having = 'a';
$criteria2 = new CDbCriteria;
$criteria2->order = 'b';
$criteria2->group = 'b';
$criteria2->join = 'b';
$criteria2->having = 'b';
$criteria1->mergeWith($criteria2);
$this->assertEquals('b, a', $criteria1->order);
$this->assertEquals('a, b', $criteria1->group);
$this->assertEquals('a b', $criteria1->join);
$this->assertEquals('(a) AND (b)', $criteria1->having);
// empty with is replaced
$criteria1 = new CDbCriteria;
$criteria1->with = '';
$criteria2 = new CDbCriteria;
$criteria2->with = 'a';
$criteria1->mergeWith($criteria2);
$this->assertEquals('a', $criteria1->with);
// not empty with are merged
$criteria1 = new CDbCriteria;
$criteria1->with = 'a';
$criteria2 = new CDbCriteria;
$criteria2->with = 'b';
$criteria1->mergeWith($criteria2);
$this->assertEquals(array('a', 'b'), $criteria1->with);
// not empty with are merged (more complex test)
$criteria1 = new CDbCriteria;
$criteria1->with = array('a', 'b');
$criteria2 = new CDbCriteria;
$criteria2->with = array('a', 'c');
$criteria1->mergeWith($criteria2);
$this->assertEquals(array('a', 'b', 'a', 'c'), $criteria1->with);
// merging two criteria with parameters
$criteria1 = new CDbCriteria;
$criteria1->compare('A1', 1);
$criteria1->compare('A2', 2);
$criteria1->compare('A3', 3);
$criteria1->compare('A4', 4);
$criteria1->compare('A5', 5);
$criteria1->compare('A6', 6);
$criteria2 = new CDbCriteria;
$criteria2->compare('B1', 7);
$criteria2->compare('B2', 8);
$criteria2->compare('B3', 9);
$criteria2->compare('B4', 10);
$criteria2->compare('B5', 11);
$criteria2->compare('B6', 12);
$criteria1->mergeWith($criteria2);
$this->assertEquals('((((((A1=:ycp0) AND (A2=:ycp1)) AND (A3=:ycp2)) AND (A4=:ycp3)) AND (A5=:ycp4)) AND (A6=:ycp5)) AND ((((((B1=:ycp6) AND (B2=:ycp7)) AND (B3=:ycp8)) AND (B4=:ycp9)) AND (B5=:ycp10)) AND (B6=:ycp11))', $criteria1->condition);
$this->assertEquals(1, $criteria1->params[':ycp0']);
$this->assertEquals(2, $criteria1->params[':ycp1']);
$this->assertEquals(3, $criteria1->params[':ycp2']);
$this->assertEquals(4, $criteria1->params[':ycp3']);
$this->assertEquals(5, $criteria1->params[':ycp4']);
$this->assertEquals(6, $criteria1->params[':ycp5']);
$this->assertEquals(7, $criteria1->params[':ycp6']);
$this->assertEquals(8, $criteria1->params[':ycp7']);
$this->assertEquals(9, $criteria1->params[':ycp8']);
$this->assertEquals(10, $criteria1->params[':ycp9']);
$this->assertEquals(11, $criteria1->params[':ycp10']);
$this->assertEquals(12, $criteria1->params[':ycp11']);
}
/**
* Merging criterias with positioned and non positioned parameters.
*
* @depends testCompare
* @covers CDbCriteria::mergeWith
*/
function testMergeWithPositionalPlaceholders(){
CDbCriteria::$paramCount=0;
$criteria1 = new CDbCriteria();
$criteria1->condition = 'A=? AND B=?';
$criteria1->params = array(0 => 10, 1 => 20);
$criteria2 = new CDbCriteria();
$criteria2->compare('C', 30);
$criteria2->compare('D', 40);
$criteria2->mergeWith($criteria1);
$this->assertEquals('((C=:ycp0) AND (D=:ycp1)) AND (A=? AND B=?)', $criteria2->condition);
$this->assertEquals(10, $criteria2->params[0]);
$this->assertEquals(20, $criteria2->params[1]);
$this->assertEquals(30, $criteria2->params[':ycp0']);
$this->assertEquals(40, $criteria2->params[':ycp1']);
// and vice versa
$criteria1 = new CDbCriteria();
$criteria1->condition = 'A=? AND B=?';
$criteria1->params = array(0 => 10, 1 => 20);
$criteria2 = new CDbCriteria();
$criteria2->compare('C', 30);
$criteria2->compare('D', 40);
$criteria1->mergeWith($criteria2);
$this->assertEquals('(A=? AND B=?) AND ((C=:ycp2) AND (D=:ycp3))', $criteria1->condition);
$this->assertEquals(10, $criteria1->params[0]);
$this->assertEquals(20, $criteria1->params[1]);
$this->assertEquals(30, $criteria1->params[':ycp2']);
$this->assertEquals(40, $criteria1->params[':ycp3']);
}
/**
* @covers CDbCriteria::addBetweenCondition
*/
function testAddBetweenCondition(){
CDbCriteria::$paramCount=0;
$criteria = new CDbCriteria();
$criteria->addBetweenCondition('A', 1, 2);
$this->assertEquals('A BETWEEN :ycp0 AND :ycp1', $criteria->condition);
$this->assertEquals(1, $criteria->params[':ycp0']);
$this->assertEquals(2, $criteria->params[':ycp1']);
}
function testToArray(){
$keys = array('select', 'condition', 'params', 'limit', 'offset', 'order', 'group', 'join', 'having', 'distinct', 'with', 'alias', 'index', 'together');
$criteria = new CDbCriteria();
$this->assertEquals($keys, array_keys($criteria->toArray()));
}
}

View File

@@ -0,0 +1,310 @@
<?php
Yii::import('system.db.CDbConnection');
Yii::import('system.db.schema.mysql.CMssqlSchema');
class CMssqlTest extends CTestCase
{
const DB_HOST='YII'; // This is the alias to mssql server. Defined in freetds.conf for linux, or in Client Network Utility on windows
const DB_NAME='yii';
const DB_USER='test';
const DB_PASS='test';
const DB_DSN_PREFIX='dblib'; // mssql on Windows, dblib on linux
private $db;
public function setUp()
{
if(!extension_loaded('pdo') || !extension_loaded("pdo_dblib"))
$this->markTestSkipped('PDO and MSSQL extensions are required.');
$dsn=self::DB_DSN_PREFIX.':host='.self::DB_HOST.';dbname='.self::DB_NAME;
$this->db=new CDbConnection($dsn,self::DB_USER,self::DB_PASS);;
try
{
$this->db->active=true;
}
catch(Exception $e)
{
$schemaFile=realpath(dirname(__FILE__).'/../data/mssql.sql');
$this->markTestSkipped("Please read $schemaFile for details on setting up the test environment for MySQL test case.");
}
$tables=array('comments','post_category','posts','categories','profiles','users','items','orders','types');
foreach($tables as $table)
{
$sql=<<<EOD
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[{$table}]') AND OBJECTPROPERTY(id, N'IsUserTable') = 1)
DROP TABLE [dbo].[{$table}]
EOD;
$this->db->createCommand($sql)->execute();
}
$sqls=file_get_contents(dirname(__FILE__).'/../data/mssql.sql');
foreach(explode('GO',$sqls) as $sql)
{
if(trim($sql)!=='')
$this->db->createCommand($sql)->execute();
}
}
public function tearDown()
{
$this->db->active=false;
}
public function testSchema()
{
$schema=$this->db->schema;
$this->assertTrue($schema instanceof CDbSchema);
$this->assertEquals($schema->dbConnection,$this->db);
$this->assertTrue($schema->commandBuilder instanceof CDbCommandBuilder);
$this->assertEquals('[posts]',$schema->quoteTableName('posts'));
$this->assertEquals('[dbo].[posts]',$schema->quoteTableName('dbo.posts'));
$this->assertEquals('[id]',$schema->quoteColumnName('id'));
$this->assertTrue($schema->getTable('posts') instanceof CDbTableSchema);
$this->assertNull($schema->getTable('foo'));
}
public function testTable()
{
$table=$this->db->schema->getTable('posts');
$this->assertTrue($table instanceof CDbTableSchema);
$this->assertEquals('posts',$table->name);
$this->assertEquals('dbo',$table->schemaName);
$this->assertEquals('[dbo].[posts]',$table->rawName);
$this->assertEquals('id',$table->primaryKey);
$this->assertEquals(array('author_id'=>array('users','id')),$table->foreignKeys);
$this->assertEquals('',$table->sequenceName);
$this->assertEquals(5,count($table->columns));
$this->assertTrue($table->getColumn('id') instanceof CDbColumnSchema);
$this->assertTrue($table->getColumn('foo')===null);
$this->assertEquals(array('id','title','create_time','author_id','content'),$table->columnNames);
$table=$this->db->schema->getTable('orders');
$this->assertEquals(array('key1','key2'),$table->primaryKey);
$table=$this->db->schema->getTable('items');
$this->assertEquals('id',$table->primaryKey);
$this->assertEquals(array('col1'=>array('orders','key1'),'col2'=>array('orders','key2')),$table->foreignKeys);
$table=$this->db->schema->getTable('types');
$this->assertTrue($table instanceof CDbTableSchema);
$this->assertEquals('types',$table->name);
$this->assertEquals('[dbo].[types]',$table->rawName);
$this->assertTrue($table->primaryKey===null);
$this->assertTrue($table->foreignKeys===array());
$this->assertTrue($table->sequenceName===null);
$table=$this->db->schema->getTable('invalid');
$this->assertNull($table);
}
public function testColumn()
{
$values=array
(
'name'=>array('id', 'title', 'create_time', 'author_id', 'content'),
'rawName'=>array('[id]', '[title]', '[create_time]', '[author_id]', '[content]'),
'defaultValue'=>array(null, null, null, null, null),
'size'=>array(10, 128, null, 10, null),
'precision'=>array(10, 128, null, 10, null),
'scale'=>array(0, null, null, 0, null),
'dbType'=>array('int','varchar','datetime','int','text'),
'type'=>array('integer','string','string','integer','string'),
'isPrimaryKey'=>array(true,false,false,false,false),
'isForeignKey'=>array(false,false,false,true,false),
);
$this->checkColumns('posts',$values);
$values=array
(
'name'=>array('int_col', 'int_col2', 'char_col', 'char_col2', 'char_col3', 'float_col', 'float_col2', 'blob_col', 'numeric_col', 'time', 'bool_col', 'bool_col2'),
'rawName'=>array('[int_col]', '[int_col2]', '[char_col]', '[char_col2]', '[char_col3]', '[float_col]', '[float_col2]', '[blob_col]', '[numeric_col]', '[time]', '[bool_col]', '[bool_col2]'),
'defaultValue'=>array(null, 1, null, "something", null, null, '1.23', null, '33.22', '2002-01-01 00:00:00', null, true),
'size'=>array(10, 10, 100, 100, null, 24, 53, null, 5, null, null, null),
'precision'=>array(10, 10, 100, 100, null, 24, 53, null, 5, null, null, null),
'scale'=>array(0, 0, null, null, null, null, null, null, 2, null, null, null),
'dbType'=>array('int','int','char','varchar','text','real','float','image','numeric','datetime','bit','bit'),
'type'=>array('integer','integer','string','string','string','double','double','string','string','string','boolean','boolean'),
'isPrimaryKey'=>array(false,false,false,false,false,false,false,false,false,false,false,false),
'isForeignKey'=>array(false,false,false,false,false,false,false,false,false,false,false,false),
);
$this->checkColumns('types',$values);
}
protected function checkColumns($tableName,$values)
{
$table=$this->db->schema->getTable($tableName);
foreach($values as $name=>$value)
{
foreach(array_values($table->columns) as $i=>$column)
{
$type1=gettype($column->$name);
$type2=gettype($value[$i]);
$this->assertTrue($column->$name===$value[$i], "$tableName.{$column->name}.$name is {$column->$name} ($type1), different from the expected {$value[$i]} ($type2).");
}
}
}
public function testCommandBuilder()
{
$schema=$this->db->schema;
$builder=$schema->commandBuilder;
$this->assertTrue($builder instanceof CDbCommandBuilder);
$table=$schema->getTable('posts');
$c=$builder->createInsertCommand($table,array('title'=>'test post','create_time'=>'2000-01-01','author_id'=>1,'content'=>'test content'));
$this->assertEquals('INSERT INTO [dbo].[posts] ([title], [create_time], [author_id], [content]) VALUES (:title, :create_time, :author_id, :content)',$c->text);
$c->execute();
$this->assertEquals(6,$builder->getLastInsertId($table));
$this->assertEquals(6, $this->db->getLastInsertID());
$c=$builder->createCountCommand($table,new CDbCriteria);
$this->assertEquals('SELECT COUNT(*) FROM [dbo].[posts] [t]',$c->text);
$this->assertEquals(6,$c->queryScalar());
$c=$builder->createDeleteCommand($table,new CDbCriteria(array(
'condition'=>'id=:id',
'params'=>array('id'=>6))));
$this->assertEquals('DELETE FROM [dbo].[posts] WHERE id=:id',$c->text);
$c->execute();
$c=$builder->createCountCommand($table,new CDbCriteria);
$this->assertEquals(5,$c->queryScalar());
$c=$builder->createFindCommand($table,new CDbCriteria(array(
'select'=>'id, title',
'condition'=>'id=:id',
'params'=>array('id'=>5),
'order'=>'title',
'limit'=>2,
'offset'=>0)));
$this->assertEquals('SELECT TOP 2 id, title FROM [dbo].[posts] [t] WHERE id=:id ORDER BY title',$c->text);
$rows=$c->query()->readAll();
$this->assertEquals(1,count($rows));
$this->assertEquals('post 5',$rows[0]['title']);
$c=$builder->createFindCommand($table,new CDbCriteria(array(
'select'=>'id, title',
'order'=>'title',
'limit'=>2,
'offset'=>3)));
$this->assertEquals('SELECT * FROM (SELECT TOP 2 * FROM (SELECT TOP 5 id, title FROM [dbo].[posts] ORDER BY title) as [__inner top table__] ORDER BY title DESC) as [__outer top table__] ORDER BY title ASC',$c->text);
$rows=$c->query()->readAll();
$this->assertEquals(2,count($rows));
$this->assertEquals('post 4',$rows[0]['title']);
$c=$builder->createUpdateCommand($table,array('title'=>'new post 5'),new CDbCriteria(array(
'condition'=>'id=:id',
'params'=>array('id'=>5))));
$c->execute();
$c=$builder->createFindCommand($table,new CDbCriteria(array(
'select'=>'title',
'condition'=>'id=:id',
'params'=>array('id'=>5))));
$this->assertEquals('new post 5',$c->queryScalar());
$c=$builder->createSqlCommand('SELECT title FROM posts WHERE id=:id',array(':id'=>3));
$this->assertEquals('post 3',$c->queryScalar());
$c=$builder->createUpdateCounterCommand($table,array('author_id'=>-2),new CDbCriteria(array('condition'=>'id=5')));
$this->assertEquals('UPDATE [dbo].[posts] SET [author_id]=[author_id]-2 WHERE id=5',$c->text);
$c->execute();
$c=$builder->createSqlCommand('SELECT author_id FROM posts WHERE id=5');
$this->assertEquals(1,$c->queryScalar());
// test bind by position
$c=$builder->createFindCommand($table,new CDbCriteria(array(
'select'=>'title',
'condition'=>'id=?',
'params'=>array(4))));
$this->assertEquals('SELECT title FROM [dbo].[posts] WHERE id=?',$c->text);
$this->assertEquals('post 4',$c->queryScalar());
// another bind by position
$c=$builder->createUpdateCommand($table,array('title'=>'new post 4'),new CDbCriteria(array(
'condition'=>'id=?',
'params'=>array(4))));
$c->execute();
$c=$builder->createSqlCommand('SELECT title FROM posts WHERE id=4');
$this->assertEquals('new post 4',$c->queryScalar());
// testCreateCriteria
$c=$builder->createCriteria('column=:value',array(':value'=>'value'));
$this->assertEquals('column=:value',$c->condition);
$this->assertEquals(array(':value'=>'value'),$c->params);
$c=$builder->createCriteria(array('condition'=>'column=:value','params'=>array(':value'=>'value')));
$this->assertEquals('column=:value',$c->condition);
$this->assertEquals(array(':value'=>'value'),$c->params);
$c2=$builder->createCriteria($c);
$this->assertTrue($c2!==$c);
$this->assertEquals('column=:value',$c2->condition);
$this->assertEquals(array(':value'=>'value'),$c2->params);
// testCreatePkCriteria
$c=$builder->createPkCriteria($table,1,'author_id>1');
$this->assertEquals('[dbo].[posts].[id]=1 AND (author_id>1)',$c->condition);
$c=$builder->createPkCriteria($table,array(1,2));
$this->assertEquals('[dbo].[posts].[id] IN (1, 2)',$c->condition);
$c=$builder->createPkCriteria($table,array());
$this->assertEquals('0=1',$c->condition);
$table2=$schema->getTable('orders');
$c=$builder->createPkCriteria($table2,array('key1'=>1,'key2'=>2),'name=\'\'');
$this->assertEquals('[dbo].[orders].[key1]=1 AND [dbo].[orders].[key2]=2 AND (name=\'\')',$c->condition);
$c=$builder->createPkCriteria($table2,array(array('key1'=>1,'key2'=>2),array('key1'=>3,'key2'=>4)));
$this->assertEquals('([dbo].[orders].[key1], [dbo].[orders].[key2]) IN ((1, 2), (3, 4))',$c->condition);
// createColumnCriteria
$c=$builder->createColumnCriteria($table,array('id'=>1,'author_id'=>2),'title=\'\'');
$this->assertEquals('[dbo].[posts].[id]=:id AND [dbo].[posts].[author_id]=:author_id AND (title=\'\')',$c->condition);
$c=$builder->createPkCriteria($table2,array());
$this->assertEquals('0=1',$c->condition);
}
public function testTransactions()
{
$transaction=$this->db->beginTransaction();
$schema=$this->db->schema;
$builder=$schema->commandBuilder;
$table=$schema->getTable('posts');
// Working transaction
try
{
$builder->createInsertCommand($table, array('title'=>'working transaction test post 1','create_time'=>'2009-01-01','author_id'=>1,'content'=>'test content'))->execute();
$builder->createInsertCommand($table, array('title'=>'working transaction test post 2','create_time'=>'2009-01-01','author_id'=>1,'content'=>'test content'))->execute();
$transaction->commit();
}
catch (Exception $e)
{
$transaction->rollBack();
}
$n=$builder->createCountCommand($table, new CDbCriteria(array('condition' => "title LIKE 'working transaction%'")))->queryScalar();
$this->assertEquals(2, $n);
// Failing Transaction
$transaction=$this->db->beginTransaction();
try
{
$builder->createInsertCommand($table, array('title'=>'failed transaction test post 1','create_time'=>'2009-01-01','author_id'=>1,'content'=>'test content'))->execute();
$builder->createInsertCommand($table, array('id' => 1, 'title'=>'failed transaction test post 2','create_time'=>'2009-01-01','author_id'=>1,'content'=>'test content'))->execute();
$transaction->commit();
}
catch (Exception $e)
{
$transaction->rollBack();
}
$n=$builder->createCountCommand($table, new CDbCriteria(array('condition' => "title LIKE 'failed transaction%'")))->queryScalar();
$this->assertEquals(0, $n);
}
}

View File

@@ -0,0 +1,128 @@
<?php
Yii::import('system.db.CDbConnection');
Yii::import('system.db.schema.mysql.CMysqlSchema');
class CMysql2Test extends CTestCase
{
private $db;
public function setUp()
{
if(!extension_loaded('pdo') || !extension_loaded('pdo_mysql'))
$this->markTestSkipped('PDO and MySQL extensions are required.');
$this->db=new CDbConnection('mysql:host=127.0.0.1;dbname=yii','test','test');
$this->db->charset='UTF8';
try
{
$this->db->active=true;
}
catch(Exception $e)
{
$schemaFile=realpath(dirname(__FILE__).'/../data/mysql.sql');
$this->markTestSkipped("Please read $schemaFile for details on setting up the test environment for MySQL test case.");
}
}
public function tearDown()
{
$this->db->active=false;
}
public function testCreateTable()
{
$sql=$this->db->schema->createTable('test',array(
'id'=>'pk',
'name'=>'string not null',
'desc'=>'text',
'primary key (id, name)',
),'Engine=InnoDB');
$expect="CREATE TABLE `test` (\n"
. "\t`id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,\n"
. "\t`name` varchar(255) not null,\n"
. "\t`desc` text,\n"
. "\tprimary key (id, name)\n"
. ") Engine=InnoDB";
$this->assertEquals($expect, $sql);
}
public function testRenameTable()
{
$sql=$this->db->schema->renameTable('test', 'test2');
$expect='RENAME TABLE `test` TO `test2`';
$this->assertEquals($expect, $sql);
}
public function testDropTable()
{
$sql=$this->db->schema->dropTable('test');
$expect='DROP TABLE `test`';
$this->assertEquals($expect, $sql);
}
public function testAddColumn()
{
$sql=$this->db->schema->addColumn('test', 'id', 'integer');
$expect='ALTER TABLE `test` ADD `id` int(11)';
$this->assertEquals($expect, $sql);
}
public function testAlterColumn()
{
$sql=$this->db->schema->alterColumn('test', 'id', 'boolean');
$expect='ALTER TABLE `test` CHANGE `id` `id` tinyint(1)';
$this->assertEquals($expect, $sql);
}
public function testRenameColumn()
{
$sql=$this->db->schema->renameColumn('users', 'username', 'name');
$expect='ALTER TABLE `users` CHANGE `username` `name` varchar(128) NOT NULL';
$this->assertEquals($expect, $sql);
}
public function testDropColumn()
{
$sql=$this->db->schema->dropColumn('test', 'id');
$expect='ALTER TABLE `test` DROP COLUMN `id`';
$this->assertEquals($expect, $sql);
}
public function testAddForeignKey()
{
$sql=$this->db->schema->addForeignKey('fk_test', 'profile', 'user_id', 'users', 'id');
$expect='ALTER TABLE `profile` ADD CONSTRAINT `fk_test` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)';
$this->assertEquals($expect, $sql);
$sql=$this->db->schema->addForeignKey('fk_test', 'profile', 'user_id', 'users', 'id','CASCADE','RESTRICTED');
$expect='ALTER TABLE `profile` ADD CONSTRAINT `fk_test` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE RESTRICTED';
$this->assertEquals($expect, $sql);
}
public function testDropForeignKey()
{
$sql=$this->db->schema->dropForeignKey('fk_test', 'profile');
$expect='ALTER TABLE `profile` DROP FOREIGN KEY `fk_test`';
$this->assertEquals($expect, $sql);
}
public function testCreateIndex()
{
$sql=$this->db->schema->createIndex('id_pk','test','id');
$expect='CREATE INDEX `id_pk` ON `test` (`id`)';
$this->assertEquals($expect, $sql);
$sql=$this->db->schema->createIndex('id_pk','test','id1,id2',true);
$expect='CREATE UNIQUE INDEX `id_pk` ON `test` (`id1`, `id2`)';
$this->assertEquals($expect, $sql);
}
public function testDropIndex()
{
$sql=$this->db->schema->dropIndex('id_pk','test');
$expect='DROP INDEX `id_pk` ON `test`';
$this->assertEquals($expect, $sql);
}
}

View File

@@ -0,0 +1,275 @@
<?php
Yii::import('system.db.CDbConnection');
Yii::import('system.db.schema.mysql.CMysqlSchema');
class CMysqlTest extends CTestCase
{
private $db;
public function setUp()
{
if(!extension_loaded('pdo') || !extension_loaded('pdo_mysql'))
$this->markTestSkipped('PDO and MySQL extensions are required.');
$this->db=new CDbConnection('mysql:host=127.0.0.1;dbname=yii','test','test');
$this->db->charset='UTF8';
try
{
$this->db->active=true;
}
catch(Exception $e)
{
$schemaFile=realpath(dirname(__FILE__).'/../data/mysql.sql');
$this->markTestSkipped("Please read $schemaFile for details on setting up the test environment for MySQL test case.");
}
$tables=array('comments','post_category','posts','categories','profiles','users','items','orders','types');
foreach($tables as $table)
$this->db->createCommand("DROP TABLE IF EXISTS $table CASCADE")->execute();
$sqls=file_get_contents(dirname(__FILE__).'/../data/mysql.sql');
foreach(explode(';',$sqls) as $sql)
{
if(trim($sql)!=='')
$this->db->createCommand($sql)->execute();
}
}
public function tearDown()
{
$this->db->active=false;
}
public function testSchema()
{
$schema=$this->db->schema;
$this->assertTrue($schema instanceof CDbSchema);
$this->assertEquals($schema->dbConnection,$this->db);
$this->assertTrue($schema->commandBuilder instanceof CDbCommandBuilder);
$this->assertEquals('`posts`',$schema->quoteTableName('posts'));
$this->assertEquals('`id`',$schema->quoteColumnName('id'));
$this->assertTrue($schema->getTable('posts') instanceof CDbTableSchema);
$this->assertNull($schema->getTable('foo'));
}
public function testTable()
{
$table=$this->db->schema->getTable('posts');
$this->assertTrue($table instanceof CDbTableSchema);
$this->assertEquals('posts',$table->name);
$this->assertEquals('`posts`',$table->rawName);
$this->assertEquals('id',$table->primaryKey);
$this->assertEquals(array('author_id'=>array('users','id')),$table->foreignKeys);
$this->assertEquals('',$table->sequenceName);
$this->assertEquals(5,count($table->columns));
$this->assertTrue($table->getColumn('id') instanceof CDbColumnSchema);
$this->assertTrue($table->getColumn('foo')===null);
$this->assertEquals(array('id','title','create_time','author_id','content'),$table->columnNames);
$table=$this->db->schema->getTable('orders');
$this->assertEquals(array('key1','key2'),$table->primaryKey);
$table=$this->db->schema->getTable('items');
$this->assertEquals('id',$table->primaryKey);
$this->assertEquals(array('col1'=>array('orders','key1'),'col2'=>array('orders','key2')),$table->foreignKeys);
$table=$this->db->schema->getTable('types');
$this->assertTrue($table instanceof CDbTableSchema);
$this->assertEquals('types',$table->name);
$this->assertEquals('`types`',$table->rawName);
$this->assertTrue($table->primaryKey===null);
$this->assertTrue($table->foreignKeys===array());
$this->assertTrue($table->sequenceName===null);
$table=$this->db->schema->getTable('invalid');
$this->assertNull($table);
}
public function testColumn()
{
$values=array
(
'name'=>array('id', 'title', 'create_time', 'author_id', 'content'),
'rawName'=>array('`id`', '`title`', '`create_time`', '`author_id`', '`content`'),
'defaultValue'=>array(null, null, null, null, null),
'size'=>array(11, 128, null, 11, null),
'precision'=>array(11, 128, null, 11, null),
'scale'=>array(null, null, null, null, null),
'dbType'=>array('int(11)','varchar(128)','timestamp','int(11)','text'),
'type'=>array('integer','string','string','integer','string'),
'isPrimaryKey'=>array(true,false,false,false,false),
'isForeignKey'=>array(false,false,false,true,false),
);
$this->checkColumns('posts',$values);
$values=array
(
'name'=>array('int_col', 'int_col2', 'char_col', 'char_col2', 'char_col3', 'float_col', 'float_col2', 'blob_col', 'numeric_col', 'time', 'bool_col', 'bool_col2'),
'rawName'=>array('`int_col`', '`int_col2`', '`char_col`', '`char_col2`', '`char_col3`', '`float_col`', '`float_col2`', '`blob_col`', '`numeric_col`', '`time`', '`bool_col`', '`bool_col2`'),
'defaultValue'=>array(null, 1, null, 'something', null, null, '1.23', null, '33.22', '2002-01-01 00:00:00', null, 1),
'size'=>array(11, 11, 100, 100, null, 4, null, null, 5, null, 1, 1),
'precision'=>array(11, 11, 100, 100, null, 4, null, null, 5, null, 1, 1),
'scale'=>array(null, null, null, null, null, 3, null, null, 2, null, null, null),
'dbType'=>array('int(11)','int(11)','char(100)','varchar(100)','text','double(4,3)','double','blob','decimal(5,2)','timestamp','tinyint(1)','tinyint(1)'),
'type'=>array('integer','integer','string','string','string','double','double','string','string','string','integer','integer'),
'isPrimaryKey'=>array(false,false,false,false,false,false,false,false,false,false,false,false),
'isForeignKey'=>array(false,false,false,false,false,false,false,false,false,false,false,false),
);
$this->checkColumns('types',$values);
}
protected function checkColumns($tableName,$values)
{
$table=$this->db->schema->getTable($tableName);
foreach($values as $name=>$value)
{
foreach(array_values($table->columns) as $i=>$column)
{
$type1=gettype($column->$name);
$type2=gettype($value[$i]);
$this->assertTrue($column->$name===$value[$i], "$tableName.{$column->name}.$name is {$column->$name} ($type1), different from the expected {$value[$i]} ($type2).");
}
}
}
public function testCommandBuilder()
{
$schema=$this->db->schema;
$builder=$schema->commandBuilder;
$this->assertTrue($builder instanceof CDbCommandBuilder);
$table=$schema->getTable('posts');
$c=$builder->createInsertCommand($table,array('title'=>'test post','create_time'=>'2000-01-01','author_id'=>1,'content'=>'test content'));
$this->assertEquals('INSERT INTO `posts` (`title`, `create_time`, `author_id`, `content`) VALUES (:yp0, :yp1, :yp2, :yp3)',$c->text);
$c->execute();
$this->assertEquals(6,$builder->getLastInsertId($table));
$c=$builder->createCountCommand($table,new CDbCriteria);
$this->assertEquals('SELECT COUNT(*) FROM `posts` `t`',$c->text);
$this->assertEquals(6,$c->queryScalar());
$c=$builder->createDeleteCommand($table,new CDbCriteria(array(
'condition'=>'id=:id',
'params'=>array('id'=>6))));
$this->assertEquals('DELETE FROM `posts` WHERE id=:id',$c->text);
$c->execute();
$c=$builder->createCountCommand($table,new CDbCriteria);
$this->assertEquals(5,$c->queryScalar());
$c=$builder->createFindCommand($table,new CDbCriteria(array(
'select'=>'id, title',
'condition'=>'id=:id',
'params'=>array('id'=>5),
'order'=>'title',
'limit'=>2,
'offset'=>0)));
$this->assertEquals('SELECT id, title FROM `posts` `t` WHERE id=:id ORDER BY title LIMIT 2',$c->text);
$rows=$c->query()->readAll();
$this->assertEquals(1,count($rows));
$this->assertEquals('post 5',$rows[0]['title']);
$c=$builder->createUpdateCommand($table,array('title'=>'new post 5'),new CDbCriteria(array(
'condition'=>'id=:id',
'params'=>array('id'=>5))));
$c->execute();
$c=$builder->createFindCommand($table,new CDbCriteria(array(
'select'=>'title',
'condition'=>'id=:id',
'params'=>array('id'=>5))));
$this->assertEquals('new post 5',$c->queryScalar());
$c=$builder->createSqlCommand('SELECT title FROM posts WHERE id=:id',array(':id'=>3));
$this->assertEquals('post 3',$c->queryScalar());
$c=$builder->createUpdateCounterCommand($table,array('author_id'=>-2),new CDbCriteria(array('condition'=>'id=5')));
$this->assertEquals('UPDATE `posts` SET `author_id`=`author_id`-2 WHERE id=5',$c->text);
$c->execute();
$c=$builder->createSqlCommand('SELECT author_id FROM posts WHERE id=5');
$this->assertEquals(1,$c->queryScalar());
// test bind by position
$c=$builder->createFindCommand($table,new CDbCriteria(array(
'select'=>'title',
'condition'=>'id=?',
'params'=>array(4))));
$this->assertEquals('SELECT title FROM `posts` `t` WHERE id=?',$c->text);
$this->assertEquals('post 4',$c->queryScalar());
// another bind by position
$c=$builder->createUpdateCommand($table,array('title'=>'new post 4'),new CDbCriteria(array(
'condition'=>'id=?',
'params'=>array(4))));
$c->execute();
$c=$builder->createSqlCommand('SELECT title FROM posts WHERE id=4');
$this->assertEquals('new post 4',$c->queryScalar());
// testCreateCriteria
$c=$builder->createCriteria('column=:value',array(':value'=>'value'));
$this->assertEquals('column=:value',$c->condition);
$this->assertEquals(array(':value'=>'value'),$c->params);
$c=$builder->createCriteria(array('condition'=>'column=:value','params'=>array(':value'=>'value')));
$this->assertEquals('column=:value',$c->condition);
$this->assertEquals(array(':value'=>'value'),$c->params);
$c2=$builder->createCriteria($c);
$this->assertTrue($c2!==$c);
$this->assertEquals('column=:value',$c2->condition);
$this->assertEquals(array(':value'=>'value'),$c2->params);
// testCreatePkCriteria
$c=$builder->createPkCriteria($table,1,'author_id>1');
$this->assertEquals('`posts`.`id`=1 AND (author_id>1)',$c->condition);
$c=$builder->createPkCriteria($table,array(1,2));
$this->assertEquals('`posts`.`id` IN (1, 2)',$c->condition);
$c=$builder->createPkCriteria($table,array());
$this->assertEquals('0=1',$c->condition);
$table2=$schema->getTable('orders');
$c=$builder->createPkCriteria($table2,array('key1'=>1,'key2'=>2),'name=``');
$this->assertEquals('`orders`.`key1`=1 AND `orders`.`key2`=2 AND (name=``)',$c->condition);
$c=$builder->createPkCriteria($table2,array(array('key1'=>1,'key2'=>2),array('key1'=>3,'key2'=>4)));
$this->assertEquals('(`orders`.`key1`, `orders`.`key2`) IN ((1, 2), (3, 4))',$c->condition);
// createColumnCriteria
$c=$builder->createColumnCriteria($table,array('id'=>1,'author_id'=>2),'title=``');
$this->assertEquals('`posts`.`id`=:yp0 AND `posts`.`author_id`=:yp1 AND (title=``)',$c->condition);
$c=$builder->createPkCriteria($table2,array());
$this->assertEquals('0=1',$c->condition);
}
public function testResetSequence()
{
$max=$this->db->createCommand("SELECT MAX(id) FROM users")->queryScalar();
$this->db->createCommand("DELETE FROM users")->execute();
$this->db->createCommand("INSERT INTO users (username, password, email) VALUES ('user4','pass4','email4')")->execute();
$max2=$this->db->createCommand("SELECT MAX(id) FROM users")->queryScalar();
$this->assertEquals($max+1,$max2);
$userTable=$this->db->schema->getTable('users');
$this->db->createCommand("DELETE FROM users")->execute();
$this->db->schema->resetSequence($userTable);return;
$this->db->createCommand("INSERT INTO users (username, password, email) VALUES ('user4','pass4','email4')")->execute();
$max=$this->db->createCommand("SELECT MAX(id) FROM users")->queryScalar();
$this->assertEquals(1,$max);
$this->db->createCommand("INSERT INTO users (username, password, email) VALUES ('user4','pass4','email4')")->execute();
$max=$this->db->createCommand("SELECT MAX(id) FROM users")->queryScalar();
$this->assertEquals(2,$max);
$this->db->createCommand("DELETE FROM users")->execute();
$this->db->schema->resetSequence($userTable,10);
$this->db->createCommand("INSERT INTO users (username, password, email) VALUES ('user4','pass4','email4')")->execute();
$max=$this->db->createCommand("SELECT MAX(id) FROM users")->queryScalar();
$this->assertEquals(10,$max);
$this->db->createCommand("INSERT INTO users (username, password, email) VALUES ('user4','pass4','email4')")->execute();
$max=$this->db->createCommand("SELECT MAX(id) FROM users")->queryScalar();
$this->assertEquals(11,$max);
}
}

View File

@@ -0,0 +1,126 @@
<?php
Yii::import('system.db.CDbConnection');
class CPostgres2Test extends CTestCase
{
private $db;
public function setUp()
{
if(!extension_loaded('pdo') || !extension_loaded('pdo_pgsql'))
$this->markTestSkipped('PDO and PostgreSQL extensions are required.');
$this->db=new CDbConnection('pgsql:host=127.0.0.1;dbname=yii','test','test');
$this->db->charset='UTF8';
try
{
$this->db->active=true;
}
catch(Exception $e)
{
$schemaFile=realpath(dirname(__FILE__).'/../data/postgres.sql');
$this->markTestSkipped("Please read $schemaFile for details on setting up the test environment for PostgreSQL test case.");
}
}
public function tearDown()
{
$this->db->active=false;
}
public function testCreateTable()
{
$sql=$this->db->schema->createTable('test',array(
'id'=>'pk',
'name'=>'string not null',
'desc'=>'text',
'primary key (id, name)',
));
$expect="CREATE TABLE \"test\" (\n"
. "\t\"id\" serial NOT NULL PRIMARY KEY,\n"
. "\t\"name\" character varying (255) not null,\n"
. "\t\"desc\" text,\n"
. "\tprimary key (id, name)\n"
. ")";
$this->assertEquals($expect, $sql);
}
public function testRenameTable()
{
$sql=$this->db->schema->renameTable('test', 'test2');
$expect='ALTER TABLE "test" RENAME TO "test2"';
$this->assertEquals($expect, $sql);
}
public function testDropTable()
{
$sql=$this->db->schema->dropTable('test');
$expect='DROP TABLE "test"';
$this->assertEquals($expect, $sql);
}
public function testAddColumn()
{
$sql=$this->db->schema->addColumn('test', 'id', 'integer');
$expect='ALTER TABLE "test" ADD COLUMN "id" integer';
$this->assertEquals($expect, $sql);
}
public function testAlterColumn()
{
$sql=$this->db->schema->alterColumn('test', 'id', 'boolean');
$expect='ALTER TABLE "test" ALTER COLUMN "id" TYPE boolean';
$this->assertEquals($expect, $sql);
}
public function testRenameColumn()
{
$sql=$this->db->schema->renameColumn('users', 'username', 'name');
$expect='ALTER TABLE "users" RENAME COLUMN "username" TO "name"';
$this->assertEquals($expect, $sql);
}
public function testDropColumn()
{
$sql=$this->db->schema->dropColumn('test', 'id');
$expect='ALTER TABLE "test" DROP COLUMN "id"';
$this->assertEquals($expect, $sql);
}
public function testAddForeignKey()
{
$sql=$this->db->schema->addForeignKey('fk_test', 'profile', 'user_id', 'users', 'id');
$expect='ALTER TABLE "profile" ADD CONSTRAINT "fk_test" FOREIGN KEY ("user_id") REFERENCES "users" ("id")';
$this->assertEquals($expect, $sql);
$sql=$this->db->schema->addForeignKey('fk_test', 'profile', 'user_id', 'users', 'id','CASCADE','RESTRICTED');
$expect='ALTER TABLE "profile" ADD CONSTRAINT "fk_test" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE RESTRICTED';
$this->assertEquals($expect, $sql);
}
public function testDropForeignKey()
{
$sql=$this->db->schema->dropForeignKey('fk_test', 'profile');
$expect='ALTER TABLE "profile" DROP CONSTRAINT "fk_test"';
$this->assertEquals($expect, $sql);
}
public function testCreateIndex()
{
$sql=$this->db->schema->createIndex('id_pk','test','id');
$expect='CREATE INDEX "id_pk" ON "test" ("id")';
$this->assertEquals($expect, $sql);
$sql=$this->db->schema->createIndex('id_pk','test','id1,id2',true);
$expect='CREATE UNIQUE INDEX "id_pk" ON "test" ("id1", "id2")';
$this->assertEquals($expect, $sql);
}
public function testDropIndex()
{
$sql=$this->db->schema->dropIndex('id_pk','test');
$expect='DROP INDEX "id_pk"';
$this->assertEquals($expect, $sql);
}
}

View File

@@ -0,0 +1,271 @@
<?php
Yii::import('system.db.CDbConnection');
class CPostgresTest extends CTestCase
{
private $db;
public function setUp()
{
if(!extension_loaded('pdo') || !extension_loaded('pdo_pgsql'))
$this->markTestSkipped('PDO and PostgreSQL extensions are required.');
$this->db=new CDbConnection('pgsql:host=127.0.0.1;dbname=yii','test','test');
$this->db->charset='UTF8';
try
{
$this->db->active=true;
}
catch(Exception $e)
{
$schemaFile=realpath(dirname(__FILE__).'/../data/postgres.sql');
$this->markTestSkipped("Please read $schemaFile for details on setting up the test environment for PostgreSQL test case.");
}
try { $this->db->createCommand('DROP SCHEMA test CASCADE')->execute(); } catch(Exception $e) { }
try { $this->db->createCommand('DROP TABLE yii_types CASCADE')->execute(); } catch(Exception $e) { }
$sqls=file_get_contents(dirname(__FILE__).'/../data/postgres.sql');
foreach(explode(';',$sqls) as $sql)
{
if(trim($sql)!=='')
$this->db->createCommand($sql)->execute();
}
}
public function tearDown()
{
$this->db->active=false;
}
public function testSchema()
{
$schema=$this->db->schema;
$this->assertTrue($schema instanceof CDbSchema);
$this->assertEquals($schema->dbConnection,$this->db);
$this->assertTrue($schema->commandBuilder instanceof CDbCommandBuilder);
$this->assertEquals('"posts"',$schema->quoteTableName('posts'));
$this->assertEquals('"id"',$schema->quoteColumnName('id'));
$this->assertTrue($schema->getTable('test.posts') instanceof CDbTableSchema);
$this->assertTrue($schema->getTable('foo')===null);
}
public function testTable()
{
$table=$this->db->schema->getTable('test.posts');
$this->assertTrue($table instanceof CDbTableSchema);
$this->assertEquals('posts',$table->name);
$this->assertEquals('"test"."posts"',$table->rawName);
$this->assertEquals('id',$table->primaryKey);
$this->assertEquals(array('author_id'=>array('users','id')),$table->foreignKeys);
$this->assertEquals('test.posts_id_seq',$table->sequenceName);
$this->assertEquals(5,count($table->columns));
$this->assertTrue($table->getColumn('id') instanceof CDbColumnSchema);
$this->assertTrue($table->getColumn('foo')===null);
$this->assertEquals(array('id','title','create_time','author_id','content'),$table->columnNames);
$table=$this->db->schema->getTable('test.orders');
$this->assertEquals(array('key1','key2'),$table->primaryKey);
$table=$this->db->schema->getTable('test.items');
$this->assertEquals('id',$table->primaryKey);
$this->assertEquals(array('col1'=>array('orders','key1'),'col2'=>array('orders','key2')),$table->foreignKeys);
$table=$this->db->schema->getTable('yii_types');
$this->assertTrue($table instanceof CDbTableSchema);
$this->assertEquals('yii_types',$table->name);
$this->assertEquals('"yii_types"',$table->rawName);
$this->assertTrue($table->primaryKey===null);
$this->assertTrue($table->foreignKeys===array());
$this->assertTrue($table->sequenceName===null);
$table=$this->db->schema->getTable('invalid');
$this->assertNull($table);
}
public function testColumn()
{
$values=array
(
'name'=>array('id', 'title', 'create_time', 'author_id', 'content'),
'rawName'=>array('"id"', '"title"', '"create_time"', '"author_id"', '"content"'),
'defaultValue'=>array(null, null, null, null, null),
'size'=>array(null, 128, null, null, null),
'precision'=>array(null, 128, null, null, null),
'scale'=>array(null, null, null, null, null),
'type'=>array('integer','string','string','integer','string'),
'isPrimaryKey'=>array(true,false,false,false,false),
'isForeignKey'=>array(false,false,false,true,false),
);
$this->checkColumns('test.posts',$values);
$values=array
(
'name'=>array('int_col', 'int_col2', 'char_col', 'char_col2', 'char_col3', 'numeric_col', 'real_col', 'blob_col', 'time', 'bool_col', 'bool_col2'),
'rawName'=>array('"int_col"', '"int_col2"', '"char_col"', '"char_col2"', '"char_col3"', '"numeric_col"', '"real_col"', '"blob_col"', '"time"', '"bool_col"', '"bool_col2"'),
'defaultValue'=>array(null, 1, null, 'something', null, null, '1.23', null, null, null, true),
'size'=>array(null, null, 100, 100, null, 4, null, null, null, null, null),
'precision'=>array(null, null, 100, 100, null, 4, null, null, null, null, null),
'scale'=>array(null, null, null, null, null, 3, null, null, null, null, null),
'type'=>array('integer','integer','string','string','string','string','double','string','string','boolean','boolean'),
'isPrimaryKey'=>array(false,false,false,false,false,false,false,false,false,false,false),
'isForeignKey'=>array(false,false,false,false,false,false,false,false,false,false,false),
);
$this->checkColumns('yii_types',$values);
}
protected function checkColumns($tableName,$values)
{
$table=$this->db->schema->getTable($tableName);
foreach($values as $name=>$value)
{
foreach(array_values($table->columns) as $i=>$column)
{
$type1=gettype($column->$name);
$type2=gettype($value[$i]);
$this->assertTrue($column->$name===$value[$i], "$tableName.{$column->name}.$name is {$column->$name} ($type1), different from the expected {$value[$i]} ($type2).");
}
}
}
public function testCommandBuilder()
{
$schema=$this->db->schema;
$builder=$schema->commandBuilder;
$this->assertTrue($builder instanceof CDbCommandBuilder);
$table=$schema->getTable('test.posts');
$c=$builder->createInsertCommand($table,array('title'=>'test post','create_time'=>'2004-10-19 10:23:54','author_id'=>1,'content'=>'test content'));
$this->assertEquals('INSERT INTO "test"."posts" ("title", "create_time", "author_id", "content") VALUES (:yp0, :yp1, :yp2, :yp3)',$c->text);
$c->execute();
$this->assertEquals(6,$builder->getLastInsertId($table));
$c=$builder->createCountCommand($table,new CDbCriteria);
$this->assertEquals('SELECT COUNT(*) FROM "test"."posts" "t"',$c->text);
$this->assertEquals(6,$c->queryScalar());
$c=$builder->createDeleteCommand($table,new CDbCriteria(array(
'condition'=>'id=:id',
'params'=>array('id'=>6))));
$this->assertEquals('DELETE FROM "test"."posts" WHERE id=:id',$c->text);
$c->execute();
$c=$builder->createCountCommand($table,new CDbCriteria);
$this->assertEquals(5,$c->queryScalar());
$c=$builder->createFindCommand($table,new CDbCriteria(array(
'select'=>'id, title',
'condition'=>'id=:id',
'params'=>array('id'=>5),
'order'=>'title',
'limit'=>2,
'offset'=>0)));
$this->assertEquals('SELECT id, title FROM "test"."posts" "t" WHERE id=:id ORDER BY title LIMIT 2',$c->text);
$rows=$c->query()->readAll();
$this->assertEquals(1,count($rows));
$this->assertEquals('post 5',$rows[0]['title']);
$c=$builder->createUpdateCommand($table,array('title'=>'new post 5'),new CDbCriteria(array(
'condition'=>'id=:id',
'params'=>array('id'=>5))));
$c->execute();
$c=$builder->createFindCommand($table,new CDbCriteria(array(
'select'=>'title',
'condition'=>'id=:id',
'params'=>array('id'=>5))));
$this->assertEquals('new post 5',$c->queryScalar());
$c=$builder->createSqlCommand('SELECT title FROM test.posts WHERE id=:id',array(':id'=>3));
$this->assertEquals('post 3',$c->queryScalar());
$c=$builder->createUpdateCounterCommand($table,array('author_id'=>-2),new CDbCriteria(array('condition'=>'id=5')));
$this->assertEquals('UPDATE "test"."posts" SET "author_id"="author_id"-2 WHERE id=5',$c->text);
$c->execute();
$c=$builder->createSqlCommand('SELECT author_id FROM posts WHERE id=5');
$this->assertEquals(1,$c->queryScalar());
// test bind by position
$c=$builder->createFindCommand($table,new CDbCriteria(array(
'select'=>'title',
'condition'=>'id=?',
'params'=>array(4))));
$this->assertEquals('SELECT title FROM "test"."posts" "t" WHERE id=?',$c->text);
$this->assertEquals('post 4',$c->queryScalar());
// another bind by position
$c=$builder->createUpdateCommand($table,array('title'=>'new post 4'),new CDbCriteria(array(
'condition'=>'id=?',
'params'=>array(4))));
$c->execute();
$c=$builder->createSqlCommand('SELECT title FROM test.posts WHERE id=4');
$this->assertEquals('new post 4',$c->queryScalar());
// testCreateCriteria
$c=$builder->createCriteria('column=:value',array(':value'=>'value'));
$this->assertEquals('column=:value',$c->condition);
$this->assertEquals(array(':value'=>'value'),$c->params);
$c=$builder->createCriteria(array('condition'=>'column=:value','params'=>array(':value'=>'value')));
$this->assertEquals('column=:value',$c->condition);
$this->assertEquals(array(':value'=>'value'),$c->params);
$c2=$builder->createCriteria($c);
$this->assertTrue($c2!==$c);
$this->assertEquals('column=:value',$c2->condition);
$this->assertEquals(array(':value'=>'value'),$c2->params);
// testCreatePkCriteria
$c=$builder->createPkCriteria($table,1,'author_id>1');
$this->assertEquals('"test"."posts"."id"=1 AND (author_id>1)',$c->condition);
$c=$builder->createPkCriteria($table,array(1,2));
$this->assertEquals('"test"."posts"."id" IN (1, 2)',$c->condition);
$table2=$schema->getTable('test.orders');
$c=$builder->createPkCriteria($table2,array('key1'=>1,'key2'=>2),'name=\'\'');
$this->assertEquals('"test"."orders"."key1"=1 AND "test"."orders"."key2"=2 AND (name=\'\')',$c->condition);
$c=$builder->createPkCriteria($table2,array(array('key1'=>1,'key2'=>2),array('key1'=>3,'key2'=>4)));
$this->assertEquals('("test"."orders"."key1", "test"."orders"."key2") IN ((1, 2), (3, 4))',$c->condition);
// createColumnCriteria
$c=$builder->createColumnCriteria($table,array('id'=>1,'author_id'=>2),'title=\'\'');
$this->assertEquals('"test"."posts"."id"=:yp0 AND "test"."posts"."author_id"=:yp1 AND (title=\'\')',$c->condition);
}
public function testResetSequence()
{
$max=$this->db->createCommand("SELECT MAX(id) FROM test.users")->queryScalar();
$this->db->createCommand("DELETE FROM test.users")->execute();
$this->db->createCommand("INSERT INTO test.users (username, password, email) VALUES ('user4','pass4','email4')")->execute();
$max2=$this->db->createCommand("SELECT MAX(id) FROM test.users")->queryScalar();
$this->assertEquals($max+1,$max2);
$userTable=$this->db->schema->getTable('test.users');
$this->db->createCommand("DELETE FROM test.users")->execute();
$this->db->schema->resetSequence($userTable);
$this->db->createCommand("INSERT INTO test.users (username, password, email) VALUES ('user4','pass4','email4')")->execute();
$max=$this->db->createCommand("SELECT MAX(id) FROM test.users")->queryScalar();
$this->assertEquals(1,$max);
$this->db->createCommand("INSERT INTO test.users (username, password, email) VALUES ('user4','pass4','email4')")->execute();
$max=$this->db->createCommand("SELECT MAX(id) FROM test.users")->queryScalar();
$this->assertEquals(2,$max);
$this->db->createCommand("DELETE FROM test.users")->execute();
$this->db->schema->resetSequence($userTable,10);
$this->db->createCommand("INSERT INTO test.users (username, password, email) VALUES ('user4','pass4','email4')")->execute();
$max=$this->db->createCommand("SELECT MAX(id) FROM test.users")->queryScalar();
$this->assertEquals(10,$max);
$this->db->createCommand("INSERT INTO test.users (username, password, email) VALUES ('user4','pass4','email4')")->execute();
$max=$this->db->createCommand("SELECT MAX(id) FROM test.users")->queryScalar();
$this->assertEquals(11,$max);
}
public function testCheckIntegrity()
{
$this->db->schema->checkIntegrity(false,'test');
$this->db->createCommand("INSERT INTO test.profiles (first_name, last_name, user_id) VALUES ('first 1','last 1',1000)")->execute();
$this->db->schema->checkIntegrity(true,'test');
}
}

View File

@@ -0,0 +1,258 @@
<?php
Yii::import('system.db.CDbConnection');
Yii::import('system.db.schema.sqlite.CSqliteSchema');
class CSqliteTest extends CTestCase
{
private $db;
public function setUp()
{
if(!extension_loaded('pdo') || !extension_loaded('pdo_sqlite'))
$this->markTestSkipped('PDO and SQLite extensions are required.');
$this->db=new CDbConnection('sqlite::memory:');
$this->db->active=true;
$this->db->pdoInstance->exec(file_get_contents(dirname(__FILE__).'/../data/sqlite.sql'));
}
public function tearDown()
{
$this->db->active=false;
}
public function testSchema()
{
$schema=$this->db->schema;
$this->assertTrue($schema instanceof CDbSchema);
$this->assertEquals($schema->dbConnection,$this->db);
$this->assertTrue($schema->commandBuilder instanceof CDbCommandBuilder);
$this->assertEquals('\'posts\'',$schema->quoteTableName('posts'));
$this->assertEquals('"id"',$schema->quoteColumnName('id'));
$this->assertTrue($schema->getTable('posts') instanceof CDbTableSchema);
$this->assertTrue($schema->getTable('foo')===null);
}
public function testTable()
{
$table=$this->db->schema->getTable('posts');
$this->assertTrue($table instanceof CDbTableSchema);
$this->assertEquals('posts',$table->name);
$this->assertEquals('\'posts\'',$table->rawName);
$this->assertEquals('id',$table->primaryKey);
$this->assertEquals(array('author_id'=>array('users','id')),$table->foreignKeys);
$this->assertTrue($table->sequenceName==='');
$this->assertEquals(5,count($table->columns));
$this->assertTrue($table->getColumn('id') instanceof CDbColumnSchema);
$this->assertTrue($table->getColumn('foo')===null);
$this->assertEquals(array('id','title','create_time','author_id','content'),$table->columnNames);
$table=$this->db->schema->getTable('orders');
$this->assertEquals(array('key1','key2'),$table->primaryKey);
$table=$this->db->schema->getTable('items');
$this->assertEquals('id',$table->primaryKey);
$this->assertEquals(array('col1'=>array('orders','key1'),'col2'=>array('orders','key2')),$table->foreignKeys);
$table=$this->db->schema->getTable('types');
$this->assertTrue($table->primaryKey===null);
$this->assertTrue($table->foreignKeys===array());
$this->assertTrue($table->sequenceName===null);
$table=$this->db->schema->getTable('invalid');
$this->assertNull($table);
}
public function testColumn()
{
$values=array
(
'name'=>array('id', 'title', 'create_time', 'author_id', 'content'),
'rawName'=>array('"id"', '"title"', '"create_time"', '"author_id"', '"content"'),
'defaultValue'=>array(null, null, null, null, null),
'size'=>array(null, 128, null, null, null),
'precision'=>array(null, 128, null, null, null),
'scale'=>array(null, null, null, null, null),
'dbType'=>array('integer','varchar(128)','timestamp','integer','text'),
'type'=>array('integer','string','string','integer','string'),
'isPrimaryKey'=>array(true,false,false,false,false),
'isForeignKey'=>array(false,false,false,true,false),
);
$this->checkColumns('posts',$values);
$values=array
(
'name'=>array('int_col', 'int_col2', 'char_col', 'char_col2', 'char_col3', 'float_col', 'float_col2', 'blob_col', 'numeric_col', 'time', 'bool_col', 'bool_col2', 'null_col'),
'rawName'=>array('"int_col"', '"int_col2"', '"char_col"', '"char_col2"', '"char_col3"', '"float_col"', '"float_col2"', '"blob_col"', '"numeric_col"', '"time"', '"bool_col"', '"bool_col2"', '"null_col"'),
'defaultValue'=>array(null, 1, null, 'something', null, null, '1.23', null, '33.22', '123', null, true, null),
'size'=>array(null, null, 100, 100, null, 4, null, null, 5, null, null, null, null),
'precision'=>array(null, null, 100, 100, null, 4, null, null, 5, null, null, null, null),
'scale'=>array(null, null, null, null, null, 3, null, null, 2, null, null, null, null),
'dbType'=>array('int','integer','char(100)','varchar(100)','text','real(4,3)','double','blob','numeric(5,2)','timestamp','bool','boolean','integer'),
'type'=>array('integer','integer','string','string','string','double','double','string','string','string','boolean','boolean','integer'),
'isPrimaryKey'=>array(false,false,false,false,false,false,false,false,false,false,false,false,false),
'isForeignKey'=>array(false,false,false,false,false,false,false,false,false,false,false,false,false),
);
$this->checkColumns('types',$values);
}
protected function checkColumns($tableName,$values)
{
$table=$this->db->schema->getTable($tableName);
foreach($values as $name=>$value)
{
foreach(array_values($table->columns) as $i=>$column)
{
$type1=gettype($column->$name);
$type2=gettype($value[$i]);
$this->assertTrue($column->$name===$value[$i], "$tableName.{$column->name}.$name is {$column->$name} ($type1), different from the expected {$value[$i]} ($type2).");
}
}
}
public function testCommandBuilder()
{
$schema=$this->db->schema;
$builder=$schema->commandBuilder;
$this->assertTrue($builder instanceof CDbCommandBuilder);
$table=$schema->getTable('posts');
$c=$builder->createInsertCommand($table,array('title'=>'test post','create_time'=>time(),'author_id'=>1,'content'=>'test content'));
$this->assertEquals('INSERT INTO \'posts\' ("title", "create_time", "author_id", "content") VALUES (:yp0, :yp1, :yp2, :yp3)',$c->text);
$c->execute();
$this->assertEquals(6,$builder->getLastInsertId($table));
$c=$builder->createCountCommand($table,new CDbCriteria);
$this->assertEquals('SELECT COUNT(*) FROM \'posts\' \'t\'',$c->text);
$this->assertEquals(6,$c->queryScalar());
$c=$builder->createDeleteCommand($table,new CDbCriteria(array(
'condition'=>'id=:id',
'params'=>array('id'=>6))));
$this->assertEquals('DELETE FROM \'posts\' WHERE id=:id',$c->text);
$c->execute();
$c=$builder->createCountCommand($table,new CDbCriteria);
$this->assertEquals(5,$c->queryScalar());
$c=$builder->createFindCommand($table,new CDbCriteria(array(
'select'=>'id, title',
'condition'=>'id=:id',
'params'=>array('id'=>5),
'order'=>'title',
'limit'=>2,
'offset'=>0)));
$this->assertEquals('SELECT id, title FROM \'posts\' \'t\' WHERE id=:id ORDER BY title LIMIT 2',$c->text);
$rows=$c->query()->readAll();
$this->assertEquals(1,count($rows));
$this->assertEquals('post 5',$rows[0]['title']);
$c=$builder->createUpdateCommand($table,array('title'=>'new post 5'),new CDbCriteria(array(
'condition'=>'id=:id',
'params'=>array('id'=>5))));
$c->execute();
$c=$builder->createFindCommand($table,new CDbCriteria(array(
'select'=>'title',
'condition'=>'id=:id',
'params'=>array('id'=>5))));
$this->assertEquals('new post 5',$c->queryScalar());
$c=$builder->createSqlCommand('SELECT title FROM posts \'t\' WHERE id=:id',array(':id'=>3));
$this->assertEquals('post 3',$c->queryScalar());
$c=$builder->createUpdateCounterCommand($table,array('author_id'=>-2),new CDbCriteria(array('condition'=>'id=5')));
$this->assertEquals('UPDATE \'posts\' SET "author_id"="author_id"-2 WHERE id=5',$c->text);
$c->execute();
$c=$builder->createSqlCommand('SELECT author_id FROM posts WHERE id=5');
$this->assertEquals(1,$c->queryScalar());
// test bind by position
$c=$builder->createFindCommand($table,new CDbCriteria(array(
'select'=>'title',
'condition'=>'id=?',
'params'=>array(4))));
$this->assertEquals('SELECT title FROM \'posts\' \'t\' WHERE id=?',$c->text);
$this->assertEquals('post 4',$c->queryScalar());
// another bind by position
$c=$builder->createUpdateCommand($table,array('title'=>'new post 4'),new CDbCriteria(array(
'condition'=>'id=?',
'params'=>array(4))));
$c->execute();
$c=$builder->createSqlCommand('SELECT title FROM posts WHERE id=4');
$this->assertEquals('new post 4',$c->queryScalar());
// testCreateCriteria
$c=$builder->createCriteria('column=:value',array(':value'=>'value'));
$this->assertEquals('column=:value',$c->condition);
$this->assertEquals(array(':value'=>'value'),$c->params);
$c=$builder->createCriteria(array('condition'=>'column=:value','params'=>array(':value'=>'value')));
$this->assertEquals('column=:value',$c->condition);
$this->assertEquals(array(':value'=>'value'),$c->params);
$c2=$builder->createCriteria($c);
$this->assertTrue($c2!==$c);
$this->assertEquals('column=:value',$c2->condition);
$this->assertEquals(array(':value'=>'value'),$c2->params);
// testCreatePkCriteria
$c=$builder->createPkCriteria($table,1,'author_id>1');
$this->assertEquals('\'posts\'."id"=1 AND (author_id>1)',$c->condition);
$c=$builder->createPkCriteria($table,array(1,2));
$this->assertEquals('\'posts\'."id" IN (1, 2)',$c->condition);
$c=$builder->createPkCriteria($table,array());
$this->assertEquals('0=1',$c->condition);
$table2=$schema->getTable('orders');
$c=$builder->createPkCriteria($table2,array('key1'=>1,'key2'=>2),'name=\'\'');
$this->assertEquals('\'orders\'."key1"=1 AND \'orders\'."key2"=2 AND (name=\'\')',$c->condition);
$c=$builder->createPkCriteria($table2,array(array('key1'=>1,'key2'=>2),array('key1'=>3,'key2'=>4)));
$this->assertEquals('\'orders\'."key1"||\',\'||\'orders\'."key2" IN (1||\',\'||2, 3||\',\'||4)',$c->condition);
// createColumnCriteria
$c=$builder->createColumnCriteria($table,array('id'=>1,'author_id'=>2),'title=\'\'');
$this->assertEquals('\'posts\'."id"=:yp0 AND \'posts\'."author_id"=:yp1 AND (title=\'\')',$c->condition);
$c=$builder->createPkCriteria($table2,array());
$this->assertEquals('0=1',$c->condition);
}
public function testResetSequence()
{
$max=$this->db->createCommand("SELECT MAX(id) FROM users")->queryScalar();
$this->db->createCommand("DELETE FROM users")->execute();
$this->db->createCommand("INSERT INTO users (username, password, email) VALUES ('user4','pass4','email4')")->execute();
$max2=$this->db->createCommand("SELECT MAX(id) FROM users")->queryScalar();
$this->assertEquals($max+1,$max2);
$userTable=$this->db->schema->getTable('users');
$this->db->createCommand("DELETE FROM users")->execute();
$this->db->schema->resetSequence($userTable);
$this->db->createCommand("INSERT INTO users (username, password, email) VALUES ('user4','pass4','email4')")->execute();
$max=$this->db->createCommand("SELECT MAX(id) FROM users")->queryScalar();
$this->assertEquals(1,$max);
$this->db->createCommand("INSERT INTO users (username, password, email) VALUES ('user4','pass4','email4')")->execute();
$max=$this->db->createCommand("SELECT MAX(id) FROM users")->queryScalar();
$this->assertEquals(2,$max);
$this->db->createCommand("DELETE FROM users")->execute();
$this->db->schema->resetSequence($userTable,10);
$this->db->createCommand("INSERT INTO users (username, password, email) VALUES ('user4','pass4','email4')")->execute();
$max=$this->db->createCommand("SELECT MAX(id) FROM users")->queryScalar();
$this->assertEquals(10,$max);
$this->db->createCommand("INSERT INTO users (username, password, email) VALUES ('user4','pass4','email4')")->execute();
$max=$this->db->createCommand("SELECT MAX(id) FROM users")->queryScalar();
$this->assertEquals(11,$max);
}
public function testCheckIntegrity()
{
$this->db->schema->checkIntegrity(false);
$this->db->schema->checkIntegrity(true);
}
}

View File

@@ -0,0 +1,49 @@
CREATE TABLE teams
(
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
name VARCHAR(128) NOT NULL,
create_time TIMESTAMP NOT NULL,
description TEXT DEFAULT 'not set'
);
CREATE TABLE players
(
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
name VARCHAR(128) NOT NULL,
team_id INTEGER NOT NULL,
CONSTRAINT FK_team_player FOREIGN KEY (team_id)
REFERENCES teams (id) ON DELETE CASCADE ON UPDATE RESTRICT
);
CREATE TABLE skills
(
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
name VARCHAR(128) NOT NULL
);
CREATE TABLE player_skill
(
player_id INTEGER NOT NULL,
skill_id INTEGER NOT NULL,
level REAL (3,4),
PRIMARY KEY (player_id, skill_id),
CONSTRAINT FK_player_skill_player FOREIGN KEY (player_id)
REFERENCES players (id) ON DELETE CASCADE ON UPDATE RESTRICT,
CONSTRAINT FK_player_skill_skill FOREIGN KEY (skill_id)
REFERENCES skills (id) ON DELETE CASCADE ON UPDATE RESTRICT
);
CREATE TABLE categories
(
id INTEGER NOT NULL,
sub_id INTEGER NOT NULL
);
CREATE TABLE products
(
id INTEGER NOT NULL,
cat_id INTEGER NOT NULL,
subcat_id INTEGER NOT NULL,
CONSTRAINT FK_product_categories FOREIGN KEY (cat_id,subcat_id)
REFERENCES categories (id,sub_id) ON DELETE CASCADE ON UPDATE RESTRICT
);

View File

@@ -0,0 +1,98 @@
<?php
class CLocaleTest extends CTestCase
{
private $noPlurals = array(
'az', 'bm', 'fa', 'ig', 'hu', 'ja', 'kde', 'kea', 'ko', 'my', 'ses', 'sg',
'to', 'tr', 'vi', 'wo', 'yo', 'zh', 'bo', 'dz', 'id', 'jv', 'ka', 'km',
'kn', 'ms', 'th'
);
/**
* Codes of locales where official guide translation exists
*/
protected $criticalLocaleCodes = array(
'en',
'bg',
'bs',
'cs',
'de',
'el',
'es',
'fr',
'he',
'hu',
'id',
'it',
'ja',
'lv',
'nl',
'no',
'pl',
'pt',
'ro',
'ru',
'sk',
'sr',
'sr_yu',
'sv',
'ta_in',
'th',
'tr',
'uk',
'vi',
'zh_cn',
'zh_tw',
);
function setUp()
{
$config = array(
'language' => 'en',
);
new TestApplication($config);
Yii::app()->configure($config);
}
function testRequiredDataExistence(){
foreach($this->criticalLocaleCodes as $localeCode){
$locale = Yii::app()->getLocale($localeCode);
// AM/PM
$this->assertNotNull($locale->getAMName(), "$localeCode: getAMName failed.");
$this->assertNotNull($locale->getPMName(), "$localeCode: getPMName failed.");
// currency
$this->assertNotNull($locale->getCurrencySymbol("USD"), "$localeCode: getCurrencySymbol USD failed.");
$this->assertNotNull($locale->getCurrencySymbol("EUR"), "$localeCode: getCurrencySymbol EUR failed.");
// numbers
$this->assertNotNull($locale->getNumberSymbol('decimal'), "$localeCode: getNumberSymbol failed.");
$this->assertNotNull($locale->getDecimalFormat(), "$localeCode: getDecimalFormat failed.");
$this->assertNotNull($locale->getCurrencyFormat(), "$localeCode: getCurrencyFormat failed.");
$this->assertNotNull($locale->getPercentFormat(), "$localeCode: getPercentFormat failed.");
$this->assertNotNull($locale->getScientificFormat(), "$localeCode: getScientificFormat failed.");
// date and time formats
$this->assertNotNull($locale->getMonthName(1), "$localeCode: getMonthName 1 failed.");
$this->assertNotNull($locale->getMonthName(12, 'abbreviated'), "$localeCode: getMonthName 12 abbreviated failed.");
$this->assertNotNull($locale->getMonthName(1, 'narrow', true), "$localeCode: getMonthName 1 narrow standalone failed.");
$this->assertEquals(12, count($locale->getMonthNames()), "$localeCode: getMonthNames failed.");
$this->assertNotNull($locale->getWeekDayName(0), "$localeCode: getWeekDayName failed.");
$this->assertNotNull($locale->getWeekDayNames(), "$localeCode: getWeekDayNames failed.");
$this->assertNotNull($locale->getEraName(1), "$localeCode: getEraName failed.");
$this->assertNotNull($locale->getDateFormat(), "$localeCode: getDateFormat failed.");
$this->assertNotNull($locale->getTimeFormat(), "$localeCode: getTimeFormat failed.");
$this->assertNotNull($locale->getDateTimeFormat(), "$localeCode: getDateTimeFormat failed.");
// ORIENTATION
$this->assertTrue(in_array($locale->getOrientation(), array('ltr', 'rtl')), "$localeCode: getOrientation failed.");
// plurals
$l = explode('_', $localeCode);
if(!in_array($l[0], $this->noPlurals)){
$pluralRules = $locale->getPluralRules();
$this->assertNotEmpty($pluralRules, $localeCode.": no plural rules");
}
}
}
}

View File

@@ -0,0 +1,70 @@
<?php
class CNumberFormatterTest extends CTestCase
{
public $usFormatter;
public $deFormatter;
public function setUp()
{
$this->usFormatter=new CNumberFormatter('en_us');
$this->deFormatter=new CNumberFormatter('de');
}
public function testFormatCurrency()
{
$numbers=array(
array(0, '$0.00', '0,00 $'),
array(100, '$100.00', '100,00 $'),
array(-100, '($100.00)', '-100,00 $'),
array(100.123, '$100.12', '100,12 $'),
array(100.1, '$100.10', '100,10 $'),
array(100.126, '$100.13', '100,13 $'),
array(1000.126, '$1,000.13', '1.000,13 $'),
array(1000000.123, '$1,000,000.12', '1.000.000,12 $'),
);
foreach($numbers as $number)
{
$this->assertEquals($number[1],$this->usFormatter->formatCurrency($number[0],'USD'));
$this->assertEquals($number[2],$this->deFormatter->formatCurrency($number[0],'USD'));
}
}
public function testFormatDecimal()
{
$numbers=array(
array(0, '0', '0'),
array(100, '100', '100'),
array(-100, '-100', '-100'),
array(100.123, '100.123', '100,123'),
array(100.1, '100.1', '100,1'),
array(100.1206, '100.121', '100,121'),
array(1000.1206, '1,000.121', '1.000,121'),
array(1000000.123, '1,000,000.123', '1.000.000,123'),
);
foreach($numbers as $number)
{
$this->assertEquals($number[1],$this->usFormatter->formatDecimal($number[0]));
$this->assertEquals($number[2],$this->deFormatter->formatDecimal($number[0]));
}
}
public function testFormatPercentage()
{
$numbers=array(
array(0, '0%', '0 %'),
array(0.123, '12%', '12 %'),
array(-0.123, '-12%', '-12 %'),
array(10.12, '1,012%', '1.012 %'),
array(10000.1, '1,000,010%', '1.000.010 %'),
);
foreach($numbers as $number)
{
$this->assertEquals($number[1],$this->usFormatter->formatPercentage($number[0]));
$this->assertEquals($number[2],$this->deFormatter->formatPercentage($number[0]));
}
}
}

View File

@@ -0,0 +1,186 @@
<?php
/**
* Tests for various usages of Yii::t
*
* http://code.google.com/p/yii/issues/detail?id=1875
* http://code.google.com/p/yii/issues/detail?id=1987
*
* http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html
*/
class YiiTTest extends CTestCase
{
function setUp()
{
$config = array(
'sourceLanguage' => 'es',
'components' => array(
'messages' => array(
'class' => 'CPhpMessageSource',
'basePath' => dirname(__FILE__).'/data',
//'forceTranslation' => true,
),
),
);
new TestApplication($config);
Yii::app()->configure($config);
}
// Simple: 'msg'
function testSimple(){
Yii::app()->setLanguage('ru');
$this->assertEquals('апельсины', Yii::t('test', 'oranges'));
}
function testSimpleSameLanguage(){
Yii::app()->setLanguage('es');
$this->assertEquals('no_changes', Yii::t('test', 'no_changes'));
}
function testSimplePlaceholders(){
Yii::app()->setLanguage('ru');
$this->assertEquals('сумочки caviar', Yii::t('test', '{brand} bags', array('{brand}' => 'caviar')));
$this->assertEquals('в корзине: 10', Yii::t('test', 'in the cart: {n}', 10));
}
function testSimplePlaceholdersSameLanguage(){
Yii::app()->setLanguage('es');
$this->assertEquals('10 changes', Yii::t('test', '{n} changes', 10));
}
// Plural: 'msg1|msg2|msg3'
function testPlural(){
// CLDR
Yii::app()->setLanguage('ru');
// array notation
$this->assertEquals('огурец', Yii::t('test', 'cucumber|cucumbers', array(1)));
//ru
$this->assertEquals('огурец', Yii::t('test', 'cucumber|cucumbers', 1));
$this->assertEquals('огурец', Yii::t('test', 'cucumber|cucumbers', 101));
$this->assertEquals('огурец', Yii::t('test', 'cucumber|cucumbers', 51));
$this->assertEquals('огурца', Yii::t('test', 'cucumber|cucumbers', 2));
$this->assertEquals('огурца', Yii::t('test', 'cucumber|cucumbers', 62));
$this->assertEquals('огурца', Yii::t('test', 'cucumber|cucumbers', 104));
$this->assertEquals('огурцов', Yii::t('test', 'cucumber|cucumbers', 5));
$this->assertEquals('огурцов', Yii::t('test', 'cucumber|cucumbers', 78));
$this->assertEquals('огурцов', Yii::t('test', 'cucumber|cucumbers', 320));
$this->assertEquals('огурцов', Yii::t('test', 'cucumber|cucumbers', 0));
// fractions (you should specify fourh variant to use these in Russian)
$this->assertEquals('огурца', Yii::t('test', 'cucumber|cucumbers', 1.5));
// en
Yii::app()->setLanguage('en');
$this->assertEquals('cucumber', Yii::t('test', 'cucumber|cucumbers', 1));
$this->assertEquals('cucumbers', Yii::t('test', 'cucumber|cucumbers', 2));
$this->assertEquals('cucumbers', Yii::t('test', 'cucumber|cucumbers', 0));
// short forms
Yii::app()->setLanguage('ru');
$this->assertEquals('огурец', Yii::t('test', 'cucumber|cucumbers', 1));
// explicit params
$this->assertEquals('огурец', Yii::t('test', 'cucumber|cucumbers', array(0 => 1)));
}
function testPluralPlaceholders(){
Yii::app()->setLanguage('ru');
$this->assertEquals('1 огурец', Yii::t('test', '{n} cucumber|{n} cucumbers', 1));
$this->assertEquals('2 огурца', Yii::t('test', '{n} cucumber|{n} cucumbers', 2));
$this->assertEquals('5 огурцов', Yii::t('test', '{n} cucumber|{n} cucumbers', 5));
// more placeholders
$this->assertEquals('+ 5 огурцов', Yii::t('test', '{sign} {n} cucumber|{sign} {n} cucumbers', array(5, '{sign}' => '+')));
// placeholder swapping
$this->assertEquals('один огурец', Yii::t('test', '{n} cucumber|{n} cucumbers', array(1, '{n}' => 'один')));
}
/**
* If there are useless params in translation just ignore them.
*/
function testPluralMoreVariants(){
Yii::app()->setLanguage('ru');
$this->assertEquals('шляпы', Yii::t('test', 'hat|hats', array(2)));
}
/**
* If there are less variants in translation like
* 'zombie|zombies' => 'зомби' (CLDR requires 3 variants for Russian
* but zombie is too special to be plural)
*
* Same for Chinese but there are no plurals at all.
*/
function testPluralLessVariants(){
// three variants are required and only one specified (still valid for
// Russian in some special cases)
Yii::app()->setLanguage('ru');
$this->assertEquals('зомби', Yii::t('test', 'zombie|zombies', 10));
$this->assertEquals('зомби', Yii::t('test', 'zombie|zombies', 1));
// language with no plurals
Yii::app()->setLanguage('zh_cn');
$this->assertEquals('k-s', Yii::t('test', 'kiss|kisses', 1));
// 3 variants are required while only 2 specified
// this one is synthetic but still good to know it at least does not
// produce error
Yii::app()->setLanguage('ru');
$this->assertEquals('син1', Yii::t('test', 'syn1|syn2|syn3', 1));
$this->assertEquals('син2', Yii::t('test', 'syn1|syn2|syn3', 2));
$this->assertEquals('син2', Yii::t('test', 'syn1|syn2|syn3', 5));
}
function pluralLessVariantsInSource(){
// new doesn't have two forms in English
Yii::app()->setLanguage('ru');
$this->assertEquals('новости', Yii::t('test', 'news', 2));
}
function testPluralSameLanguage(){
Yii::app()->setLanguage('es');
$this->assertEquals('cucumbez', Yii::t('test', 'cucumbez|cucumberz', 1));
$this->assertEquals('cucumberz', Yii::t('test', 'cucumbez|cucumberz', 2));
$this->assertEquals('cucumberz', Yii::t('test', 'cucumbez|cucumberz', 0));
}
function testPluralPlaceholdersSameLanguage(){
Yii::app()->setLanguage('es');
$this->assertEquals('1 cucumbez', Yii::t('test', '{n} cucumbez|{n} cucumberz', 1));
$this->assertEquals('2 cucumberz', Yii::t('test', '{n} cucumbez|{n} cucumberz', 2));
$this->assertEquals('5 cucumberz', Yii::t('test', '{n} cucumbez|{n} cucumberz', 5));
}
// Choice: 'expr1#msg1|expr2#msg2|expr3#msg3'
function testChoice(){
Yii::app()->setLanguage('ru');
// simple choices
$this->assertEquals('одна книга', Yii::t('test', 'n==1#one book|n>1#many books', 1));
$this->assertEquals('много книг', Yii::t('test', 'n==1#one book|n>1#many books', 10));
$this->assertEquals('одна книга', Yii::t('test', '1#one book|n>1#many books', 1));
$this->assertEquals('много книг', Yii::t('test', '1#one book|n>1#many books', 10));
}
function testChoiceSameLanguage(){
Yii::app()->setLanguage('es');
$this->assertEquals('one book', Yii::t('test', 'n==1#one book|n>1#many books', 1));
$this->assertEquals('many books', Yii::t('test', 'n==1#one book|n>1#many books', 10));
}
function testChoicePlaceholders(){
//$this->assertEquals('51 apples', Yii::t('app', '1#1apple|n>1|{n} apples', array(51, 'n'=>51)));
}
function testChoicePlaceholdersSameLanguage(){
}
}

View File

@@ -0,0 +1,4 @@
<?php
return array(
'cucumber|cucumbers' => 'cucumber|cucumbers',
);

View File

@@ -0,0 +1,15 @@
<?php
return array(
'oranges' => 'апельсины',
'{brand} bags' => 'сумочки {brand}',
'in the cart: {n}' => 'в корзине: {n}',
'cucumber|cucumbers' => 'огурец|огурца|огурцов|огурца',
'{n} cucumber|{n} cucumbers' => '{n} огурец|{n} огурца|{n} огурцов',
'{sign} {n} cucumber|{sign} {n} cucumbers' => '{sign} {n} огурец|{sign} {n} огурца|{sign} {n} огурцов',
'zombie|zombies' => 'зомби',
'hat|hats' => 'шляпа|шляпы|шляп|useless1|useless2',
'news' => 'новость|новости|новостей',
'syn1|syn2|syn3' => 'син1|син2',
'n==1#one book|n>1#many books' => 'n==1#одна книга|n>1#много книг',
'1#one book|n>1#many books' => '1#одна книга|n>1#много книг',
);

View File

@@ -0,0 +1,4 @@
<?php
return array(
'kiss|kisses' => 'k-s',
);

View File

@@ -0,0 +1,11 @@
<?php
class CDateTimeParserTest extends CTestCase
{
function testParseDefaults()
{
$this->assertEquals(
'31-12-2011 23:59:59',
date('d-m-Y H:i:s', CDateTimeParser::parse('2011-12-31', 'yyyy-MM-dd', array('hour' => 23, 'minute' => 59, 'second' => 59)))
);
}
}

View File

@@ -0,0 +1,12 @@
<?php
require 'ValidatorTestModel.php';
class CEmailValidatorTest extends CTestCase
{
function testEmpty()
{
$model = new ValidatorTestModel();
$model->validate(array('email'));
$this->assertArrayHasKey('email', $model->getErrors());
}
}

View File

@@ -0,0 +1,12 @@
<?php
class ValidatorTestModel extends CFormModel
{
public $email;
public function rules()
{
return array(
array('email', 'email', 'allowEmpty' => false),
);
}
}

View File

@@ -0,0 +1,42 @@
<?php
Yii::import('system.web.CAssetManager');
class CAssetManagerTest extends CTestCase
{
public function testBasePath()
{
$am2=new CAssetManager;
$app=new TestApplication;
$app->reset();
$am2->init($app);
$this->assertEquals($am2->basePath,$app->basePath.DIRECTORY_SEPARATOR.'assets');
}
public function testBaseUrl()
{
$app=new TestApplication;
$app->request->baseUrl='/test';
$am=new CAssetManager;
$am->init($app);
$this->assertEquals($am->baseUrl,'/test/assets');
}
public function testPublishFile()
{
$app=new TestApplication;
$app->reset();
$am=new CAssetManager;
$am->init($app);
$path1=$am->getPublishedPath(__FILE__);
clearstatcache();
$this->assertFalse(is_file($path1));
$url=$am->publish(__FILE__);
$path2=$am->getPublishedPath(__FILE__);
$this->assertEquals($path1,$path2);
clearstatcache();
$this->assertTrue(is_file($path1));
$this->assertEquals(basename($path1),basename(__FILE__));
$this->assertEquals($url,$am->baseUrl.'/'.basename(dirname($path2)).'/'.basename($path2));
}
}

View File

@@ -0,0 +1,187 @@
<?php
Yii::import('system.web.CController');
Yii::import('system.web.filters.CFilter');
Yii::import('system.web.actions.CAction');
class TestController extends CController
{
public $defaultAction='external';
public $internal=0;
public $external=0;
public $internalFilter1=0;
public $internalFilter2=0;
public $internalFilter3=0;
public $externalFilter=0;
public function filters()
{
return array(
'filter1',
'filter2 + internal',
array(
'TestFilter',
'expire'=>300,
),
'filter3 - internal',
);
}
public function actions()
{
return array(
'external'=>'TestAction',
);
}
public function missingAction($actionName)
{
throw new CException('test missing');
}
public function filterFilter1($chain)
{
$chain->run();
$this->internalFilter1++;
}
public function filterFilter2($chain)
{
$this->internalFilter2++;
$chain->run();
}
public function filterFilter3($chain)
{
$this->internalFilter3++;
$chain->run();
}
public function actionInternal()
{
$this->internal++;
}
public $a;
public $b;
public $c;
public $d;
public function actionCreate($a,$b,$c=3,$d=4)
{
$this->a=$a;
$this->b=$b;
$this->c=$c;
$this->d=$d;
}
}
class TestFilter extends CFilter
{
public $expire=0;
public function filter($chain)
{
if($chain->controller->externalFilter<=1)
{
$chain->controller->externalFilter++;
$chain->run();
}
}
}
class TestAction extends CAction
{
public function run()
{
$this->controller->external++;
}
}
class CControllerTest extends CTestCase
{
public function testDefaultProperties()
{
$app=new TestApplication;
$_SERVER['REQUEST_METHOD']='GET';
$c=new CController('test/subtest');
$this->assertEquals($c->id,'test/subtest');
$this->assertEquals($c->filters(),array());
$this->assertEquals($c->actions(),array());
$this->assertNull($c->action);
$this->assertEquals($c->defaultAction,'index');
$this->assertEquals($c->viewPath,$app->viewPath.'/test/subtest');
$this->setExpectedException('CHttpException');
$c->missingAction('index');
}
public function testRunAction()
{
$app=new TestApplication;
$c=new TestController('test');
$this->assertEquals($c->internal,0);
$this->assertEquals($c->external,0);
$this->assertEquals($c->internalFilter1,0);
$this->assertEquals($c->internalFilter2,0);
$this->assertEquals($c->internalFilter3,0);
$this->assertEquals($c->externalFilter,0);
$c->run('');
$this->assertEquals($c->internal,0);
$this->assertEquals($c->external,1);
$this->assertEquals($c->internalFilter1,1);
$this->assertEquals($c->internalFilter2,0);
$this->assertEquals($c->internalFilter3,1);
$this->assertEquals($c->externalFilter,1);
$c->run('internal');
$this->assertEquals($c->internal,1);
$this->assertEquals($c->external,1);
$this->assertEquals($c->internalFilter1,2);
$this->assertEquals($c->internalFilter2,1);
$this->assertEquals($c->internalFilter3,1);
$this->assertEquals($c->externalFilter,2);
$c->run('external');
$this->assertEquals($c->internal,1);
$this->assertEquals($c->external,1);
$this->assertEquals($c->internalFilter1,3);
$this->assertEquals($c->internalFilter2,1);
$this->assertEquals($c->internalFilter3,1);
$this->assertEquals($c->externalFilter,2);
$this->setExpectedException('CException');
$c->run('unknown');
}
public function testActionParams()
{
$app=new TestApplication;
$c=new TestController('test');
$_GET['a']=1;
$_GET['b']='2';
$c->run('create');
$this->assertTrue($c->a===1);
$this->assertTrue($c->b==='2');
$this->assertTrue($c->c===3);
$this->assertTrue($c->d===4);
$_GET['a']=11;
$_GET['b']='22';
$_GET['d']='44';
$c->run('create');
$this->assertTrue($c->a===11);
$this->assertTrue($c->b==='22');
$this->assertTrue($c->c===3);
$this->assertTrue($c->d==='44');
}
public function testActionParamsInvalid()
{
$app=new TestApplication;
$c=new TestController('test');
$_GET=array('a'=>1);
$this->setExpectedException('CException');
$c->run('create');
}
}

View File

@@ -0,0 +1,84 @@
<?php
/**
* CSortTest
*/
Yii::import('system.db.CDbConnection');
Yii::import('system.db.ar.CActiveRecord');
class CSortTest extends CTestCase {
private $db;
public function setUp(){
if(!extension_loaded('pdo') || !extension_loaded('pdo_sqlite'))
$this->markTestSkipped('PDO and SQLite extensions are required.');
$this->db=new CDbConnection('sqlite::memory:');
$this->db->active=true;
$this->db->pdoInstance->exec(file_get_contents(dirname(__FILE__).'/CSortTest.sql'));
CActiveRecord::$db=$this->db;
}
public function tearDown(){
$this->db->active=false;
}
/**
* Tests for acceptance of fields with dots in
* CSort::attributes.
*
* @return void
*/
function testGetDirectionsWithDots(){
$_GET['sort'] = 'comments.id';
$criteria = new CDbCriteria();
$criteria->with = 'comments';
$sort = new CSort('Post');
$sort->attributes = array(
'id',
'comments.id' => array(
'asc'=>'comments.id',
'desc'=>'comments.id desc',
),
);
$sort->applyOrder($criteria);
$directions = $sort->getDirections();
$this->assertTrue(isset($directions['comments.id']));
}
}
class TestPost extends CActiveRecord {
public static function model($className=__CLASS__) {
return parent::model($className);
}
public function tableName() {
return 'post';
}
public function relations() {
return array(
'comments'=>array(self::HAS_MANY, 'TestComment', 'post_id'),
);
}
}
class TestComment extends CActiveRecord {
public static function model($className=__CLASS__) {
return parent::model($className);
}
public function tableName() {
return 'comment';
}
public function relations() {
return array(
'post'=>array(self::BELONGS_TO, 'TestPost', 'post_id'),
);
}
}

View File

@@ -0,0 +1,12 @@
CREATE TABLE comment (
id INTEGER PRIMARY KEY,
post_id INTEGER,
text text,
created_at INTEGER
);
CREATE TABLE post (
id INTEGER PRIMARY KEY,
created_at INTEGER,
title VARCHAR(255)
);

View File

@@ -0,0 +1,559 @@
<?php
Yii::import('system.web.CUrlManager');
Yii::import('system.web.CHttpRequest');
class TestHttpRequest extends CHttpRequest
{
private $myPathInfo;
private $myScriptUrl;
public function getScriptUrl()
{
return $this->myScriptUrl;
}
public function setScriptUrl($value)
{
$this->myScriptUrl=$value;
}
public function getPathInfo()
{
return $this->myPathInfo;
}
public function setPathInfo($value)
{
$this->myPathInfo=$value;
}
}
class CUrlManagerTest extends CTestCase
{
public function testParseUrlWithPathFormat()
{
$rules=array(
'article/<id:\d+>'=>'article/read',
'article/<year:\d{4}>/<title>/*'=>'article/read',
'a/<_a>/*'=>'article',
'register/*'=>'user',
'home/*'=>'',
'ad/*'=>'admin/index/list',
'<c:(post|comment)>/<id:\d+>/<a:(create|update|delete)>'=>'<c>/<a>',
'<c:(post|comment)>/<id:\d+>'=>'<c>/view',
'<c:(post|comment)>s/*'=>'<c>/list',
'http://<user:\w+>.example.com/<lang:\w+>/profile'=>'user/profile',
);
$entries=array(
array(
'pathInfo'=>'article/123',
'route'=>'article/read',
'params'=>array('id'=>'123'),
),
array(
'pathInfo'=>'article/123/name/value',
'route'=>'article/123/name/value',
'params'=>array(),
),
array(
'pathInfo'=>'article/2000/title goes here',
'route'=>'article/read',
'params'=>array('year'=>'2000','title'=>'title goes here'),
),
array(
'pathInfo'=>'article/2000/title goes here/name/value',
'route'=>'article/read',
'params'=>array('year'=>'2000','title'=>'title goes here','name'=>'value'),
),
array(
'pathInfo'=>'register/username/admin',
'route'=>'user',
'params'=>array('username'=>'admin'),
),
array(
'pathInfo'=>'home/name/value/name1/value1',
'route'=>'',
'params'=>array('name'=>'value','name1'=>'value1'),
),
array(
'pathInfo'=>'home2/name/value/name1/value1',
'route'=>'home2/name/value/name1/value1',
'params'=>array(),
),
array(
'pathInfo'=>'post',
'route'=>'post',
'params'=>array(),
),
array(
'pathInfo'=>'post/read',
'route'=>'post/read',
'params'=>array(),
),
array(
'pathInfo'=>'post/read/id/100',
'route'=>'post/read/id/100',
'params'=>array(),
),
array(
'pathInfo'=>'',
'route'=>'',
'params'=>array(),
),
array(
'pathInfo'=>'ad/name/value',
'route'=>'admin/index/list',
'params'=>array('name'=>'value'),
),
array(
'pathInfo'=>'admin/name/value',
'route'=>'admin/name/value',
'params'=>array(),
),
array(
'pathInfo'=>'posts',
'route'=>'post/list',
'params'=>array(),
),
array(
'pathInfo'=>'posts/page/3',
'route'=>'post/list',
'params'=>array('page'=>3),
),
array(
'pathInfo'=>'post/3',
'route'=>'post/view',
'params'=>array('id'=>3),
),
array(
'pathInfo'=>'post/3/delete',
'route'=>'post/delete',
'params'=>array('id'=>3),
),
array(
'pathInfo'=>'post/3/delete/a',
'route'=>'post/3/delete/a',
'params'=>array(),
),
array(
'pathInfo'=>'en/profile',
'route'=>'user/profile',
'params'=>array('user'=>'admin','lang'=>'en'),
),
);
$config=array(
'basePath'=>dirname(__FILE__),
'components'=>array(
'request'=>array(
'class'=>'TestHttpRequest',
'scriptUrl'=>'/app/index.php',
),
),
);
$app=new TestApplication($config);
$app->controllerPath=dirname(__FILE__).DIRECTORY_SEPARATOR.'controllers';
$request=$app->request;
$_SERVER['HTTP_HOST']='admin.example.com';
$um=new CUrlManager;
$um->urlSuffix='.html';
$um->urlFormat='path';
$um->rules=$rules;
$um->init($app);
foreach($entries as $entry)
{
$request->pathInfo=$entry['pathInfo'];
$_GET=array();
$route=$um->parseUrl($request);
$this->assertEquals($entry['route'],$route);
$this->assertEquals($entry['params'],$_GET);
// test the .html version
$request->pathInfo=$entry['pathInfo'].'.html';
$_GET=array();
$route=$um->parseUrl($request);
$this->assertEquals($entry['route'],$route);
$this->assertEquals($entry['params'],$_GET);
}
}
public function testcreateUrlWithPathFormat()
{
$rules=array(
'article/<id:\d+>'=>'article/read',
'article/<year:\d{4}>/<title>/*'=>'article/read',
'a/<_a>/*'=>'article',
'register/*'=>'user',
'home/*'=>'',
'<c:(post|comment)>/<id:\d+>/<a:(create|update|delete)>'=>'<c>/<a>',
'<c:(post|comment)>/<id:\d+>'=>'<c>/view',
'<c:(post|comment)>s/*'=>'<c>/list',
'http://<user:\w+>.example.com/<lang:\w+>/profile'=>'user/profile',
);
$config=array(
'basePath'=>dirname(__FILE__),
'components'=>array(
'request'=>array(
'class'=>'TestHttpRequest',
),
),
);
$_SERVER['HTTP_HOST']='user.example.com';
$app=new TestApplication($config);
$entries=array(
array(
'scriptUrl'=>'/apps/index.php',
'url'=>'/apps/index.php/post/123?name1=value1',
'url2'=>'/apps/post/123?name1=value1',
'url3'=>'/apps/post/123.html?name1=value1',
'route'=>'post/view',
'params'=>array(
'id'=>'123',
'name1'=>'value1',
),
),
array(
'scriptUrl'=>'/apps/index.php',
'url'=>'/apps/index.php/post/123/update?name1=value1',
'url2'=>'/apps/post/123/update?name1=value1',
'url3'=>'/apps/post/123/update.html?name1=value1',
'route'=>'post/update',
'params'=>array(
'id'=>'123',
'name1'=>'value1',
),
),
array(
'scriptUrl'=>'/apps/index.php',
'url'=>'/apps/index.php/posts/page/123',
'url2'=>'/apps/posts/page/123',
'url3'=>'/apps/posts/page/123.html',
'route'=>'post/list',
'params'=>array(
'page'=>'123',
),
),
array(
'scriptUrl'=>'/apps/index.php',
'url'=>'/apps/index.php/article/123?name1=value1',
'url2'=>'/apps/article/123?name1=value1',
'url3'=>'/apps/article/123.html?name1=value1',
'route'=>'article/read',
'params'=>array(
'id'=>'123',
'name1'=>'value1',
),
),
array(
'scriptUrl'=>'/index.php',
'url'=>'/index.php/article/123?name1=value1',
'url2'=>'/article/123?name1=value1',
'url3'=>'/article/123.html?name1=value1',
'route'=>'article/read',
'params'=>array(
'id'=>'123',
'name1'=>'value1',
),
),
array(
'scriptUrl'=>'/apps/index.php',
'url'=>'/apps/index.php/article/2000/the_title/name1/value1',
'url2'=>'/apps/article/2000/the_title/name1/value1',
'url3'=>'/apps/article/2000/the_title/name1/value1.html',
'route'=>'article/read',
'params'=>array(
'year'=>'2000',
'title'=>'the_title',
'name1'=>'value1',
),
),
array(
'scriptUrl'=>'/index.php',
'url'=>'/index.php/article/2000/the_title/name1/value1',
'url2'=>'/article/2000/the_title/name1/value1',
'url3'=>'/article/2000/the_title/name1/value1.html',
'route'=>'article/read',
'params'=>array(
'year'=>'2000',
'title'=>'the_title',
'name1'=>'value1',
),
),
array(
'scriptUrl'=>'/apps/index.php',
'url'=>'/apps/index.php/post/edit/id/123/name1/value1',
'url2'=>'/apps/post/edit/id/123/name1/value1',
'url3'=>'/apps/post/edit/id/123/name1/value1.html',
'route'=>'post/edit',
'params'=>array(
'id'=>'123',
'name1'=>'value1',
),
),
array(
'scriptUrl'=>'/index.php',
'url'=>'http://admin.example.com/en/profile',
'url2'=>'http://admin.example.com/en/profile',
'url3'=>'http://admin.example.com/en/profile.html',
'route'=>'user/profile',
'params'=>array(
'user'=>'admin',
'lang'=>'en',
),
),
array(
'scriptUrl'=>'/index.php',
'url'=>'/en/profile',
'url2'=>'/en/profile',
'url3'=>'/en/profile.html',
'route'=>'user/profile',
'params'=>array(
'user'=>'user',
'lang'=>'en',
),
),
);
foreach($entries as $entry)
{
$app->request->baseUrl=null; // reset so that it can be determined based on scriptUrl
$app->request->scriptUrl=$entry['scriptUrl'];
$um=new CUrlManager;
$um->urlFormat='path';
$um->rules=$rules;
$um->init($app);
$url=$um->createUrl($entry['route'],$entry['params']);
$this->assertEquals($entry['url'],$url);
$um=new CUrlManager;
$um->urlFormat='path';
$um->rules=$rules;
$um->init($app);
$um->showScriptName=false;
$url=$um->createUrl($entry['route'],$entry['params']);
$this->assertEquals($entry['url2'],$url);
$um->urlSuffix='.html';
$url=$um->createUrl($entry['route'],$entry['params']);
$this->assertEquals($entry['url3'],$url);
}
}
public function testParseUrlWithGetFormat()
{
$config=array(
'basePath'=>dirname(__FILE__),
'components'=>array(
'request'=>array(
'class'=>'TestHttpRequest',
'scriptUrl'=>'/app/index.php',
),
),
);
$entries=array(
array(
'route'=>'article/read',
'name'=>'value',
),
);
$app=new TestApplication($config);
$request=$app->request;
$um=new CUrlManager;
$um->urlFormat='get';
$um->routeVar='route';
$um->init($app);
foreach($entries as $entry)
{
$_GET=$entry;
$route=$um->parseUrl($request);
$this->assertEquals($entry['route'],$route);
$this->assertEquals($_GET,$entry);
}
}
public function testCreateUrlWithGetFormat()
{
$config=array(
'basePath'=>dirname(__FILE__),
'components'=>array(
'request'=>array(
'class'=>'TestHttpRequest',
),
),
);
$app=new TestApplication($config);
$entries=array(
array(
'scriptUrl'=>'/apps/index.php',
'url'=>'/apps/index.php?route=article/read&name=value&name1=value1',
'url2'=>'/apps/?route=article/read&name=value&name1=value1',
'route'=>'article/read',
'params'=>array(
'name'=>'value',
'name1'=>'value1',
),
),
array(
'scriptUrl'=>'/index.php',
'url'=>'/index.php?route=article/read&name=value&name1=value1',
'url2'=>'/?route=article/read&name=value&name1=value1',
'route'=>'article/read',
'params'=>array(
'name'=>'value',
'name1'=>'value1',
),
),
);
foreach($entries as $entry)
{
$app->request->baseUrl=null;
$app->request->scriptUrl=$entry['scriptUrl'];
$um=new CUrlManager;
$um->urlFormat='get';
$um->routeVar='route';
$um->init($app);
$url=$um->createUrl($entry['route'],$entry['params'],'&');
$this->assertEquals($url,$entry['url']);
$um=new CUrlManager;
$um->urlFormat='get';
$um->routeVar='route';
$um->showScriptName=false;
$um->init($app);
$url=$um->createUrl($entry['route'],$entry['params'],'&');
$this->assertEquals($url,$entry['url2']);
}
}
public function testDefaultParams()
{
$config=array(
'basePath'=>dirname(__FILE__),
'components'=>array(
'request'=>array(
'class'=>'TestHttpRequest',
),
),
);
$app=new TestApplication($config);
$app->request->baseUrl=null; // reset so that it can be determined based on scriptUrl
$app->request->scriptUrl='/apps/index.php';
$um=new CUrlManager;
$um->urlFormat='path';
$um->rules=array(
''=>array('site/page', 'defaultParams'=>array('view'=>'about')),
'posts'=>array('post/index', 'defaultParams'=>array('page'=>1)),
'<slug:[0-9a-z-]+>' => array('news/list', 'defaultParams' => array('page' => 1)),
);
$um->init($app);
$url=$um->createUrl('site/page',array('view'=>'about'));
$this->assertEquals('/apps/index.php/',$url);
$app->request->pathInfo='';
$_GET=array();
$route=$um->parseUrl($app->request);
$this->assertEquals('site/page',$route);
$this->assertEquals(array('view'=>'about'),$_GET);
$url=$um->createUrl('post/index',array('page'=>1));
$this->assertEquals('/apps/index.php/posts',$url);
$app->request->pathInfo='posts';
$_GET=array();
$route=$um->parseUrl($app->request);
$this->assertEquals('post/index',$route);
$this->assertEquals(array('page'=>'1'),$_GET);
$url=$um->createUrl('news/list', array('slug' => 'example', 'page' => 1));
$this->assertEquals('/apps/index.php/example',$url);
$app->request->pathInfo='example';
$_GET=array();
$route=$um->parseUrl($app->request);
$this->assertEquals('news/list',$route);
$this->assertEquals(array('slug'=>'example', 'page'=>'1'),$_GET);
}
public function testVerb()
{
$config=array(
'basePath'=>dirname(__FILE__),
'components'=>array(
'request'=>array(
'class'=>'TestHttpRequest',
),
),
);
$rules=array(
'article/<id:\d+>'=>array('article/read', 'verb'=>'GET'),
'article/update/<id:\d+>'=>array('article/update', 'verb'=>'POST'),
'article/update/*'=>'article/admin',
);
$entries=array(
array(
'scriptUrl'=>'/apps/index.php',
'url'=>'article/123',
'verb'=>'GET',
'route'=>'article/read',
),
array(
'scriptUrl'=>'/apps/index.php',
'url'=>'article/update/123',
'verb'=>'POST',
'route'=>'article/update',
),
array(
'scriptUrl'=>'/apps/index.php',
'url'=>'article/update/123',
'verb'=>'GET',
'route'=>'article/admin',
),
);
foreach($entries as $entry)
{
$_SERVER['REQUEST_METHOD']=$entry['verb'];
$app=new TestApplication($config);
$app->request->baseUrl=null; // reset so that it can be determined based on scriptUrl
$app->request->scriptUrl=$entry['scriptUrl'];
$app->request->pathInfo=$entry['url'];
$um=new CUrlManager;
$um->urlFormat='path';
$um->rules=$rules;
$um->init($app);
$route=$um->parseUrl($app->request);
$this->assertEquals($entry['route'],$route);
}
}
public function testParsingOnly()
{
$config=array(
'basePath'=>dirname(__FILE__),
'components'=>array(
'request'=>array(
'class'=>'TestHttpRequest',
),
),
);
$rules=array(
'(articles|article)/<id:\d+>'=>array('article/read', 'parsingOnly'=>true),
'article/<id:\d+>'=>array('article/read', 'verb'=>'GET'),
);
$_SERVER['REQUEST_METHOD']='GET';
$app=new TestApplication($config);
$app->request->baseUrl=null; // reset so that it can be determined based on scriptUrl
$app->request->scriptUrl='/apps/index.php';
$app->request->pathInfo='articles/123';
$um=new CUrlManager;
$um->urlFormat='path';
$um->rules=$rules;
$um->init($app);
$route=$um->parseUrl($app->request);
$this->assertEquals('article/read',$route);
$url=$um->createUrl('article/read', array('id'=>345));
$this->assertEquals('/apps/index.php/article/345',$url);
}
}

View File

@@ -0,0 +1,243 @@
<?php
abstract class AuthManagerTestBase extends CTestCase
{
protected $auth;
public function testcreateAuthItem()
{
$type=CAuthItem::TYPE_TASK;
$name='editUser';
$description='edit a user';
$bizRule='checkUserIdentity()';
$data=array(1,2,3);
$item=$this->auth->createAuthItem($name,$type,$description,$bizRule,$data);
$this->assertTrue($item instanceof CAuthItem);
$this->assertEquals($item->type,$type);
$this->assertEquals($item->name,$name);
$this->assertEquals($item->description,$description);
$this->assertEquals($item->bizRule,$bizRule);
$this->assertEquals($item->data,$data);
// test shortcut
$name2='createUser';
$item2=$this->auth->createRole($name2,$description,$bizRule,$data);
$this->assertEquals($item2->type,CAuthItem::TYPE_ROLE);
// test adding an item with the same name
$this->setExpectedException('CException');
$this->auth->createAuthItem($name,$type,$description,$bizRule,$data);
}
public function testGetAuthItem()
{
$this->assertTrue($this->auth->getAuthItem('readPost') instanceof CAuthItem);
$this->assertTrue($this->auth->getAuthItem('reader') instanceof CAuthItem);
$this->assertNull($this->auth->getAuthItem('unknown'));
}
public function testRemoveAuthItem()
{
$this->assertTrue($this->auth->getAuthItem('updatePost') instanceof CAuthItem);
$this->assertTrue($this->auth->removeAuthItem('updatePost'));
$this->assertNull($this->auth->getAuthItem('updatePost'));
$this->assertFalse($this->auth->removeAuthItem('updatePost'));
}
public function testChangeItemName()
{
$item=$this->auth->getAuthItem('readPost');
$this->assertTrue($item instanceof CAuthItem);
$this->assertTrue($this->auth->hasItemChild('reader','readPost'));
$item->name='readPost2';
$this->assertNull($this->auth->getAuthItem('readPost'));
$this->assertEquals($this->auth->getAuthItem('readPost2'),$item);
$this->assertFalse($this->auth->hasItemChild('reader','readPost'));
$this->assertTrue($this->auth->hasItemChild('reader','readPost2'));
}
public function testAddItemChild()
{
$this->auth->addItemChild('createPost','updatePost');
// test adding upper level item to lower one
$this->setExpectedException('CException');
$this->auth->addItemChild('readPost','reader');
}
public function testAddItemChild2()
{
// test adding inexistent items
$this->setExpectedException('CException');
$this->assertFalse($this->auth->addItemChild('createPost2','updatePost'));
}
public function testRemoveItemChild()
{
$this->assertTrue($this->auth->hasItemChild('reader','readPost'));
$this->assertTrue($this->auth->removeItemChild('reader','readPost'));
$this->assertFalse($this->auth->hasItemChild('reader','readPost'));
$this->assertFalse($this->auth->removeItemChild('reader','readPost'));
}
public function testGetItemChildren()
{
$this->assertEquals(array(),$this->auth->getItemChildren('readPost'));
$children=$this->auth->getItemChildren('author');
$this->assertEquals(3,count($children));
$this->assertTrue(reset($children) instanceof CAuthItem);
}
public function testAssign()
{
$auth=$this->auth->assign('createPost','new user','rule','data');
$this->assertTrue($auth instanceof CAuthAssignment);
$this->assertEquals($auth->userId,'new user');
$this->assertEquals($auth->itemName,'createPost');
$this->assertEquals($auth->bizRule,'rule');
$this->assertEquals($auth->data,'data');
$this->setExpectedException('CException');
$this->auth->assign('createPost2','new user','rule','data');
}
public function testRevoke()
{
$this->assertTrue($this->auth->isAssigned('author','author B'));
$auth=$this->auth->getAuthAssignment('author','author B');
$this->assertTrue($auth instanceof CAuthAssignment);
$this->assertTrue($this->auth->revoke('author','author B'));
$this->assertFalse($this->auth->isAssigned('author','author B'));
$this->assertFalse($this->auth->revoke('author','author B'));
}
public function testGetAuthAssignments()
{
$this->auth->assign('deletePost','author B');
$auths=$this->auth->getAuthAssignments('author B');
$this->assertEquals(2,count($auths));
$this->assertTrue(reset($auths) instanceof CAuthAssignment);
}
public function testGetAuthItems()
{
$this->assertEquals(count($this->auth->getRoles()),4);
$this->assertEquals(count($this->auth->getOperations()),4);
$this->assertEquals(count($this->auth->getTasks()),1);
$this->assertEquals(count($this->auth->getAuthItems()),9);
$this->assertEquals(count($this->auth->getAuthItems(null,'author B')),1);
$this->assertEquals(count($this->auth->getAuthItems(null,'author C')),0);
$this->assertEquals(count($this->auth->getAuthItems(CAuthItem::TYPE_ROLE,'author B')),1);
$this->assertEquals(count($this->auth->getAuthItems(CAuthItem::TYPE_OPERATION,'author B')),0);
}
public function testClearAll()
{
$this->auth->clearAll();
$this->assertEquals(count($this->auth->getRoles()),0);
$this->assertEquals(count($this->auth->getOperations()),0);
$this->assertEquals(count($this->auth->getTasks()),0);
$this->assertEquals(count($this->auth->getAuthItems()),0);
$this->assertEquals(count($this->auth->getAuthAssignments('author B')),0);
}
public function testClearAuthAssignments()
{
$this->auth->clearAuthAssignments();
$this->assertEquals(count($this->auth->getAuthAssignments('author B')),0);
}
public function testDetectLoop()
{
$this->setExpectedException('CException');
$this->auth->addItemChild('readPost','readPost');
}
public function testExecuteBizRule()
{
$this->assertTrue($this->auth->executeBizRule(null,array(),null));
$this->assertTrue($this->auth->executeBizRule('return 1==true;',array(),null));
$this->assertTrue($this->auth->executeBizRule('return $params[0]==$params[1];',array(1,'1'),null));
$this->assertFalse($this->auth->executeBizRule('invalid',array(),null));
}
public function testCheckAccess()
{
$results=array(
'reader A'=>array(
'createPost'=>false,
'readPost'=>true,
'updatePost'=>false,
'updateOwnPost'=>false,
'deletePost'=>false,
),
'author B'=>array(
'createPost'=>true,
'readPost'=>true,
'updatePost'=>true,
'updateOwnPost'=>true,
'deletePost'=>false,
),
'editor C'=>array(
'createPost'=>false,
'readPost'=>true,
'updatePost'=>true,
'updateOwnPost'=>false,
'deletePost'=>false,
),
'admin D'=>array(
'createPost'=>true,
'readPost'=>true,
'updatePost'=>true,
'updateOwnPost'=>false,
'deletePost'=>true,
),
);
$params=array('authorID'=>'author B');
foreach(array('reader A','author B','editor C','admin D') as $user)
{
$params['userID']=$user;
foreach(array('createPost','readPost','updatePost','updateOwnPost','deletePost') as $operation)
{
$result=$this->auth->checkAccess($operation,$user,$params);
$this->assertEquals($results[$user][$operation],$result);
}
}
}
protected function prepareData()
{
$this->auth->createOperation('createPost','create a post');
$this->auth->createOperation('readPost','read a post');
$this->auth->createOperation('updatePost','update a post');
$this->auth->createOperation('deletePost','delete a post');
$task=$this->auth->createTask('updateOwnPost','update a post by author himself','return $params["authorID"]==$params["userID"];');
$task->addChild('updatePost');
$role=$this->auth->createRole('reader');
$role->addChild('readPost');
$role=$this->auth->createRole('author');
$role->addChild('reader');
$role->addChild('createPost');
$role->addChild('updateOwnPost');
$role=$this->auth->createRole('editor');
$role->addChild('reader');
$role->addChild('updatePost');
$role=$this->auth->createRole('admin');
$role->addChild('editor');
$role->addChild('author');
$role->addChild('deletePost');
$this->auth->assign('reader','reader A');
$this->auth->assign('author','author B');
$this->auth->assign('editor','editor C');
$this->auth->assign('admin','admin D');
}
}

View File

@@ -0,0 +1,45 @@
<?php
require_once(dirname(__FILE__).'/AuthManagerTestBase.php');
class CDbAuthManagerTest extends AuthManagerTestBase
{
private $db;
public function setUp()
{
if(!extension_loaded('pdo') || !extension_loaded('pdo_pgsql'))
$this->markTestSkipped('PDO and PostgreSQL extensions are required.');
$schemaFile=realpath(dirname(__FILE__).'/schema.sql');
$this->db=new CDbConnection('pgsql:host=localhost;dbname=yii','test','test');
try
{
$this->db->active=true;
}
catch(Exception $e)
{
$this->markTestSkipped("Please read $schemaFile for details on setting up the test environment for PostgreSQL test case.");
}
$sqls=file_get_contents($schemaFile);
foreach(explode(';',$sqls) as $sql)
{
if(trim($sql)!=='')
$this->db->createCommand($sql)->execute();
}
$this->db->active=false;
$this->auth=new CDbAuthManager;
$this->auth->db=$this->db;
$this->auth->init();
$this->prepareData();
}
public function tearDown()
{
if($this->db)
$this->db->active=false;
}
}

View File

@@ -0,0 +1,29 @@
<?php
require_once(dirname(__FILE__).'/AuthManagerTestBase.php');
class CPhpAuthManagerTest extends AuthManagerTestBase
{
public function setUp()
{
$authFile=dirname(__FILE__).'/data/auth.php';
@unlink($authFile);
$this->auth=new CPhpAuthManager;
$this->auth->authFile=$authFile;
$this->auth->init();
$this->prepareData();
}
public function tearDown()
{
@unlink($this->auth->authFile);
}
public function testSaveLoad()
{
$this->auth->save();
$this->auth->clearAll();
$this->auth->load();
$this->testCheckAccess();
}
}

View File

@@ -0,0 +1,32 @@
drop table if exists authassignment cascade;
drop table if exists authitemchild cascade;
drop table if exists authitem cascade;
create table authitem
(
name varchar(64) not null,
type integer not null,
description text,
bizrule text,
data text,
primary key (name)
);
create table authitemchild
(
parent varchar(64) not null,
child varchar(64) not null,
primary key (parent,child),
foreign key (parent) references authitem (name) on delete cascade on update cascade,
foreign key (child) references authitem (name) on delete cascade on update cascade
);
create table authassignment
(
itemname varchar(64) not null,
userid varchar(64) not null,
bizrule text,
data text,
primary key (itemname,userid),
foreign key (itemname) references authitem (name) on delete cascade on update cascade
);

View File

View File

@@ -0,0 +1,79 @@
<?php
Yii::import('system.db.CDbConnection');
Yii::import('system.db.ar.CActiveRecord');
require_once(dirname(__FILE__).'/../../db/data/models.php');
/**
* CJSON Test
*/
class CJSONTest extends CTestCase {
private $db;
protected function setUp()
{
if(!extension_loaded('pdo') || !extension_loaded('pdo_sqlite'))
$this->markTestSkipped('PDO and SQLite extensions are required.');
$this->db=new CDbConnection('sqlite::memory:');
$this->db->active=true;
$this->db->pdoInstance->exec(file_get_contents(dirname(__FILE__).'/../../db/data/sqlite.sql'));
CActiveRecord::$db=$this->db;
}
protected function tearDown()
{
$this->db->active=false;
}
/**
* native json_encode can't do it
* @return void
*/
public function testEncodeSingleAR(){
$post = Post::model()->findByPk(1);
$this->assertEquals(
'{"id":"1","title":"post 1","create_time":"100000","author_id":"1","content":"content 1"}',
CJSON::encode($post)
);
}
/**
* native json_encode can't do it
* @return void
*/
public function testEncodeMultipleARs(){
$posts=Post::model()->findAllByPk(array(1, 2));
$this->assertEquals(
'[{"id":"1","title":"post 1","create_time":"100000","author_id":"1","content":"content 1"},{"id":"2","title":"post 2","create_time":"100001","author_id":"2","content":"content 2"}]',
CJSON::encode($posts)
);
}
public function testEncodeSimple(){
$this->assertEquals("true", CJSON::encode(true));
$this->assertEquals("false", CJSON::encode(false));
$this->assertEquals("null", CJSON::encode(null));
$this->assertEquals("123", CJSON::encode(123));
$this->assertEquals("123.12", CJSON::encode(123.12));
$this->assertEquals('"test\\\\me"', CJSON::encode('test\me'));
}
public function testEncodeArray(){
$objArr = array('a' => 'b');
$arrArr = array('a', 'b');
$mixedArr = array('c', 'a' => 'b');
$nestedArr = array('a', 'b' => array('a', 'b' => 'c'));
$this->assertEquals('{"a":"b"}', CJSON::encode($objArr));
$this->assertEquals('["a","b"]', CJSON::encode($arrArr));
$this->assertEquals('{"0":"c","a":"b"}', CJSON::encode($mixedArr));
$this->assertEquals('{"0":"a","b":{"0":"a","b":"c"}}', CJSON::encode($nestedArr));
}
public function testDecode(){
$this->assertEquals(array('c', 'a' => 'b'), CJSON::decode('{"0":"c","a":"b"}'));
$this->assertEquals(array('a', 'b'), CJSON::decode('["a","b"]'));
$this->assertEquals(array('a', 'b' => array('a', 'b' => 'c')), CJSON::decode('{"0":"a","b":{"0":"a","b":"c"}}'));
}
}

7
tests/phpunit.xml Normal file
View File

@@ -0,0 +1,7 @@
<phpunit bootstrap="bootstrap.php"
colors="false"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
stopOnFailure="false">
</phpunit>

13
tests/readme.txt Normal file
View File

@@ -0,0 +1,13 @@
This folder contains unit tests of Yii framework.
PHPUnit 3.3+ and xdebug (for code coverage report) are required.
To run a single unit test, use:
>> phpunit path/to/test.php
To run all tests under a directory, use:
>> phpunit --verbose path/to/tests/directory
To generate code coverage report:
>> phpunit --coverage-html reports path/to/tests/directory/or/test/class
Please use 'phpunit --help' to see more command line options.

1
tests/rununit.bat Normal file
View File

@@ -0,0 +1 @@
phpunit --verbose framework