1
0
mirror of https://github.com/Chouchen/ShikiryuRSS.git synced 2025-12-14 14:20:40 +01:00

🧪 Add failing tests

* 🚧 Add failing tests

Closes #3

* 🧪 Add failing tests

Closes #3

* 🧪 Failing tests makes somes rules pop better

---------

Co-authored-by: Clement Desmidt <clement@desmidt.fr>
This commit is contained in:
Shikiryu
2023-04-19 17:03:59 +02:00
committed by GitHub
parent 58e0866b46
commit 5ef0160145
10 changed files with 343 additions and 39 deletions

View File

@@ -96,12 +96,12 @@ class Channel extends HasValidator implements SRSSElement
* @validate hour
* @format hour
*/
protected ?string $skipHours = null;
protected ?array $skipHours = null;
/**
* @validate day
* @format day
*/
protected ?string $skipDays = null;
protected ?array $skipDays = null;
/**
* @return bool

View File

@@ -12,6 +12,17 @@ use Shikiryu\SRSS\Validator\Validator;
/**
* https://cyber.harvard.edu/rss/rss.html#hrelementsOfLtitemgt
* @property null|string title
* @property null|string link
* @property null|string description
* @property null|string author
* @property null|array category
* @property null|string comments
* @property null|Enclosure enclosure
* @property null|string guid
* @property null|string pubDate
* @property null|Source source
* @property array medias
*/
class Item extends HasValidator implements SRSSElement
{

View File

@@ -0,0 +1,12 @@
<?php
namespace Shikiryu\SRSS\Exception;
class InvalidPropertyException extends SRSSException
{
public function __construct(string $object, string $property, ?string $value)
{
parent::__construct(sprintf('Invalid property `%s` = `%s` in `%s`', $property, $value, $object));
}
}

View File

@@ -110,6 +110,18 @@ class SRSSParser extends DomDocument
}
$category->value = $child->nodeValue;
$this->doc->channel->category = $category;
} elseif ($child->nodeName === 'skipHours') {
foreach ($child->childNodes as $hour) {
if ($hour->nodeType === XML_ELEMENT_NODE) {
$this->doc->channel->skipHours = $hour->nodeValue;
}
}
} elseif ($child->nodeName === 'skipDays') {
foreach ($child->childNodes as $day) {
if ($day->nodeType === XML_ELEMENT_NODE) {
$this->doc->channel->skipDays = $day->nodeValue;
}
}
} else {
$this->doc->channel->{$child->nodeName} = $child->nodeValue;
}

View File

