Skip to content

Commit

Permalink
Added color extension to core
Browse files Browse the repository at this point in the history
  • Loading branch information
pimjansen committed Jan 28, 2022
1 parent dc988fe commit cbf6b6c
Show file tree
Hide file tree
Showing 4 changed files with 321 additions and 0 deletions.
180 changes: 180 additions & 0 deletions src/Faker/Core/Color.php
@@ -0,0 +1,180 @@
<?php

declare(strict_types=1);

namespace Faker\Core;

use Faker\Extension;
use Faker\Extension\Helper;

/**
* @experimental This class is experimental and does not fall under our BC promise
*/
final class Color implements Extension\ColorExtension
{
/**
* @var string[]
*/
private array $safeColorNames = [
'black', 'maroon', 'green', 'navy', 'olive',
'purple', 'teal', 'lime', 'blue', 'silver',
'gray', 'yellow', 'fuchsia', 'aqua', 'white',
];

/**
* @var string[]
*/
private array $allColorNames = [
'AliceBlue', 'AntiqueWhite', 'Aqua', 'Aquamarine',
'Azure', 'Beige', 'Bisque', 'Black', 'BlanchedAlmond',
'Blue', 'BlueViolet', 'Brown', 'BurlyWood', 'CadetBlue',
'Chartreuse', 'Chocolate', 'Coral', 'CornflowerBlue',
'Cornsilk', 'Crimson', 'Cyan', 'DarkBlue', 'DarkCyan',
'DarkGoldenRod', 'DarkGray', 'DarkGreen', 'DarkKhaki',
'DarkMagenta', 'DarkOliveGreen', 'Darkorange', 'DarkOrchid',
'DarkRed', 'DarkSalmon', 'DarkSeaGreen', 'DarkSlateBlue',
'DarkSlateGray', 'DarkTurquoise', 'DarkViolet', 'DeepPink',
'DeepSkyBlue', 'DimGray', 'DimGrey', 'DodgerBlue', 'FireBrick',
'FloralWhite', 'ForestGreen', 'Fuchsia', 'Gainsboro', 'GhostWhite',
'Gold', 'GoldenRod', 'Gray', 'Green', 'GreenYellow', 'HoneyDew',
'HotPink', 'IndianRed', 'Indigo', 'Ivory', 'Khaki', 'Lavender',
'LavenderBlush', 'LawnGreen', 'LemonChiffon', 'LightBlue', 'LightCoral',
'LightCyan', 'LightGoldenRodYellow', 'LightGray', 'LightGreen', 'LightPink',
'LightSalmon', 'LightSeaGreen', 'LightSkyBlue', 'LightSlateGray', 'LightSteelBlue',
'LightYellow', 'Lime', 'LimeGreen', 'Linen', 'Magenta', 'Maroon', 'MediumAquaMarine',
'MediumBlue', 'MediumOrchid', 'MediumPurple', 'MediumSeaGreen', 'MediumSlateBlue',
'MediumSpringGreen', 'MediumTurquoise', 'MediumVioletRed', 'MidnightBlue',
'MintCream', 'MistyRose', 'Moccasin', 'NavajoWhite', 'Navy', 'OldLace', 'Olive',
'OliveDrab', 'Orange', 'OrangeRed', 'Orchid', 'PaleGoldenRod', 'PaleGreen',
'PaleTurquoise', 'PaleVioletRed', 'PapayaWhip', 'PeachPuff', 'Peru', 'Pink', 'Plum',
'PowderBlue', 'Purple', 'Red', 'RosyBrown', 'RoyalBlue', 'SaddleBrown', 'Salmon',
'SandyBrown', 'SeaGreen', 'SeaShell', 'Sienna', 'Silver', 'SkyBlue', 'SlateBlue',
'SlateGray', 'Snow', 'SpringGreen', 'SteelBlue', 'Tan', 'Teal', 'Thistle', 'Tomato',
'Turquoise', 'Violet', 'Wheat', 'White', 'WhiteSmoke', 'Yellow', 'YellowGreen',
];

/**
* @example '#fa3cc2'
*/
public function hexColor(): string
{
$number = new Number();

return '#' . str_pad(dechex($number->numberBetween(1, 16777215)), 6, '0', STR_PAD_LEFT);
}

/**
* @example '#ff0044'
*/
public function safeHexColor(): string
{
$number = new Number();
$color = str_pad(dechex($number->numberBetween(0, 255)), 3, '0', STR_PAD_LEFT);

return sprintf(
'#%s%s%s%s%s%s',
$color[0],
$color[0],
$color[1],
$color[1],
$color[2],
$color[2]
);
}

/**
* @example 'array(0,255,122)'
*
* @return string[]
*/
public function rgbColorAsArray(): array
{
$color = $this->hexColor();

return [
hexdec(substr($color, 1, 2)),
hexdec(substr($color, 3, 2)),
hexdec(substr($color, 5, 2)),
];
}

/**
* @example '0,255,122'
*/
public function rgbColor(): string
{
return implode(',', $this->rgbColorAsArray());
}

/**
* @example 'rgb(0,255,122)'
*/
public function rgbCssColor(): string
{
return sprintf(
'rgb(%s)',
$this->rgbColor()
);
}

/**
* @example 'rgba(0,255,122,0.8)'
*/
public function rgbaCssColor(): string
{
$number = new Number();

return sprintf(
'rgba(%s,%s)',
$this->rgbColor(),
$number->randomFloat(1, 0, 1)
);
}

/**
* @example 'blue'
*/
public function safeColorName(): string
{
return Helper::randomElement($this->safeColorNames);
}

/**
* @example 'NavajoWhite'
*/
public function colorName(): string
{
return Helper::randomElement($this->allColorNames);
}

/**
* @example '340,50,20'
*/
public function hslColor(): string
{
$number = new Number();

return sprintf(
'%s,%s,%s',
$number->numberBetween(0, 360),
$number->numberBetween(0, 100),
$number->numberBetween(0, 100)
);
}

/**
* @example array(340, 50, 20)
*
* @return string[]
*/
public function hslColorAsArray(): array
{
$number = new Number();

return [
$number->numberBetween(0, 360),
$number->numberBetween(0, 100),
$number->numberBetween(0, 100),
];
}
}
63 changes: 63 additions & 0 deletions src/Faker/Extension/ColorExtension.php
@@ -0,0 +1,63 @@
<?php

