Completed
Push — master ( 054cba...664c0e )
by Daniel
09:44
created

ShortcodeParserTest::testSpacesForDelimiter()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 0
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace SilverStripe\View\Tests\Parsers;
4
5
use SilverStripe\Dev\SapphireTest;
6
use SilverStripe\View\Parsers\ShortcodeParser;
7
8
class ShortcodeParserTest extends SapphireTest
9
{
10
11
    protected $arguments, $contents, $tagName, $parser;
0 ignored issues
show
Coding Style introduced by
It is generally advisable to only define one property per statement.

Only declaring a single property per statement allows you to later on add doc comments more easily.

It is also recommended by PSR2, so it is a common style that many people expect.

Loading history...
12
    protected $extra = array();
13
14
    public function setUp()
15
    {
16
        ShortcodeParser::get('test')->register('test_shortcode', array($this, 'shortcodeSaver'));
17
        $this->parser = ShortcodeParser::get('test');
18
19
        parent::setUp();
20
    }
21
22
    public function tearDown()
23
    {
24
        ShortcodeParser::get('test')->unregister('test_shortcode');
25
26
        parent::tearDown();
27
    }
28
29
    /**
30
     * Tests that valid short codes that have not been registered are not replaced.
31
     */
32
    public function testNotRegisteredShortcode()
33
    {
34
        ShortcodeParser::$error_behavior = ShortcodeParser::STRIP;
35
36
        $this->assertEquals(
37
            '',
38
            $this->parser->parse('[not_shortcode]')
39
        );
40
41
        $this->assertEquals(
42
            '<img class="">',
43
            $this->parser->parse('<img class="[not_shortcode]">')
44
        );
45
46
        ShortcodeParser::$error_behavior = ShortcodeParser::WARN;
47
48
        $this->assertEquals(
49
            '<strong class="warning">[not_shortcode]</strong>',
50
            $this->parser->parse('[not_shortcode]')
51
        );
52
53
        ShortcodeParser::$error_behavior = ShortcodeParser::LEAVE;
54
55
        $this->assertEquals(
56
            '[not_shortcode]',
57
            $this->parser->parse('[not_shortcode]')
58
        );
59
        $this->assertEquals(
60
            '[not_shortcode /]',
61
            $this->parser->parse('[not_shortcode /]')
62
        );
63
        $this->assertEquals(
64
            '[not_shortcode,foo="bar"]',
65
            $this->parser->parse('[not_shortcode,foo="bar"]')
66
        );
67
        $this->assertEquals(
68
            '[not_shortcode]a[/not_shortcode]',
69
            $this->parser->parse('[not_shortcode]a[/not_shortcode]')
70
        );
71
        $this->assertEquals(
72
            '[/not_shortcode]',
73
            $this->parser->parse('[/not_shortcode]')
74
        );
75
76
        $this->assertEquals(
77
            '<img class="[not_shortcode]">',
78
            $this->parser->parse('<img class="[not_shortcode]">')
79
        );
80
    }
81
82
    public function testSimpleTag()
83
    {
84
        $tests = array(
85
            '[test_shortcode]',
86
            '[test_shortcode ]', '[test_shortcode,]', '[test_shortcode, ]'.
87
            '[test_shortcode/]', '[test_shortcode /]', '[test_shortcode,/]', '[test_shortcode, /]'
88
        );
89
90
        foreach ($tests as $test) {
91
            $this->parser->parse($test);
92
93
            $this->assertEquals(array(), $this->arguments, $test);
94
            $this->assertEquals('', $this->contents, $test);
95
            $this->assertEquals('test_shortcode', $this->tagName, $test);
96
        }
97
    }
98
99
    public function testOneArgument()
100
    {
101
        $tests = array (
102
            '[test_shortcode foo="bar"]', '[test_shortcode,foo="bar"]',
103
            "[test_shortcode foo='bar']", "[test_shortcode,foo='bar']",
104
            '[test_shortcode  foo  =  "bar"  /]', '[test_shortcode,  foo  =  "bar"  /]'
105
        );
106
107
        foreach ($tests as $test) {
108
            $this->parser->parse($test);
109
110
            $this->assertEquals(array('foo' => 'bar'), $this->arguments, $test);
111
            $this->assertEquals('', $this->contents, $test);
112
            $this->assertEquals('test_shortcode', $this->tagName, $test);
113
        }
114
    }
115
116
    public function testMultipleArguments()
117
    {
118
        $this->parser->parse('[test_shortcode foo = "bar",bar=\'foo\', baz="buz"]');
119
120
        $this->assertEquals(array('foo' => 'bar', 'bar' => 'foo', 'baz' => 'buz'), $this->arguments);
121
        $this->assertEquals('', $this->contents);
122
        $this->assertEquals('test_shortcode', $this->tagName);
123
    }
124
125
    public function testEnclosing()
126
    {
127
        $this->parser->parse('[test_shortcode]foo[/test_shortcode]');
128
129
        $this->assertEquals(array(), $this->arguments);
130
        $this->assertEquals('foo', $this->contents);
131
        $this->assertEquals('test_shortcode', $this->tagName);
132
    }
133
134
    public function testEnclosingWithArguments()
135
    {
136
        $this->parser->parse('[test_shortcode,foo = "bar",bar=\'foo\',baz="buz"]foo[/test_shortcode]');
137
138
        $this->assertEquals(array('foo' => 'bar', 'bar' => 'foo', 'baz' => 'buz'), $this->arguments);
139
        $this->assertEquals('foo', $this->contents);
140
        $this->assertEquals('test_shortcode', $this->tagName);
141
    }
142
143
    public function testShortcodeEscaping()
144
    {
145
        $this->assertEquals(
146
            '[test_shortcode]',
147
            $this->parser->parse('[[test_shortcode]]')
148
        );
149
150
        $this->assertEquals(
151
            '[test_shortcode /]',
152
            $this->parser->parse('[[test_shortcode /]]')
153
        );
154
155
        $this->assertEquals(
156
            '[test_shortcode]content[/test_shortcode]',
157
            $this->parser->parse('[[test_shortcode]content[/test_shortcode]]')
158
        );
159
160
        $this->assertEquals(
161
            '[test_shortcode]content',
162
            $this->parser->parse('[[test_shortcode]][test_shortcode]content[/test_shortcode]')
163
        );
164
165
        $this->assertEquals(
166
            '[test_shortcode]content[/test_shortcode]content2',
167
            $this->parser->parse('[[test_shortcode]content[/test_shortcode]][test_shortcode]content2[/test_shortcode]')
168
        );
169
170
        $this->assertEquals(
171
            '[[Doesnt strip double [ character if not a shortcode',
172
            $this->parser->parse('[[Doesnt strip double [ character if not a [test_shortcode]shortcode[/test_shortcode]')
173
        );
174
175
        $this->assertEquals(
176
            '[[Doesnt shortcode get confused by double ]] characters',
177
            $this->parser->parse(
178
                '[[Doesnt [test_shortcode]shortcode[/test_shortcode] get confused by double ]] characters'
179
            )
180
        );
181
    }
182
183
    public function testUnquotedArguments()
184
    {
185
        $this->assertEquals('', $this->parser->parse('[test_shortcode,foo=bar!,baz = buz123]'));
186
        $this->assertEquals(array('foo' => 'bar!', 'baz' => 'buz123'), $this->arguments);
187
    }
188
189
    public function testSpacesForDelimiter()
190
    {
191
        $this->assertEquals('', $this->parser->parse('[test_shortcode foo=bar! baz = buz123]'));
192
        $this->assertEquals(array('foo' => 'bar!', 'baz' => 'buz123'), $this->arguments);
193
    }
194
195
    public function testSelfClosingTag()
196
    {
197
        $this->assertEquals(
198
            'morecontent',
199
            $this->parser->parse('[test_shortcode,id="1"/]more[test_shortcode,id="2"]content[/test_shortcode]'),
200
            'Assert that self-closing tags are respected during parsing.'
201
        );
202
203
        $this->assertEquals(2, $this->arguments['id']);
204
    }
205
206
    public function testConsecutiveTags()
207
    {
208
        $this->assertEquals('', $this->parser->parse('[test_shortcode][test_shortcode]'));
209
    }
210
211
    protected function assertEqualsIgnoringWhitespace($a, $b, $message = null)
212
    {
213
        $this->assertEquals(preg_replace('/\s+/', '', $a), preg_replace('/\s+/', '', $b), $message);
214
    }
215
216
    public function testExtractBefore()
217
    {
218
        // Left extracts to before the current block
219
        $this->assertEqualsIgnoringWhitespace(
220
            'Code<div>FooBar</div>',
221
            $this->parser->parse('<div>Foo[test_shortcode class=left]Code[/test_shortcode]Bar</div>')
222
        );
223
        // Even if the immediate parent isn't a the current block
224
        $this->assertEqualsIgnoringWhitespace(
225
            'Code<div>Foo<b>BarBaz</b>Qux</div>',
226
            $this->parser->parse('<div>Foo<b>Bar[test_shortcode class=left]Code[/test_shortcode]Baz</b>Qux</div>')
227
        );
228
    }
229
230
    public function testExtractSplit()
231
    {
232
        $this->markTestSkipped(
233
            'Feature disabled due to https://github.com/silverstripe/silverstripe-framework/issues/5987'
234
        );
235
        // Center splits the current block
236
        $this->assertEqualsIgnoringWhitespace(
237
            '<div>Foo</div>Code<div>Bar</div>',
238
            $this->parser->parse('<div>Foo[test_shortcode class=center]Code[/test_shortcode]Bar</div>')
239
        );
240
        // Even if the immediate parent isn't a the current block
241
        $this->assertEqualsIgnoringWhitespace(
242
            '<div>Foo<b>Bar</b></div>Code<div><b>Baz</b>Qux</div>',
243
            $this->parser->parse('<div>Foo<b>Bar[test_shortcode class=center]Code[/test_shortcode]Baz</b>Qux</div>')
244
        );
245
    }
246
247
    public function testExtractNone()
248
    {
249
        // No class means don't extract
250
        $this->assertEqualsIgnoringWhitespace(
251
            '<div>FooCodeBar</div>',
252
            $this->parser->parse('<div>Foo[test_shortcode]Code[/test_shortcode]Bar</div>')
253
        );
254
    }
255
256
    public function testShortcodesInsideScriptTag()
257
    {
258
        $this->assertEqualsIgnoringWhitespace(
259
            '<script>hello</script>',
260
            $this->parser->parse('<script>[test_shortcode]hello[/test_shortcode]</script>')
261
        );
262
    }
263
264
    public function testFalseyArguments()
265
    {
266
        $this->parser->parse('<p>[test_shortcode falsey=0]');
267
268
        $this->assertEquals(
269
            array(
270
            'falsey' => '',
271
            ),
272
            $this->arguments
273
        );
274
    }
275
276
    public function testNumericShortcodes()
277
    {
278
        $this->assertEqualsIgnoringWhitespace(
279
            '[2]',
280
            $this->parser->parse('[2]')
281
        );
282
        $this->assertEqualsIgnoringWhitespace(
283
            '<script>[2]</script>',
284
            $this->parser->parse('<script>[2]</script>')
285
        );
286
287
        $this->parser->register(
288
            '2',
289
            function () {
290
                return 'this is 2';
291
            }
292
        );
293
294
        $this->assertEqualsIgnoringWhitespace(
295
            'this is 2',
296
            $this->parser->parse('[2]')
297
        );
298
        $this->assertEqualsIgnoringWhitespace(
299
            '<script>this is 2</script>',
300
            $this->parser->parse('<script>[2]</script>')
301
        );
302
303
        $this->parser->unregister('2');
304
    }
305
306
    public function testExtraContext()
307
    {
308
        $this->parser->parse('<a href="[test_shortcode]">Test</a>');
309
310
        $this->assertInstanceOf('DOMNode', $this->extra['node']);
311
        $this->assertInstanceOf('DOMElement', $this->extra['element']);
312
        $this->assertEquals($this->extra['element']->tagName, 'a');
313
    }
314
315
    public function testNoParseAttemptIfNoCode()
316
    {
317
        $stub = $this->getMock('SilverStripe\\View\\Parsers\\ShortcodeParser', array('replaceElementTagsWithMarkers'));
318
        $stub->register(
319
            'test',
320
            function () {
321
                return '';
322
            }
323
        );
324
325
        $stub->expects($this->never())
326
            ->method('replaceElementTagsWithMarkers')->will($this->returnValue(array('', '')));
327
328
        $stub->parse('<p>test</p>');
329
    }
330
331
    // -----------------------------------------------------------------------------------------------------------------
332
333
    /**
334
     * Stores the result of a shortcode parse in object properties for easy testing access.
335
     */
336
    public function shortcodeSaver($arguments, $content, $parser, $tagName, $extra)
337
    {
338
        $this->arguments = $arguments;
339
        $this->contents = $content;
340
        $this->tagName = $tagName;
341
        $this->extra = $extra;
342
343
        return $content;
344
    }
345
}
346