Skip to content

Instantly share code, notes, and snippets.

@milkmeowo
Last active January 20, 2017 01:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save milkmeowo/e9172dc6db80411d8361e78264a5a00b to your computer and use it in GitHub Desktop.
Save milkmeowo/e9172dc6db80411d8361e78264a5a00b to your computer and use it in GitHub Desktop.
<?php
namespace Tests\Feature;
use Illuminate\Support\Collection;
use Tests\TestCase;
class HOMCollectionTest extends TestCase
{
/**
* The methods that can be proxied.
*
* @var array
*/
protected $proxies = [
'contains',
'each',
'every',
'filter',
'first',
'map',
'partition',
'reject',
'sortBy',
'sortByDesc',
'sum',
];
/*
|------------------------------------------------
| HOM Contains
|------------------------------------------------
*/
public function testContainsUserPermissions()
{
// 如果是一个用户,拥有最基础的用户权限
$permissions = [
'User' => [
'crate' => false,
'update' => false,
'read' => true, // 注意: User 只有 read 为 true
'delete' => false,
],
];
$c = new Collection($permissions);
/*
|------------------------------------------------
| 传统用法
|------------------------------------------------
*/
//用户只能 读
$this->assertTrue($c->contains('read', true));
// 不能 增 改 删
$this->assertFalse($c->contains('crate', true));
$this->assertFalse($c->contains('update', true));
$this->assertFalse($c->contains('delete', true));
/*
|------------------------------------------------
| HOM 用法
|------------------------------------------------
*/
//用户只能 读
$this->assertTrue($c->contains->read);
// 不能 增 改 删
$this->assertFalse($c->contains->crate);
$this->assertFalse($c->contains->update);
$this->assertFalse($c->contains->delete);
}
public function testContainsEditorPermissions()
{
// 如果是一个编辑,拥有最基础的用户权限,还有编辑的权限
$permissions = [
'User' => [
'crate' => false,
'update' => false,
'read' => true, // 注意: User 只有 read 为 true
'delete' => false,
],
'Editor' => [
'crate' => true,
'update' => true,
'read' => true,
'delete' => false, // 注意: Editor 只有 delete 为 false
],
];
$c = new Collection($permissions);
/*
|------------------------------------------------
| 传统用法
|------------------------------------------------
*/
// 编辑可以 增 改 读
$this->assertTrue($c->contains('crate', true));
$this->assertTrue($c->contains('update', true));
$this->assertTrue($c->contains('read', true));
// 不能 删
$this->assertFalse($c->contains('delete', true));
/*
|------------------------------------------------
| HOM 用法
|------------------------------------------------
*/
// 编辑可以 增 改 读
$this->assertTrue($c->contains->crate);
$this->assertTrue($c->contains->update);
$this->assertTrue($c->contains->read);
// 不能 删
$this->assertFalse($c->contains->delete);
}
/*
|------------------------------------------------
| HOM Each
|------------------------------------------------
*/
public function testEachUnreadNotificationsMarkAsRead()
{
// 现在有一些未读通知,我们需要把它们标记为已读。
/*
|------------------------------------------------
| 传统用法
|------------------------------------------------
*/
$c = new Collection([
'first' => new UnreadNotifications('first'),
'second' => new UnreadNotifications('second'),
'third' => new UnreadNotifications('third')
]);
$readNotifications = $c->each(function ($notification) {
$notification->markAsRead();
});
$this->assertEquals('first read at 20170119', $readNotifications['first']->read_at);
$this->assertEquals('second read at 20170119', $readNotifications['second']->read_at);
$this->assertEquals('third read at 20170119', $readNotifications['third']->read_at);
/*
|------------------------------------------------
| HOM 用法
|------------------------------------------------
*/
$c = new Collection([
'four' => new UnreadNotifications('four'),
'five' => new UnreadNotifications('five'),
'six' => new UnreadNotifications('six')
]);
$readNotifications = $c->each->markAsRead();
$this->assertEquals('four read at 20170119', $readNotifications['four']->read_at);
$this->assertEquals('five read at 20170119', $readNotifications['five']->read_at);
$this->assertEquals('six read at 20170119', $readNotifications['six']->read_at);
}
/*
|------------------------------------------------
| HOM every
|------------------------------------------------
*/
public function testEveryProfileFinish()
{
// 假设用户个人资料都必须完善之后才能发言
$confirmProfile = [
[
'title' => 'avatar',
'finish' => true
],
[
'title' => 'email',
'finish' => true
]
];
$notConfirmProfile = [
[
'title' => 'avatar',
'finish' => true
],
[
'title' => 'email',
'finish' => true
],
[
'title' => 'wechat',
'finish' => false // 注意:这里微信还没填写
],
];
/*
|------------------------------------------------
| 传统用法
|------------------------------------------------
*/
$cConfirm = new Collection($confirmProfile);
$this->assertTrue($cConfirm->every('finish'));
$cNotConfirm = new Collection($notConfirmProfile);
$this->assertFalse($cNotConfirm->every('finish'));
/*
|------------------------------------------------
| HOM 用法
|------------------------------------------------
*/
$cConfirm = new Collection($confirmProfile);
$this->assertTrue($cConfirm->every->finish);
$cNotConfirm = new Collection($notConfirmProfile);
$this->assertFalse($cNotConfirm->every->finish);
}
/*
|------------------------------------------------
| HOM filter and reject
|------------------------------------------------
*/
public function testFilterOrRejectEmployeesRetired()
{
$employees = [
'Alice' => new Employees('Alice', true),
'Milkmeowo' => new Employees('Milkmeowo', false),
'Bob' => new Employees('Bob', true),
];
$expectRetired = [
'Alice' => new Employees('Alice', true),
'Bob' => new Employees('Bob', true)
];
$expectNotRetired = [
'Milkmeowo' => new Employees('Milkmeowo', false)
];
/*
|------------------------------------------------
| 传统用法
|------------------------------------------------
*/
$c = new Collection($employees);
// filter
$actualRetired = $c->filter(function ($employee) {
return $employee->retired;
})->all();
$this->assertEquals($expectRetired, $actualRetired);
// reject
$actualNotRetired = $c->reject(function ($employee) {
return $employee->retired;
})->all();
$this->assertEquals($expectNotRetired, $actualNotRetired);
/*
|------------------------------------------------
| HOM 用法
|------------------------------------------------
*/
$c = new Collection($employees);
// filter
$actualRetired = $c->filter->retired->all();
$this->assertEquals($expectRetired, $actualRetired);
// reject
$actualNotRetired = $c->reject->retired->all();
$this->assertEquals($expectNotRetired, $actualNotRetired);
}
/*
|------------------------------------------------
| HOM first
|------------------------------------------------
*/
public function testFirstEmployeeRetired()
{
$employees = [
'Alice' => new Employees('Alice', false), // 注意:这里把 Alice 设置为还没退休
'Milkmeowo' => new Employees('Milkmeowo', false),
'Bob' => new Employees('Bob', true),
];
$expect = new Employees('Bob', true);
$c = new Collection($employees);
/*
|------------------------------------------------
| 传统用法
|------------------------------------------------
*/
$actual = $c->first(function ($value, $key) {
return $value->retired;
});
$this->assertEquals($expect, $actual);
/*
|------------------------------------------------
| HOM 用法
|------------------------------------------------
*/
$this->assertEquals($expect, $c->first->retired);
}
/*
|------------------------------------------------
| HOM map
|------------------------------------------------
*/
public function testMap()
{
$person1 = [ 'name' => 'Taylor' ];
$person2 = [ 'name' => 'Yaz' ];
$expectName = [ 'Taylor', 'Yaz' ];
$expectUppercaseName = [ 'TAYLOR', 'MILKMEOWO' ];
/*
|------------------------------------------------
| 传统用法
|------------------------------------------------
*/
$collection = collect([ $person1, $person2 ]);
$actual = $collection->map(function ($item, $key) {
return $item['name'];
})->toArray();
$this->assertEquals($expectName, $actual);
$collection = collect([
new Person('taylor'),
new Person('milkmeowo')
]);
$actual = $collection->each(function ($item, $key) {
return $item->uppercase();
})->map(function ($item, $key) {
return $item->name;
})->toArray();
$this->assertEquals($expectUppercaseName, $actual);
/*
|------------------------------------------------
| HOM 用法
|------------------------------------------------
*/
$collection = collect([ $person1, $person2 ]);
$actual = $collection->map->name->toArray();
$this->assertEquals($expectName, $actual);
$collection = collect([
new Person('taylor'),
new Person('milkmeowo')
]);
$actual = $collection->each->uppercase()->map->name->toArray();
$this->assertEquals($expectUppercaseName, $actual);
}
/*
|------------------------------------------------
| HOM partition
|------------------------------------------------
*/
public function testPartition()
{
$courses = new Collection([
'a' => [ 'free' => true ],
'b' => [ 'free' => false ],
'c' => [ 'free' => true ],
]);
$expectFree = [
'a' => [ 'free' => true ],
'c' => [ 'free' => true ],
];
$expectPremium = [
'b' => [ 'free' => false ],
];
/*
|------------------------------------------------
| 传统用法
|------------------------------------------------
*/
list( $free, $premium ) = $courses->partition('free');
$this->assertSame($expectFree, $free->toArray());
$this->assertSame($expectPremium, $premium->toArray());
/*
|------------------------------------------------
| HOM 用法
|------------------------------------------------
*/
list( $free, $premium ) = $courses->partition->free;
$this->assertSame($expectFree, $free->toArray());
$this->assertSame($expectPremium, $premium->toArray());
}
/*
|------------------------------------------------
| HOM Sort and SortBydesc
|------------------------------------------------
*/
public function testSortOrSortByDesc()
{
$collection = collect([
[ 'name' => 'Desk', 'price' => 200 ],
[ 'name' => 'Chair', 'price' => 100 ],
[ 'name' => 'Bookcase', 'price' => 150 ],
]);
$expectSorted = [
[ 'name' => 'Chair', 'price' => 100 ],
[ 'name' => 'Bookcase', 'price' => 150 ],
[ 'name' => 'Desk', 'price' => 200 ],
];
$expectSortedByDesc = [
[ 'name' => 'Desk', 'price' => 200 ],
[ 'name' => 'Bookcase', 'price' => 150 ],
[ 'name' => 'Chair', 'price' => 100 ],
];
/*
|------------------------------------------------
| 传统用法
|------------------------------------------------
*/
$sorted = $collection->sortBy('price');
$this->assertEquals($expectSorted, $sorted->values()->all());
$sortedByDesc = $collection->sortByDesc('price');
$this->assertEquals($expectSortedByDesc, $sortedByDesc->values()->all());
/*
|------------------------------------------------
| HOM 用法
|------------------------------------------------
*/
$sortedHOM = $collection->sortBy->price;
$this->assertEquals($expectSorted, $sortedHOM->values()->all());
$sortedByDescHOM = $collection->sortByDesc->price;
$this->assertEquals($expectSortedByDesc, $sortedByDescHOM->values()->all());
}
/*
|------------------------------------------------
| HOM sum
|------------------------------------------------
*/
public function testSum()
{
$iceCreams = [ (object) [ 'iceCream' => 40 ], (object) [ 'iceCream' => 60 ] ];
$c = new Collection($iceCreams);
/*
|------------------------------------------------
| 传统用法
|------------------------------------------------
*/
$this->assertEquals(100, $c->sum('iceCream'));
$this->assertEquals(100, $c->sum(function ($i) {
return $i->iceCream;
}));
/*
|------------------------------------------------
| HOM 用法
|------------------------------------------------
*/
$this->assertEquals(100, $c->sum->iceCream);
}
}
class Person
{
public $name;
/**
* Person constructor.
*
* @param string $name
*/
public function __construct($name)
{
$this->name = $name;
}
public function uppercase()
{
$this->name = strtoupper($this->name);
}
}
class Employees
{
public $name;
public $retired;
/**
* Employees constructor.
*
* @param $name
* @param $retired
*/
public function __construct($name, $retired)
{
$this->name = $name;
$this->retired = $retired;
}
}
class UnreadNotifications
{
public $title;
public $read_at = null;
/**
* UnreadNotifications constructor.
*
* @param $title
*/
public function __construct($title)
{
$this->title = $title;
}
public function markAsRead()
{
$this->read_at = $this->title.' read at 20170119';
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment