mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
0e5b099287
Since that used to be the default shortcode notation for our core "insert media" functionality, its important to have this fixed and keep supporting "legacy" content created with 3.0.
226 lines
7.2 KiB
PHP
226 lines
7.2 KiB
PHP
<?php
|
|
/**
|
|
* @package framework
|
|
* @subpackage tests
|
|
*/
|
|
class ShortcodeParserTest extends SapphireTest {
|
|
|
|
protected $arguments, $contents, $tagName, $parser;
|
|
|
|
public function setUp() {
|
|
ShortcodeParser::get('test')->register('test_shortcode', array($this, 'shortcodeSaver'));
|
|
$this->parser = ShortcodeParser::get('test');
|
|
|
|
parent::setUp();
|
|
}
|
|
|
|
/**
|
|
* Tests that valid short codes that have not been registered are not replaced.
|
|
*/
|
|
public function testNotRegisteredShortcode() {
|
|
ShortcodeParser::$error_behavior = ShortcodeParser::STRIP;
|
|
|
|
$this->assertEquals(
|
|
'',
|
|
$this->parser->parse('[not_shortcode]')
|
|
);
|
|
|
|
$this->assertEquals(
|
|
'<img class="">',
|
|
$this->parser->parse('<img class="[not_shortcode]">')
|
|
);
|
|
|
|
ShortcodeParser::$error_behavior = ShortcodeParser::WARN;
|
|
|
|
$this->assertEquals(
|
|
'<strong class="warning">[not_shortcode]</strong>',
|
|
$this->parser->parse('[not_shortcode]')
|
|
);
|
|
|
|
ShortcodeParser::$error_behavior = ShortcodeParser::LEAVE;
|
|
|
|
$this->assertEquals('[not_shortcode]',
|
|
$this->parser->parse('[not_shortcode]'));
|
|
$this->assertEquals('[not_shortcode /]',
|
|
$this->parser->parse('[not_shortcode /]'));
|
|
$this->assertEquals('[not_shortcode,foo="bar"]',
|
|
$this->parser->parse('[not_shortcode,foo="bar"]'));
|
|
$this->assertEquals('[not_shortcode]a[/not_shortcode]',
|
|
$this->parser->parse('[not_shortcode]a[/not_shortcode]'));
|
|
$this->assertEquals('[/not_shortcode]',
|
|
$this->parser->parse('[/not_shortcode]'));
|
|
|
|
$this->assertEquals(
|
|
'<img class="[not_shortcode]">',
|
|
$this->parser->parse('<img class="[not_shortcode]">')
|
|
);
|
|
}
|
|
|
|
public function testSimpleTag() {
|
|
$tests = array(
|
|
'[test_shortcode]',
|
|
'[test_shortcode ]', '[test_shortcode,]', '[test_shortcode, ]'.
|
|
'[test_shortcode/]', '[test_shortcode /]', '[test_shortcode,/]', '[test_shortcode, /]'
|
|
);
|
|
|
|
foreach($tests as $test) {
|
|
$this->parser->parse($test);
|
|
|
|
$this->assertEquals(array(), $this->arguments, $test);
|
|
$this->assertEquals('', $this->contents, $test);
|
|
$this->assertEquals('test_shortcode', $this->tagName, $test);
|
|
}
|
|
}
|
|
|
|
public function testOneArgument() {
|
|
$tests = array (
|
|
'[test_shortcode foo="bar"]', '[test_shortcode,foo="bar"]',
|
|
"[test_shortcode foo='bar']", "[test_shortcode,foo='bar']",
|
|
'[test_shortcode foo = "bar" /]', '[test_shortcode, foo = "bar" /]'
|
|
);
|
|
|
|
foreach($tests as $test) {
|
|
$this->parser->parse($test);
|
|
|
|
$this->assertEquals(array('foo' => 'bar'), $this->arguments, $test);
|
|
$this->assertEquals('', $this->contents, $test);
|
|
$this->assertEquals('test_shortcode', $this->tagName, $test);
|
|
}
|
|
}
|
|
|
|
public function testMultipleArguments() {
|
|
$this->parser->parse('[test_shortcode foo = "bar",bar=\'foo\', baz="buz"]');
|
|
|
|
$this->assertEquals(array('foo' => 'bar', 'bar' => 'foo', 'baz' => 'buz'), $this->arguments);
|
|
$this->assertEquals('', $this->contents);
|
|
$this->assertEquals('test_shortcode', $this->tagName);
|
|
}
|
|
|
|
public function testEnclosing() {
|
|
$this->parser->parse('[test_shortcode]foo[/test_shortcode]');
|
|
|
|
$this->assertEquals(array(), $this->arguments);
|
|
$this->assertEquals('foo', $this->contents);
|
|
$this->assertEquals('test_shortcode', $this->tagName);
|
|
}
|
|
|
|
public function testEnclosingWithArguments() {
|
|
$this->parser->parse('[test_shortcode,foo = "bar",bar=\'foo\',baz="buz"]foo[/test_shortcode]');
|
|
|
|
$this->assertEquals(array('foo' => 'bar', 'bar' => 'foo', 'baz' => 'buz'), $this->arguments);
|
|
$this->assertEquals('foo', $this->contents);
|
|
$this->assertEquals('test_shortcode', $this->tagName);
|
|
}
|
|
|
|
public function testShortcodeEscaping() {
|
|
$this->assertEquals(
|
|
'[test_shortcode]',
|
|
$this->parser->parse('[[test_shortcode]]')
|
|
);
|
|
|
|
$this->assertEquals(
|
|
'[test_shortcode /]',
|
|
$this->parser->parse('[[test_shortcode /]]')
|
|
);
|
|
|
|
$this->assertEquals(
|
|
'[test_shortcode]content[/test_shortcode]',
|
|
$this->parser->parse('[[test_shortcode]content[/test_shortcode]]'
|
|
));
|
|
|
|
$this->assertEquals(
|
|
'[test_shortcode]content',
|
|
$this->parser->parse('[[test_shortcode]][test_shortcode]content[/test_shortcode]')
|
|
);
|
|
|
|
$this->assertEquals(
|
|
'[test_shortcode]content[/test_shortcode]content2',
|
|
$this->parser->parse('[[test_shortcode]content[/test_shortcode]][test_shortcode]content2[/test_shortcode]'
|
|
));
|
|
|
|
$this->assertEquals(
|
|
'[[Doesnt strip double [ character if not a shortcode',
|
|
$this->parser->parse('[[Doesnt strip double [ character if not a [test_shortcode]shortcode[/test_shortcode]'
|
|
));
|
|
|
|
$this->assertEquals(
|
|
'[[Doesnt shortcode get confused by double ]] characters',
|
|
$this->parser->parse('[[Doesnt [test_shortcode]shortcode[/test_shortcode] get confused by double ]] characters'
|
|
));
|
|
}
|
|
|
|
public function testUnquotedArguments() {
|
|
$this->assertEquals('', $this->parser->parse('[test_shortcode,foo=bar!,baz = buz123]'));
|
|
$this->assertEquals(array('foo' => 'bar!', 'baz' => 'buz123'), $this->arguments);
|
|
}
|
|
|
|
public function testSpacesForDelimiter() {
|
|
$this->assertEquals('', $this->parser->parse('[test_shortcode foo=bar! baz = buz123]'));
|
|
$this->assertEquals(array('foo' => 'bar!', 'baz' => 'buz123'), $this->arguments);
|
|
}
|
|
|
|
public function testSelfClosingTag() {
|
|
$this->assertEquals (
|
|
'morecontent',
|
|
$this->parser->parse('[test_shortcode,id="1"/]more[test_shortcode,id="2"]content[/test_shortcode]'),
|
|
'Assert that self-closing tags are respected during parsing.'
|
|
);
|
|
|
|
$this->assertEquals(2, $this->arguments['id']);
|
|
}
|
|
|
|
public function testConsecutiveTags() {
|
|
$this->assertEquals('', $this->parser->parse('[test_shortcode][test_shortcode]'));
|
|
}
|
|
|
|
protected function assertEqualsIgnoringWhitespace($a, $b, $message = null) {
|
|
$this->assertEquals(preg_replace('/\s+/', '', $a), preg_replace('/\s+/', '', $b), $message);
|
|
}
|
|
|
|
public function testtExtract() {
|
|
// Left extracts to before the current block
|
|
$this->assertEqualsIgnoringWhitespace(
|
|
'Code<div>FooBar</div>',
|
|
$this->parser->parse('<div>Foo[test_shortcode class=left]Code[/test_shortcode]Bar</div>')
|
|
);
|
|
|
|
// Even if the immediate parent isn't a the current block
|
|
$this->assertEqualsIgnoringWhitespace(
|
|
'Code<div>Foo<b>BarBaz</b>Qux</div>',
|
|
$this->parser->parse('<div>Foo<b>Bar[test_shortcode class=left]Code[/test_shortcode]Baz</b>Qux</div>')
|
|
);
|
|
|
|
// Center splits the current block
|
|
$this->assertEqualsIgnoringWhitespace(
|
|
'<div>Foo</div>Code<div>Bar</div>',
|
|
$this->parser->parse('<div>Foo[test_shortcode class=center]Code[/test_shortcode]Bar</div>')
|
|
);
|
|
|
|
// Even if the immediate parent isn't a the current block
|
|
$this->assertEqualsIgnoringWhitespace(
|
|
'<div>Foo<b>Bar</b></div>Code<div><b>Baz</b>Qux</div>',
|
|
$this->parser->parse('<div>Foo<b>Bar[test_shortcode class=center]Code[/test_shortcode]Baz</b>Qux</div>')
|
|
);
|
|
|
|
// No class means don't extract
|
|
$this->assertEqualsIgnoringWhitespace(
|
|
'<div>FooCodeBar</div>',
|
|
$this->parser->parse('<div>Foo[test_shortcode]Code[/test_shortcode]Bar</div>')
|
|
);
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------------------------------------------
|
|
|
|
/**
|
|
* Stores the result of a shortcode parse in object properties for easy testing access.
|
|
*/
|
|
public function shortcodeSaver($arguments, $content = null, $parser, $tagName = null) {
|
|
$this->arguments = $arguments;
|
|
$this->contents = $content;
|
|
$this->tagName = $tagName;
|
|
|
|
return $content;
|
|
}
|
|
|
|
}
|