1
0
mirror of https://github.com/erusev/parsedown.git synced 2023-08-10 21:13:06 +03:00

Merge pull request #423 from PhrozenByte/bugfix/CommonMarkTest

Fix CommonMark test
This commit is contained in:
Aidan Woods 2018-02-28 17:05:24 +00:00 committed by GitHub
commit 48a053fe29
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 152 additions and 86 deletions

View File

@ -20,8 +20,9 @@ matrix:
- php: nightly - php: nightly
- php: hhvm-nightly - php: hhvm-nightly
before_script: install:
- composer install --prefer-dist --no-interaction --no-progress - composer install --prefer-dist --no-interaction --no-progress
script: script:
- vendor/bin/phpunit - vendor/bin/phpunit
- vendor/bin/phpunit test/CommonMarkTestWeak.php || true

View File

@ -20,5 +20,13 @@
}, },
"autoload": { "autoload": {
"psr-0": {"Parsedown": ""} "psr-0": {"Parsedown": ""}
},
"autoload-dev": {
"psr-0": {
"TestParsedown": "test/",
"ParsedownTest": "test/",
"CommonMarkTest": "test/",
"CommonMarkTestWeak": "test/"
}
} }
} }

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="test/bootstrap.php" colors="true"> <phpunit bootstrap="vendor/autoload.php" colors="true">
<testsuites> <testsuites>
<testsuite> <testsuite>
<file>test/ParsedownTest.php</file> <file>test/ParsedownTest.php</file>

View File

@ -1,77 +0,0 @@
<?php
/**
* Test Parsedown against the CommonMark spec.
*
* Some code based on the original JavaScript test runner by jgm.
*
* @link http://commonmark.org/ CommonMark
* @link http://git.io/8WtRvQ JavaScript test runner
*/
use PHPUnit\Framework\TestCase;
class CommonMarkTest extends TestCase
{
const SPEC_URL = 'https://raw.githubusercontent.com/jgm/stmd/master/spec.txt';
/**
* @dataProvider data
* @param $section
* @param $markdown
* @param $expectedHtml
*/
function test_($section, $markdown, $expectedHtml)
{
$Parsedown = new Parsedown();
$Parsedown->setUrlsLinked(false);
$actualHtml = $Parsedown->text($markdown);
$actualHtml = $this->normalizeMarkup($actualHtml);
$this->assertEquals($expectedHtml, $actualHtml);
}
function data()
{
$spec = file_get_contents(self::SPEC_URL);
$spec = strstr($spec, '<!-- END TESTS -->', true);
$tests = array();
$currentSection = '';
preg_replace_callback(
'/^\.\n([\s\S]*?)^\.\n([\s\S]*?)^\.$|^#{1,6} *(.*)$/m',
function($matches) use ( & $tests, & $currentSection, & $testCount) {
if (isset($matches[3]) and $matches[3]) {
$currentSection = $matches[3];
} else {
$testCount++;
$markdown = $matches[1];
$markdown = preg_replace('/→/', "\t", $markdown);
$expectedHtml = $matches[2];
$expectedHtml = $this->normalizeMarkup($expectedHtml);
$tests []= array(
$currentSection, # section
$markdown, # markdown
$expectedHtml, # html
);
}
},
$spec
);
return $tests;
}
private function normalizeMarkup($markup)
{
$markup = preg_replace("/\n+/", "\n", $markup);
$markup = preg_replace('/^\s+/m', '', $markup);
$markup = preg_replace('/^((?:<[\w]+>)+)\n/m', '$1', $markup);
$markup = preg_replace('/\n((?:<\/[\w]+>)+)$/m', '$1', $markup);
$markup = trim($markup);
return $markup;
}
}

View File

@ -0,0 +1,71 @@
<?php
/**
* Test Parsedown against the CommonMark spec
*
* @link http://commonmark.org/ CommonMark
*/
class CommonMarkTestStrict extends PHPUnit_Framework_TestCase
{
const SPEC_URL = 'https://raw.githubusercontent.com/jgm/CommonMark/master/spec.txt';
protected $parsedown;
protected function setUp()
{
$this->parsedown = new TestParsedown();
$this->parsedown->setUrlsLinked(false);
}
/**
* @dataProvider data
* @param $id
* @param $section
* @param $markdown
* @param $expectedHtml
*/
public function testExample($id, $section, $markdown, $expectedHtml)
{
$actualHtml = $this->parsedown->text($markdown);
$this->assertEquals($expectedHtml, $actualHtml);
}
/**
* @return array
*/
public function data()
{
$spec = file_get_contents(self::SPEC_URL);
if ($spec === false) {
$this->fail('Unable to load CommonMark spec from ' . self::SPEC_URL);
}
$spec = str_replace("\r\n", "\n", $spec);
$spec = strstr($spec, '<!-- END TESTS -->', true);
$matches = array();
preg_match_all('/^`{32} example\n((?s).*?)\n\.\n(?:|((?s).*?)\n)`{32}$|^#{1,6} *(.*?)$/m', $spec, $matches, PREG_SET_ORDER);
$data = array();
$currentId = 0;
$currentSection = '';
foreach ($matches as $match) {
if (isset($match[3])) {
$currentSection = $match[3];
} else {
$currentId++;
$markdown = str_replace('→', "\t", $match[1]);
$expectedHtml = isset($match[2]) ? str_replace('→', "\t", $match[2]) : '';
$data[$currentId] = array(
'id' => $currentId,
'section' => $currentSection,
'markdown' => $markdown,
'expectedHtml' => $expectedHtml
);
}
}
return $data;
}
}

