You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
162 lines
7.7 KiB
162 lines
7.7 KiB
<?php
|
|
/** @license MIT
|
|
* Copyright 2023 J. King
|
|
* See LICENSE and AUTHORS files for details */
|
|
|
|
declare(strict_types=1);
|
|
namespace MensBeam\Microformats\TestCase;
|
|
|
|
use MensBeam\Microformats;
|
|
|
|
/**
|
|
* @covers MensBeam\Microformats
|
|
* @covers MensBeam\Microformats\Parser
|
|
*/
|
|
class StandardTest extends \PHPUnit\Framework\TestCase {
|
|
protected const SUPPRESSED = [
|
|
'microformats-v1/hcard/multiple' => "whether vcard keys are p- or u- is unclear",
|
|
'microformats-v1/includes/hcarditemref' => "include pattern not implemented",
|
|
'microformats-v1/includes/heventitemref' => "include pattern not implemented",
|
|
'microformats-v1/includes/hyperlink' => "include pattern not implemented",
|
|
'microformats-v1/includes/object' => "include pattern not implemented",
|
|
'microformats-v1/includes/table' => "include pattern not implemented",
|
|
'microformats-v2/rel/duplicate-rels' => "this test has a spurious newline at the beginning of a value",
|
|
'microformats-v2-unit/names/names-microformats' => "This is probably a bug in the HTML parser",
|
|
'microformats-v2-unit/nested/nested-microformat-mistyped' => "The spec may change here soon",
|
|
];
|
|
|
|
/** @dataProvider provideStandardTests */
|
|
public function testStandardTests(string $name, string $path, array $options): void {
|
|
if (isset(self::SUPPRESSED[$name])) {
|
|
$this->markTestIncomplete(self::SUPPRESSED[$name]);
|
|
}
|
|
// parse input
|
|
$base = strpos($name, "microformats-v2-unit/") === 0 ? "http://example.test/" : "http://example.com/";
|
|
$act = Microformats::fromFile($path.".html", "text/html; charset=UTF-8", $base, $options);
|
|
// read expectation data
|
|
$exp = json_decode(file_get_contents($path.".json"), true);
|
|
if ($exp) {
|
|
$pattern = '#(\bhttps?://[^/ "\']+)($|[ "\'])#';
|
|
$replace = "$1/$2";
|
|
// fix up expectation where necessary
|
|
array_walk_recursive($exp, function(&$v) use ($pattern, $replace) {
|
|
// URLs differ trivially from output of our normalization library
|
|
$v = preg_replace($pattern, $replace, $v);
|
|
});
|
|
// URLs also need fixing as keys in rel-urls
|
|
foreach ($exp['rel-urls'] as $k => $v) {
|
|
$fixed = preg_replace($pattern, $replace, $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);
|
|
exit;
|
|
}
|
|
// sort both arrays
|
|
$this->ksort($exp);
|
|
$this->ksort($act);
|
|
// run comparison
|
|
foreach ($exp['items'] as $k => $mf) {
|
|
$x = json_encode($mf, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES);
|
|
$a = json_encode($act['items'][$k] ?? new \stdClass, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES);
|
|
$types = implode(", ", $mf['type']);
|
|
$this->assertSame($x, $a, "Microformat $types does not match");
|
|
}
|
|
$this->assertEquals($exp, $act);
|
|
}
|
|
|
|
public function provideStandardTests(): \Generator {
|
|
// the standard tests
|
|
yield from $this->provideTestList(\MensBeam\Microformats\BASE."vendor-bin/phpunit/vendor/mf2/tests/tests/", ['thoroughTrim' => false, 'dateNormalization' => false]);
|
|
// tests from php-mf2
|
|
yield from $this->provideTestList(\MensBeam\Microformats\BASE."tests/cases/third-party/", ['dateNormalization' => false, 'lang' => false]);
|
|
// 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]);
|
|
yield from $this->provideTestList(\MensBeam\Microformats\BASE."tests/cases/mensbeam/thoroughtrim-false/", ['thoroughTrim' => false]);
|
|
// new unit tests, still being written
|
|
yield from $this->provideTestList(\MensBeam\Microformats\BASE."tests/cases/microformats-v2-unit/");
|
|
}
|
|
|
|
protected function provideTestList(string $set, array $options = []): \Generator {
|
|
if (!is_dir($set)) {
|
|
return;
|
|
}
|
|
$base = strtr(\MensBeam\Microformats\BASE."tests/cases/", "\\", "/");
|
|
if (strpos(strtr($set, "\\", "/"), $base,) !== 0) {
|
|
$base = strtr($set, "\\", "/");
|
|
}
|
|
foreach (new \RegexIterator(new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($set)), '/\.json$/') as $file) {
|
|
$path = $file->getPathname();
|
|
$path = preg_replace('/\.json$/', '', $path);
|
|
$name = strtr($path, "\\", "/");
|
|
$name = str_replace($base, "", $name);
|
|
// perform some special handling for the standard unit test suite
|
|
if (!$options && preg_match('/^microformats-v2-unit\//', $name)) {
|
|
if (preg_match('/^microformats-v2-unit\/(?=text\/)/', $name)) {
|
|
// if we're doing standard textContent tests, do a single test with the correct option
|
|
yield $name => [$name, $path, ['thoroughTrim' => false]];
|
|
} else {
|
|
// otherwise run the test with both text trimming algorithms so that we ensure the tests pass with both
|
|
$opt = [
|
|
'thoroughTrim' => true,
|
|
'dateNormalization' => true,
|
|
];
|
|
yield "$name options:default" => [$name, $path, $opt];
|
|
$opt = [
|
|
'thoroughTrim' => false,
|
|
'dateNormalization' => false,
|
|
];
|
|
yield "$name options:standard" => [$name, $path, $opt];
|
|
}
|
|
} else {
|
|
yield $name => [$name, $path, $options];
|
|
}
|
|
}
|
|
}
|
|
|
|
protected function ksort(&$arr) {
|
|
foreach ($arr as &$v) {
|
|
if (is_array($v)) {
|
|
$this->ksort($v);
|
|
}
|
|
}
|
|
ksort($arr);
|
|
}
|
|
|
|
protected function fixTests(array $exp, string $test) {
|
|
switch ($test) {
|
|
case "microformats-v2/h-event/time":
|
|
case "microformats-v1/hcalendar/time":
|
|
$this->fixDates($exp['items'][0]['properties']['start']);
|
|
break;
|
|
case "microformats-v2/h-event/concatenate":
|
|
case "third-party/phpmf2/classic/vevent-summary":
|
|
$this->fixDates($exp['items'][0]['properties']['start']);
|
|
$this->fixDates($exp['items'][0]['properties']['end']);
|
|
break;
|
|
case "third-party/phpmf2/vcp":
|
|
$this->fixDates($exp['items'][5]['properties']['published']);
|
|
$exp['items'][7]['properties']['published'][0] = "2013-02-01 06:01";
|
|
break;
|
|
case "third-party/phpmf2/classic/fberriman":
|
|
$exp['items'][0]['properties']['published'][0] = "2013-05-14T11:54:06+00:00";
|
|
break;
|
|
}
|
|
return $exp;
|
|
}
|
|
|
|
protected function fixDates(&$dateArray): void {
|
|
foreach ($dateArray as &$d) {
|
|
$d = strtr($d, "Tt", " ");
|
|
$d = preg_replace('/([+-]\d\d)(\d\d)$/', "$1:$2", $d);
|
|
$d = preg_replace('/:\d\d[+-]\d\d$/', "$0:00", $d);
|
|
}
|
|
}
|
|
}
|