Commit 3518813a by Carsten Brandt

Merge branch 'master' into redis

* master: (108 commits) fixed indentation in test files cleanup tests Travis-CI build status. CS fixes. CS fixes. Change magic property to normal method. (Thanks to @maxlapko.) CS fixes. Fixed duplicated merge. Fixes issue #50: implemented pager widgets. fix: remove pointless unset remove fix for unset timezone from bootstrap app mod: don't use ArrayHelper to avoid loading another class during every request better have timezone fix in application Add exception classes hierarchy UML diagram. Initial Gettext support. RBAC sql files identation fix RBAC sql files DbManager some Db fields renaming DbManager code style fix + right Exception type fix Unit tests fix ... Conflicts: tests/unit/framework/caching/ApcCacheTest.php tests/unit/framework/caching/CacheTest.php
parents f59f3908 3bdb6c31
......@@ -10,4 +10,7 @@ nbproject
.settings
# windows thumbnail cache
Thumbs.db
\ No newline at end of file
Thumbs.db
# composer vendor dir
/yii/vendor
\ No newline at end of file
<?php
// comment out the following line to disable debug mode
defined('YII_DEBUG') or define('YII_DEBUG', true);
require(__DIR__ . '/../../framework/yii.php');
$frameworkPath = __DIR__ . '/../../yii';
require($frameworkPath . '/Yii.php');
// Register Composer autoloader
@include($frameworkPath . '/vendor/autoload.php');
$config = require(__DIR__ . '/protected/config/main.php');
$application = new yii\web\Application($config);
......
......@@ -3,6 +3,12 @@
return array(
'id' => 'hello',
'basePath' => dirname(__DIR__),
'preload' => array('log'),
'modules' => array(
'debug' => array(
'class' => 'yii\debug\Module',
)
),
'components' => array(
'cache' => array(
'class' => 'yii\caching\FileCache',
......@@ -14,6 +20,15 @@ return array(
'assetManager' => array(
'bundles' => require(__DIR__ . '/assets.php'),
),
'log' => array(
'class' => 'yii\logging\Router',
'targets' => array(
'file' => array(
'class' => 'yii\logging\FileTarget',
'levels' => array('error', 'warning'),
),
),
),
),
'params' => array(
'adminEmail' => 'admin@example.com',
......
......@@ -6,6 +6,15 @@ use app\models\ContactForm;
class SiteController extends Controller
{
public function actions()
{
return array(
'captcha' => array(
'class' => 'yii\web\CaptchaAction',
),
);
}
public function actionIndex()
{
echo $this->render('index');
......
......@@ -26,7 +26,7 @@ class ContactForm extends Model
// email has to be a valid email address
array('email', 'email'),
// verifyCode needs to be entered correctly
//array('verifyCode', 'captcha', 'allowEmpty' => !Captcha::checkRequirements()),
array('verifyCode', 'captcha'),
);
}
......
<?php
use yii\helpers\Html;
use yii\widgets\Menu;
/**
* @var $this \yii\base\View
* @var $content string
*/
use yii\helpers\Html;
$this->registerAssetBundle('app');
?>
<?php $this->beginPage(); ?>
......@@ -23,16 +25,17 @@ $this->registerAssetBundle('app');
<div class="navbar">
<div class="navbar-inner">
<div class="container">
<ul class="nav">
<li><?php echo Html::a('Home', Yii::$app->homeUrl); ?></li>
<li><?php echo Html::a('About', array('/site/about')); ?></li>
<li><?php echo Html::a('Contact', array('/site/contact')); ?></li>
<?php if (Yii::$app->user->isGuest): ?>
<li><?php echo Html::a('Login', array('/site/login')); ?></li>
<?php else: ?>
<li><?php echo Html::a('Logout (' . Html::encode(Yii::$app->user->identity->username) . ')', array('/site/logout')); ?></li>
<?php endif; ?>
</ul>
<?php $this->widget(Menu::className(), array(
'options' => array('class' => 'nav'),
'items' => array(
array('label' => 'Home', 'url' => array('/site/index')),
array('label' => 'About', 'url' => array('/site/about')),
array('label' => 'Contact', 'url' => array('/site/contact')),
Yii::$app->user->isGuest ?
array('label' => 'Login', 'url' => array('/site/login')) :
array('label' => 'Logout (' . Yii::$app->user->identity->username .')' , 'url' => array('/site/logout')),
),
)); ?>
</div>
</div>
</div>
......@@ -55,6 +58,7 @@ $this->registerAssetBundle('app');
</div>
<?php $this->endBody(); ?>
</div>
<?php $this->widget('yii\debug\Toolbar'); ?>
</body>
</html>
<?php $this->endPage(); ?>
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
use yii\widgets\Captcha;
/**
* @var yii\base\View $this
* @var yii\widgets\ActiveForm $form
......@@ -10,7 +13,7 @@ $this->params['breadcrumbs'][] = $this->title;
?>
<h1><?php echo Html::encode($this->title); ?></h1>
<?php if(Yii::$app->session->hasFlash('contactFormSubmitted')): ?>
<?php if (Yii::$app->session->hasFlash('contactFormSubmitted')): ?>
<div class="alert alert-success">
Thank you for contacting us. We will respond to you as soon as possible.
</div>
......@@ -20,7 +23,7 @@ $this->params['breadcrumbs'][] = $this->title;
If you have business inquiries or other questions, please fill out the following form to contact us. Thank you.
</p>
<?php $form = $this->beginWidget('yii\widgets\ActiveForm', array(
<?php $form = $this->beginWidget(ActiveForm::className(), array(
'options' => array('class' => 'form-horizontal'),
'fieldConfig' => array('inputOptions' => array('class' => 'input-xlarge')),
)); ?>
......@@ -28,6 +31,15 @@ $this->params['breadcrumbs'][] = $this->title;
<?php echo $form->field($model, 'email')->textInput(); ?>
<?php echo $form->field($model, 'subject')->textInput(); ?>
<?php echo $form->field($model, 'body')->textArea(array('rows' => 6)); ?>
<?php
$field = $form->field($model, 'verifyCode');
echo $field->begin();
echo $field->label();
$this->widget(Captcha::className());
echo Html::activeTextInput($model, 'verifyCode', array('class' => 'input-medium'));
echo $field->error();
echo $field->end();
?>
<div class="form-actions">
<?php echo Html::submitButton('Submit', null, null, array('class' => 'btn btn-primary')); ?>
</div>
......
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
/**
* @var yii\base\View $this
* @var yii\widgets\ActiveForm $form
......@@ -12,7 +14,7 @@ $this->params['breadcrumbs'][] = $this->title;
<p>Please fill out the following fields to login:</p>
<?php $form = $this->beginWidget('yii\widgets\ActiveForm', array('options' => array('class' => 'form-horizontal'))); ?>
<?php $form = $this->beginWidget(ActiveForm::className(), array('options' => array('class' => 'form-horizontal'))); ?>
<?php echo $form->field($model, 'username')->textInput(); ?>
<?php echo $form->field($model, 'password')->passwordInput(); ?>
<?php echo $form->field($model, 'rememberMe')->checkbox(); ?>
......
......@@ -11,7 +11,7 @@
// fcgi doesn't have STDIN defined by default
defined('STDIN') or define('STDIN', fopen('php://stdin', 'r'));
require(__DIR__ . '/../framework/yii.php');
require(__DIR__ . '/../framework/Yii.php');
$id = 'yiic-build';
$basePath = __DIR__;
......
{
"name": "yiisoft/yii2",
"description": "Yii2 Web Programming Framework",
"keywords": ["yii", "framework"],
"homepage": "http://www.yiiframework.com/",
"type": "library",
"license": "BSD-3-Clause",
"authors": [
{
"name": "Qiang Xue",
"email": "qiang.xue@gmail.com",
"homepage": "http://www.yiiframework.com/",
"role": "Founder and project lead"
},
{
"name": "Alexander Makarov",
"email": "sam@rmcreative.ru",
"homepage": "http://rmcreative.ru/",
"role": "Core framework development"
},
{
"name": "Maurizio Domba",
"homepage": "http://mdomba.info/",
"role": "Core framework development"
},
{
"name": "Carsten Brandt",
"email": "mail@cebe.cc",
"homepage": "http://cebe.cc/",
"role": "Core framework development"
},
{
"name": "Timur Ruziev",
"email": "resurtm@gmail.com",
"homepage": "http://resurtm.com/",
"role": "Core framework development"
},
{
"name": "Paul Klimov",
"email": "klimov.paul@gmail.com",
"role": "Core framework development"
},
{
"name": "Wei Zhuo",
"email": "weizhuo@gmail.com",
"role": "Project site maintenance and development"
},
{
"name": "Sebastián Thierer",
"email": "sebas@artfos.com",
"role": "Component development"
},
{
"name": "Jeffrey Winesett",
"email": "jefftulsa@gmail.com",
"role": "Documentation and marketing"
}
],
"support": {
"issues": "https://github.com/yiisoft/yii2/issues?state=open",
"forum": "http://www.yiiframework.com/forum/",
"wiki": "http://www.yiiframework.com/wiki/",
"irc": "irc://irc.freenode.net/yii",
"source": "https://github.com/yiisoft/yii2"
},
"config": {
"vendor-dir": "yii/vendor"
},
"bin": [
"yii/yiic"
],
"require": {
"php": ">=5.3.0",
"michelf/php-markdown": "1.3",
"twig/twig": "1.12.*",
"smarty/smarty": "3.1.*",
"ezyang/htmlpurifier": "v4.5.0"
}
}
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file"
],
"hash": "7d46ce9c4d8d5f4ecae1611ea8f0b49c",
"packages": [
{
"name": "ezyang/htmlpurifier",
"version": "v4.5.0",
"source": {
"type": "git",
"url": "https://github.com/ezyang/htmlpurifier.git",
"reference": "v4.5.0"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/v4.5.0",
"reference": "v4.5.0",
"shasum": ""
},
"require": {
"php": ">=5.2"
},
"type": "library",
"autoload": {
"psr-0": {
"HTMLPurifier": "library/"
},
"files": [
"library/HTMLPurifier.composer.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"LGPL"
],
"authors": [
{
"name": "Edward Z. Yang",
"email": "admin@htmlpurifier.org",
"homepage": "http://ezyang.com"
}
],
"description": "Standards compliant HTML filter written in PHP",
"homepage": "http://htmlpurifier.org/",
"keywords": [
"html"
],
"time": "2013-02-18 00:04:08"
},
{
"name": "michelf/php-markdown",
"version": "1.3",
"source": {
"type": "git",
"url": "https://github.com/michelf/php-markdown.git",
"reference": "1.3"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/michelf/php-markdown/zipball/1.3",
"reference": "1.3",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-lib": "1.3.x-dev"
}
},
"autoload": {
"psr-0": {
"Michelf": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Michel Fortin",
"email": "michel.fortin@michelf.ca",
"homepage": "http://michelf.ca/",
"role": "Developer"
},
{
"name": "John Gruber",
"homepage": "http://daringfireball.net/"
}
],
"description": "PHP Markdown",
"homepage": "http://michelf.ca/projects/php-markdown/",
"keywords": [
"markdown"
],
"time": "2013-04-11 18:53:11"
},
{
"name": "smarty/smarty",
"version": "v3.1.13",
"source": {
"type": "svn",
"url": "http://smarty-php.googlecode.com/svn",
"reference": "/tags/v3.1.13/@4699"
},
"require": {
"php": ">=5.2"
},
"type": "library",
"autoload": {
"classmap": [
"distribution/libs/Smarty.class.php",
"distribution/libs/SmartyBC.class.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"LGPL-3.0"
],
"authors": [
{
"name": "Monte Ohrt",
"email": "monte@ohrt.com"
},
{
"name": "Uwe Tews",
"email": "uwe.tews@googlemail.com"
},
{
"name": "Rodney Rehm",
"email": "rodney.rehm@medialize.de"
}
],
"description": "Smarty - the compiling PHP template engine",
"homepage": "http://www.smarty.net",
"keywords": [
"templating"
],
"time": "2013-01-26 12:03:52"
},
{
"name": "twig/twig",
"version": "v1.12.3",
"source": {
"type": "git",
"url": "https://github.com/fabpot/Twig.git",
"reference": "v1.12.3"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/fabpot/Twig/zipball/v1.12.3",
"reference": "v1.12.3",
"shasum": ""
},
"require": {
"php": ">=5.2.4"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.12-dev"
}
},
"autoload": {
"psr-0": {
"Twig_": "lib/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Armin Ronacher",
"email": "armin.ronacher@active-4.com"
}
],
"description": "Twig, the flexible, fast, and secure template language for PHP",
"homepage": "http://twig.sensiolabs.org",
"keywords": [
"templating"
],
"time": "2013-04-08 12:40:11"
}
],
"packages-dev": [
],
"aliases": [
],
"minimum-stability": "stable",
"stability-flags": [
],
"platform": {
"php": ">=5.3.0"
},
"platform-dev": [
]
}
......@@ -162,7 +162,7 @@ class PostController extends Controller
In the view you should access fields of each invidual record from `$posts` as array:
```php
foreach($posts as $post) {
foreach ($posts as $post) {
echo $post['title']."<br>";
}
```
......
......@@ -6,6 +6,17 @@ We hope this list will make it easier for you to upgrade from Yii 1.1 and quickl
master Yii 2.0 based on your existing Yii knowledge.
Namespace
---------
The most obvious change in Yii 2.0 is the use of namespaces. Almost every core class
is namespaced, e.g., `yii\web\Request`. The "C" prefix is no longer used in class names.
The naming of the namespaces follows the directory structure. For example, `yii\web\Request`
indicates the corresponding class file is `web/Request.php` under the Yii framework folder.
You can use any core class without explicitly include that class file, thanks to the Yii
class loader.
Component and Object
--------------------
......@@ -15,7 +26,7 @@ via getters and setters. The `Component` class extends from `Object` and support
the event feature and the behavior feature.
If your class does not need the event or behavior feature, you should consider using
`Object` as the based class. This is usually the case for classes that represent basic
`Object` as the base class. This is usually the case for classes that represent basic
data structures.
......@@ -26,7 +37,7 @@ The `Object` class introduces a uniform way of configuring objects. Any descenda
of `Object` should declare its constructor (if needed) in the following way so that
it can be properly configured:
~~~
```php
class MyClass extends \yii\Object
{
public function __construct($param1, $param2, $config = array())
......@@ -43,7 +54,7 @@ class MyClass extends \yii\Object
// ... initialization after configuration is applied
}
}
~~~
```
In the above, the last parameter of the constructor must take a configuration array
which contains name-value pairs for initializing the properties at the end of the constructor.
......@@ -53,13 +64,14 @@ the configuration is applied.
By following this convention, you will be able to create and configure a new object
using a configuration array like the following:
~~~
```php
$object = Yii::createObject(array(
'class' => 'MyClass',
'property1' => 'abc',
'property2' => 'cde',
), $param1, $param2);
~~~
```
Events
......@@ -69,28 +81,30 @@ There is no longer the need to define an `on`-method in order to define an event
Instead, you can use whatever event names. To attach a handler to an event, you should
use the `on` method now:
~~~
```php
$component->on($eventName, $handler);
// To detach the handler, use:
// $component->off($eventName, $handler);
~~~
```
When you attach a handler, you can now associate it with some parameters which can be later
accessed via the event parameter by the handler:
~~~
```php
$component->on($eventName, $handler, $params);
~~~
```
Because of this change, you can now use "global" events. Simply trigger and attach handlers to
an event of the application instance:
~~~
```php
Yii::$app->on($eventName, $handler);
....
// this will trigger the event and cause $handler to be invoked.
Yii::$app->trigger($eventName);
~~~
```
Path Alias
......@@ -124,12 +138,13 @@ Because you can access the view object through the "view" application component,
you can now render a view file like the following anywhere in your code, not necessarily
in controllers or widgets:
~~~
```php
$content = Yii::$app->view->renderFile($viewFile, $params);
// You can also explicitly create a new View instance to do the rendering
// $view = new View;
// $view->renderFile($viewFile, $params);
~~~
```
Also, there is no more `CClientScript` in Yii 2.0. The `View` class has taken over its role
with significant improvements. For more details, please see the "assets" subsection.
......@@ -154,7 +169,7 @@ validation under which scenario. Child classes should overwrite `scenarios()` to
a list of scenarios and the corresponding attributes that need to be validated when
`validate()` is called. For example,
~~~
```php
public function scenarios()
{
return array(
......@@ -162,7 +177,8 @@ public function scenarios()
'frontend' => array('email', '!name'),
);
}
~~~
```
This method also determines which attributes are safe and which are not. In particular,
given a scenario, if an attribute appears in the corresponding attribute list in `scenarios()`
......@@ -183,14 +199,15 @@ sending them out. You have to `echo` them explicitly, e.g., `echo $this->render(
A new method called `populate()` is introduced to simplify the data population from user inputs
to a model. For example,
~~~
$post = new Post;
```php
$model = new Post;
if ($this->populate($_POST, $model)) {...}
// which is equivalent to:
if (isset($_POST['Post'])) {
$post->attributes = $_POST['Post'];
$model->attributes = $_POST['Post'];
}
~~~
```
Themes
......@@ -245,7 +262,7 @@ define a new filter. To use a filter, you should attach the filter class to the
as a behavior. For example, to use the `AccessControl` filter, you should have the following
code in a controller:
~~~
```php
public function behaviors()
{
return array(
......@@ -258,7 +275,8 @@ public function behaviors()
),
);
}
~~~
```
Assets
......@@ -290,7 +308,7 @@ Yii 2.0 introduces the *field* concept for building a form using `ActiveForm`. A
is a container consisting of a label, an input, and an error message. It is represented
as an `ActiveField` object. Using fields, you can build a form more cleanly than before:
~~~
```php
<?php $form = $this->beginWidget('yii\widgets\ActiveForm'); ?>
<?php echo $form->field($model, 'username')->textInput(); ?>
<?php echo $form->field($model, 'password')->passwordInput(); ?>
......@@ -298,7 +316,8 @@ as an `ActiveField` object. Using fields, you can build a form more cleanly than
<?php echo Html::submitButton('Login'); ?>
</div>
<?php $this->endWidget(); ?>
~~~
```
Query Builder
......@@ -308,7 +327,7 @@ In 1.1, query building is scattered among several classes, including `CDbCommand
`CDbCriteria`, and `CDbCommandBuilder`. Yii 2.0 uses `Query` to represent a DB query
and `QueryBuilder` to generate SQL statements from query objects. For example,
~~~
```php
$query = new \yii\db\Query;
$query->select('id, name')
->from('tbl_user')
......@@ -317,7 +336,8 @@ $query->select('id, name')
$command = $query->createCommand();
$sql = $command->sql;
$rows = $command->queryAll();
~~~
```
Best of all, such query building methods can be used together with `ActiveRecord`,
as explained in the next sub-section.
......@@ -331,7 +351,7 @@ is about relational ActiveRecord query. In 1.1, you have to declare the relation
in the `relations()` method. In 2.0, this is done via getter methods that return
an `ActiveQuery` object. For example, the following method declares an "orders" relation:
~~~
```php
class Customer extends \yii\db\ActiveRecord
{
public function getOrders()
......@@ -339,7 +359,8 @@ class Customer extends \yii\db\ActiveRecord
return $this->hasMany('Order', array('customer_id' => 'id'));
}
}
~~~
```
You can use `$customer->orders` to access the customer's orders. You can also
use `$customer->getOrders()->andWhere('status=1')->all()` to perform on-the-fly
......@@ -355,7 +376,7 @@ by filtering with the primary keys of the primary records.
Yii 2.0 no longer uses the `model()` method when performing queries. Instead, you
use the `find()` method like the following:
~~~
```php
// to retrieve all *active* customers and order them by their ID:
$customers = Customer::find()
->where(array('status' => $active))
......@@ -363,7 +384,8 @@ $customers = Customer::find()
->all();
// return the customer whose PK is 1
$customer = Customer::find(1);
~~~
```
The `find()` method returns an instance of `ActiveQuery` which is a subclass of `Query`.
Therefore, you can use all query methods of `Query`.
......@@ -372,10 +394,9 @@ Instead of returning ActiveRecord objects, you may call `ActiveQuery::asArray()`
return results in terms of arrays. This is more efficient and is especially useful
when you need to return large number of records. For example,
~~~
```php
$customers = Customer::find()->asArray()->all();
~~~
```
By default, ActiveRecord now only saves dirty attributes. In 1.1, all attributes
would be saved to database when you call `save()`, regardless they are changed or not,
......@@ -390,10 +411,10 @@ within double curly brackets is treated as a table name, and a name enclosed wit
double square brackets is treated as a column name. They will be quoted according to
the database driver being used. For example,
~~~
```php
$command = $connection->createCommand('SELECT [[id]] FROM {{posts}}');
echo $command->sql; // MySQL: SELECT `id` FROM `posts`
~~~
```
This feature is especially useful if you are developing an application that supports
different DBMS.
......@@ -415,13 +436,14 @@ parameters. For example, if you have rule declared as follows, then it will matc
both `post/popular` and `post/1/popular`. In 1.1, you would have to use two rules to achieve
the same goal.
~~~
```php
array(
'pattern' => 'post/<page:\d+>/<tag>',
'route' => 'post/index',
'defaults' => array('page' => 1),
)
~~~
```
Response
......
......@@ -9,6 +9,8 @@ If you are looking for a production-ready PHP framework, please use
Yii 2.0 is still under heavy development. We may make significant changes
without prior notices. **Yii 2.0 is not ready for production use yet.**
[![Build Status](https://secure.travis-ci.org/yiisoft/yii2.png)](http://travis-ci.org/yiisoft/yii2)
DIRECTORY STRUCTURE
-------------------
......
<?php
namespace yiiunit;
class DatabaseTestCase extends TestCase
{
protected $database;
protected $driverName = 'mysql';
protected $db;
protected function setUp()
{
parent::setUp();
$databases = $this->getParam('databases');
$this->database = $databases[$this->driverName];
$pdo_database = 'pdo_'.$this->driverName;
if (!extension_loaded('pdo') || !extension_loaded($pdo_database)) {
$this->markTestSkipped('pdo and pdo_'.$pdo_database.' extension are required.');
}
}
/**
* @param bool $reset whether to clean up the test database
* @param bool $open whether to open and populate test database
* @return \yii\db\Connection
*/
public function getConnection($reset = true, $open = true)
{
if (!$reset && $this->db) {
return $this->db;
}
$db = new \yii\db\Connection;
$db->dsn = $this->database['dsn'];
if (isset($this->database['username'])) {
$db->username = $this->database['username'];
$db->password = $this->database['password'];
}
if ($open) {
$db->open();
$lines = explode(';', file_get_contents($this->database['fixture']));
foreach ($lines as $line) {
if (trim($line) !== '') {
$db->pdo->exec($line);
}
}
}
$this->db = $db;
return $db;
}
}
......@@ -6,6 +6,7 @@ class MysqlTestCase extends TestCase
{
protected function setUp()
{
parent::setUp();
if (!extension_loaded('pdo') || !extension_loaded('pdo_mysql')) {
$this->markTestSkipped('pdo and pdo_mysql extensions are required.');
}
......
......@@ -2,15 +2,58 @@
namespace yiiunit;
/**
* This is the base class for all yii framework unit tests.
*/
class TestCase extends \yii\test\TestCase
{
public static $params;
public function getParam($name)
/**
* Clean up after test.
* By default the application created with [[mockApplication]] will be destroyed.
*/
protected function tearDown()
{
parent::tearDown();
$this->destroyApplication();
}
/**
* Returns a test configuration param from /data/config.php
* @param string $name params name
* @param mixed $default default value to use when param is not set.
* @return mixed the value of the configuration param
*/
public function getParam($name, $default = null)
{
if (self::$params === null) {
self::$params = require(__DIR__ . '/data/config.php');
}
return isset(self::$params[$name]) ? self::$params[$name] : null;
return isset(self::$params[$name]) ? self::$params[$name] : $default;
}
/**
* Populates Yii::$app with a new application
* The application will be destroyed on tearDown() automatically.
* @param array $config The application configuration, if needed
*/
protected function mockApplication($config=array())
{
static $defaultConfig = array(
'id' => 'testapp',
'basePath' => __DIR__,
);
$appClass = $this->getParam( 'appClass', '\yii\web\Application' );
new $appClass(array_merge($defaultConfig,$config));
}
/**
* Destroys application in Yii::$app by setting it to null.
*/
protected function destroyApplication()
{
\Yii::$app = null;
}
}
......@@ -5,10 +5,8 @@ define('YII_DEBUG', true);
$_SERVER['SCRIPT_NAME'] = '/' . __DIR__;
$_SERVER['SCRIPT_FILENAME'] = __FILE__;
require_once(__DIR__ . '/../../framework/yii.php');
require_once(__DIR__ . '/../../yii/Yii.php');
Yii::setAlias('@yiiunit', __DIR__);
new \yii\web\Application(array('id' => 'testapp', 'basePath' => __DIR__));
require_once(__DIR__ . '/TestCase.php');
<?php
return array(
'mysql' => array(
'dsn' => 'mysql:host=127.0.0.1;dbname=yiitest',
'username' => 'travis',
'password' => '',
'fixture' => __DIR__ . '/mysql.sql',
//'appClass' => '\yii\web\Application',
'appClass' => '\yii\console\Application',
'databases' => array(
'mysql' => array(
'dsn' => 'mysql:host=127.0.0.1;dbname=yiitest',
'username' => 'travis',
'password' => '',
'fixture' => __DIR__ . '/mysql.sql',
),
'sqlite' => array(
'dsn' => 'sqlite::memory:',
'fixture' => __DIR__ . '/sqlite.sql',
),
),
'redis' => array(
'dsn' => 'redis://localhost:6379/0',
......
msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: \n"
"PO-Revision-Date: \n"
"Last-Translator: resurtm <resurtm@gmail.com>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 1.5.5\n"
msgctxt "context1"
msgid ""
"Aliquam tempus elit vel purus molestie placerat. In sollicitudin tincidunt\n"
"aliquet. Integer tincidunt gravida tempor. In convallis blandit dui vel "
"malesuada.\n"
"Nunc vel sapien nunc, a pretium nulla."
msgstr ""
"Олицетворение однократно. Представленный лексико-семантический анализ "
"является\n"
"психолингвистическим в своей основе, но механизм сочленений полидисперсен. "
"Впечатление\n"
"однократно. Различное расположение выбирает сюжетный механизм сочленений."
msgctxt "context1"
msgid "String number two."
msgstr "Строка номер два."
msgctxt "context2"
msgid ""
"The other\n"
"\n"
"context.\n"
msgstr ""
"Другой\n"
"\n"
"контекст.\n"
msgctxt "context1"
msgid ""
"Missing\n"
"\r\t\"translation."
msgstr ""
msgctxt "context1"
msgid ""
"Nunc vel sapien nunc, a pretium nulla.\n"
"Pellentesque habitant morbi tristique senectus et netus et malesuada fames "
"ac turpis egestas."
msgstr "Короткий перевод."
msgid "contextless"
msgstr ""
msgctxt "context2"
msgid ""
"test1\\ntest2\n"
"\\\n"
"test3"
msgstr ""
"тест1\\nтест2\n"
"\\\n"
"тест3"
/**
* This is the database schema for testing MySQL support of Yii DAO and Active Record.
* The following database setup is required to perform then relevant tests:
* Database name: yiitest
* username: test
* password: test
* charset: utf8
* The database setup in config.php is required to perform then relevant tests:
*/
DROP TABLE IF EXISTS tbl_order_item CASCADE;
......
......@@ -11,13 +11,15 @@ class YiiBaseTest extends TestCase
{
public $aliases;
public function setUp()
protected function setUp()
{
parent::setUp();
$this->aliases = Yii::$aliases;
}
public function tearDown()
protected function tearDown()
{
parent::tearDown();
Yii::$aliases = $this->aliases;
}
......@@ -47,7 +49,6 @@ class YiiBaseTest extends TestCase
public function testGetVersion()
{
echo Yii::getVersion();
$this->assertTrue((boolean)preg_match('~\d+\.\d+(?:\.\d+)?(?:-\w+)?~', \Yii::getVersion()));
}
......
......@@ -24,13 +24,15 @@ class ComponentTest extends TestCase
*/
protected $component;
public function setUp()
protected function setUp()
{
parent::setUp();
$this->component = new NewComponent();
}
public function tearDown()
protected function tearDown()
{
parent::tearDown();
$this->component = null;
}
......
......@@ -15,52 +15,56 @@ class DictionaryTest extends \yiiunit\TestCase
* @var \yii\base\Dictionary
*/
protected $dictionary;
protected $item1,$item2,$item3;
protected $item1;
protected $item2;
protected $item3;
public function setUp()
protected function setUp()
{
$this->dictionary=new Dictionary;
$this->item1=new MapItem;
$this->item2=new MapItem;
$this->item3=new MapItem;
$this->dictionary->add('key1',$this->item1);
$this->dictionary->add('key2',$this->item2);
parent::setUp();
$this->dictionary = new Dictionary;
$this->item1 = new MapItem;
$this->item2 = new MapItem;
$this->item3 = new MapItem;
$this->dictionary->add('key1', $this->item1);
$this->dictionary->add('key2', $this->item2);
}
public function tearDown()
protected function tearDown()
{
$this->dictionary=null;
$this->item1=null;
$this->item2=null;
$this->item3=null;
parent::tearDown();
$this->dictionary = null;
$this->item1 = null;
$this->item2 = null;
$this->item3 = null;
}
public function testConstruct()
{
$a=array(1,2,'key3'=>3);
$dictionary=new Dictionary($a);
$this->assertEquals(3,$dictionary->getCount());
$a = array(1, 2, 'key3' => 3);
$dictionary = new Dictionary($a);
$this->assertEquals(3, $dictionary->getCount());
$dictionary2=new Dictionary($this->dictionary);
$this->assertEquals(2,$dictionary2->getCount());
$this->assertEquals(2, $dictionary2->getCount());
}
public function testGetCount()
{
$this->assertEquals(2,$this->dictionary->getCount());
$this->assertEquals(2, $this->dictionary->getCount());
}
public function testGetKeys()
{
$keys=$this->dictionary->getKeys();
$this->assertEquals(2,count($keys));
$this->assertEquals('key1',$keys[0]);
$this->assertEquals('key2',$keys[1]);
$keys = $this->dictionary->getKeys();
$this->assertEquals(2, count($keys));
$this->assertEquals('key1', $keys[0]);
$this->assertEquals('key2', $keys[1]);
}
public function testAdd()
{
$this->dictionary->add('key3',$this->item3);
$this->assertEquals(3,$this->dictionary->getCount());
$this->dictionary->add('key3', $this->item3);
$this->assertEquals(3, $this->dictionary->getCount());
$this->assertTrue($this->dictionary->has('key3'));
$this->dictionary[] = 'test';
......@@ -69,21 +73,21 @@ class DictionaryTest extends \yiiunit\TestCase
public function testRemove()
{
$this->dictionary->remove('key1');
$this->assertEquals(1,$this->dictionary->getCount());
$this->assertEquals(1, $this->dictionary->getCount());
$this->assertTrue(!$this->dictionary->has('key1'));
$this->assertTrue($this->dictionary->remove('unknown key')===null);
$this->assertTrue($this->dictionary->remove('unknown key') === null);
}
public function testRemoveAll()
{
$this->dictionary->add('key3',$this->item3);
$this->dictionary->add('key3', $this->item3);
$this->dictionary->removeAll();
$this->assertEquals(0,$this->dictionary->getCount());
$this->assertEquals(0, $this->dictionary->getCount());
$this->assertTrue(!$this->dictionary->has('key1') && !$this->dictionary->has('key2'));
$this->dictionary->add('key3',$this->item3);
$this->dictionary->add('key3', $this->item3);
$this->dictionary->removeAll(true);
$this->assertEquals(0,$this->dictionary->getCount());
$this->assertEquals(0, $this->dictionary->getCount());
$this->assertTrue(!$this->dictionary->has('key1') && !$this->dictionary->has('key2'));
}
......@@ -96,7 +100,7 @@ class DictionaryTest extends \yiiunit\TestCase
public function testFromArray()
{
$array=array('key3'=>$this->item3,'key4'=>$this->item1);
$array = array('key3' => $this->item3, 'key4' => $this->item1);
$this->dictionary->copyFrom($array);
$this->assertEquals(2, $this->dictionary->getCount());
......@@ -109,21 +113,21 @@ class DictionaryTest extends \yiiunit\TestCase
public function testMergeWith()
{
$a=array('a'=>'v1','v2',array('2'),'c'=>array('3','c'=>'a'));
$b=array('v22','a'=>'v11',array('2'),'c'=>array('c'=>'3','a'));
$c=array('a'=>'v11','v2',array('2'),'c'=>array('3','c'=>'3','a'),'v22',array('2'));
$dictionary=new Dictionary($a);
$dictionary2=new Dictionary($b);
$a = array('a' => 'v1', 'v2', array('2'), 'c' => array('3', 'c' => 'a'));
$b = array('v22', 'a' => 'v11', array('2'), 'c' => array('c' => '3', 'a'));
$c = array('a' => 'v11', 'v2', array('2'), 'c' => array('3', 'c' => '3', 'a'), 'v22', array('2'));
$dictionary = new Dictionary($a);
$dictionary2 = new Dictionary($b);
$dictionary->mergeWith($dictionary2);
$this->assertTrue($dictionary->toArray()===$c);
$this->assertTrue($dictionary->toArray() === $c);
$array=array('key2'=>$this->item1,'key3'=>$this->item3);
$this->dictionary->mergeWith($array,false);
$this->assertEquals(3,$this->dictionary->getCount());
$this->assertEquals($this->item1,$this->dictionary['key2']);
$this->assertEquals($this->item3,$this->dictionary['key3']);
$array = array('key2' => $this->item1, 'key3' => $this->item3);
$this->dictionary->mergeWith($array, false);
$this->assertEquals(3, $this->dictionary->getCount());
$this->assertEquals($this->item1, $this->dictionary['key2']);
$this->assertEquals($this->item3, $this->dictionary['key3']);
$this->setExpectedException('yii\base\InvalidParamException');
$this->dictionary->mergeWith($this,false);
$this->dictionary->mergeWith($this, false);
}
public function testRecursiveMergeWithTraversable(){
......@@ -135,7 +139,7 @@ class DictionaryTest extends \yiiunit\TestCase
'k4' => $this->item3,
))
));
$dictionary->mergeWith($obj,true);
$dictionary->mergeWith($obj, true);
$this->assertEquals(3, $dictionary->getCount());
$this->assertEquals($this->item1, $dictionary['k1']);
......@@ -145,23 +149,23 @@ class DictionaryTest extends \yiiunit\TestCase
public function testArrayRead()
{
$this->assertEquals($this->item1,$this->dictionary['key1']);
$this->assertEquals($this->item2,$this->dictionary['key2']);
$this->assertEquals(null,$this->dictionary['key3']);
$this->assertEquals($this->item1, $this->dictionary['key1']);
$this->assertEquals($this->item2, $this->dictionary['key2']);
$this->assertEquals(null, $this->dictionary['key3']);
}
public function testArrayWrite()
{
$this->dictionary['key3']=$this->item3;
$this->assertEquals(3,$this->dictionary->getCount());
$this->assertEquals($this->item3,$this->dictionary['key3']);
$this->dictionary['key3'] = $this->item3;
$this->assertEquals(3, $this->dictionary->getCount());
$this->assertEquals($this->item3, $this->dictionary['key3']);
$this->dictionary['key1']=$this->item3;
$this->assertEquals(3,$this->dictionary->getCount());
$this->assertEquals($this->item3,$this->dictionary['key1']);
$this->dictionary['key1'] = $this->item3;
$this->assertEquals(3, $this->dictionary->getCount());
$this->assertEquals($this->item3, $this->dictionary['key1']);
unset($this->dictionary['key2']);
$this->assertEquals(2,$this->dictionary->getCount());
$this->assertEquals(2, $this->dictionary->getCount());
$this->assertTrue(!$this->dictionary->has('key2'));
unset($this->dictionary['unknown key']);
......@@ -169,22 +173,23 @@ class DictionaryTest extends \yiiunit\TestCase
public function testArrayForeach()
{
$n=0;
$found=0;
foreach($this->dictionary as $index=>$item)
{
$n = 0;
$found = 0;
foreach ($this->dictionary as $index => $item) {
$n++;
if($index==='key1' && $item===$this->item1)
if ($index === 'key1' && $item === $this->item1) {
$found++;
if($index==='key2' && $item===$this->item2)
}
if ($index === 'key2' && $item === $this->item2) {
$found++;
}
}
$this->assertTrue($n==2 && $found==2);
$this->assertTrue($n == 2 && $found == 2);
}
public function testArrayMisc()
{
$this->assertEquals($this->dictionary->Count,count($this->dictionary));
$this->assertEquals($this->dictionary->Count, count($this->dictionary));
$this->assertTrue(isset($this->dictionary['key1']));
$this->assertFalse(isset($this->dictionary['unknown key']));
}
......
......@@ -155,7 +155,7 @@ class ModelTest extends TestCase
// iteration
$attributes = array();
foreach($speaker as $key => $attribute) {
foreach ($speaker as $key => $attribute) {
$attributes[$key] = $attribute;
}
$this->assertEquals(array(
......
......@@ -14,13 +14,15 @@ class ObjectTest extends TestCase
*/
protected $object;
public function setUp()
protected function setUp()
{
parent::setUp();
$this->object = new NewObject;
}
public function tearDown()
protected function tearDown()
{
parent::tearDown();
$this->object = null;
}
......
......@@ -15,39 +15,43 @@ class VectorTest extends \yiiunit\TestCase
* @var Vector
*/
protected $vector;
protected $item1, $item2, $item3;
protected $item1;
protected $item2;
protected $item3;
public function setUp()
protected function setUp()
{
$this->vector=new Vector;
$this->item1=new ListItem;
$this->item2=new ListItem;
$this->item3=new ListItem;
parent::setUp();
$this->vector = new Vector;
$this->item1 = new ListItem;
$this->item2 = new ListItem;
$this->item3 = new ListItem;
$this->vector->add($this->item1);
$this->vector->add($this->item2);
}
public function tearDown()
protected function tearDown()
{
$this->vector=null;
$this->item1=null;
$this->item2=null;
$this->item3=null;
parent::tearDown();
$this->vector = null;
$this->item1 = null;
$this->item2 = null;
$this->item3 = null;
}
public function testConstruct()
{
$a=array(1,2,3);
$vector=new Vector($a);
$this->assertEquals(3,$vector->getCount());
$vector2=new Vector($this->vector);
$this->assertEquals(2,$vector2->getCount());
$a = array(1, 2, 3);
$vector = new Vector($a);
$this->assertEquals(3, $vector->getCount());
$vector2 = new Vector($this->vector);
$this->assertEquals(2, $vector2->getCount());
}
public function testItemAt()
{
$a=array(1, 2, null, 4);
$vector=new Vector($a);
$a = array(1, 2, null, 4);
$vector = new Vector($a);
$this->assertEquals(1, $vector->itemAt(0));
$this->assertEquals(2, $vector->itemAt(1));
$this->assertNull($vector->itemAt(2));
......@@ -56,37 +60,37 @@ class VectorTest extends \yiiunit\TestCase
public function testGetCount()
{
$this->assertEquals(2,$this->vector->getCount());
$this->assertEquals(2,$this->vector->Count);
$this->assertEquals(2, $this->vector->getCount());
$this->assertEquals(2, $this->vector->Count);
}
public function testAdd()
{
$this->vector->add(null);
$this->vector->add($this->item3);
$this->assertEquals(4,$this->vector->getCount());
$this->assertEquals(3,$this->vector->indexOf($this->item3));
$this->assertEquals(4, $this->vector->getCount());
$this->assertEquals(3, $this->vector->indexOf($this->item3));
}
public function testInsertAt()
{
$this->vector->insertAt(0,$this->item3);
$this->assertEquals(3,$this->vector->getCount());
$this->assertEquals(2,$this->vector->indexOf($this->item2));
$this->assertEquals(0,$this->vector->indexOf($this->item3));
$this->assertEquals(1,$this->vector->indexOf($this->item1));
$this->vector->insertAt(0, $this->item3);
$this->assertEquals(3, $this->vector->getCount());
$this->assertEquals(2, $this->vector->indexOf($this->item2));
$this->assertEquals(0, $this->vector->indexOf($this->item3));
$this->assertEquals(1, $this->vector->indexOf($this->item1));
$this->setExpectedException('yii\base\InvalidParamException');
$this->vector->insertAt(4,$this->item3);
$this->vector->insertAt(4, $this->item3);
}
public function testRemove()
{
$this->vector->remove($this->item1);
$this->assertEquals(1,$this->vector->getCount());
$this->assertEquals(-1,$this->vector->indexOf($this->item1));
$this->assertEquals(0,$this->vector->indexOf($this->item2));
$this->assertEquals(1, $this->vector->getCount());
$this->assertEquals(-1, $this->vector->indexOf($this->item1));
$this->assertEquals(0, $this->vector->indexOf($this->item2));
$this->assertEquals(false,$this->vector->remove($this->item1));
$this->assertEquals(false, $this->vector->remove($this->item1));
}
......@@ -94,9 +98,9 @@ class VectorTest extends \yiiunit\TestCase
{
$this->vector->add($this->item3);
$this->vector->removeAt(1);
$this->assertEquals(-1,$this->vector->indexOf($this->item2));
$this->assertEquals(1,$this->vector->indexOf($this->item3));
$this->assertEquals(0,$this->vector->indexOf($this->item1));
$this->assertEquals(-1, $this->vector->indexOf($this->item2));
$this->assertEquals(1, $this->vector->indexOf($this->item3));
$this->assertEquals(0, $this->vector->indexOf($this->item1));
$this->setExpectedException('yii\base\InvalidParamException');
$this->vector->removeAt(2);
}
......@@ -105,15 +109,15 @@ class VectorTest extends \yiiunit\TestCase
{
$this->vector->add($this->item3);
$this->vector->removeAll();
$this->assertEquals(0,$this->vector->getCount());
$this->assertEquals(-1,$this->vector->indexOf($this->item1));
$this->assertEquals(-1,$this->vector->indexOf($this->item2));
$this->assertEquals(0, $this->vector->getCount());
$this->assertEquals(-1, $this->vector->indexOf($this->item1));
$this->assertEquals(-1, $this->vector->indexOf($this->item2));
$this->vector->add($this->item3);
$this->vector->removeAll(true);
$this->assertEquals(0,$this->vector->getCount());
$this->assertEquals(-1,$this->vector->indexOf($this->item1));
$this->assertEquals(-1,$this->vector->indexOf($this->item2));
$this->assertEquals(0, $this->vector->getCount());
$this->assertEquals(-1, $this->vector->indexOf($this->item1));
$this->assertEquals(-1, $this->vector->indexOf($this->item2));
}
public function testHas()
......@@ -125,30 +129,32 @@ class VectorTest extends \yiiunit\TestCase
public function testIndexOf()
{
$this->assertEquals(0,$this->vector->indexOf($this->item1));
$this->assertEquals(1,$this->vector->indexOf($this->item2));
$this->assertEquals(-1,$this->vector->indexOf($this->item3));
$this->assertEquals(0, $this->vector->indexOf($this->item1));
$this->assertEquals(1, $this->vector->indexOf($this->item2));
$this->assertEquals(-1, $this->vector->indexOf($this->item3));
}
public function testFromArray()
{
$array=array($this->item3,$this->item1);
$array = array($this->item3, $this->item1);
$this->vector->copyFrom($array);
$this->assertTrue(count($array)==2 && $this->vector[0]===$this->item3 && $this->vector[1]===$this->item1);
$this->assertTrue(count($array) == 2 && $this->vector[0] === $this->item3 && $this->vector[1] === $this->item1);
$this->setExpectedException('yii\base\InvalidParamException');
$this->vector->copyFrom($this);
}
public function testMergeWith()
{
$array=array($this->item3,$this->item1);
$array = array($this->item3, $this->item1);
$this->vector->mergeWith($array);
$this->assertTrue($this->vector->getCount()==4 && $this->vector[0]===$this->item1 && $this->vector[3]===$this->item1);
$this->assertTrue($this->vector->getCount() == 4 && $this->vector[0] === $this->item1 &&
$this->vector[3] === $this->item1);
$a=array(1);
$vector=new Vector($a);
$a = array(1);
$vector = new Vector($a);
$this->vector->mergeWith($vector);
$this->assertTrue($this->vector->getCount()==5 && $this->vector[0]===$this->item1 && $this->vector[3]===$this->item1 && $this->vector[4]===1);
$this->assertTrue($this->vector->getCount() == 5 && $this->vector[0] === $this->item1 &&
$this->vector[3] === $this->item1 && $this->vector[4] === 1);
$this->setExpectedException('yii\base\InvalidParamException');
$this->vector->mergeWith($this);
......@@ -156,37 +162,40 @@ class VectorTest extends \yiiunit\TestCase
public function testToArray()
{
$array=$this->vector->toArray();
$this->assertTrue(count($array)==2 && $array[0]===$this->item1 && $array[1]===$this->item2);
$array = $this->vector->toArray();
$this->assertTrue(count($array) == 2 && $array[0] === $this->item1 && $array[1] === $this->item2);
}
public function testArrayRead()
{
$this->assertTrue($this->vector[0]===$this->item1);
$this->assertTrue($this->vector[1]===$this->item2);
$this->assertTrue($this->vector[0] === $this->item1);
$this->assertTrue($this->vector[1] === $this->item2);
$this->setExpectedException('yii\base\InvalidParamException');
$a=$this->vector[2];
$a = $this->vector[2];
}
public function testGetIterator()
{
$n=0;
$found=0;
foreach($this->vector as $index=>$item)
{
foreach($this->vector as $a=>$b); // test of iterator
$n = 0;
$found = 0;
foreach ($this->vector as $index => $item) {
foreach ($this->vector as $a => $b) {
// test of iterator
}
$n++;
if($index===0 && $item===$this->item1)
if ($index === 0 && $item === $this->item1) {
$found++;
if($index===1 && $item===$this->item2)
}
if ($index === 1 && $item === $this->item2) {
$found++;
}
}
$this->assertTrue($n==2 && $found==2);
$this->assertTrue($n == 2 && $found == 2);
}
public function testArrayMisc()
{
$this->assertEquals($this->vector->Count,count($this->vector));
$this->assertEquals($this->vector->Count, count($this->vector));
$this->assertTrue(isset($this->vector[1]));
$this->assertFalse(isset($this->vector[2]));
}
......
......@@ -15,9 +15,9 @@ class ApcCacheTest extends CacheTest
*/
protected function getCacheInstance()
{
if(!extension_loaded("apc")) {
if (!extension_loaded("apc")) {
$this->markTestSkipped("APC not installed. Skipping.");
} else if ('cli' === PHP_SAPI && !ini_get('apc.enable_cli')) {
} elseif ('cli' === PHP_SAPI && !ini_get('apc.enable_cli')) {
$this->markTestSkipped("APC cli is not enabled. Skipping.");
}
......@@ -25,7 +25,7 @@ class ApcCacheTest extends CacheTest
$this->markTestSkipped("APC is installed but not enabled. Skipping.");
}
if($this->_cacheInstance === null) {
if ($this->_cacheInstance === null) {
$this->_cacheInstance = new ApcCache();
}
return $this->_cacheInstance;
......
......@@ -13,6 +13,12 @@ abstract class CacheTest extends TestCase
*/
abstract protected function getCacheInstance();
protected function setUp()
{
parent::setUp();
$this->mockApplication();
}
/**
* @return Cache
*/
......
......@@ -17,6 +17,8 @@ class DbCacheTest extends CacheTest
$this->markTestSkipped('pdo and pdo_mysql extensions are required.');
}
parent::setUp();
$this->getConnection()->createCommand("
CREATE TABLE IF NOT EXISTS tbl_cache (
id char(128) NOT NULL,
......@@ -34,8 +36,9 @@ class DbCacheTest extends CacheTest
*/
function getConnection($reset = true)
{
if($this->_connection === null) {
$params = $this->getParam('mysql');
if ($this->_connection === null) {
$databases = $this->getParam('databases');
$params = $databases['mysql'];
$db = new \yii\db\Connection;
$db->dsn = $params['dsn'];
$db->username = $params['username'];
......@@ -60,7 +63,7 @@ class DbCacheTest extends CacheTest
*/
protected function getCacheInstance()
{
if($this->_cacheInstance === null) {
if ($this->_cacheInstance === null) {
$this->_cacheInstance = new DbCache(array(
'db' => $this->getConnection(),
));
......
......@@ -15,7 +15,7 @@ class FileCacheTest extends CacheTest
*/
protected function getCacheInstance()
{
if($this->_cacheInstance === null) {
if ($this->_cacheInstance === null) {
$this->_cacheInstance = new FileCache(array(
'cachePath' => '@yiiunit/runtime/cache',
));
......
......@@ -15,11 +15,11 @@ class MemCacheTest extends CacheTest
*/
protected function getCacheInstance()
{
if(!extension_loaded("memcache")) {
if (!extension_loaded("memcache")) {
$this->markTestSkipped("memcache not installed. Skipping.");
}
if($this->_cacheInstance === null) {
if ($this->_cacheInstance === null) {
$this->_cacheInstance = new MemCache();
}
return $this->_cacheInstance;
......
......@@ -15,11 +15,11 @@ class MemCachedTest extends CacheTest
*/
protected function getCacheInstance()
{
if(!extension_loaded("memcached")) {
if (!extension_loaded("memcached")) {
$this->markTestSkipped("memcached not installed. Skipping.");
}
if($this->_cacheInstance === null) {
if ($this->_cacheInstance === null) {
$this->_cacheInstance = new MemCache(array(
'useMemcached' => true,
));
......
......@@ -15,15 +15,15 @@ class WinCacheTest extends CacheTest
*/
protected function getCacheInstance()
{
if(!extension_loaded('wincache')) {
if (!extension_loaded('wincache')) {
$this->markTestSkipped("Wincache not installed. Skipping.");
}
if(!ini_get('wincache.ucenabled')) {
if (!ini_get('wincache.ucenabled')) {
$this->markTestSkipped("Wincache user cache disabled. Skipping.");
}
if($this->_cacheInstance === null) {
if ($this->_cacheInstance === null) {
$this->_cacheInstance = new WinCache();
}
return $this->_cacheInstance;
......
......@@ -15,11 +15,11 @@ class XCacheTest extends CacheTest
*/
protected function getCacheInstance()
{
if(!function_exists("xcache_isset")) {
if (!function_exists("xcache_isset")) {
$this->markTestSkipped("XCache not installed. Skipping.");
}
if($this->_cacheInstance === null) {
if ($this->_cacheInstance === null) {
$this->_cacheInstance = new XCache();
}
return $this->_cacheInstance;
......
......@@ -15,11 +15,11 @@ class ZendDataCacheTest extends CacheTest
*/
protected function getCacheInstance()
{
if(!function_exists("zend_shm_cache_store")) {
if (!function_exists("zend_shm_cache_store")) {
$this->markTestSkipped("Zend Data cache not installed. Skipping.");
}
if($this->_cacheInstance === null) {
if ($this->_cacheInstance === null) {
$this->_cacheInstance = new ZendDataCache();
}
return $this->_cacheInstance;
......
......@@ -10,10 +10,11 @@ use yiiunit\data\ar\OrderItem;
use yiiunit\data\ar\Order;
use yiiunit\data\ar\Item;
class ActiveRecordTest extends \yiiunit\MysqlTestCase
class ActiveRecordTest extends \yiiunit\DatabaseTestCase
{
public function setUp()
protected function setUp()
{
parent::setUp();
ActiveRecord::$db = $this->getConnection();
}
......
......@@ -7,7 +7,7 @@ use yii\db\Command;
use yii\db\Query;
use yii\db\DataReader;
class CommandTest extends \yiiunit\MysqlTestCase
class CommandTest extends \yiiunit\DatabaseTestCase
{
function testConstruct()
{
......@@ -140,7 +140,7 @@ class CommandTest extends \yiiunit\MysqlTestCase
$db = $this->getConnection();
// bindParam
$sql = 'INSERT INTO tbl_customer(email,name,address) VALUES (:email, :name, :address)';
$sql = 'INSERT INTO tbl_customer(email, name, address) VALUES (:email, :name, :address)';
$command = $db->createCommand($sql);
$email = 'user4@example.com';
$name = 'user4';
......
......@@ -4,12 +4,12 @@ namespace yiiunit\framework\db;
use yii\db\Connection;
class ConnectionTest extends \yiiunit\MysqlTestCase
class ConnectionTest extends \yiiunit\DatabaseTestCase
{
function testConstruct()
{
$connection = $this->getConnection(false);
$params = $this->getParam('mysql');
$params = $this->database;
$this->assertEquals($params['dsn'], $connection->dsn);
$this->assertEquals($params['username'], $connection->username);
......@@ -18,7 +18,7 @@ class ConnectionTest extends \yiiunit\MysqlTestCase
function testOpenClose()
{
$connection = $this->getConnection(false);
$connection = $this->getConnection(false, false);
$this->assertFalse($connection->isActive);
$this->assertEquals(null, $connection->pdo);
......@@ -39,9 +39,8 @@ class ConnectionTest extends \yiiunit\MysqlTestCase
function testGetDriverName()
{
$connection = $this->getConnection(false);
$this->assertEquals('mysql', $connection->driverName);
$this->assertFalse($connection->isActive);
$connection = $this->getConnection(false, false);
$this->assertEquals($this->driverName, $connection->driverName);
}
function testQuoteValue()
......
......@@ -7,7 +7,7 @@ use yii\db\Command;
use yii\db\Query;
use yii\db\DataReader;
class QueryTest extends \yiiunit\MysqlTestCase
class QueryTest extends \yiiunit\DatabaseTestCase
{
function testSelect()
{
......@@ -20,7 +20,7 @@ class QueryTest extends \yiiunit\MysqlTestCase
$query = new Query;
$query->select('id, name', 'something')->distinct(true);
$this->assertEquals(array('id','name'), $query->select);
$this->assertEquals(array('id', 'name'), $query->select);
$this->assertTrue($query->distinct);
$this->assertEquals('something', $query->selectOption);
}
......
<?php
namespace yiiunit\framework\db\sqlite;
class SqliteActiveRecordTest extends \yiiunit\framework\db\ActiveRecordTest
{
protected function setUp()
{
$this->driverName = 'sqlite';
parent::setUp();
}
}
<?php
namespace yiiunit\framework\db\sqlite;
class SqliteCommandTest extends \yiiunit\framework\db\CommandTest
{
protected function setUp()
{
$this->driverName = 'sqlite';
parent::setUp();
}
public function testAutoQuoting()
{
$db = $this->getConnection(false);
$sql = 'SELECT [[id]], [[t.name]] FROM {{tbl_customer}} t';
$command = $db->createCommand($sql);
$this->assertEquals("SELECT \"id\", 't'.\"name\" FROM 'tbl_customer' t", $command->sql);
}
}
<?php
namespace yiiunit\framework\db\sqlite;
class SqliteConnectionTest extends \yiiunit\framework\db\ConnectionTest
{
protected function setUp()
{
$this->driverName = 'sqlite';
parent::setUp();
}
public function testConstruct()
{
$connection = $this->getConnection(false);
$params = $this->database;
$this->assertEquals($params['dsn'], $connection->dsn);
}
public function testQuoteValue()
{
$connection = $this->getConnection(false);
$this->assertEquals(123, $connection->quoteValue(123));
$this->assertEquals("'string'", $connection->quoteValue('string'));
$this->assertEquals("'It''s interesting'", $connection->quoteValue("It's interesting"));
}
public function testQuoteTableName()
{
$connection = $this->getConnection(false);
$this->assertEquals("'table'", $connection->quoteTableName('table'));
$this->assertEquals("'schema'.'table'", $connection->quoteTableName('schema.table'));
$this->assertEquals('{{table}}', $connection->quoteTableName('{{table}}'));
$this->assertEquals('(table)', $connection->quoteTableName('(table)'));
}
public function testQuoteColumnName()
{
$connection = $this->getConnection(false);
$this->assertEquals('"column"', $connection->quoteColumnName('column'));
$this->assertEquals("'table'.\"column\"", $connection->quoteColumnName('table.column'));
$this->assertEquals('[[column]]', $connection->quoteColumnName('[[column]]'));
$this->assertEquals('{{column}}', $connection->quoteColumnName('{{column}}'));
$this->assertEquals('(column)', $connection->quoteColumnName('(column)'));
}
}
<?php
/**
* Created by JetBrains PhpStorm.
* User: RusMaxim
* Date: 09.05.13
* Time: 21:41
* To change this template use File | Settings | File Templates.
*/
namespace yiiunit\framework\db\sqlite;
class SqliteQueryTest extends \yiiunit\framework\db\QueryTest
{
protected function setUp()
{
$this->driverName = 'sqlite';
parent::setUp();
}
}
......@@ -12,6 +12,16 @@ class ArrayHelperTest extends \yii\test\TestCase
}
public function testRemove()
{
$array = array('name' => 'b', 'age' => 3);
$name = ArrayHelper::remove($array, 'name');
$this->assertEquals($name, 'b');
$this->assertEquals($array, array('age' => 3));
}
public function testMultisort()
{
// single key
......
......@@ -4,15 +4,14 @@ namespace yiiunit\framework\helpers;
use Yii;
use yii\helpers\Html;
use yii\web\Application;
use yiiunit\TestCase;
class HtmlTest extends \yii\test\TestCase
class HtmlTest extends TestCase
{
public function setUp()
protected function setUp()
{
new Application(array(
'id' => 'test',
'basePath' => '@yiiunit/runtime',
parent::setUp();
$this->mockApplication(array(
'components' => array(
'request' => array(
'class' => 'yii\web\Request',
......@@ -30,11 +29,6 @@ class HtmlTest extends \yii\test\TestCase
$this->assertEquals($expected, $actual);
}
public function tearDown()
{
Yii::$app = null;
}
public function testEncode()
{
$this->assertEquals("a&lt;&gt;&amp;&quot;&#039;", Html::encode("a<>&\"'"));
......
......@@ -4,7 +4,7 @@
namespace yiiunit\framework\helpers;
use yii\helpers\Json;
use yii\helpers\JsExpression;
use yii\web\JsExpression;
class JsonTest extends \yii\test\TestCase
{
......
......@@ -40,7 +40,7 @@ class StringHelperTest extends \yii\test\TestCase
'car' => 'cars',
);
foreach($testData as $testIn => $testOut) {
foreach ($testData as $testIn => $testOut) {
$this->assertEquals($testOut, StringHelper::pluralize($testIn));
$this->assertEquals(ucfirst($testOut), ucfirst(StringHelper::pluralize($testIn)));
}
......@@ -70,4 +70,48 @@ class StringHelperTest extends \yii\test\TestCase
$this->assertEquals('PostTag', StringHelper::id2camel('post-tag'));
$this->assertEquals('PostTag', StringHelper::id2camel('post_tag', '_'));
}
public function testBasename()
{
$this->assertEquals('', StringHelper::basename(''));
$this->assertEquals('file', StringHelper::basename('file'));
$this->assertEquals('file.test', StringHelper::basename('file.test', '.test2'));
$this->assertEquals('file', StringHelper::basename('file.test', '.test'));
$this->assertEquals('file', StringHelper::basename('/file'));
$this->assertEquals('file.test', StringHelper::basename('/file.test', '.test2'));
$this->assertEquals('file', StringHelper::basename('/file.test', '.test'));
$this->assertEquals('file', StringHelper::basename('/path/to/file'));
$this->assertEquals('file.test', StringHelper::basename('/path/to/file.test', '.test2'));
$this->assertEquals('file', StringHelper::basename('/path/to/file.test', '.test'));
$this->assertEquals('file', StringHelper::basename('\file'));
$this->assertEquals('file.test', StringHelper::basename('\file.test', '.test2'));
$this->assertEquals('file', StringHelper::basename('\file.test', '.test'));
$this->assertEquals('file', StringHelper::basename('C:\file'));
$this->assertEquals('file.test', StringHelper::basename('C:\file.test', '.test2'));
$this->assertEquals('file', StringHelper::basename('C:\file.test', '.test'));
$this->assertEquals('file', StringHelper::basename('C:\path\to\file'));
$this->assertEquals('file.test', StringHelper::basename('C:\path\to\file.test', '.test2'));
$this->assertEquals('file', StringHelper::basename('C:\path\to\file.test', '.test'));
// mixed paths
$this->assertEquals('file.test', StringHelper::basename('/path\to/file.test'));
$this->assertEquals('file.test', StringHelper::basename('/path/to\file.test'));
$this->assertEquals('file.test', StringHelper::basename('\path/to\file.test'));
// \ and / in suffix
$this->assertEquals('file', StringHelper::basename('/path/to/filete/st', 'te/st'));
$this->assertEquals('st', StringHelper::basename('/path/to/filete/st', 'te\st'));
$this->assertEquals('file', StringHelper::basename('/path/to/filete\st', 'te\st'));
$this->assertEquals('st', StringHelper::basename('/path/to/filete\st', 'te/st'));
// http://www.php.net/manual/en/function.basename.php#72254
$this->assertEquals('foo', StringHelper::basename('/bar/foo/'));
$this->assertEquals('foo', StringHelper::basename('\\bar\\foo\\'));
}
}
......@@ -7,6 +7,9 @@ class VarDumperTest extends \yii\test\TestCase
public function testDumpObject()
{
$obj = new \StdClass();
ob_start();
VarDumper::dump($obj);
$this->assertEquals("stdClass#1\n(\n)", ob_get_contents());
ob_end_clean();
}
}
<?php
namespace yiiunit\framework\i18n;
use yii\i18n\GettextMessageSource;
use yiiunit\TestCase;
class GettextMessageSourceTest extends TestCase
{
public function testLoadMessages()
{
$this->markTestSkipped();
}
}
<?php
namespace yiiunit\framework\i18n;
use yii\i18n\GettextMoFile;
use yiiunit\TestCase;
class GettextMoFileTest extends TestCase
{
public function testLoad()
{
$moFile = new GettextMoFile();
$moFilePath = __DIR__ . '/../../data/i18n/test.mo';
$context1 = $moFile->load($moFilePath, 'context1');
$context2 = $moFile->load($moFilePath, 'context2');
// item count
$this->assertCount(3, $context1);
$this->assertCount(2, $context2);
// original messages
$this->assertArrayNotHasKey("Missing\n\r\t\"translation.", $context1);
$this->assertArrayHasKey("Aliquam tempus elit vel purus molestie placerat. In sollicitudin tincidunt\naliquet. Integer tincidunt gravida tempor. In convallis blandit dui vel malesuada.\nNunc vel sapien nunc, a pretium nulla.", $context1);
$this->assertArrayHasKey("String number two.", $context1);
$this->assertArrayHasKey("Nunc vel sapien nunc, a pretium nulla.\nPellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.", $context1);
$this->assertArrayHasKey("The other\n\ncontext.\n", $context2);
$this->assertArrayHasKey("test1\\ntest2\n\\\ntest3", $context2);
// translated messages
$this->assertFalse(in_array("", $context1));
$this->assertTrue(in_array("Олицетворение однократно. Представленный лексико-семантический анализ является\nпсихолингвистическим в своей основе, но механизм сочленений полидисперсен. Впечатление\nоднократно. Различное расположение выбирает сюжетный механизм сочленений.", $context1));
$this->assertTrue(in_array('Строка номер два.', $context1));
$this->assertTrue(in_array('Короткий перевод.', $context1));
$this->assertTrue(in_array("Другой\n\nконтекст.\n", $context2));
$this->assertTrue(in_array("тест1\\nтест2\n\\\nтест3", $context2));
}
public function testSave()
{
// initial data
$s = chr(4);
$messages = array(
'Hello!' => 'Привет!',
"context1{$s}Hello?" => 'Привет?',
'Hello!?' => '',
"context1{$s}Hello!?!" => '',
"context2{$s}\"Quotes\"" => '"Кавычки"',
"context2{$s}\nNew lines\n" => "\nПереносы строк\n",
"context2{$s}\tTabs\t" => "\tТабы\t",
"context2{$s}\rCarriage returns\r" => "\rВозвраты кареток\r",
);
// create temporary directory and dump messages
$poFileDirectory = __DIR__ . '/../../runtime/i18n';
if (!is_dir($poFileDirectory)) {
mkdir($poFileDirectory);
}
if (is_file($poFileDirectory . '/test.mo')) {
unlink($poFileDirectory . '/test.mo');
}
$moFile = new GettextMoFile();
$moFile->save($poFileDirectory . '/test.mo', $messages);
// load messages
$context1 = $moFile->load($poFileDirectory . '/test.mo', 'context1');
$context2 = $moFile->load($poFileDirectory . '/test.mo', 'context2');
// context1
$this->assertCount(2, $context1);
$this->assertArrayHasKey('Hello?', $context1);
$this->assertTrue(in_array('Привет?', $context1));
$this->assertArrayHasKey('Hello!?!', $context1);
$this->assertTrue(in_array('', $context1));
// context2
$this->assertCount(4, $context2);
$this->assertArrayHasKey("\"Quotes\"", $context2);
$this->assertTrue(in_array('"Кавычки"', $context2));
$this->assertArrayHasKey("\nNew lines\n", $context2);
$this->assertTrue(in_array("\nПереносы строк\n", $context2));
$this->assertArrayHasKey("\tTabs\t", $context2);
$this->assertTrue(in_array("\tТабы\t", $context2));
$this->assertArrayHasKey("\rCarriage returns\r", $context2);
$this->assertTrue(in_array("\rВозвраты кареток\r", $context2));
}
}
<?php
namespace yiiunit\framework\i18n;
use yii\i18n\GettextPoFile;
use yiiunit\TestCase;
class GettextPoFileTest extends TestCase
{
public function testLoad()
{
$poFile = new GettextPoFile();
$poFilePath = __DIR__ . '/../../data/i18n/test.po';
$context1 = $poFile->load($poFilePath, 'context1');
$context2 = $poFile->load($poFilePath, 'context2');
// item count
$this->assertCount(4, $context1);
$this->assertCount(2, $context2);
// original messages
$this->assertArrayHasKey("Missing\n\r\t\"translation.", $context1);
$this->assertArrayHasKey("Aliquam tempus elit vel purus molestie placerat. In sollicitudin tincidunt\naliquet. Integer tincidunt gravida tempor. In convallis blandit dui vel malesuada.\nNunc vel sapien nunc, a pretium nulla.", $context1);
$this->assertArrayHasKey("String number two.", $context1);
$this->assertArrayHasKey("Nunc vel sapien nunc, a pretium nulla.\nPellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.", $context1);
$this->assertArrayHasKey("The other\n\ncontext.\n", $context2);
$this->assertArrayHasKey("test1\\\ntest2\n\\\\\ntest3", $context2);
// translated messages
$this->assertTrue(in_array("", $context1));
$this->assertTrue(in_array("Олицетворение однократно. Представленный лексико-семантический анализ является\nпсихолингвистическим в своей основе, но механизм сочленений полидисперсен. Впечатление\nоднократно. Различное расположение выбирает сюжетный механизм сочленений.", $context1));
$this->assertTrue(in_array('Строка номер два.', $context1));
$this->assertTrue(in_array('Короткий перевод.', $context1));
$this->assertTrue(in_array("Другой\n\nконтекст.\n", $context2));
$this->assertTrue(in_array("тест1\\\nтест2\n\\\\\nтест3", $context2));
}
public function testSave()
{
// initial data
$s = chr(4);
$messages = array(
'Hello!' => 'Привет!',
"context1{$s}Hello?" => 'Привет?',
'Hello!?' => '',
"context1{$s}Hello!?!" => '',
"context2{$s}\"Quotes\"" => '"Кавычки"',
"context2{$s}\nNew lines\n" => "\nПереносы строк\n",
"context2{$s}\tTabs\t" => "\tТабы\t",
"context2{$s}\rCarriage returns\r" => "\rВозвраты кареток\r",
);
// create temporary directory and dump messages
$poFileDirectory = __DIR__ . '/../../runtime/i18n';
if (!is_dir($poFileDirectory)) {
mkdir($poFileDirectory);
}
if (is_file($poFileDirectory . '/test.po')) {
unlink($poFileDirectory . '/test.po');
}
$poFile = new GettextPoFile();
$poFile->save($poFileDirectory . '/test.po', $messages);
// load messages
$context1 = $poFile->load($poFileDirectory . '/test.po', 'context1');
$context2 = $poFile->load($poFileDirectory . '/test.po', 'context2');
// context1
$this->assertCount(2, $context1);
$this->assertArrayHasKey('Hello?', $context1);
$this->assertTrue(in_array('Привет?', $context1));
$this->assertArrayHasKey('Hello!?!', $context1);
$this->assertTrue(in_array('', $context1));
// context2
$this->assertCount(4, $context2);
$this->assertArrayHasKey("\"Quotes\"", $context2);
$this->assertTrue(in_array('"Кавычки"', $context2));
$this->assertArrayHasKey("\nNew lines\n", $context2);
$this->assertTrue(in_array("\nПереносы строк\n", $context2));
$this->assertArrayHasKey("\tTabs\t", $context2);
$this->assertTrue(in_array("\tТабы\t", $context2));
$this->assertArrayHasKey("\rCarriage returns\r", $context2);
$this->assertTrue(in_array("\rВозвраты кареток\r", $context2));
}
}
<?php
namespace yiiunit\framework\rbac;
use yii\rbac\Assignment;
use yii\rbac\Item;
use yiiunit\TestCase;
abstract class ManagerTestBase extends TestCase
{
/** @var \yii\rbac\PhpManager|\yii\rbac\DbManager */
protected $auth;
public function testCreateItem()
{
$type = Item::TYPE_TASK;
$name = 'editUser';
$description = 'edit a user';
$bizRule = 'checkUserIdentity()';
$data = array(1, 2, 3);
$item = $this->auth->createItem($name, $type, $description, $bizRule, $data);
$this->assertTrue($item instanceof Item);
$this->assertEquals($item->type, $type);
$this->assertEquals($item->name, $name);
$this->assertEquals($item->description, $description);
$this->assertEquals($item->bizRule, $bizRule);
$this->assertEquals($item->data, $data);
// test shortcut
$name2 = 'createUser';
$item2 = $this->auth->createRole($name2, $description, $bizRule, $data);
$this->assertEquals($item2->type, Item::TYPE_ROLE);
// test adding an item with the same name
$this->setExpectedException('Exception');
$this->auth->createItem($name, $type, $description, $bizRule, $data);
}
public function testGetItem()
{
$this->assertTrue($this->auth->getItem('readPost') instanceof Item);
$this->assertTrue($this->auth->getItem('reader') instanceof Item);
$this->assertNull($this->auth->getItem('unknown'));
}
public function testRemoveAuthItem()
{
$this->assertTrue($this->auth->getItem('updatePost') instanceof Item);
$this->assertTrue($this->auth->removeItem('updatePost'));
$this->assertNull($this->auth->getItem('updatePost'));
$this->assertFalse($this->auth->removeItem('updatePost'));
}
public function testChangeItemName()
{
$item = $this->auth->getItem('readPost');
$this->assertTrue($item instanceof Item);
$this->assertTrue($this->auth->hasItemChild('reader', 'readPost'));
$item->name = 'readPost2';
$this->assertNull($this->auth->getItem('readPost'));
$this->assertEquals($this->auth->getItem('readPost2'), $item);
$this->assertFalse($this->auth->hasItemChild('reader', 'readPost'));
$this->assertTrue($this->auth->hasItemChild('reader', 'readPost2'));
}
public function testAddItemChild()
{
$this->auth->addItemChild('createPost', 'updatePost');
// test adding upper level item to lower one
$this->setExpectedException('Exception');
$this->auth->addItemChild('readPost', 'reader');
}
public function testAddItemChild2()
{
// test adding inexistent items
$this->setExpectedException('Exception');
$this->assertFalse($this->auth->addItemChild('createPost2', 'updatePost'));
}
public function testRemoveItemChild()
{
$this->assertTrue($this->auth->hasItemChild('reader', 'readPost'));
$this->assertTrue($this->auth->removeItemChild('reader', 'readPost'));
$this->assertFalse($this->auth->hasItemChild('reader', 'readPost'));
$this->assertFalse($this->auth->removeItemChild('reader', 'readPost'));
}
public function testGetItemChildren()
{
$this->assertEquals(array(), $this->auth->getItemChildren('readPost'));
$children = $this->auth->getItemChildren('author');
$this->assertEquals(3, count($children));
$this->assertTrue(reset($children) instanceof Item);
}
public function testAssign()
{
$auth = $this->auth->assign('new user', 'createPost', 'rule', 'data');
$this->assertTrue($auth instanceof Assignment);
$this->assertEquals($auth->userId, 'new user');
$this->assertEquals($auth->itemName, 'createPost');
$this->assertEquals($auth->bizRule, 'rule');
$this->assertEquals($auth->data, 'data');
$this->setExpectedException('Exception');
$this->auth->assign('new user', 'createPost2', 'rule', 'data');
}
public function testRevoke()
{
$this->assertTrue($this->auth->isAssigned('author B', 'author'));
$auth = $this->auth->getAssignment('author B', 'author');
$this->assertTrue($auth instanceof Assignment);
$this->assertTrue($this->auth->revoke('author B', 'author'));
$this->assertFalse($this->auth->isAssigned('author B', 'author'));
$this->assertFalse($this->auth->revoke('author B', 'author'));
}
public function testGetAssignments()
{
$this->auth->assign('author B', 'deletePost');
$auths = $this->auth->getAssignments('author B');
$this->assertEquals(2, count($auths));
$this->assertTrue(reset($auths) instanceof Assignment);
}
public function testGetItems()
{
$this->assertEquals(count($this->auth->getRoles()), 4);
$this->assertEquals(count($this->auth->getOperations()), 4);
$this->assertEquals(count($this->auth->getTasks()), 1);
$this->assertEquals(count($this->auth->getItems()), 9);
$this->assertEquals(count($this->auth->getItems('author B', null)), 1);
$this->assertEquals(count($this->auth->getItems('author C', null)), 0);
$this->assertEquals(count($this->auth->getItems('author B', Item::TYPE_ROLE)), 1);
$this->assertEquals(count($this->auth->getItems('author B', Item::TYPE_OPERATION)), 0);
}
public function testClearAll()
{
$this->auth->clearAll();
$this->assertEquals(count($this->auth->getRoles()), 0);
$this->assertEquals(count($this->auth->getOperations()), 0);
$this->assertEquals(count($this->auth->getTasks()), 0);
$this->assertEquals(count($this->auth->getItems()), 0);
$this->assertEquals(count($this->auth->getAssignments('author B')), 0);
}
public function testClearAssignments()
{
$this->auth->clearAssignments();
$this->assertEquals(count($this->auth->getAssignments('author B')), 0);
}
public function testDetectLoop()
{
$this->setExpectedException('Exception');
$this->auth->addItemChild('readPost', 'readPost');
}
public function testExecuteBizRule()
{
$this->assertTrue($this->auth->executeBizRule(null, array(), null));
$this->assertTrue($this->auth->executeBizRule('return 1 == true;', array(), null));
$this->assertTrue($this->auth->executeBizRule('return $params[0] == $params[1];', array(1, '1'), null));
$this->assertFalse($this->auth->executeBizRule('invalid', array(), null));
}
public function testCheckAccess()
{
$results = array(
'reader A' => array(
'createPost' => false,
'readPost' => true,
'updatePost' => false,
'updateOwnPost' => false,
'deletePost' => false,
),
'author B' => array(
'createPost' => true,
'readPost' => true,
'updatePost' => true,
'updateOwnPost' => true,
'deletePost' => false,
),
'editor C' => array(
'createPost' => false,
'readPost' => true,
'updatePost' => true,
'updateOwnPost' => false,
'deletePost' => false,
),
'admin D' => array(
'createPost' => true,
'readPost' => true,
'updatePost' => true,
'updateOwnPost' => false,
'deletePost' => true,
),
);
$params = array('authorID' => 'author B');
foreach (array('reader A', 'author B', 'editor C', 'admin D') as $user) {
$params['userID'] = $user;
foreach (array('createPost', 'readPost', 'updatePost', 'updateOwnPost', 'deletePost') as $operation) {
$result = $this->auth->checkAccess($user, $operation, $params);
$this->assertEquals($results[$user][$operation], $result);
}
}
}
protected function prepareData()
{
$this->auth->createOperation('createPost', 'create a post');
$this->auth->createOperation('readPost', 'read a post');
$this->auth->createOperation('updatePost', 'update a post');
$this->auth->createOperation('deletePost', 'delete a post');
$task = $this->auth->createTask('updateOwnPost', 'update a post by author himself', 'return $params["authorID"] == $params["userID"];');
$task->addChild('updatePost');
$role = $this->auth->createRole('reader');
$role->addChild('readPost');
$role = $this->auth->createRole('author');
$role->addChild('reader');
$role->addChild('createPost');
$role->addChild('updateOwnPost');
$role = $this->auth->createRole('editor');
$role->addChild('reader');
$role->addChild('updatePost');
$role = $this->auth->createRole('admin');
$role->addChild('editor');
$role->addChild('author');
$role->addChild('deletePost');
$this->auth->assign('reader A', 'reader');
$this->auth->assign('author B', 'author');
$this->auth->assign('editor C', 'editor');
$this->auth->assign('admin D', 'admin');
}
}
<?php
namespace yiiunit\framework\rbac;
use Yii;
use yii\rbac\PhpManager;
//require_once(__DIR__ . '/ManagerTestBase.php');
class PhpManagerTest extends ManagerTestBase
{
protected function setUp()
{
parent::setUp();
$this->mockApplication();
$authFile = Yii::$app->getRuntimePath() . '/rbac.php';
@unlink($authFile);
$this->auth = new PhpManager;
$this->auth->authFile = $authFile;
$this->auth->init();
$this->prepareData();
}
protected function tearDown()
{
parent::tearDown();
@unlink($this->auth->authFile);
}
public function testSaveLoad()
{
$this->auth->save();
$this->auth->clearAll();
$this->auth->load();
$this->testCheckAccess();
}
}
<?php
require(__DIR__ . '/../../../framework/yii.php');
require(__DIR__ . '/../../../yii/Yii.php');
$application = new yii\web\Application('test', __DIR__ . '/protected');
$application->run();
......@@ -18,7 +18,7 @@ require(__DIR__ . '/YiiBase.php');
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class Yii extends YiiBase
class Yii extends \yii\YiiBase
{
}
......
......@@ -4,6 +4,8 @@
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yii;
use yii\base\Exception;
use yii\base\InvalidConfigException;
use yii\base\InvalidParamException;
......@@ -60,7 +62,7 @@ class YiiBase
*/
public static $enableIncludePath = true;
/**
* @var yii\console\Application|yii\web\Application the application instance
* @var \yii\console\Application|\yii\web\Application the application instance
*/
public static $app;
/**
......@@ -156,8 +158,8 @@ class YiiBase
{
foreach ($namespaces as $name => $path) {
if ($name !== '') {
$name = '@' . str_replace('\\', '/', $name);
static::setAlias($name, $path);
$name = trim(strtr($name, array('\\' => '/', '_' => '/')), '/');
static::setAlias('@' . $name, rtrim($path, '/\\') . '/' . $name);
}
}
}
......@@ -368,7 +370,8 @@ class YiiBase
include($classFile);
if (class_exists($className, false) || interface_exists($className, false)) {
if (class_exists($className, false) || interface_exists($className, false) ||
function_exists('trait_exists') && trait_exists($className, false)) {
return true;
} else {
throw new UnknownClassException("Unable to find '$className' in file: $classFile");
......@@ -449,12 +452,12 @@ class YiiBase
}
$args = func_get_args();
array_shift($args); // remove $config
if ($config !== array()) {
if (!empty($config)) {
$args[] = $config;
}
return $reflection->newInstanceArgs($args);
} else {
return $config === array() ? new $class : new $class($config);
return empty($config) ? new $class : new $class($config);
}
}
......
......@@ -28,4 +28,18 @@ return array(
),
'depends' => array('yii', 'yii/validation'),
),
'yii/captcha' => array(
'sourcePath' => __DIR__ . '/assets',
'js' => array(
'yii.captcha.js',
),
'depends' => array('yii'),
),
'yii/debug' => array(
'sourcePath' => __DIR__ . '/assets',
'js' => array(
'yii.debug.js',
),
'depends' => array('yii'),
),
);
......@@ -116,8 +116,8 @@
});
},
options: function() {
return this.data('yiiActiveForm').settings;
data: function() {
return this.data('yiiActiveForm');
},
submitForm: function () {
......@@ -384,4 +384,4 @@
}
};
})(window.jQuery);
\ No newline at end of file
})(window.jQuery);
/**
* Yii Captcha widget.
*
* This is the JavaScript widget used by the yii\widgets\Captcha widget.
*
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
(function ($) {
$.fn.yiiCaptcha = function (method) {
if (methods[method]) {
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
} else if (typeof method === 'object' || !method) {
return methods.init.apply(this, arguments);
} else {
$.error('Method ' + method + ' does not exist on jQuery.yiiCaptcha');
return false;
}
};
var defaults = {
refreshUrl: undefined,
hashKey: undefined
};
var methods = {
init: function (options) {
return this.each(function () {
var $e = $(this);
var settings = $.extend({}, defaults, options || {});
$e.data('yiiCaptcha', {
settings: settings
});
$e.on('click.yiiCaptcha', function() {
methods.refresh.apply($e);
return false;
});
});
},
refresh: function () {
var $e = this,
settings = this.data('yiiCaptcha').settings;
$.ajax({
url: $e.data('yiiCaptcha').settings.refreshUrl,
dataType: 'json',
cache: false,
success: function(data) {
$e.attr('src', data['url']);
$('body').data(settings.hashKey, [data['hash1'], data['hash2']]);
}
});
},
destroy: function () {
return this.each(function () {
$(window).unbind('.yiiCaptcha');
$(this).removeData('yiiCaptcha');
});
},
data: function() {
return this.data('yiiCaptcha');
}
};
})(window.jQuery);
/**
* Yii debug module.
*
* This JavaScript module provides the functions needed by the Yii debug toolbar.
*
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
yii.debug = (function ($) {
return {
load: function (id, url) {
$.ajax({
url: url,
//dataType: 'json',
success: function(data) {
var $e = $('#' + id);
$e.html(data);
}
});
}
};
})(jQuery);
/**
* Yii validation module.
*
* This JavaScript module provides the validation methods for the built-in validaotrs.
* This JavaScript module provides the validation methods for the built-in validators.
*
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
......
......@@ -8,7 +8,6 @@
namespace yii\base;
use Yii;
use yii\helpers\FileHelper;
/**
* Application is the base class for all application classes.
......@@ -85,6 +84,13 @@ class Application extends Module
} else {
throw new InvalidConfigException('The "basePath" configuration is required.');
}
if (isset($config['timeZone'])) {
$this->setTimeZone($config['timeZone']);
unset($config['timeZone']);
} elseif (!ini_get('date.timezone')) {
$this->setTimeZone('UTC');
}
$this->registerErrorHandlers();
$this->registerCoreComponents();
......@@ -223,6 +229,8 @@ class Application extends Module
/**
* Returns the time zone used by this application.
* This is a simple wrapper of PHP function date_default_timezone_get().
* If time zone is not configured in php.ini or application config,
* it will be set to UTC by default.
* @return string the time zone used by this application.
* @see http://php.net/manual/en/function.date-default-timezone-get.php
*/
......@@ -306,12 +314,12 @@ class Application extends Module
}
/**
* @return null|Component
* @todo
* Returns the auth manager for this application.
* @return \yii\rbac\Manager the auth manager for this application.
*/
public function getAuthManager()
{
return $this->getComponent('auth');
return $this->getComponent('authManager');
}
/**
......
......@@ -8,7 +8,6 @@
namespace yii\base;
use Yii;
use yii\helpers\FileHelper;
use yii\helpers\StringHelper;
/**
......@@ -183,7 +182,7 @@ class Controller extends Component
}
}
if ($missing !== array()) {
if (!empty($missing)) {
throw new InvalidRequestException(Yii::t('yii|Missing required parameters: {params}', array(
'{params}' => implode(', ', $missing),
)));
......@@ -204,7 +203,7 @@ class Controller extends Component
public function forward($route, $params = array())
{
$status = $this->run($route, $params);
exit($status);
Yii::$app->end($status);
}
/**
......@@ -279,7 +278,7 @@ class Controller extends Component
* Child classes may override this method to throw exceptions when there are missing and/or unknown parameters.
* @param Action $action the currently requested action
* @param array $missingParams the names of the missing parameters
* @param array $unknownParams the unknown parameters (name=>value)
* @param array $unknownParams the unknown parameters (name => value)
*/
public function validateActionParams($action, $missingParams, $unknownParams)
{
......@@ -319,10 +318,10 @@ class Controller extends Component
/** @var Model $model */
$scope = $model->formName();
if ($scope == '') {
$model->attributes = $data;
$model->setAttributes($data);
$success = true;
} elseif (isset($data[$scope])) {
$model->attributes = $data[$scope];
$model->setAttributes($data[$scope]);
$success = true;
}
}
......
......@@ -24,7 +24,7 @@ use yii\helpers\ArrayHelper;
* $dictionary[$key] = $value; // add a key-value pair
* unset($dictionary[$key]); // remove the value with the specified key
* if (isset($dictionary[$key])) // if the dictionary contains the key
* foreach ($dictionary as $key=>$value) // traverse the items in the dictionary
* foreach ($dictionary as $key => $value) // traverse the items in the dictionary
* $n = count($dictionary); // returns the number of items in the dictionary
* ~~~
*
......@@ -51,7 +51,7 @@ class Dictionary extends Object implements \IteratorAggregate, \ArrayAccess, \Co
*/
public function __construct($data = array(), $config = array())
{
if ($data !== array()) {
if (!empty($data)) {
$this->copyFrom($data);
}
parent::__construct($config);
......@@ -187,7 +187,7 @@ class Dictionary extends Object implements \IteratorAggregate, \ArrayAccess, \Co
public function copyFrom($data)
{
if (is_array($data) || $data instanceof \Traversable) {
if ($this->_d !== array()) {
if (!empty($this->_d)) {
$this->removeAll();
}
if ($data instanceof self) {
......
......@@ -83,7 +83,7 @@ class ErrorHandler extends Component
} else {
// if there is an error during error rendering it's useful to
// display PHP error in debug mode instead of a blank screen
if(YII_DEBUG) {
if (YII_DEBUG) {
ini_set('display_errors', 1);
}
......@@ -231,7 +231,7 @@ class ErrorHandler extends Component
echo '<div class="plus">+</div><div class="minus">-</div>';
}
echo '&nbsp;';
if(isset($t['file'])) {
if (isset($t['file'])) {
echo $this->htmlEncode($t['file']) . '(' . $t['line'] . '): ';
}
if (!empty($t['class'])) {
......
......@@ -100,9 +100,10 @@ class HttpException extends UserException
509 => 'Bandwidth Limit Exceeded',
);
if(isset($httpCodes[$this->statusCode]))
if (isset($httpCodes[$this->statusCode])) {
return $httpCodes[$this->statusCode];
else
} else {
return \Yii::t('yii|Error');
}
}
}
......@@ -33,7 +33,7 @@ use yii\validators\Validator;
* @property Vector $validators All the validators declared in the model.
* @property array $activeValidators The validators applicable to the current [[scenario]].
* @property array $errors Errors for all attributes or the specified attribute. Empty array is returned if no error.
* @property array $attributes Attribute values (name=>value).
* @property array $attributes Attribute values (name => value).
* @property string $scenario The scenario that this model is in.
*
* @author Qiang Xue <qiang.xue@gmail.com>
......@@ -76,7 +76,7 @@ class Model extends Component implements \IteratorAggregate, \ArrayAccess
* array(
* 'attribute list',
* 'validator type',
* 'on'=>'scenario name',
* 'on' => 'scenario name',
* ...other parameters...
* )
* ~~~
......@@ -109,11 +109,11 @@ class Model extends Component implements \IteratorAggregate, \ArrayAccess
* // built-in "required" validator
* array('username', 'required'),
* // built-in "length" validator customized with "min" and "max" properties
* array('username', 'length', 'min'=>3, 'max'=>12),
* array('username', 'length', 'min' => 3, 'max' => 12),
* // built-in "compare" validator that is used in "register" scenario only
* array('password', 'compare', 'compareAttribute'=>'password2', 'on'=>'register'),
* array('password', 'compare', 'compareAttribute' => 'password2', 'on' => 'register'),
* // an inline validator defined via the "authenticate()" method in the model class
* array('password', 'authenticate', 'on'=>'login'),
* array('password', 'authenticate', 'on' => 'login'),
* // a validator of class "CaptchaValidator"
* array('captcha', 'CaptchaValidator'),
* );
......@@ -220,7 +220,7 @@ class Model extends Component implements \IteratorAggregate, \ArrayAccess
* Note, in order to inherit labels defined in the parent class, a child class needs to
* merge the parent labels with child labels using functions such as `array_merge()`.
*
* @return array attribute labels (name=>label)
* @return array attribute labels (name => label)
* @see generateAttributeLabel
*/
public function attributeLabels()
......@@ -511,7 +511,7 @@ class Model extends Component implements \IteratorAggregate, \ArrayAccess
* Defaults to null, meaning all attributes listed in [[attributes()]] will be returned.
* If it is an array, only the attributes in the array will be returned.
* @param array $except list of attributes whose value should NOT be returned.
* @return array attribute values (name=>value).
* @return array attribute values (name => value).
*/
public function getAttributes($names = null, $except = array())
{
......@@ -531,7 +531,7 @@ class Model extends Component implements \IteratorAggregate, \ArrayAccess
/**
* Sets the attribute values in a massive way.
* @param array $values attribute values (name=>value) to be assigned to the model.
* @param array $values attribute values (name => value) to be assigned to the model.
* @param boolean $safeOnly whether the assignments should only be done to the safe attributes.
* A safe attribute is one that is associated with a validation rule in the current [[scenario]].
* @see safeAttributes()
......
......@@ -15,6 +15,14 @@ namespace yii\base;
class Object
{
/**
* @return string the fully qualified name of this class.
*/
public static function className()
{
return get_called_class();
}
/**
* Constructor.
* The default implementation does two things:
*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment