GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( 8f3a65...0386f1 )
by Tomasz
12s
created

ParserTest::assertShortcodes()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 13
rs 9.8333
c 0
b 0
f 0
cc 2
nc 2
nop 2
1
<?php
2
namespace Thunder\Shortcode\Tests;
3
4
use Thunder\Shortcode\HandlerContainer\HandlerContainer;
5
use Thunder\Shortcode\Parser\RegularParser;
6
use Thunder\Shortcode\Parser\ParserInterface;
7
use Thunder\Shortcode\Parser\RegexParser;
8
use Thunder\Shortcode\Parser\WordpressParser;
9
use Thunder\Shortcode\Shortcode\ParsedShortcode;
10
use Thunder\Shortcode\Shortcode\Shortcode;
11
use Thunder\Shortcode\Syntax\CommonSyntax;
12
use Thunder\Shortcode\Syntax\Syntax;
13
14
/**
15
 * @author Tomasz Kowalczyk <[email protected]>
16
 */
17
final class ParserTest extends AbstractTestCase
18
{
19
    /**
20
     * @param ParserInterface $parser
21
     * @param string $code
22
     * @param ParsedShortcode[] $expected
23
     *
24
     * @dataProvider provideShortcodes
25
     */
26
    public function testParser(ParserInterface $parser, $code, array $expected)
27
    {
28
        $this->assertShortcodes($parser->parse($code), $expected);
29
    }
30
31
    private function assertShortcodes(array $actual, array $expected)
32
    {
33
        $count = count($actual);
34
        static::assertCount($count, $expected, 'counts');
0 ignored issues
show
Documentation introduced by
$expected is of type array, but the function expects a object<Countable>|object...nit\Framework\iterable>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
35
        for ($i = 0; $i < $count; $i++) {
36
            static::assertSame($actual[$i]->getName(), $expected[$i]->getName(), 'name');
37
            static::assertSame($actual[$i]->getParameters(), $expected[$i]->getParameters(), 'parameters');
38
            static::assertSame($actual[$i]->getContent(), $expected[$i]->getContent(), 'content');
39
            static::assertSame($actual[$i]->getText(), $expected[$i]->getText(), 'text');
40
            static::assertSame($actual[$i]->getOffset(), $expected[$i]->getOffset(), 'offset');
41
            static::assertSame($actual[$i]->getBbCode(), $expected[$i]->getBbCode(), 'bbCode');
42
        }
43
    }
44
45
    public function provideShortcodes()
46
    {
47
        $s = new CommonSyntax();
48
49
        $tests = array(
50
            // invalid
51
            array($s, '', array()),
52
            array($s, '[]', array()),
53
            array($s, '![](image.jpg)', array()),
54
            array($s, 'x html([a. title][, alt][, classes]) x', array()),
55
            array($s, '[/y]', array()),
56
            array($s, '[sc', array()),
57
            array($s, '[sc / [/sc]', array()),
58
            array($s, '[sc arg="val', array()),
59
60
            // single shortcodes
61
            array($s, '[sc]', array(
62
                new ParsedShortcode(new Shortcode('sc', array(), null), '[sc]', 0),
63
            )),
64
            array($s, '[sc arg=val]', array(
65
                new ParsedShortcode(new Shortcode('sc', array('arg' => 'val'), null), '[sc arg=val]', 0),
66
            )),
67
            array($s, '[sc novalue arg="complex value"]', array(
68
                new ParsedShortcode(new Shortcode('sc', array('novalue' => null, 'arg' => 'complex value'), null), '[sc novalue arg="complex value"]', 0),
69
            )),
70
            array($s, '[sc x="ąćęłńóśżź ĄĆĘŁŃÓŚŻŹ"]', array(
71
                new ParsedShortcode(new Shortcode('sc', array('x' => 'ąćęłńóśżź ĄĆĘŁŃÓŚŻŹ'), null), '[sc x="ąćęłńóśżź ĄĆĘŁŃÓŚŻŹ"]', 0),
72
            )),
73
            array($s, '[sc x="multi'."\n".'line"]', array(
74
                new ParsedShortcode(new Shortcode('sc', array('x' => 'multi'."\n".'line'), null), '[sc x="multi'."\n".'line"]', 0),
75
            )),
76
            array($s, '[sc noval x="val" y]content[/sc]', array(
77
                new ParsedShortcode(new Shortcode('sc', array('noval' => null, 'x' => 'val', 'y' => null), 'content'), '[sc noval x="val" y]content[/sc]', 0),
78
            )),
79
            array($s, '[sc x="{..}"]', array(
80
                new ParsedShortcode(new Shortcode('sc', array('x' => '{..}'), null), '[sc x="{..}"]', 0),
81
            )),
82
            array($s, '[sc a="x y" b="x" c=""]', array(
83
                new ParsedShortcode(new Shortcode('sc', array('a' => 'x y', 'b' => 'x', 'c' => ''), null), '[sc a="x y" b="x" c=""]', 0),
84
            )),
85
            array($s, '[sc a="a \"\" b"]', array(
86
                new ParsedShortcode(new Shortcode('sc', array('a' => 'a \"\" b'), null), '[sc a="a \"\" b"]', 0),
87
            )),
88
            array($s, '[sc/]', array(
89
                new ParsedShortcode(new Shortcode('sc', array(), null), '[sc/]', 0),
90
            )),
91
            array($s, '[sc    /]', array(
92
                new ParsedShortcode(new Shortcode('sc', array(), null), '[sc    /]', 0),
93
            )),
94
            array($s, '[sc arg=val cmp="a b"/]', array(
95
                new ParsedShortcode(new Shortcode('sc', array('arg' => 'val', 'cmp' => 'a b'), null), '[sc arg=val cmp="a b"/]', 0),
96
            )),
97
            array($s, '[sc x y   /]', array(
98
                new ParsedShortcode(new Shortcode('sc', array('x' => null, 'y' => null), null), '[sc x y   /]', 0),
99
            )),
100
            array($s, '[sc  x="\ "   /]', array(
101
                new ParsedShortcode(new Shortcode('sc', array('x' => '\ '), null), '[sc  x="\ "   /]', 0),
102
            )),
103
            array($s, '[   sc   x =  "\ "   y =   value  z   /    ]', array(
104
                new ParsedShortcode(new Shortcode('sc', array('x' => '\ ', 'y' => 'value', 'z' => null), null), '[   sc   x =  "\ "   y =   value  z   /    ]', 0),
105
            )),
106
            array($s, '[ sc   x=  "\ "   y    =value   ] vv [ /  sc  ]', array(
107
                new ParsedShortcode(new Shortcode('sc', array('x' => '\ ', 'y' => 'value'), ' vv '), '[ sc   x=  "\ "   y    =value   ] vv [ /  sc  ]', 0),
108
            )),
109
            array($s, '[sc url="http://giggle.com/search" /]', array(
110
                new ParsedShortcode(new Shortcode('sc', array('url' => 'http://giggle.com/search'), null), '[sc url="http://giggle.com/search" /]', 0),
111
            )),
112
113
            // bbcode
114
            array($s, '[sc   =   "http://giggle.com/search" /]', array(
115
                new ParsedShortcode(new Shortcode('sc', array(), null, 'http://giggle.com/search'), '[sc   =   "http://giggle.com/search" /]', 0),
116
            )),
117
118
            // multiple shortcodes
119
            array($s, 'Lorem [ipsum] random [code-code arg=val] which is here', array(
120
                new ParsedShortcode(new Shortcode('ipsum', array(), null), '[ipsum]', 6),
121
                new ParsedShortcode(new Shortcode('code-code', array('arg' => 'val'), null), '[code-code arg=val]', 21),
122
            )),
123
            array($s, 'x [aa] x [aa] x', array(
124
                new ParsedShortcode(new Shortcode('aa', array(), null), '[aa]', 2),
125
                new ParsedShortcode(new Shortcode('aa', array(), null), '[aa]', 9),
126
            )),
127
            array($s, 'x [x]a[/x] x [x]a[/x] x', array(
128
                new ParsedShortcode(new Shortcode('x', array(), 'a'), '[x]a[/x]', 2),
129
                new ParsedShortcode(new Shortcode('x', array(), 'a'), '[x]a[/x]', 13),
130
            )),
131
            array($s, 'x [x x y=z a="b c"]a[/x] x [x x y=z a="b c"]a[/x] x', array(
132
                new ParsedShortcode(new Shortcode('x', array('x' => null, 'y' => 'z', 'a' => 'b c'), 'a'), '[x x y=z a="b c"]a[/x]', 2),
133
                new ParsedShortcode(new Shortcode('x', array('x' => null, 'y' => 'z', 'a' => 'b c'), 'a'), '[x x y=z a="b c"]a[/x]', 27),
134
            )),
135
            array($s, 'x [code /] y [code]z[/code] x [code] y [code/] a', array(
136
                new ParsedShortcode(new Shortcode('code', array(), null), '[code /]', 2),
137
                new ParsedShortcode(new Shortcode('code', array(), 'z'), '[code]z[/code]', 13),
138
                new ParsedShortcode(new Shortcode('code', array(), null), '[code]', 30),
139
                new ParsedShortcode(new Shortcode('code', array(), null), '[code/]', 39),
140
            )),
141
            array($s, 'x [code arg=val /] y [code cmp="xx"/] x [code x=y/] a', array(
142
                new ParsedShortcode(new Shortcode('code', array('arg' => 'val'), null), '[code arg=val /]', 2),
143
                new ParsedShortcode(new Shortcode('code', array('cmp' => 'xx'), null), '[code cmp="xx"/]', 21),
144
                new ParsedShortcode(new Shortcode('code', array('x' => 'y'), null), '[code x=y/]', 40),
145
            )),
146
            array($s, 'x [    code arg=val /]a[ code/]c[x    /    ] m [ y ] c [   /   y]', array(
147
                new ParsedShortcode(new Shortcode('code', array('arg' => 'val'), null), '[    code arg=val /]', 2),
148
                new ParsedShortcode(new Shortcode('code', array(), null), '[ code/]', 23),
149
                new ParsedShortcode(new Shortcode('x', array(), null), '[x    /    ]', 32),
150
                new ParsedShortcode(new Shortcode('y', array(), ' c '), '[ y ] c [   /   y]', 47),
151
            )),
152
153
            // other syntax
154
            array(new Syntax('[[', ']]', '//', '==', '""'), '[[code arg==""val oth""]]cont[[//code]]', array(
155
                new ParsedShortcode(new Shortcode('code', array('arg' => 'val oth'), 'cont'), '[[code arg==""val oth""]]cont[[//code]]', 0),
156
            )),
157
            array(new Syntax('^', '$', '&', '!!!', '@@'), '^code a!!!@@\"\"@@ b!!!@@x\"y@@ c$cnt^&code$', array(
158
                new ParsedShortcode(new Shortcode('code', array('a' => '\"\"', 'b' => 'x\"y', 'c' => null), 'cnt'), '^code a!!!@@\"\"@@ b!!!@@x\"y@@ c$cnt^&code$', 0),
159
            )),
160
161
            // UTF-8 sequences
162
            array($s, '’’’’[sc]’’[sc]', array(
163
                new ParsedShortcode(new Shortcode('sc', array(), null), '[sc]', 4),
164
                new ParsedShortcode(new Shortcode('sc', array(), null), '[sc]', 10),
165
            )),
166
167
            // performance
0 ignored issues
show
Unused Code Comprehensibility introduced by
65% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
168
//            array($s, 'x [[aa]] y', array()),
169
            array($s, str_repeat('[a]', 20), array_map(function($offset) { // 20
170
                return new ParsedShortcode(new Shortcode('a', array(), null), '[a]', $offset);
171
            }, range(0, 57, 3))),
172
            array($s, '[b][a]x[a][/a][/a][/b] [b][a][a][/a]y[/a][/b]', array(
173
                new ParsedShortcode(new Shortcode('b', array(), '[a]x[a][/a][/a]'), '[b][a]x[a][/a][/a][/b]', 0),
174
                new ParsedShortcode(new Shortcode('b', array(), '[a][a][/a]y[/a]'), '[b][a][a][/a]y[/a][/b]', 23),
175
            )),
176
            array($s, '[b] [a][a][a] [/b] [b] [a][a][a] [/b]', array(
177
                new ParsedShortcode(new Shortcode('b', array(), ' [a][a][a] '), '[b] [a][a][a] [/b]', 0),
178
                new ParsedShortcode(new Shortcode('b', array(), ' [a][a][a] '), '[b] [a][a][a] [/b]', 19),
179
            )),
180
            array($s, '[name]random[/other]', array(
181
                new ParsedShortcode(new Shortcode('name', array(), null), '[name]', 0),
182
            )),
183
            array($s, '[0][1][2][3]', array(
184
                new ParsedShortcode(new Shortcode('0', array(), null), '[0]', 0),
185
                new ParsedShortcode(new Shortcode('1', array(), null), '[1]', 3),
186
                new ParsedShortcode(new Shortcode('2', array(), null), '[2]', 6),
187
                new ParsedShortcode(new Shortcode('3', array(), null), '[3]', 9),
188
            )),
189
            array($s, '[_][na_me][_name][name_][n_am_e][_n_]', array(
190
                new ParsedShortcode(new Shortcode('_', array(), null), '[_]', 0),
191
                new ParsedShortcode(new Shortcode('na_me', array(), null), '[na_me]', 3),
192
                new ParsedShortcode(new Shortcode('_name', array(), null), '[_name]', 10),
193
                new ParsedShortcode(new Shortcode('name_', array(), null), '[name_]', 17),
194
                new ParsedShortcode(new Shortcode('n_am_e', array(), null), '[n_am_e]', 24),
195
                new ParsedShortcode(new Shortcode('_n_', array(), null), '[_n_]', 32),
196
            )),
197
            array($s, '[x]/[/x] [x]"[/x] [x]=[/x] [x]][/x] [x] [/x] [x]x[/x]', array(
198
                new ParsedShortcode(new Shortcode('x', array(), '/'), '[x]/[/x]', 0),
199
                new ParsedShortcode(new Shortcode('x', array(), '"'), '[x]"[/x]', 9),
200
                new ParsedShortcode(new Shortcode('x', array(), '='), '[x]=[/x]', 18),
201
                new ParsedShortcode(new Shortcode('x', array(), ']'), '[x]][/x]', 27),
202
                new ParsedShortcode(new Shortcode('x', array(), ' '), '[x] [/x]', 36),
203
                new ParsedShortcode(new Shortcode('x', array(), 'x'), '[x]x[/x]', 45),
204
            )),
205
            array($s, '[a]0[/a]', array(
206
                new ParsedShortcode(new Shortcode('a', array(), '0'), '[a]0[/a]', 0),
207
            )),
208
            array($s, '[fa icon=fa-camera /] [fa icon=fa-camera extras=fa-4x /]', array(
209
                new ParsedShortcode(new Shortcode('fa', array('icon' => 'fa-camera'), null), '[fa icon=fa-camera /]', 0),
210
                new ParsedShortcode(new Shortcode('fa', array('icon' => 'fa-camera', 'extras' => 'fa-4x'), null), '[fa icon=fa-camera extras=fa-4x /]', 22),
211
            )),
212
            array($s, '[fa icon=fa-circle-o-notch extras=fa-spin,fa-3x /]', array(
213
                new ParsedShortcode(new Shortcode('fa', array('icon' => 'fa-circle-o-notch', 'extras' => 'fa-spin,fa-3x'), null), '[fa icon=fa-circle-o-notch extras=fa-spin,fa-3x /]', 0),
214
            )),
215
            array($s, '[z =]', array()),
216
            array($s, '[x=#F00 one=#F00 two="#F00"]', array(
217
                new ParsedShortcode(new Shortcode('x', array('one' => '#F00', 'two' => '#F00'), null, '#F00'), '[x=#F00 one=#F00 two="#F00"]', 0),
218
            )),
219
            array($s, '[*] [* xyz arg=val]', array(
220
                new ParsedShortcode(new Shortcode('*', array(), null, null), '[*]', 0),
221
                new ParsedShortcode(new Shortcode('*', array('xyz' => null, 'arg' => 'val'), null, null), '[* xyz arg=val]', 4),
222
            )),
223
            array($s, '[*=bb x=y]cnt[/*]', array(
224
                new ParsedShortcode(new Shortcode('*', array('x' => 'y'), 'cnt', 'bb'), '[*=bb x=y]cnt[/*]', 0),
225
            )),
226
            array($s, '[ [] ] [x] [ ] [/x] ] [] [ [y] ] [] [ [z] [/#] [/z] [ [] ] [/] [/y] ] [z] [ [/ [/] /] ] [/z]', array(
227
                new ParsedShortcode(new Shortcode('x', array(), ' [ ] ', null), '[x] [ ] [/x]', 7),
228
                new ParsedShortcode(new Shortcode('y', array(), ' ] [] [ [z] [/#] [/z] [ [] ] [/] ', null), '[y] ] [] [ [z] [/#] [/z] [ [] ] [/] [/y]', 27),
229
                new ParsedShortcode(new Shortcode('z', array(), ' [ [/ [/] /] ] ', null), '[z] [ [/ [/] /] ] [/z]', 70),
230
            )),
231
            // falsy string values
232
            array($s, '[a=0 b=0]0[/a]', array(
233
                new ParsedShortcode(new Shortcode('a', array('b' => '0'), '0', '0'), '[a=0 b=0]0[/a]', 0),
234
            )),
235
        );
236
237
        /**
238
         * WordPress can't handle:
239
         *   - incorrect shortcode opening tag (blindly matches everything
240
         *     between opening token and closing token)
241
         *   - spaces between shortcode open tag and its name ([  name]),
242
         *   - spaces around BBCode part ([name  = "bbcode"]),
243
         *   - escaped tokens anywhere in the arguments ([x arg=" \" "]),
244
         *   - configurable syntax (that's intended),
245
         *   - numbers in shortcode name.
246
         *
247
         * Tests cases from array above with identifiers in the array below must be skipped.
248
         */
249
        $wordpressSkip = array(3, 6, 16, 21, 22, 23, 25, 32, 33, 34, 46, 47, 49, 51);
250
        $result = array();
251
        foreach($tests as $key => $test) {
252
            $syntax = array_shift($test);
253
254
            $result[] = array_merge(array(new RegexParser($syntax)), $test);
255
            $result[] = array_merge(array(new RegularParser($syntax)), $test);
256
            if(!in_array($key, $wordpressSkip, true)) {
257
                $result[] = array_merge(array(new WordpressParser()), $test);
258
            }
259
        }
260
261
        return $result;
262
    }
263
264
    public function testIssue77()
265
    {
266
        $parser = new RegularParser();
267
268
        $this->assertShortcodes($parser->parse('[a][x][/x][x k="v][/x][y]x[/y]'), array(
269
            new ParsedShortcode(new Shortcode('a', array(), null, null), '[a]', 0),
270
            new ParsedShortcode(new Shortcode('x', array(), '', null), '[x][/x]', 3),
271
            new ParsedShortcode(new Shortcode('y', array(), 'x', null), '[y]x[/y]', 22),
272
        ));
273
274
        $this->assertShortcodes($parser->parse('[a k="v][x][/x]'), array(
275
            new ParsedShortcode(new Shortcode('x', array(), '', null), '[x][/x]', 8),
276
        ));
277
    }
278
279
    public function testWordPress()
280
    {
281
        $parser = new WordpressParser();
282
283
        $this->testParser($parser, '[code arg="<html" oth=\'val\']', array(
284
            new ParsedShortcode(new Shortcode('code', array('arg' => '', 'oth' => 'val'), null), '[code arg="<html" oth=\'val\']', 0)
285
        ));
286
        $this->testParser($parser, '[code "xxx"]', array(
287
            new ParsedShortcode(new Shortcode('code', array('xxx' => null), null, null), '[code "xxx"]', 0)
288
        ));
289
        $this->testParser($parser, '[code="xxx"] [code=yyy-aaa]', array(
290
            new ParsedShortcode(new Shortcode('code', array('="xxx"' => null), null), '[code="xxx"]', 0),
291
            new ParsedShortcode(new Shortcode('code', array('=yyy-aaa' => null), null), '[code=yyy-aaa]', 13)
292
        ));
293
294
        $handlers = new HandlerContainer();
295
        $handlers->add('_', function() {});
296
        $handlers->add('na_me', function() {});
297
        $handlers->add('_n_', function() {});
298
        $this->testParser(WordpressParser::createFromHandlers($handlers), '[_][na_me][_name][name_][n_am_e][_n_]', array(
299
            new ParsedShortcode(new Shortcode('_', array(), null), '[_]', 0),
300
            new ParsedShortcode(new Shortcode('na_me', array(), null), '[na_me]', 3),
301
            new ParsedShortcode(new Shortcode('_n_', array(), null), '[_n_]', 32),
302
        ));
303
        $this->testParser(WordpressParser::createFromNames(array('_', 'na_me', '_n_')), '[_][na_me][_name][name_][n_am_e][_n_]', array(
304
            new ParsedShortcode(new Shortcode('_', array(), null), '[_]', 0),
305
            new ParsedShortcode(new Shortcode('na_me', array(), null), '[na_me]', 3),
306
            new ParsedShortcode(new Shortcode('_n_', array(), null), '[_n_]', 32),
307
        ));
308
    }
309
310
    public function testWordpressInvalidNamesException()
311
    {
312
        $this->willThrowException('InvalidArgumentException');
313
        WordpressParser::createFromNames(array('string', new \stdClass()));
314
    }
315
316
    public function testInstances()
317
    {
318
        static::assertInstanceOf('Thunder\Shortcode\Parser\WordPressParser', new WordpressParser());
319
        static::assertInstanceOf('Thunder\Shortcode\Parser\RegularParser', new RegularParser());
320
    }
321
}
322