Merge pull request #8417 from creative-commoners/pulls/4.3/many-many-through-sorting-tests

Add more list sorting tests and fix many many through sorting
This commit is contained in:
Robbie Averill 2018-10-03 13:30:20 +02:00 committed by GitHub
commit b0871ebd75
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 134 additions and 44 deletions

View File

@ -3,6 +3,7 @@
namespace SilverStripe\ORM; namespace SilverStripe\ORM;
use SilverStripe\Core\Config\Config;
use SilverStripe\Core\Injector\Injectable; use SilverStripe\Core\Injector\Injectable;
use SilverStripe\Core\Injector\Injector; use SilverStripe\Core\Injector\Injector;
use SilverStripe\Dev\Deprecation; use SilverStripe\Dev\Deprecation;
@ -253,6 +254,13 @@ class ManyManyThroughQueryManipulator implements DataQueryManipulator
); );
} }
// Set a default sort from the join model if available and nothing is already set
if (empty($sqlSelect->getOrderBy())
&& $sort = Config::inst()->get($this->getJoinClass(), 'default_sort')
) {
$sqlSelect->setOrderBy($sort);
}
// Apply join and record sql for later insertion (at end of replacements) // Apply join and record sql for later insertion (at end of replacements)
// By using a string placeholder $$_SUBQUERY_$$ we protect field/table rewrites from interfering twice // By using a string placeholder $$_SUBQUERY_$$ we protect field/table rewrites from interfering twice
// on the already-finalised inner list // on the already-finalised inner list

View File

