Skip to content

Commit 252bbe1

Browse files
authored
[FEATURE] Add OutputFormat::setSpaceAroundSelectorCombinator() (#1504)
Resolves #1446
1 parent 8e87b8a commit 252bbe1

5 files changed

Lines changed: 129 additions & 2 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ Please also have a look at our
1010

1111
### Added
1212

13+
- Add `OutputFormat::setSpaceAroundSelectorCombinator()` (#1504)
1314
- Add support for escaped quotes in the selectors (#1485, #1489)
1415
- Provide line number in exception message for mismatched parentheses in
1516
selector (#1435)

src/OutputFormat.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,11 @@ final class OutputFormat
9292
*/
9393
private $spaceAfterSelectorSeparator = ' ';
9494

95+
/**
96+
* @var string
97+
*/
98+
private $spaceAroundSelectorCombinator = ' ';
99+
95100
/**
96101
* This is what’s inserted before the separator in value lists, by default.
97102
*
@@ -434,6 +439,27 @@ public function setSpaceAfterSelectorSeparator(string $whitespace): self
434439
return $this;
435440
}
436441

442+
/**
443+
* @internal
444+
*/
445+
public function getSpaceAroundSelectorCombinator(): string
446+
{
447+
return $this->spaceAroundSelectorCombinator;
448+
}
449+
450+
/**
451+
* The spacing set is also used for the descendent combinator, which is whitespace only,
452+
* unless an empty string is set, in which case a space will be used.
453+
*
454+
* @return $this fluent interface
455+
*/
456+
public function setSpaceAroundSelectorCombinator(string $whitespace): self
457+
{
458+
$this->spaceAroundSelectorCombinator = $whitespace;
459+
460+
return $this;
461+
}
462+
437463
/**
438464
* @internal
439465
*/
@@ -724,6 +750,7 @@ public static function createCompact(): self
724750
->setSpaceAfterRuleName('')
725751
->setSpaceBeforeOpeningBrace('')
726752
->setSpaceAfterSelectorSeparator('')
753+
->setSpaceAroundSelectorCombinator('')
727754
->setSemicolonAfterLastRule(false)
728755
->setRenderComments(false);
729756

src/Property/Selector/Combinator.php

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,14 @@ public function getSpecificity(): int
9494

9595
public function render(OutputFormat $outputFormat): string
9696
{
97-
// TODO: allow optional spacing controlled via OutputFormat
98-
return $this->value !== ' ' ? (' ' . $this->value . ' ') : ' ';
97+
$spacing = $outputFormat->getSpaceAroundSelectorCombinator();
98+
if ($this->value === ' ') {
99+
$rendering = $spacing !== '' ? $spacing : ' ';
100+
} else {
101+
$rendering = $spacing . $this->value . $spacing;
102+
}
103+
104+
return $rendering;
99105
}
100106

101107
/**

tests/Unit/OutputFormatTest.php

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,33 @@ public function setSpaceAfterSelectorSeparatorProvidesFluentInterface(): void
414414
self::assertSame($this->subject, $this->subject->setSpaceAfterSelectorSeparator(' '));
415415
}
416416

417+
/**
418+
* @test
419+
*/
420+
public function getSpaceAroundSelectorCombinatorInitiallyReturnsSpace(): void
421+
{
422+
self::assertSame(' ', $this->subject->getSpaceAroundSelectorCombinator());
423+
}
424+
425+
/**
426+
* @test
427+
*/
428+
public function setSpaceAroundSelectorCombinatorSetsSpaceAroundSelectorCombinator(): void
429+
{
430+
$value = ' ';
431+
$this->subject->setSpaceAroundSelectorCombinator($value);
432+
433+
self::assertSame($value, $this->subject->getSpaceAroundSelectorCombinator());
434+
}
435+
436+
/**
437+
* @test
438+
*/
439+
public function setSpaceAroundSelectorCombinatorProvidesFluentInterface(): void
440+
{
441+
self::assertSame($this->subject, $this->subject->setSpaceAroundSelectorCombinator(' '));
442+
}
443+
417444
/**
418445
* @test
419446
*/
@@ -1024,6 +1051,16 @@ public function createCompactReturnsInstanceWithSpaceAfterSelectorSeparatorSetTo
10241051
self::assertSame('', $newInstance->getSpaceAfterSelectorSeparator());
10251052
}
10261053

1054+
/**
1055+
* @test
1056+
*/
1057+
public function createCompactReturnsInstanceWithSpaceAroundSelectorCombinatorSetToEmptyString(): void
1058+
{
1059+
$newInstance = OutputFormat::createCompact();
1060+
1061+
self::assertSame('', $newInstance->getSpaceAroundSelectorCombinator());
1062+
}
1063+
10271064
/**
10281065
* @test
10291066
*/
@@ -1163,6 +1200,16 @@ public function createPrettyReturnsInstanceWithSpaceAfterSelectorSeparatorSetToS
11631200
self::assertSame(' ', $newInstance->getSpaceAfterSelectorSeparator());
11641201
}
11651202

1203+
/**
1204+
* @test
1205+
*/
1206+
public function createPrettyReturnsInstanceWithSpaceAroundSelectorCombinatorSetToSpace(): void
1207+
{
1208+
$newInstance = OutputFormat::createPretty();
1209+
1210+
self::assertSame(' ', $newInstance->getSpaceAroundSelectorCombinator());
1211+
}
1212+
11661213
/**
11671214
* @test
11681215
*/

tests/Unit/Property/Selector/CombinatorTest.php

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,52 @@ public function renderReturnsDefaultRenderingForValueProvided(string $value, str
271271
self::assertSame($expectedRendering, $subject->render(OutputFormat::create()));
272272
}
273273

274+
/**
275+
* @return array<non-empty-string, array{0: string}>
276+
*/
277+
public static function provideSpacing(): array
278+
{
279+
return [
280+
'empty string' => [''],
281+
'space' => [' '],
282+
'newline' => ["\n"],
283+
'carriage return' => ["\r"],
284+
'tab' => ["\t"],
285+
];
286+
}
287+
288+
/**
289+
* @test
290+
*
291+
* @dataProvider provideSpacing
292+
*/
293+
public function renderIncludesSpacingSetInOutputFormat(string $spacing): void
294+
{
295+
$subject = new Combinator('>');
296+
$outputFormat = (OutputFormat::create())->setSpaceAroundSelectorCombinator($spacing);
297+
298+
$result = $subject->render($outputFormat);
299+
300+
$expectedRendering = $spacing . '>' . $spacing;
301+
self::assertSame($expectedRendering, $result);
302+
}
303+
304+
/**
305+
* @test
306+
*
307+
* @dataProvider provideSpacing
308+
*/
309+
public function renderReturnsSpacingSetInOutputFormatForDescendentCombinatorOrSpaceIfNeeded(string $spacing): void
310+
{
311+
$subject = new Combinator(' ');
312+
$outputFormat = (OutputFormat::create())->setSpaceAroundSelectorCombinator($spacing);
313+
314+
$result = $subject->render($outputFormat);
315+
316+
$expectedRendering = $spacing !== '' ? $spacing : ' ';
317+
self::assertSame($expectedRendering, $result);
318+
}
319+
274320
/**
275321
* @test
276322
*/

0 commit comments

Comments
 (0)