Skip to content

Commit

Permalink
model matcher like shoulda matchers for Yii 2.x
Browse files Browse the repository at this point in the history
  • Loading branch information
developeruz committed Jul 19, 2015
1 parent ba590b8 commit 4859149
Show file tree
Hide file tree
Showing 3 changed files with 192 additions and 1 deletion.
118 changes: 118 additions & 0 deletions ModelMatcher.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
<?php

namespace developeruz\yii_matcher;

use yii\base\Model;
use yii\base\Security;
use yii\codeception\TestCase;
use yii\console\Exception;
use yii\validators\Validator;


class ModelMatcher extends TestCase {

public $class;

public function __construct($class)
{
parent::__construct();
$this->class = $class;
}

public function mustBeSafe($attribute, $onScenario = Model::SCENARIO_DEFAULT)
{
$model = $this->getModel($onScenario);
$this->assertTrue($model->isAttributeSafe($attribute));
}

public function mustBeNotSafe($attribute, $onScenario = Model::SCENARIO_DEFAULT)
{
$model = $this->getModel($onScenario);
$this->assertFalse($model->isAttributeSafe($attribute));
}

public function mustBeRequired($attribute, $onScenario = Model::SCENARIO_DEFAULT)
{
$model = $this->getModel($onScenario);
$this->assertTrue($model->isAttributeRequired($attribute));
}

public function mustBeNotRequired($attribute, $onScenario = Model::SCENARIO_DEFAULT)
{
$model = $this->getModel($onScenario);
$this->assertFalse($model->isAttributeRequired($attribute));
}

public function matchLength($attribute, $min = null, $max = null, $onScenario = Model::SCENARIO_DEFAULT)
{
$stringValidator = $this->getValidator('yii\validators\StringValidator', ['max' => $max, 'min' => $min], $attribute, $onScenario);
$stringGenerator = new Security();

if(!empty($min))
{
$string = $stringGenerator->generateRandomString($min - 1);
$this->assertFalse($stringValidator->validate($string));

$string = $stringGenerator->generateRandomString($min);
$this->assertTrue($stringValidator->validate($string));
}

if(!empty($max))
{
$string = $stringGenerator->generateRandomString($max + 1);
$this->assertFalse($stringValidator->validate($string));

$string = $stringGenerator->generateRandomString($max);
$this->assertTrue($stringValidator->validate($string));
}
}

public function hasOne($relationName, $relatedClass, $links = null)
{
$model = $this->getModel();
$relation = $model->getRelation($relationName);

$this->assertEquals($relatedClass, $relation->modelClass);
$this->assertFalse($relation->multiple);

if(!empty($links))
{
$actualLinks = $relation->link;
$this->assertEmpty(array_diff($actualLinks, $links));
}
}

public function hasMany($relationName, $relatedClass, $links = null)
{
$model = $this->getModel();
$relation = $model->getRelation($relationName);

$this->assertEquals($relatedClass, $relation->modelClass);
$this->assertTrue($relation->multiple);

if(!empty($links))
{
$actualLinks = $relation->link;
$this->assertEmpty(array_diff($actualLinks, $links));
}
}


private function getModel($scenario = Model::SCENARIO_DEFAULT)
{
$model = new $this->class();
$model->scenario = $scenario;
return $model;
}

private function getValidator($type, $params, $attribute , $onScenario)
{
$model = $this->getModel($onScenario);
$validator = Validator::createValidator($type, $model, $attribute, $params);
if(empty($validator))
{
throw new Exception('Can not generate validator');
}
return $validator;
}
}
50 changes: 49 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,50 @@
# yii-matcher
Класс для легкого тестирования моделей в Yii2
============

**Что и зачем тестировать?** Разработчики Yii-фреимворка протестировали и гарантируют правильную работу правил валидации.
Но они не гарантируют, что вы незабыли их прописать в модели или позже не удалили некоторые из них. Поэтому важно писать unit-тесты
для моделей. Данный класс облегчит тестирование правил валидации ваших моделей.

## Установка:##
```bash
$ php composer.phar require developeruz/yii-matcher "*"
```

## Пример использования:##

```php
use developeruz\yii_matcher\ModelMatcher;

class ValidateTest extends TestCase {

public function testPhoneIsSafeOnlyInRegistration()
{
$userModel = new ModelMatcher('app\models\User');
$userModel->mustBeSafe('phone', 'registration');
$userModel->mustBeNotSafe('phone');
}

public function testUserHasPostsRelation()
{
$userModel = new ModelMatcher('app\models\User');
$userModel->hasMany('posts', 'app\models\Post', ['user_id' => 'id']);
}

public function testLoginLength()
{
$userModel = new ModelMatcher('app\models\User');
$userModel->matchLength('login', 3, 20);
}
}
```
## Доступные методы: ##

- **mustBeSafe()** и **mustBeNotSafe()** - проверка на возможность массового присвоения атрибута
- **mustBeRequired()** и **mustBeNotRequired()** - проверка на обязательность заполнения параметра
- **matchLength()** - проверка на длинну строки. Для того, чтобы провести проверку только на *min* или *max*,
задайте второй параметр как null.
- **hasOne()** и **hasMany()** - проверка на наличие связей

Все методы принимают в качестве параметра имя аттрибута и необязательный параметр - сценарий.

*PS: С радостью приму pull-request с дополнительными matcher-ами. Или пишите в issue какие еще валидаторы стоит добавить*
25 changes: 25 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"name": "developeruz/yii-matcher",
"description": "Test case like shoulda matchers for Yii 2.x",
"keywords": ["yii", "unit test"],
"type": "yii2-extension",
"license": "MIT",
"authors": [
{
"name": "Elvira Sheina",
"email": "[email protected]",
"homepage": "http://developer.uz"
}
],
"require": {
"yiisoft/yii2": "*"
},
"support": {
"issues": "https://github.com/developeruz/yii-matcher/issues"
},
"autoload": {
"psr-4": {
"developeruz\\yii_matcher\\": ""
}
}
}

0 comments on commit 4859149

Please sign in to comment.