code:
<?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 scopes
		$criteria1=new CDbCriteria;
		$criteria1->scopes='scope1';

		$criteria2=new CDbCriteria;
		$criteria2->scopes='scope2';

		$criteria1->mergeWith($criteria2);

		$this->assertEquals(array('scope1','scope2'),$criteria1->scopes);

		$criteria1=new CDbCriteria;
		$criteria1->scopes='scope1';

		$criteria2=new CDbCriteria;
		$criteria2->scopes=array('scope2'=>1);

		$criteria1->mergeWith($criteria2);

		$this->assertEquals(array('scope1','scope2'=>1),$criteria1->scopes);

		$criteria1=new CDbCriteria;
		$criteria1->scopes=array('scope1'=>array(1,2));

		$criteria2=new CDbCriteria;
		$criteria2->scopes=array('scope2'=>array(3,4));

		$criteria1->mergeWith($criteria2);

		$this->assertEquals(array('scope1'=>array(1,2),'scope2'=>array(3,4)),$criteria1->scopes);

		$criteria1=new CDbCriteria;
		$criteria1->scopes=array('scope'=>array(1,2));

		$criteria2=new CDbCriteria;
		$criteria2->scopes=array('scope'=>array(3,4));

		$criteria1->mergeWith($criteria2);

		$this->assertEquals(array(array('scope'=>array(1,2)),array('scope'=>array(3,4))),$criteria1->scopes);

		$criteria1=new CDbCriteria;
		$criteria1->scopes=array('scope'=>array(1,2),'scope1');

		$criteria2=new CDbCriteria;
		$criteria2->scopes=array('scope2','scope'=>array(3,4));

		$criteria1->mergeWith($criteria2);

		$this->assertEquals(array(array('scope'=>array(1,2)),'scope1','scope2',array('scope'=>array(3,4))),$criteria1->scopes);

		$criteria1=new CDbCriteria;
		$criteria1->scopes=array(array('scope'=>array(1,2)),array('scope'=>array(3,4)));

		$criteria2=new CDbCriteria;
		$criteria2->scopes=array(array('scope'=>array(5,6)),array('scope'=>array(7,8)));

		$criteria1->mergeWith($criteria2);

		$this->assertEquals(array(array('scope'=>array(1,2)),array('scope'=>array(3,4)),array('scope'=>array(5,6)),array('scope'=>array(7,8))),$criteria1->scopes);

		// 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', 'scopes', 'with', 'alias', 'index', 'together');
		$criteria = new CDbCriteria();
		$this->assertEquals($keys, array_keys($criteria->toArray()));
	}
}


code:
<?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);

	}
}

repo_name: DaSourcerer/yii

license: mit


code:
<?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.");
		}

		$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 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);
	}
}


code:
<?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'=>-1),new CDbCriteria(array('condition'=>'id=5')));
		$this->assertEquals('UPDATE `posts` SET `author_id`=`author_id`-1 WHERE id=5',$c->text);
		$c->execute();
		$c=$builder->createSqlCommand('SELECT author_id FROM posts WHERE id=5');
		$this->assertEquals(2,$c->queryScalar());

		// test for updates with joins
		$c=$builder->createUpdateCommand($table,array('title'=>'new post 1'),new CDbCriteria(array(
				'condition'=>'u.`username`=:username',
				'join'=>'JOIN `users` u ON `author_id`=u.`id`',
				'params'=>array(':username'=>'user1'))));
		$c->execute();
		$c=$builder->createFindCommand($table,new CDbCriteria(array(
				'select'=>'title',
				'condition'=>'id=:id',
				'params'=>array('id'=>1))));
		$this->assertEquals('new post 1',$c->queryScalar());

		$c=$builder->createUpdateCounterCommand($table,array('author_id'=>-1),new CDbCriteria(array(
				'condition'=>'u.`username`="user2"',
				'join'=>'JOIN `users` u ON `author_id`=u.`id`')));
		$this->assertEquals('UPDATE `posts` JOIN `users` u ON `author_id`=u.`id` SET `author_id`=`author_id`-1 WHERE u.`username`="user2"',$c->text);
		$c->execute();
		$c=$builder->createSqlCommand('SELECT author_id FROM posts WHERE id=2');
		$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);
	}
}


code:
<?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);
	}
}


code:
<?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');
	}
}


code:
<?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);
	}
}


code:
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
);


code:
<?php
/**
 * CDateFormatterTest
 */
class CDateFormatterTest extends CTestCase
{
	public function testWeekInMonth()
	{
		for($year=1970; $year<=date('Y'); $year++)
		{
			for($month=1;$month<=12;$month++) {
				$day=date('t',mktime(0,0,0,$month,1,$year));
				$weekNum=Yii::app()->dateFormatter->format("W",mktime(0,0,0,$month,$day,$year));
				//echo sprintf("%d/%d/%d\t%d\n",$year,$month,$day,$weekNum);
			}
		}

		//echo "Week number for 2011/01/01 is ".Yii::app()->dateFormatter->format("W",mktime(0,0,0,1,1,2011));
		//echo "Week number for 2011/01/07 is ".Yii::app()->dateFormatter->format("W",mktime(0,0,0,1,7,2011));
	}
}


