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 $entries;
private function __construct() {
}
public static function parse(string $data, ?string $contentType = null, ?string $url = null): self {
$out = new self;
return $out;

2
lib/Parser/Exception.php

@ -8,5 +8,5 @@ namespace JKingWeb\Lax\Parser;
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\Collection as PersonCollection;
use JKingWeb\Lax\Category\Collection as CategoryCollection;
use JKingWeb\Lax\Parser\Exception;
class Feed implements \JKingWeb\Lax\Parser\Feed {
use 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 = "") {
$this->init($data, $contentType);
$this->data = $data;
$this->contentType = $contentType;
$this->url = $url;
}
/** Performs initialization of the instance */
protected function init(string $data, string $contentType = "", string $url = "") {
$this->reqUrl = $url;
$this->json = json_decode($data);
$this->url = $this->reqUrl;
$this->type = "json";
$this->version = $this->fetchMember("version", "str") ?? "";
/** Performs format-specific preparation and validation */
protected function init(): void {
$type = preg_replace("/[\s;,].*/", "", trim(strtolower($this->contentType)));
if (strlen($type) && !in_array($type, self::MIME_TYPES)) {
throw new Exception("notJSONType");
}
$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 */
public function parse(\JKingWeb\Lax\Feed $feed): \JKingWeb\Lax\Feed {
$this->init();
return $feed;
$feed->id = $this->getId();
$feed->url = $this->getUrl();
$feed->link = $this->getLink();

11
tests/cases/JSON/TestJSONFeed.php

@ -6,7 +6,9 @@
declare(strict_types=1);
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> */
class TestJSON extends \PHPUnit\Framework\TestCase {
@ -17,9 +19,11 @@ class TestJSON extends \PHPUnit\Framework\TestCase {
} elseif (!is_string($input)) {
throw new \Exception("Test input is invalid");
}
$f = new Feed;
$p = new Parser($input, $type);
if ($output instanceof \Exception) {
$this->expectExceptionObject($output);
new Feed($input, $type);
$p->parse($f);
} else {
$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 (json_decode(file_get_contents($path), true) as $index => $test) {
if (isset($test['exception'])) {
$class = "\JKingWeb\Lax\Parser\Exception" . $test['exception'][0];
$test['output'] = new $class($test['exception'][1] ?? "");
$test['output'] = new Exception((string) $test['exception']);
}
yield "$file #$index: {$test['description']}" => [
$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",
"input": "{",
"exception": ["Syntax", "notJSON"]
"exception": "notJSON"
},
{
"description": "Not valid JSON 2",
"input": "<rss><channel/></rss>",
"exception": ["Syntax", "notJSON"]
"exception": "notJSON"
},
{
"description": "Not a JSON feed 1",
"input": {},
"exception": ["Semantics", "notAFeed"]
"input": "{}",
"exception": "notJSONFeed"
},
{
"description": "Not a JSON feed 2",
"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/"},
"exception": ["Semantics", "unknownVersion"]
"exception": "notJSONFeed"
},
{
"description": "Unknown version 2",
"description": "Unknown version 1",
"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"},
"exception": ["Semantics", "unknownVersion"]
"exception": "unsupportedJSONFeedVersion"
},
{
"description": "Unknown version 4",
"input": {"version": "https://jsonfeed.org/version/1.1"},
"exception": ["Semantics", "unknownVersion"]
"description": "Unknown version 3",
"input": {"version": "https://jsonfeed.org/version/0.1"},
"exception": "unsupportedJSONFeedVersion"
}
]
Loading…
Cancel
Save