Browse Source

Add some original tests

master
J. King 11 months ago
parent
commit
8d4a61adaa
  1. 19
      lib/Microformats/Parser.php
  2. 41
      tests/cases/StandardTest.php
  3. 9
      tests/cases/mensbeam/default-settings/entry-date.html
  4. 16
      tests/cases/mensbeam/default-settings/entry-date.json
  5. 31
      tests/cases/mensbeam/default-settings/implied-prop.html
  6. 6
      tests/cases/mensbeam/default-settings/name-conflict.html
  7. 28
      tests/cases/mensbeam/default-settings/name-conflict.json
  8. 15
      tests/cases/mensbeam/lang-true/lang.html
  9. 50
      tests/cases/mensbeam/lang-true/lang.json

19
lib/Microformats/Parser.php

@ -355,10 +355,9 @@ class Parser {
* @param \DOMElement $node The element to start searching from, including itself
*/
protected function getRootCandidates(\DOMElement $node): void {
$query = [];
$query[] = './/*[contains(concat(" ", normalize-space(@class)), " h-")]';
$query = [".", ".//*[contains(concat(' ', normalize-space(@class)), ' h-')]"];
foreach (array_keys(static::BACKCOMPAT_ROOTS) as $root) {
$query[] = './/*[contains(concat(" ", normalize-space(@class), " "), " '.$root.' ")]';
$query[] = ".//*[contains(concat(' ', normalize-space(@class), ' '), ' $root ')]";
}
$query = implode("|", $query);
$this->roots = iterator_to_array($this->xpath->query($query, $node));
@ -711,7 +710,7 @@ class Parser {
# else if .h-x>abbr:only-child[title]:not([title=""]):not[.h-*] then use that abbr title for name
$name = $set->item(0)->getAttribute("title");
} elseif (
($set = $this->xpath->query("./*[not(template) and count(../*) = 1]", $root))->length
($set = $this->xpath->query("./*[local-name() != 'template' and count(../*) = 1]", $root))->length
&& !$this->hasRoots($set->item(0))
&& ($set = $this->xpath->query("./img[@alt and @alt != '' and count(../*) = 1]", $set->item(0)))->length
&& !$this->hasRoots($set->item(0))
@ -719,7 +718,7 @@ class Parser {
# else if .h-x>:only-child:not[.h-*]>img:only-child[alt]:not([alt=""]):not[.h-*] then use that img’s alt for name
$name = $set->item(0)->getAttribute("alt");
} elseif (
($set = $this->xpath->query("./*[not(template) and count(../*) = 1]", $root))->length
($set = $this->xpath->query("./*[local-name() != 'template' and count(../*) = 1]", $root))->length
&& !$this->hasRoots($set->item(0))
&& ($set = $this->xpath->query("./area[@alt and @alt != '' and count(../*) = 1]", $set->item(0)))->length
&& !$this->hasRoots($set->item(0))
@ -727,7 +726,7 @@ class Parser {
# else if .h-x>:only-child:not[.h-*]>area:only-child[alt]:not([alt=""]):not[.h-*] then use that area’s alt for name
$name = $set->item(0)->getAttribute("alt");
} elseif (
($set = $this->xpath->query("./*[not(template) and count(../*) = 1]", $root))->length
($set = $this->xpath->query("./*[local-name() != 'template' and count(../*) = 1]", $root))->length
&& !$this->hasRoots($set->item(0))
&& ($set = $this->xpath->query("./abbr[@title and @title != '' and count(../*) = 1]", $set->item(0)))->length
&& !$this->hasRoots($set->item(0))
@ -758,7 +757,7 @@ class Parser {
# else if .h-x>object[data]:only-of-type:not[.h-*] then use that object’s data for photo
$photo = $set->item(0)->getAttribute("data");
} elseif (
($set = $this->xpath->query("./*[not(template) and count(../*) = 1]", $root))->length
($set = $this->xpath->query("./*[local-name() != 'template' and count(../*) = 1]", $root))->length
&& !$this->hasRoots($set->item(0))
&& ($set = $this->xpath->query("./img[@src and count(../img) = 1]", $set->item(0)))->length
&& !$this->hasRoots($set->item(0))
@ -766,7 +765,7 @@ class Parser {
# else if .h-x>:only-child:not[.h-*]>img[src]:only-of-type:not[.h-*], then use the result of "parse an img element for src and alt" (see Sec.1.5) for photo
$out['properties']['photo'] = [$this->parseImg($set->item(0))];
} elseif (
($set = $this->xpath->query("./*[not(template) and count(../*) = 1]", $root))->length
($set = $this->xpath->query("./*[local-name() != 'template' and count(../*) = 1]", $root))->length
&& !$this->hasRoots($set->item(0))
&& ($set = $this->xpath->query("./object[@data and count(../object) = 1]", $set->item(0)))->length
&& !$this->hasRoots($set->item(0))
@ -797,7 +796,7 @@ class Parser {
# else if .h-x>area[href]:only-of-type:not[.h-*], then use that [href] for url
$url = $set->item(0)->getAttribute("href");
} elseif (
($set = $this->xpath->query("./*[not(template) and count(../*) = 1]", $root))->length
($set = $this->xpath->query("./*[local-name() != 'template' and count(../*) = 1]", $root))->length
&& !$this->hasRoots($set->item(0))
&& ($set = $this->xpath->query("./a[@href and count(../a) = 1]", $set->item(0)))->length
&& !$this->hasRoots($set->item(0))
@ -805,7 +804,7 @@ class Parser {
# else if .h-x>:only-child:not[.h-*]>a[href]:only-of-type:not[.h-*], then use that [href] for url
$url = $set->item(0)->getAttribute("href");
} elseif (
($set = $this->xpath->query("./*[not(template) and count(../*) = 1]", $root))->length
($set = $this->xpath->query("./*[local-name() != 'template' and count(../*) = 1]", $root))->length
&& !$this->hasRoots($set->item(0))
&& ($set = $this->xpath->query("./area[@href and count(../area) = 1]", $set->item(0)))->length
&& !$this->hasRoots($set->item(0))

41
tests/cases/StandardTest.php

@ -29,32 +29,36 @@ class StandardTest extends \PHPUnit\Framework\TestCase {
if (isset(self::SUPPRESSED[$name])) {
$this->markTestIncomplete(self::SUPPRESSED[$name]);
}
// parse input
$act = Microformats::fromFile($path.".html", "text/html; charset=UTF-8", "http://example.com/", $options);
// read expectation data
$exp = json_decode(file_get_contents($path.".json"), true);
// fix up expectation where necessary
array_walk_recursive($exp, function(&$v) {
// URLs differ trivially from output of our normalization library
$v = preg_replace('#^https?://[^/]+$#', "$0/", $v);
});
// URLs also need fixing as keys in rel-urls
foreach ($exp['rel-urls'] as $k => $v) {
$fixed = preg_replace('#^https?://[^/]+$#', "$0/", $k);
$exp['rel-urls'][$fixed] = $v;
if ($fixed !== $k) {
unset($exp['rel-urls'][$k]);
if ($exp) {
// fix up expectation where necessary
array_walk_recursive($exp, function(&$v) {
// URLs differ trivially from output of our normalization library
$v = preg_replace('#^https?://[^/]+$#', "$0/", $v);
});
// URLs also need fixing as keys in rel-urls
foreach ($exp['rel-urls'] as $k => $v) {
$fixed = preg_replace('#^https?://[^/]+$#', "$0/", $k);
$exp['rel-urls'][$fixed] = $v;
if ($fixed !== $k) {
unset($exp['rel-urls'][$k]);
}
}
// perform some further monkey-patching on specific tests
$exp = $this->fixTests($exp, $name);
} else {
// if there are no expectations we're probably developing a new test; print the output as JSON
echo Microformats::toJson($act, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES | \JSON_UNESCAPED_UNICODE);
exit;
}
// perform some further monkey-patching on specific tests
$exp = $this->fixTests($exp, $name);
// parse input
$act = Microformats::fromFile($path.".html", "text/html; charset=UTF-8", "http://example.com/", $options);
// sort both arrays
$this->ksort($exp);
$this->ksort($act);
// run comparison
if (!$exp) {
echo json_encode($act, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES | \JSON_UNESCAPED_UNICODE);
exit;
}
$this->assertSame($exp, $act);
}
@ -64,6 +68,9 @@ class StandardTest extends \PHPUnit\Framework\TestCase {
yield from $this->provideTestList([\MensBeam\Microformats\BASE."vendor-bin/phpunit/vendor/mf2/tests/tests/"], ['simpleTrim' => true]);
// tests from php-mf2
yield from $this->provideTestList([\MensBeam\Microformats\BASE."tests/cases/third-party/"], []);
// tests from our own corpus
yield from $this->provideTestList([\MensBeam\Microformats\BASE."tests/cases/mensbeam/default-settings/"], []);
yield from $this->provideTestList([\MensBeam\Microformats\BASE."tests/cases/mensbeam/lang-true/"], ['lang' => true]);
}
protected function provideTestList(array $tests, ?array $options = null): \Generator {

9
tests/cases/mensbeam/default-settings/entry-date.html

@ -0,0 +1,9 @@
<!--
This tests the negative cases of "entry-date", when it is on the wrong
element date or the element does not have the correct attribute.
-->
<div class="hentry">
<span class="entry-date">2023-06-21</span>
<time class="entry-date">2023-06-22</time>
<time class="entry-date" datetime="2023-06-23">This one is correct</time>
</div>

16
tests/cases/mensbeam/default-settings/entry-date.json

@ -0,0 +1,16 @@
{
"items": [
{
"type": [
"h-entry"
],
"properties": {
"published": [
"2023-06-23"
]
}
}
],
"rels": {},
"rel-urls": {}
}

31
tests/cases/mensbeam/default-settings/implied-prop.html

@ -0,0 +1,31 @@
<!--
This only tests a few cases not covered by standard tests. In particular we
need to ensure that templates are not used as valid elements.
-->
<div class="h-test">
<template>
<img src="ook" alt="eek">
</template>
Template be gone!
</div>
<div class="h-test">
<template>
<area src="ook" alt="eek">
</template>
Template be gone!
</div>
<div class="h-test">
<template>
<img src="ook" alt="eek">
</template>
Template be gone!
</div>
<div class="h-test">
<template>
<abbr title="eek">ook</abbr>
</template>
Template be gone!
</div>

6
tests/cases/mensbeam/default-settings/name-conflict.html

@ -0,0 +1,6 @@
<div class="h-test">
<span class="p-no-conflict">2023-06-06T05:32:12-04:00</span>
<span class="p-dt-wins dt-dt-wins">2023-06-06T05:32:12-04:00</span>
<span class="p-u-wins dt-u-wins u-u-wins">2023-06-06T05:32:12-04:00</span>
<span class="p-e-wins dt-e-wins u-e-wins e-e-wins">2023-06-06T05:32:12-04:00</span>
</div>

28
tests/cases/mensbeam/default-settings/name-conflict.json

@ -0,0 +1,28 @@
{
"items": [
{
"type": [
"h-test"
],
"properties": {
"no-conflict": [
"2023-06-06T05:32:12-04:00"
],
"dt-wins": [
"2023-06-06 05:32:12-0400"
],
"u-wins": [
"http://example.com/2023-06-06T05:32:12-04:00"
],
"e-wins": [
{
"html": "2023-06-06T05:32:12-04:00",
"value": "2023-06-06T05:32:12-04:00"
}
]
}
}
],
"rels": {},
"rel-urls": {}
}

15
tests/cases/mensbeam/lang-true/lang.html

@ -0,0 +1,15 @@
<html class="h-test">
<div lang="ja">
<div class="h-test">
<div class="p-name">日本語</div>
<div class="e-ook" lang="en">English</div>
</div>
<div class="h-test" lang="iu">
<div lang="fr">
<div class="e-ook">français</div>
</div>
<div class="p-name">ᐃᓄᒃᑎᑐᑦ</div>
</div>
</div>

50
tests/cases/mensbeam/lang-true/lang.json

@ -0,0 +1,50 @@
{
"items": [
{
"type": [
"h-test"
],
"properties": {},
"children": [
{
"type": [
"h-test"
],
"properties": {
"name": [
"日本語"
],
"ook": [
{
"html": "English",
"value": "English",
"lang": "en"
}
]
},
"lang": "ja"
},
{
"type": [
"h-test"
],
"properties": {
"ook": [
{
"html": "français",
"value": "français",
"lang": "fr"
}
],
"name": [
"ᐃᓄᒃᑎᑐᑦ"
]
},
"lang": "iu"
}
]
}
],
"rels": {},
"rel-urls": {}
}
Loading…
Cancel
Save