@@ -11,6 +11,7 @@ use Shikiryu\SRSS\Entity\Channel\Cloud;
use Shikiryu\SRSS\Entity\Channel\Image;
use Shikiryu\SRSS\Entity\Item;
use Shikiryu\SRSS\Exception\ChannelNotFoundInRSSException;
use Shikiryu\SRSS\Exception\InvalidPropertyException;
use Shikiryu\SRSS\Exception\PropertyNotFoundException;
use Shikiryu\SRSS\Exception\SRSSException;
use Shikiryu\SRSS\Exception\UnreadableRSSException;
@@ -27,17 +28,18 @@ use Shikiryu\SRSS\Validator\Validator;
* @property null|string $managingEditor
* @property null|string $webMaster
* @property null|string $pubDate
* @property null|string $lastBuildDate
* @property null|string $lastBuildDate
* @property null|Category[] $category
* @property null|string $generator
* @property null|string $docs
* @property null|Cloud $cloud
* @property null|string $ttl
* @property null|Image $image
* @property null|string $rating
* @property null|string $textInput
* @property null|string $skipHours
* @property null|string $skipDays
* @property null|string $generator
* @property null|string $docs
* @property null|Cloud $cloud
* @property null|string $ttl
* @property null|Image $image
* @property null|string $rating
* @property null|string $textInput
* @property null|string $skipHours
* @property null|string $skipDays
* @property string|null $validated
*/
class SRSS implements Iterator
{
@@ -126,15 +128,16 @@ class SRSS implements Iterator
if (!property_exists(Channel::class, $name)) {
throw new PropertyNotFoundException(Channel::class, $name);
}
if ((new Validator())->isValidValueForObjectProperty($this->channel, $name, $val)) {
if (SRSSTools::getPropertyType(Channel::class, $name) === 'array') {
$this->channel->{$name} = $val;
} else {
$val = is_string($val) ? (new Formator())->formatValue($this->channel, $name, $val) : $val;
$this->channel->{$name} = $val;
}
if (!(new Validator())->isValidValueForObjectProperty($this->channel, $name, $val)) {
throw new InvalidPropertyException(get_class($this), $name, $val);
}
if (SRSSTools::getPropertyType(Channel::class, $name) === 'array') {
$this->channel->{$name} = $val;
} else {
$val = is_string($val) ? (new Formator())->formatValue($this->channel, $name, $val) : $val;
$this->channel->{$name} = $val;
}
}

View File

@@ -143,7 +143,7 @@ class Formator
return $check;
}
return sprintf('<![CDATA[ %s ]]>', htmlspecialchars($check));
return sprintf('<![CDATA[ %s ]]>', $check);
}
/**

View File

@@ -2,6 +2,7 @@
namespace Shikiryu\SRSS\Validator;
use Shikiryu\SRSS\Exception\InvalidPropertyException;
use Shikiryu\SRSS\Exception\PropertyNotFoundException;
use Shikiryu\SRSS\Exception\SRSSException;
use Shikiryu\SRSS\SRSSTools;
@@ -27,17 +28,19 @@ abstract class HasValidator
if (!property_exists(static::class, $name)) {
throw new PropertyNotFoundException(static::class, $name);
}
if ((new Validator())->isValidValueForObjectProperty($this, $name, $val)) {
if (SRSSTools::getPropertyType(static::class, $name) === 'array') {
/** @var array $this->{$name} */
$this->{$name}[] = $val;
} else {
$val = is_string($val) ? (new Formator())->formatValue($this, $name, $val) : $val;
$this->{$name} = $val;
}
if (!(new Validator())->isValidValueForObjectProperty($this, $name, $val)) {
throw new InvalidPropertyException(get_class($this), $name, $val);
}
if (SRSSTools::getPropertyType(static::class, $name) === 'array') {
/** @var array $this->{$name} */
$this->{$name}[] = $val;
} else {
$val = is_string($val) ? (new Formator())->formatValue($this, $name, $val) : $val;
$this->{$name} = $val;
}
}
/**

View File

@@ -24,6 +24,7 @@ class Validator
*/
public function isValidValueForObjectProperty($object, $property, $value): bool
{
$this->object = $object;
try {
$property = $this->getReflectedProperty($object, $property);
} catch (ReflectionException) {
@@ -31,17 +32,19 @@ class Validator
}
$propertyAnnotations = $this->_getPropertyAnnotations($property);
if (empty($value) && !in_array('required', $propertyAnnotations, true)) {
if (empty($value) && count(array_filter($propertyAnnotations, static fn($rule) => str_starts_with($rule, 'required'))) === 0) {
return true;
}
foreach ($propertyAnnotations as $propertyAnnotation) {
$annotation = explode(' ', $propertyAnnotation);
$object->validated[$property->name] = $this->_validateProperty($annotation, $value);
if ($this->_validateProperty($annotation, $value) === false) {
return false;
}
}
return count(array_filter($object->validated, static fn($v) => ($v !== null && $v === false))) === 0;
return true;
}
/**
@@ -69,9 +72,10 @@ class Validator
*/
public function isObjectValid($object): bool
{
if (!$object->validated) {
$object->validated = [];
// if (!$object->validated) {
$object = $this->validateObject($object);
}
// }
return !in_array(false, $object->validated, true);
}
@@ -91,7 +95,7 @@ class Validator
foreach ($properties as $property) {
$propertyValue = $object->{$property['name']};
if (empty($propertyValue) && !in_array('required', $property['rules'], true)) {
if (empty($propertyValue) && count(array_filter($property['rules'], static fn($rule) => str_starts_with($rule, 'required'))) === 0) {
continue;
}
@@ -117,7 +121,7 @@ class Validator
$args_annotation = array_splice($annotation, 1);
return $this->{sprintf('_validate%s', ucfirst($annotation[0]))}($property, ...$args_annotation);
return $this->{sprintf('_validate%s', ucfirst($annotation[0]))}($property, $args_annotation);
}
@@ -197,18 +201,38 @@ class Validator
private function _validateHour($value): bool
{
if (is_array($value)) {
foreach ($value as $val) {
if ($this->_validateHour($val) === false) {
return false;
}
}
return true;
}
$options = [
'options' => [
'default' => 0,
'min_range' => 0,
'max_range' => 23
]
];
return filter_var($value, FILTER_VALIDATE_INT, $options) !== false;
}
private function _validateDay($value): bool
{
if (is_array($value)) {
foreach ($value as $val) {
if ($this->_validateDay($val) === false) {
return false;
}
}
return true;
}
return in_array(
strtolower($value),
['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday']
@@ -251,4 +275,13 @@ class Validator
{
return filter_var($value, FILTER_VALIDATE_EMAIL);
}
private function _validateMax($value, array $max): bool
{
return $value <= current($max);
}
private function _validateMin($value, array $max): bool
{
return $value >= current($max);
}
}