Skip to content

Commit d180eb0

Browse files
authored
Merge pull request #220 from PHPCSStandards/feature/file-gettokensasstring-add-tests
File::getTokensAsString(): add tests
2 parents fe453f8 + 88d5c91 commit d180eb0

File tree

3 files changed

+372
-1
lines changed

3 files changed

+372
-1
lines changed

tests/Core/AbstractMethodUnitTest.php

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,15 @@ abstract class AbstractMethodUnitTest extends TestCase
2828
*/
2929
protected static $fileExtension = 'inc';
3030

31+
/**
32+
* The tab width setting to use when tokenizing the file.
33+
*
34+
* This allows for test case files to use a different tab width than the default.
35+
*
36+
* @var integer
37+
*/
38+
protected static $tabWidth = 4;
39+
3140
/**
3241
* The \PHP_CodeSniffer\Files\File object containing the parsed contents of the test case file.
3342
*
@@ -63,7 +72,10 @@ public static function initializeFile()
6372
self::setStaticConfigProperty('configData', ['report_width' => 80]);
6473
self::setStaticConfigProperty('configDataFile', '');
6574

66-
$config = new Config();
75+
$config = new Config();
76+
// Also set a tab-width to enable testing tab-replaced vs `orig_content`.
77+
$config->tabWidth = static::$tabWidth;
78+
6779
$ruleset = new Ruleset($config);
6880

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

0 commit comments

Comments
 (0)