/* * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package test.javafx.css; import com.sun.javafx.css.*; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.util.Arrays; import java.util.List; import java.util.Map; import javafx.css.CssParser; import javafx.css.CssParserShim; import javafx.css.Declaration; import javafx.css.FontFace; import javafx.css.ParsedValue; import javafx.css.ParsedValue; import javafx.css.Rule; import javafx.css.RuleShim; import javafx.css.Stylesheet; import javafx.scene.paint.Color; import javafx.scene.paint.LinearGradient; import javafx.scene.paint.Paint; import javafx.scene.paint.Stop; import javafx.scene.text.Font; import javafx.util.Duration; import org.junit.Test; import static org.junit.Assert.*; public class CssParserTest { @Test public void testRT_16959() { CssParser instance = new CssParser(); // RT-16959 is an infinite loop on incomplete linear gradient ParsedValue result = new CssParserShim(instance) .parseExpr("-fx-background-color", "linear-gradient(from 0% 0% to 0% 100%, )"); assertNull("parseExpr", result); // The bad syntax should be skipped. The stylesheet should have one // linear gradient with colors red, white, blue. Stylesheet ss = instance.parse( "* { " + "-fx-background-color: linear-gradient(from 0% 0% to 0% 100%, ); " + "-fx-background-color: linear-gradient(from 0% 0% to 0% 100%, red, white, blue); " + "}" ); assertNotNull(ss); List rules = ss.getRules(); assertEquals(1,rules.size(),0); List decls = RuleShim.getUnobservedDeclarationList(ss.getRules().get(0)); assertTrue(decls.size()==1); Declaration decl = decls.get(0); ParsedValue value = decl.getParsedValue(); assertTrue(value != null); Paint[] layers = (Paint[])value.convert(null); assertTrue(layers.length == 1); LinearGradient lg = (LinearGradient)layers[0]; List stops = lg.getStops(); assertTrue(stops.size()==3); assertEquals(Color.RED, stops.get(0).getColor()); assertEquals(Color.WHITE, stops.get(1).getColor()); assertEquals(Color.BLUE, stops.get(2).getColor()); } @Test public void testRT_17770() { // RT-17770 is an infinite loop on a dangling comma. // Missing term should be ignored String stylesheetText = "* {" + "-fx-background-color: linear-gradient( " + "to right, " + "rgba(141, 138, 125, 0.0), " + "rgba(248, 248, 246, 0.3) 45%, " + "rgba(248, 248, 246, 0.8) 50%, " + "rgba(248, 248, 246, 0.3) 55%, " + "rgba(141, 138, 125, 0.0), " + "); " + "}"; CssParser instance = new CssParser(); Stylesheet ss = instance.parse(stylesheetText); assertNotNull(ss); List rules = ss.getRules(); assertEquals(1,rules.size(),0); List decls = RuleShim.getUnobservedDeclarationList(ss.getRules().get(0)); assertTrue(decls.size()==1); Declaration decl = decls.get(0); ParsedValue value = decl.getParsedValue(); assertTrue(value != null); Paint[] layers = (Paint[])value.convert(null); assertTrue(layers.length == 1); LinearGradient lg = (LinearGradient)layers[0]; List stops = lg.getStops(); assertTrue(stops.size()==5); assertEquals(Color.rgb(141, 138, 125, 0.0), stops.get(0).getColor()); assertEquals(Color.rgb(248, 248, 246, 0.3), stops.get(1).getColor()); assertEquals(Color.rgb(248, 248, 246, 0.8), stops.get(2).getColor()); assertEquals(Color.rgb(248, 248, 246, 0.3), stops.get(3).getColor()); assertEquals(Color.rgb(141, 138, 125, 0.0), stops.get(4).getColor()); } @Test public void testParseSizeWithInvalidDigits() { CssParser instance = new CssParser(); // RT-16959 is an infinite loop on incomplete linear gradient ParsedValue result = new CssParserShim(instance).parseExpr("-fx-font-size", "10ptx"); assertNull("parseExpr", result); // The bad syntax should be skipped. Stylesheet ss = instance.parse( "* {" + "-fx-font-size: 10ptx; " + "-fx-font-size: 12px; " + "}" ); assertNotNull(ss); List rules = ss.getRules(); assertEquals(1,rules.size(),0); List decls = RuleShim.getUnobservedDeclarationList(ss.getRules().get(0)); assertTrue(decls.size()==1); Declaration decl = decls.get(0); ParsedValue value = decl.getParsedValue(); assertTrue(value != null); Double size = (Double)value.convert(Font.font("Amble", 12)); assertTrue(Double.compare(size, 12) == 0); } @Test public void testRT_17830() { CssParser instance = new CssParser(); // The empty declaration should be skipped. The stylesheet should have // two declarations. Stylesheet ss = instance.parse(".rt17830 {-fx-fill: red;; -fx-stroke: yellow; }"); assertNotNull(ss); List rules = ss.getRules(); assertEquals(1,rules.size(),0); List decls = RuleShim.getUnobservedDeclarationList(ss.getRules().get(0)); assertEquals(2,decls.size(),0); Declaration decl = decls.get(0); ParsedValue value = decl.getParsedValue(); assertTrue(value != null); Paint paint = (Paint)value.convert(null); assertEquals(Color.RED, paint); decl = decls.get(1); value = decl.getParsedValue(); assertTrue(value != null); paint = (Paint)value.convert(null); assertEquals(Color.YELLOW, paint); } @Test public void testRT_20311() { CssParser instance = new CssParser(); try { instance.parse(".rt-20311 { -fx-background-color:red\n-fx-border-color:black; }"); } catch (Exception e) { fail(e.toString()); } } @Test public void testFontFace() { // http://fonts.googleapis.com/css?family=Bree+Serif String css = "@font-face {\n" + "font-family: 'Bree Serif';\n" + "font-style: normal;\n" + "font-weight: 400;\n" + "src: local('Bree Serif'), local('BreeSerif-Regular'), url(http://themes.googleusercontent.com/static/fonts/breeserif/v2/LQ7WLTaITDg4OSRuOZCps73hpw3pgy2gAi-Ip7WPMi0.woff) format('woff');\n"+ "}"; Stylesheet stylesheet = new CssParser().parse(css); int nFontFaceSrcs = checkFontFace(stylesheet); assertEquals(3, nFontFaceSrcs); } @Test public void testFontFaceMoreThanOneSrc() { // http://fonts.googleapis.com/css?family=Bree+Serif String css = "@font-face {\n" + "font-family: 'Bree Serif';\n" + "font-style: normal;\n" + "font-weight: 400;\n" + "src: local('Bree Serif'), local('BreeSerif-Regular'), url(http://themes.googleusercontent.com/static/fonts/breeserif/v2/LQ7WLTaITDg4OSRuOZCps73hpw3pgy2gAi-Ip7WPMi0.woff) format('woff'),\n"+ " local('Bree Serif'), local('BreeSerif-Regular'), url(http://themes.googleusercontent.com/static/fonts/breeserif/v2/LQ7WLTaITDg4OSRuOZCps73hpw3pgy2gAi-Ip7WPMi0.woff) format('woff');\n"+ "}"; Stylesheet stylesheet = new CssParser().parse(css); int nFontFaceSrcs = checkFontFace(stylesheet); assertEquals(6, nFontFaceSrcs); } public static int checkFontFace(Stylesheet stylesheet) { List fontFaces = stylesheet.getFontFaces(); assertNotNull(fontFaces); assertEquals(1, fontFaces.size()); FontFaceImpl fontFace = (FontFaceImpl)fontFaces.get(0); Map descriptors = fontFace.getDescriptors(); assertEquals("'Bree Serif'", descriptors.get("font-family")); assertEquals("normal", descriptors.get("font-style")); assertEquals("400", descriptors.get("font-weight")); List fontFaceSrcs = fontFace.getSources(); int nFontFaceSrcs = fontFaceSrcs != null ? fontFaceSrcs.size() : 0; for(int n=0; n