Browse Source

Added SortTest

tags/2.0.0-beta
Qiang Xue 11 years ago
parent
commit
ac8801bc63
  1. 89
      framework/yii/data/Sort.php
  2. 175
      tests/unit/framework/data/SortTest.php
  3. 3
      tests/unit/framework/web/UrlManagerTest.php

89
framework/yii/data/Sort.php

@ -29,8 +29,10 @@ use yii\helpers\Inflector;
* 'attributes' => array( * 'attributes' => array(
* 'age', * 'age',
* 'name' => array( * 'name' => array(
* 'asc' => array('last_name', 'first_name'), * 'asc' => array('first_name' => Sort::ASC, 'last_name' => Sort::ASC),
* 'desc' => array('last_name' => true, 'first_name' => true), * 'desc' => array('first_name' => Sort::DESC, 'last_name' => Sort::DESC),
* 'default' => Sort::DESC,
* 'label' => 'Name',
* ), * ),
* ), * ),
* )); * ));
@ -96,7 +98,7 @@ class Sort extends Object
* ~~~ * ~~~
* array( * array(
* 'age', * 'age',
* 'user' => array( * 'name' => array(
* 'asc' => array('first_name' => Sort::ASC, 'last_name' => Sort::ASC), * 'asc' => array('first_name' => Sort::ASC, 'last_name' => Sort::ASC),
* 'desc' => array('first_name' => Sort::DESC, 'last_name' => Sort::DESC), * 'desc' => array('first_name' => Sort::DESC, 'last_name' => Sort::DESC),
* 'default' => Sort::DESC, * 'default' => Sort::DESC,
@ -164,9 +166,9 @@ class Sort extends Object
* @var array separators used in the generated URL. This must be an array consisting of * @var array separators used in the generated URL. This must be an array consisting of
* two elements. The first element specifies the character separating different * two elements. The first element specifies the character separating different
* attributes, while the second element specifies the character separating attribute name * attributes, while the second element specifies the character separating attribute name
* and the corresponding sort direction. Defaults to `array('-', '.')`. * and the corresponding sort direction. Defaults to `array('.', '-')`.
*/ */
public $separators = array('-', '.'); public $separators = array('.', '-');
/** /**
* @var array parameters (name => value) that should be used to obtain the current sort directions * @var array parameters (name => value) that should be used to obtain the current sort directions
* and to create new sort URLs. If not set, $_GET will be used instead. * and to create new sort URLs. If not set, $_GET will be used instead.
@ -178,15 +180,21 @@ class Sort extends Object
* @see defaults * @see defaults
*/ */
public $params; public $params;
/**
* @var \yii\web\UrlManager the URL manager used for creating sort URLs. If not set,
* the "urlManager" application component will be used.
*/
public $urlManager;
/** /**
* Returns the columns and their corresponding sort directions. * Returns the columns and their corresponding sort directions.
* @param boolean $recalculate whether to recalculate the sort directions
* @return array the columns (keys) and their corresponding sort directions (values). * @return array the columns (keys) and their corresponding sort directions (values).
* This can be passed to [[\yii\db\Query::orderBy()]] to construct a DB query. * This can be passed to [[\yii\db\Query::orderBy()]] to construct a DB query.
*/ */
public function getOrders() public function getOrders($recalculate = false)
{ {
$attributeOrders = $this->getAttributeOrders(); $attributeOrders = $this->getAttributeOrders($recalculate);
$orders = array(); $orders = array();
foreach ($attributeOrders as $attribute => $direction) { foreach ($attributeOrders as $attribute => $direction) {
$definition = $this->getAttribute($attribute); $definition = $this->getAttribute($attribute);
@ -198,32 +206,6 @@ class Sort extends Object
return $orders; return $orders;
} }
/**
* Generates a hyperlink that links to the sort action to sort by the specified attribute.
* Based on the sort direction, the CSS class of the generated hyperlink will be appended
* with "asc" or "desc".
* @param string $attribute the attribute name by which the data should be sorted by.
* @param array $options additional HTML attributes for the hyperlink tag
* @return string the generated hyperlink
* @throws InvalidConfigException if the attribute is unknown
*/
public function link($attribute, $options = array())
{
if (($direction = $this->getAttributeOrder($attribute)) !== null) {
$class = $direction ? 'desc' : 'asc';
if (isset($options['class'])) {
$options['class'] .= ' ' . $class;
} else {
$options['class'] = $class;
}
}
$url = $this->createUrl($attribute);
$definition = $this->getAttribute($attribute);
$label = isset($definition['label']) ? $definition['label'] : Html::encode(Inflector::camel2words($attribute));
return Html::a($label, $url, $options);
}
private $_attributeOrders; private $_attributeOrders;
/** /**
@ -248,7 +230,7 @@ class Sort extends Object
} }
} }
if (($this->getAttribute($attribute)) !== false) { if (($this->getAttribute($attribute)) !== null) {
$this->_attributeOrders[$attribute] = $descending; $this->_attributeOrders[$attribute] = $descending;
if (!$this->enableMultiSort) { if (!$this->enableMultiSort) {
return $this->_attributeOrders; return $this->_attributeOrders;
@ -277,6 +259,32 @@ class Sort extends Object
} }
/** /**
* Generates a hyperlink that links to the sort action to sort by the specified attribute.
* Based on the sort direction, the CSS class of the generated hyperlink will be appended
* with "asc" or "desc".
* @param string $attribute the attribute name by which the data should be sorted by.
* @param array $options additional HTML attributes for the hyperlink tag
* @return string the generated hyperlink
* @throws InvalidConfigException if the attribute is unknown
*/
public function link($attribute, $options = array())
{
if (($direction = $this->getAttributeOrder($attribute)) !== null) {
$class = $direction ? 'desc' : 'asc';
if (isset($options['class'])) {
$options['class'] .= ' ' . $class;
} else {
$options['class'] = $class;
}
}
$url = $this->createUrl($attribute);
$definition = $this->getAttribute($attribute);
$label = isset($definition['label']) ? $definition['label'] : Html::encode(Inflector::camel2words($attribute));
return Html::a($label, $url, $options);
}
/**
* Creates a URL for sorting the data by the specified attribute. * Creates a URL for sorting the data by the specified attribute.
* This method will consider the current sorting status given by [[attributeOrders]]. * This method will consider the current sorting status given by [[attributeOrders]].
* For example, if the current page already sorts the data by the specified attribute in ascending order, * For example, if the current page already sorts the data by the specified attribute in ascending order,
@ -289,7 +297,7 @@ class Sort extends Object
*/ */
public function createUrl($attribute) public function createUrl($attribute)
{ {
if (($definition = $this->getAttribute($attribute)) === false) { if (($definition = $this->getAttribute($attribute)) === null) {
throw new InvalidConfigException("Unknown attribute: $attribute"); throw new InvalidConfigException("Unknown attribute: $attribute");
} }
$directions = $this->getAttributeOrders(); $directions = $this->getAttributeOrders();
@ -313,15 +321,15 @@ class Sort extends Object
$params = $this->params === null ? $_GET : $this->params; $params = $this->params === null ? $_GET : $this->params;
$params[$this->sortVar] = implode($this->separators[0], $sorts); $params[$this->sortVar] = implode($this->separators[0], $sorts);
$route = $this->route === null ? Yii::$app->controller->getRoute() : $this->route; $route = $this->route === null ? Yii::$app->controller->getRoute() : $this->route;
$urlManager = $this->urlManager === null ? Yii::$app->getUrlManager() : $this->urlManager;
return Yii::$app->getUrlManager()->createUrl($route, $params); return $urlManager->createUrl($route, $params);
} }
/** /**
* Returns the attribute definition of the specified name. * Returns the attribute definition of the specified name.
* @param string $name the attribute name * @param string $name the attribute name
* @return array|boolean the sort definition (column names => sort directions). * @return array the sort definition (column names => sort directions).
* False is returned if the attribute cannot be sorted. * Null is returned if the attribute cannot be sorted.
* @see attributes * @see attributes
*/ */
public function getAttribute($name) public function getAttribute($name)
@ -332,10 +340,9 @@ class Sort extends Object
return array( return array(
'asc' => array($name => self::ASC), 'asc' => array($name => self::ASC),
'desc' => array($name => self::DESC), 'desc' => array($name => self::DESC),
'label' => Inflector::camel2words($name),
); );
} else { } else {
return false; return null;
} }
} }
} }