@ -11,17 +11,16 @@ use SilverStripe\ORM\Tests\HasManyListTest\Employee;
class HasManyListTest extends SapphireTest class HasManyListTest extends SapphireTest
{ {
// Borrow the model from DataObjectTest
protected static $fixture_file = [ protected static $fixture_file = [
'DataObjectTest.yml', // Borrow the model from DataObjectTest 'DataObjectTest.yml', // Borrow the model from DataObjectTest
'HasManyListTest.yml', 'HasManyListTest.yml',
]; ];
public static $extra_data_objects = array( public static $extra_data_objects = [
Company::class, Company::class,
Employee::class, Employee::class,
CompanyCar::class, CompanyCar::class,
); ];
public static function getExtraDataObjects() public static function getExtraDataObjects()
{ {
@ -36,7 +35,7 @@ class HasManyListTest extends SapphireTest
{ {
// Relies on the fact that (unrelated) comments exist in the fixture file already // Relies on the fact that (unrelated) comments exist in the fixture file already
$newTeam = new Team(); // has_many Comments $newTeam = new Team(); // has_many Comments
$this->assertEquals(array(), $newTeam->Comments()->column('ID')); $this->assertEquals([], $newTeam->Comments()->column('ID'));
} }
/** /**
@ -48,23 +47,23 @@ class HasManyListTest extends SapphireTest
// Check that expected teams exist // Check that expected teams exist
$list = Team::get(); $list = Team::get();
$this->assertEquals( $this->assertEquals(
array('Subteam 1', 'Subteam 2', 'Subteam 3', 'Team 1', 'Team 2', 'Team 3'), ['Subteam 1', 'Subteam 2', 'Subteam 3', 'Team 1', 'Team 2', 'Team 3'],
$list->sort('Title')->column('Title') $list->sort('Title')->column('Title')
); );
// Test that each team has the correct fans // Test that each team has the correct fans
$team1 = $this->objFromFixture(DataObjectTest\Team::class, 'team1'); $team1 = $this->objFromFixture(DataObjectTest\Team::class, 'team1');
$team2 = $this->objFromFixture(DataObjectTest\Team::class, 'team2'); $team2 = $this->objFromFixture(DataObjectTest\Team::class, 'team2');
$this->assertEquals(array('Bob', 'Joe'), $team1->Comments()->sort('Name')->column('Name')); $this->assertEquals(['Bob', 'Joe'], $team1->Comments()->sort('Name')->column('Name'));
$this->assertEquals(array('Phil'), $team2->Comments()->sort('Name')->column('Name')); $this->assertEquals(['Phil'], $team2->Comments()->sort('Name')->column('Name'));
// Test that removing comments from unrelated team has no effect // Test that removing comments from unrelated team has no effect
$team1comment = $this->objFromFixture(DataObjectTest\TeamComment::class, 'comment1'); $team1comment = $this->objFromFixture(DataObjectTest\TeamComment::class, 'comment1');
$team2comment = $this->objFromFixture(DataObjectTest\TeamComment::class, 'comment3'); $team2comment = $this->objFromFixture(DataObjectTest\TeamComment::class, 'comment3');
$team1->Comments()->remove($team2comment); $team1->Comments()->remove($team2comment);
$team2->Comments()->remove($team1comment); $team2->Comments()->remove($team1comment);
$this->assertEquals(array('Bob', 'Joe'), $team1->Comments()->sort('Name')->column('Name')); $this->assertEquals(['Bob', 'Joe'], $team1->Comments()->sort('Name')->column('Name'));
$this->assertEquals(array('Phil'), $team2->Comments()->sort('Name')->column('Name')); $this->assertEquals(['Phil'], $team2->Comments()->sort('Name')->column('Name'));
$this->assertEquals($team1->ID, $team1comment->TeamID); $this->assertEquals($team1->ID, $team1comment->TeamID);
$this->assertEquals($team2->ID, $team2comment->TeamID); $this->assertEquals($team2->ID, $team2comment->TeamID);
@ -73,9 +72,45 @@ class HasManyListTest extends SapphireTest
$team2comment = $this->objFromFixture(DataObjectTest\TeamComment::class, 'comment3'); $team2comment = $this->objFromFixture(DataObjectTest\TeamComment::class, 'comment3');
$team1->Comments()->remove($team1comment); $team1->Comments()->remove($team1comment);
$team2->Comments()->remove($team2comment); $team2->Comments()->remove($team2comment);
$this->assertEquals(array('Bob'), $team1->Comments()->sort('Name')->column('Name')); $this->assertEquals(['Bob'], $team1->Comments()->sort('Name')->column('Name'));
$this->assertEquals(array(), $team2->Comments()->sort('Name')->column('Name')); $this->assertEquals([], $team2->Comments()->sort('Name')->column('Name'));
$this->assertEmpty($team1comment->TeamID); $this->assertEmpty($team1comment->TeamID);
$this->assertEmpty($team2comment->TeamID); $this->assertEmpty($team2comment->TeamID);
} }
public function testDefaultSortIsUsedOnList()
{
/** @var Company $company */
$company = $this->objFromFixture(Company::class, 'silverstripe');
$this->assertListEquals([
['Make' => 'Ferrari'],
['Make' => 'Jaguar'],
['Make' => 'Lamborghini'],
], $company->CompanyCars());
}
public function testCanBeSortedDescending()
{
/** @var Company $company */
$company = $this->objFromFixture(Company::class, 'silverstripe');
$this->assertListEquals([
['Make' => 'Lamborghini'],
['Make' => 'Jaguar'],
['Make' => 'Ferrari'],
], $company->CompanyCars()->sort('"Make" DESC'));
}
public function testSortByModel()
{
/** @var Company $company */
$company = $this->objFromFixture(Company::class, 'silverstripe');
$this->assertListEquals([
['Model' => 'Countach'],
['Model' => 'E Type'],
['Model' => 'F40'],
], $company->CompanyCars()->sort('"Model" ASC'));
}
} }

View File

@ -1,26 +1,26 @@
SilverStripe\ORM\Tests\DataObjectTest\Company: SilverStripe\ORM\Tests\HasManyListTest\Company:
silverstripe: silverstripe:
Name: 'SilverStripe Ltd' Name: 'SilverStripe Ltd'
SilverStripe\ORM\Tests\HasManyListTest\Employee: SilverStripe\ORM\Tests\HasManyListTest\Employee:
john: john:
Name: 'John Smith' Name: 'John Smith'
Company: =>SilverStripe\ORM\Tests\DataObjectTest\Company.silverstripe Company: =>SilverStripe\ORM\Tests\HasManyListTest\Company.silverstripe
jenny: jenny:
Name: 'Jenny Smith' Name: 'Jenny Smith'
Company: =>SilverStripe\ORM\Tests\DataObjectTest\Company.silverstripe Company: =>SilverStripe\ORM\Tests\HasManyListTest\Company.silverstripe
SilverStripe\ORM\Tests\HasManyListTest\CompanyCar: SilverStripe\ORM\Tests\HasManyListTest\CompanyCar:
jaguar: jaguar:
Make: 'Jaguar' Make: 'Jaguar'
Model: 'E Type' Model: 'E Type'
User: =>SilverStripe\ORM\Tests\HasManyListTest\Employee.john User: =>SilverStripe\ORM\Tests\HasManyListTest\Employee.john
Company: =>SilverStripe\ORM\Tests\DataObjectTest\Company.silverstripe Company: =>SilverStripe\ORM\Tests\HasManyListTest\Company.silverstripe
ferrari: ferrari:
Make: 'Ferrari' Make: 'Ferrari'
Model: 'F40' Model: 'F40'
User: =>SilverStripe\ORM\Tests\HasManyListTest\Employee.jenny User: =>SilverStripe\ORM\Tests\HasManyListTest\Employee.jenny
Company: =>SilverStripe\ORM\Tests\DataObjectTest\Company.silverstripe Company: =>SilverStripe\ORM\Tests\HasManyListTest\Company.silverstripe
lamborghini: lamborghini:
Make: 'Lamborghini' Make: 'Lamborghini'
Model: 'Countach' Model: 'Countach'
User: =>SilverStripe\ORM\Tests\HasManyListTest\Employee.jenny User: =>SilverStripe\ORM\Tests\HasManyListTest\Employee.jenny
Company: =>SilverStripe\ORM\Tests\DataObjectTest\Company.silverstripe Company: =>SilverStripe\ORM\Tests\HasManyListTest\Company.silverstripe

View File

@ -7,13 +7,15 @@ use SilverStripe\ORM\DataObject;
class CompanyCar extends DataObject implements TestOnly class CompanyCar extends DataObject implements TestOnly
{ {
private static $db = array( private static $db = [
'Make' => 'Varchar(100)', 'Make' => 'Varchar(100)',
'Model' => 'Varchar(100)', 'Model' => 'Varchar(100)',
); ];
private static $has_one = array( private static $has_one = [
'User' => Employee::class, 'User' => Employee::class,
'Company' => Company::class, 'Company' => Company::class,
); ];
private static $default_sort = 'Make';
} }

View File

@ -70,33 +70,76 @@ class ManyManyThroughListTest extends SapphireTest
$this->assertNotNull($item2->getJoin()); $this->assertNotNull($item2->getJoin());
$this->assertEquals('join 2', $item2->getJoin()->Title); $this->assertEquals('join 2', $item2->getJoin()->Title);
$this->assertEquals('join 2', $item2->ManyManyThroughListTest_JoinObject->Title); $this->assertEquals('join 2', $item2->ManyManyThroughListTest_JoinObject->Title);
}
// Test sorting on join table /**
$items = $parent->Items()->sort('"ManyManyThroughListTest_JoinObject"."Sort"'); * @param string $sort
$this->assertListEquals( * @param array $expected
[ * @dataProvider sortingProvider
['Title' => 'item 2'], */
['Title' => 'item 1'], public function testSorting($sort, $expected)
], {
$items /** @var ManyManyThroughListTest\TestObject $parent */
); $parent = $this->objFromFixture(ManyManyThroughListTest\TestObject::class, 'parent1');
$items = $parent->Items()->sort('"ManyManyThroughListTest_JoinObject"."Sort" ASC'); $items = $parent->Items();
$this->assertListEquals( if ($sort) {
[ $items = $items->sort($sort);
['Title' => 'item 1'], }
['Title' => 'item 2'], $this->assertSame($expected, $items->column('Title'));
}
/**
* @return array[]
*/
public function sortingProvider()
{
return [
'nothing passed (default)' => [
null,
['item 2', 'item 1'],
], ],
$items 'table with default column' => [
); '"ManyManyThroughListTest_JoinObject"."Sort"',
$items = $parent->Items()->sort('"ManyManyThroughListTest_JoinObject"."Title" DESC'); ['item 2', 'item 1'],
$this->assertListEquals(
[
['Title' => 'item 2'],
['Title' => 'item 1'],
], ],
$items 'table with default column ascending' => [
); '"ManyManyThroughListTest_JoinObject"."Sort" ASC',
['item 2', 'item 1'],
],
'table with default column descending' => [
'"ManyManyThroughListTest_JoinObject"."Sort" DESC',
['item 1', 'item 2'],
],
'table with column descending' => [
'"ManyManyThroughListTest_JoinObject"."Title" DESC',
['item 2', 'item 1'],
],
'table with column ascending' => [
'"ManyManyThroughListTest_JoinObject"."Title" ASC',
['item 1', 'item 2'],
],
'default column' => [
'"Sort"',
['item 2', 'item 1'],
],
'default column ascending' => [
'"Sort" ASC',
['item 2', 'item 1'],
],
'default column descending' => [
'"Sort" DESC',
['item 1', 'item 2'],
],
'column descending' => [
'"Title" DESC',
['item 2', 'item 1'],
],
'column ascending' => [
'"Title" ASC',
['item 1', 'item 2'],
],
];
} }
public function testAdd() public function testAdd()

View File

@ -23,4 +23,6 @@ class JoinObject extends DataObject implements TestOnly
'Parent' => TestObject::class, 'Parent' => TestObject::class,
'Child' => Item::class, 'Child' => Item::class,
]; ];
private static $default_sort = '"Sort" ASC';
} }