Skip to content

Commit

Permalink
Merge pull request #733 from hydephp/extract-publication-type-enum
Browse files Browse the repository at this point in the history
Create enum for publication types
  • Loading branch information
caendesilva authored Dec 5, 2022
2 parents 0dd3229 + 28bf846 commit 47b44c6
Show file tree
Hide file tree
Showing 6 changed files with 135 additions and 61 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ protected function captureFieldInput(PublicationFieldType $field, PublicationTyp
}

// Fields which are not of type array, text or image
$fieldRules = Collection::create(PublicationFieldType::DEFAULT_RULES)->{$field->type};
$fieldRules = collect($field->type->rules());
if ($fieldRules->contains('between')) {
$fieldRules->forget($fieldRules->search('between'));
if ($field->min && $field->max) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use Hyde\Console\Commands\Interfaces\CommandHandleInterface;
use Hyde\Console\Concerns\ValidatingCommand;
use Hyde\Framework\Actions\CreatesNewPublicationType;
use Hyde\Framework\Features\Publications\Concerns\PublicationFieldTypes;
use Hyde\Framework\Features\Publications\Models\PublicationFieldType;
use Hyde\Framework\Features\Publications\PublicationService;
use Illuminate\Support\Str;
Expand All @@ -21,7 +22,6 @@
use function scandir;
use function strtolower;
use function trim;
use function ucfirst;

/**
* Hyde Command to create a new publication type.
Expand Down Expand Up @@ -99,7 +99,7 @@ protected function captureFieldsDefinitions(): Collection
$addAnother = $this->askWithValidation('addAnother', '<bg=magenta;fg=white>Add another field (y/n)</>', ['required', 'string', 'in:y,n'], 'n');

// map field choice to actual field type
$fieldData['type'] = PublicationFieldType::TYPES[$type];
$fieldData['type'] = PublicationFieldTypes::values()[$type - 1];

$fields->add(PublicationFieldType::fromArray($fieldData));
$count++;
Expand All @@ -110,14 +110,14 @@ protected function captureFieldsDefinitions(): Collection

protected function getFieldType(): int
{
$options = PublicationFieldType::TYPES;
$options = PublicationFieldTypes::cases();
foreach ($options as $key => $value) {
$options[$key] = ucfirst($value);
$options[$key] = $value->name;
}
$options[5] = 'Datetime (YYYY-MM-DD (HH:MM:SS))';
$options[6] = 'URL';
$options[9] = 'Local Image';
$options[10] = 'Tag (select value from list)';
$options[4] = 'Datetime (YYYY-MM-DD (HH:MM:SS))';
$options[5] = 'URL';
$options[8] = 'Local Image';
$options[9] = 'Tag (select value from list)';

return (int) $this->choice('Field type', $options, 1) + 1;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php

declare(strict_types=1);

namespace Hyde\Framework\Features\Publications\Concerns;

use BadMethodCallException;
use Illuminate\Support\Collection;

/**
* The supported field types for publication types.
*
* @see \Hyde\Framework\Features\Publications\Models\PublicationFieldType
* @see \Hyde\Framework\Testing\Feature\PublicationFieldTypesEnumTest
*/
enum PublicationFieldTypes: string
{
case String = 'string';
case Boolean = 'boolean';
case Integer = 'integer';
case Float = 'float';
case Datetime = 'datetime';
case Url = 'url';
case Array = 'array';
case Text = 'text';
case Image = 'image';
case Tag = 'tag';

public function rules(): array
{
return self::getRules($this);
}

public static function collect(): Collection
{
return collect(self::cases());
}

public static function values(): array
{
return self::collect()->pluck('value')->toArray();
}

public static function getRules(self $type): array
{
/** @noinspection PhpDuplicateMatchArmBodyInspection */
return match ($type) {
self::String => ['required', 'string', 'between'],
self::Boolean => ['required', 'boolean'],
self::Integer => ['required', 'integer', 'between'],
self::Float => ['required', 'numeric', 'between'],
self::Datetime => ['required', 'datetime', 'between'],
self::Url => ['required', 'url'],
self::Text => ['required', 'string', 'between'],
self::Array => throw new BadMethodCallException('This type has no validation rules'),
self::Image => throw new BadMethodCallException('This type has no validation rules'),
self::Tag => throw new BadMethodCallException('This type has no validation rules'),
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,43 +4,24 @@

namespace Hyde\Framework\Features\Publications\Models;

use Hyde\Framework\Features\Publications\Concerns\PublicationFieldTypes;
use Hyde\Support\Concerns\Serializable;
use Hyde\Support\Contracts\SerializableContract;
use Illuminate\Support\Str;
use InvalidArgumentException;
use function strtolower;

/**
* Represents an entry in the "fields" array of a publication type schema.
*
* @see \Hyde\Framework\Features\Publications\Concerns\PublicationFieldTypes
* @see \Hyde\Framework\Testing\Feature\PublicationFieldTypeTest
*/
class PublicationFieldType implements SerializableContract
{
use Serializable;

public final const TYPES = [
1 => 'string',
2 => 'boolean',
3 => 'integer',
4 => 'float',
5 => 'datetime',
6 => 'url',
7 => 'array',
8 => 'text',
9 => 'image',
10 => 'tag',
];

public final const DEFAULT_RULES = [
'string' => ['required', 'string', 'between'],
'boolean' => ['required', 'boolean'],
'integer' => ['required', 'integer', 'between'],
'float' => ['required', 'numeric', 'between'],
'datetime' => ['required', 'datetime', 'between'],
'url' => ['required', 'url'],
'text' => ['required', 'string', 'between'],
];

public readonly string $type;
public readonly PublicationFieldTypes $type;
public readonly string $max;
public readonly string $min;
public readonly string $name;
Expand All @@ -53,16 +34,12 @@ public static function fromArray(array $array): static

public function __construct(string $type, string $name, int|string|null $min, int|string|null $max, ?string $tagGroup = null)
{
$this->type = strtolower($type);
$this->type = PublicationFieldTypes::from(strtolower($type));
$this->name = Str::kebab($name);
$this->min = (string) $min;
$this->max = (string) $max;
$this->tagGroup = $tagGroup;

if (! in_array(strtolower($type), self::TYPES)) {
throw new InvalidArgumentException(sprintf("The type '$type' is not a valid type. Valid types are: %s.", implode(', ', self::TYPES)));
}

if ($max < $min) {
throw new InvalidArgumentException("The 'max' value cannot be less than the 'min' value.");
}
Expand All @@ -71,7 +48,7 @@ public function __construct(string $type, string $name, int|string|null $min, in
public function toArray(): array
{
return [
'type' => $this->type,
'type' => $this->type->value,
'name' => $this->name,
'min' => $this->min,
'max' => $this->max,
Expand Down
29 changes: 7 additions & 22 deletions packages/framework/tests/Feature/PublicationFieldTypeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@

namespace Hyde\Framework\Testing\Feature;

use Hyde\Framework\Features\Publications\Concerns\PublicationFieldTypes;
use Hyde\Framework\Features\Publications\Models\PublicationFieldType;
use Hyde\Testing\TestCase;
use InvalidArgumentException;
use ValueError;

/**
* @covers \Hyde\Framework\Features\Publications\Models\PublicationFieldType
Expand All @@ -18,7 +20,7 @@ public function test_can_instantiate_class()
$field = $this->makeField();
$this->assertInstanceOf(PublicationFieldType::class, $field);

$this->assertSame('string', $field->type);
$this->assertSame(PublicationFieldTypes::String, $field->type);
$this->assertSame('test', $field->name);
$this->assertSame('1', $field->min);
$this->assertSame('10', $field->max);
Expand All @@ -35,7 +37,7 @@ public function test_from_array_method()

$this->assertInstanceOf(PublicationFieldType::class, $field);

$this->assertSame('string', $field->type);
$this->assertSame(PublicationFieldTypes::String, $field->type);
$this->assertSame('test', $field->name);
$this->assertSame('1', $field->min);
$this->assertSame('10', $field->max);
Expand Down Expand Up @@ -80,16 +82,16 @@ public function test_integers_can_be_added_as_strings()

public function test_type_must_be_valid()
{
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage("The type 'invalid' is not a valid type. Valid types are: string, boolean, integer, float, datetime, url, array, text, image, tag.");
$this->expectException(ValueError::class);
$this->expectExceptionMessage('"invalid" is not a valid backing value for enum "Hyde\Framework\Features\Publications\Concerns\PublicationFieldTypes"');

new PublicationFieldType('invalid', 'test', '1', '10');
}

public function test_type_input_is_case_insensitive()
{
$field = new PublicationFieldType('STRING', 'test', '1', '10');
$this->assertSame('string', $field->type);
$this->assertSame(PublicationFieldTypes::String, $field->type);
}

public function test_name_gets_stored_as_kebab_case()
Expand All @@ -103,23 +105,6 @@ public function test_validate_input_against_rules()
$this->markTestIncomplete('TODO: Implement this method.');
}

public function test_types_constant()
{
$this->assertSame([
1 => 'string',
2 => 'boolean',
3 => 'integer',
4 => 'float',
5 => 'datetime',
6 => 'url',
7 => 'array',
8 => 'text',
9 => 'image',
10 => 'tag',

], PublicationFieldType::TYPES);
}

protected function makeField(): PublicationFieldType
{
return new PublicationFieldType('string', 'test', 1, '10');
Expand Down
52 changes: 52 additions & 0 deletions packages/framework/tests/Feature/PublicationFieldTypesEnumTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php

declare(strict_types=1);

namespace Hyde\Framework\Testing\Feature;

use BadMethodCallException;
use Hyde\Framework\Features\Publications\Concerns\PublicationFieldTypes;
use Hyde\Testing\TestCase;

/**
* @covers \Hyde\Framework\Features\Publications\Concerns\PublicationFieldTypes
*/
class PublicationFieldTypesEnumTest extends TestCase
{
public function testCanGetRulesForEnum()
{
$this->assertSame([
'required',
'string',
'between',
], PublicationFieldTypes::String->rules());
}

public function testCollectCreatesCollectionOfCases()
{
$this->assertEquals(collect(PublicationFieldTypes::cases()), PublicationFieldTypes::collect());
}

public function testValuesReturnsArrayOfCaseValues()
{
$this->assertSame([
0 => 'string',
1 => 'boolean',
2 => 'integer',
3 => 'float',
4 => 'datetime',
5 => 'url',
6 => 'array',
7 => 'text',
8 => 'image',
9 => 'tag',
], PublicationFieldTypes::values());
}

public function testCanGetRulesForEnumWithNoRules()
{
$this->expectException(BadMethodCallException::class);
$this->expectExceptionMessage('This type has no validation rules');
PublicationFieldTypes::Tag->rules();
}
}

0 comments on commit 47b44c6

Please sign in to comment.