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.
151 lines
5.0 KiB
151 lines
5.0 KiB
<?php
|
|
/** @license MIT
|
|
* Copyright 2018 J. King
|
|
* See LICENSE and AUTHORS files for details */
|
|
|
|
declare(strict_types=1);
|
|
namespace JKingWeb\Lax\TestCase\JSON;
|
|
|
|
/* Test format is as follows:
|
|
|
|
Each test is a JSON object with the following keys:
|
|
|
|
- `description`: a short human-readable description of the test
|
|
- `base_url`: A base URL against which relative URLs should be resolved
|
|
- `input`: The test input, as a string or directly as a JSON Feed structure
|
|
- `output`: The result of the parsing upon success; described in more detail below
|
|
- `exception`: The exception ID thrown upon failure
|
|
|
|
The 'description' and 'input' keys along with either 'output' or 'exception'
|
|
are required for all tests.
|
|
|
|
The test output is necessarily mangled due to the limits of JSON:
|
|
|
|
- Any field which should be a URL should be written as a string, which
|
|
will be transformed accordingly
|
|
- Any collections should be represented as arrays of objects, 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 an object 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 JKingWeb\Lax\Entry;
|
|
use JKingWeb\Lax\Parser\Exception;
|
|
use JKingWeb\Lax\Parser\JSON\Feed as Parser;
|
|
use JKingWeb\Lax\Person\Person;
|
|
use JKingWeb\Lax\Person\Collection as PersonCollection;
|
|
use JKingWeb\Lax\Feed;
|
|
use JKingWeb\Lax\Text;
|
|
use JKingWeb\Lax\Url;
|
|
|
|
/**
|
|
* @covers JKingWeb\Lax\Parser\JSON\Feed<extended>
|
|
* @covers JKingWeb\Lax\Parser\JSON\Entry<extended>
|
|
*/
|
|
class JSONTest extends \PHPUnit\Framework\TestCase {
|
|
/** @dataProvider provideJSONFeedVersion1 */
|
|
public function testJSONFeedVersion1($input, string $type, $output): void {
|
|
if (is_object($input)) {
|
|
$input = json_encode($input);
|
|
} elseif (!is_string($input)) {
|
|
throw new \Exception("Test input is invalid");
|
|
}
|
|
$p = new Parser($input, $type);
|
|
if ($output instanceof \Exception) {
|
|
$this->expectExceptionObject($output);
|
|
$p->parse(new Feed);
|
|
} else {
|
|
$act = $p->parse(new Feed);
|
|
$exp = $this->makeFeed($output);
|
|
$this->assertEquals($exp, $act);
|
|
$this->assertEqualsCanonicalizing($exp, $act);
|
|
}
|
|
}
|
|
|
|
public function provideJSONFeedVersion1(): iterable {
|
|
foreach (new \GlobIterator(__DIR__."/*.json", \FilesystemIterator::CURRENT_AS_PATHNAME | \FilesystemIterator::KEY_AS_FILENAME) as $file => $path) {
|
|
foreach (json_decode(file_get_contents($path)) as $index => $test) {
|
|
if (isset($test->exception)) {
|
|
$test->output = new Exception((string) $test->exception);
|
|
}
|
|
yield "$file #$index: {$test->description}" => [
|
|
$test->input,
|
|
$test->type ?? "",
|
|
$test->output,
|
|
];
|
|
}
|
|
}
|
|
}
|
|
|
|
protected 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 === "people") {
|
|
$c = new PersonCollection;
|
|
foreach ($v as $m) {
|
|
$c[] = $this->makePerson($m);
|
|
}
|
|
$f->$k = $c;
|
|
} elseif ($k === "entries") {
|
|
$c = [];
|
|
foreach ($v as $m) {
|
|
$c[] = $this->makeEntry($m);
|
|
}
|
|
$f->$k = $c;
|
|
} elseif (in_array($k, ["meta", "sched"])) {
|
|
foreach ($v as $kk => $vv) {
|
|
$f->$k->$kk = $vv;
|
|
}
|
|
} elseif (in_array($k, ["url", "link", "icon", "image"])) {
|
|
$f->$k = new Url($v);
|
|
} else {
|
|
$f->$k = $v;
|
|
}
|
|
}
|
|
return $f;
|
|
}
|
|
|
|
protected function makeEntry(\stdClass $entry): Entry {
|
|
$e = new Entry;
|
|
foreach ($entry as $k => $v) {
|
|
if (in_array($k, ["link", "relatedLink", "banner"])) {
|
|
$e->$k = new Url($v);
|
|
} elseif (in_array($k, ["title", "summary", "content"])) {
|
|
$e->$k = $this->makeText($v);
|
|
} else {
|
|
$e->$k = $v;
|
|
}
|
|
}
|
|
return $e;
|
|
}
|
|
|
|
protected 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;
|
|
}
|
|
|
|
protected function makePerson(\stdClass $person): Person {
|
|
$p = new Person;
|
|
foreach ($person as $k => $v) {
|
|
if (in_array($k, ["url", "avatar"])) {
|
|
$p->$k = new Url($v);
|
|
} else {
|
|
$p->$k = $v;
|
|
}
|
|
}
|
|
return $p;
|
|
}
|
|
}
|