Skip to content

Commit 3ede1c4

Browse files
committed
Add more tests for rejecting invalid selectors.
Also reject selectors that comprise only whitespace.
1 parent 283ed48 commit 3ede1c4

File tree

2 files changed

+50
-10
lines changed

2 files changed

+50
-10
lines changed

src/RuleSet/DeclarationBlock.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,7 @@ private static function parseSelector(ParserState $parserState, array &$comments
354354
throw new UnexpectedTokenException(')', $nextCharacter);
355355
}
356356

357-
$selector = \implode('', $selectorParts);
357+
$selector = \trim(\implode('', $selectorParts));
358358
if ($selector === '') {
359359
throw new UnexpectedTokenException('selector', $nextCharacter, 'literal', $parserState->currentLine());
360360
}

tests/Unit/RuleSet/DeclarationBlockTest.php

Lines changed: 49 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -226,23 +226,44 @@ public function parseExtractsTwoCommentsFromSelector(): void
226226
}
227227

228228
/**
229-
* @return array<non-empty-string, array{0: non-empty-string}>
229+
* @return array<non-empty-string, array{0: string, 1: non-empty-string}>
230230
*/
231-
public static function provideInvalidSelector(): array
231+
public static function provideInvalidSelectorAndExpectedExceptionMessage(): array
232232
{
233233
return [
234-
'lone `(`' => ['('],
235-
'lone `)`' => [')'],
236-
'unclosed `(`' => [':not(#your-mug'],
237-
'extra `)`' => [':not(#your-mug))'],
234+
'no selector' => ['', 'Token “selector” (literal) not found. Got “{”. [line no: 1]'],
235+
'lone `(`' => ['(', 'Token “)” (literal) not found. Got “{”.'],
236+
'lone `)`' => [')', 'Token “anything but” (literal) not found. Got “)”.'],
237+
'lone `,`' => [',', 'Token “selector” (literal) not found. Got “,”. [line no: 1]'],
238+
'unclosed `(`' => [':not(#your-mug', 'Token “)” (literal) not found. Got “{”.'],
239+
'extra `)`' => [':not(#your-mug))', 'Token “anything but” (literal) not found. Got “)”.'],
240+
'`,` missing left operand' => [', a', 'Token “selector” (literal) not found. Got “,”. [line no: 1]'],
241+
'`,` missing right operand' => ['a,', 'Token “selector” (literal) not found. Got “{”. [line no: 1]'],
238242
];
239243
}
240244

245+
/**
246+
* @return array<non-empty-string, array{0: string}>
247+
*/
248+
public static function provideInvalidSelector(): array
249+
{
250+
// Re-use the set of invalid selectors, but remove the expected exception message for tests that don't need it.
251+
return \array_map(
252+
/**
253+
* @param array{0: string, 1: non-empty-string}
254+
*
255+
* @return array<{0: string}>
256+
*/
257+
static function (array $testData): array {
258+
return [$testData[0]];
259+
},
260+
self::provideInvalidSelectorAndExpectedExceptionMessage()
261+
);
262+
}
263+
241264
/**
242265
* @test
243266
*
244-
* @param non-empty-string $selector
245-
*
246267
* @dataProvider provideInvalidSelector
247268
*/
248269
public function parseSkipsBlockWithInvalidSelector(string $selector): void
@@ -257,6 +278,25 @@ public function parseSkipsBlockWithInvalidSelector(string $selector): void
257278
self::assertTrue($parserState->comes($nextCss));
258279
}
259280

281+
/**
282+
* @test
283+
*
284+
* @param non-empty-string $expectedExceptionMessage
285+
*
286+
* @dataProvider provideInvalidSelectorAndExpectedExceptionMessage
287+
*/
288+
public function parseInStrictModeThrowsExceptionWithInvalidSelector(
289+
string $selector,
290+
string $expectedExceptionMessage
291+
): void {
292+
$this->expectException(UnexpectedTokenException::class);
293+
$this->expectExceptionMessage($expectedExceptionMessage);
294+
295+
$parserState = new ParserState($selector . ' {}', Settings::create()->beStrict());
296+
297+
$subject = DeclarationBlock::parse($parserState);
298+
}
299+
260300
/**
261301
* @return array<non-empty-string, array{0: non-empty-string}>
262302
*/
@@ -514,7 +554,7 @@ public static function provideInvalidStandaloneSelector(): array
514554
public function setSelectorsThrowsExceptionWithInvalidSelector(string $selector): void
515555
{
516556
$this->expectException(UnexpectedTokenException::class);
517-
$this->expectExceptionMessageMatches('/^Selector\\(s\\) string is not valid. /');
557+
$this->expectExceptionMessageMatches('/^Selector\\(s\\) string is not valid./');
518558

519559
$subject = new DeclarationBlock();
520560

0 commit comments

Comments
 (0)