Browse Source

Make test format to YAML; extract more media types

YAML tests should make it significantly less painful to test parsing of
XML-based newsfeed formats
master
J. King 4 years ago
parent
commit
7affcfa57f
  1. 4
      lib/Parser/Construct.php
  2. 28
      tests/cases/JSON/JSONTest.php
  3. 628
      tests/cases/JSON/entry.json
  4. 547
      tests/cases/JSON/entry.yaml
  5. 33
      tests/cases/JSON/failures.json
  6. 24
      tests/cases/JSON/failures.yaml
  7. 261
      tests/cases/JSON/feed.json
  8. 221
      tests/cases/JSON/feed.yaml
  9. 3
      vendor-bin/phpunit/composer.json
  10. 61
      vendor-bin/phpunit/composer.lock

4
lib/Parser/Construct.php

@ -64,7 +64,7 @@ trait Construct {
}
protected function parseMediaType(string $type, ?Url $url = null): ?string {
if (preg_match('<^\s*([0-9a-z]+(?:/[!#$%&\'\*\+\-\.^_`|~0-9a-z]+)?)(?:\s|;|$)>i', $type, $match)) {
if (preg_match('<^\s*([0-9a-z]+(?:/[!#$%&\'\*\+\-\.^_`|~0-9a-z]+)?)(?:\s|;|,|$)>i', $type, $match)) {
/* NOTE: The pattern used here is a subset of what is
technically allowed by RFC 7231: the "type" portion
is supposed to be as general as the "subtype" portion,
@ -91,6 +91,8 @@ trait Construct {
return ($this->mime ?? ($this->mime = new \Mimey\MimeTypes))->getMimeType($ext);
}
}
} elseif ($url && $url->getScheme() === "data") {
return $this->parseMediaType($url->getPath()) ?? "text/plain";
}
return null;
}

28
tests/cases/JSON/JSONTest.php

@ -8,27 +8,26 @@ namespace JKingWeb\Lax\TestCase\JSON;
/* Test format is as follows:
Each test is a JSON object with the following keys:
Each test is a YAML map with the following keys:
- `description`: a short human-readable description of the test
- `doc_url`: A fictitious URL where a newsfeed might be located, used for relative URL resolution
- `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
- `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 'description' and 'input' keys along with either 'output' or 'exception'
are required for all tests.
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 JSON:
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 an array with the relative part first, followed by the base that should
as a sequence with the relative part first, followed by the base that should
be applied to it
- Any collections should be represented as arrays of objects, which will
- 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 an object with any of the properties of the
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
@ -49,6 +48,9 @@ use JKingWeb\Lax\Enclosure\Enclosure;
use JKingWeb\Lax\Person\Collection as PersonCollection;
use JKingWeb\Lax\Category\Collection as CategoryCollection;
use JKingWeb\Lax\Enclosure\Collection as EnclosureCollection;
use Symfony\Component\Yaml\Yaml;
use Symfony\Component\Yaml\Parser as YamlParser;
/**
* @covers JKingWeb\Lax\Parser\Construct<extended>
@ -75,12 +77,12 @@ class JSONTest extends \PHPUnit\Framework\TestCase {
}
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) {
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 #$index: {$test->description}" => [
yield "$file: {$description}" => [
$test->input,
$test->type ?? "",
$test->doc_url ?? null,
@ -204,4 +206,4 @@ class JSONTest extends \PHPUnit\Framework\TestCase {
return new Url($url);
}
}
}
}

628
tests/cases/JSON/entry.json

@ -1,628 +0,0 @@
[
{
"description": "Minimal entry",
"input": {
"version": "https://jsonfeed.org/version/1",
"items": [{
"id": "1"
}]
},
"output": {
"format": "json",
"version": "1",
"entries": [
{
"id": "1"
}
]
}
},
{
"description": "Invalid entry 1 (no ID)",
"input": {
"version": "https://jsonfeed.org/version/1",
"items": [{
"title": "Example title"
}]
},
"output": {
"format": "json",
"version": "1"
}
},
{
"description": "Invalid entry 2 (null ID)",
"input": {
"version": "https://jsonfeed.org/version/1",
"items": [{
"id": null,
"title": "Example title"
}]
},
"output": {
"format": "json",
"version": "1"
}
},
{
"description": "Invalid entry 3 (boolean ID)",
"input": {
"version": "https://jsonfeed.org/version/1",
"items": [{
"id": true,
"title": "Example title"
}]
},
"output": {
"format": "json",
"version": "1"
}
},
{
"description": "Invalid entry 4 (array ID)",
"input": {
"version": "https://jsonfeed.org/version/1",
"items": [{
"id": ["1"],
"title": "Example title"
}]
},
"output": {
"format": "json",
"version": "1"
}
},
{
"description": "Invalid entry 5 (object ID)",
"input": {
"version": "https://jsonfeed.org/version/1",
"items": [{
"id": {"id": "1"},
"title": "Example title"
}]
},
"output": {
"format": "json",
"version": "1"
}
},
{
"description": "Invalid entry 6 (empty string ID)",
"input": {
"version": "https://jsonfeed.org/version/1",
"items": [{
"id": "",
"title": "Example title"
}]
},
"output": {
"format": "json",
"version": "1"
}
},
{
"description": "Integer ID",
"input": {
"version": "https://jsonfeed.org/version/1",
"items": [{
"id": 1
}]
},
"output": {
"format": "json",
"version": "1",
"entries": [
{
"id": "1"
}
]
}
},
{
"description": "Float ID",
"input": {
"version": "https://jsonfeed.org/version/1",
"items": [{
"id": 3.0e-10
}]
},
"output": {
"format": "json",
"version": "1",
"entries": [
{
"id": "0.0000000003"
}
]
}
},
{
"description": "Negative float ID",
"input": {
"version": "https://jsonfeed.org/version/1",
"items": [{
"id": -3.0e-10
}]
},
"output": {
"format": "json",
"version": "1",
"entries": [
{
"id": "-0.0000000003"
}
]
}
},
{
"description": "Simple float ID",
"input": {
"version": "https://jsonfeed.org/version/1",
"items": [{
"id": 0.3
}]
},
"output": {
"format": "json",
"version": "1",
"entries": [
{
"id": "0.3"
}
]
}
},
{
"description": "Bignum ID",
"input": "{\"version\": \"https://jsonfeed.org/version/1\",\"items\": [{\"id\": 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999}]}",
"output": {
"format": "json",
"version": "1",
"entries": [
{
"id": "9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999"
}
]
}
},
{
"description": "Entry language",
"input": {
"version": "https://jsonfeed.org/version/1",
"language": "en",
"items": [
{
"id": 1,
"language": "fr"
},
{
"id": "2"
}
]
},
"output": {
"format": "json",
"version": "1",
"lang": "en",
"entries": [
{
"id": "1",
"lang": "fr"
},
{
"id": "2",
"lang": "en"
}
]
}
},
{
"description": "Entry banner",
"input": {
"version": "https://jsonfeed.org/version/1",
"items": [
{
"id": "1",
"banner_image": "http://example.com/banner"
}
]
},
"output": {
"format": "json",
"version": "1",
"entries": [
{
"id": "1",
"banner": "http://example.com/banner"
}
]
}
},
{
"description": "Entry dates",
"input": {
"version": "https://jsonfeed.org/version/1",
"items": [
{
"id": "1",
"date_published": "2020-03-03T21:12:42Z",
"date_modified": "2020-03-03T21:12:42Z"
}
]
},
"output": {
"format": "json",
"version": "1",
"entries": [
{
"id": "1",
"dateCreated": "2020-03-03T21:12:42Z",
"dateModified": "2020-03-03T21:12:42Z"
}
]
}
},
{
"description": "Entry URLs",
"input": {
"version": "https://jsonfeed.org/version/1",
"items": [
{
"id": "1",
"url": "http://example.com/",
"external_url": "http://example.org/"
}
]
},
"output": {
"format": "json",
"version": "1",
"entries": [
{
"id": "1",
"link": "http://example.com/",
"relatedLink": "http://example.org/"
}
]
}
},
{
"description": "Entry title",
"input": {
"version": "https://jsonfeed.org/version/1",
"items": [
{
"id": "1",
"title": "Example title"
}
]
},
"output": {
"format": "json",
"version": "1",
"entries": [
{
"id": "1",
"title": "Example title"
}
]
}
},
{
"description": "Entry summary",
"input": {
"version": "https://jsonfeed.org/version/1",
"items": [
{
"id": "1",
"summary": "Example summary"
}
]
},
"output": {
"format": "json",
"version": "1",
"entries": [
{
"id": "1",
"summary": "Example summary"
}
]
}
},
{
"description": "Entry content (plain only)",
"input": {
"version": "https://jsonfeed.org/version/1",
"items": [
{
"id": "1",
"content_text": "Plain content"
}
]
},
"output": {
"format": "json",
"version": "1",
"entries": [
{
"id": "1",
"content": {
"plain": "Plain content"
}
}
]
}
},
{
"description": "Entry content (HTML only)",
"input": {
"version": "https://jsonfeed.org/version/1",
"items": [
{
"id": "1",
"content_html": "HTML content"
}
]
},
"output": {
"format": "json",
"version": "1",
"entries": [
{
"id": "1",
"content": {
"html": "HTML content"
}
}
]
}
},
{
"description": "Entry content (mixed)",
"input": {
"version": "https://jsonfeed.org/version/1",
"items": [
{
"id": "1",
"content_text": "Plain content",
"content_html": "HTML content"
}
]
},
"output": {
"format": "json",
"version": "1",
"entries": [
{
"id": "1",
"content": {
"plain": "Plain content",
"html": "HTML content"
}
}
]
}
},
{
"description": "Entry categories",
"input": {
"version": "https://jsonfeed.org/version/1",
"items": [
{
"id": "1",
"tags": ["this", "that", "the other thing", "", null, false, 1, 3.0, " "]
}
]
},
"output": {
"format": "json",
"version": "1",
"entries": [
{
"id": "1",
"categories": [
{"name": "this"},
{"name": "that"},
{"name": "the other thing"},
{"name": " "}
]
}
]
}
},
{
"description": "Entry authors",
"input": {
"version": "https://jsonfeed.org/version/1",
"authors": [
{"name": "Jane Doe"},
{"name": "John Doe"}
],
"items": [
{
"id": 1,
"author": {"name": "John Doe"},
"authors": [{"name": "Jane Doe"}]
},
{
"id": 2,
"author": {"name": "John Doe"}
},
{
"id": 3,
"authors": [{"name": "Jane Doe"}]
},
{
"id": 4
},
{
"id": 5,
"authors": [{"NAME": "Jane Doe"}]
}
]
},
"output": {
"format": "json",
"version": "1",
"people": [
{"name": "Jane Doe", "role": "author"},
{"name": "John Doe", "role": "author"}
],
"entries": [
{"id": "1", "people": [{"name": "Jane Doe", "role": "author"}]},
{"id": "2", "people": [{"name": "John Doe", "role": "author"}]},
{"id": "3", "people": [{"name": "Jane Doe", "role": "author"}]},
{"id": "4", "people": [{"name": "Jane Doe", "role": "author"},{"name": "John Doe", "role": "author"}]},
{"id": "5", "people": [{"name": "Jane Doe", "role": "author"},{"name": "John Doe", "role": "author"}]}
]
}
},
{
"description": "Entry image",
"input": {
"version": "https://jsonfeed.org/version/1",
"items": [{
"id": "1",
"image": "http://example.com/image"
}]
},
"output": {
"format": "json",
"version": "1",
"entries": [
{
"id": "1",
"enclosures": [
{
"type": "image",
"url": "http://example.com/image",
"preferred": true
}
]
}
]
}
},
{
"description": "Entry attachments",
"input": {
"version": "https://jsonfeed.org/version/1",
"items": [{
"id": "1",
"attachments": [
{
"url": "http://example.com/image",
"mime_type": "image/svg+xml; charset=\"urf-8\"",
"title": "Logo",
"size_in_bytes": 2345
},
{
"url": "http://example.com/graphic.png"
},
{
"url": "http://example.com/graphic.PNG"
},
{
"url": "data:text/plain,Hello%20World!",
"title": "Example text"
},
{
"url": "data:text/plain,File:example.jpg",
"title": "Sneaky URN"
},
{
"url": "http://example.com/talk",
"mime_type": "audio",
"duration_in_seconds": 72
},
{
"title": "Invalid URL",
"url": "http://[.com/bogus"
},
{
"title": "No URL"
}
]
}]
},
"output": {
"format": "json",
"version": "1",
"entries": [
{
"id": "1",
"enclosures": [
{
"type": "image/svg+xml",
"url": "http://example.com/image",
"title": "Logo",
"size": 2345
},
{
"type": "image/png",
"url": "http://example.com/graphic.png"
},
{
"type": "image/png",
"url": "http://example.com/graphic.PNG"
},
{
"url": "data:text/plain,Hello%20World!",
"title": "Example text"
},
{
"url": "data:text/plain,File:example.jpg",
"title": "Sneaky URN"
},
{
"url": "http://example.com/talk",
"type": "audio",
"duration": 72
}
]
}
]
}
},
{
"description": "Entry image and attachments",
"input": {
"version": "https://jsonfeed.org/version/1",
"items": [{
"id": "1",
"attachments": [
{
"url": "http://example.com/image",
"mime_type": "image/svg+xml; charset=\"urf-8\"",
"title": "Logo",
"size_in_bytes": 2345
}
],
"image": "http://example.com/image"
}]
},
"output": {
"format": "json",
"version": "1",
"entries": [
{
"id": "1",
"enclosures": [
{
"type": "image",
"url": "http://example.com/image",
"preferred": true
},
{
"type": "image/svg+xml",
"url": "http://example.com/image",
"title": "Logo",
"size": 2345
}
]
}
]
}
}
]

547
tests/cases/JSON/entry.yaml

@ -0,0 +1,547 @@
Minimal entry:
input: >
{
"version": "https://jsonfeed.org/version/1",
"items": [{
"id": "1"
}]
}
output:
format: json
version: '1'
entries:
- id: '1'
Invalid entry 1: # no ID
input: >
{
"version": "https://jsonfeed.org/version/1",
"items": [{
"title": "Example title"
}]
}
output:
format: json
version: '1'
Invalid entry 2: # null ID
input: >
{
"version": "https://jsonfeed.org/version/1",
"items": [{
"title": "Example title",
"id": null
}]
}
output:
format: json
version: '1'
Invalid entry 3: # boolean ID
input: >
{
"version": "https://jsonfeed.org/version/1",
"items": [{
"title": "Example title",
"id": true
}]
}
output:
format: json
version: '1'
Invalid entry 4: # array ID
input: >
{
"version": "https://jsonfeed.org/version/1",
"items": [{
"title": "Example title",
"id": ["1"]
}]
}
output:
format: json
version: '1'
Invalid entry 5: # object ID
input: >
{
"version": "https://jsonfeed.org/version/1",
"items": [{
"title": "Example title",
"id": {"id": "1"}
}]
}
output:
format: json
version: '1'
Invalid entry 6: # empty string ID
input: >
{
"version": "https://jsonfeed.org/version/1",
"items": [{
"title": "Example title",
"id": ""
}]
}
output:
format: json
version: '1'
Integer ID:
input: >
{
"version": "https://jsonfeed.org/version/1",
"items": [{
"id": 1
}]
}
output:
format: json
version: '1'
entries:
- id: '1'
Float ID:
input: >
{
"version": "https://jsonfeed.org/version/1",
"items": [{
"id": 3.0e-10
}]
}
output:
format: json
version: '1'
entries:
- id: '0.0000000003'
Negative float ID:
input: >
{
"version": "https://jsonfeed.org/version/1",
"items": [{
"id": -3.0e-10
}]
}
output:
format: json
version: '1'
entries:
- id: '-0.0000000003'
Simple float ID:
input: >
{
"version": "https://jsonfeed.org/version/1",
"items": [{
"id": 0.3
}]
}
output:
format: json
version: '1'
entries:
- id: '0.3'
Bignum ID:
input: >
{
"version": "https://jsonfeed.org/version/1",
"items": [{
"id": 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999
}]
}
output:
format: json
version: '1'
entries:
- id: '9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999'
Entry language:
input: >
{
"version": "https://jsonfeed.org/version/1",
"language": "en",
"items": [
{
"id": 1,
"language": "fr"
},
{
"id": "2"
}
]
}
output:
format: json
version: '1'
lang: en
entries:
- id: '1'
lang: fr
- id: '2'
lang: en
Entry banner:
input: >
{
"version": "https://jsonfeed.org/version/1",
"items": [
{
"id": "1",
"banner_image": "http://example.com/banner"
}
]
}
output:
format: json
version: '1'
entries:
- id: '1'
banner: 'http://example.com/banner'
Entry dates:
input: >
{
"version": "https://jsonfeed.org/version/1",
"items": [
{
"id": "1",
"date_published": "2020-03-03T21:12:42Z",
"date_modified": "2020-03-03T21:12:42Z"
}
]
}
output:
format: json
version: '1'
entries:
- id: '1'
dateCreated: '2020-03-03T21:12:42Z'
dateModified: '2020-03-03T21:12:42Z'
Entry URLs:
input: >
{
"version": "https://jsonfeed.org/version/1",
"items": [
{
"id": "1",
"url": "http://example.com/",
"external_url": "http://example.org/"
}
]
}
output:
format: json
version: '1'
entries:
- id: '1'
link: 'http://example.com/'
relatedLink: 'http://example.org/'
Entry title:
input: >
{
"version": "https://jsonfeed.org/version/1",
"items": [
{
"id": "1",
"title": "Example title"
}
]
}
output:
format: json
version: '1'
entries:
- id: '1'
title: 'Example title'
Entry summary:
input: >
{
"version": "https://jsonfeed.org/version/1",
"items": [
{
"id": "1",
"summary": "Example summary"
}
]
}
output:
format: json
version: '1'
entries:
- id: '1'
summary: 'Example summary'
Entry content (plain only):
input: >
{
"version": "https://jsonfeed.org/version/1",
"items": [
{
"id": "1",
"content_text": "Plain content"
}
]
}
output:
format: json
version: '1'
entries:
- id: '1'
content:
plain: 'Plain content'
Entry content (HTML only):
input: >
{
"version": "https://jsonfeed.org/version/1",
"items": [
{
"id": "1",
"content_html": "HTML content"
}
]
}
output:
format: json
version: '1'
entries:
- id: '1'
content:
html: 'HTML content'
Entry content (mixed):
input: >
{
"version": "https://jsonfeed.org/version/1",
"items": [
{
"id": "1",
"content_text": "Plain content",
"content_html": "HTML content"
}
]
}
output:
format: json
version: '1'
entries:
- id: '1'
content:
plain: 'Plain content'
html: 'HTML content'
Entry categories:
input: >
{
"version": "https://jsonfeed.org/version/1",
"items": [
{
"id": "1",
"tags": ["this", "that", "the other thing", "", null, false, 1, 3.0, " "]
}
]
}
output:
format: json
version: '1'
entries:
- id: '1'
categories:
- name: this
- name: that
- name: 'the other thing'
- name: ' '
Entry authors:
input: >
{
"version": "https://jsonfeed.org/version/1",
"authors": [
{"name": "Jane Doe"},
{"name": "John Doe"}
],
"items": [
{
"id": 1,
"author": {"name": "John Doe"},
"authors": [{"name": "Jane Doe"}]
},
{
"id": 2,
"author": {"name": "John Doe"}
},
{
"id": 3,
"authors": [{"name": "Jane Doe"}]
},
{
"id": 4
},
{
"id": 5,
"authors": [{"NAME": "Jane Doe"}]
}
]
}
output:
format: json
version: '1'
people:
- name: Jane Doe
role: author
- name: John Doe
role: author
entries:
- id: '1'
people:
- name: Jane Doe
role: author
- id: '2'
people:
- name: John Doe
role: author
- id: '3'
people:
- name: Jane Doe
role: author
- id: '4'
people:
- name: Jane Doe
role: author
- name: John Doe
role: author
- id: '5'
people:
- name: Jane Doe
role: author
- name: John Doe
role: author
Entry image:
input: >
{
"version": "https://jsonfeed.org/version/1",
"items": [{
"id": "1",
"image": "http://example.com/image"
}]
}
output:
format: json
version: '1'
entries:
- id: '1'
enclosures:
- url: 'http://example.com/image'
type: image
preferred: true
Entry attachments:
input: >
{
"version": "https://jsonfeed.org/version/1",
"items": [{
"id": "1",
"attachments": [
{
"url": "http://example.com/image",
"mime_type": "image/svg+xml; charset=\"urf-8\"",
"title": "Logo",
"size_in_bytes": 2345
},
{
"url": "http://example.com/graphic.png"
},
{
"url": "http://example.com/graphic.PNG"
},
{
"url": "data:text/rtf,Hello%20World!",
"title": "Example text"
},
{
"url": "data:,Hello%20World!",
"title": "Example text"
},
{
"url": "urn:bogus:example.jpg",
"title": "Sneaky URN"
},
{
"url": "http://example.com/talk",
"mime_type": "audio",
"duration_in_seconds": 72
},
{
"title": "Invalid URL",
"url": "http://[.com/bogus"
},
{
"title": "No URL"
}
]
}]
}
output:
format: json
version: '1'
entries:
- id: '1'
enclosures:
- url: 'http://example.com/image'
type: 'image/svg+xml'
title: Logo
size: 2345
- url: 'http://example.com/graphic.png'
type: 'image/png'
- url: 'http://example.com/graphic.PNG'
type: 'image/png'
- url: 'data:text/rtf,Hello%20World!'
type: 'text/rtf'
title: 'Example text'
- url: 'data:,Hello%20World!'
type: 'text/plain'
title: 'Example text'
- url: 'urn:bogus:example.jpg'
title: 'Sneaky URN'
- url: 'http://example.com/talk'
type: 'audio'
duration: 72
Entry image and attachments:
input: >
{
"version": "https://jsonfeed.org/version/1",
"items": [{
"id": "1",
"attachments": [
{
"url": "http://example.com/logo",
"mime_type": "image/svg+xml; charset=\"urf-8\"",
"title": "Logo",
"size_in_bytes": 2345
}
],
"image": "http://example.com/image"
}]
}
output:
format: json
version: '1'
entries:
- id: '1'
enclosures:
- url: 'http://example.com/image'
type: image
preferred: true
- url: 'http://example.com/logo'
type: 'image/svg+xml'
title: Logo
size: 2345

33
tests/cases/JSON/failures.json

@ -1,33 +0,0 @@
[
{
"description": "Content-Type mismatch",
"type": "text/html",
"input": {"version": "https://jsonfeed.org/version/1"},
"exception": "notJSONType"
},
{
"description": "Not valid JSON 1",
"input": "{",
"exception": "notJSON"
},
{
"description": "Not valid JSON 2",
"input": "<rss><channel/></rss>",
"exception": "notJSON"
},
{
"description": "Not a JSON feed 1",
"input": "{}",
"exception": "notJSONFeed"
},
{
"description": "Not a JSON feed 2",
"input": {"version": "https://example.com/"},
"exception": "notJSONFeed"
},
{
"description": "Not a JSON feed 3",
"input": {"version": "https://jsonfeed.org/version/"},
"exception": "notJSONFeed"
}
]

24
tests/cases/JSON/failures.yaml

@ -0,0 +1,24 @@
Content-Type mismatch:
type: text/html
input: '{"version": "https://jsonfeed.org/version/1"}'
exception: notJSONType
Not valid JSON 1:
input: '{'
exception: notJSON
Not valid JSON 2:
input: '<rss><channel/></rss>'
exception: notJSON
Not a JSON feed 1:
input: '{}'
exception: notJSONFeed
Not a JSON feed 2:
input: '{"version": "https://example.com/"}'
exception: notJSONFeed
Not a JSON feed 3:
input: '{"version": "https://jsonfeed.org/version/"}'
exception: notJSONFeed

261
tests/cases/JSON/feed.json

@ -1,261 +0,0 @@
[
{
"description": "Minimal example 1",
"input": {
"version": "https://jsonfeed.org/version/1"
},
"output": {
"format": "json",
"version": "1"
}
},
{
"description": "Minimal example 2",
"input": {
"version": "https://jsonfeed.org/version/1.1"
},
"output": {
"format": "json",
"version": "1.1"
}
},
{
"description": "Correct type of member",
"input": {
"version": "https://jsonfeed.org/version/1",
"title": "Example title"
},
"output": {
"format": "json",
"version": "1",
"title": "Example title"
}
},
{
"description": "Incorrect type of member",
"input": {
"version": "https://jsonfeed.org/version/1",
"title": 1001001
},
"output": {
"format": "json",
"version": "1"
}
},
{
"description": "URL -> ID equivalence",
"input": {
"version": "https://jsonfeed.org/version/1",
"title": "Example title",
"feed_url": "http://example.com/"
},
"output": {
"format": "json",
"version": "1",
"title": "Example title",
"id": "http://example.com/",
"url": "http://example.com/"
}
},
{
"description": "Single author",
"input": {
"version": "https://jsonfeed.org/version/1",
"author": {"name": "John Doe", "url": "http://example.org/", "avatar": "http://example.org/avatar"}
},
"output": {
"format": "json",
"version": "1",
"people": [
{
"role": "author",
"name": "John Doe",
"url": "http://example.org/",
"avatar": "http://example.org/avatar"
}
]
}
},
{
"description": "Multiple authors",
"input": {
"version": "https://jsonfeed.org/version/1",
"authors": [
{"name": "John Doe", "url": "http://example.org/", "avatar": "http://example.org/avatar"},
{"name": "Jane Doe", "url": "http://example.net/", "avatar": "http://example.net/avatar"}
]
},
"output": {
"format": "json",
"version": "1",
"people": [
{
"role": "author",
"name": "John Doe",
"url": "http://example.org/",
"avatar": "http://example.org/avatar"
},
{
"role": "author",
"name": "Jane Doe",
"url": "http://example.net/",
"avatar": "http://example.net/avatar"
}
]
}
},
{
"description": "Fallback author",
"input": {
"version": "https://jsonfeed.org/version/1",
"authors": [
{"name": "John Doe", "url": "http://example.org/", "avatar": "http://example.org/avatar"},
{"name": "Jane Doe", "url": "http://example.net/", "avatar": "http://example.net/avatar"}
],
"author": {"name": "John Smith", "url": "http://example.biz/", "avatar": "http://example.biz/avatar"}
},
"output": {
"format": "json",
"version": "1",
"people": [
{
"role": "author",
"name": "John Doe",
"url": "http://example.org/",
"avatar": "http://example.org/avatar"
},
{
"role": "author",
"name": "Jane Doe",
"url": "http://example.net/",
"avatar": "http://example.net/avatar"
}
]
}
},
{
"description": "Empty author",
"input": {
"version": "https://jsonfeed.org/version/1",
"author": {}
},
"output": {
"format": "json",
"version": "1"
}
},
{
"description": "Empty authors",
"input": {
"version": "https://jsonfeed.org/version/1",
"authors": [{}]
},
"output": {
"format": "json",
"version": "1"
}
},
{
"description": "Empty authors with fallback",
"input": {
"version": "https://jsonfeed.org/version/1",
"authors": [{}],
"author": {"name": "John Doe", "url": "http://example.org/", "avatar": "http://example.org/avatar"}
},
"output": {
"format": "json",
"version": "1",
"people": [
{
"role": "author",
"name": "John Doe",
"url": "http://example.org/",
"avatar": "http://example.org/avatar"
}
]
}
},
{
"description": "Expired feed",
"input": {
"version": "https://jsonfeed.org/version/1",
"expired": true
},
"output": {
"format": "json",
"version": "1",
"sched": {
"expired": true
}
}
},
{
"description": "Not expired feed",
"input": {
"version": "https://jsonfeed.org/version/1",
"expired": false
},
"output": {
"format": "json",
"version": "1",
"sched": {
"expired": false
}
}
},
{
"description": "Invalidly expired feed",
"input": {
"version": "https://jsonfeed.org/version/1",
"expired": 1
},
"output": {
"format": "json",
"version": "1"
}
},
{
"description": "Basic example",
"input": {
"version": "https://jsonfeed.org/version/1",
"language": "en",
"title": "Example title",
"feed_url": "http://example.com/",
"home_page_url": "http://example.net/",
"description": "Example description",
"user_comment": "Example comment",
"next_url": "http://example.com/next",
"icon": "http://example.com/image",
"favicon": "http://example.com/icon"
},
"output": {
"format": "json",
"version": "1",
"lang": "en",
"title": "Example title",
"id": "http://example.com/",
"url": "http://example.com/",
"link": "http://example.net/",
"summary": "Example description",
"icon": "http://example.com/icon",
"image": "http://example.com/image"
}
},
{
"description": "Relative URL resolution",
"doc_url": "http://example.com",
"input": {
"version": "https://jsonfeed.org/version/1",
"feed_url": "feed.json"
},
"output": {
"meta": {
"url": "http://example.com"
},
"format": "json",
"version": "1",
"id": "feed.json",
"url": ["feed.json", "http://example.com"]
}
}
]

221
tests/cases/JSON/feed.yaml

@ -0,0 +1,221 @@
Minimal example 1:
input: >
{
"version": "https://jsonfeed.org/version/1"
}
output:
format: json
version: '1'
Minimal example 2:
input: >
{
"version": "https://jsonfeed.org/version/1.1"
}
output:
format: json
version: '1.1'
Correct type of member:
input: >
{
"version": "https://jsonfeed.org/version/1",
"title": "Example title"
}
output:
format: json
version: '1'
title: 'Example title'
Incorrect type of member:
input: >
{
"version": "https://jsonfeed.org/version/1",
"title": 1001001
}
output:
format: json
version: '1'
URL -> ID equivalence:
input: >
{
"version": "https://jsonfeed.org/version/1",
"feed_url": "http://example.com/"
}
output:
format: json
version: '1'
id: 'http://example.com/'
url: 'http://example.com/'
Single author:
input: >
{
"version": "https://jsonfeed.org/version/1",
"author": {"name": "John Doe", "url": "http://example.org/", "avatar": "http://example.org/avatar"}
}
output:
format: json
version: '1'
people:
- role: author
name: John Doe
url: 'http://example.org/'
avatar: http://example.org/avatar
Multiple authors:
input: >
{
"version": "https://jsonfeed.org/version/1",
"authors": [
{"name": "John Doe", "url": "http://example.org/", "avatar": "http://example.org/avatar"},
{"name": "Jane Doe", "url": "http://example.net/", "avatar": "http://example.net/avatar"}
]
}
output:
format: json
version: '1'
people:
- role: author
name: John Doe
url: 'http://example.org/'
avatar: http://example.org/avatar
- role: author
name: Jane Doe
url: 'http://example.net/'
avatar: http://example.net/avatar
Fallback author:
input: >
{
"version": "https://jsonfeed.org/version/1",
"authors": [
{"name": "John Doe", "url": "http://example.org/", "avatar": "http://example.org/avatar"},
{"name": "Jane Doe", "url": "http://example.net/", "avatar": "http://example.net/avatar"}
],
"author": {"name": "John Smith", "url": "http://example.biz/", "avatar": "http://example.biz/avatar"}
}
output:
format: json
version: '1'
people:
- role: author
name: John Doe
url: 'http://example.org/'
avatar: http://example.org/avatar
- role: author
name: Jane Doe
url: 'http://example.net/'
avatar: http://example.net/avatar
Empty author:
input: >
{
"version": "https://jsonfeed.org/version/1",
"author": {}
}
output:
format: json
version: '1'
Empty authors:
input: >
{
"version": "https://jsonfeed.org/version/1",
"authors": [{}]
}
output:
format: json
version: '1'
Empty authors with fallback:
input: >
{
"version": "https://jsonfeed.org/version/1",
"authors": [{}],
"author": {"name": "John Doe", "url": "http://example.org/", "avatar": "http://example.org/avatar"}
}
output:
format: json
version: '1'
people:
- role: author
name: John Doe
url: 'http://example.org/'
avatar: http://example.org/avatar
Expired feed:
input: >
{
"version": "https://jsonfeed.org/version/1",
"expired": true
}
output:
format: json
version: '1'
sched:
expired: true
Not expired feed:
input: >
{
"version": "https://jsonfeed.org/version/1",
"expired": false
}
output:
format: json
version: '1'
sched:
expired: false
Improperly expired feed: # the 'expired' JSON Feed key is explicitly a boolean
input: >
{
"version": "https://jsonfeed.org/version/1",
"expired": 1
}
output:
format: json
version: '1'
Multiple elements:
input: >
{
"version": "https://jsonfeed.org/version/1",
"language": "en",
"title": "Example title",
"feed_url": "http://example.com/",
"home_page_url": "http://example.net/",
"description": "Example description",
"user_comment": "Example comment",
"next_url": "http://example.com/next",
"icon": "http://example.com/image",
"favicon": "http://example.com/icon"
}
output:
format: json
version: '1'
lang: en
title: Example title
id: 'http://example.com/'
url: 'http://example.com/'
link: 'http://example.net/'
summary: Example description
icon: 'http://example.com/icon'
image: 'http://example.com/image'
Relative URL resolution:
doc_url: 'http://example.com'
input: >
{
"version": "https://jsonfeed.org/version/1",
"feed_url": "feed.json"
}
output:
meta:
url: 'http://example.com'
format: json
version: '1'
id: 'feed.json'
url: ['feed.json', 'http://example.com']

3
vendor-bin/phpunit/composer.json

@ -1,5 +1,6 @@
{
"require-dev": {
"phpunit/phpunit": "^9.0"
"phpunit/phpunit": "^9.0",
"symfony/yaml": "^5.0"
}
}

61
vendor-bin/phpunit/composer.lock

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "b7670d90fa803400168312d1b096854c",
"content-hash": "5f6ef85b0137813e2008ed286079c104",
"packages": [],
"packages-dev": [
{
@ -1501,6 +1501,65 @@
],
"time": "2020-01-13T11:15:53+00:00"
},
{
"name": "symfony/yaml",
"version": "v5.0.5",
"source": {
"type": "git",
"url": "https://github.com/symfony/yaml.git",
"reference": "a4b613d7e44f62941adff5a802cff70adee57d3f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/yaml/zipball/a4b613d7e44f62941adff5a802cff70adee57d3f",
"reference": "a4b613d7e44f62941adff5a802cff70adee57d3f",
"shasum": ""
},
"require": {
"php": "^7.2.5",
"symfony/polyfill-ctype": "~1.8"
},
"conflict": {
"symfony/console": "<4.4"
},
"require-dev": {
"symfony/console": "^4.4|^5.0"
},
"suggest": {
"symfony/console": "For validating YAML files using the lint command"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "5.0-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Component\\Yaml\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony Yaml Component",
"homepage": "https://symfony.com",
"time": "2020-02-03T13:51:17+00:00"
},
{
"name": "theseer/tokenizer",
"version": "1.1.3",

Loading…
Cancel
Save