namespace Faker\Extension;

/**
* @experimental This interface is experimental and does not fall under our BC promise
*/
interface ColorExtension extends Extension
{
/**
* @example '#fa3cc2'
*/
public function hexColor(): string;

/**
* @example '#ff0044'
*/
public function safeHexColor(): string;

/**
* @example 'array(0,255,122)'
*
* @return string[]
*/
public function rgbColorAsArray(): array;

/**
* @example '0,255,122'
*/
public function rgbColor(): string;

/**
* @example 'rgb(0,255,122)'
*/
public function rgbCssColor(): string;

/**
* @example 'rgba(0,255,122,0.8)'
*/
public function rgbaCssColor(): string;

/**
* @example 'blue'
*/
public function safeColorName(): string;

/**
* @example 'NavajoWhite'
*/
public function colorName(): string;

/**
* @example '340,50,20'
*/
public function hslColor(): string;

/**
* @example array(340, 50, 20)
*
* @return string[]
*/
public function hslColorAsArray(): array;
}
1 change: 1 addition & 0 deletions src/Faker/Extension/ContainerBuilder.php
Expand Up @@ -63,6 +63,7 @@ public static function defaultExtensions(): array
return [
BarcodeExtension::class => Core\Barcode::class,
BloodExtension::class => Core\Blood::class,
ColorExtension::class => Core\Color::class,
FileExtension::class => Core\File::class,
NumberExtension::class => Core\Number::class,
VersionExtension::class => Core\Version::class,
Expand Down
77 changes: 77 additions & 0 deletions test/Faker/Core/ColorTest.php
@@ -0,0 +1,77 @@
<?php

declare(strict_types=1);

namespace Faker\Test\Core;

use Faker\Core\Color;
use Faker\Test\TestCase;

final class ColorTest extends TestCase
{
public function testHexColor()
{
$color = new Color();
self::assertMatchesRegularExpression('/^#[a-f0-9]{6}$/i', $color->hexColor());
}

public function testSafeHexColor()
{
$color = new Color();
self::assertMatchesRegularExpression('/^#[a-f0-9]{6}$/i', $color->safeHexColor());
}

public function testRgbColorAsArray()
{
$color = new Color();
self::assertCount(3, $color->rgbColorAsArray());
}

public function testRgbColor()
{
$color = new Color();
$regexp = '([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])';
self::assertMatchesRegularExpression('/^' . $regexp . ',' . $regexp . ',' . $regexp . '$/i', $color->rgbColor());
}

public function testRgbCssColor()
{
$color = new Color();
$regexp = '([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])';
self::assertMatchesRegularExpression('/^rgb\(' . $regexp . ',' . $regexp . ',' . $regexp . '\)$/i', $color->rgbCssColor());
}

public function testRgbaCssColor()
{
$color = new Color();
$regexp = '([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])';
$regexpAlpha = '([01]?(\.\d+)?)';
self::assertMatchesRegularExpression('/^rgba\(' . $regexp . ',' . $regexp . ',' . $regexp . ',' . $regexpAlpha . '\)$/i', $color->rgbaCssColor());
}

public function testSafeColorName()
{
$color = new Color();
self::assertMatchesRegularExpression('/^[\w]+$/', $color->safeColorName());
}

public function testColorName()
{
$color = new Color();
self::assertMatchesRegularExpression('/^[\w]+$/', $color->colorName());
}

public function testHslColor()
{
$color = new Color();
$regexp360 = '(?:36[0]|3[0-5][0-9]|[12][0-9][0-9]|[1-9]?[0-9])';
$regexp100 = '(?:100|[1-9]?[0-9])';
self::assertMatchesRegularExpression('/^' . $regexp360 . ',' . $regexp100 . ',' . $regexp100 . '$/', $color->hslColor());
}

public function testHslColorArray()
{
$color = new Color();
self::assertCount(3, $color->hslColorAsArray());
}
}

0 comments on commit cbf6b6c

Please sign in to comment.