From 63d0b03b50425adf19b6737caacf3b89c8f76261 Mon Sep 17 00:00:00 2001 From: Clement Desmidt Date: Fri, 7 Apr 2023 17:57:35 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=9A=A7=20Continues=20tests,=20parser=20an?= =?UTF-8?q?d=20starts=20builder?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For #4 --- .gitignore | 1 + phpunit.xml | 30 +++ src/{ => Builder}/SRSSBuilder.php | 54 +++++- src/Entity/Channel.php | 14 +- src/Entity/Channel/Image.php | 41 ++++- src/Entity/Item.php | 65 +++++-- src/Entity/Media/Content.php | 173 +++++++----------- src/Entity/Media/Group.php | 8 - src/{ => Exception}/SRSSException.php | 2 +- src/{SRSSItem.php => Parser/ItemParser.php} | 23 +-- src/Parser/MediaContentParser.php | 79 ++++++++ src/{ => Parser}/SRSSParser.php | 12 +- src/SRSS.php | 46 ++--- src/SRSSTools.php | 14 +- src/Validator/Validator.php | 110 +++++++++-- tests/BasicBuilderTest.php | 40 ++++ .../{BasicReader.php => BasicReaderTest.php} | 8 +- tests/MediaTest.php | 8 +- 18 files changed, 494 insertions(+), 234 deletions(-) create mode 100644 phpunit.xml rename src/{ => Builder}/SRSSBuilder.php (76%) delete mode 100644 src/Entity/Media/Group.php rename src/{ => Exception}/SRSSException.php (90%) rename src/{SRSSItem.php => Parser/ItemParser.php} (89%) create mode 100644 src/Parser/MediaContentParser.php rename src/{ => Parser}/SRSSParser.php (92%) create mode 100644 tests/BasicBuilderTest.php rename tests/{BasicReader.php => BasicReaderTest.php} (90%) diff --git a/.gitignore b/.gitignore index 4eb89f8..2d769b6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /vendor/ /.idea /tests/error.log +/.phpunit.result.cache diff --git a/phpunit.xml b/phpunit.xml new file mode 100644 index 0000000..e340815 --- /dev/null +++ b/phpunit.xml @@ -0,0 +1,30 @@ + + + + + + + tests + + + + + + src/ + + + + + + + + \ No newline at end of file diff --git a/src/SRSSBuilder.php b/src/Builder/SRSSBuilder.php similarity index 76% rename from src/SRSSBuilder.php rename to src/Builder/SRSSBuilder.php index 9d89403..5a6f1ae 100644 --- a/src/SRSSBuilder.php +++ b/src/Builder/SRSSBuilder.php @@ -1,16 +1,27 @@ createElement('rss'); $root->setAttribute('version', '2.0'); $channel = $this->createElement('channel'); + + $this->appendChannelToDom($srss->channel, $channel); + + $this->appendItemsToDom($srss->items, $channel); + $root->appendChild($channel); $this->appendChild($root); $this->encoding = 'UTF-8'; @@ -18,13 +29,16 @@ class SRSSBuilder extends DomDocument $this->formatOutput = true; $this->preserveWhiteSpace = false; // $docs = 'http://www.scriptol.fr/rss/RSS-2.0.html'; + + $this->save($filepath); } /** * add a SRSS Item as an item into current RSS as first item - * @param SRSSItem $item + * + * @param ItemParser $item */ - public function addItemBefore(SRSSItem $item) + public function addItemBefore(ItemParser $item) { $node = $this->importNode($item->getItem(), true); $items = $this->getElementsByTagName('item'); @@ -41,9 +55,10 @@ class SRSSBuilder extends DomDocument /** * add a SRSS Item as an item into current RSS - * @param SRSSItem $item + * + * @param ItemParser $item */ - public function addItem(SRSSItem $item) + public function addItem(ItemParser $item) { $node = $this->importNode($item->getItem(), true); $channel = $this->_getChannel(); @@ -54,7 +69,7 @@ class SRSSBuilder extends DomDocument * display XML * see DomDocument's docs */ - public function show(): bool|string + public function show() { // TODO build return $this->saveXml(); @@ -159,4 +174,29 @@ class SRSSBuilder extends DomDocument } $this->attr['cloud'] = $array; } + + private function appendChannelToDom(Channel $channel, DOMElement $node) + { + foreach (array_filter($channel->toArray(), fn($el) => !empty($el)) as $name => $value) { + $new_node = $this->createElement($name, $value); + $node->appendChild($new_node); + } + } + + private function appendItemsToDom(array $items, DOMElement $channel) + { + foreach ($items as $item) { + $this->appendItemToDom($item, $channel); + } + } + + private function appendItemToDom(Item $item, DOMElement $channel) + { + $itemNode = $this->createElement('item'); + foreach (array_filter($item->toArray()) as $name => $value) { + $new_node = $this->createElement($name, $value); + $itemNode->appendChild($new_node); + } + $channel->appendChild($itemNode); + } } \ No newline at end of file diff --git a/src/Entity/Channel.php b/src/Entity/Channel.php index 9700bad..d4d958f 100644 --- a/src/Entity/Channel.php +++ b/src/Entity/Channel.php @@ -16,18 +16,18 @@ class Channel extends HasValidator implements SRSSElement * @required * @nohtml */ - public string $title; + public string $title = ''; /** * @required * @url */ - public string $link; + public string $link = ''; /** * @required */ - public string $description; + public string $description = ''; /** * @lang @@ -96,9 +96,7 @@ class Channel extends HasValidator implements SRSSElement */ public function isValid(): bool { - $annotation_validation = new Validator(); - - return $annotation_validation->isObjectValid($this); + return (new Validator())->isObjectValid($this); } /** @@ -106,6 +104,8 @@ class Channel extends HasValidator implements SRSSElement */ public function toArray(): array { - return get_object_vars($this); + $vars = get_object_vars($this); + unset($vars['validated']); + return $vars; } } \ No newline at end of file diff --git a/src/Entity/Channel/Image.php b/src/Entity/Channel/Image.php index d794078..f4fac3a 100644 --- a/src/Entity/Channel/Image.php +++ b/src/Entity/Channel/Image.php @@ -2,14 +2,47 @@ namespace Shikiryu\SRSS\Entity\Channel; -class Image +use Shikiryu\SRSS\Entity\SRSSElement; +use Shikiryu\SRSS\Validator\HasValidator; +use Shikiryu\SRSS\Validator\Validator; + +class Image extends HasValidator implements SRSSElement { + /** + * @required + * @url + */ public string $url; + /** + * @required + * @nohtml + */ public string $title; + /** + * @required + * @url + */ public string $link; - public int $width; // Maximum value for width is 144, default value is 88. - public int $height; //Maximum value for height is 400, default value is 31. + /** + * @int + * @max 144 + */ + public int $width = 88; // Maximum value for width is 144, default value is 88. + /** + * @int + * @max 400 + */ + public int $height = 31; //Maximum value for height is 400, default value is 31. + public string $description; - public array $required = ['url', 'title', 'link']; + public function isValid(): bool + { + return (new Validator())->isObjectValid($this); + } + + public function toArray(): array + { + return get_object_vars($this); + } } \ No newline at end of file diff --git a/src/Entity/Item.php b/src/Entity/Item.php index e3cd66b..2831f2f 100644 --- a/src/Entity/Item.php +++ b/src/Entity/Item.php @@ -2,33 +2,68 @@ namespace Shikiryu\SRSS\Entity; -class Item implements SRSSElement +use Shikiryu\SRSS\Validator\HasValidator; +use Shikiryu\SRSS\Validator\Validator; + +/** + * https://cyber.harvard.edu/rss/rss.html#hrelementsOfLtitemgt + */ +class Item extends HasValidator implements SRSSElement { - public ?string $title; - public ?string $link; - public ?string $description; - public ?string $author; - public ?string $category; - public ?string $comments; - public ?string $enclosure; - public ?string $guid; - public ?string $pubDate; - public ?string $source; + /** + * @requiredOr description + * @nohtml + */ + public ?string $title = null; + /** + * @url + */ + public ?string $link = null; + /** + * @requiredOr title + */ + public ?string $description = null; + /** + * @email + */ + public ?string $author = null; + /* + * TODO can be multiple with attributes and all + */ + public ?string $category = null; + /** + * @url + */ + public ?string $comments = null; + /* + * TODO 1 attributes and 1 value + */ + public ?string $enclosure = null; + public ?string $guid = null; + /** + * @date + */ + public ?string $pubDate = null; + /* + * TODO 1 attributes and 1 value + */ + public ?string $source = null; /** * @var \Shikiryu\SRSS\Entity\Media\Content[] + * @contentMedia */ public array $medias = []; - public array $required = ['description']; - public function isValid(): bool { - return count(array_filter($this->required, fn($field) => !empty($this->{$field}))) === 0; + return (new Validator())->isObjectValid($this); } public function toArray(): array { - return get_object_vars($this); + $vars = get_object_vars($this); + unset($vars['validated']); + return $vars; } } \ No newline at end of file diff --git a/src/Entity/Media/Content.php b/src/Entity/Media/Content.php index 1e09671..bfbd14a 100644 --- a/src/Entity/Media/Content.php +++ b/src/Entity/Media/Content.php @@ -2,123 +2,76 @@ namespace Shikiryu\SRSS\Entity\Media; -use DOMDocument; -use DOMElement; -use DOMNode; -use Shikiryu\SRSS\SRSSException; -use Shikiryu\SRSS\SRSSTools; +use Shikiryu\SRSS\Entity\SRSSElement; +use Shikiryu\SRSS\Validator\HasValidator; +use Shikiryu\SRSS\Validator\Validator; -class Content extends DomDocument +class Content extends HasValidator implements SRSSElement { - protected array $possibilities = [ - 'url' => 'link', - 'fileSize' => 'int', // TODO - 'type' => 'media_type', // TODO - 'medium' => 'media_medium', // TODO - 'isDefault' => 'bool', // TODO - 'expression' => 'medium_expression', // TODO - 'bitrate' => 'int', - 'framerate' => 'int', - 'samplingrate' => 'float', - 'channels' => 'int', - 'duration' => 'int', - 'height' => 'int', - 'width' => 'int', - 'lang' => '', - ]; - private array $attr = []; - - private DOMNode $node; - /** - * Constructor - * - * @param DomNode $node + * @url */ - public function __construct(?\DOMNode $node = null) + public ?string $url = null; + /** + * @int + */ + public ?int $filesize = null; + /** + * @mediaType + */ + public ?string $type = null; + /** + * @mediaMedium + */ + public ?string $medium = null; + /** + * @bool + */ + public ?bool $isDefault = null; + /** + * @mediaExpression + */ + public ?string $expression = null; + /** + * @int + */ + public ?int $bitrate = null; + /** + * @int + */ + public ?int $framerate = null; + /** + * @float + */ + public ?float $samplerate = null; + /** + * @int + */ + public ?int $channels = null; + /** + * @int + */ + public ?int $duration = null; + /** + * @int + */ + public ?int $height = null; + /** + * @int + */ + public ?int $width = null; + /** + * @lang + */ + public ?string $lang = null; + + public function isValid(): bool { - parent::__construct(); - if ($node instanceof DOMElement) { - $this->node = $this->importNode($node, true); - } else { - $this->node = $this->importNode(new DomElement('item')); - } - $this->_loadAttributes(); + return (new Validator())->isObjectValid($this); } - /** - * @return void - */ - private function _loadAttributes(): void + public function toArray(): array { - foreach ($this->node->attributes as $attributes) { - if (array_key_exists($attributes->name, $this->possibilities)) { - $this->{$attributes->name} = $attributes->value; - } - } - } - - /** - * main getter for properties - * - * @param $name - * - * @return null|string - * @throws SRSSException - */ - public function __get($name) - { - if (array_key_exists($name, $this->attr)) { - return $this->attr[$name]; - } - - if (array_key_exists($name, $this->possibilities)) { - $tmp = $this->node->getElementsByTagName($name); - if ($tmp->length !== 1) { - return null; - } - - return $tmp->item(0)->nodeValue; - } - - throw new SRSSException(sprintf('%s is not a possible item (%s)', $name, implode(', ', array_keys($this->possibilities)))); - } - - /** - * @param $name - * - * @return bool - */ - public function __isset($name) - { - return isset($this->attr[$name]); - } - - /** - * main setter for properties - * - * @param $name - * @param $val - * - * @throws SRSSException - */ - public function __set($name, $val) - { - if (!array_key_exists($name, $this->possibilities)) { - throw new SRSSException(sprintf('%s is not a possible item (%s)', $name, implode(', ', array_keys($this->possibilities)))); - } - - $flag = $this->possibilities[$name]; - - if ($flag !== '') { - $val = SRSSTools::check($val, $flag); - } - - if (!empty($val)) { - if ($this->$name === null) { - $this->node->appendChild(new DomElement($name, $val)); - } - $this->attr[$name] = $val; - } + return get_object_vars($this); } } \ No newline at end of file diff --git a/src/Entity/Media/Group.php b/src/Entity/Media/Group.php deleted file mode 100644 index 64ca71c..0000000 --- a/src/Entity/Media/Group.php +++ /dev/null @@ -1,8 +0,0 @@ -node = $this->importNode($node, true); -// else $this->node = $this->importNode(new DomElement('item')); -// $this->_loadAttributes(); } /** @@ -60,9 +58,9 @@ class SRSSItem extends DomDocument if (array_key_exists($child->nodeName, self::$possibilities) && self::$possibilities[$child->nodeName] === 'folder') { self::_loadChildAttributes($item, $child); } elseif ($child->nodeName === 'media:content') { - $item->medias[] = new Content($child); + $item->medias[] = MediaContentParser::read($child); } else { - $item->{$child->nodeName} = $child->nodeValue; + $item->{$child->nodeName} = trim($child->nodeValue); } } } @@ -188,15 +186,6 @@ class SRSSItem extends DomDocument throw new SRSSException(sprintf('%s is not a possible item (%s)', $name, implode(', ', array_keys($this->possibilities)))); } - /** - * display item's XML - * see DomDocument's docs - */ - public function show() - { - return $this->saveXml(); - } - /** * transform current item's object into an array * @return array diff --git a/src/Parser/MediaContentParser.php b/src/Parser/MediaContentParser.php new file mode 100644 index 0000000..4896cf5 --- /dev/null +++ b/src/Parser/MediaContentParser.php @@ -0,0 +1,79 @@ + 'nohtml', + 'link' => 'link', + 'description' => 'html', + 'author' => 'email', + 'category' => 'nohtml', + 'comments' => 'link', + 'enclosure' => '', + 'guid' => 'nohtml', + 'pubDate' => 'date', + 'source' => 'link', + 'media:group' => 'folder', + 'media:content' => '', + ]; + + /** + * Constructor + * + * @param DomNode $node + */ + public function __construct($node = null) + { + parent::__construct(); + } + + /** + * @param Content $item + * @param $nodes + * + * @return void + */ + private static function _loadChildAttributes(Content $item, $nodes): void + { + foreach ($nodes->attributes as $attribute) { + + if (property_exists(Content::class, $attribute->name)) { + $item->{$attribute->name} = $attribute->value; + } + + } + } + + /** + * @param DOMNode|null $node + * + * @return Content + */ + public static function read(?DOMNode $node = null): Content + { + $content = new Content(); + if ($node instanceof DOMNode) { + self::_loadChildAttributes($content, $node); + } + + return $content; + } +} \ No newline at end of file diff --git a/src/SRSSParser.php b/src/Parser/SRSSParser.php similarity index 92% rename from src/SRSSParser.php rename to src/Parser/SRSSParser.php index 70e5a04..a7f9076 100644 --- a/src/SRSSParser.php +++ b/src/Parser/SRSSParser.php @@ -1,6 +1,6 @@ _getChannel(); /** @var DOMNodeList $items */ @@ -70,7 +72,7 @@ class SRSSParser extends DomDocument $this->doc->items = []; if ($length > 0) { for($i = 0; $i < $length; $i++) { - $this->doc->items[$i] = SRSSItem::read($items->item($i)); + $this->doc->items[$i] = ItemParser::read($items->item($i)); } } diff --git a/src/SRSS.php b/src/SRSS.php index 954f5bb..4eb353d 100644 --- a/src/SRSS.php +++ b/src/SRSS.php @@ -5,38 +5,17 @@ namespace Shikiryu\SRSS; use Iterator; use Shikiryu\SRSS\Entity\Channel; use Shikiryu\SRSS\Entity\Item; +use Shikiryu\SRSS\Exception\SRSSException; +use Shikiryu\SRSS\Parser\SRSSParser; class SRSS implements Iterator { public Channel $channel; + /** @var Item[] */ public array $items; // array of SRSSItems private int $position; // Iterator position - // lists of possible attributes for RSS - protected $possibleAttr = [ - 'title' => 'nohtml', - 'link' => 'link', - 'description' => 'html', - 'language' => '', - //'language' => 'lang', - 'copyright' => 'nohtml', - 'pubDate' => 'date', - 'lastBuildDate' => 'date', - 'category' => 'nohtml', - 'docs' => 'link', - 'cloud' => '', - 'generator' => 'nohtml', - 'managingEditor' => 'email', - 'webMaster' => 'email', - 'ttl' => 'int', - 'image' => '', - 'rating' => 'nohtml', - //'textInput' => '', - 'skipHours' => 'hour', - 'skipDays' => 'day', - ]; - /** * Constructor */ @@ -78,15 +57,10 @@ class SRSS implements Iterator public function isValid(): bool { $valid = true; - $items = $this->getItems(); - $invalidItems = []; - $i = 1; - foreach ($items as $item) { + foreach ($this->getItems() as $item) { if ($item->isValid() === false) { - $invalidItems[] = $i; $valid = false; } - $i++; } return ($valid && $this->channel->isValid()); @@ -115,11 +89,10 @@ class SRSS implements Iterator if (!property_exists(Channel::class, $name)) { throw new SRSSException($name . ' is not a possible item'); } - $flag = $this->possibleAttr[$name]; - $val = SRSSTools::check($val, $flag); - if (!empty($val)) { + // TODO add validator ? +// if ((new Validator())->isPropertyValid($this->channel, $name)) { $this->channel->{$name} = $val; - } +// } } /** @@ -231,4 +204,9 @@ class SRSS implements Iterator return $doc; } + + public function addItem(Item $rssItem) + { + $this->items[] = $rssItem; + } } diff --git a/src/SRSSTools.php b/src/SRSSTools.php index e7d42a4..9d7ee3e 100644 --- a/src/SRSSTools.php +++ b/src/SRSSTools.php @@ -2,9 +2,11 @@ namespace Shikiryu\SRSS; +use DateTimeInterface; + class SRSSTools { - public static function check($check, $flag) + /*public static function check($check, $flag) { return match ($flag) { 'nohtml' => self::noHTML($check), @@ -19,11 +21,9 @@ class SRSSTools 'media_type' => self::checkMediaType($check), 'media_medium' => self::checkMediaMedium($check), 'bool' => self::checkBool($check), - 'medium_expression' => self::checkMediumExpression($check), - '' => $check, - default => throw new SRSSException('flag ' . $flag . ' does not exist.'), + 'medium_expression' => self::checkMediumExpression($check) }; - } + }*/ /** * format the RSS to the wanted format @@ -61,6 +61,10 @@ class SRSSTools return date("D, d M Y H:i:s T", strtotime($date)); } + if (count(explode(' ', $date)) === 2) { + return \DateTime::createFromFormat('Y-m-d H:i:s', $date)->format(DateTimeInterface::RSS); + } + [$j, $m, $a] = explode('/', $date); return date("D, d M Y H:i:s T", strtotime($a.'-'.$m.'-'.$j)); diff --git a/src/Validator/Validator.php b/src/Validator/Validator.php index 2161006..c16f1de 100644 --- a/src/Validator/Validator.php +++ b/src/Validator/Validator.php @@ -5,9 +5,36 @@ namespace Shikiryu\SRSS\Validator; use DateTimeInterface; use ReflectionClass; use ReflectionException; +use ReflectionProperty; +use Shikiryu\SRSS\Entity\Media\Content; class Validator { + protected ?object $object = null; + /** + * @throws \ReflectionException + */ + public function isPropertyValid($object, $property) + { + $properties = array_filter($this->_getClassProperties(get_class($object)), fn($p) => $p->getName() === $property); + if (count($properties) !== 1) { + return false; + } + + $properties = current($properties); + $propertyValue = $object->{$properties->name}; + $propertyAnnotations = $this->_getPropertyAnnotations($properties); + + if (!in_array('required', $propertyAnnotations, true) && empty($propertyValue)) { + return true; + } + + foreach ($propertyAnnotations as $propertyAnnotation) { + $annotation = explode(' ', $propertyAnnotation); + + $object->validated[$properties->name] = $this->_validateProperty($annotation, $propertyValue); + } + } /** * @throws ReflectionException @@ -18,7 +45,7 @@ class Validator $object = $this->validateObject($object); } - return !in_array(false, $object->validated); + return !in_array(false, $object->validated, true); } /** @@ -26,20 +53,25 @@ class Validator */ public function validateObject($object) { + $this->object = $object; $properties = $this->_getClassProperties(get_class($object)); + $properties = array_map(fn($property) => array_merge( + ['name' => $property->name], + ['rules' => $this->_getPropertyAnnotations($property)] + ), $properties); foreach ($properties as $property) { - $propertyValue = $object->{$property->name}; - $propertyAnnotations = $this->_getPropertyAnnotations($property, get_class($object)); + $propertyValue = $object->{$property['name']}; +// $propertyAnnotations = $this->_getPropertyAnnotations($property, get_class($object)); - if (!in_array('required', $propertyAnnotations) && empty($propertyValue)) { + if (!in_array('required', $property['rules'], true) && empty($propertyValue)) { continue; } - foreach ($propertyAnnotations as $propertyAnnotation) { + foreach ($property['rules'] as $propertyAnnotation) { $annotation = explode(' ', $propertyAnnotation); - $object->validated[$property->name] = $this->_validateProperty($annotation, $propertyValue); + $object->validated[$property['name']] = $this->_validateProperty($annotation, $propertyValue); } } @@ -48,24 +80,29 @@ class Validator private function _validateProperty(array $annotation, $property): bool { - if (count($annotation) === 1) { - return call_user_func([$this, sprintf('_validate%s', ucfirst($annotation[0]))], $property); + if ($annotation[0] === 'var') { + return true; } - return true; // TODO check + if (count($annotation) === 1) { + return $this->{sprintf('_validate%s', ucfirst($annotation[0]))}($property); + } + + $args_annotation = array_splice($annotation, 1); + + return $this->{sprintf('_validate%s', ucfirst($annotation[0]))}($property, ...$args_annotation); } /** + * @return ReflectionProperty[] * @throws ReflectionException */ private function _getClassProperties($class): array { - $ReflectionClass = new ReflectionClass($class); - - return $ReflectionClass->getProperties(); + return (new ReflectionClass($class))->getProperties(); } - private function _getPropertyAnnotations($property, $className): array + private function _getPropertyAnnotations(ReflectionProperty $property): array { preg_match_all('#@(.*?)\n#s', $property->getDocComment(), $annotations); @@ -87,6 +124,21 @@ class Validator return !empty(trim($value)); } + private function _validateRequiredOr($value, $other_values): bool + { + if (!empty($value)) { + return true; + } + + foreach ($other_values as $other_value) { + if (!empty($this->object->$other_value)) { + return true; + } + } + + return false; + } + /** * @param $value * @return bool @@ -143,4 +195,36 @@ class Validator ['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday'] ); } + + private function _validateContentMedia($value) + { + if (is_array($value)) { + foreach ($value as $content) { + if (!$content->isValid()) { + return false; + } + } + return true; + } + + if ($value instanceof Content) { + return $value->isValid(); + } + + return false; + } + + private function _validateMediaType($value): bool + { + return true; + } + private function _validateMediaMedium($value): bool + { + return in_array($value, ['image', 'audio', 'video', 'document', 'executable']); + } + + private function _validateMediaExpression($value): bool + { + return in_array($value, ['sample', 'full', 'nonstop']); + } } \ No newline at end of file diff --git a/tests/BasicBuilderTest.php b/tests/BasicBuilderTest.php new file mode 100644 index 0000000..d3be8ed --- /dev/null +++ b/tests/BasicBuilderTest.php @@ -0,0 +1,40 @@ +title = 'My Blog'; + $srss->description = 'is the best'; + $srss->link = 'http://shikiryu.com/devblog/'; + $items = [ + ['title' => 'title 1', 'link' => 'http://shikiryu.com/devblog/article-1', 'pubDate' => SRSSTools::getRSSDate('2012-03-05 12:02:01'), 'description' => 'description 1'], + ['title' => 'title 2', 'link' => 'http://shikiryu.com/devblog/article-2', 'pubDate' => SRSSTools::getRSSDate('2022-03-05 22:02:02'), 'description' => 'description 2'], + ['title' => 'title 3', 'link' => 'http://shikiryu.com/devblog/article-3', 'pubDate' => SRSSTools::getRSSDate('2032-03-05 32:02:03'), 'description' => 'description 3'], + ['title' => 'title 4', 'link' => 'http://shikiryu.com/devblog/article-4', 'pubDate' => SRSSTools::getRSSDate('2042-03-05 42:02:04'), 'description' => 'description 4'], + ]; + foreach ($items as $item) { + $rssItem = new Item(); + $rssItem->title = $item['title']; + $rssItem->link = $item['link']; + $rssItem->pubDate = $item['pubDate']; + $rssItem->description = $item['description']; + $srss->addItem($rssItem); + } + + self::assertTrue($srss->isValid()); + + $filepath = __DIR__.'/resources/tmp/build/testCreateBasicRSS.rss'; + $builder = new SRSSBuilder(); + $builder->build($srss, $filepath); + + self::assertFileExists($filepath); + } +} \ No newline at end of file diff --git a/tests/BasicReader.php b/tests/BasicReaderTest.php similarity index 90% rename from tests/BasicReader.php rename to tests/BasicReaderTest.php index 8e4834e..331ecde 100644 --- a/tests/BasicReader.php +++ b/tests/BasicReaderTest.php @@ -1,10 +1,10 @@ title); - self::assertTrue($rss->channel->isValid()); + self::assertTrue($rss->isValid()); } public function testRssNotFound() @@ -41,6 +41,6 @@ class BasicReader extends TestCase self::assertEquals('http://liftoff.msfc.nasa.gov/news/2003/news-laundry.asp', $rss->getLast()->link); self::assertEquals('Fri, 30 May 2003 11:06:42 GMT', $rss->getItem(2)->pubDate); - self::assertTrue($rss->channel->isValid()); + self::assertTrue($rss->isValid()); } } \ No newline at end of file diff --git a/tests/MediaTest.php b/tests/MediaTest.php index 67511d0..0e88c10 100644 --- a/tests/MediaTest.php +++ b/tests/MediaTest.php @@ -7,25 +7,25 @@ class MediaTest extends TestCase { public function testImages() { - $rss = SRSS::read('resources/media/cnn.xml'); + $rss = SRSS::read(__DIR__.'/resources/media/cnn.xml'); self::assertEquals('CNN.com - RSS Channel - Entertainment', $rss->title); $first_item = $rss->getFirst(); self::assertEquals('Kirstie Alley, \'Cheers\' and \'Veronica\'s Closet\' star, dead at 71', $first_item->title); self::assertEquals('https://cdn.cnn.com/cnnnext/dam/assets/221205172141-kirstie-alley-2005-super-169.jpg', $first_item->medias[0]->url); - self::assertTrue($rss->channel->isValid(), var_export($rss->channel->validated, true)); + self::assertTrue($rss->isValid(), var_export($rss->channel->validated, true)); } public function testMusicVideo() { - $rss = SRSS::read('resources/media/music-video.xml'); + $rss = SRSS::read(__DIR__.'/resources/media/music-video.xml'); self::assertEquals('Music Videos 101', $rss->title); self::assertCount(1, $rss->items); $first_item = $rss->getFirst(); self::assertEquals('http://www.foo.com/movie.mov', $first_item->medias[0]->url); - self::assertTrue($rss->channel->isValid()); + self::assertTrue($rss->isValid()); } } \ No newline at end of file