Skip to content

Commit

Permalink
add getCaseInsensitive and hasCaseInsensitive
Browse files Browse the repository at this point in the history
  • Loading branch information
freekmurze committed Jun 30, 2023
1 parent 16846aa commit 3577ede
Show file tree
Hide file tree
Showing 56 changed files with 2,032 additions and 2,749 deletions.
5 changes: 4 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@
"amphp/parallel-functions": "^1.1.0",
"mockery/mockery": "^1.4.2",
"orchestra/testbench": "^6.23|^7.0|^8.0",
"phpunit/phpunit": "^9.4.4",
"pestphp/pest": "dev-develop as 2.99",
"pestphp/pest-plugin-drift": "2.x-dev",
"pestphp/pest-plugin-type-coverage": "2.x-dev",
"phpunit/phpunit": "10.2.2",
"spatie/laravel-ray": "^1.29",
"symfony/stopwatch": "^5.2|^6.0"
},
Expand Down
15 changes: 15 additions & 0 deletions phpunit.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.2/phpunit.xsd" bootstrap="vendor/autoload.php" colors="true">
<testsuites>
<testsuite name="Test Suite">
<directory suffix="Test.php">./tests</directory>
</testsuite>
</testsuites>
<coverage/>
<source>
<include>
<directory suffix=".php">./app</directory>
<directory suffix=".php">./src</directory>
</include>
</source>
</phpunit>
4 changes: 4 additions & 0 deletions src/CollectionMacroServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

use Illuminate\Support\Collection;
use Illuminate\Support\ServiceProvider;
use Spatie\CollectionMacros\Macros\GetCaseInsensitive;
use Spatie\CollectionMacros\Macros\HasCaseInsensitive;