code:
<?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");
			}
		}
	}
}


code:
<?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]));
		}
	}
}


code:
<?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);
	}

	function tearDown()
	{
		Yii::app()->sourceLanguage = 'en_us';
	}

	// 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(){

	}
}


code:
<?php
return array(
	'cucumber|cucumbers' => 'cucumber|cucumbers',
);


code:
<?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#много книг',
);


code:
<?php
return array(
	'kiss|kisses' => 'k-s',
);


code:
<?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)))
		);
	}
}


code:
<?php

require_once 'ModelMock.php';

/**
 * CBooleanValidatorTest
 *
 * @author   Kevin Bradwick <kbradwick@gmail.com>
 */
class CBooleanValidatorTest extends CTestCase
{
    /**
     * Test we can catch validation errors using custom false/true values
     *
     * @return null
     */
    public function testValidationUsingCustomFalseTrueValues()
    {
        $model = $this->getModelMock(array('falseValue' => 'false', 'trueValue' => 'true'));
        $model->foo = 'blah';
        $this->assertFalse($model->hasErrors('foo'));

        $model->foo = 'false';
        $this->assertTrue($model->validate());

        // client script
        $validator = new CBooleanValidator;
        $validator->trueValue = 'foo';
        $validator->falseValue = 'bar';
        $script = $validator->clientValidateAttribute($model, 'foo');
        $this->assertContains('Foo must be either foo or bar', $script);
    }

    /**
     * Test allow empty
     *
     * @return null
     */
    public function testValidateAndAllowEmpty()
    {
        $model = $this->getModelMock(array('allowEmpty' => false));
        $this->assertFalse($model->validate());
        $this->assertTrue($model->hasErrors('foo'));

        $model = $this->getModelMock(array('allowEmpty' => true));
        $this->assertTrue($model->validate());
    }

    /**
     * Test using strict
     *
     * @return null
     */
    public function testValidationUsingStrict()
    {
        $model = $this->getModelMock(array('strict' => true));
        $model->foo = 1;
        $this->assertFalse($model->validate());
        $this->assertTrue($model->hasErrors('foo'));

        $model->foo = '1';
        $this->assertTrue($model->hasErrors('foo'));
    }

    /**
     * Mocks up an object to test with
     *
     * @param array $params additional parameters sent to rules
     *
     * @return null
     */
    protected function getModelMock($params=array())
    {
        $rules = array(
            array('foo', 'boolean')
        );

        foreach ($params as $rule => $value) {
            $rules[0][$rule] = $value;
        }

        $stub = $this->getMock('ModelMock', array('rules'));
        $stub->expects($this->any())
             ->method('rules')
             ->will($this->returnValue($rules));

        return $stub;
    }
}


code:
<?php

require_once 'ModelMock.php';

/**
 * CCompareValidatorTest
 *
 * @author   Kevin Bradwick <kbradwick@gmail.com>
 */
class CCompareValidatorTest extends CTestCase
{
    /**
     * Test we can catch validation errors
     *
     * @return null
     */
    public function testValidationErrorsWithEquals()
    {
        $model = $this->getModelMock(array('compareAttribute' => 'bar'));
        $model->foo = 'foo';
        $model->bar = 'bar';

        $this->assertFalse($model->validate());
        $this->assertTrue($model->hasErrors('foo'));
        $model->bar = 'foo';
        $this->assertTrue($model->validate());

        // client validation
        $validator = new CCompareValidator;
        $validator->operator = '=';
        $validator->compareAttribute = 'bar';
        $script = $validator->clientValidateAttribute($model, 'foo');
        $this->assertInternalType('string', $script);
        $this->assertContains('Foo must be repeated exactly.', $script);
    }

    /**
     * Test we can catch validation errors
     *
     * @return null
     */
    public function testValidationErrorsWithNotEquals()
    {
        $model = $this->getModelMock(array(
            'operator' => '!=',
            'strict' => true,
            'compareAttribute' => 'bar',
        ));
        $model->foo = 'foo';
        $model->bar = 'bar';

        $this->assertTrue($model->validate());

        $model->bar = 'foo';
        $this->assertFalse($model->validate());
        $this->assertTrue($model->hasErrors('foo'));

        // client validation
        $validator = new CCompareValidator;
        $validator->operator = '!=';
        $validator->compareAttribute = 'bar';
        $script = $validator->clientValidateAttribute($model, 'foo');
        $this->assertInternalType('string', $script);
        $this->assertContains('Foo must not be equal to \"Bar\".', $script);
    }

