/** * Copyright (C) 2014-2017 Philip Helger (www.helger.com) * philip[at]helger[dot]com * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.helger.css.reader; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import java.io.File; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.helger.commons.charset.EUnicodeBOM; import com.helger.commons.collection.ArrayHelper; import com.helger.commons.io.streamprovider.ByteArrayInputStreamProvider; import com.helger.css.ECSSVersion; import com.helger.css.decl.CSSDeclaration; import com.helger.css.decl.CSSExpressionMemberFunction; import com.helger.css.decl.CSSExpressionMemberMath; import com.helger.css.decl.CSSExpressionMemberTermSimple; import com.helger.css.decl.CSSExpressionMemberTermURI; import com.helger.css.decl.CSSStyleRule; import com.helger.css.decl.CascadingStyleSheet; import com.helger.css.decl.ICSSExpressionMember; import com.helger.css.reader.errorhandler.CollectingCSSParseErrorHandler; import com.helger.css.reader.errorhandler.DoNothingCSSParseErrorHandler; import com.helger.css.reader.errorhandler.LoggingCSSParseErrorHandler; import com.helger.css.writer.CSSWriter; import com.helger.css.writer.CSSWriterSettings; /** * Test reading CSS 3.0 stuff * * @author Philip Helger */ public final class CSSReader30SpecialFuncTest { private static final Logger s_aLogger = LoggerFactory.getLogger (CSSReader30SpecialFuncTest.class); @Test public void testReadSpecialGood () { final ECSSVersion eVersion = ECSSVersion.CSS30; final Charset aCharset = StandardCharsets.UTF_8; final File aFile = new File ("src/test/resources/testfiles/css30/good/artificial/test-postcss-cssnext.css"); final CascadingStyleSheet aCSS = CSSReader.readFromFile (aFile, aCharset, eVersion); assertNotNull (aCSS); final String sCSS = new CSSWriter (eVersion, false).getCSSAsString (aCSS); assertNotNull (sCSS); if (false) s_aLogger.info (sCSS); } @Test public void testReadExpressions () { final ECSSVersion eVersion = ECSSVersion.CSS30; final CSSWriterSettings aCSSWS = new CSSWriterSettings (eVersion, false); final Charset aCharset = StandardCharsets.UTF_8; final File aFile = new File ("src/test/resources/testfiles/css30/good/artificial/test-expression.css"); final CascadingStyleSheet aCSS = CSSReader.readFromFile (aFile, aCharset, eVersion); assertNotNull (aCSS); assertEquals (1, aCSS.getRuleCount ()); assertEquals (1, aCSS.getStyleRuleCount ()); final CSSStyleRule aSR = aCSS.getStyleRuleAtIndex (0); assertEquals ("div", aSR.getSelectorsAsCSSString (aCSSWS, 0)); assertEquals (23, aSR.getDeclarationCount ()); int i = 0; for (final CSSDeclaration aDecl : aSR.getAllDeclarations ()) { final String sExpectedName = Character.toString ((char) ('a' + i)); assertEquals (sExpectedName, aDecl.getProperty ()); ++i; } CSSDeclaration aDecl; ICSSExpressionMember aMember; // a: -5 aDecl = aSR.getDeclarationOfPropertyName ("a"); assertNotNull (aDecl); assertEquals (1, aDecl.getExpression ().getMemberCount ()); aMember = aDecl.getExpression ().getMemberAtIndex (0); assertTrue (aMember instanceof CSSExpressionMemberTermSimple); assertEquals ("-5", aMember.getAsCSSString (aCSSWS)); // b: +5 aDecl = aSR.getDeclarationOfPropertyName ("b"); assertNotNull (aDecl); assertEquals (1, aDecl.getExpression ().getMemberCount ()); aMember = aDecl.getExpression ().getMemberAtIndex (0); assertTrue (aMember instanceof CSSExpressionMemberTermSimple); assertEquals ("+5", aMember.getAsCSSString (aCSSWS)); // c: 5 aDecl = aSR.getDeclarationOfPropertyName ("c"); assertNotNull (aDecl); assertEquals (1, aDecl.getExpression ().getMemberCount ()); aMember = aDecl.getExpression ().getMemberAtIndex (0); assertTrue (aMember instanceof CSSExpressionMemberTermSimple); assertEquals ("5", aMember.getAsCSSString (aCSSWS)); // d: -5.12 aDecl = aSR.getDeclarationOfPropertyName ("d"); assertNotNull (aDecl); assertEquals (1, aDecl.getExpression ().getMemberCount ()); aMember = aDecl.getExpression ().getMemberAtIndex (0); assertTrue (aMember instanceof CSSExpressionMemberTermSimple); assertEquals ("-5.12", aMember.getAsCSSString (aCSSWS)); // e: +5.12 aDecl = aSR.getDeclarationOfPropertyName ("e"); assertNotNull (aDecl); assertEquals (1, aDecl.getExpression ().getMemberCount ()); aMember = aDecl.getExpression ().getMemberAtIndex (0); assertTrue (aMember instanceof CSSExpressionMemberTermSimple); assertEquals ("+5.12", aMember.getAsCSSString (aCSSWS)); // f: 5.12 aDecl = aSR.getDeclarationOfPropertyName ("f"); assertNotNull (aDecl); assertEquals (1, aDecl.getExpression ().getMemberCount ()); aMember = aDecl.getExpression ().getMemberAtIndex (0); assertTrue (aMember instanceof CSSExpressionMemberTermSimple); assertEquals ("5.12", aMember.getAsCSSString (aCSSWS)); // g: -5.12% aDecl = aSR.getDeclarationOfPropertyName ("g"); assertNotNull (aDecl); assertEquals (1, aDecl.getExpression ().getMemberCount ()); aMember = aDecl.getExpression ().getMemberAtIndex (0); assertTrue (aMember instanceof CSSExpressionMemberTermSimple); assertEquals ("-5.12%", aMember.getAsCSSString (aCSSWS)); // h: +5.12% aDecl = aSR.getDeclarationOfPropertyName ("h"); assertNotNull (aDecl); assertEquals (1, aDecl.getExpression ().getMemberCount ()); aMember = aDecl.getExpression ().getMemberAtIndex (0); assertTrue (aMember instanceof CSSExpressionMemberTermSimple); assertEquals ("+5.12%", aMember.getAsCSSString (aCSSWS)); // i: 5.12% aDecl = aSR.getDeclarationOfPropertyName ("i"); assertNotNull (aDecl); assertEquals (1, aDecl.getExpression ().getMemberCount ()); aMember = aDecl.getExpression ().getMemberAtIndex (0); assertTrue (aMember instanceof CSSExpressionMemberTermSimple); assertEquals ("5.12%", aMember.getAsCSSString (aCSSWS)); // j: -5px aDecl = aSR.getDeclarationOfPropertyName ("j"); assertNotNull (aDecl); assertEquals (1, aDecl.getExpression ().getMemberCount ()); aMember = aDecl.getExpression ().getMemberAtIndex (0); assertTrue (aMember instanceof CSSExpressionMemberTermSimple); assertEquals ("-5px", aMember.getAsCSSString (aCSSWS)); // k: +5px aDecl = aSR.getDeclarationOfPropertyName ("k"); assertNotNull (aDecl); assertEquals (1, aDecl.getExpression ().getMemberCount ()); aMember = aDecl.getExpression ().getMemberAtIndex (0); assertTrue (aMember instanceof CSSExpressionMemberTermSimple); assertEquals ("+5px", aMember.getAsCSSString (aCSSWS)); // l: 5px aDecl = aSR.getDeclarationOfPropertyName ("l"); assertNotNull (aDecl); assertEquals (1, aDecl.getExpression ().getMemberCount ()); aMember = aDecl.getExpression ().getMemberAtIndex (0); assertTrue (aMember instanceof CSSExpressionMemberTermSimple); assertEquals ("5px", aMember.getAsCSSString (aCSSWS)); // m: 'string1' aDecl = aSR.getDeclarationOfPropertyName ("m"); assertNotNull (aDecl); assertEquals (1, aDecl.getExpression ().getMemberCount ()); aMember = aDecl.getExpression ().getMemberAtIndex (0); assertTrue (aMember instanceof CSSExpressionMemberTermSimple); assertEquals ("'string1'", aMember.getAsCSSString (aCSSWS)); // n: "string2" aDecl = aSR.getDeclarationOfPropertyName ("n"); assertNotNull (aDecl); assertEquals (1, aDecl.getExpression ().getMemberCount ()); aMember = aDecl.getExpression ().getMemberAtIndex (0); assertTrue (aMember instanceof CSSExpressionMemberTermSimple); assertEquals ("\"string2\"", aMember.getAsCSSString (aCSSWS)); // o: abc aDecl = aSR.getDeclarationOfPropertyName ("o"); assertNotNull (aDecl); assertEquals (1, aDecl.getExpression ().getMemberCount ()); aMember = aDecl.getExpression ().getMemberAtIndex (0); assertTrue (aMember instanceof CSSExpressionMemberTermSimple); assertEquals ("abc", aMember.getAsCSSString (aCSSWS)); // p: from aDecl = aSR.getDeclarationOfPropertyName ("p"); assertNotNull (aDecl); assertEquals (1, aDecl.getExpression ().getMemberCount ()); aMember = aDecl.getExpression ().getMemberAtIndex (0); assertTrue (aMember instanceof CSSExpressionMemberTermSimple); assertEquals ("from", aMember.getAsCSSString (aCSSWS)); // q: to aDecl = aSR.getDeclarationOfPropertyName ("q"); assertNotNull (aDecl); assertEquals (1, aDecl.getExpression ().getMemberCount ()); aMember = aDecl.getExpression ().getMemberAtIndex (0); assertTrue (aMember instanceof CSSExpressionMemberTermSimple); assertEquals ("to", aMember.getAsCSSString (aCSSWS)); // r: url(a.gif) aDecl = aSR.getDeclarationOfPropertyName ("r"); assertNotNull (aDecl); assertEquals (1, aDecl.getExpression ().getMemberCount ()); aMember = aDecl.getExpression ().getMemberAtIndex (0); assertTrue (aMember instanceof CSSExpressionMemberTermURI); assertEquals ("url(a.gif)", aMember.getAsCSSString (aCSSWS)); // s: #123 aDecl = aSR.getDeclarationOfPropertyName ("s"); assertNotNull (aDecl); assertEquals (1, aDecl.getExpression ().getMemberCount ()); aMember = aDecl.getExpression ().getMemberAtIndex (0); assertTrue (aMember instanceof CSSExpressionMemberTermSimple); assertEquals ("#123", aMember.getAsCSSString (aCSSWS)); // t: function(5,6,abc) aDecl = aSR.getDeclarationOfPropertyName ("t"); assertNotNull (aDecl); assertEquals (1, aDecl.getExpression ().getMemberCount ()); aMember = aDecl.getExpression ().getMemberAtIndex (0); assertTrue (aMember instanceof CSSExpressionMemberFunction); assertEquals ("function", ((CSSExpressionMemberFunction) aMember).getFunctionName ()); // 3 parameters and 2 commas assertEquals (5, ((CSSExpressionMemberFunction) aMember).getExpression ().getMemberCount ()); assertEquals ("function(5,6,abc)", aMember.getAsCSSString (aCSSWS)); // u: calc(4 + 5) aDecl = aSR.getDeclarationOfPropertyName ("u"); assertNotNull (aDecl); assertEquals (1, aDecl.getExpression ().getMemberCount ()); aMember = aDecl.getExpression ().getMemberAtIndex (0); assertTrue (aMember instanceof CSSExpressionMemberMath); // 2 values and 1 operator assertEquals (3, ((CSSExpressionMemberMath) aMember).getMemberCount ()); assertEquals ("calc(4 + 5)", aMember.getAsCSSString (aCSSWS)); // v: inherit aDecl = aSR.getDeclarationOfPropertyName ("v"); assertNotNull (aDecl); assertEquals (1, aDecl.getExpression ().getMemberCount ()); aMember = aDecl.getExpression ().getMemberAtIndex (0); assertTrue (aMember instanceof CSSExpressionMemberTermSimple); assertEquals ("inherit", aMember.getAsCSSString (aCSSWS)); // w: u+1234 aDecl = aSR.getDeclarationOfPropertyName ("w"); assertNotNull (aDecl); assertEquals (1, aDecl.getExpression ().getMemberCount ()); aMember = aDecl.getExpression ().getMemberAtIndex (0); assertTrue (aMember instanceof CSSExpressionMemberTermSimple); assertEquals ("u+1234", aMember.getAsCSSString (aCSSWS)); // Write result final String sCSS = new CSSWriter (aCSSWS).getCSSAsString (aCSS); assertNotNull (sCSS); if (false) s_aLogger.info (sCSS); } @Test public void testReadSpecialBadButRecoverable () { final CollectingCSSParseErrorHandler aErrors = new CollectingCSSParseErrorHandler (); final ECSSVersion eVersion = ECSSVersion.CSS30; final Charset aCharset = StandardCharsets.UTF_8; final File aFile = new File ("src/test/resources/testfiles/css30/bad_but_recoverable_and_browsercompliant/test-string.css"); final CascadingStyleSheet aCSS = CSSReader.readFromFile (aFile, aCharset, eVersion, aErrors.and (new LoggingCSSParseErrorHandler ())); assertNotNull (aFile.getAbsolutePath (), aCSS); } @Test public void testReadWithBOM () { final String sCSSBase = "/* comment */.class{color:red}.class{color:blue}"; for (final EUnicodeBOM eBOM : EUnicodeBOM.values ()) { final Charset aDeterminedCharset = eBOM.getCharset (); if (aDeterminedCharset != null) { final CascadingStyleSheet aCSS = CSSReader.readFromStream (new ByteArrayInputStreamProvider (ArrayHelper.getConcatenated (eBOM.getAllBytes (), sCSSBase.getBytes (aDeterminedCharset))), aDeterminedCharset, ECSSVersion.CSS30, new DoNothingCSSParseErrorHandler ()); assertNotNull ("Failed to read with BOM " + eBOM, aCSS); assertEquals (".class{color:red}.class{color:blue}", new CSSWriter (ECSSVersion.CSS30, true).getCSSAsString (aCSS)); } } } @Test public void testReadSingleLineComments () { final ECSSVersion eVersion = ECSSVersion.CSS30; final Charset aCharset = StandardCharsets.UTF_8; final File aFile = new File ("src/test/resources/testfiles/css30/good/artificial/test-singleline-comments.css"); final CascadingStyleSheet aCSS = CSSReader.readFromFile (aFile, aCharset, eVersion); assertNotNull (aCSS); assertEquals (13, aCSS.getRuleCount ()); assertEquals (13, aCSS.getStyleRuleCount ()); // #any1 - #any5 assertEquals (2, aCSS.getStyleRuleAtIndex (1).getDeclarationCount ()); assertEquals (1, aCSS.getStyleRuleAtIndex (2).getDeclarationCount ()); assertEquals (1, aCSS.getStyleRuleAtIndex (3).getDeclarationCount ()); assertEquals (0, aCSS.getStyleRuleAtIndex (4).getDeclarationCount ()); assertEquals (0, aCSS.getStyleRuleAtIndex (5).getDeclarationCount ()); // .test1 - .test7 assertEquals (2, aCSS.getStyleRuleAtIndex (6).getDeclarationCount ()); assertEquals (3, aCSS.getStyleRuleAtIndex (7).getDeclarationCount ()); assertEquals (1, aCSS.getStyleRuleAtIndex (8).getDeclarationCount ()); assertEquals (1, aCSS.getStyleRuleAtIndex (9).getDeclarationCount ()); assertEquals (2, aCSS.getStyleRuleAtIndex (10).getDeclarationCount ()); assertEquals (2, aCSS.getStyleRuleAtIndex (11).getDeclarationCount ()); assertEquals (1, aCSS.getStyleRuleAtIndex (12).getDeclarationCount ()); } }