1<?php
2
3namespace Phalcon\Test\Unit\Annotations;
4
5use Phalcon\Annotations\Reader;
6use Phalcon\Test\Module\UnitTest;
7
8/**
9 * \Phalcon\Test\Unit\Annotations\ReaderTest
10 * Tests for \Phalcon\Annotations\Reader component
11 *
12 * @copyright (c) 2011-2017 Phalcon Team
13 * @link      https://phalconphp.com
14 * @author    Andres Gutierrez <andres@phalconphp.com>
15 * @author    Serghei Iakovlev <serghei@phalconphp.com>
16 * @package   Phalcon\Test\Unit\Annotations
17 *
18 * The contents of this file are subject to the New BSD License that is
19 * bundled with this package in the file LICENSE.txt
20 *
21 * If you did not receive a copy of the license and are unable to obtain it
22 * through the world-wide-web, please send an email to license@phalconphp.com
23 * so that we can send you a copy immediately.
24 */
25class ReaderTest extends UnitTest
26{
27    /**
28     * Test throws ReflectionException when non-existent got class
29     *
30     * @author Serghei Iakovlev <serghei@phalconphp.com>
31     * @since  2016-01-25
32     */
33    public function testParseWithNonExistentClass()
34    {
35        $this->specify(
36            "Reader::parse does not throws ReflectionException when non-existent got class",
37            function () {
38                $reader = new Reader();
39                $reader->parse('TestClass1');
40            },
41            ['throws' => ['ReflectionException', 'Class TestClass1 does not exist']]
42        );
43    }
44
45    /**
46     * Test throws Phalcon\Annotations\Exception when got class with invalid annotation
47     *
48     * @author Serghei Iakovlev <serghei@phalconphp.com>
49     * @since  2016-01-25
50     */
51    public function testParseWithInvalidAnnotation()
52    {
53        $this->specify(
54            "Reader::parse does not throws Phalcon\\Annotations\\Exception when got class with invalid annotation",
55            function () {
56                require_once PATH_DATA . 'annotations/TestInvalid.php';
57
58                $reader = new Reader();
59                $reader->parse('TestInvalid');
60            },
61            [
62                'throws' => [
63                    'Phalcon\Annotations\Exception',
64                    'Syntax error, unexpected EOF in ' . PATH_DATA . 'annotations/TestInvalid.php'
65                ]
66            ]
67        );
68    }
69
70    /**
71     * Tests Reader::parse
72     *
73     * @author Serghei Iakovlev <serghei@phalconphp.com>
74     * @since  2016-01-25
75     */
76    public function testReaderParse()
77    {
78        $this->specify(
79            "Reader::parse parses the annotations incorrectly",
80            function () {
81                require_once PATH_DATA . 'annotations/TestClass.php';
82
83                $reader = new Reader();
84                $parsing = $reader->parse('TestClass');
85
86                expect(isset($parsing['class']))->true();
87                expect($parsing['class'])->count(9);
88
89                // Simple
90                expect($parsing['class'][0]['name'])->equals('Simple');
91                expect(isset($parsing['class'][0]['arguments']))->false();
92
93                // Single Param
94                expect($parsing['class'][1]['name'])->equals('SingleParam');
95                expect(isset($parsing['class'][1]['arguments']))->true();
96                expect($parsing['class'][1]['arguments'])->count(1);
97                expect($parsing['class'][1]['arguments'][0]['expr']['value'])->equals('Param');
98
99                // Multiple Params
100                expect($parsing['class'][2]['name'])->equals('MultipleParams');
101                expect(isset($parsing['class'][2]['arguments']))->true();
102                expect($parsing['class'][2]['arguments'])->count(8);
103                expect($parsing['class'][2]['arguments'][0]['expr']['value'])->equals('First');
104                expect($parsing['class'][2]['arguments'][1]['expr']['value'])->equals('Second');
105                expect($parsing['class'][2]['arguments'][2]['expr']['value'])->equals('1');
106                expect($parsing['class'][2]['arguments'][3]['expr']['value'])->equals('1.1');
107                expect($parsing['class'][2]['arguments'][4]['expr']['value'])->equals('-10');
108                expect($parsing['class'][2]['arguments'][5]['expr']['type'])->equals(305);
109                expect($parsing['class'][2]['arguments'][6]['expr']['type'])->equals(306);
110                expect($parsing['class'][2]['arguments'][7]['expr']['type'])->equals(304);
111
112                // Single Array Param
113                expect($parsing['class'][3]['name'])->equals('Params');
114                expect(isset($parsing['class'][3]['arguments']))->true();
115                expect($parsing['class'][3]['arguments'])->count(1);
116                expect($parsing['class'][3]['arguments'][0]['expr']['type'])->equals(308);
117                expect($parsing['class'][3]['arguments'][0]['expr']['items'])->count(3);
118                expect($parsing['class'][3]['arguments'][0]['expr']['items'][0]['expr']['value'])->equals('key1');
119                expect($parsing['class'][3]['arguments'][0]['expr']['items'][1]['expr']['value'])->equals('key2');
120                expect($parsing['class'][3]['arguments'][0]['expr']['items'][2]['expr']['value'])->equals('key3');
121
122                // Hash Params
123                expect($parsing['class'][4]['name'])->equals('HashParams');
124                expect(isset($parsing['class'][4]['arguments']))->true();
125                expect($parsing['class'][4]['arguments'])->count(1);
126                expect($parsing['class'][4]['arguments'][0]['expr']['type'])->equals(308);
127                expect($parsing['class'][4]['arguments'][0]['expr']['items'])->count(3);
128                expect($parsing['class'][4]['arguments'][0]['expr']['items'][0]['name'])->equals('key1');
129                expect($parsing['class'][4]['arguments'][0]['expr']['items'][0]['expr']['value'])->equals('value');
130                expect($parsing['class'][4]['arguments'][0]['expr']['items'][1]['name'])->equals('key2');
131                expect($parsing['class'][4]['arguments'][0]['expr']['items'][1]['expr']['value'])->equals('value');
132                expect($parsing['class'][4]['arguments'][0]['expr']['items'][2]['name'])->equals('key3');
133                expect($parsing['class'][4]['arguments'][0]['expr']['items'][2]['expr']['value'])->equals('value');
134
135                // Named Params
136                expect($parsing['class'][5]['name'])->equals('NamedParams');
137                expect(isset($parsing['class'][5]['arguments']))->true();
138                expect($parsing['class'][5]['arguments'])->count(2);
139                expect($parsing['class'][5]['arguments'][0]['name'])->equals('first');
140                expect($parsing['class'][5]['arguments'][0]['expr']['value'])->equals('some');
141                expect($parsing['class'][5]['arguments'][1]['name'])->equals('second');
142                expect($parsing['class'][5]['arguments'][1]['expr']['value'])->equals('other');
143
144                // Alternative Named Params
145                expect($parsing['class'][6]['name'])->equals('AlternativeNamedParams');
146                expect(isset($parsing['class'][6]['arguments']))->true();
147                expect($parsing['class'][6]['arguments'])->count(2);
148                expect($parsing['class'][6]['arguments'][0]['name'])->equals('first');
149                expect($parsing['class'][6]['arguments'][0]['expr']['value'])->equals('some');
150                expect($parsing['class'][6]['arguments'][1]['name'])->equals('second');
151                expect($parsing['class'][6]['arguments'][1]['expr']['value'])->equals('other');
152
153                // Alternative Hash Params
154                expect($parsing['class'][7]['name'])->equals('AlternativeHashParams');
155                expect(isset($parsing['class'][7]['arguments']))->true();
156                expect($parsing['class'][7]['arguments'])->count(1);
157                expect($parsing['class'][7]['arguments'][0]['expr']['type'])->equals(308);
158                expect($parsing['class'][7]['arguments'][0]['expr']['items'])->count(3);
159                expect($parsing['class'][7]['arguments'][0]['expr']['items'][0]['name'])->equals('key1');
160                expect($parsing['class'][7]['arguments'][0]['expr']['items'][0]['expr']['value'])->equals('value');
161                expect($parsing['class'][7]['arguments'][0]['expr']['items'][1]['name'])->equals('key2');
162                expect($parsing['class'][7]['arguments'][0]['expr']['items'][1]['expr']['value'])->equals('value');
163                expect($parsing['class'][7]['arguments'][0]['expr']['items'][2]['name'])->equals('key3');
164                expect($parsing['class'][7]['arguments'][0]['expr']['items'][2]['expr']['value'])->equals('value');
165
166                // Recursive Hash
167                expect($parsing['class'][8]['name'])->equals('RecursiveHash');
168                expect(isset($parsing['class'][8]['arguments']))->true();
169                expect($parsing['class'][8]['arguments'])->count(1);
170                expect($parsing['class'][8]['arguments'][0]['expr']['type'])->equals(308);
171                expect($parsing['class'][8]['arguments'][0]['expr']['items'])->count(3);
172                expect($parsing['class'][8]['arguments'][0]['expr']['items'][0]['name'])->equals('key1');
173                expect($parsing['class'][8]['arguments'][0]['expr']['items'][0]['expr']['value'])->equals('value');
174                expect($parsing['class'][8]['arguments'][0]['expr']['items'][1]['name'])->equals('key2');
175                expect($parsing['class'][8]['arguments'][0]['expr']['items'][1]['expr']['value'])->equals('value');
176                expect($parsing['class'][8]['arguments'][0]['expr']['items'][2]['name'])->equals('key3');
177                expect($parsing['class'][8]['arguments'][0]['expr']['items'][2]['expr']['type'])->equals(308);
178
179                // Properties
180                expect(isset($parsing['properties']))->true();
181                expect($parsing['properties'])->count(3);
182
183                // Multiple well ordered annotations
184                expect(isset($parsing['properties']['testProp1']))->true();
185                expect($parsing['properties']['testProp1'])->count(4);
186                expect($parsing['properties']['testProp1'][0]['name'])->equals('var');
187                expect($parsing['properties']['testProp1'][1]['name'])->equals('Simple');
188                expect($parsing['properties']['testProp1'][2]['name'])->equals('SingleParam');
189                expect($parsing['properties']['testProp1'][3]['name'])->equals('MultipleParams');
190
191                // Comment without content
192                expect(isset($parsing['properties']['testProp2']))->false();
193
194                // Same line annotations
195                expect($parsing['properties']['testProp3'])->count(3);
196                expect($parsing['properties']['testProp3'][0]['name'])->equals('Simple');
197                expect($parsing['properties']['testProp3'][1]['name'])->equals('SingleParam');
198                expect($parsing['properties']['testProp3'][2]['name'])->equals('MultipleParams');
199
200                // Same line annotations
201                expect($parsing['properties']['testProp4'])->count(3);
202                expect($parsing['properties']['testProp4'][0]['name'])->equals('Simple');
203                expect($parsing['properties']['testProp4'][1]['name'])->equals('SingleParam');
204                expect($parsing['properties']['testProp4'][2]['name'])->equals('MultipleParams');
205
206                // No docblock
207                expect(isset($parsing['properties']['testProp5']))->false();
208
209                // No annotations
210                expect(isset($parsing['properties']['testProp6']))->false();
211
212                // Properties
213                expect(isset($parsing['methods']))->true();
214                expect($parsing['methods'])->count(4);
215
216                // Multiple well ordered annotations
217                expect(isset($parsing['methods']['testMethod1']))->true();
218                expect($parsing['methods']['testMethod1'])->count(5);
219                expect($parsing['methods']['testMethod1'][0]['name'])->equals('return');
220
221                expect($parsing['methods']['testMethod1'][1]['name'])->equals('Simple');
222                expect($parsing['methods']['testMethod1'][2]['name'])->equals('SingleParam');
223                expect($parsing['methods']['testMethod1'][3]['name'])->equals('MultipleParams');
224                expect($parsing['methods']['testMethod1'][4]['name'])->equals('NamedMultipleParams');
225
226                // Comment without content
227                expect(isset($parsing['methods']['testMethod2']))->false();
228
229                // Same line annotations
230                expect($parsing['methods']['testMethod3'])->count(3);
231                expect($parsing['methods']['testMethod3'][0]['name'])->equals('Simple');
232                expect($parsing['methods']['testMethod3'][1]['name'])->equals('SingleParam');
233                expect($parsing['methods']['testMethod3'][2]['name'])->equals('MultipleParams');
234
235                // Unordered annotations
236                expect($parsing['methods']['testMethod4'])->count(3);
237                expect($parsing['methods']['testMethod4'][0]['name'])->equals('Simple');
238                expect($parsing['methods']['testMethod4'][1]['name'])->equals('SingleParam');
239                expect($parsing['methods']['testMethod4'][2]['name'])->equals('MultipleParams');
240
241                // Unordered annotations + extra content
242                expect($parsing['methods']['testMethod5'])->count(3);
243                expect($parsing['methods']['testMethod5'][0]['name'])->equals('Simple');
244                expect($parsing['methods']['testMethod5'][1]['name'])->equals('SingleParam');
245                expect($parsing['methods']['testMethod5'][2]['name'])->equals('MultipleParams');
246            }
247        );
248    }
249}
250