class CollectionMacroServiceProvider extends ServiceProvider
{
Expand Down Expand Up @@ -33,9 +35,11 @@ private function macros(): array
'firstOrPush' => \Spatie\CollectionMacros\Macros\FirstOrPush::class,
'fourth' => \Spatie\CollectionMacros\Macros\Fourth::class,
'fromPairs' => \Spatie\CollectionMacros\Macros\FromPairs::class,
'getCaseInsensitive' => \Spatie\CollectionMacros\Macros\GetCaseInsensitive::class,
'getNth' => \Spatie\CollectionMacros\Macros\GetNth::class,
'glob' => \Spatie\CollectionMacros\Macros\Glob::class,
'groupByModel' => \Spatie\CollectionMacros\Macros\GroupByModel::class,
'hasCaseInsensitive' => \Spatie\CollectionMacros\Macros\HasCaseInsensitive::class,
'head' => \Spatie\CollectionMacros\Macros\Head::class,
'if' => \Spatie\CollectionMacros\Macros\IfMacro::class,
'ifAny' => \Spatie\CollectionMacros\Macros\IfAny::class,
Expand Down
34 changes: 34 additions & 0 deletions src/Macros/GetCaseInsensitive.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

namespace Spatie\CollectionMacros\Macros;

/**
* Get the value of a given key. If $key is a string, we'll search for the
* key using a case-insensitive comparison.
*
* @param string|callable $callback
* @param bool $preserveKeys
* @param mixed $modelKey
* @param mixed $itemsKey
*
* @mixin \Illuminate\Support\Collection
*
* @return \Illuminate\Support\Collection
*/
class GetCaseInsensitive
{
public function __invoke()
{
return function (mixed $key): mixed {
$matchingKey = $this->search(function ($value, $collectionKey) use ($key) {
return strcasecmp($collectionKey, $key) === 0;
});

if ($matchingKey === false) {
return null;
}

return $this->get($matchingKey);
};
}
}
30 changes: 30 additions & 0 deletions src/Macros/HasCaseInsensitive.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

namespace Spatie\CollectionMacros\Macros;

/**
* Determine if the collection contains a key with a given name.
* If $key is a string, we'll search for the key using a case-insensitive comparison.
*
* @param string|callable $callback
* @param bool $preserveKeys
* @param mixed $modelKey
* @param mixed $itemsKey
*
* @mixin \Illuminate\Support\Collection
*
* @return \Illuminate\Support\Collection
*/
class HasCaseInsensitive
{
public function __invoke()
{
return function (mixed $key): bool {
$matchingKey = $this->search(function ($value, $collectionKey) use ($key) {
return strcasecmp($collectionKey, $key) === 0;
});

return $matchingKey !== false;
};
}
}
4 changes: 3 additions & 1 deletion src/Macros/ParallelMap.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@
use Illuminate\Support\Collection;

/**
* Idential to map but each item will be processed in parallel.
* @deprecated This function will be removed in the next major release.
*
* Identical to map but each item will be processed in parallel.
*
* This function requires the installation of amphp/parallel-functions
*
Expand Down
6 changes: 6 additions & 0 deletions tests/Feature/ExampleTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?php


test('example', function () {
expect(true)->toBeTrue();
});
87 changes: 35 additions & 52 deletions tests/Macros/AfterTest.php
Original file line number Diff line number Diff line change
@@ -1,69 +1,52 @@
<?php

namespace Spatie\CollectionMacros\Test\Macros;

use Illuminate\Support\Collection;
use Spatie\CollectionMacros\Test\TestCase;

class AfterTest extends TestCase
{
/** @test */
public function it_can_retrieve_an_item_that_comes_after_an_item()
{
$data = new Collection([1, 2, 3]);
it('can retrieve an item that comes after an item', function () {
$data = new Collection([1, 2, 3]);

$this->assertEquals(2, $data->after(1));
}
expect($data->after(1))->toEqual(2);
});

/** @test */
public function it_retrieves_items_by_value_and_doesnt_reorder_them()
{
$data = new Collection([
4 => 3,
2 => 1,
1 => 2,
3 => 4,
]);
it('retrieves items by value and doesnt reorder them', function () {
$data = new Collection([
4 => 3,
2 => 1,
1 => 2,
3 => 4,
]);

$this->assertEquals(1, $data->after(3));
}
expect($data->after(3))->toEqual(1);
});

/** @test */
public function it_can_find_the_next_item_in_a_collection_of_strings()
{
$data = new Collection([
'foo' => 'bar',
'bar' => 'foo',
]);
it('can find the next item in a collection of strings', function () {
$data = new Collection([
'foo' => 'bar',
'bar' => 'foo',
]);

$this->assertEquals('foo', $data->after('bar'));
}
expect($data->after('bar'))->toEqual('foo');
});

/** @test */
public function it_can_find_the_next_item_based_on_a_callback()
{
$data = new Collection([3, 1, 2]);
it('can find the next item based on a callback', function () {
$data = new Collection([3, 1, 2]);

$result = $data->after(function ($item) {
return $item > 2;
});
$result = $data->after(function ($item) {
return $item > 2;
});

$this->assertEquals(1, $result);
}
expect($result)->toEqual(1);
});

/** @test */
public function it_returns_null_if_there_isnt_a_next_item()
{
$data = new Collection([1, 2, 3]);
it('returns null if there isnt a next item', function () {
$data = new Collection([1, 2, 3]);

$this->assertNull($data->after(3));
}
expect($data->after(3))->toBeNull();
});

/** @test */
public function it_can_return_a_fallback_value_if_there_isnt_a_next_item()
{
$data = new Collection([1, 2, 3]);
it('can return a fallback value if there isnt a next item', function () {
$data = new Collection([1, 2, 3]);

$this->assertEquals(4, $data->after(3, 4));
}
}
expect($data->after(3, 4))->toEqual(4);
});
47 changes: 18 additions & 29 deletions tests/Macros/AtTest.php
Original file line number Diff line number Diff line change
@@ -1,33 +1,22 @@
<?php

