|
16 | 16 | *******************************************************************************/ |
17 | 17 | package org.eclipse.e4.ui.tests.css.core; |
18 | 18 |
|
| 19 | +import static org.junit.jupiter.api.Assertions.assertEquals; |
19 | 20 | import static org.junit.jupiter.api.Assertions.assertFalse; |
20 | 21 | import static org.junit.jupiter.api.Assertions.assertTrue; |
21 | 22 |
|
@@ -274,6 +275,62 @@ void testTagNameCaseSensitivity() throws Exception { |
274 | 275 | assertFalse(engine.matches(lower, capitalElement, null)); |
275 | 276 | } |
276 | 277 |
|
| 278 | + // --- Selector specificity (cascade ordering depends on this) --- |
| 279 | + |
| 280 | + @Test |
| 281 | + void testSimpleSelectorSpecificity() throws Exception { |
| 282 | + TestCSSEngine engine = new TestCSSEngine(); |
| 283 | + assertEquals(0, parse(engine, "*").specificity()); |
| 284 | + assertEquals(1, parse(engine, "Button").specificity()); |
| 285 | + assertEquals(10, parse(engine, ".primary").specificity()); |
| 286 | + assertEquals(100, parse(engine, "#go").specificity()); |
| 287 | + } |
| 288 | + |
| 289 | + @Test |
| 290 | + void testAttributeAndPseudoSpecificity() throws Exception { |
| 291 | + TestCSSEngine engine = new TestCSSEngine(); |
| 292 | + // Attribute and pseudo-class selectors weigh the same as a class. |
| 293 | + assertEquals(11, parse(engine, "Button[style]").specificity()); |
| 294 | + assertEquals(11, parse(engine, "Button[style~='SWT.CHECK']").specificity()); |
| 295 | + assertEquals(11, parse(engine, "Button:selected").specificity()); |
| 296 | + } |
| 297 | + |
| 298 | + @Test |
| 299 | + void testCompoundSelectorSpecificitySums() throws Exception { |
| 300 | + TestCSSEngine engine = new TestCSSEngine(); |
| 301 | + // Button + .primary + #go = 1 + 10 + 100. |
| 302 | + assertEquals(111, parse(engine, "Button.primary#go").specificity()); |
| 303 | + } |
| 304 | + |
| 305 | + @Test |
| 306 | + void testCombinatorSpecificitySums() throws Exception { |
| 307 | + TestCSSEngine engine = new TestCSSEngine(); |
| 308 | + // Combinators contribute nothing themselves; the operands sum. |
| 309 | + assertEquals(2, parse(engine, "Composite Button").specificity()); |
| 310 | + assertEquals(2, parse(engine, "Composite > Button").specificity()); |
| 311 | + assertEquals(11, parse(engine, "Composite .primary").specificity()); |
| 312 | + } |
| 313 | + |
| 314 | + @Test |
| 315 | + void testSelectorListSpecificityIsMax() throws Exception { |
| 316 | + TestCSSEngine engine = new TestCSSEngine(); |
| 317 | + // A list reports the highest specificity among its alternatives. |
| 318 | + assertEquals(100, engine.parseSelectors("Button, .primary, #go").specificity()); |
| 319 | + assertEquals(10, engine.parseSelectors("Button, .primary").specificity()); |
| 320 | + } |
| 321 | + |
| 322 | + @Test |
| 323 | + void testSpecificityOrderingIdBeatsClassBeatsType() throws Exception { |
| 324 | + TestCSSEngine engine = new TestCSSEngine(); |
| 325 | + int universal = parse(engine, "*").specificity(); |
| 326 | + int type = parse(engine, "Button").specificity(); |
| 327 | + int clazz = parse(engine, ".primary").specificity(); |
| 328 | + int id = parse(engine, "#go").specificity(); |
| 329 | + assertTrue(universal < type, "universal must rank below a type selector"); |
| 330 | + assertTrue(type < clazz, "a type selector must rank below a class selector"); |
| 331 | + assertTrue(clazz < id, "a class selector must rank below an id selector"); |
| 332 | + } |
| 333 | + |
277 | 334 | private static boolean matchesAny(CSSEngine engine, Selectors.SelectorList list, Element element) { |
278 | 335 | for (Selector selector : list.alternatives()) { |
279 | 336 | if (engine.matches(selector, element, null)) { |
|
0 commit comments