    /**
     * Test we can catch validation errors
     *
     * @return null
     */
    public function testValidationErrorsWitGreaterThan()
    {
        $model = $this->getModelMock(array(
            'operator' => '>',
            'strict' => true,
            'compareAttribute' => 'bar',
        ));
        $model->foo = 1;
        $model->bar = 2;

        $this->assertFalse($model->validate());
        $this->assertTrue($model->hasErrors('foo'));
        $model->bar = 0;
        $this->assertTrue($model->validate());

        // client validation
        $validator = new CCompareValidator;
        $validator->operator = '>';
        $validator->compareAttribute = 'bar';
        $script = $validator->clientValidateAttribute($model, 'foo');
        $this->assertInternalType('string', $script);
        $this->assertContains('Foo must be greater than \"Bar\"', $script);
    }

    /**
     * Test we can catch validation errors
     *
     * @return null
     */
    public function testValidationErrorsWitGreaterThanOrEqual()
    {
        $model = $this->getModelMock(array(
            'operator' => '>=',
            'strict' => true,
            'compareAttribute' => 'bar',
        ));
        $model->foo = 1;
        $model->bar = 2;

        $this->assertFalse($model->validate());
        $this->assertTrue($model->hasErrors('foo'));
        $model->bar = 1;
        $this->assertTrue($model->validate());

        // client validation
        $validator = new CCompareValidator;
        $validator->operator = '>=';
        $validator->compareAttribute = 'bar';
        $script = $validator->clientValidateAttribute($model, 'foo');
        $this->assertInternalType('string', $script);
        $this->assertContains('Foo must be greater than or equal to \"Bar\"', $script);
    }

    /**
     * Test we can catch validation errors
     *
     * @return null
     */
    public function testValidationErrorsWitLessThan()
    {
        $model = $this->getModelMock(array(
            'operator' => '<',
            'strict' => true,
            'compareAttribute' => 'bar',
        ));
        $model->foo = 3;
        $model->bar = 2;

        $this->assertFalse($model->validate());
        $this->assertTrue($model->hasErrors('foo'));
        $model->bar = 4;
        $this->assertTrue($model->validate());

        // client validation
        $validator = new CCompareValidator;
        $validator->operator = '<';
        $validator->compareAttribute = 'bar';
        $script = $validator->clientValidateAttribute($model, 'foo');
        $this->assertInternalType('string', $script);
        $this->assertContains('Foo must be less than \"Bar\"', $script);
    }

    /**
     * Test we can catch validation errors
     *
     * @return null
     */
    public function testValidationErrorsWitLessThanOrEqual()
    {
        $model = $this->getModelMock(array(
            'operator' => '<=',
            'strict' => true,
            'compareAttribute' => 'bar',
        ));
        $model->foo = 3;
        $model->bar = 2;

        $this->assertFalse($model->validate());
        $this->assertTrue($model->hasErrors('foo'));
        $model->bar = 3;
        $this->assertTrue($model->validate());

        // client validation
        $validator = new CCompareValidator;
        $validator->operator = '<=';
        $validator->compareAttribute = 'bar';
        $script = $validator->clientValidateAttribute($model, 'foo');
        $this->assertInternalType('string', $script);
        $this->assertContains('Foo must be less than or equal to \"Bar\"', $script);
    }

    /**
     * @expectedException CException
     */
    public function testClientValidateAttributeThrowsExcpetion()
    {
        $model = $this->getModelMock(array(
            'operator' => '<=',
            'strict' => true,
            'compareAttribute' => 'bar',
        ));
        $validator = new CCompareValidator;
        $validator->operator = '}';
        $validator->clientValidateAttribute($model, 'foo');
    }

    /**
     * @expectedException CException
     */
    public function testValidateThrowsExcpetionforBadOperator()
    {
        $model = $this->getModelMock(array(
            'operator' => ']]',
            'strict' => true,
            'compareAttribute' => 'bar',
        ));
        $model->validate();
    }

    /**
     * Test overriding value by setting compareValue
     *
     * @return null
     */
    public function testOverrideCompareValue()
    {
        $rules = array(
            array('foo', 'compare', 'compareValue' => 'hello')
        );

        $stub = $this->getMock('ModelMock', array('rules'));
        $stub->expects($this->any())
             ->method('rules')
             ->will($this->returnValue($rules));

        $stub->foo = 'foo';
        $this->assertFalse($stub->validate());

        // client validation
        $validator = new CCompareValidator;
        $validator->operator = '=';
        $validator->compareValue = 'bar';
        $script = $validator->clientValidateAttribute($stub, 'foo');
        $this->assertInternalType('string', $script);
        $this->assertContains('Foo must be repeated exactly', $script);
    }

    /**
     * Mocks up an object to test with
     *
     * @param array $operator optional parameters to configure rule
     *
     * @return null
     */
    protected function getModelMock($params=array())
    {
        $rules = array(
            array('foo', 'compare')
        );

        foreach ($params as $rule => $value) {
            $rules[0][$rule] = $value;
        }

        $stub = $this->getMock('ModelMock', array('rules'));
        $stub->expects($this->any())
             ->method('rules')
             ->will($this->returnValue($rules));

        return $stub;
    }
}