175
tests/unit/framework/data/SortTest.php

@ -0,0 +1,175 @@
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yiiunit\framework\data;
use yii\web\UrlManager;
use yiiunit\TestCase;
use yii\data\Sort;
/**
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class SortTest extends TestCase
{
public function testGetOrders()
{
$sort = new Sort(array(
'attributes' => array(
'age',
'name' => array(
'asc' => array('first_name' => Sort::ASC, 'last_name' => Sort::ASC),
'desc' => array('first_name' => Sort::DESC, 'last_name' => Sort::DESC),
),
),
'params' => array(
'sort' => 'age.name-desc'
),
'enableMultiSort' => true,
));
$orders = $sort->getOrders();
$this->assertEquals(3, count($orders));
$this->assertEquals(Sort::ASC, $orders['age']);
$this->assertEquals(Sort::DESC, $orders['first_name']);
$this->assertEquals(Sort::DESC, $orders['last_name']);
$sort->enableMultiSort = false;
$orders = $sort->getOrders(true);
$this->assertEquals(1, count($orders));
$this->assertEquals(Sort::ASC, $orders['age']);
}
public function testGetAttributeOrders()
{
$sort = new Sort(array(
'attributes' => array(
'age',
'name' => array(
'asc' => array('first_name' => Sort::ASC, 'last_name' => Sort::ASC),
'desc' => array('first_name' => Sort::DESC, 'last_name' => Sort::DESC),
),
),
'params' => array(
'sort' => 'age.name-desc'
),
'enableMultiSort' => true,
));
$orders = $sort->getAttributeOrders();
$this->assertEquals(2, count($orders));
$this->assertEquals(Sort::ASC, $orders['age']);
$this->assertEquals(Sort::DESC, $orders['name']);
$sort->enableMultiSort = false;
$orders = $sort->getAttributeOrders(true);
$this->assertEquals(1, count($orders));
$this->assertEquals(Sort::ASC, $orders['age']);
}
public function testGetAttributeOrder()
{
$sort = new Sort(array(
'attributes' => array(
'age',
'name' => array(
'asc' => array('first_name' => Sort::ASC, 'last_name' => Sort::ASC),
'desc' => array('first_name' => Sort::DESC, 'last_name' => Sort::DESC),
),
),
'params' => array(
'sort' => 'age.name-desc'
),
'enableMultiSort' => true,
));
$this->assertEquals(Sort::ASC, $sort->getAttributeOrder('age'));
$this->assertEquals(Sort::DESC, $sort->getAttributeOrder('name'));
$this->assertNull($sort->getAttributeOrder('xyz'));
}
public function testGetAttribute()
{
$sort = new Sort(array(
'attributes' => array(
'age',
'name' => array(
'asc' => array('first_name' => Sort::ASC, 'last_name' => Sort::ASC),
'desc' => array('first_name' => Sort::DESC, 'last_name' => Sort::DESC),
),
),
'params' => array(
'sort' => 'age.name-desc'
),
'enableMultiSort' => true,
));
$attribute = array('asc' => array('age' => Sort::ASC), 'desc' => array('age' => Sort::DESC));
$this->assertEquals($attribute, $sort->getAttribute('age'));
$attribute = array(
'asc' => array('first_name' => Sort::ASC, 'last_name' => Sort::ASC),
'desc' => array('first_name' => Sort::DESC, 'last_name' => Sort::DESC),
);
$this->assertEquals($attribute, $sort->getAttribute('name'));
$this->assertNull($sort->getAttribute('xyz'));
}
public function testCreateUrl()
{
$manager = new UrlManager(array(
'baseUrl' => '/index.php',
'cache' => null,
));
$sort = new Sort(array(
'attributes' => array(
'age',
'name' => array(
'asc' => array('first_name' => Sort::ASC, 'last_name' => Sort::ASC),
'desc' => array('first_name' => Sort::DESC, 'last_name' => Sort::DESC),
),
),
'params' => array(
'sort' => 'age.name-desc'
),
'enableMultiSort' => true,
'urlManager' => $manager,
'route' => 'site/index',
));
$this->assertEquals('/index.php?r=site/index&sort=age-desc.name-desc', $sort->createUrl('age'));
$this->assertEquals('/index.php?r=site/index&sort=name.age', $sort->createUrl('name'));
}
public function testLink()
{
$this->mockApplication();
$manager = new UrlManager(array(
'baseUrl' => '/index.php',
'cache' => null,
));
$sort = new Sort(array(
'attributes' => array(
'age',
'name' => array(
'asc' => array('first_name' => Sort::ASC, 'last_name' => Sort::ASC),
'desc' => array('first_name' => Sort::DESC, 'last_name' => Sort::DESC),
),
),
'params' => array(
'sort' => 'age.name-desc'
),
'enableMultiSort' => true,
'urlManager' => $manager,
'route' => 'site/index',
));
$this->assertEquals('<a class="asc" href="/index.php?r=site/index&amp;sort=age-desc.name-desc">Age</a>', $sort->link('age'));
}
}

3
tests/unit/framework/web/UrlManagerTest.php

@ -257,9 +257,6 @@ class UrlManagerTest extends TestCase
public function testParseRESTRequest() public function testParseRESTRequest()
{ {
$manager = new UrlManager(array(
'cache' => null,
));
$request = new Request; $request = new Request;
// pretty URL rules // pretty URL rules

Loading…
Cancel
Save