99use Sabberworm \CSS \Rule \Rule ;
1010use Sabberworm \CSS \RuleSet \RuleSet ;
1111use Sabberworm \CSS \Tests \Unit \RuleSet \Fixtures \ConcreteRuleSet ;
12+ use TRegx \DataProvider \DataProviders ;
1213
1314/**
1415 * @covers \Sabberworm\CSS\RuleSet\RuleSet
@@ -27,6 +28,143 @@ public function implementsCSSElement()
2728 self ::assertInstanceOf (CSSElement::class, $ subject );
2829 }
2930
31+ /**
32+ * @return array<string, array{0: list<non-empty-string>}>
33+ */
34+ public static function providePropertyNamesToBeSetInitially ()
35+ {
36+ return [
37+ 'no properties ' => [[]],
38+ 'one property ' => [['color ' ]],
39+ 'two different properties ' => [['color ' , 'display ' ]],
40+ 'two of the same property ' => [['color ' , 'color ' ]],
41+ ];
42+ }
43+
44+ /**
45+ * @return array<string, array{0: non-empty-string}>
46+ */
47+ public static function providePropertyNameToAdd ()
48+ {
49+ return [
50+ 'property name `color` maybe matching that of existing declaration ' => ['color ' ],
51+ 'property name `display` maybe matching that of existing declaration ' => ['display ' ],
52+ 'property name `width` not matching that of existing declaration ' => ['width ' ],
53+ ];
54+ }
55+
56+ /**
57+ * @return array<string, array{0: list<string>, 1: string}>
58+ */
59+ public static function provideInitialPropertyNamesAndPropertyNameToAdd ()
60+ {
61+ return DataProviders::cross (self ::providePropertyNamesToBeSetInitially (), self ::providePropertyNameToAdd ());
62+ }
63+
64+ /**
65+ * @test
66+ *
67+ * @param list<string> $initialPropertyNames
68+ *
69+ * @dataProvider provideInitialPropertyNamesAndPropertyNameToAdd
70+ */
71+ public function addRuleWithoutSiblingAddsRuleAfterInitialRulesAndSetsValidLineAndColumnNumbers (
72+ array $ initialPropertyNames ,
73+ string $ propertyNameToAdd
74+ ) {
75+ if ($ initialPropertyNames === []) {
76+ self ::markTestSkipped ('currently broken - first rule added does not have valid line number set ' );
77+ }
78+
79+ $ subject = new ConcreteRuleSet ();
80+ $ ruleToAdd = new Rule ($ propertyNameToAdd );
81+ self ::setRulesFromPropertyNames ($ subject , $ initialPropertyNames );
82+
83+ $ subject ->addRule ($ ruleToAdd );
84+
85+ $ rules = $ subject ->getRules ();
86+ self ::assertSame ($ ruleToAdd , \end ($ rules ));
87+ self ::assertIsInt ($ ruleToAdd ->getLineNumber (), 'line number not set ' );
88+ self ::assertGreaterThanOrEqual (1 , $ ruleToAdd ->getLineNumber (), 'line number not valid ' );
89+ self ::assertIsInt ($ ruleToAdd ->getColumnNumber (), 'column number not set ' );
90+ self ::assertGreaterThanOrEqual (0 , $ ruleToAdd ->getColumnNumber (), 'column number not valid ' );
91+ }
92+
93+ /**
94+ * @test
95+ *
96+ * @dataProvider provideInitialPropertyNamesAndPropertyNameToAdd
97+ *
98+ * @param list<string> $initialPropertyNames
99+ */
100+ public function addRuleWithOnlyLineNumberAddsRuleAndSetsColumnNumberPreservingLineNumber (
101+ array $ initialPropertyNames ,
102+ string $ propertyNameToAdd
103+ ) {
104+ self ::markTestSkipped ('currently broken - does not set column number ' );
105+
106+ $ subject = new ConcreteRuleSet ();
107+ $ ruleToAdd = new Rule ($ propertyNameToAdd );
108+ $ ruleToAdd ->setPosition (42 );
109+ self ::setRulesFromPropertyNames ($ subject , $ initialPropertyNames );
110+
111+ $ subject ->addRule ($ ruleToAdd );
112+
113+ self ::assertContains ($ ruleToAdd , $ subject ->getRules ());
114+ self ::assertIsInt ($ ruleToAdd ->getColumnNumber (), 'column number not set ' );
115+ self ::assertGreaterThanOrEqual (0 , $ ruleToAdd ->getColumnNumber (), 'column number not valid ' );
116+ self ::assertSame (42 , $ ruleToAdd ->getLineNumber (), 'line number not preserved ' );
117+ }
118+
119+ /**
120+ * @test
121+ *
122+ * @dataProvider provideInitialPropertyNamesAndPropertyNameToAdd
123+ *
124+ * @param list<string> $initialPropertyNames
125+ */
126+ public function addRuleWithOnlyColumnNumberAddsRuleAndSetsLineNumberPreservingColumnNumber (
127+ array $ initialPropertyNames ,
128+ string $ propertyNameToAdd
129+ ) {
130+ self ::markTestSkipped ('currently broken - does not preserve column number ' );
131+
132+ $ subject = new ConcreteRuleSet ();
133+ $ ruleToAdd = new Rule ($ propertyNameToAdd );
134+ $ ruleToAdd ->setPosition (null , 42 );
135+ self ::setRulesFromPropertyNames ($ subject , $ initialPropertyNames );
136+
137+ $ subject ->addRule ($ ruleToAdd );
138+
139+ self ::assertContains ($ ruleToAdd , $ subject ->getRules ());
140+ self ::assertIsInt ($ ruleToAdd ->getLineNumber (), 'line number not set ' );
141+ self ::assertGreaterThanOrEqual (1 , $ ruleToAdd ->getLineNumber (), 'line number not valid ' );
142+ self ::assertSame (42 , $ ruleToAdd ->getColumnNumber (), 'column number not preserved ' );
143+ }
144+
145+ /**
146+ * @test
147+ *
148+ * @dataProvider provideInitialPropertyNamesAndPropertyNameToAdd
149+ *
150+ * @param list<string> $initialPropertyNames
151+ */
152+ public function addRuleWithCompletePositionAddsRuleAndPreservesPosition (
153+ array $ initialPropertyNames ,
154+ string $ propertyNameToAdd
155+ ) {
156+ $ subject = new ConcreteRuleSet ();
157+ $ ruleToAdd = new Rule ($ propertyNameToAdd );
158+ $ ruleToAdd ->setPosition (42 , 64 );
159+ self ::setRulesFromPropertyNames ($ subject , $ initialPropertyNames );
160+
161+ $ subject ->addRule ($ ruleToAdd );
162+
163+ self ::assertContains ($ ruleToAdd , $ subject ->getRules ());
164+ self ::assertSame (42 , $ ruleToAdd ->getLineNumber (), 'line number not preserved ' );
165+ self ::assertSame (64 , $ ruleToAdd ->getColumnNumber (), 'column number not preserved ' );
166+ }
167+
30168 /**
31169 * @return array<string, array{0: list<string>, 1: string, 2: list<string>}>
32170 */
@@ -171,25 +309,12 @@ public function removeMatchingRulesRemovesRulesByPropertyNamePrefixAndKeepsOther
171309 }
172310 }
173311
174- /**
175- * @return array<string, array{0: list<string>}>
176- */
177- public static function providePropertyNamesToRemove ()
178- {
179- return [
180- 'no properties ' => [[]],
181- 'one property ' => [['color ' ]],
182- 'two different properties ' => [['color ' , 'display ' ]],
183- 'two of the same property ' => [['color ' , 'color ' ]],
184- ];
185- }
186-
187312 /**
188313 * @test
189314 *
190315 * @param list<string> $propertyNamesToRemove
191316 *
192- * @dataProvider providePropertyNamesToRemove
317+ * @dataProvider providePropertyNamesToBeSetInitially
193318 */
194319 public function removeAllRulesRemovesAllRules (array $ propertyNamesToRemove )
195320 {
0 commit comments