View File

@ -0,0 +1,63 @@
<?php
require_once(__DIR__ . '/CommonMarkTestStrict.php');
/**
* Test Parsedown against the CommonMark spec, but less aggressive
*
* The resulting HTML markup is cleaned up before comparison, so examples
* which would normally fail due to actually invisible differences (e.g.
* superfluous whitespaces), don't fail. However, cleanup relies on block
* element detection. The detection doesn't work correctly when a element's
* `display` CSS property is manipulated. According to that this test is only
* a interim solution on Parsedown's way to full CommonMark compatibility.
*
* @link http://commonmark.org/ CommonMark
*/
class CommonMarkTestWeak extends CommonMarkTestStrict
{
protected $textLevelElementRegex;
protected function setUp()
{
parent::setUp();
$textLevelElements = $this->parsedown->getTextLevelElements();
array_walk($textLevelElements, function (&$element) {
$element = preg_quote($element, '/');
});
$this->textLevelElementRegex = '\b(?:' . implode('|', $textLevelElements) . ')\b';
}
/**
* @dataProvider data
* @param $id
* @param $section
* @param $markdown
* @param $expectedHtml
*/
public function testExample($id, $section, $markdown, $expectedHtml)
{
$expectedHtml = $this->cleanupHtml($expectedHtml);
$actualHtml = $this->parsedown->text($markdown);
$actualHtml = $this->cleanupHtml($actualHtml);
$this->assertEquals($expectedHtml, $actualHtml);
}
protected function cleanupHtml($markup)
{
// invisible whitespaces at the beginning and end of block elements
// however, whitespaces at the beginning of <pre> elements do matter
$markup = preg_replace(
array(
'/(<(?!(?:' . $this->textLevelElementRegex . '|\bpre\b))\w+\b[^>]*>(?:<' . $this->textLevelElementRegex . '[^>]*>)*)\s+/s',
'/\s+((?:<\/' . $this->textLevelElementRegex . '>)*<\/(?!' . $this->textLevelElementRegex . ')\w+\b>)/s'
),
'$1',
$markup
);
return $markup;
}
}

View File

@ -29,7 +29,7 @@ class ParsedownTest extends TestCase
*/ */
protected function initParsedown() protected function initParsedown()
{ {
$Parsedown = new Parsedown(); $Parsedown = new TestParsedown();
return $Parsedown; return $Parsedown;
} }
@ -136,15 +136,14 @@ color: red;
<p>comment</p> <p>comment</p>
<p>&lt;!-- html comment --&gt;</p> <p>&lt;!-- html comment --&gt;</p>
EXPECTED_HTML; EXPECTED_HTML;
$parsedownWithNoMarkup = new Parsedown();
$parsedownWithNoMarkup = new TestParsedown();
$parsedownWithNoMarkup->setMarkupEscaped(true); $parsedownWithNoMarkup->setMarkupEscaped(true);
$this->assertEquals($expectedHtml, $parsedownWithNoMarkup->text($markdownWithHtml)); $this->assertEquals($expectedHtml, $parsedownWithNoMarkup->text($markdownWithHtml));
} }
public function testLateStaticBinding() public function testLateStaticBinding()
{ {
include __DIR__ . '/TestParsedown.php';
$parsedown = Parsedown::instance(); $parsedown = Parsedown::instance();
$this->assertInstanceOf('Parsedown', $parsedown); $this->assertInstanceOf('Parsedown', $parsedown);

View File

@ -2,4 +2,8 @@
class TestParsedown extends Parsedown class TestParsedown extends Parsedown
{ {
public function getTextLevelElements()
{
return $this->textLevelElements;
}
} }

View File

@ -1,3 +0,0 @@
<?php
include 'Parsedown.php';