Browse Source

Make first battery of tests pass

master
J. King 4 years ago
parent
commit
69ceee0b39
  1. 3
      lib/Feed.php
  2. 2
      lib/Parser/Exception.php
  3. 10
      lib/Parser/ExceptionSemantics.php
  4. 10
      lib/Parser/ExceptionSyntax.php
  5. 47
      lib/Parser/JSON/Feed.php
  6. 11
      tests/cases/JSON/TestJSONFeed.php
  7. 34
      tests/cases/JSON/failures.json

3
lib/Feed.php

@ -19,9 +19,6 @@ class Feed {
public $dateModified; public $dateModified;
public $entries; public $entries;
private function __construct() {
}
public static function parse(string $data, ?string $contentType = null, ?string $url = null): self { public static function parse(string $data, ?string $contentType = null, ?string $url = null): self {
$out = new self; $out = new self;
return $out; return $out;

2
lib/Parser/Exception.php

@ -8,5 +8,5 @@ namespace JKingWeb\Lax\Parser;
use JKingWeb\Lax\Exception as BaseException; use JKingWeb\Lax\Exception as BaseException;
abstract class Exception extends BaseException { class Exception extends BaseException {
} }

10
lib/Parser/ExceptionSemantics.php

@ -1,10 +0,0 @@
<?php
/** @license MIT
* Copyright 2018 J. King et al.
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Lax\Parser;
class ExceptionSemantics extends Exception {
}

10
lib/Parser/ExceptionSyntax.php

@ -1,10 +0,0 @@
<?php
/** @license MIT
* Copyright 2018 J. King et al.
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Lax\Parser;
class ExceptionSyntax extends Exception {
}

47
lib/Parser/JSON/Feed.php

@ -9,27 +9,56 @@ namespace JKingWeb\Lax\Parser\JSON;
use JKingWeb\Lax\Person\Person; use JKingWeb\Lax\Person\Person;
use JKingWeb\Lax\Person\Collection as PersonCollection; use JKingWeb\Lax\Person\Collection as PersonCollection;
use JKingWeb\Lax\Category\Collection as CategoryCollection; use JKingWeb\Lax\Category\Collection as CategoryCollection;
use JKingWeb\Lax\Parser\Exception;
class Feed implements \JKingWeb\Lax\Parser\Feed { class Feed implements \JKingWeb\Lax\Parser\Feed {
use Construct; use Construct;
use Primitives\Construct; use Primitives\Construct;
/** Constructs a parsed feed */ const MIME_TYPES = [
"application/json", // generic JSON
"application/feed+json", // JSON Feed-specific type
"text/json", // obsolete type for JSON
];
const VERSIONS = [
'https://jsonfeed.org/version/1' => "1",
'https://jsonfeed.org/version/1.1' => "1.1",
];
protected $data;
protected $contentType;
protected $url;
/** Constructs a feed parser without actually doing anything */
public function __construct(string $data, string $contentType = "", string $url = "") { public function __construct(string $data, string $contentType = "", string $url = "") {
$this->init($data, $contentType); $this->data = $data;
$this->contentType = $contentType;
$this->url = $url;
} }
/** Performs initialization of the instance */ /** Performs format-specific preparation and validation */
protected function init(string $data, string $contentType = "", string $url = "") { protected function init(): void {
$this->reqUrl = $url; $type = preg_replace("/[\s;,].*/", "", trim(strtolower($this->contentType)));
$this->json = json_decode($data); if (strlen($type) && !in_array($type, self::MIME_TYPES)) {
$this->url = $this->reqUrl; throw new Exception("notJSONType");
$this->type = "json"; }
$this->version = $this->fetchMember("version", "str") ?? ""; $data = @json_decode($this->data, false, 20);
if (!is_object($data)) {
throw new Exception("notJSON");
} elseif (!isset($data->version) || !preg_match("<^https://jsonfeed\.org/version/(\d+(?:\.\d+)?)$>", $data->version, $match)) {
throw new Exception("notJSONFeed");
} elseif (version_compare($match[1], "1.0", "<") || version_compare($match[1], "2", ">=")) {
throw new Exception("unsupportedJSONFeedVersion");
}
$this->data = $data;
$this->version = $match[1];
} }
/** Parses the feed to extract sundry metadata */ /** Parses the feed to extract sundry metadata */
public function parse(\JKingWeb\Lax\Feed $feed): \JKingWeb\Lax\Feed { public function parse(\JKingWeb\Lax\Feed $feed): \JKingWeb\Lax\Feed {
$this->init();
return $feed;
$feed->id = $this->getId(); $feed->id = $this->getId();
$feed->url = $this->getUrl(); $feed->url = $this->getUrl();
$feed->link = $this->getLink(); $feed->link = $this->getLink();

11
tests/cases/JSON/TestJSONFeed.php

@ -6,7 +6,9 @@
declare(strict_types=1); declare(strict_types=1);
namespace JKingWeb\Lax\TestCase\JSON; namespace JKingWeb\Lax\TestCase\JSON;
use JKingWeb\Lax\Parser\JSON\Feed; use JKingWeb\Lax\Parser\Exception;
use JKingWeb\Lax\Feed;
use JKingWeb\Lax\Parser\JSON\Feed as Parser;
/** @covers JKingWeb\Lax\Parser\JSON\Feed<extended> */ /** @covers JKingWeb\Lax\Parser\JSON\Feed<extended> */
class TestJSON extends \PHPUnit\Framework\TestCase { class TestJSON extends \PHPUnit\Framework\TestCase {
@ -17,9 +19,11 @@ class TestJSON extends \PHPUnit\Framework\TestCase {
} elseif (!is_string($input)) { } elseif (!is_string($input)) {
throw new \Exception("Test input is invalid"); throw new \Exception("Test input is invalid");
} }
$f = new Feed;
$p = new Parser($input, $type);
if ($output instanceof \Exception) { if ($output instanceof \Exception) {
$this->expectExceptionObject($output); $this->expectExceptionObject($output);
new Feed($input, $type); $p->parse($f);
} else { } else {
$this->assertTrue(false); $this->assertTrue(false);
} }
@ -29,8 +33,7 @@ class TestJSON extends \PHPUnit\Framework\TestCase {
foreach (new \GlobIterator(__DIR__."/*.json", \FilesystemIterator::CURRENT_AS_PATHNAME | \FilesystemIterator::KEY_AS_FILENAME) as $file => $path) { foreach (new \GlobIterator(__DIR__."/*.json", \FilesystemIterator::CURRENT_AS_PATHNAME | \FilesystemIterator::KEY_AS_FILENAME) as $file => $path) {
foreach (json_decode(file_get_contents($path), true) as $index => $test) { foreach (json_decode(file_get_contents($path), true) as $index => $test) {
if (isset($test['exception'])) { if (isset($test['exception'])) {
$class = "\JKingWeb\Lax\Parser\Exception" . $test['exception'][0]; $test['output'] = new Exception((string) $test['exception']);
$test['output'] = new $class($test['exception'][1] ?? "");
} }
yield "$file #$index: {$test['description']}" => [ yield "$file #$index: {$test['description']}" => [
$test['input'], $test['input'],

34
tests/cases/JSON/failures.json

@ -1,42 +1,48 @@
[ [
{
"description": "Content-Type mismatch",
"type": "text/html",
"input": {"version": "https://jsonfeed.org/version/1"},
"exception": "notJSONType"
},
{ {
"description": "Not valid JSON 1", "description": "Not valid JSON 1",
"input": "{", "input": "{",
"exception": ["Syntax", "notJSON"] "exception": "notJSON"
}, },
{ {
"description": "Not valid JSON 2", "description": "Not valid JSON 2",
"input": "<rss><channel/></rss>", "input": "<rss><channel/></rss>",
"exception": ["Syntax", "notJSON"] "exception": "notJSON"
}, },
{ {
"description": "Not a JSON feed 1", "description": "Not a JSON feed 1",
"input": {}, "input": "{}",
"exception": ["Semantics", "notAFeed"] "exception": "notJSONFeed"
}, },
{ {
"description": "Not a JSON feed 2", "description": "Not a JSON feed 2",
"input": {"version": "https://example.com/"}, "input": {"version": "https://example.com/"},
"exception": ["Semantics", "notAFeed"] "exception": "notJSONFeed"
}, },
{ {
"description": "Unknown version 1", "description": "Not a JSON feed 3",
"input": {"version": "https://jsonfeed.org/version/"}, "input": {"version": "https://jsonfeed.org/version/"},
"exception": ["Semantics", "unknownVersion"] "exception": "notJSONFeed"
}, },
{ {
"description": "Unknown version 2", "description": "Unknown version 1",
"input": {"version": "https://jsonfeed.org/version/2"}, "input": {"version": "https://jsonfeed.org/version/2"},
"exception": ["Semantics", "unknownVersion"] "exception": "unsupportedJSONFeedVersion"
}, },
{ {
"description": "Unknown version 3", "description": "Unknown version 2",
"input": {"version": "https://jsonfeed.org/version/11"}, "input": {"version": "https://jsonfeed.org/version/11"},
"exception": ["Semantics", "unknownVersion"] "exception": "unsupportedJSONFeedVersion"
}, },
{ {
"description": "Unknown version 4", "description": "Unknown version 3",
"input": {"version": "https://jsonfeed.org/version/1.1"}, "input": {"version": "https://jsonfeed.org/version/0.1"},
"exception": ["Semantics", "unknownVersion"] "exception": "unsupportedJSONFeedVersion"
} }
] ]
Loading…
Cancel
Save