Skip to content

Commit

Permalink
Improve formatter DX
Browse files Browse the repository at this point in the history
  • Loading branch information
nyamsprod committed Jun 5, 2022
1 parent 1cbdc7d commit c4236f9
Show file tree
Hide file tree
Showing 10 changed files with 323 additions and 51 deletions.
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Changelog

All Notable changes to `bakame/laravel-intl-formatter` will be documented in this file
All Notable changes to `bakame/intl-formatter` will be documented in this file

## [0.1.0] - 2022-06-04
## [0.1.0] - 2022-06-05

**Initial release!**

Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Laravel Intl Formatter
Intl Formatter
=======================================

[![Author](http://img.shields.io/badge/author-@nyamsprod-blue.svg?style=flat-square)](https://twitter.com/nyamsprod)
Expand All @@ -8,8 +8,8 @@ Laravel Intl Formatter
[![Total Downloads](https://img.shields.io/packagist/dt/bakame/intl-formatter.svg?style=flat-square)](https://packagist.org/packages/bakame/intl-formatter)
[![Sponsor development of this project](https://img.shields.io/badge/sponsor%20this%20package-%E2%9D%A4-ff69b4.svg?style=flat-square)](https://github.com/sponsors/nyamsprod)

The package can be used in any Laravel based application to quickly handle internationalization
by providing helper functions in Blade templates or Laravel codebase.
The package can be used in any PHP application to quickly handle internationalization
by providing classes to format locale, language, timezones, currency and dates.

System Requirements
-------
Expand Down
2 changes: 1 addition & 1 deletion phpunit.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
</report>
</coverage>
<testsuites>
<testsuite name="Bakame Laravel Intl Formatter Test Suite">
<testsuite name="Bakame Intl Formatter Test Suite">
<directory suffix="Test.php">src</directory>
</testsuite>
</testsuites>
Expand Down
84 changes: 66 additions & 18 deletions src/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
namespace Bakame\Intl;

use Bakame\Intl\Options\DateType;
use Bakame\Intl\Options\NumberAttribute;
use Bakame\Intl\Options\NumberStyle;
use Bakame\Intl\Options\SymbolAttribute;
use Bakame\Intl\Options\TextAttribute;
use Bakame\Intl\Options\TimeType;

final class Configuration
Expand All @@ -22,24 +25,24 @@ final class Configuration
public ?string $numberPattern;
/**
* @readonly
* @var array<int, int|float>
* @var array<NumberAttribute>
*/
public array $attributes;
/**
* @readonly
* @var array<int, string>
* @var array<TextAttribute>
*/
public array $textAttributes;
/**
* @readonly
* @var array<int, string>
* @var array<SymbolAttribute>
*/
public array $symbolAttributes;

/**
* @param array<int, int|float> $attributes
* @param array<int, string> $textAttributes
* @param array<int, string> $symbolAttributes
* @param array<NumberAttribute> $attributes
* @param array<TextAttribute> $textAttributes
* @param array<SymbolAttribute> $symbolAttributes
*/
public function __construct(
DateType $dateType,
Expand All @@ -64,16 +67,16 @@ public function __construct(
/**
* @param array{
* date:array{
* dateType:int,
* timeType:int,
* dateFormat:string,
* timeFormat:string,
* pattern?:?string
* },
* number:array{
* style:int,
* style:string,
* pattern?:?string,
* attributes?:array<int, int|float>,
* textAttributes?:array<int,string>,
* symbolAttributes?:array<int,string>
* attributes?:array<string, int|float|string>,
* textAttributes?:array<string,string>,
* symbolAttributes?:array<string,string>
* }
* } $settings
*/
Expand All @@ -100,14 +103,59 @@ public static function fromApplication(array $settings): self
}

return new self(
DateType::from($settings['date']['dateType']),
TimeType::from($settings['date']['timeType']),
NumberStyle::from($settings['number']['style']),
DateType::fromName($settings['date']['dateFormat']),
TimeType::fromName($settings['date']['timeFormat']),
NumberStyle::fromName($settings['number']['style']),
$settings['date']['pattern'],
$settings['number']['pattern'],
$settings['number']['attributes'],
$settings['number']['textAttributes'],
$settings['number']['symbolAttributes'],
self::filterNumberAttributes($settings['number']['attributes']),
self::filterTextAttributes($settings['number']['textAttributes']),
self::filterSymboAttributes($settings['number']['symbolAttributes']),
);
}

/**
* @param array<string,int|float|string> $attributes
*
* @return array<NumberAttribute>
*/
private static function filterNumberAttributes(array $attributes): array
{
$res = [];
foreach ($attributes as $name => $value) {
$res[] = NumberAttribute::from($name, $value);
}

return $res;
}

/**
* @param array<string,string> $attributes
*
* @return array<TextAttribute>
*/
private static function filterTextAttributes(array $attributes): array
{
$res = [];
foreach ($attributes as $name => $value) {
$res[] = TextAttribute::from($name, $value);
}

return $res;
}

/**
* @param array<string,string> $attributes
*
* @return array<SymbolAttribute>
*/
private static function filterSymboAttributes(array $attributes): array
{
$res = [];
foreach ($attributes as $name => $value) {
$res[] = SymbolAttribute::from($name, $value);
}

return $res;
}
}
101 changes: 101 additions & 0 deletions src/ConfigurationTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
<?php

declare(strict_types=1);

namespace Bakame\Intl;

use Bakame\Intl\Options\DateType;
use Bakame\Intl\Options\NumberAttribute;
use Bakame\Intl\Options\NumberStyle;
use Bakame\Intl\Options\TimeType;
use IntlDateFormatter;
use NumberFormatter;
use PHPUnit\Framework\TestCase;

final class ConfigurationTest extends TestCase
{
/** @test */
public function it_can_be_instantiated_with_only_required_properties(): void
{
$config = new Configuration(
DateType::fromName('full'),
TimeType::fromName('short'),
NumberStyle::fromName('currency'),
null,
'',
[NumberAttribute::from('grouping_used', 2)],
);

self::assertCount(1, $config->attributes);
self::assertSame(NumberFormatter::GROUPING_USED, $config->attributes[0]->name);
self::assertSame(2, $config->attributes[0]->value);
self::assertCount(0, $config->textAttributes);
self::assertCount(0, $config->symbolAttributes);
self::assertNull($config->datePattern);
self::assertEmpty($config->numberPattern);
self::assertSame(IntlDateFormatter::FULL, $config->dateType->value);
self::assertSame(IntlDateFormatter::SHORT, $config->timeType->value);
self::assertSame(NumberFormatter::CURRENCY, $config->style->value);
}

/** @test */
public function it_can_be_instantiated_with_only_required_properties_via_settings(): void
{
$config = Configuration::fromApplication([
'date' => [
'dateFormat' => 'full',
'timeFormat' => 'short',
],
'number' => [
'style' => 'currency',
],
]);

self::assertCount(0, $config->attributes);
self::assertCount(0, $config->textAttributes);
self::assertCount(0, $config->symbolAttributes);
self::assertNull($config->datePattern);
self::assertNull($config->numberPattern);
self::assertSame(IntlDateFormatter::FULL, $config->dateType->value);
self::assertSame(IntlDateFormatter::SHORT, $config->timeType->value);
self::assertSame(NumberFormatter::CURRENCY, $config->style->value);
}

/** @test */
public function it_fails_load_configuration_with_invalid_attribute_name(): void
{
$this->expectException(FailedFormatting::class);

Configuration::fromApplication([
'date' => [
'dateFormat' => 'full',
'timeFormat' => 'short',
],
'number' => [
'style' => 'currency',
'attributes' => [
'foobar' => 1,
],
],
]);
}

/** @test */
public function it_fails_load_configuration_with_invalid_attribute_value(): void
{
$this->expectException(FailedFormatting::class);

Configuration::fromApplication([
'date' => [
'dateFormat' => 'full',
'timeFormat' => 'short',
],
'number' => [
'style' => 'currency',
'attributes' => [
'grouping_used' => '2',
],
],
]);
}
}
12 changes: 6 additions & 6 deletions src/Formatter.php
Original file line number Diff line number Diff line change
Expand Up @@ -283,16 +283,16 @@ private function setNumberFormatterAttributes(NumberFormatter $numberFormatter,

private function addDefaultAttributes(NumberFormatter $numberFormatter): void
{
foreach ($this->configuration->attributes as $attribute => $value) {
$numberFormatter->setAttribute($attribute, $value);
foreach ($this->configuration->attributes as $attribute) {
$attribute->addTo($numberFormatter);
}

foreach ($this->configuration->textAttributes as $attribute => $value) {
$numberFormatter->setTextAttribute($attribute, $value);
foreach ($this->configuration->textAttributes as $textAttribute) {
$textAttribute->addTo($numberFormatter);
}

foreach ($this->configuration->symbolAttributes as $attribute => $value) {
$numberFormatter->setSymbol($attribute, $value);
foreach ($this->configuration->symbolAttributes as $symbolAttribute) {
$symbolAttribute->addTo($numberFormatter);
}

if (null !== $this->configuration->numberPattern) {
Expand Down
20 changes: 9 additions & 11 deletions src/FormatterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@
use DateTime;
use DateTimeImmutable;
use DateTimeZone;
use IntlDateFormatter;
use NumberFormatter;
use PHPUnit\Framework\TestCase;

/**
Expand All @@ -25,11 +23,11 @@ protected function setUp(): void
$this->formatter = new Formatter(
Configuration::fromApplication([
'date' => [
'dateType' => IntlDateFormatter::FULL,
'timeType' => IntlDateFormatter::FULL,
'dateFormat' => 'full',
'timeFormat' => 'full',
],
'number' => [
'style' => NumberFormatter::DECIMAL,
'style' => 'decimal',
],
]),
SystemDateResolver::fromSystem()
Expand All @@ -41,14 +39,14 @@ public function it_can_be_instantiated_with_a_different_configuration(): void
{
$configuration = Configuration::fromApplication([
'date' => [
'dateType' => IntlDateFormatter::FULL,
'timeType' => IntlDateFormatter::FULL,
'dateFormat' => 'full',
'timeFormat' => 'full',
],
'number' => [
'style' => NumberFormatter::DECIMAL,
'attributes' => [NumberFormatter::FRACTION_DIGITS => 1],
'textAttributes' => [NumberFormatter::POSITIVE_PREFIX => '++'],
'symbolAttributes' => [NumberFormatter::DECIMAL_SEPARATOR_SYMBOL => 'x'],
'style' => 'decimal',
'attributes' => ['fraction_digit' => 1],
'textAttributes' => ['positive_prefix' => '++'],
'symbolAttributes' => ['decimal_separator' => 'x'],
],
]);

Expand Down
39 changes: 29 additions & 10 deletions src/Options/DateType.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,34 @@

use IntlDateFormatter;

final class DateType extends PseudoEnum
{
protected const CONSTANTS = [
'none' => IntlDateFormatter::NONE,
'short' => IntlDateFormatter::SHORT,
'medium' => IntlDateFormatter::MEDIUM,
'long' => IntlDateFormatter::LONG,
'full' => IntlDateFormatter::FULL,
];
if (7 < PHP_MAJOR_VERSION && extension_loaded('intl')) {
final class DateType extends PseudoEnum
{
protected const CONSTANTS = [
'none' => IntlDateFormatter::NONE,
'short' => IntlDateFormatter::SHORT,
'medium' => IntlDateFormatter::MEDIUM,
'long' => IntlDateFormatter::LONG,
'full' => IntlDateFormatter::FULL,
'relative_short' => IntlDateFormatter::RELATIVE_SHORT,
'relative_medium' => IntlDateFormatter::RELATIVE_MEDIUM,
'relative_long' => IntlDateFormatter::RELATIVE_LONG,
'relative_full' => IntlDateFormatter::RELATIVE_FULL,
];

protected static string $description = 'date format';
protected static string $description = 'date format';
}
} else {
final class DateType extends PseudoEnum
{
protected const CONSTANTS = [
'none' => IntlDateFormatter::NONE,
'short' => IntlDateFormatter::SHORT,
'medium' => IntlDateFormatter::MEDIUM,
'long' => IntlDateFormatter::LONG,
'full' => IntlDateFormatter::FULL,
];

protected static string $description = 'date format';
}
}
Loading

0 comments on commit c4236f9

Please sign in to comment.