Skip to content

Commit 2a3d64f

Browse files
committed
File::getTokensAsString(): add tests
This imports the tests which were already in use in PHPCSUtils into PHP_CodeSniffer.
1 parent 1150bc4 commit 2a3d64f

File tree

2 files changed

+362
-0
lines changed

2 files changed

+362
-0
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
/* testNamespace */
4+
namespace Foo\Bar\Baz;
5+
6+
/* testUseWithComments */
7+
use Foo /*comment*/ \ Bar
8+
// phpcs:ignore Stnd.Cat.Sniff -- For reasons.
9+
\ Bah;
10+
11+
$cl = function() {
12+
/* testCalculation */
13+
return 1 + 2 +
14+
// Comment.
15+
3 + 4
16+
+ 5 + 6 + 7 > 20;
17+
}
18+
19+
/* testEchoWithTabs */
20+
echo 'foo',
21+
'bar' ,
22+
'baz';
23+
24+
/* testEndOfFile */
25+
echo $foo;
Lines changed: 337 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,337 @@
1+
<?php
2+
/**
3+
* Tests for the \PHP_CodeSniffer\Files\File::getTokensAsString method.
4+
*
5+
* @author Juliette Reinders Folmer <[email protected]>
6+
* @copyright 2022-2024 PHPCSStandards Contributors
7+
* @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
8+
*/
9+
10+
namespace PHP_CodeSniffer\Tests\Core\File;
11+
12+
use PHP_CodeSniffer\Exceptions\RuntimeException;
13+
use PHP_CodeSniffer\Tests\Core\AbstractMethodUnitTest;
14+
15+
/**
16+
* Tests for the \PHP_CodeSniffer\Files\File:getTokensAsString method.
17+
*
18+
* @covers \PHP_CodeSniffer\Files\File::getTokensAsString
19+
*/
20+
class GetTokensAsStringTest extends AbstractMethodUnitTest
21+
{
22+
23+
24+
/**
25+
* Test passing a non-existent token pointer.
26+
*
27+
* @return void
28+
*/
29+
public function testNonExistentToken()
30+
{
31+
$this->expectException(RuntimeException::class);
32+
$this->expectExceptionMessage('The $start position for getTokensAsString() must exist in the token stack');
33+
34+
self::$phpcsFile->getTokensAsString(100000, 10);
35+
36+
}//end testNonExistentToken()
37+
38+
39+
/**
40+
* Test passing a non integer `$start`, like the result of a failed $phpcsFile->findNext().
41+
*
42+
* @return void
43+
*/
44+
public function testNonIntegerStart()
45+
{
46+
$this->expectException(RuntimeException::class);
47+
$this->expectExceptionMessage('The $start position for getTokensAsString() must exist in the token stack');
48+
49+
self::$phpcsFile->getTokensAsString(false, 10);
50+
51+
}//end testNonIntegerStart()
52+
53+
54+
/**
55+
* Test passing a non integer `$length`.
56+
*
57+
* @return void
58+
*/
59+
public function testNonIntegerLength()
60+
{
61+
$result = self::$phpcsFile->getTokensAsString(10, false);
62+
$this->assertSame('', $result);
63+
64+
$result = self::$phpcsFile->getTokensAsString(10, 1.5);
65+
$this->assertSame('', $result);
66+
67+
}//end testNonIntegerLength()
68+
69+
70+
/**
71+
* Test passing a zero or negative `$length`.
72+
*
73+
* @return void
74+
*/
75+
public function testLengthEqualToOrLessThanZero()
76+
{
77+
$result = self::$phpcsFile->getTokensAsString(10, -10);
78+
$this->assertSame('', $result);
79+
80+
$result = self::$phpcsFile->getTokensAsString(10, 0);
81+
$this->assertSame('', $result);
82+
83+
}//end testLengthEqualToOrLessThanZero()
84+
85+
86+
/**
87+
* Test passing a `$length` beyond the end of the file.
88+
*
89+
* @return void
90+
*/
91+
public function testLengthBeyondEndOfFile()
92+
{
93+
$semicolon = $this->getTargetToken('/* testEndOfFile */', T_SEMICOLON);
94+
$result = self::$phpcsFile->getTokensAsString($semicolon, 20);
95+
$this->assertSame(
96+
';
97+
',
98+
$result
99+
);
100+
101+
}//end testLengthBeyondEndOfFile()
102+
103+
104+
/**
105+
* Test getting a token set as a string.
106+
*
107+
* @param string $testMarker The comment which prefaces the target token in the test file.
108+
* @param int|string $startTokenType The type of token(s) to look for for the start of the string.
109+
* @param int $length Token length to get.
110+
* @param string $expected The expected function return value.
111+
*
112+
* @dataProvider dataGetTokensAsString()
113+
*
114+
* @return void
115+
*/
116+
public function testGetTokensAsString($testMarker, $startTokenType, $length, $expected)
117+
{
118+
$start = $this->getTargetToken($testMarker, $startTokenType);
119+
$result = self::$phpcsFile->getTokensAsString($start, $length);
120+
$this->assertSame($expected, $result);
121+
122+
}//end testGetTokensAsString()
123+
124+
125+
/**
126+
* Data provider.
127+
*
128+
* @see testGetTokensAsString() For the array format.
129+
*
130+
* @return array<string, array<string, string|int>>
131+
*/
132+
public static function dataGetTokensAsString()
133+
{
134+
return [
135+
'length-0' => [
136+
'testMarker' => '/* testCalculation */',
137+
'startTokenType' => T_LNUMBER,
138+
'length' => 0,
139+
'expected' => '',
140+
],
141+
'length-1' => [
142+
'testMarker' => '/* testCalculation */',
143+
'startTokenType' => T_LNUMBER,
144+
'length' => 1,
145+
'expected' => '1',
146+
],
147+
'length-2' => [
148+
'testMarker' => '/* testCalculation */',
149+
'startTokenType' => T_LNUMBER,
150+
'length' => 2,
151+
'expected' => '1 ',
152+
],
153+
'length-3' => [
154+
'testMarker' => '/* testCalculation */',
155+
'startTokenType' => T_LNUMBER,
156+
'length' => 3,
157+
'expected' => '1 +',
158+
],
159+
'length-4' => [
160+
'testMarker' => '/* testCalculation */',
161+
'startTokenType' => T_LNUMBER,
162+
'length' => 4,
163+
'expected' => '1 + ',
164+
],
165+
'length-5' => [
166+
'testMarker' => '/* testCalculation */',
167+
'startTokenType' => T_LNUMBER,
168+
'length' => 5,
169+
'expected' => '1 + 2',
170+
],
171+
'length-6' => [
172+
'testMarker' => '/* testCalculation */',
173+
'startTokenType' => T_LNUMBER,
174+
'length' => 6,
175+
'expected' => '1 + 2 ',
176+
],
177+
'length-7' => [
178+
'testMarker' => '/* testCalculation */',
179+
'startTokenType' => T_LNUMBER,
180+
'length' => 7,
181+
'expected' => '1 + 2 +',
182+
],
183+
'length-8' => [
184+
'testMarker' => '/* testCalculation */',
185+
'startTokenType' => T_LNUMBER,
186+
'length' => 8,
187+
'expected' => '1 + 2 +
188+
',
189+
],
190+
'length-9' => [
191+
'testMarker' => '/* testCalculation */',
192+
'startTokenType' => T_LNUMBER,
193+
'length' => 9,
194+
'expected' => '1 + 2 +
195+
',
196+
],
197+
'length-10' => [
198+
'testMarker' => '/* testCalculation */',
199+
'startTokenType' => T_LNUMBER,
200+
'length' => 10,
201+
'expected' => '1 + 2 +
202+
// Comment.
203+
',
204+
],
205+
'length-11' => [
206+
'testMarker' => '/* testCalculation */',
207+
'startTokenType' => T_LNUMBER,
208+
'length' => 11,
209+
'expected' => '1 + 2 +
210+
// Comment.
211+
',
212+
],
213+
'length-12' => [
214+
'testMarker' => '/* testCalculation */',
215+
'startTokenType' => T_LNUMBER,
216+
'length' => 12,
217+
'expected' => '1 + 2 +
218+
// Comment.
219+
3',
220+
],
221+
'length-13' => [
222+
'testMarker' => '/* testCalculation */',
223+
'startTokenType' => T_LNUMBER,
224+
'length' => 13,
225+
'expected' => '1 + 2 +
226+
// Comment.
227+
3 ',
228+
],
229+
'length-14' => [
230+
'testMarker' => '/* testCalculation */',
231+
'startTokenType' => T_LNUMBER,
232+
'length' => 14,
233+
'expected' => '1 + 2 +
234+
// Comment.
235+
3 +',
236+
],
237+
'length-34' => [
238+
'testMarker' => '/* testCalculation */',
239+
'startTokenType' => T_LNUMBER,
240+
'length' => 34,
241+
'expected' => '1 + 2 +
242+
// Comment.
243+
3 + 4
244+
+ 5 + 6 + 7 > 20;',
245+
],
246+
'namespace' => [
247+
'testMarker' => '/* testNamespace */',
248+
'startTokenType' => T_NAMESPACE,
249+
'length' => 4,
250+
'expected' => 'namespace Foo\Bar\Baz;',
251+
],
252+
'use-with-comments' => [
253+
'testMarker' => '/* testUseWithComments */',
254+
'startTokenType' => T_USE,
255+
'length' => 17,
256+
'expected' => 'use Foo /*comment*/ \ Bar
257+
// phpcs:ignore Stnd.Cat.Sniff -- For reasons.
258+
\ Bah;',
259+
],
260+
'echo-with-tabs' => [
261+
'testMarker' => '/* testEchoWithTabs */',
262+
'startTokenType' => T_ECHO,
263+
'length' => 13,
264+
'expected' => 'echo \'foo\',
265+
\'bar\' ,
266+
\'baz\';',
267+
],
268+
'end-of-file' => [
269+
'testMarker' => '/* testEndOfFile */',
270+
'startTokenType' => T_ECHO,
271+
'length' => 4,
272+
'expected' => 'echo $foo;',
273+
],
274+
];
275+
276+
}//end dataGetTokensAsString()
277+
278+
279+
/**
280+
* Test getting a token set as a string with the original, non tab-replaced content.
281+
*
282+
* @param string $testMarker The comment which prefaces the target token in the test file.
283+
* @param int|string $startTokenType The type of token(s) to look for for the start of the string.
284+
* @param int $length Token length to get.
285+
* @param string $expected The expected function return value.
286+
*
287+
* @dataProvider dataGetOrigContent()
288+
*
289+
* @return void
290+
*/
291+
public function testGetOrigContent($testMarker, $startTokenType, $length, $expected)
292+
{
293+
$start = $this->getTargetToken($testMarker, $startTokenType);
294+
$result = self::$phpcsFile->getTokensAsString($start, $length, true);
295+
$this->assertSame($expected, $result);
296+
297+
}//end testGetOrigContent()
298+
299+
300+
/**
301+
* Data provider.
302+
*
303+
* @see testGetOrigContent() For the array format.
304+
*
305+
* @return array<string, array<string, string|int>>
306+
*/
307+
public static function dataGetOrigContent()
308+
{
309+
return [
310+
'use-with-comments' => [
311+
'testMarker' => '/* testUseWithComments */',
312+
'startTokenType' => T_USE,
313+
'length' => 17,
314+
'expected' => 'use Foo /*comment*/ \ Bar
315+
// phpcs:ignore Stnd.Cat.Sniff -- For reasons.
316+
\ Bah;',
317+
],
318+
'echo-with-tabs' => [
319+
'testMarker' => '/* testEchoWithTabs */',
320+
'startTokenType' => T_ECHO,
321+
'length' => 13,
322+
'expected' => 'echo \'foo\',
323+
\'bar\' ,
324+
\'baz\';',
325+
],
326+
'end-of-file' => [
327+
'testMarker' => '/* testEndOfFile */',
328+
'startTokenType' => T_ECHO,
329+
'length' => 4,
330+
'expected' => 'echo $foo;',
331+
],
332+
];
333+
334+
}//end dataGetOrigContent()
335+
336+
337+
}//end class

0 commit comments

Comments
 (0)