Skip to content

Commit

Permalink
[2.x] Extract badge style from file format (#46)
Browse files Browse the repository at this point in the history
* Extract badge style from file format

* Make file extension optional

* Add ability to get custom style from query string
  • Loading branch information
antonkomarev authored Jul 28, 2020
1 parent d60ce00 commit 75665a8
Show file tree
Hide file tree
Showing 15 changed files with 140 additions and 88 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
* add CircleCI for build and tests
* add changelog
* configure and run php-cs-fixer with new code style roles
* add setting custom badge style from query string
* add psalm

### Changed
Expand All @@ -20,6 +21,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
* refactoring library to full typed
* upgrade readme
* use class notation in tests
* badge style separated from file format

### Deprecated
* this version works only with php version >= 7.4
Expand Down
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,16 @@ $poser = new Poser($render);

echo $poser->generate('license', 'MIT', '428F7E', 'plastic');
// or
echo $poser->generateFromURI('license-MIT-428F7E.plastic');
echo $poser->generateFromURI('license-MIT-428F7E.svg?style=plastic');
// or
echo $poser->generateFromURI('license-MIT-428F7E?style=plastic');
// or
$image = $poser->generate('license', 'MIT', '428F7E', 'plastic');

echo $image->getFormat();
echo $image->getStyle();
```

The allowed format are: `plastic`, `flat` and `flat-square`.
The allowed styles are: `plastic`, `flat` and `flat-square`.


## Encoding
Expand Down
2 changes: 1 addition & 1 deletion features/ui_command_creating_image_file.feature
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Feature: Generation of an image
I want to use the poser script

Scenario: Create the image running a script with plastic format
When I run "poser license MIT blue -p /tmp/img.svg -f plastic"
When I run "poser license MIT blue -p /tmp/img.svg -s plastic"
Then it should pass
And the content of "/tmp/img.svg" should be equal to "bootstrap/fixtures/license-MIT-blue_plastic.svg"

Expand Down
2 changes: 1 addition & 1 deletion features/ui_command_echo_image.feature
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Feature: Generation of an image by echo-ing the content
I want to use the poser script

Scenario: Echo the image running a script with plastic format
When I run "poser license MIT blue -f plastic"
When I run "poser license MIT blue -s plastic"
Then it should pass
And the same output should be like the content of "bootstrap/fixtures/license-MIT-blue_plastic.svg"

Expand Down
12 changes: 6 additions & 6 deletions spec/PUGX/Poser/BadgeSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ class BadgeSpec extends ObjectBehavior
{
public function it_is_initializable(): void
{
$this->beConstructedWith('a', 'b', '97CA00', 'svg');
$this->beConstructedWith('a', 'b', '97CA00', 'flat');
$this->shouldHaveType(Badge::class);
}

public function it_should_be_constructed_by_fromURI_factory_method(): void
{
$this->beConstructedWith('a', 'b', '97CA00', 'svg');
$this->beConstructedWith('a', 'b', '97CA00', 'flat');
$assert = 'version-stable-97CA00.svg';
$it = Badge::fromURI($assert);

Expand All @@ -27,7 +27,7 @@ public function it_should_be_constructed_by_fromURI_factory_method(): void

public function it_should_be_constructed_by_fromURI_factory_method_escaping_correctly_underscores(): void
{
$this->beConstructedWith('a', 'b', '97CA00', 'svg');
$this->beConstructedWith('a', 'b', '97CA00', 'flat');
$input = 'I__m__liugg__io-b-97CA00.svg';
$assertInput = 'I_m_liugg_io-b-97CA00.svg';
$it = Badge::fromURI($input);
Expand All @@ -39,7 +39,7 @@ public function it_should_be_constructed_by_fromURI_factory_method_escaping_corr

public function it_should_be_constructed_by_fromURI_factory_method_escaping_correctly_with_single_underscore(): void
{
$this->beConstructedWith('a', 'b', '97CA00', 'svg');
$this->beConstructedWith('a', 'b', '97CA00', 'flat');
$input = 'I_m_liuggio-b-97CA00.svg';
$assertInput = 'I m liuggio-b-97CA00.svg';
$it = Badge::fromURI($input);
Expand All @@ -51,7 +51,7 @@ public function it_should_be_constructed_by_fromURI_factory_method_escaping_corr

public function it_should_be_constructed_by_fromURI_factory_method_escaping_correctly_with_dashes(): void
{
$this->beConstructedWith('a', 'b', '97CA00', 'svg');
$this->beConstructedWith('a', 'b', '97CA00', 'flat');
$input = 'I--m--liuggio-b-97CA00.svg';
$assertInput = 'I-m-liuggio-b-97CA00.svg';
$it = Badge::fromURI($input);
Expand All @@ -66,7 +66,7 @@ public function it_should_be_constructed_by_fromURI_factory_method_escaping_corr
*/
public function it_should_validate_available_color_schemes($colorName, $expectedValue): void
{
$this->beConstructedWith('a', 'b', $colorName, 'svg');
$this->beConstructedWith('a', 'b', $colorName, 'flat');
$this->getHexColor()->shouldBeString();
}

Expand Down
52 changes: 49 additions & 3 deletions spec/PUGX/Poser/PoserSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@
use PhpSpec\ObjectBehavior;
use PUGX\Poser\Poser;
use PUGX\Poser\Render\SvgFlatRender;
use PUGX\Poser\Render\SvgFlatSquareRender;

class PoserSpec extends ObjectBehavior
{
public function let(): void
{
$render = new SvgFlatRender();
$this->beConstructedWith([$render]);
$this->beConstructedWith([
new SvgFlatRender(),
new SvgFlatSquareRender(),
]);
}

public function it_is_initializable(): void
Expand All @@ -24,9 +27,10 @@ public function it_should_be_able_to_generate_an_svg_image(): void
$subject = 'stable';
$status = 'v2.0';
$color = '97CA00';
$style = 'flat';
$format = 'svg';

$this->generate($subject, $status, $color, $format)->shouldBeAValidSVGImageContaining($subject, $status);
$this->generate($subject, $status, $color, $style, $format)->shouldBeAValidSVGImageContaining($subject, $status);
}

public function it_should_be_able_to_generate_an_svg_image_from_URI(): void
Expand All @@ -36,6 +40,48 @@ public function it_should_be_able_to_generate_an_svg_image_from_URI(): void
$this->generateFromURI($subject)->shouldBeAValidSVGImageContaining('stable', 'v2.0');
}

public function it_should_be_able_to_generate_an_svg_image_from_URI_without_file_extension(): void
{
$subject = 'stable-v2.0-97CA00';

$this->generateFromURI($subject)->shouldBeAValidSVGImageContaining('stable', 'v2.0');
}

public function it_should_be_able_to_generate_an_svg_image_from_URI_with_style(): void
{
$subject = 'stable-v2.0-97CA00.svg?style=flat-square';

$this->generateFromURI($subject)->shouldBeAValidSVGImageContaining('stable', 'v2.0');
}

public function it_should_be_able_to_generate_an_svg_image_from_URI_with_empty_style(): void
{
$subject = 'stable-v2.0-97CA00.svg?style=';

$this->generateFromURI($subject)->shouldBeAValidSVGImageContaining('stable', 'v2.0');
}

public function it_should_be_able_to_generate_an_svg_image_from_URI_with_empty_query(): void
{
$subject = 'stable-v2.0-97CA00.svg?';

$this->generateFromURI($subject)->shouldBeAValidSVGImageContaining('stable', 'v2.0');
}

public function it_should_be_able_to_generate_an_svg_image_from_URI_without_file_extension_with_style(): void
{
$subject = 'stable-v2.0-97CA00?style=flat-square';

$this->generateFromURI($subject)->shouldBeAValidSVGImageContaining('stable', 'v2.0');
}

public function it_should_throw_exception_on_generate_an_svg_image_with_bad_uri(): void
{
$subject = 'stable-v2.0-';

$this->shouldThrow(\InvalidArgumentException::class)->during('generateFromURI', [$subject]);
}

public function getMatchers(): array
{
return [
Expand Down
29 changes: 22 additions & 7 deletions src/Badge.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

class Badge
{
public const DEFAULT_STYLE = 'flat';
public const DEFAULT_FORMAT = 'svg';

private static array $colorScheme = [
Expand All @@ -21,14 +22,16 @@ class Badge
private string $subject;
private string $status;
private string $color;
private string $style;
private string $format;

public function __construct(string $subject, string $status, string $color, string $format = self::DEFAULT_FORMAT)
public function __construct(string $subject, string $status, string $color, string $style = self::DEFAULT_STYLE, string $format = self::DEFAULT_FORMAT)
{
$this->subject = $this->escapeValue($subject);
$this->status = $this->escapeValue($status);
$this->format = $this->escapeValue($format);
$this->color = $this->getColorHex($color);
$this->style = $this->escapeValue($style);
$this->format = $this->escapeValue($format);

if (!$this->isValidColorHex($this->color)) {
throw new \InvalidArgumentException(\sprintf('Color not valid %s', $this->color));
Expand All @@ -51,19 +54,23 @@ public static function getColorNamesAvailable(): array
*/
public static function fromURI(string $URI): self
{
$regex = '/^(([^-]|--)+)-(([^-]|--)+)-(([^-]|--)+)\.(svg|png|gif|jpg)$/';
$parsedURI = \parse_url($URI);
$path = $parsedURI['path'];
\parse_str($parsedURI['query'] ?? '', $query);

$regex = '/^(([^-]|--)+)-(([^-]|--)+)-(([^-.]|--)+)(\.(svg|png|gif|jpg))?$/';
$match = [];

if (1 !== \preg_match($regex, $URI, $match) && (7 !== \count($match))) {
if (1 !== \preg_match($regex, $path, $match) && (6 > \count($match))) {
throw new \InvalidArgumentException('The URI given is not a valid URI' . $URI);
}

$subject = $match[1];
$status = $match[3];
$color = $match[5];
$format = $match[7];
$style = isset($query['style']) && '' !== $query['style'] ? $query['style'] : self::DEFAULT_STYLE;
$format = $match[8] ?? self::DEFAULT_FORMAT;

return new self($subject, $status, $color, $format);
return new self($subject, $status, $color, $style, $format);
}

/**
Expand All @@ -74,6 +81,14 @@ public function getHexColor(): string
return '#' . $this->color;
}

/**
* @return string the style of the image eg. `flat`.
*/
public function getStyle(): string
{
return $this->style;
}

/**
* @return string the format of the image eg. `svg`.
*/
Expand Down
14 changes: 7 additions & 7 deletions src/Image.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ class Image
{
private string $content;

private string $format;
private string $style;

private function __construct(string $content, string $format)
private function __construct(string $content, string $style)
{
$this->content = $content;
$this->format = $format;
$this->style = $style;
}

/**
Expand All @@ -40,13 +40,13 @@ public function __toString(): string
/**
* Factory method.
*/
public static function createFromString(string $content, string $format): self
public static function createFromString(string $content, string $style): self
{
return new self($content, $format);
return new self($content, $style);
}

public function getFormat(): string
public function getStyle(): string
{
return $this->format;
return $this->style;
}
}
31 changes: 15 additions & 16 deletions src/Poser.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,23 +21,24 @@ public function __construct($renders)
}

foreach ($renders as $render) {
$this->addFormatRender($render);
$this->addStyleRender($render);
}
}

/**
* Generate and Render a badge according to the format.
* Generate and Render a badge according to the style.
*
* @param $subject
* @param $status
* @param $color
* @param $style
* @param $format
*/
public function generate(string $subject, string $status, string $color, string $format): Image
public function generate(string $subject, string $status, string $color, string $style, string $format): Image
{
$badge = new Badge($subject, $status, $color, $format);
$badge = new Badge($subject, $status, $color, $style, $format);

return $this->getRenderFor($badge->getFormat())->render($badge);
return $this->getRenderFor($badge->getStyle())->render($badge);
}

/**
Expand All @@ -50,30 +51,28 @@ public function generateFromURI(string $string): Image
{
$badge = Badge::fromURI($string);

return $this->getRenderFor($badge->getFormat())->render($badge);
return $this->getRenderFor($badge->getStyle())->render($badge);
}

/**
* All the formats available.
* All the styles available.
*/
public function validFormats(): array
public function validStyles(): array
{
return \array_keys($this->renders);
}

private function addFormatRender(RenderInterface $render): void
private function addStyleRender(RenderInterface $render): void
{
foreach ($render->supportedFormats() as $format) {
$this->renders[$format] = $render;
}
$this->renders[$render->getBadgeStyle()] = $render;
}

private function getRenderFor(string $format): RenderInterface
private function getRenderFor(string $style): RenderInterface
{
if (!isset($this->renders[$format])) {
throw new \InvalidArgumentException(\sprintf('No render founds for this format [%s]', $format));
if (!isset($this->renders[$style])) {
throw new \InvalidArgumentException(\sprintf('No render founds for this style [%s]', $style));
}

return $this->renders[$format];
return $this->renders[$style];
}
}
Loading

0 comments on commit 75665a8

Please sign in to comment.