/*******************************************************************************
* Copyright (c) 2014 Stefan Winkler and others. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Stefan Winkler <stefan@winklerweb.net> - initial API and implementation
* Lars Vogel <Lars.Vogel@gmail.com> - Bug 430468
* Daniel Raap <raap@subshell.com> - Bug 511836
******************************************************************************/
package org.eclipse.e4.ui.tests.css.core.parser;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.StringReader;
import org.eclipse.e4.ui.css.core.engine.CSSEngine;
import org.eclipse.e4.ui.css.core.impl.dom.DocumentCSSImpl;
import org.eclipse.e4.ui.css.core.impl.dom.ViewCSSImpl;
import org.eclipse.e4.ui.tests.css.core.util.ParserTestUtil;
import org.eclipse.e4.ui.tests.css.core.util.TestElement;
import org.junit.Before;
import org.junit.Test;
import org.w3c.css.sac.InputSource;
import org.w3c.dom.css.CSSRule;
import org.w3c.dom.css.CSSRuleList;
import org.w3c.dom.css.CSSStyleDeclaration;
import org.w3c.dom.css.CSSStyleSheet;
import org.w3c.dom.css.ViewCSS;
import org.w3c.dom.stylesheets.StyleSheet;
import org.w3c.dom.stylesheets.StyleSheetList;
public class ImportTest {
private CSSEngine engine;
@Before
public void setUp() {
engine = ParserTestUtil.createEngine();
}
/**
* Test case for Bug 430052 - [CSS] Imported rules cannot be overridden
*
* @throws Exception
*/
@Test
public void testOverrideImportedRule() throws Exception {
String importedCss = ".ClassAlpha {\n" //
+ " property: value;\n" //
+ " }\n" + " .ClassBeta {\n" //
+ " property: value1;\n" //
+ " }";
File importedFile = createTempCssFile(importedCss);
String importingCss = createImport(importedFile) //
+ " .ClassBeta {\n" //
+ " property: value2;\n" //
+ " }";
// we need a file URL so that the import can be resolved
String importedFolderPath = importedFile.getParent();
String importingUrl = "file:///" + importedFolderPath + "/importing.css";
ViewCSS viewCSS = createViewCss(importingUrl, importingCss);
TestElement buttonAlpha = new TestElement("Button", engine);
buttonAlpha.setClass("ClassAlpha");
TestElement buttonBeta = new TestElement("Button", engine);
buttonBeta.setClass("ClassBeta");
CSSStyleDeclaration styleAlpha = viewCSS.getComputedStyle(buttonAlpha,
null);
CSSStyleDeclaration styleBeta = viewCSS.getComputedStyle(buttonBeta,
null);
assertEquals("value", styleAlpha.getPropertyCSSValue("property")
.getCssText());
assertEquals("value2", styleBeta.getPropertyCSSValue("property")
.getCssText());
}
/**
* Test for [CSS] nested imports duplicate rules
*/
@Test
public void testNestedImports() throws IOException {
String deepNestedCss = "ChildChild { property: value; }\n";
File importedFile = createTempCssFile(deepNestedCss);
String childStyle = "Child { property: value; }\n";
String childCss = createImport(importedFile) + childStyle;
importedFile = createTempCssFile(childCss);
String rootStyle = "Root { property: value; }\n";
String rootCss = createImport(importedFile) + rootStyle;
// we need a file URL so that the import can be resolved
String importedFolderPath = importedFile.getParent();
String importingUrl = "file:///" + importedFolderPath + "/root.css";
CSSStyleSheet result = parseStyleSheet(importingUrl, rootCss);
// check the parsing result
assertNotNull(result);
CSSRuleList cssRules = result.getCssRules();
assertEquals(3, cssRules.getLength());
assertStyle(deepNestedCss, cssRules, 0);
assertStyle(childStyle, cssRules, 1);
assertStyle(rootStyle, cssRules, 2);
// check the full DocumentCSS of the engine
StyleSheetList documentStyleSheets = engine.getDocumentCSS().getStyleSheets();
assertEquals(1, documentStyleSheets.getLength());
StyleSheet documentStyleSheet = documentStyleSheets.item(0);
assertEquals(result, documentStyleSheet);
}
private void assertStyle(String expectedStyleText, CSSRuleList cssRules, int index) {
assertEquals(CSSRule.STYLE_RULE, cssRules.item(index).getType());
assertEquals(expectedStyleText.trim(), cssRules.item(index).getCssText());
}
private File createTempCssFile(String cssString) throws IOException {
File result = File.createTempFile("e4.ui.tests-", ".css");
try (FileWriter fileWriter = new FileWriter(result)) {
fileWriter.write(cssString);
return result;
}
}
private String createImport(File importedFile) {
String cssUrl = importedFile.getName();
return "@import url('" + cssUrl + "');\n";
}
private CSSStyleSheet parseStyleSheet(String sourceUrl, String cssString) throws IOException {
InputSource source = new InputSource();
source.setURI(sourceUrl); // must not be null
source.setCharacterStream(new StringReader(cssString));
return (CSSStyleSheet) engine.parseStyleSheet(source);
}
private ViewCSS createViewCss(String sourceUrl, String cssString)
throws IOException {
StyleSheet styleSheet = parseStyleSheet(sourceUrl, cssString);
DocumentCSSImpl docCss = new DocumentCSSImpl();
docCss.addStyleSheet(styleSheet);
return new ViewCSSImpl(docCss);
}
}