Completed
Push — master ( 327ddb...5776a0 )
by Daniel
17:43
created

ShortcodeParserTest::tearDown()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 3
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 5
rs 9.4285
1
<?php
2
/**
3
 * @package framework
4
 * @subpackage tests
5
 */
6
class ShortcodeParserTest extends SapphireTest {
7
8
	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...
9
	protected $extra = array();
10
11
	public function setUp() {
12
		ShortcodeParser::get('test')->register('test_shortcode', array($this, 'shortcodeSaver'));
13
		$this->parser = ShortcodeParser::get('test');
14
15
		parent::setUp();
16
	}
17
18
	public function tearDown() {
19
		ShortcodeParser::get('test')->unregister('test_shortcode');
20
21
		parent::tearDown();
22
	}
23
24
	/**
25
	 * Tests that valid short codes that have not been registered are not replaced.
26
	 */
27
	public function testNotRegisteredShortcode() {
28
		ShortcodeParser::$error_behavior = ShortcodeParser::STRIP;
29
30
		$this->assertEquals(
31
			'',
32
			$this->parser->parse('[not_shortcode]')
33
		);
34
35
		$this->assertEquals(
36
			'<img class="">',
37
			$this->parser->parse('<img class="[not_shortcode]">')
38
		);
39
40
		ShortcodeParser::$error_behavior = ShortcodeParser::WARN;
41
42
		$this->assertEquals(
43
			'<strong class="warning">[not_shortcode]</strong>',
44
			$this->parser->parse('[not_shortcode]')
45
		);
46
47
		ShortcodeParser::$error_behavior = ShortcodeParser::LEAVE;
48
49
		$this->assertEquals('[not_shortcode]',
50
			$this->parser->parse('[not_shortcode]'));
51
		$this->assertEquals('[not_shortcode /]',
52
			$this->parser->parse('[not_shortcode /]'));
53
		$this->assertEquals('[not_shortcode,foo="bar"]',
54
			$this->parser->parse('[not_shortcode,foo="bar"]'));
55
		$this->assertEquals('[not_shortcode]a[/not_shortcode]',
56
			$this->parser->parse('[not_shortcode]a[/not_shortcode]'));
57
		$this->assertEquals('[/not_shortcode]',
58
			$this->parser->parse('[/not_shortcode]'));
59
60
		$this->assertEquals(
61
			'<img class="[not_shortcode]">',
62
			$this->parser->parse('<img class="[not_shortcode]">')
63
		);
64
	}
65
66
	public function testSimpleTag() {
67
		$tests = array(
68
			'[test_shortcode]',
69
			'[test_shortcode ]', '[test_shortcode,]', '[test_shortcode, ]'.
70
			'[test_shortcode/]', '[test_shortcode /]', '[test_shortcode,/]', '[test_shortcode, /]'
71
		);
72
73
		foreach($tests as $test) {
74
			$this->parser->parse($test);
75
76
			$this->assertEquals(array(), $this->arguments, $test);
77
			$this->assertEquals('', $this->contents, $test);
78
			$this->assertEquals('test_shortcode', $this->tagName, $test);
79
		}
80
	}
81
82
	public function testOneArgument() {
83
		$tests = array (
84
			'[test_shortcode foo="bar"]', '[test_shortcode,foo="bar"]',
85
			"[test_shortcode foo='bar']", "[test_shortcode,foo='bar']",
86
			'[test_shortcode  foo  =  "bar"  /]', '[test_shortcode,  foo  =  "bar"  /]'
87
		);
88
89
		foreach($tests as $test) {
90
			$this->parser->parse($test);
91
92
			$this->assertEquals(array('foo' => 'bar'), $this->arguments, $test);
93
			$this->assertEquals('', $this->contents, $test);
94
			$this->assertEquals('test_shortcode', $this->tagName, $test);
95
		}
96
	}
97
98
	public function testMultipleArguments() {
99
		$this->parser->parse('[test_shortcode foo = "bar",bar=\'foo\', baz="buz"]');
100
101
		$this->assertEquals(array('foo' => 'bar', 'bar' => 'foo', 'baz' => 'buz'), $this->arguments);
102
		$this->assertEquals('', $this->contents);
103
		$this->assertEquals('test_shortcode', $this->tagName);
104
	}
105
106
	public function testEnclosing() {
107
		$this->parser->parse('[test_shortcode]foo[/test_shortcode]');
108
109
		$this->assertEquals(array(), $this->arguments);
110
		$this->assertEquals('foo', $this->contents);
111
		$this->assertEquals('test_shortcode', $this->tagName);
112
	}
113
114
	public function testEnclosingWithArguments() {
115
		$this->parser->parse('[test_shortcode,foo = "bar",bar=\'foo\',baz="buz"]foo[/test_shortcode]');
116
117
		$this->assertEquals(array('foo' => 'bar', 'bar' => 'foo', 'baz' => 'buz'), $this->arguments);
118
		$this->assertEquals('foo', $this->contents);
119
		$this->assertEquals('test_shortcode', $this->tagName);
120
	}
121
122
	public function testShortcodeEscaping() {
123
		$this->assertEquals(
124
			'[test_shortcode]',
125
			$this->parser->parse('[[test_shortcode]]')
126
		);
127
128
		$this->assertEquals(
129
			'[test_shortcode /]',
130
			$this->parser->parse('[[test_shortcode /]]')
131
		);
132
133
		$this->assertEquals(
134
			'[test_shortcode]content[/test_shortcode]',
135
			$this->parser->parse('[[test_shortcode]content[/test_shortcode]]'
136
		));
137
138
		$this->assertEquals(
139
			'[test_shortcode]content',
140
			$this->parser->parse('[[test_shortcode]][test_shortcode]content[/test_shortcode]')
141
		);
142
143
		$this->assertEquals(
144
			'[test_shortcode]content[/test_shortcode]content2',
145
			$this->parser->parse('[[test_shortcode]content[/test_shortcode]][test_shortcode]content2[/test_shortcode]'
146
		));
147
148
		$this->assertEquals(
149
			'[[Doesnt strip double [ character if not a shortcode',
150
			$this->parser->parse('[[Doesnt strip double [ character if not a [test_shortcode]shortcode[/test_shortcode]'
151
		));
152
153
		$this->assertEquals(
154
			'[[Doesnt shortcode get confused by double ]] characters',
155
			$this->parser->parse(
156
				'[[Doesnt [test_shortcode]shortcode[/test_shortcode] get confused by double ]] characters')
157
		);
158
	}
159
160
	public function testUnquotedArguments() {
161
		$this->assertEquals('', $this->parser->parse('[test_shortcode,foo=bar!,baz = buz123]'));
162
		$this->assertEquals(array('foo' => 'bar!', 'baz' => 'buz123'), $this->arguments);
163
	}
164
165
	public function testSpacesForDelimiter() {
166
		$this->assertEquals('', $this->parser->parse('[test_shortcode foo=bar! baz = buz123]'));
167
		$this->assertEquals(array('foo' => 'bar!', 'baz' => 'buz123'), $this->arguments);
168
	}
169
170
	public function testSelfClosingTag() {
171
		$this->assertEquals (
172
			'morecontent',
173
			$this->parser->parse('[test_shortcode,id="1"/]more[test_shortcode,id="2"]content[/test_shortcode]'),
174
			'Assert that self-closing tags are respected during parsing.'
175
		);
176
177
		$this->assertEquals(2, $this->arguments['id']);
178
	}
179
180
	public function testConsecutiveTags() {
181
		$this->assertEquals('', $this->parser->parse('[test_shortcode][test_shortcode]'));
182
	}
183
184
	protected function assertEqualsIgnoringWhitespace($a, $b, $message = null) {
185
		$this->assertEquals(preg_replace('/\s+/', '', $a), preg_replace('/\s+/', '', $b), $message);
186
	}
187
188
	public function testtExtract() {
189
		// Left extracts to before the current block
190
		$this->assertEqualsIgnoringWhitespace(
191
			'Code<div>FooBar</div>',
192
			$this->parser->parse('<div>Foo[test_shortcode class=left]Code[/test_shortcode]Bar</div>')
193
		);
194
195
		// Even if the immediate parent isn't a the current block
196
		$this->assertEqualsIgnoringWhitespace(
197
			'Code<div>Foo<b>BarBaz</b>Qux</div>',
198
			$this->parser->parse('<div>Foo<b>Bar[test_shortcode class=left]Code[/test_shortcode]Baz</b>Qux</div>')
199
		);
200
201
		// Center splits the current block
202
		$this->assertEqualsIgnoringWhitespace(
203
			'<div>Foo</div>Code<div>Bar</div>',
204
			$this->parser->parse('<div>Foo[test_shortcode class=center]Code[/test_shortcode]Bar</div>')
205
		);
206
207
		// Even if the immediate parent isn't a the current block
208
		$this->assertEqualsIgnoringWhitespace(
209
			'<div>Foo<b>Bar</b></div>Code<div><b>Baz</b>Qux</div>',
210
			$this->parser->parse('<div>Foo<b>Bar[test_shortcode class=center]Code[/test_shortcode]Baz</b>Qux</div>')
211
		);
212
213
		// No class means don't extract
214
		$this->assertEqualsIgnoringWhitespace(
215
			'<div>FooCodeBar</div>',
216
			$this->parser->parse('<div>Foo[test_shortcode]Code[/test_shortcode]Bar</div>')
217
		);
218
	}
219
220
	public function testShortcodesInsideScriptTag() {
221
		$this->assertEqualsIgnoringWhitespace(
222
			'<script>hello</script>',
223
			$this->parser->parse('<script>[test_shortcode]hello[/test_shortcode]</script>')
224
		);
225
	}
226
227
	public function testFalseyArguments() {
228
		$this->parser->parse('<p>[test_shortcode falsey=0]');
229
230
		$this->assertEquals(array(
231
			'falsey' => '',
232
		), $this->arguments);
233
	}
234
235
	public function testNumericShortcodes() {
236
		$this->assertEqualsIgnoringWhitespace(
237
			'[2]',
238
			$this->parser->parse('[2]')
239
		);
240
		$this->assertEqualsIgnoringWhitespace(
241
			'<script>[2]</script>',
242
			$this->parser->parse('<script>[2]</script>')
243
		);
244
245
		$this->parser->register('2', function($attributes, $content, $this, $tag, $extra) {
0 ignored issues
show
Unused Code introduced by
The parameter $attributes is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $content is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $this is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $tag is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $extra is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
246
			return 'this is 2';
247
		});
248
249
		$this->assertEqualsIgnoringWhitespace(
250
			'this is 2',
251
			$this->parser->parse('[2]')
252
		);
253
		$this->assertEqualsIgnoringWhitespace(
254
			'<script>this is 2</script>',
255
			$this->parser->parse('<script>[2]</script>')
256
		);
257
258
		$this->parser->unregister('2');
259
	}
260
261
	public function testExtraContext() {
262
		$this->parser->parse('<a href="[test_shortcode]">Test</a>');
263
264
		$this->assertInstanceOf('DOMNode', $this->extra['node']);
265
		$this->assertInstanceOf('DOMElement', $this->extra['element']);
266
		$this->assertEquals($this->extra['element']->tagName, 'a');
267
	}
268
269
	public function testNoParseAttemptIfNoCode() {
270
		$stub = $this->getMock('ShortcodeParser', array('replaceElementTagsWithMarkers'));
271
		$stub->register('test', function() {
272
			return '';
273
		});
274
275
		$stub->expects($this->never())
276
			->method('replaceElementTagsWithMarkers')->will($this->returnValue(array('', '')));
277
278
		$stub->parse('<p>test</p>');
279
	}
280
281
	// -----------------------------------------------------------------------------------------------------------------
282
283
	/**
284
	 * Stores the result of a shortcode parse in object properties for easy testing access.
285
	 */
286
	public function shortcodeSaver($arguments, $content, $parser, $tagName, $extra) {
287
		$this->arguments = $arguments;
288
		$this->contents = $content;
289
		$this->tagName = $tagName;
290
		$this->extra = $extra;
291
292
		return $content;
293
	}
294
295
}
296