Skip to content

Commit

Permalink
Merge pull request #4 from KaririCode-Framework/develop
Browse files Browse the repository at this point in the history
refactor(input-exception): enhance InputException with new error type…
  • Loading branch information
walmir-silva authored Oct 17, 2024
2 parents 56109df + e1fa5a7 commit 65c8eb7
Show file tree
Hide file tree
Showing 2 changed files with 210 additions and 0 deletions.
103 changes: 103 additions & 0 deletions src/Input/InputException.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,14 @@ final class InputException extends AbstractException
private const CODE_INVALID_FORMAT = 1901;
private const CODE_MISSING_REQUIRED = 1902;
private const CODE_EXCEEDS_MAX_LENGTH = 1903;
private const CODE_INVALID_ARGUMENT = 1904;
private const CODE_BELOW_MIN_LENGTH = 1905;
private const CODE_OUT_OF_RANGE = 1906;
private const CODE_INVALID_TYPE = 1907;
private const CODE_INVALID_OPTION = 1908;
private const CODE_DUPLICATE_ENTRY = 1909;
private const CODE_INVALID_DATE = 1910;
private const CODE_INVALID_CONFIG_PARAM = 1911;

public static function invalidFormat(string $field): self
{
Expand Down Expand Up @@ -38,4 +46,99 @@ public static function exceedsMaxLength(string $field, int $maxLength): self
"Field '{$field}' exceeds maximum length of {$maxLength}"
);
}

public static function invalidArgument(string $field, mixed $value, ?string $expectedType = null): self
{
$message = "Invalid argument for field '{$field}'. Received value: " . self::formatValue($value);
if (null !== $expectedType) {
$message .= ", expected type: {$expectedType}";
}

return self::createException(
self::CODE_INVALID_ARGUMENT,
'INVALID_ARGUMENT',
$message
);
}

public static function belowMinLength(string $field, int $minLength): self
{
return self::createException(
self::CODE_BELOW_MIN_LENGTH,
'BELOW_MIN_LENGTH',
"Field '{$field}' is below minimum length of {$minLength}"
);
}

public static function outOfRange(string $field, $min, $max): self
{
return self::createException(
self::CODE_OUT_OF_RANGE,
'OUT_OF_RANGE',
"Field '{$field}' is out of range. Must be between {$min} and {$max}"
);
}

public static function invalidType(string $field, string $expectedType): self
{
return self::createException(
self::CODE_INVALID_TYPE,
'INVALID_TYPE',
"Field '{$field}' is of invalid type. Expected {$expectedType}"
);
}

public static function invalidOption(string $field, array $validOptions): self
{
$optionsString = implode(', ', $validOptions);

return self::createException(
self::CODE_INVALID_OPTION,
'INVALID_OPTION',
"Invalid option for field '{$field}'. Valid options are: {$optionsString}"
);
}

public static function duplicateEntry(string $field, $value): self
{
return self::createException(
self::CODE_DUPLICATE_ENTRY,
'DUPLICATE_ENTRY',
"Duplicate entry for field '{$field}' with value '{$value}'"
);
}

public static function invalidDate(string $field, string $format): self
{
return self::createException(
self::CODE_INVALID_DATE,
'INVALID_DATE',
"Invalid date for field '{$field}'. Expected format: {$format}"
);
}

public static function invalidConfigParam(string $param, mixed $value, string $expectedDescription): self
{
$message = "Invalid configuration parameter '{$param}'. " .
'Received value: ' . self::formatValue($value) .
". Expected: {$expectedDescription}";

return self::createException(
self::CODE_INVALID_CONFIG_PARAM,
'INVALID_CONFIG_PARAM',
$message
);
}

private static function formatValue(mixed $value): string
{
return match (true) {
is_string($value) => "'{$value}'",
is_bool($value) => $value ? 'true' : 'false',
is_null($value) => 'null',
is_array($value) => 'array',
is_object($value) => get_class($value),
default => (string) $value,
};
}
}
107 changes: 107 additions & 0 deletions tests/Input/InputExceptionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,111 @@ public function testExceedsMaxLength(): void
1903
);
}

public function testInvalidArgument(): void
{
$field = 'age';
$value = 'not a number';
$expectedType = 'integer';
$exception = InputException::invalidArgument($field, $value, $expectedType);
$this->assertExceptionStructure(
$exception,
'INVALID_ARGUMENT',
"Invalid argument for field 'age'. Received value: 'not a number', expected type: integer",
1904
);
}

public function testBelowMinLength(): void
{
$field = 'password';
$minLength = 8;
$exception = InputException::belowMinLength($field, $minLength);
$this->assertExceptionStructure(
$exception,
'BELOW_MIN_LENGTH',
"Field '{$field}' is below minimum length of {$minLength}",
1905
);
}

public function testOutOfRange(): void
{
$field = 'rating';
$min = 1;
$max = 5;
$exception = InputException::outOfRange($field, $min, $max);
$this->assertExceptionStructure(
$exception,
'OUT_OF_RANGE',
"Field '{$field}' is out of range. Must be between {$min} and {$max}",
1906
);
}

public function testInvalidType(): void
{
$field = 'count';
$expectedType = 'integer';
$exception = InputException::invalidType($field, $expectedType);
$this->assertExceptionStructure(
$exception,
'INVALID_TYPE',
"Field '{$field}' is of invalid type. Expected {$expectedType}",
1907
);
}

public function testInvalidOption(): void
{
$field = 'status';
$validOptions = ['active', 'inactive', 'pending'];
$exception = InputException::invalidOption($field, $validOptions);
$this->assertExceptionStructure(
$exception,
'INVALID_OPTION',
"Invalid option for field '{$field}'. Valid options are: active, inactive, pending",
1908
);
}

public function testDuplicateEntry(): void
{
$field = 'email';
$value = 'test@example.com';
$exception = InputException::duplicateEntry($field, $value);
$this->assertExceptionStructure(
$exception,
'DUPLICATE_ENTRY',
"Duplicate entry for field '{$field}' with value '{$value}'",
1909
);
}

public function testInvalidDate(): void
{
$field = 'birthdate';
$format = 'Y-m-d';
$exception = InputException::invalidDate($field, $format);
$this->assertExceptionStructure(
$exception,
'INVALID_DATE',
"Invalid date for field '{$field}'. Expected format: {$format}",
1910
);
}

public function testInvalidConfigParam(): void
{
$param = 'timeout';
$value = -1;
$expectedDescription = 'a positive integer';
$exception = InputException::invalidConfigParam($param, $value, $expectedDescription);
$this->assertExceptionStructure(
$exception,
'INVALID_CONFIG_PARAM',
"Invalid configuration parameter '{$param}'. Received value: -1. Expected: {$expectedDescription}",
1911
);
}
}

0 comments on commit 65c8eb7

Please sign in to comment.