Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
Y
yii2
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
PSDI Army
yii2
Commits
8106cded
Commit
8106cded
authored
Nov 16, 2013
by
Qiang Xue
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implemented DB fixture manager.
parent
83ab0f06
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
329 additions
and
0 deletions
+329
-0
DbFixtureManager.php
framework/yii/test/DbFixtureManager.php
+219
-0
DbTestTrait.php
framework/yii/test/DbTestTrait.php
+110
-0
No files found.
framework/yii/test/DbFixtureManager.php
0 → 100644
View file @
8106cded
<?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\Component
;
use
yii\base\InvalidConfigException
;
use
yii\db\ActiveRecord
;
use
yii\db\Connection
;
/**
* DbFixtureManager manages database fixtures during tests.
*
* A fixture represents a list of rows for a specific table. For a test method,
* using a fixture means that at the beginning of the method, the table has and only
* has the rows that are given in the fixture. Therefore, the table's state is
* predictable.
*
* A fixture is represented as a PHP script whose name (without suffix) is the
* same as the table name (if schema name is needed, it should be prefixed to
* the table name). The PHP script returns an array representing a list of table
* rows. Each row is an associative array of column values indexed by column names.
*
* Fixtures must be stored under the [[basePath]] directory. The directory
* may contain a file named `init.php` which will be executed before any fixture is loaded.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class
DbFixtureManager
extends
Component
{
/**
* @var string the init script file that should be executed before running each test.
* This should be a path relative to [[basePath]].
*/
public
$initScript
=
'init.php'
;
/**
* @var string the base path containing all fixtures. This can be either a directory path or path alias.
*/
public
$basePath
=
'@app/tests/fixtures'
;
/**
* @var Connection|string the DB connection object or the application component ID of the DB connection.
* After the DbFixtureManager object is created, if you want to change this property, you should only assign it
* with a DB connection object.
*/
public
$db
=
'db'
;
/**
* @var array list of database schemas that the test tables may reside in. Defaults to
* array(''), 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
=
[
''
];
private
$_rows
;
// fixture name, row alias => row
private
$_models
;
// fixture name, row alias => record (or class name)
private
$_modelClasses
;
/**
* Loads the specified fixtures.
*
* This method does the following things to load the fixtures:
*
* - Run [[initScript]] if any.
* - Clean up data and models loaded in memory previously.
* - Load each specified fixture by calling [[loadFixture()]].
*
* @param array $fixtures a list of fixtures (fixture name => table name or AR class name) to be loaded.
* Each array element can be either a table name (with schema prefix if needed), or a fully-qualified
* ActiveRecord class name (e.g. `app\models\Post`). An element can be associated with a key
* which will be treated as the fixture name.
* @return array the loaded fixture data (fixture name => table rows)
* @throws InvalidConfigException if a model class specifying a fixture is not an ActiveRecord class.
*/
public
function
load
(
array
$fixtures
=
[])
{
$this
->
basePath
=
Yii
::
getAlias
(
$this
->
basePath
);
if
(
is_string
(
$this
->
db
))
{
$this
->
db
=
Yii
::
$app
->
getComponent
(
$this
->
db
);
}
if
(
!
$this
->
db
instanceof
Connection
)
{
throw
new
InvalidConfigException
(
"The 'db' property must be either a DB connection instance or the application component ID of a DB connection."
);
}
foreach
(
$fixtures
as
$name
=>
$fixture
)
{
if
(
strpos
(
$fixture
,
'\\'
)
!==
false
)
{
$model
=
new
$fixture
;
if
(
$model
instanceof
ActiveRecord
)
{
$this
->
_modelClasses
[
$name
]
=
$fixture
;
$fixtures
[
$name
]
=
$model
->
getTableSchema
()
->
name
;
}
else
{
throw
new
InvalidConfigException
(
"Fixture '
$fixture
' must be an ActiveRecord class."
);
}
}
}
$this
->
_modelClasses
=
$this
->
_rows
=
$this
->
_models
=
[];
$this
->
checkIntegrity
(
false
);
if
(
!
empty
(
$this
->
initScript
))
{
$initFile
=
$this
->
basePath
.
'/'
.
$this
->
initScript
;
if
(
is_file
(
$initFile
))
{
require
(
$initFile
);
}
}
foreach
(
$fixtures
as
$name
=>
$tableName
)
{
$rows
=
$this
->
loadFixture
(
$tableName
);
if
(
is_array
(
$rows
))
{
$this
->
_rows
[
$name
]
=
$rows
;
}
}
$this
->
checkIntegrity
(
true
);
return
$this
->
_rows
;
}
/**
* Loads the fixture for the specified table.
*
* This method does the following tasks to load the fixture for a table:
*
* - Remove existing rows in the table.
* - If there is any auto-incremental column, the corresponding sequence will be reset to 0.
* - If a fixture file is found, it will be executed, and its return value will be treated
* as rows which will then be inserted into the table.
*
* @param string $tableName table name
* @return array|boolean the loaded fixture rows indexed by row aliases (if any).
* False is returned if the table does not have a fixture.
* @throws InvalidConfigException if the specified table does not exist
*/
public
function
loadFixture
(
$tableName
)
{
$table
=
$this
->
db
->
getSchema
()
->
getTableSchema
(
$tableName
);
if
(
$table
===
null
)
{
throw
new
InvalidConfigException
(
"Table does not exist:
$tableName
"
);
}
$this
->
db
->
createCommand
()
->
truncateTable
(
$tableName
);
$fileName
=
$this
->
basePath
.
'/'
.
$tableName
.
'.php'
;
if
(
!
is_file
(
$fileName
))
{
return
false
;
}
$rows
=
[];
foreach
(
require
(
$fileName
)
as
$alias
=>
$row
)
{
$this
->
db
->
createCommand
()
->
insert
(
$tableName
,
$row
)
->
execute
();
if
(
$table
->
sequenceName
!==
null
)
{
foreach
(
$table
->
primaryKey
as
$pk
)
{
if
(
!
isset
(
$row
[
$pk
]))
{
$row
[
$pk
]
=
$this
->
db
->
getLastInsertID
(
$table
->
sequenceName
);
break
;
}
}
}
$rows
[
$alias
]
=
$row
;
}
return
$rows
;
}
/**
* Returns the fixture data rows.
* The rows will have updated primary key values if the primary key is auto-incremental.
* @param string $fixtureName the fixture name
* @return array the fixture data rows. False is returned if there is no such fixture data.
*/
public
function
getRows
(
$fixtureName
)
{
return
isset
(
$this
->
_rows
[
$fixtureName
])
?
$this
->
_rows
[
$fixtureName
]
:
false
;
}
/**
* Returns the specified ActiveRecord instance in the fixture data.
* @param string $fixtureName the fixture name
* @param string $modelName the alias for the fixture data row
* @return \yii\db\ActiveRecord the ActiveRecord instance. Null is returned if there is no such fixture row.
*/
public
function
getModel
(
$fixtureName
,
$modelName
)
{
if
(
!
isset
(
$this
->
_modelClasses
[
$fixtureName
])
||
!
isset
(
$this
->
_rows
[
$fixtureName
][
$modelName
]))
{
return
null
;
}
if
(
isset
(
$this
->
_models
[
$fixtureName
][
$modelName
]))
{
return
$this
->
_models
[
$fixtureName
][
$modelName
];
}
$row
=
$this
->
_rows
[
$fixtureName
][
$modelName
];
/** @var \yii\db\ActiveRecord $modelClass */
$modelClass
=
$this
->
_models
[
$fixtureName
];
/** @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
[
$fixtureName
][
$modelName
]
=
$modelClass
::
find
(
$keys
);
}
/**
* Enables or disables database integrity check.
* This method may be used to temporarily turn off foreign constraints check.
* @param boolean $check whether to enable database integrity check
*/
public
function
checkIntegrity
(
$check
)
{
foreach
(
$this
->
schemas
as
$schema
)
{
$this
->
db
->
createCommand
()
->
checkIntegrity
(
$check
,
$schema
);
}
}
}
framework/yii/test/DbTestTrait.php
0 → 100644
View file @
8106cded
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace
yii\test
;
use
Yii
;
/**
* DbTestTrait implements the commonly used methods for setting up and accessing fixture data.
*
* To use DbTestTrait, call the [[loadFixtures()]] method in the setup method in a test case class.
* The specified fixtures will be loaded and accessible through [[getFixtureData()]] and [[getFixtureModel()]].
*
* For example,
*
* ~~~
* use yii\test\DbTestTrait;
* use app\models\Post;
* use app\models\User;
*
* class PostTestCase extends \PHPUnit_Framework_TestCase
* {
* use DbTestTrait;
*
* public function setUp()
* {
* $this->loadFixtures([
* 'posts' => Post::className(),
* 'users' => User::className(),
* ]);
* }
* }
* ~~~
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
trait
DbTestTrait
{
/**
* Loads the specified fixtures.
*
* This method should typically be called in the setup method of test cases so that
* the fixtures are loaded before running each test method.
*
* This method does the following things:
*
* - Run [[DbFixtureManager::initScript]] if it is found under [[DbFixtureManager::basePath]].
* - Clean up data and models loaded in memory previously.
* - Load each specified fixture:
* * Truncate the corresponding table.
* * If a fixture file named `TableName.php` is found under [[DbFixtureManager::basePath]],
* the file will be executed, and the return value will be treated as rows which will
* then be inserted into the table.
*
* @param array $fixtures a list of fixtures (fixture name => table name or AR class name) to be loaded.
* Each array element can be either a table name (with schema prefix if needed), or a fully-qualified
* ActiveRecord class name (e.g. `app\models\Post`). An element can be optionally associated with a key
* which will be treated as the fixture name. For example,
*
* ~~~
* [
* 'tbl_comment',
* 'users' => 'tbl_user', // 'users' is the fixture name, 'tbl_user' is a table name
* 'posts' => 'app\models\Post, // 'app\models\Post' is a model class name
* ]
* ~~~
*
* @return array the loaded fixture data (fixture name => table rows)
*/
public
function
loadFixtures
(
array
$fixtures
=
[])
{
return
$this
->
getFixtureManager
()
->
load
(
$fixtures
);
}
/**
* Returns the DB fixture manager.
* @return DbFixtureManager the DB fixture manager
*/
public
function
getFixtureManager
()
{
return
Yii
::
$app
->
getComponent
(
'fixture'
);
}
/**
* Returns the table rows of the named fixture.
* @param string $fixtureName the fixture name.
* @return array the named fixture table rows. False is returned if there is no such fixture data.
*/
public
function
getFixtureRows
(
$fixtureName
)
{
return
$this
->
getFixtureManager
()
->
getRows
(
$fixtureName
);
}
/**
* Returns the named AR instance corresponding to the named fixture.
* @param string $fixtureName the fixture name.
* @param string $modelName the name of the fixture data row
* @return \yii\db\ActiveRecord the named AR instance corresponding to the named fixture.
* Null is returned if there is no such fixture or the record cannot be found.
*/
public
function
getFixtureModel
(
$fixtureName
,
$modelName
)
{
return
$this
->
getFixtureManager
()
->
getModel
(
$fixtureName
,
$modelName
);
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment