You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
240 lines
8.1 KiB
240 lines
8.1 KiB
<?php
|
|
/** @license MIT
|
|
* Copyright 2018 J. King
|
|
* See LICENSE and AUTHORS files for details */
|
|
|
|
declare(strict_types=1);
|
|
namespace MensBeam\Lax\TestCase\Parser;
|
|
|
|
use MensBeam\Lax\Feed;
|
|
use MensBeam\Lax\Date;
|
|
use MensBeam\Lax\Text;
|
|
use MensBeam\Lax\Url;
|
|
use MensBeam\Lax\Entry;
|
|
use MensBeam\Lax\Metadata;
|
|
use MensBeam\Lax\Schedule;
|
|
use MensBeam\Lax\MimeType;
|
|
use MensBeam\Lax\Link\Link;
|
|
use MensBeam\Lax\Person\Person;
|
|
use MensBeam\Lax\Category\Category;
|
|
use MensBeam\Lax\Enclosure\Enclosure;
|
|
use MensBeam\Lax\Link\Collection as LinkCollection;
|
|
use MensBeam\Lax\Person\Collection as PersonCollection;
|
|
use MensBeam\Lax\Category\Collection as CategoryCollection;
|
|
use MensBeam\Lax\Enclosure\Collection as EnclosureCollection;
|
|
use MensBeam\Lax\Parser\Exception;
|
|
use Symfony\Component\Yaml\Yaml;
|
|
use Symfony\Component\Yaml\Parser as YamlParser;
|
|
use GuzzleHttp\Psr7\Response;
|
|
|
|
class AbstractParserTestCase extends \PHPUnit\Framework\TestCase {
|
|
protected function provideParserTests(string $glob): iterable {
|
|
foreach (new \GlobIterator($glob, \FilesystemIterator::CURRENT_AS_PATHNAME | \FilesystemIterator::KEY_AS_FILENAME) as $file => $path) {
|
|
foreach ((new YamlParser)->parseFile($path, Yaml::PARSE_OBJECT_FOR_MAP) as $description => $test) {
|
|
if (isset($test->exception)) {
|
|
$test->output = new Exception((string) $test->exception);
|
|
} else {
|
|
$test->output = $this->makeFeed($test->output);
|
|
}
|
|
if (is_object($test->input)) {
|
|
assert((isset($test->input->head) && $test->input->head instanceof \stdClass) || (isset($test->input->body) && is_string($test->input->body)), "Input is not in a correct format");
|
|
$test->input = new Response($test->input->status ?? 200, (array) ($test->input->head ?? []), $test->input->body ?? null);
|
|
}
|
|
yield "$file: {$description}" => [
|
|
$test->input,
|
|
$test->type ?? "",
|
|
$test->doc_url ?? null,
|
|
$test->output,
|
|
];
|
|
}
|
|
}
|
|
}
|
|
|
|
private function makeFeed(\stdClass $output): Feed {
|
|
$f = new Feed;
|
|
foreach ($output as $k => $v) {
|
|
if (in_array($k, ["title", "summary"])) {
|
|
$f->$k = $this->makeText($v);
|
|
} elseif ($k === "dateModified") {
|
|
$f->$k = new Date($v, new \DateTimeZone("UTC"));
|
|
} elseif ($k === "people") {
|
|
$c = new PersonCollection;
|
|
foreach ($v as $m) {
|
|
$c[] = $this->makePerson($m);
|
|
}
|
|
$f->$k = $c;
|
|
} elseif ($k === "categories") {
|
|
$c = new CategoryCollection;
|
|
foreach ($v as $m) {
|
|
$o = new Category;
|
|
foreach ($m as $kk => $vv) {
|
|
$o->$kk = $vv;
|
|
}
|
|
$c[] = $o;
|
|
}
|
|
$f->$k = $c;
|
|
} elseif ($k === "entries") {
|
|
$c = [];
|
|
foreach ($v as $m) {
|
|
$c[] = $this->makeEntry($m);
|
|
}
|
|
$f->$k = $c;
|
|
} elseif ($k === "meta") {
|
|
$f->$k = $this->makeMeta($v);
|
|
} elseif ($k === "sched") {
|
|
$f->$k = $this->makeSched($v);
|
|
} elseif (in_array($k, ["url", "link", "icon", "image"])) {
|
|
$f->$k = $this->makeUrl($v);
|
|
} else {
|
|
$f->$k = $v;
|
|
}
|
|
}
|
|
return $f;
|
|
}
|
|
|
|
private function makeEntry(\stdClass $entry): Entry {
|
|
$e = new Entry;
|
|
foreach ($entry as $k => $v) {
|
|
if (in_array($k, ["link", "relatedLink", "banner"])) {
|
|
$e->$k = $this->makeUrl($v);
|
|
} elseif (in_array($k, ["dateCreated", "dateModified"])) {
|
|
$e->$k = new Date($v, new \DateTimeZone("UTC"));
|
|
} elseif (in_array($k, ["title", "summary", "content"])) {
|
|
$e->$k = $this->makeText($v);
|
|
} elseif ($k === "people") {
|
|
$c = new PersonCollection;
|
|
foreach ($v as $m) {
|
|
$c[] = $this->makePerson($m);
|
|
}
|
|
$e->$k = $c;
|
|
} elseif ($k === "enclosures") {
|
|
$c = new EnclosureCollection;
|
|
foreach ($v as $m) {
|
|
$c[] = $this->makeEnclosure($m);
|
|
}
|
|
$e->$k = $c;
|
|
} elseif ($k === "categories") {
|
|
$c = new CategoryCollection;
|
|
foreach ($v as $m) {
|
|
$o = new Category;
|
|
foreach ($m as $kk => $vv) {
|
|
$o->$kk = $vv;
|
|
}
|
|
$c[] = $o;
|
|
}
|
|
$e->$k = $c;
|
|
} else {
|
|
$e->$k = $v;
|
|
}
|
|
}
|
|
return $e;
|
|
}
|
|
|
|
private function makeText($data): Text {
|
|
if (is_string($data)) {
|
|
return new Text($data);
|
|
}
|
|
$out = new Text;
|
|
foreach ($data as $k => $v) {
|
|
$out->$k = $v;
|
|
}
|
|
return $out;
|
|
}
|
|
|
|
private function makePerson(\stdClass $person): Person {
|
|
$p = new Person;
|
|
foreach ($person as $k => $v) {
|
|
if (in_array($k, ["url", "avatar"])) {
|
|
$p->$k = $this->makeUrl($v);
|
|
} else {
|
|
$p->$k = $v;
|
|
}
|
|
}
|
|
return $p;
|
|
}
|
|
|
|
private function makeEnclosure(\stdClass $enclosure): Enclosure {
|
|
$e = new Enclosure;
|
|
if (is_iterable($enclosure->data ?? null)) {
|
|
foreach ($enclosure->data as $k => $v) {
|
|
$e[$k] = $this->makeEnclosure($v);
|
|
}
|
|
$e->preferred = $enclosure->preferred ?? null;
|
|
} else {
|
|
foreach ($enclosure as $k => $v) {
|
|
if ($k === "url") {
|
|
$e->$k = $this->makeUrl($v);
|
|
} elseif ($k === "title") {
|
|
$e->$k = $this->makeText($v);
|
|
} elseif ($k === "type") {
|
|
$e->$k = MimeType::parseLoose($v);
|
|
} else {
|
|
$e->$k = $v;
|
|
}
|
|
}
|
|
}
|
|
return $e;
|
|
}
|
|
|
|
private function makeMeta(\stdClass $meta): Metadata {
|
|
$m = new Metadata;
|
|
foreach ($meta as $k => $v) {
|
|
if ($k === "url") {
|
|
$m->$k = $this->makeUrl($v);
|
|
} elseif ($k === "type") {
|
|
$m->$k = MimeType::parse($v);
|
|
} elseif ($k === "links") {
|
|
$m->$k = $this->makeLinks($v);
|
|
} elseif (in_array($k, ["date", "lastModified", "expires"])) {
|
|
$m->$k = new Date($v);
|
|
} elseif (in_array($k, ["age", "maxAge"])) {
|
|
$m->$k = new \DateInterval($v);
|
|
} else {
|
|
$m->$k = $v;
|
|
}
|
|
}
|
|
return $m;
|
|
}
|
|
|
|
private function makeSched(\stdClass $sched): Schedule {
|
|
$s = new Schedule;
|
|
foreach ($sched as $k => $v) {
|
|
if ($k === 'base') {
|
|
$s->$k = new Date($v);
|
|
} elseif ($k === 'interval') {
|
|
$s->$k = new \DateInterval($v);
|
|
} else {
|
|
$s->$k = $v;
|
|
}
|
|
}
|
|
return $s;
|
|
}
|
|
|
|
private function makeUrl($url): ?Url {
|
|
if (is_array($url)) {
|
|
return new Url($url[0] ?? "", $url[1] ?? null);
|
|
} else {
|
|
return new Url($url);
|
|
}
|
|
}
|
|
|
|
private function makeLinks(array $links): LinkCollection {
|
|
$out = new LinkCollection;
|
|
foreach ($links as $link) {
|
|
$m = new Link;
|
|
foreach ((array) $link as $k => $v) {
|
|
if ($k === "type") {
|
|
$m->$k = MimeType::parse($v);
|
|
} elseif ($k === "attr") {
|
|
$m->$k = (array) $v;
|
|
} elseif (in_array($k, ["url", "anchor"])) {
|
|
$m->$k = $this->makeUrl($v);
|
|
} else {
|
|
$m->$k = $v;
|
|
}
|
|
}
|
|
$out[] = $m;
|
|
}
|
|
return $out;
|
|
}
|
|
}
|
|
|