namespace Spatie\CollectionMacros\Test\Macros;

use Illuminate\Support\Collection;
use Spatie\CollectionMacros\Test\TestCase;

class AtTest extends TestCase
{
/** @test */
public function it_retrieves_an_item_by_positive_index()
{
$data = new Collection([1, 2, 3]);

$this->assertEquals(2, $data->at(1));
}

/** @test */
public function it_retrieves_an_item_by_negative_index()
{
$data = new Collection([1, 2, 3]);

$this->assertEquals(3, $data->at(-1));
}

/** @test */
public function it_retrieves_an_item_by_zero_index()
{
$data = new Collection([1, 2, 3]);

$this->assertEquals(1, $data->at(0));
}
}

it('retrieves an item by positive index', function () {
$data = new Collection([1, 2, 3]);

expect($data->at(1))->toEqual(2);
});

it('retrieves an item by negative index', function () {
$data = new Collection([1, 2, 3]);

expect($data->at(-1))->toEqual(3);
});

it('retrieves an item by zero index', function () {
$data = new Collection([1, 2, 3]);

expect($data->at(0))->toEqual(1);
});
87 changes: 35 additions & 52 deletions tests/Macros/BeforeTest.php
Original file line number Diff line number Diff line change
@@ -1,69 +1,52 @@
<?php

namespace Spatie\CollectionMacros\Test\Macros;

use Illuminate\Support\Collection;
use Spatie\CollectionMacros\Test\TestCase;

class BeforeTest extends TestCase
{
/** @test */
public function it_can_retrieve_an_item_that_comes_before_an_item()
{
$data = new Collection([1, 2, 3]);
it('can retrieve an item that comes before an item', function () {
$data = new Collection([1, 2, 3]);

$this->assertEquals(1, $data->before(2));
}
expect($data->before(2))->toEqual(1);
});

/** @test */
public function it_retrieves_items_by_value_and_doesnt_reorder_them()
{
$data = new Collection([
4 => 3,
2 => 1,
1 => 2,
3 => 4,
]);
it('retrieves items by value and doesnt reorder them', function () {
$data = new Collection([
4 => 3,
2 => 1,
1 => 2,
3 => 4,
]);

$this->assertEquals(2, $data->before(4));
}
expect($data->before(4))->toEqual(2);
});

/** @test */
public function it_can_find_the_previous_item_in_a_collection_of_strings()
{
$data = new Collection([
'foo' => 'bar',
'bar' => 'foo',
]);
it('can find the previous item in a collection of strings', function () {
$data = new Collection([
'foo' => 'bar',
'bar' => 'foo',
]);

$this->assertEquals('bar', $data->before('foo'));
}
expect($data->before('foo'))->toEqual('bar');
});

/** @test */
public function it_can_find_the_previous_item_based_on_a_callback()
{
$data = new Collection([3, 1, 2]);
it('can find the previous item based on a callback', function () {
$data = new Collection([3, 1, 2]);

$result = $data->before(function ($item) {
return $item < 2;
});
$result = $data->before(function ($item) {
return $item < 2;
});

$this->assertEquals(3, $result);
}
expect($result)->toEqual(3);
});

/** @test */
public function it_returns_null_if_there_isnt_a_previous_item()
{
$data = new Collection([1, 2, 3]);
it('returns null if there isnt a previous item', function () {
$data = new Collection([1, 2, 3]);

$this->assertNull($data->before(1));
}
expect($data->before(1))->toBeNull();
});

/** @test */
public function it_can_return_a_fallback_value_if_there_isnt_a_previous_item()
{
$data = new Collection([1, 2, 3]);
it('can return a fallback value if there isnt a previous item', function () {
$data = new Collection([1, 2, 3]);

$this->assertEquals('The void', $data->before(1, 'The void'));
}
}
expect($data->before(1, 'The void'))->toEqual('The void');
});
Loading

0 comments on commit 3577ede

Please sign in to comment.