diff --git a/tests/Unit/RuleSet/RuleSetTest.php b/tests/Unit/RuleSet/RuleSetTest.php index 847078bb..303e718b 100644 --- a/tests/Unit/RuleSet/RuleSetTest.php +++ b/tests/Unit/RuleSet/RuleSetTest.php @@ -9,6 +9,7 @@ use Sabberworm\CSS\Rule\Rule; use Sabberworm\CSS\RuleSet\RuleSet; use Sabberworm\CSS\Tests\Unit\RuleSet\Fixtures\ConcreteRuleSet; +use TRegx\DataProvider\DataProviders; /** * @covers \Sabberworm\CSS\RuleSet\RuleSet @@ -27,6 +28,148 @@ public function implementsCSSElement() self::assertInstanceOf(CSSElement::class, $subject); } + /** + * @return array}> + */ + public static function providePropertyNamesToBeSetInitially() + { + return [ + 'no properties' => [[]], + 'one property' => [['color']], + 'two different properties' => [['color', 'display']], + 'two of the same property' => [['color', 'color']], + ]; + } + + /** + * @return array + */ + public static function providePropertyNameToAdd() + { + return [ + 'property name `color` maybe matching that of existing declaration' => ['color'], + 'property name `display` maybe matching that of existing declaration' => ['display'], + 'property name `width` not matching that of existing declaration' => ['width'], + ]; + } + + /** + * @return array, 1: string}> + */ + public static function provideInitialPropertyNamesAndPropertyNameToAdd() + { + if (!\class_exists(DataProviders::class)) { + self::markTestSkipped('`DataProviders` class is not available'); + return []; + } + + return DataProviders::cross(self::providePropertyNamesToBeSetInitially(), self::providePropertyNameToAdd()); + } + + /** + * @test + * + * @param list $initialPropertyNames + * + * @dataProvider provideInitialPropertyNamesAndPropertyNameToAdd + */ + public function addRuleWithoutSiblingAddsRuleAfterInitialRulesAndSetsValidLineAndColumnNumbers( + array $initialPropertyNames, + string $propertyNameToAdd + ) { + if ($initialPropertyNames === []) { + self::markTestSkipped('currently broken - first rule added does not have valid line number set'); + } + + $subject = new ConcreteRuleSet(); + $ruleToAdd = new Rule($propertyNameToAdd); + self::setRulesFromPropertyNames($subject, $initialPropertyNames); + + $subject->addRule($ruleToAdd); + + $rules = $subject->getRules(); + self::assertSame($ruleToAdd, \end($rules)); + self::assertInternalType('int', $ruleToAdd->getLineNumber(), 'line number not set'); + self::assertGreaterThanOrEqual(1, $ruleToAdd->getLineNumber(), 'line number not valid'); + self::assertInternalType('int', $ruleToAdd->getColumnNumber(), 'column number not set'); + self::assertGreaterThanOrEqual(0, $ruleToAdd->getColumnNumber(), 'column number not valid'); + } + + /** + * @test + * + * @dataProvider provideInitialPropertyNamesAndPropertyNameToAdd + * + * @param list $initialPropertyNames + */ + public function addRuleWithOnlyLineNumberAddsRuleAndSetsColumnNumberPreservingLineNumber( + array $initialPropertyNames, + string $propertyNameToAdd + ) { + self::markTestSkipped('currently broken - does not set column number'); + + $subject = new ConcreteRuleSet(); + $ruleToAdd = new Rule($propertyNameToAdd); + $ruleToAdd->setPosition(42); + self::setRulesFromPropertyNames($subject, $initialPropertyNames); + + $subject->addRule($ruleToAdd); + + self::assertContains($ruleToAdd, $subject->getRules()); + self::assertInternalType('int', $ruleToAdd->getColumnNumber(), 'column number not set'); + self::assertGreaterThanOrEqual(0, $ruleToAdd->getColumnNumber(), 'column number not valid'); + self::assertSame(42, $ruleToAdd->getLineNumber(), 'line number not preserved'); + } + + /** + * @test + * + * @dataProvider provideInitialPropertyNamesAndPropertyNameToAdd + * + * @param list $initialPropertyNames + */ + public function addRuleWithOnlyColumnNumberAddsRuleAndSetsLineNumberPreservingColumnNumber( + array $initialPropertyNames, + string $propertyNameToAdd + ) { + self::markTestSkipped('currently broken - does not preserve column number'); + + $subject = new ConcreteRuleSet(); + $ruleToAdd = new Rule($propertyNameToAdd); + $ruleToAdd->setPosition(null, 42); + self::setRulesFromPropertyNames($subject, $initialPropertyNames); + + $subject->addRule($ruleToAdd); + + self::assertContains($ruleToAdd, $subject->getRules()); + self::assertInternalType('int', $ruleToAdd->getLineNumber(), 'line number not set'); + self::assertGreaterThanOrEqual(1, $ruleToAdd->getLineNumber(), 'line number not valid'); + self::assertSame(42, $ruleToAdd->getColumnNumber(), 'column number not preserved'); + } + + /** + * @test + * + * @dataProvider provideInitialPropertyNamesAndPropertyNameToAdd + * + * @param list $initialPropertyNames + */ + public function addRuleWithCompletePositionAddsRuleAndPreservesPosition( + array $initialPropertyNames, + string $propertyNameToAdd + ) { + $subject = new ConcreteRuleSet(); + $ruleToAdd = new Rule($propertyNameToAdd); + $ruleToAdd->setPosition(42, 64); + self::setRulesFromPropertyNames($subject, $initialPropertyNames); + + $subject->addRule($ruleToAdd); + + self::assertContains($ruleToAdd, $subject->getRules()); + self::assertSame(42, $ruleToAdd->getLineNumber(), 'line number not preserved'); + self::assertSame(64, $ruleToAdd->getColumnNumber(), 'column number not preserved'); + } + /** * @return array, 1: string, 2: list}> */ @@ -171,25 +314,12 @@ public function removeMatchingRulesRemovesRulesByPropertyNamePrefixAndKeepsOther } } - /** - * @return array}> - */ - public static function providePropertyNamesToRemove() - { - return [ - 'no properties' => [[]], - 'one property' => [['color']], - 'two different properties' => [['color', 'display']], - 'two of the same property' => [['color', 'color']], - ]; - } - /** * @test * * @param list $propertyNamesToRemove * - * @dataProvider providePropertyNamesToRemove + * @dataProvider providePropertyNamesToBeSetInitially */ public function removeAllRulesRemovesAllRules(array $propertyNamesToRemove) {