Skip to content

Commit

Permalink
feat(support): adds string pluralizer
Browse files Browse the repository at this point in the history
  • Loading branch information
innocenzi authored Sep 18, 2024
1 parent 4785aea commit 32fb3e9
Show file tree
Hide file tree
Showing 10 changed files with 195 additions and 2 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- Add `LanguageHelper::pluralize` and `LanguageHelper::singularize`
- Unit tests for the CommandBus `dispatch` method.
- Replaced Ignition with Whoops.
- Properly detect environment from `.env` when present.
- `discovery:cache` command that will generate the discovery cache
- `discovery:cache` command that will generate the discovery cache
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"description": "The PHP framework that gets out of your way.",
"license": "MIT",
"require": {
"doctrine/inflector": "^2.0",
"egulias/email-validator": "^4.0.2",
"ext-dom": "*",
"ext-fileinfo": "*",
Expand Down
4 changes: 3 additions & 1 deletion src/Tempest/Support/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
"license": "MIT",
"minimum-stability": "dev",
"require": {
"php": "^8.3"
"php": "^8.3",
"doctrine/inflector": "^2.0",
"tempest/container": "self.version"
},
"autoload": {
"psr-4": {
Expand Down
14 changes: 14 additions & 0 deletions src/Tempest/Support/src/LanguageHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@

namespace Tempest\Support;

use Countable;
use function Tempest\get;
use Tempest\Support\Pluralizer\Pluralizer;

final class LanguageHelper
{
/**
Expand All @@ -19,4 +23,14 @@ public static function join(array $parts): string

return $last;
}

public static function pluralize(string $value, int|array|Countable $count = 2): string
{
return get(Pluralizer::class)->pluralize($value, $count);
}

public static function singularize(string $value): string
{
return get(Pluralizer::class)->singularize($value);
}
}
50 changes: 50 additions & 0 deletions src/Tempest/Support/src/Pluralizer/InflectorPluralizer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

declare(strict_types=1);

namespace Tempest\Support\Pluralizer;

use Countable;
use Doctrine\Inflector\Inflector;
use Doctrine\Inflector\InflectorFactory;

final class InflectorPluralizer implements Pluralizer
{
private Inflector $inflector;

public function __construct(string $language = 'english')
{
$this->inflector = InflectorFactory::createForLanguage($language)->build();
}

public function pluralize(string $value, int|array|Countable $count = 2): string
{
if (is_countable($count)) {
$count = count($count);
}

if ((int) abs($count) === 1 || preg_match('/^(.*)[A-Za-z0-9\x{0080}-\x{FFFF}]$/u', $value) == 0) {
return $value;
}

return $this->matchCase($this->inflector->pluralize($value), $value);
}

public function singularize(string $value): string
{
return $this->matchCase($this->inflector->singularize($value), $value);
}

private function matchCase(string $value, string $comparison): string
{
$functions = ['mb_strtolower', 'mb_strtoupper', 'ucfirst', 'ucwords'];

foreach ($functions as $function) {
if ($function($comparison) === $comparison) {
return $function($value);
}
}

return $value;
}
}
14 changes: 14 additions & 0 deletions src/Tempest/Support/src/Pluralizer/Pluralizer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

declare(strict_types=1);

namespace Tempest\Support\Pluralizer;

use Countable;

interface Pluralizer
{
public function pluralize(string $value, int|array|Countable $count = 2): string;

public function singularize(string $value): string;
}
16 changes: 16 additions & 0 deletions src/Tempest/Support/src/Pluralizer/PluralizerInitializer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

declare(strict_types=1);

namespace Tempest\Support\Pluralizer;

use Tempest\Container\Container;
use Tempest\Container\Initializer;

final readonly class PluralizerInitializer implements Initializer
{
public function initialize(Container $container): Pluralizer
{
return new InflectorPluralizer();
}
}
23 changes: 23 additions & 0 deletions src/Tempest/Support/tests/LanguageHelperTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

declare(strict_types=1);

namespace Tempest\Support\Tests;

use PHPUnit\Framework\Attributes\TestWith;
use PHPUnit\Framework\TestCase;
use Tempest\Support\LanguageHelper;

/**
* @internal
* @small
*/
final class LanguageHelperTest extends TestCase
{
#[TestWith([['Jon', 'Jane'], 'Jon and Jane'])]
#[TestWith([['Jon', 'Jane', 'Jill'], 'Jon, Jane and Jill'])]
public function test_join(array $parts, string $expected): void
{
$this->assertEquals($expected, LanguageHelper::join($parts));
}
}
38 changes: 38 additions & 0 deletions src/Tempest/Support/tests/Pluralizer/InflectorPluralizerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

declare(strict_types=1);

namespace Tempest\Support\Tests\Pluralizer;

use Countable;
use PHPUnit\Framework\Attributes\TestWith;
use PHPUnit\Framework\TestCase;
use Tempest\Support\Pluralizer\InflectorPluralizer;

/**
* @internal
* @small
*/
final class InflectorPluralizerTest extends TestCase
{
#[TestWith(['migration', 'migrations', 0])]
#[TestWith(['migration', 'migration', 1])]
#[TestWith(['Migration', 'Migrations', 2])]
#[TestWith(['migration', 'migrations', 2])]
#[TestWith(['migration', 'migrations', [1, 2]])]
public function test_that_pluralizer_pluralizes(string $value, string $expected, int|array|Countable $count): void
{
$pluralizer = new InflectorPluralizer();

$this->assertEquals($expected, $pluralizer->pluralize($value, $count));
}

#[TestWith(['Migrations', 'Migration'])]
#[TestWith(['migrations', 'migration'])]
public function test_that_pluralizer_singularizes(string $value, string $expected): void
{
$pluralizer = new InflectorPluralizer();

$this->assertEquals($expected, $pluralizer->singularize($value));
}
}
34 changes: 34 additions & 0 deletions tests/Integration/Support/LanguageHelperTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

declare(strict_types=1);

namespace Tests\Tempest\Integration\Support;

use Countable;
use PHPUnit\Framework\Attributes\TestWith;
use Tempest\Support\LanguageHelper;
use Tests\Tempest\Integration\FrameworkIntegrationTestCase;

/**
* @internal
* @small
*/
final class LanguageHelperTest extends FrameworkIntegrationTestCase
{
#[TestWith(['migration', 'migrations', 0])]
#[TestWith(['migration', 'migration', 1])]
#[TestWith(['Migration', 'Migrations', 2])]
#[TestWith(['migration', 'migrations', 2])]
#[TestWith(['migration', 'migrations', [1, 2]])]
public function test_that_pluralize_pluralizes(string $value, string $expected, int|array|Countable $count): void
{
$this->assertEquals($expected, LanguageHelper::pluralize($value, $count));
}

#[TestWith(['Migrations', 'Migration'])]
#[TestWith(['migrations', 'migration'])]
public function test_that_pluralizer_singularizes(string $value, string $expected): void
{
$this->assertEquals($expected, LanguageHelper::singularize($value));
}
}

0 comments on commit 32fb3e9

Please sign in to comment.