Qiang Xue
11 years ago
13 changed files with 706 additions and 248 deletions
@ -0,0 +1,27 @@
|
||||
<?php |
||||
/** |
||||
* @link http://www.yiiframework.com/ |
||||
* @copyright Copyright (c) 2008 Yii Software LLC |
||||
* @license http://www.yiiframework.com/license/ |
||||
*/ |
||||
|
||||
namespace yii\codeception; |
||||
|
||||
use yii\test\InitDbFixture; |
||||
|
||||
/** |
||||
* @author Qiang Xue <qiang.xue@gmail.com> |
||||
* @since 2.0 |
||||
*/ |
||||
class DbTestCase extends TestCase |
||||
{ |
||||
/** |
||||
* @inheritdoc |
||||
*/ |
||||
protected function globalFixtures() |
||||
{ |
||||
return [ |
||||
InitDbFixture::className(), |
||||
]; |
||||
} |
||||
} |
@ -0,0 +1,80 @@
|
||||
<?php |
||||
/** |
||||
* @link http://www.yiiframework.com/ |
||||
* @copyright Copyright (c) 2008 Yii Software LLC |
||||
* @license http://www.yiiframework.com/license/ |
||||
*/ |
||||
|
||||
namespace yii\base; |
||||
|
||||
/** |
||||
* ArrayAccessTrait provides the implementation for `IteratorAggregate`, `ArrayAccess` and `Countable`. |
||||
* |
||||
* Note that ArrayAccessTrait requires the class using it contain a property named `data` which should be an array. |
||||
* The data will be exposed by ArrayAccessTrait to support accessing the class object like an array. |
||||
* |
||||
* @author Qiang Xue <qiang.xue@gmail.com> |
||||
* @since 2.0 |
||||
*/ |
||||
trait ArrayAccessTrait |
||||
{ |
||||
/** |
||||
* Returns an iterator for traversing the data. |
||||
* This method is required by the SPL interface `IteratorAggregate`. |
||||
* It will be implicitly called when you use `foreach` to traverse the collection. |
||||
* @return \ArrayIterator an iterator for traversing the cookies in the collection. |
||||
*/ |
||||
public function getIterator() |
||||
{ |
||||
return new \ArrayIterator($this->data); |
||||
} |
||||
|
||||
/** |
||||
* Returns the number of data items. |
||||
* This method is required by Countable interface. |
||||
* @return integer number of data elements. |
||||
*/ |
||||
public function count() |
||||
{ |
||||
return count($this->data); |
||||
} |
||||
|
||||
/** |
||||
* This method is required by the interface ArrayAccess. |
||||
* @param mixed $offset the offset to check on |
||||
* @return boolean |
||||
*/ |
||||
public function offsetExists($offset) |
||||
{ |
||||
return isset($this->data[$offset]); |
||||
} |
||||
|
||||
/** |
||||
* This method is required by the interface ArrayAccess. |
||||
* @param integer $offset the offset to retrieve element. |
||||
* @return mixed the element at the offset, null if no element is found at the offset |
||||
*/ |
||||
public function offsetGet($offset) |
||||
{ |
||||
return isset($this->data[$offset]) ? $this->data[$offset] : null; |
||||
} |
||||
|
||||
/** |
||||
* This method is required by the interface ArrayAccess. |
||||
* @param integer $offset the offset to set element |
||||
* @param mixed $item the element value |
||||
*/ |
||||
public function offsetSet($offset, $item) |
||||
{ |
||||
$this->data[$offset] = $item; |
||||
} |
||||
|
||||
/** |
||||
* This method is required by the interface ArrayAccess. |
||||
* @param mixed $offset the offset to unset element |
||||
*/ |
||||
public function offsetUnset($offset) |
||||
{ |
||||
unset($this->data[$offset]); |
||||
} |
||||
} |
@ -0,0 +1,111 @@
|
||||
<?php |
||||
/** |
||||
* @link http://www.yiiframework.com/ |
||||
* @copyright Copyright (c) 2008 Yii Software LLC |
||||
* @license http://www.yiiframework.com/license/ |
||||
*/ |
||||
|
||||
namespace yii\test; |
||||
|
||||
use Yii; |
||||
use yii\base\ArrayAccessTrait; |
||||
use yii\base\InvalidConfigException; |
||||
|
||||
/** |
||||
* BaseActiveFixture is the base class for fixture classes that support accessing fixture data as ActiveRecord objects. |
||||
* |
||||
* @author Qiang Xue <qiang.xue@gmail.com> |
||||
* @since 2.0 |
||||
*/ |
||||
abstract class BaseActiveFixture extends DbFixture implements \IteratorAggregate, \ArrayAccess, \Countable |
||||
{ |
||||
use ArrayAccessTrait; |
||||
|
||||
/** |
||||
* @var string the AR model class associated with this fixture. |
||||
* @see tableName |
||||
*/ |
||||
public $modelClass; |
||||
/** |
||||
* @var boolean whether to create the corresponding DB schema for this fixture. |
||||
* By setting this property to be true, the [[loadSchema()]] method will be called when the fixture is loaded. |
||||
*/ |
||||
public $loadSchema = true; |
||||
/** |
||||
* @var boolean whether to load fixture data. |
||||
* By setting this property to be true, the [[loadData()]] method will be called when the fixture is loaded. |
||||
*/ |
||||
public $loadData = true; |
||||
/** |
||||
* @var array the data rows. Each array element represents one row of data (column name => column value). |
||||
*/ |
||||
public $data = []; |
||||
/** |
||||
* @var \yii\db\ActiveRecord[] the loaded AR models |
||||
*/ |
||||
private $_models = []; |
||||
|
||||
|
||||
/** |
||||
* @inheritdoc |
||||
*/ |
||||
public function load() |
||||
{ |
||||
if ($this->loadSchema) { |
||||
$this->loadSchema(); |
||||
} |
||||
if ($this->loadData) { |
||||
$this->loadData(); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Returns the AR model by the specified model name. |
||||
* A model name is the key of the corresponding data row returned by [[loadData()]]. |
||||
* @param string $name the model name. |
||||
* @return null|\yii\db\ActiveRecord the AR model, or null if the model cannot be found in the database |
||||
* @throws \yii\base\InvalidConfigException if [[modelClass]] is not set. |
||||
*/ |
||||
public function getModel($name) |
||||
{ |
||||
if (!isset($this->data[$name])) { |
||||
return null; |
||||
} |
||||
if (array_key_exists($name, $this->_models)) { |
||||
return $this->_models[$name]; |
||||
} |
||||
|
||||
if ($this->modelClass === null) { |
||||
throw new InvalidConfigException('The "modelClass" property must be set.'); |
||||
} |
||||
$row = $this->data[$name]; |
||||
/** @var \yii\db\ActiveRecord $modelClass */ |
||||
$modelClass = $this->modelClass; |
||||
/** @var \yii\db\ActiveRecord $model */ |
||||
$model = new $modelClass; |
||||
$keys = []; |
||||
foreach ($model->primaryKey() as $key) { |
||||
$keys[$key] = isset($row[$key]) ? $row[$key] : null; |
||||
} |
||||
return $this->_models[$name] = $modelClass::find($keys); |
||||
} |
||||
|
||||
/** |
||||
* Creates the database schema needed by this fixture. |
||||
* You may override this method by creating the DB table associated with this fixture |
||||
* and other relevant DB elements, such as views, triggers. |
||||
*/ |
||||
protected function loadSchema() |
||||
{ |
||||
} |
||||
|
||||
/** |
||||
* Loads the fixture data. |
||||
* The default implementation will first reset the DB table and then populate it with the data |
||||
* returned by [[getData()]]. |
||||
*/ |
||||
protected function loadData() |
||||
{ |
||||
return []; |
||||
} |
||||
} |
@ -0,0 +1,74 @@
|
||||
<?php |
||||
/** |
||||
* @link http://www.yiiframework.com/ |
||||
* @copyright Copyright (c) 2008 Yii Software LLC |
||||
* @license http://www.yiiframework.com/license/ |
||||
*/ |
||||
|
||||
namespace yii\test; |
||||
|
||||
use Yii; |
||||
|
||||
/** |
||||
* InitDbFixture represents the initial state needed for DB-related tests. |
||||
* |
||||
* Its main task is to toggle integrity check of the database during data loading. |
||||
* This is needed by other DB-related fixtures (e.g. [[ActiveFixture]]) so that they can populate |
||||
* data into the database without triggering integrity check errors. |
||||
* |
||||
* Besides, DbFixture also attempts to load an [[initScript|initialization script]] if it exists. |
||||
* |
||||
* You should normally use InitDbFixture to prepare a skeleton test database. |
||||
* Other DB fixtures will then add specific tables and data to this database. |
||||
* |
||||
* @author Qiang Xue <qiang.xue@gmail.com> |
||||
* @since 2.0 |
||||
*/ |
||||
class InitDbFixture extends DbFixture |
||||
{ |
||||
/** |
||||
* @var string the init script file that should be executed when loading this fixture. |
||||
* This should be either a file path or path alias. Note that if the file does not exist, |
||||
* no error will be raised. |
||||
*/ |
||||
public $initScript = '@app/tests/fixtures/initdb.php'; |
||||
/** |
||||
* @var array list of database schemas that the test tables may reside in. Defaults to |
||||
* [''], meaning using the default schema (an empty string refers to the |
||||
* default schema). This property is mainly used when turning on and off integrity checks |
||||
* so that fixture data can be populated into the database without causing problem. |
||||
*/ |
||||
public $schemas = ['']; |
||||
|
||||
|
||||
/** |
||||
* @inheritdoc |
||||
*/ |
||||
public function beforeLoad() |
||||
{ |
||||
foreach ($this->schemas as $schema) { |
||||
$this->checkIntegrity(false, $schema); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* @inheritdoc |
||||
*/ |
||||
public function afterLoad() |
||||
{ |
||||
foreach ($this->schemas as $schema) { |
||||
$this->checkIntegrity(true, $schema); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* @inheritdoc |
||||
*/ |
||||
public function load() |
||||
{ |
||||
$file = Yii::getAlias($this->initScript); |
||||
if (is_file($file)) { |
||||
require($file); |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue