1 /* 2 * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.javafx.css; 27 28 import com.sun.javafx.css.parser.CSSParser; 29 import java.util.Arrays; 30 import java.util.Collection; 31 import java.util.List; 32 import javafx.scene.paint.Color; 33 import org.junit.Test; 34 import static org.junit.Assert.*; 35 36 import org.junit.runner.RunWith; 37 import org.junit.runners.Parameterized; 38 import org.junit.runners.Parameterized.Parameters; 39 40 @RunWith(Parameterized.class) 41 public class SelectorPartitioningTest { 42 43 public SelectorPartitioningTest(final Data data) { 44 this.data = data; 45 this.instance = new SelectorPartitioning(); 46 } 47 private final Data data; 48 private final SelectorPartitioning instance; 49 50 private static class Data { 51 final Color color; 52 final String stylesheetText; 53 54 Data(Color color, String stylesheetText) { 55 this.color = color; 56 this.stylesheetText = stylesheetText; 57 } 58 59 } 60 61 private static class SimpleData extends Data { 62 63 final SimpleSelector selector; 64 final boolean matches; 65 66 SimpleData(String type, String styleClass, String id, Color color) { 67 this(type, styleClass, id, color, true); 68 } 69 SimpleData(String type, String styleClass, String id, Color color, boolean matches) { 70 super(color, (new StringBuilder() 71 .append((type != null ? type : "*")) 72 .append((styleClass != null ? ".".concat(styleClass) : "")) 73 .append((id != null ? "#".concat(id) : "")) 74 .append("{-fx-fill: rgb(") 75 .append(Double.valueOf(color.getRed()*255).intValue()).append(",") 76 .append(Double.valueOf(color.getGreen()*255).intValue()).append(",") 77 .append(Double.valueOf(color.getBlue()*255).intValue()).append(");}") 78 ).toString()); 79 List<String> styleClasses = 80 styleClass != null ? Arrays.asList(styleClass.split("\\.")) : null; 81 this.selector = 82 new SimpleSelector(type, styleClasses, null, id); 83 this.matches = matches; 84 } 85 } 86 87 private static class ComplexData extends Data { 88 89 final SimpleData[] data; 90 final SimpleSelector selector; 91 final int matches; 92 93 ComplexData(SimpleSelector selector, SimpleData... data) { 94 super(Color.TRANSPARENT, combineStylesheets(data)); 95 this.data = data; 96 this.selector = selector; 97 int n = 0; 98 for (SimpleData datum : data) { 99 if (datum.matches) n += 1; 100 } 101 this.matches = n; 102 } 103 104 static String combineStylesheets(Data... data) { 105 StringBuilder buf = new StringBuilder(); 106 for (Data datum : data) { 107 buf.append(datum.stylesheetText).append('\n'); 108 } 109 return buf.toString(); 110 } 111 } 112 113 114 @Parameters 115 public static Collection data() { 116 117 int red = 0; 118 int green = 0; 119 int blue = 0; 120 return Arrays.asList(new Object[] { 121 /* selector = * */ 122 new Object[] {new SimpleData("*", null, null, Color.rgb(red += 10, 0, 0))}, 123 /* selector = A */ 124 new Object[] {new SimpleData("A", null, null, Color.rgb(red += 10, 0, 0))}, 125 /* selector = * A.b */ 126 new Object[] {new SimpleData("A", "b", null, Color.rgb(red += 10, 0, 0))}, 127 /* selector = A#c */ 128 new Object[] {new SimpleData("A", null, "c", Color.rgb(red += 10, 0, 0))}, 129 /* selector = A.b#c */ 130 new Object[] {new SimpleData("A", "b", "c", Color.rgb(red += 10, 0, 0))}, 131 /* selector = *.b */ 132 new Object[] {new SimpleData("*", "b", null, Color.rgb(red += 10, 0, 0))}, 133 /* selector = *#c */ 134 new Object[] {new SimpleData("*", null, "c", Color.rgb(red += 10, 0, 0))}, 135 /* selector = *.b#c */ 136 new Object[] {new SimpleData("*", "b", "c", Color.rgb(red += 10, 0, 0))}, 137 138 new Object[] { 139 new ComplexData( 140 (SimpleSelector)Selector.createSelector("*.b"), 141 new SimpleData("*", "b", null, Color.rgb(0, green += 10, 0), true), 142 new SimpleData("*", "c", null, Color.rgb(0, green += 10, 0), false), 143 new SimpleData("*", "b.c", null, Color.rgb(0, green += 10, 0), false) 144 )}, 145 new Object[] { 146 new ComplexData( 147 (SimpleSelector)Selector.createSelector("*.b.c"), 148 new SimpleData("*", "b", null, Color.rgb(0, green += 10, 0), true), 149 new SimpleData("*", "c", null, Color.rgb(0, green += 10, 0), true), 150 new SimpleData("*", "b.c", null, Color.rgb(0, green += 10, 0), true) 151 )}, 152 new Object[] { 153 new ComplexData( 154 (SimpleSelector)Selector.createSelector("A.b"), 155 new SimpleData("*", "b", null, Color.rgb(0, green += 10, 0), true), 156 new SimpleData("A", "b", null, Color.rgb(0, green += 10, 0), true), 157 new SimpleData("*", null, null, Color.rgb(0, green += 10, 0), true), 158 new SimpleData("*", "c", null, Color.rgb(0, green += 10, 0), false), 159 new SimpleData("*", "b.c", null, Color.rgb(0, green += 10, 0), false) 160 )}, 161 new Object[] { 162 new ComplexData( 163 (SimpleSelector)Selector.createSelector("A.c"), 164 new SimpleData("*", "b", null, Color.rgb(0, green += 10, 0), false), 165 new SimpleData("A", "b", null, Color.rgb(0, green += 10, 0), false), 166 new SimpleData("*", null, null, Color.rgb(0, green += 10, 0), true), 167 new SimpleData("*", "c", null, Color.rgb(0, green += 10, 0), true), 168 new SimpleData("*", "b.c", null, Color.rgb(0, green += 10, 0), false) 169 )}, 170 new Object[] { 171 new ComplexData( 172 (SimpleSelector)Selector.createSelector("A.b.c"), 173 new SimpleData("*", "b", null, Color.rgb(0, green += 10, 0), true), 174 new SimpleData("A", "b", null, Color.rgb(0, green += 10, 0), true), 175 new SimpleData("*", null, null, Color.rgb(0, green += 10, 0), true), 176 new SimpleData("*", "c", null, Color.rgb(0, green += 10, 0), true), 177 new SimpleData("*", "b.c", null, Color.rgb(0, green += 10, 0), true) 178 )} 179 }); 180 } 181 182 @Test 183 public void testSelectorPartitionAndMatch() { 184 185 Stylesheet stylesheet = 186 CSSParser.getInstance().parse(data.stylesheetText); 187 188 for (Rule rule : stylesheet.getRules()) { 189 for (Selector selector : rule.getUnobservedSelectorList()) { 190 instance.partition(selector); 191 } 192 } 193 194 if (data instanceof SimpleData) { 195 testWithSimpleData((SimpleData)data, stylesheet); 196 } else { 197 testWithComplexData((ComplexData)data, stylesheet); 198 } 199 } 200 201 private void testWithSimpleData(SimpleData simpleData, Stylesheet stylesheet) { 202 203 SimpleSelector simple = simpleData.selector; 204 205 List<Selector> matched = instance.match(simple.getId(), simple.getName(), simple.getStyleClassSet()); 206 207 assertEquals(1,matched.size()); 208 Selector selector = matched.get(0); 209 210 Rule rule = selector.getRule(); 211 212 assertEquals(1,rule.getUnobservedDeclarationList().size()); 213 Declaration decl = rule.getUnobservedDeclarationList().get(0); 214 215 assertEquals("-fx-fill", decl.property); 216 217 Color color = (Color)decl.parsedValue.convert(null); 218 219 assertEquals(simpleData.selector.toString(), data.color.getRed(), color.getRed(), 0.00001); 220 assertEquals(simpleData.selector.toString(), data.color.getGreen(), color.getGreen(), 0.00001); 221 assertEquals(simpleData.selector.toString(), data.color.getBlue(), color.getBlue(), 0.00001); 222 223 } 224 225 private void testWithComplexData(ComplexData complexData, Stylesheet stylesheet) { 226 227 SimpleSelector simple = complexData.selector; 228 229 List<Selector> matched = instance.match(simple.getId(), simple.getName(), simple.getStyleClassSet()); 230 assertEquals(complexData.matches, matched.size()); 231 232 for(Selector s1 : matched) { 233 for (SimpleData datum : complexData.data) { 234 Selector s2 = datum.selector; 235 if (s1.equals(s2)) { 236 assertTrue(s1.toString() + " != " + s2.toString(), datum.matches); 237 } 238 } 239 } 240 241 } 242 243 }