|
|
|
@@ -4,379 +4,378 @@ namespace Tests\Readability;
|
|
|
|
|
|
|
|
|
|
use Monolog\Handler\TestHandler;
|
|
|
|
|
use Monolog\Logger;
|
|
|
|
|
use Psr\Log\LoggerInterface;
|
|
|
|
|
use Readability\JSLikeHTMLElement;
|
|
|
|
|
use Readability\Readability;
|
|
|
|
|
|
|
|
|
|
class ReadabilityTest extends \PHPUnit\Framework\TestCase
|
|
|
|
|
{
|
|
|
|
|
/** @var TestHandler */
|
|
|
|
|
public $logHandler;
|
|
|
|
|
/** @var LoggerInterface */
|
|
|
|
|
public $logger;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @requires extension tidy
|
|
|
|
|
*/
|
|
|
|
|
public function testConstructDefault()
|
|
|
|
|
public function testConstructDefault(): void
|
|
|
|
|
{
|
|
|
|
|
$readability = $this->getReadability('');
|
|
|
|
|
$this->assertSame('utf8', $readability->tidy_config['input-encoding']);
|
|
|
|
|
$readability->init();
|
|
|
|
|
|
|
|
|
|
$this->assertNull($readability->url);
|
|
|
|
|
$this->assertInstanceOf('DomDocument', $readability->dom);
|
|
|
|
|
$this->assertInstanceOf(\DOMDocument::class, $readability->dom);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testConstructHtml5Parser()
|
|
|
|
|
public function testConstructHtml5Parser(): void
|
|
|
|
|
{
|
|
|
|
|
$readability = $this->getReadability('<html/>', 'http://0.0.0.0', 'html5lib');
|
|
|
|
|
$readability->init();
|
|
|
|
|
|
|
|
|
|
$this->assertEquals('http://0.0.0.0', $readability->url);
|
|
|
|
|
$this->assertInstanceOf('DomDocument', $readability->dom);
|
|
|
|
|
$this->assertEquals('<html/>', $readability->original_html);
|
|
|
|
|
$this->assertSame('http://0.0.0.0', $readability->url);
|
|
|
|
|
$this->assertInstanceOf(\DOMDocument::class, $readability->dom);
|
|
|
|
|
$this->assertSame('<html/>', $readability->original_html);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @requires extension tidy
|
|
|
|
|
*/
|
|
|
|
|
public function testConstructSimple()
|
|
|
|
|
public function testConstructSimple(): void
|
|
|
|
|
{
|
|
|
|
|
$readability = $this->getReadability('<html/>', 'http://0.0.0.0');
|
|
|
|
|
$readability->init();
|
|
|
|
|
|
|
|
|
|
$this->assertEquals('http://0.0.0.0', $readability->url);
|
|
|
|
|
$this->assertInstanceOf('DomDocument', $readability->dom);
|
|
|
|
|
$this->assertEquals('<html/>', $readability->original_html);
|
|
|
|
|
$this->assertSame('http://0.0.0.0', $readability->url);
|
|
|
|
|
$this->assertInstanceOf(\DOMDocument::class, $readability->dom);
|
|
|
|
|
$this->assertSame('<html/>', $readability->original_html);
|
|
|
|
|
$this->assertTrue($readability->tidied);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testConstructDefaultWithoutTidy()
|
|
|
|
|
public function testConstructDefaultWithoutTidy(): void
|
|
|
|
|
{
|
|
|
|
|
$readability = $this->getReadability('', null, 'libxml', false);
|
|
|
|
|
$readability->init();
|
|
|
|
|
|
|
|
|
|
$this->assertNull($readability->url);
|
|
|
|
|
$this->assertEquals('', $readability->original_html);
|
|
|
|
|
$this->assertSame('', $readability->original_html);
|
|
|
|
|
$this->assertFalse($readability->tidied);
|
|
|
|
|
|
|
|
|
|
$this->assertInstanceOf('DomDocument', $readability->dom);
|
|
|
|
|
$this->assertInstanceOf(\DOMDocument::class, $readability->dom);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testConstructSimpleWithoutTidy()
|
|
|
|
|
public function testConstructSimpleWithoutTidy(): void
|
|
|
|
|
{
|
|
|
|
|
$readability = $this->getReadability('<html/>', 'http://0.0.0.0', 'libxml', false);
|
|
|
|
|
$readability->init();
|
|
|
|
|
|
|
|
|
|
$this->assertEquals('http://0.0.0.0', $readability->url);
|
|
|
|
|
$this->assertInstanceOf('DomDocument', $readability->dom);
|
|
|
|
|
$this->assertEquals('<html/>', $readability->original_html);
|
|
|
|
|
$this->assertSame('http://0.0.0.0', $readability->url);
|
|
|
|
|
$this->assertInstanceOf(\DOMDocument::class, $readability->dom);
|
|
|
|
|
$this->assertSame('<html/>', $readability->original_html);
|
|
|
|
|
$this->assertFalse($readability->tidied);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testInitNoContent()
|
|
|
|
|
public function testInitNoContent(): void
|
|
|
|
|
{
|
|
|
|
|
$readability = $this->getReadability('<html/>', 'http://0.0.0.0');
|
|
|
|
|
$res = $readability->init();
|
|
|
|
|
|
|
|
|
|
$this->assertFalse($res);
|
|
|
|
|
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
|
|
|
|
|
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
|
|
|
|
|
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getContent());
|
|
|
|
|
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getTitle());
|
|
|
|
|
$this->assertEmpty($readability->getTitle()->getInnerHtml());
|
|
|
|
|
$this->assertContains('Sorry, Readability was unable to parse this page for content.', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertStringContainsString('Sorry, Readability was unable to parse this page for content.', $readability->getContent()->getInnerHtml());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testInitP()
|
|
|
|
|
public function testInitP(): void
|
|
|
|
|
{
|
|
|
|
|
$readability = $this->getReadability(str_repeat('<p>This is the awesome content :)</p>', 7), 'http://0.0.0.0');
|
|
|
|
|
$res = $readability->init();
|
|
|
|
|
|
|
|
|
|
$this->assertTrue($res);
|
|
|
|
|
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
|
|
|
|
|
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
|
|
|
|
|
$this->assertContains('<div readability=', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getContent());
|
|
|
|
|
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getTitle());
|
|
|
|
|
$this->assertStringContainsString('<div readability=', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertEmpty($readability->getTitle()->getInnerHtml());
|
|
|
|
|
$this->assertContains('This is the awesome content :)', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertStringContainsString('This is the awesome content :)', $readability->getContent()->getInnerHtml());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testInitDivP()
|
|
|
|
|
public function testInitDivP(): void
|
|
|
|
|
{
|
|
|
|
|
$readability = $this->getReadability('<div>' . str_repeat('<p>This is the awesome content :)</p>', 7) . '</div>', 'http://0.0.0.0');
|
|
|
|
|
$res = $readability->init();
|
|
|
|
|
|
|
|
|
|
$this->assertTrue($res);
|
|
|
|
|
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
|
|
|
|
|
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
|
|
|
|
|
$this->assertContains('<div readability=', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getContent());
|
|
|
|
|
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getTitle());
|
|
|
|
|
$this->assertStringContainsString('<div readability=', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertEmpty($readability->getTitle()->getInnerHtml());
|
|
|
|
|
$this->assertContains('This is the awesome content :)', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertStringContainsString('This is the awesome content :)', $readability->getContent()->getInnerHtml());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testInitDiv()
|
|
|
|
|
public function testInitDiv(): void
|
|
|
|
|
{
|
|
|
|
|
$readability = $this->getReadability('<div>' . str_repeat('This is the awesome content :)', 7) . '</div>', 'http://0.0.0.0');
|
|
|
|
|
$readability->debug = true;
|
|
|
|
|
$res = $readability->init();
|
|
|
|
|
|
|
|
|
|
$this->assertTrue($res);
|
|
|
|
|
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
|
|
|
|
|
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
|
|
|
|
|
$this->assertContains('<div readability=', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getContent());
|
|
|
|
|
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getTitle());
|
|
|
|
|
$this->assertStringContainsString('<div readability=', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertEmpty($readability->getTitle()->getInnerHtml());
|
|
|
|
|
$this->assertContains('This is the awesome content :)', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertStringContainsString('This is the awesome content :)', $readability->getContent()->getInnerHtml());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testWithFootnotes()
|
|
|
|
|
public function testWithFootnotes(): void
|
|
|
|
|
{
|
|
|
|
|
$readability = $this->getReadability('<div>' . str_repeat('<p>This is an awesome text with some links, here there are: <a href="http://0.0.0.0/test.html">the awesome</a></p>', 7) . '</div>', 'http://0.0.0.0');
|
|
|
|
|
$readability->debug = true;
|
|
|
|
|
$readability->convertLinksToFootnotes = true;
|
|
|
|
|
$res = $readability->init();
|
|
|
|
|
|
|
|
|
|
$this->assertTrue($res);
|
|
|
|
|
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
|
|
|
|
|
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
|
|
|
|
|
$this->assertContains('<div readability=', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getContent());
|
|
|
|
|
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getTitle());
|
|
|
|
|
$this->assertStringContainsString('<div readability=', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertEmpty($readability->getTitle()->getInnerHtml());
|
|
|
|
|
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertContains('readabilityFootnoteLink', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertContains('readabilityLink-3', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertStringContainsString('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertStringContainsString('readabilityFootnoteLink', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertStringContainsString('readabilityLink-3', $readability->getContent()->getInnerHtml());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testStandardClean()
|
|
|
|
|
public function testStandardClean(): void
|
|
|
|
|
{
|
|
|
|
|
$readability = $this->getReadability('<div><h2>Title</h2>' . str_repeat('<p>This is an awesome text with some links, here there are: <a href="http://0.0.0.0/test.html">the awesome</a></p>', 7) . '<a href="#nofollow" rel="nofollow">will NOT be removed</a></div>', 'http://0.0.0.0');
|
|
|
|
|
$readability->debug = true;
|
|
|
|
|
$readability->lightClean = false;
|
|
|
|
|
$res = $readability->init();
|
|
|
|
|
|
|
|
|
|
$this->assertTrue($res);
|
|
|
|
|
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
|
|
|
|
|
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
|
|
|
|
|
$this->assertContains('<div readability=', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getContent());
|
|
|
|
|
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getTitle());
|
|
|
|
|
$this->assertStringContainsString('<div readability=', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertEmpty($readability->getTitle()->getInnerHtml());
|
|
|
|
|
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertContains('will NOT be removed', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertNotContains('<h2>', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertStringContainsString('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertStringContainsString('will NOT be removed', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertStringNotContainsString('<h2>', $readability->getContent()->getInnerHtml());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testWithIframe()
|
|
|
|
|
public function testWithIframe(): void
|
|
|
|
|
{
|
|
|
|
|
$readability = $this->getReadability('<div><h2>Title</h2>' . str_repeat('<p>This is an awesome text with some links, here there are: <a href="http://0.0.0.0/test.html">the awesome</a></p>', 7) . '<p>This is an awesome text with some links, here there are <iframe src="http://youtube.com/test" href="#nofollow" rel="nofollow"></iframe><iframe>http://soundcloud.com/test</iframe></p></div>', 'http://0.0.0.0');
|
|
|
|
|
$readability->debug = true;
|
|
|
|
|
$res = $readability->init();
|
|
|
|
|
|
|
|
|
|
$this->assertTrue($res);
|
|
|
|
|
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
|
|
|
|
|
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
|
|
|
|
|
$this->assertContains('<div readability=', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getContent());
|
|
|
|
|
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getTitle());
|
|
|
|
|
$this->assertStringContainsString('<div readability=', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertEmpty($readability->getTitle()->getInnerHtml());
|
|
|
|
|
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertContains('nofollow', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertStringContainsString('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertStringContainsString('nofollow', $readability->getContent()->getInnerHtml());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testWithArticle()
|
|
|
|
|
public function testWithArticle(): void
|
|
|
|
|
{
|
|
|
|
|
$readability = $this->getReadability('<article><p>' . str_repeat('This is an awesome text with some links, here there are: the awesome', 20) . '</p><p>This is an awesome text with some links, here there are <iframe src="http://youtube.com/test" href="#nofollow" rel="nofollow"></iframe></p></article>', 'http://0.0.0.0');
|
|
|
|
|
$readability->debug = true;
|
|
|
|
|
$res = $readability->init();
|
|
|
|
|
|
|
|
|
|
$this->assertTrue($res);
|
|
|
|
|
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
|
|
|
|
|
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
|
|
|
|
|
$this->assertContains('alt="article"', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getContent());
|
|
|
|
|
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getTitle());
|
|
|
|
|
$this->assertStringContainsString('alt="article"', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertEmpty($readability->getTitle()->getInnerHtml());
|
|
|
|
|
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertContains('nofollow', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertStringContainsString('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertStringContainsString('nofollow', $readability->getContent()->getInnerHtml());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testWithAside()
|
|
|
|
|
public function testWithAside(): void
|
|
|
|
|
{
|
|
|
|
|
$readability = $this->getReadability('<article>' . str_repeat('<p>This is an awesome text with some links, here there are: <a href="http://0.0.0.0/test.html">the awesome</a></p>', 7) . '<footer><aside>' . str_repeat('<p>This is an awesome text with some links, here there are</p>', 8) . '</aside></footer></article>', 'http://0.0.0.0');
|
|
|
|
|
$readability->debug = true;
|
|
|
|
|
$res = $readability->init();
|
|
|
|
|
|
|
|
|
|
$this->assertTrue($res);
|
|
|
|
|
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
|
|
|
|
|
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
|
|
|
|
|
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getContent());
|
|
|
|
|
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getTitle());
|
|
|
|
|
$this->assertEmpty($readability->getTitle()->getInnerHtml());
|
|
|
|
|
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertNotContains('<aside>', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertContains('<footer readability="5"/>', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertStringContainsString('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertStringNotContainsString('<aside>', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertStringContainsString('<footer readability="9"/>', $readability->getContent()->getInnerHtml());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testWithClasses()
|
|
|
|
|
public function testWithClasses(): void
|
|
|
|
|
{
|
|
|
|
|
$readability = $this->getReadability('<article>' . str_repeat('<p>This is an awesome text with some links, here there are: <a href="http://0.0.0.0/test.html">the awesome</a></p>', 7) . '<div style="display:none">' . str_repeat('<p class="clock">This text should be removed</p>', 10) . '</div></article>', 'http://0.0.0.0');
|
|
|
|
|
$readability->debug = true;
|
|
|
|
|
$res = $readability->init();
|
|
|
|
|
|
|
|
|
|
$this->assertTrue($res);
|
|
|
|
|
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
|
|
|
|
|
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
|
|
|
|
|
$this->assertContains('alt="article"', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getContent());
|
|
|
|
|
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getTitle());
|
|
|
|
|
$this->assertStringContainsString('alt="article"', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertEmpty($readability->getTitle()->getInnerHtml());
|
|
|
|
|
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertNotContains('This text should be removed', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertStringContainsString('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertStringNotContainsString('This text should be removed', $readability->getContent()->getInnerHtml());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testWithClassesWithoutLightClean()
|
|
|
|
|
public function testWithClassesWithoutLightClean(): void
|
|
|
|
|
{
|
|
|
|
|
$readability = $this->getReadability('<article>' . str_repeat('<p>This is an awesome text with some links, here there are: <a href="http://0.0.0.0/test.html">the awesome</a></p>', 7) . '<div style="display:none">' . str_repeat('<p class="clock">This text should be removed</p>', 10) . '</div></article>', 'http://0.0.0.0');
|
|
|
|
|
$readability->debug = true;
|
|
|
|
|
$readability->lightClean = false;
|
|
|
|
|
$res = $readability->init();
|
|
|
|
|
|
|
|
|
|
$this->assertTrue($res);
|
|
|
|
|
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
|
|
|
|
|
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
|
|
|
|
|
$this->assertContains('alt="article"', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getContent());
|
|
|
|
|
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getTitle());
|
|
|
|
|
$this->assertStringContainsString('alt="article"', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertEmpty($readability->getTitle()->getInnerHtml());
|
|
|
|
|
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertNotContains('This text should be removed', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertStringContainsString('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertStringNotContainsString('This text should be removed', $readability->getContent()->getInnerHtml());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testWithTd()
|
|
|
|
|
public function testWithTd(): void
|
|
|
|
|
{
|
|
|
|
|
$readability = $this->getReadability('<table><tr>' . str_repeat('<td><p>This is an awesome text with some links, here there are the awesome</td>', 7) . '</tr></table>', 'http://0.0.0.0');
|
|
|
|
|
$readability->debug = true;
|
|
|
|
|
$res = $readability->init();
|
|
|
|
|
|
|
|
|
|
$this->assertTrue($res);
|
|
|
|
|
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
|
|
|
|
|
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
|
|
|
|
|
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getContent());
|
|
|
|
|
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getTitle());
|
|
|
|
|
$this->assertEmpty($readability->getTitle()->getInnerHtml());
|
|
|
|
|
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertStringContainsString('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testWithSameClasses()
|
|
|
|
|
public function testWithSameClasses(): void
|
|
|
|
|
{
|
|
|
|
|
$readability = $this->getReadability('<article class="awesomecontent">' . str_repeat('<p>This is an awesome text with some links, here there are the awesome</p>', 7) . '<div class="awesomecontent">This text is also an awesome text and you should know that !</div></article>', 'http://0.0.0.0');
|
|
|
|
|
$readability->debug = true;
|
|
|
|
|
$res = $readability->init();
|
|
|
|
|
|
|
|
|
|
$this->assertTrue($res);
|
|
|
|
|
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
|
|
|
|
|
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
|
|
|
|
|
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getContent());
|
|
|
|
|
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getTitle());
|
|
|
|
|
$this->assertEmpty($readability->getTitle()->getInnerHtml());
|
|
|
|
|
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertContains('This text is also an awesome text and you should know that', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertStringContainsString('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertStringContainsString('This text is also an awesome text and you should know that', $readability->getContent()->getInnerHtml());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testWithScript()
|
|
|
|
|
public function testWithScript(): void
|
|
|
|
|
{
|
|
|
|
|
$readability = $this->getReadability('<article class="awesomecontent">' . str_repeat('<p>This is an awesome text with some links, here there are the awesome</p>', 7) . '<p><script>This text is also an awesome text and you should know that !</script></p></article>', 'http://0.0.0.0');
|
|
|
|
|
$readability->debug = true;
|
|
|
|
|
$res = $readability->init();
|
|
|
|
|
|
|
|
|
|
$this->assertTrue($res);
|
|
|
|
|
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
|
|
|
|
|
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
|
|
|
|
|
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getContent());
|
|
|
|
|
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getTitle());
|
|
|
|
|
$this->assertEmpty($readability->getTitle()->getInnerHtml());
|
|
|
|
|
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertNotContains('This text is also an awesome text and you should know that', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertStringContainsString('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertStringNotContainsString('This text is also an awesome text and you should know that', $readability->getContent()->getInnerHtml());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testTitle()
|
|
|
|
|
public function testTitle(): void
|
|
|
|
|
{
|
|
|
|
|
$readability = $this->getReadability('<title>this is my title</title><article class="awesomecontent">' . str_repeat('<p>This is an awesome text with some links, here there are the awesome</p>', 7) . '<p></p></article>', 'http://0.0.0.0');
|
|
|
|
|
$readability->debug = true;
|
|
|
|
|
$res = $readability->init();
|
|
|
|
|
|
|
|
|
|
$this->assertTrue($res);
|
|
|
|
|
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
|
|
|
|
|
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
|
|
|
|
|
$this->assertEquals('this is my title', $readability->getTitle()->getInnerHtml());
|
|
|
|
|
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertNotContains('This text is also an awesome text and you should know that', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getContent());
|
|
|
|
|
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getTitle());
|
|
|
|
|
$this->assertSame('this is my title', $readability->getTitle()->getInnerHtml());
|
|
|
|
|
$this->assertStringContainsString('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertStringNotContainsString('This text is also an awesome text and you should know that', $readability->getContent()->getInnerHtml());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testTitleWithDash()
|
|
|
|
|
public function testTitleWithDash(): void
|
|
|
|
|
{
|
|
|
|
|
$readability = $this->getReadability('<title> title2 - title3 </title><article class="awesomecontent">' . str_repeat('<p>This is an awesome text with some links, here there are the awesome</p>', 7) . '<p></p></article>', 'http://0.0.0.0');
|
|
|
|
|
$readability->debug = true;
|
|
|
|
|
$res = $readability->init();
|
|
|
|
|
|
|
|
|
|
$this->assertTrue($res);
|
|
|
|
|
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
|
|
|
|
|
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
|
|
|
|
|
$this->assertEquals('title2 - title3', $readability->getTitle()->getInnerHtml());
|
|
|
|
|
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertNotContains('This text is also an awesome text and you should know that', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getContent());
|
|
|
|
|
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getTitle());
|
|
|
|
|
$this->assertSame('title2 - title3', $readability->getTitle()->getInnerHtml());
|
|
|
|
|
$this->assertStringContainsString('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertStringNotContainsString('This text is also an awesome text and you should know that', $readability->getContent()->getInnerHtml());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testTitleWithDoubleDot()
|
|
|
|
|
public function testTitleWithDoubleDot(): void
|
|
|
|
|
{
|
|
|
|
|
$readability = $this->getReadability('<title> title2 : title3 </title><article class="awesomecontent">' . str_repeat('<p>This is an awesome text with some links, here there are the awesome</p>', 7) . '<p></p></article>', 'http://0.0.0.0');
|
|
|
|
|
$readability->debug = true;
|
|
|
|
|
$res = $readability->init();
|
|
|
|
|
|
|
|
|
|
$this->assertTrue($res);
|
|
|
|
|
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
|
|
|
|
|
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
|
|
|
|
|
$this->assertEquals('title2 : title3', $readability->getTitle()->getInnerHtml());
|
|
|
|
|
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertNotContains('This text is also an awesome text and you should know that', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getContent());
|
|
|
|
|
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getTitle());
|
|
|
|
|
$this->assertSame('title2 : title3', $readability->getTitle()->getInnerHtml());
|
|
|
|
|
$this->assertStringContainsString('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertStringNotContainsString('This text is also an awesome text and you should know that', $readability->getContent()->getInnerHtml());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testTitleTooShortUseH1()
|
|
|
|
|
public function testTitleTooShortUseH1(): void
|
|
|
|
|
{
|
|
|
|
|
$readability = $this->getReadability('<title>too short</title><h1>this is my h1 title !</h1><article class="awesomecontent">' . str_repeat('<p>This is an awesome text with some links, here there are the awesome</p>', 7) . '<p></p></article>', 'http://0.0.0.0');
|
|
|
|
|
$readability->debug = true;
|
|
|
|
|
$res = $readability->init();
|
|
|
|
|
|
|
|
|
|
$this->assertTrue($res);
|
|
|
|
|
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
|
|
|
|
|
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
|
|
|
|
|
$this->assertEquals('this is my h1 title !', $readability->getTitle()->getInnerHtml());
|
|
|
|
|
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertNotContains('This text is also an awesome text and you should know that', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getContent());
|
|
|
|
|
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getTitle());
|
|
|
|
|
$this->assertSame('this is my h1 title !', $readability->getTitle()->getInnerHtml());
|
|
|
|
|
$this->assertStringContainsString('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertStringNotContainsString('This text is also an awesome text and you should know that', $readability->getContent()->getInnerHtml());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// dummy function to be used to the next test
|
|
|
|
|
public function error2Exception($code, $string, $file, $line, $context)
|
|
|
|
|
public function testAutoClosingIframeNotThrowingException(): void
|
|
|
|
|
{
|
|
|
|
|
throw new \Exception($string, $code);
|
|
|
|
|
}
|
|
|
|
|
$oldErrorReporting = error_reporting(\E_ALL);
|
|
|
|
|
$oldDisplayErrors = ini_set('display_errors', '1');
|
|
|
|
|
// dummy function to be used to the next test
|
|
|
|
|
set_error_handler(static function (int $errno, string $errstr, string $errfile, int $errline) {
|
|
|
|
|
throw new \Exception($errstr, $errno);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
public function testAutoClosingIframeNotThrowingException()
|
|
|
|
|
{
|
|
|
|
|
error_reporting(\E_ALL | \E_STRICT);
|
|
|
|
|
ini_set('display_errors', true);
|
|
|
|
|
set_error_handler([$this, 'error2Exception'], \E_ALL | \E_STRICT);
|
|
|
|
|
try {
|
|
|
|
|
$data = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
|
|
|
|
<html xmlns="http://www.w3.org/1999/xhtml" lang="ru-RU" prefix="og: http://ogp.me/ns#">
|
|
|
|
|
|
|
|
|
|
$data = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
|
|
|
|
<html xmlns="http://www.w3.org/1999/xhtml" lang="ru-RU" prefix="og: http://ogp.me/ns#">
|
|
|
|
|
<head profile="http://gmpg.org/xfn/11">
|
|
|
|
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
|
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
|
|
|
|
|
|
|
|
<head profile="http://gmpg.org/xfn/11">
|
|
|
|
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
|
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
|
|
|
|
|
|
|
|
</head>
|
|
|
|
|
<body class="single single-post postid-22030 single-format-standard">
|
|
|
|
|
<div id="wrapper">
|
|
|
|
|
<div id="content">
|
|
|
|
|
<div class="post-22030 post type-post status-publish format-standard has-post-thumbnail hentry category-video category-reviews tag-193" id="post-22030">
|
|
|
|
|
<h1>3D Touch — будущее мобильных игр</h1>
|
|
|
|
|
<div class="postdate">Автор: <strong>Сергей Пак</strong> | Просмотров: 1363 | Опубликовано: 14 сентября 2015 </div>
|
|
|
|
|
<div class="entry">
|
|
|
|
|
<p>Компания Apple представила новую технологию 3D Touch, которая является прямым потомком более ранней версии Force Touch — последняя, напомним, используется сейчас в трекпадах Macbook Pro и Macbook 2015. Теперь управлять устройством стало в разы проще, и Force Touch открывает перед пользователями новые возможности, но при этом 3D Touch — это про другое. Дело в том, что теперь и на мобильных устройствах интерфейс будет постепенно меняться, кардинальные перемены ждут мобильный гейминг, потому что здесь разработчики действительно могут разгуляться.<span id="more-22030"></span></p>
|
|
|
|
|
<p><iframe src="https://www.youtube.com/embed/PUep6xNeKjA" width="560" height="315" frameborder="0" allowfullscreen="allowfullscreen"></iframe></p>
|
|
|
|
|
<p>Итак, просто представьте себе, что iPhone 6S — это, по большому счету, отличная игровая приставка, которую вы носите с собой, а еще она может выдавать невероятной красоты картинку. Но проблема заключается, пожалуй, в том, что управлять персонажем в играх довольно трудно — он неповоротлив, обладает заторможенной реакцией, а игровой клиент зачастую требует перегруза интерфейса для того, чтобы обеспечить максимально большое количество возможностей. Благодаря трехуровневому нажатию можно избавиться от лишних кнопок и обеспечить более качественный обзор местности, и при этом пользователь будет закрывать пальцами минимальное пространство.</p>
|
|
|
|
|
</head>
|
|
|
|
|
<body class="single single-post postid-22030 single-format-standard">
|
|
|
|
|
<div id="wrapper">
|
|
|
|
|
<div id="content">
|
|
|
|
|
<div class="post-22030 post type-post status-publish format-standard has-post-thumbnail hentry category-video category-reviews tag-193" id="post-22030">
|
|
|
|
|
<h1>3D Touch — будущее мобильных игр</h1>
|
|
|
|
|
<div class="postdate">Автор: <strong>Сергей Пак</strong> | Просмотров: 1363 | Опубликовано: 14 сентября 2015 </div>
|
|
|
|
|
<div class="entry">
|
|
|
|
|
<p>Компания Apple представила новую технологию 3D Touch, которая является прямым потомком более ранней версии Force Touch — последняя, напомним, используется сейчас в трекпадах Macbook Pro и Macbook 2015. Теперь управлять устройством стало в разы проще, и Force Touch открывает перед пользователями новые возможности, но при этом 3D Touch — это про другое. Дело в том, что теперь и на мобильных устройствах интерфейс будет постепенно меняться, кардинальные перемены ждут мобильный гейминг, потому что здесь разработчики действительно могут разгуляться.<span id="more-22030"></span></p>
|
|
|
|
|
<p><iframe src="https://www.youtube.com/embed/PUep6xNeKjA" width="560" height="315" frameborder="0" allowfullscreen="allowfullscreen"></iframe></p>
|
|
|
|
|
<p>Итак, просто представьте себе, что iPhone 6S — это, по большому счету, отличная игровая приставка, которую вы носите с собой, а еще она может выдавать невероятной красоты картинку. Но проблема заключается, пожалуй, в том, что управлять персонажем в играх довольно трудно — он неповоротлив, обладает заторможенной реакцией, а игровой клиент зачастую требует перегруза интерфейса для того, чтобы обеспечить максимально большое количество возможностей. Благодаря трехуровневому нажатию можно избавиться от лишних кнопок и обеспечить более качественный обзор местности, и при этом пользователь будет закрывать пальцами минимальное пространство.</p>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</body>
|
|
|
|
|
</html>';
|
|
|
|
|
</body>
|
|
|
|
|
</html>';
|
|
|
|
|
|
|
|
|
|
$readability = $this->getReadability($data, 'http://iosgames.ru/?p=22030');
|
|
|
|
|
$readability->debug = true;
|
|
|
|
|
$readability = $this->getReadability($data, 'http://iosgames.ru/?p=22030');
|
|
|
|
|
|
|
|
|
|
$res = $readability->init();
|
|
|
|
|
$res = $readability->init();
|
|
|
|
|
|
|
|
|
|
$this->assertTrue($res);
|
|
|
|
|
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
|
|
|
|
|
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
|
|
|
|
|
$this->assertContains('<iframe src="https://www.youtube.com/embed/PUep6xNeKjA" width="560" height="315" frameborder="0" allowfullscreen="allowfullscreen"> </iframe>', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertContains('3D Touch', $readability->getTitle()->getInnerHtml());
|
|
|
|
|
$this->assertTrue($res);
|
|
|
|
|
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getContent());
|
|
|
|
|
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getTitle());
|
|
|
|
|
$this->assertStringContainsString('<iframe src="https://www.youtube.com/embed/PUep6xNeKjA" width="560" height="315" frameborder="0" allowfullscreen="allowfullscreen"> </iframe>', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertStringContainsString('3D Touch', $readability->getTitle()->getInnerHtml());
|
|
|
|
|
} finally {
|
|
|
|
|
restore_error_handler();
|
|
|
|
|
if (false !== $oldDisplayErrors) {
|
|
|
|
|
ini_set('display_errors', $oldDisplayErrors);
|
|
|
|
|
}
|
|
|
|
|
error_reporting($oldErrorReporting);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* This should generate an Exception "DOMElement::setAttribute(): ID post-60 already defined".
|
|
|
|
|
*/
|
|
|
|
|
public function testAppendIdAlreadyHere()
|
|
|
|
|
public function testAppendIdAlreadyHere(): void
|
|
|
|
|
{
|
|
|
|
|
$data = '<!DOCTYPE html>
|
|
|
|
|
<html lang="fr">
|
|
|
|
@@ -423,16 +422,15 @@ class ReadabilityTest extends \PHPUnit\Framework\TestCase
|
|
|
|
|
</html>';
|
|
|
|
|
|
|
|
|
|
$readability = $this->getReadability($data, 'http://0.0.0.0');
|
|
|
|
|
$readability->debug = true;
|
|
|
|
|
|
|
|
|
|
$res = $readability->init();
|
|
|
|
|
|
|
|
|
|
$this->assertTrue($res);
|
|
|
|
|
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
|
|
|
|
|
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
|
|
|
|
|
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getContent());
|
|
|
|
|
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getTitle());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testPostFilters()
|
|
|
|
|
public function testPostFilters(): void
|
|
|
|
|
{
|
|
|
|
|
$readability = $this->getReadability('<div>' . str_repeat('<p>This <strong>is</strong> the awesome content :)</p>', 10) . '</div>', 'http://0.0.0.0');
|
|
|
|
|
$readability->addPostFilter('!<strong[^>]*>(.*?)</strong>!is', '');
|
|
|
|
@@ -440,63 +438,213 @@ class ReadabilityTest extends \PHPUnit\Framework\TestCase
|
|
|
|
|
$res = $readability->init();
|
|
|
|
|
|
|
|
|
|
$this->assertTrue($res);
|
|
|
|
|
$this->assertContains('This the awesome content :)', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertStringContainsString('This the awesome content :)', $readability->getContent()->getInnerHtml());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testPreFilters()
|
|
|
|
|
public function testPreFilters(): void
|
|
|
|
|
{
|
|
|
|
|
$this->markTestSkipped('Won\'t work until loadHtml() is moved in init() instead of __construct()');
|
|
|
|
|
|
|
|
|
|
$readability = $this->getReadability('<div>' . str_repeat('<p>This <b>is</b> the awesome and WONDERFUL content :)</p>', 7) . '</div>', 'http://0.0.0.0');
|
|
|
|
|
$readability->addPreFilter('!<b[^>]*>(.*?)</b>!is', '');
|
|
|
|
|
|
|
|
|
|
$res = $readability->init();
|
|
|
|
|
|
|
|
|
|
$this->assertTrue($res);
|
|
|
|
|
$this->assertContains('This the awesome and WONDERFUL content :)', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertStringContainsString('This the awesome and WONDERFUL content :)', $readability->getContent()->getInnerHtml());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testChildNodeGoneNull()
|
|
|
|
|
public function testChildNodeGoneNull(): void
|
|
|
|
|
{
|
|
|
|
|
// from http://www.ayyaantuu.net/ethiopia-targets-opposition-lawmakers/
|
|
|
|
|
$html = file_get_contents('tests/fixtures/childNodeGoesNull.html');
|
|
|
|
|
$html = (string) file_get_contents('tests/fixtures/childNodeGoesNull.html');
|
|
|
|
|
|
|
|
|
|
$readability = $this->getReadability($html, 'http://0.0.0.0');
|
|
|
|
|
$readability->debug = true;
|
|
|
|
|
$readability->convertLinksToFootnotes = true;
|
|
|
|
|
$res = $readability->init();
|
|
|
|
|
|
|
|
|
|
$this->assertTrue($res);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testKeepFootnotes()
|
|
|
|
|
public function dataForHasSingleTagInsideElement(): array
|
|
|
|
|
{
|
|
|
|
|
// from https://www.schreibdichte.de/blog/feed-aggregator-und-spaeter-lesen-dienst-im-team
|
|
|
|
|
$html = file_get_contents('tests/fixtures/keepFootnotes.html');
|
|
|
|
|
|
|
|
|
|
$readability = $this->getReadability($html, 'http://0.0.0.0');
|
|
|
|
|
$readability->debug = true;
|
|
|
|
|
$res = $readability->init();
|
|
|
|
|
|
|
|
|
|
$this->assertTrue($res);
|
|
|
|
|
$this->assertContains('<sup id="fnref1:fnfeed_2"><a href="#fn:fnfeed_2" class="footnote-ref">2</a></sup>', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertContains('<a href="#fnref1:fnfeed_2" rev="footnote"', $readability->getContent()->getInnerHtml());
|
|
|
|
|
return [
|
|
|
|
|
'single matching tag, no other content' => [
|
|
|
|
|
'<div><p>Some text</p></div>', 'p', true,
|
|
|
|
|
],
|
|
|
|
|
'single matching tag with comment' => [
|
|
|
|
|
'<div><!-- comment --><p>Some text</p></div>', 'p', true,
|
|
|
|
|
],
|
|
|
|
|
'whitespace-only text around single matching tag' => [
|
|
|
|
|
'<div> <p>Some text</p> </div>', 'p', true,
|
|
|
|
|
],
|
|
|
|
|
'two matching tags' => [
|
|
|
|
|
'<div><p>One</p><p>Two</p></div>', 'p', false,
|
|
|
|
|
],
|
|
|
|
|
'non-whitespace text alongside the single tag' => [
|
|
|
|
|
'<div>Some text<p>One</p></div>', 'p', false,
|
|
|
|
|
],
|
|
|
|
|
'single tag with a different name' => [
|
|
|
|
|
'<div><span>One</span></div>', 'p', false,
|
|
|
|
|
],
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testWithWipedBody()
|
|
|
|
|
/**
|
|
|
|
|
* @dataProvider dataForHasSingleTagInsideElement
|
|
|
|
|
*/
|
|
|
|
|
public function testHasSingleTagInsideElement(string $html, string $tag, bool $expected): void
|
|
|
|
|
{
|
|
|
|
|
// from https://www.cs.cmu.edu/~rgs/alice-table.html
|
|
|
|
|
$html = file_get_contents('tests/fixtures/wipedBody.html');
|
|
|
|
|
$dom = new \DOMDocument();
|
|
|
|
|
$dom->loadHTML('<html><body>' . $html . '</body></html>');
|
|
|
|
|
$node = $dom->getElementsByTagName('div')->item(0);
|
|
|
|
|
|
|
|
|
|
$readability = $this->getReadability('', '', 'libxml', false);
|
|
|
|
|
|
|
|
|
|
$method = new \ReflectionMethod($readability, 'hasSingleTagInsideElement');
|
|
|
|
|
if (\PHP_VERSION_ID < 80100) {
|
|
|
|
|
$method->setAccessible(true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$this->assertSame($expected, $method->invoke($readability, $node, $tag));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testDivToPElementWithComment(): void
|
|
|
|
|
{
|
|
|
|
|
$text = str_repeat('Padded real article text to reach decent length for content scoring threshold here. ', 8);
|
|
|
|
|
$html = '<div><!-- comment --><code>some code snippet</code> ' . $text . '</div>';
|
|
|
|
|
|
|
|
|
|
$readability = $this->getReadability($html, 'http://0.0.0.0', 'libxml', false);
|
|
|
|
|
$readability->debug = true;
|
|
|
|
|
$res = $readability->init();
|
|
|
|
|
|
|
|
|
|
$this->assertTrue($res);
|
|
|
|
|
$this->assertContains('<a href="alice-I.html">Down the Rabbit-Hole</a>', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertStringContainsString('some code snippet', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertStringContainsString('Padded real article text', $readability->getContent()->getInnerHtml());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private function getReadability($html, $url = null, $parser = 'libxml', $useTidy = true)
|
|
|
|
|
public function testKeepFootnotes(): void
|
|
|
|
|
{
|
|
|
|
|
// from https://www.schreibdichte.de/blog/feed-aggregator-und-spaeter-lesen-dienst-im-team
|
|
|
|
|
$html = (string) file_get_contents('tests/fixtures/keepFootnotes.html');
|
|
|
|
|
|
|
|
|
|
$readability = $this->getReadability($html, 'http://0.0.0.0');
|
|
|
|
|
$res = $readability->init();
|
|
|
|
|
|
|
|
|
|
$this->assertTrue($res);
|
|
|
|
|
$this->assertStringContainsString('<sup id="fnref1:fnfeed_2"><a href="#fn:fnfeed_2" class="footnote-ref">2</a></sup>', $readability->getContent()->getInnerHtml());
|
|
|
|
|
$this->assertStringContainsString('<a href="#fnref1:fnfeed_2" rev="footnote"', $readability->getContent()->getInnerHtml());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testWithWipedBody(): void
|
|
|
|
|
{
|
|
|
|
|
// from https://www.cs.cmu.edu/~rgs/alice-table.html
|
|
|
|
|
$html = (string) file_get_contents('tests/fixtures/wipedBody.html');
|
|
|
|
|
|
|
|
|
|
$readability = $this->getReadability($html, 'http://0.0.0.0', 'libxml', false);
|
|
|
|
|
$res = $readability->init();
|
|
|
|
|
|
|
|
|
|
$this->assertTrue($res);
|
|
|
|
|
$this->assertStringContainsString('<a href="alice-I.html">Down the Rabbit-Hole</a>', $readability->getContent()->getInnerHtml());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function dataForVisibleNode(): array
|
|
|
|
|
{
|
|
|
|
|
return [
|
|
|
|
|
'visible node' => [
|
|
|
|
|
'<div>' . str_repeat('<p>This <b>is</b> the awesome and WONDERFUL content :)</p>', 7) . '</div>',
|
|
|
|
|
true,
|
|
|
|
|
],
|
|
|
|
|
'display=none' => [
|
|
|
|
|
'<div style="display:none;">' . str_repeat('<p>This <b>is</b> the awesome and WONDERFUL content :)</p>', 7) . '</div>',
|
|
|
|
|
false,
|
|
|
|
|
],
|
|
|
|
|
'display=inline' => [
|
|
|
|
|
'<div style="display:inline;">' . str_repeat('<p>This <b>is</b> the awesome and WONDERFUL content :)</p>', 7) . '</div>',
|
|
|
|
|
true,
|
|
|
|
|
],
|
|
|
|
|
'hidden attribute' => [
|
|
|
|
|
'<div hidden>' . str_repeat('<p>This <b>is</b> the awesome and WONDERFUL content :)</p>', 7) . '</div>',
|
|
|
|
|
false,
|
|
|
|
|
],
|
|
|
|
|
'missing display' => [
|
|
|
|
|
'<div style="color:#ccc;">' . str_repeat('<p>This <b>is</b> the awesome and WONDERFUL content :)</p>', 7) . '</div>',
|
|
|
|
|
true,
|
|
|
|
|
],
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @dataProvider dataForVisibleNode
|
|
|
|
|
*/
|
|
|
|
|
public function testVisibleNode(string $content, bool $shouldBeVisible): void
|
|
|
|
|
{
|
|
|
|
|
$readability = $this->getReadability($content, 'http://0.0.0.0');
|
|
|
|
|
$res = $readability->init();
|
|
|
|
|
|
|
|
|
|
if ($shouldBeVisible) {
|
|
|
|
|
$this->assertStringContainsString('WONDERFUL content', $readability->getContent()->getInnerHtml());
|
|
|
|
|
} else {
|
|
|
|
|
$this->assertStringNotContainsString('WONDERFUL content', $readability->getContent()->getInnerHtml());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// https://github.com/wallabag/wallabag/issues/8158
|
|
|
|
|
public function testCharsetAfterTitle(): void
|
|
|
|
|
{
|
|
|
|
|
$readability = $this->getReadability('<!DOCTYPE html><html lang="et"><head><title>Tõde ja õigus I</title> <meta charset="utf-8"></head><body><p>See oli läinud aastasaja kolmanda veerandi lõpul. Päike lähenes silmapiirile, seistes sedavõrd madalas, et enam ei ulatunud valgustama ei mäkke ronivat hobust, kes puutelgedega vankrit vedas, ei vankril istuvat noort naist ega ka ligi kolmekümnelist meest, kes kõndis vankri kõrval.</p></body></html>', 'https://et.wikisource.org/wiki/T%C3%B5de_ja_%C3%B5igus_I/I');
|
|
|
|
|
$readability->convertLinksToFootnotes = true;
|
|
|
|
|
$res = $readability->init();
|
|
|
|
|
|
|
|
|
|
$this->assertTrue($res);
|
|
|
|
|
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getContent());
|
|
|
|
|
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getTitle());
|
|
|
|
|
$this->assertSame('Tõde ja õigus I', $readability->getTitle()->getInnerHtml());
|
|
|
|
|
$this->assertStringContainsString('Päike lähenes', $readability->getContent()->getInnerHtml());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return array<string, array{0: string, 1: string, 2?: bool}>
|
|
|
|
|
*/
|
|
|
|
|
public function dataForHtmlLang(): array
|
|
|
|
|
{
|
|
|
|
|
return [
|
|
|
|
|
'meta' => [
|
|
|
|
|
'<html lang="fr"><head><meta charset="utf-8"></head><body><article>' . str_repeat('<p>Tous les êtres humains naissent libres et égaux en dignité et en droits. Ils sont doués de raison et de conscience et doivent agir les uns envers les autres dans un esprit de fraternité.</p>', 7) . '</article></body></html>',
|
|
|
|
|
'fr',
|
|
|
|
|
],
|
|
|
|
|
'head' => [
|
|
|
|
|
'<html lang="fr"><head><title>Foo</title></head><body><article>' . str_repeat('<p>Tous les êtres humains naissent libres et égaux en dignité et en droits. Ils sont doués de raison et de conscience et doivent agir les uns envers les autres dans un esprit de fraternité.</p>', 7) . '</article></body></html>',
|
|
|
|
|
'fr',
|
|
|
|
|
],
|
|
|
|
|
'headless' => [
|
|
|
|
|
'<html lang="fr"><body><article>' . str_repeat('<p>Tous les êtres humains naissent libres et égaux en dignité et en droits. Ils sont doués de raison et de conscience et doivent agir les uns envers les autres dans un esprit de fraternité.</p>', 7) . '</article></body></html>',
|
|
|
|
|
'fr',
|
|
|
|
|
// tidy would add <head> tag.
|
|
|
|
|
false,
|
|
|
|
|
],
|
|
|
|
|
'fragment' => [
|
|
|
|
|
'<article>' . str_repeat('<p>Tous les êtres humains naissent libres et égaux en dignité et en droits. Ils sont doués de raison et de conscience et doivent agir les uns envers les autres dans un esprit de fraternité.</p>', 7) . '</article>',
|
|
|
|
|
'',
|
|
|
|
|
// tidy would add <html>.
|
|
|
|
|
false,
|
|
|
|
|
],
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @dataProvider dataForHtmlLang
|
|
|
|
|
*/
|
|
|
|
|
public function testHtmlLang(string $html, string $lang, bool $useTidy = true): void
|
|
|
|
|
{
|
|
|
|
|
$readability = $this->getReadability($html, 'http://0.0.0.0', 'libxml', $useTidy);
|
|
|
|
|
$res = $readability->init();
|
|
|
|
|
|
|
|
|
|
$this->assertTrue($res);
|
|
|
|
|
$this->assertInstanceOf(\DOMDocument::class, $readability->dom);
|
|
|
|
|
$this->assertSame($lang, $readability->dom->documentElement->getAttribute('lang'));
|
|
|
|
|
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getContent());
|
|
|
|
|
$this->assertStringContainsString('êtres', $readability->getContent()->getInnerHtml());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private function getReadability(string $html, ?string $url = null, string $parser = 'libxml', bool $useTidy = true): Readability
|
|
|
|
|
{
|
|
|
|
|
$readability = new Readability($html, $url, $parser, $useTidy);
|
|
|
|
|
|
|
|
|
|