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.
222 lines
7.4 KiB
222 lines
7.4 KiB
<?php
|
|
/** @license MIT
|
|
* Copyright 2018 J. King
|
|
* See LICENSE and AUTHORS files for details */
|
|
|
|
declare(strict_types=1);
|
|
namespace MensBeam\Lax\TestCase;
|
|
|
|
/* Test format is as follows:
|
|
|
|
Each test is a YAML map with the following keys:
|
|
|
|
- `input`: The test input as a string
|
|
- `output`: The result of the parsing upon success; described in more detail below
|
|
- `exception`: The exception ID thrown upon failure
|
|
- `type`: An HTTP Content-Type (with or without parameters) for the document
|
|
- `doc_url`: A fictitious URL where a newsfeed might be located, used for relative URL resolution
|
|
|
|
The 'input' key along with either 'output' or 'exception' are required for all tests.
|
|
|
|
The test output is necessarily mangled due to the limits of YAML:
|
|
|
|
- Any field which should be an absolute URL should be written as a string,
|
|
which will be transformed accordingly. Relative URLs should be represented
|
|
as a sequence with the relative part first, followed by the base that should
|
|
be applied to it
|
|
- Any collections should be represented as sequences of maps, which will
|
|
all be transformed accordingly
|
|
- Rich text can either be supplied as a string (which will yield a Text object
|
|
with plain-text content) or as a map with any of the properties of the
|
|
Text class listed
|
|
|
|
The transformations as performed by the `makeFeed` and `makeEntry` methods
|
|
of the abstract test case.
|
|
|
|
*/
|
|
|
|
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\Person\Person;
|
|
use MensBeam\Lax\Category\Category;
|
|
use MensBeam\Lax\Enclosure\Enclosure;
|
|
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;
|
|
|
|
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);
|
|
}
|
|
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;
|
|
foreach ($enclosure as $k => $v) {
|
|
if ($k === "url") {
|
|
$e->$k = $this->makeUrl($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 = new Url($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);
|
|
}
|
|
}
|
|
}
|
|
|