* @covers JKingWeb\Lax\Parser\JSON\Feed * @covers JKingWeb\Lax\Parser\JSON\Entry */ class JSONTest extends \PHPUnit\Framework\TestCase { /** @dataProvider provideJSONFeedVersion1 */ public function testJSONFeedVersion1($input, string $type, ?string $url, $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, $url); 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); } } public function provideJSONFeedVersion1(): iterable { foreach (new \GlobIterator(__DIR__."/*.yaml", \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); } yield "$file: {$description}" => [ $test->input, $test->type ?? "", $test->doc_url ?? null, $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) { if ($kk === "url") { $f->$k->$kk = $this->makeUrl($vv); } else { $f->$k->$kk = $vv; } } } elseif (in_array($k, ["url", "link", "icon", "image"])) { $f->$k = $this->makeUrl($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 = $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; } 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 = $this->makeUrl($v); } else { $p->$k = $v; } } return $p; } protected function makeEnclosure(\stdClass $enclosure): Enclosure { $e = new Enclosure; foreach ($enclosure as $k => $v) { if ($k === "urli") { $e->$k = $this->makeUrl($v); } else { $e->$k = $v; } } return $e; } protected function makeUrl($url): ?Url { if (is_array($url)) { return new Url($url[0] ?? "", ($url[1] ?? null) ? new Url($url[1]) : null); } else { return new Url($url); } } }