Java tutorial
/* * (C) Copyright 2012, IBM Corporation * * 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.ibm.jaggr.core.impl.modulebuilder.css; import com.ibm.jaggr.core.IAggregator; import com.ibm.jaggr.core.NotFoundException; import com.ibm.jaggr.core.cachekeygenerator.ICacheKeyGenerator; import com.ibm.jaggr.core.cachekeygenerator.KeyGenUtil; import com.ibm.jaggr.core.config.IConfig; import com.ibm.jaggr.core.impl.config.ConfigImpl; import com.ibm.jaggr.core.impl.modulebuilder.css.CSSModuleBuilder; import com.ibm.jaggr.core.impl.resource.FileResource; import com.ibm.jaggr.core.options.IOptions; import com.ibm.jaggr.core.resource.IResource; import com.ibm.jaggr.core.resource.StringResource; import com.ibm.jaggr.core.test.TestUtils; import com.ibm.jaggr.core.test.TestUtils.Ref; import com.ibm.jaggr.core.transport.IHttpTransport; import com.ibm.jaggr.core.util.CopyUtil; import org.apache.commons.codec.binary.Base64; import org.easymock.EasyMock; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.mozilla.javascript.Scriptable; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileWriter; import java.io.IOException; import java.io.OutputStream; import java.io.Reader; import java.io.StringWriter; import java.net.URI; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.regex.Pattern; import javax.servlet.http.HttpServletRequest; import junit.framework.Assert; public class CSSModuleBuilderTest extends EasyMock { static File tmpdir; static File testdir; static final String base64PngData = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAASCAYAAACaV7S8AAAAAXNSR0IArs4c6QAAACNJREFUCNdj+P///0cmBgaGJ0wMDAyPsbAgXIb////zMZACAIj0DUFA3QqvAAAAAElFTkSuQmCC"; Map<String, String[]> requestParams = new HashMap<String, String[]>(); Map<String, Object> requestAttributes = new HashMap<String, Object>(); Scriptable configScript; IAggregator mockAggregator; Ref<IConfig> configRef; HttpServletRequest mockRequest; CSSModuleBuilderTester builder = new CSSModuleBuilderTester(); List<ICacheKeyGenerator> keyGens = builder.getCacheKeyGenerators(mockAggregator); long seq = 1; class CSSModuleBuilderTester extends CSSModuleBuilder { @Override protected Reader getContentReader(String mid, IResource resource, HttpServletRequest request, List<ICacheKeyGenerator> keyGens) throws IOException { return super.getContentReader(mid, resource, request, keyGens); } } @BeforeClass public static void setUpBeforeClass() throws Exception { tmpdir = new File(System.getProperty("java.io.tmpdir")); testdir = new File(tmpdir, "CSSModuleBuilderTest"); testdir.mkdir(); } @AfterClass public static void tearDownAfterClass() throws Exception { TestUtils.deleteRecursively(testdir); } @Before public void setUp() throws Exception { configRef = new Ref<IConfig>(null); mockAggregator = TestUtils.createMockAggregator(configRef, testdir); mockRequest = TestUtils.createMockRequest(mockAggregator, requestAttributes, requestParams, null, null); replay(mockRequest); replay(mockAggregator); IConfig cfg = new ConfigImpl(mockAggregator, tmpdir.toURI(), "{}"); configRef.set(cfg); configScript = (Scriptable) cfg.getRawConfig(); } @After public void tearDown() throws Exception { } @Test public void testMinify() throws Exception { // test comment and white space removal String css, output; // Get a URI to the test resources. Note that we can't use the class loader // here do to the fact that it gets confused by the split packages. URI resuri = testdir.toURI(); css = "/* comments */\r\n.foo\t { \tcolor:black; \r\nfont-weight : bold;\r\n/* inline comment */ }\r\n/* trailing comment */\n\t.bar { font-size:small } \r\n"; output = buildCss(new StringResource(css, resuri)); Assert.assertEquals(".foo{color:black;font-weight:bold} .bar{font-size:small}", output); // create file to import css = "/* Importe file */\r\n\r\n.imported {\r\n\tcolor : black;\r\n}"; CopyUtil.copy(css, new FileWriter(new File(testdir, "imported.css"))); /* * Make sure imports are not inlined by default */ css = "/* importing file */\n\r@import \"imported.css\""; output = buildCss(new StringResource(css, resuri)); Assert.assertEquals("@import \"imported.css\"", output); /* * Make sure that quoted strings and url(...) patterns are not * minified */ css = "/* importing file */\n\r@import \"name with spaces.css\"\r\n@import url(name with spaces.css)\r\n@import url( \" name with spaces.css\" )\r\n"; output = buildCss(new StringResource(css, resuri)); Assert.assertEquals( "@import \"name with spaces.css\" @import url(name with spaces.css) @import url(\" name with spaces.css\")", output); css = "/* importing file */\n\r@import 'name with spaces.css'\r\n@import url( ' name with spaces.css' )\r\n"; output = buildCss(new StringResource(css, resuri)); Assert.assertEquals("@import 'name with spaces.css' @import url(' name with spaces.css')", output); /* * test odd-ball use cases that might break us */ css = "@import \"funny name with url(...) inside.css\" .foo { color : black }"; output = buildCss(new StringResource(css, resuri)); Assert.assertEquals("@import \"funny name with url(...) inside.css\" .foo{color:black}", output); css = "@import url( funny name ' with \"embedded \" quotes.css ) .foo { color : black }"; output = buildCss(new StringResource(css, resuri)); Assert.assertEquals("@import url(funny name ' with \"embedded \" quotes.css) .foo{color:black}", output); css = "@import \"funny 'name' with url(\"...\") and embedded quotes inside.css\" .foo { color : black }"; output = buildCss(new StringResource(css, resuri)); Assert.assertEquals( "@import \"funny 'name' with url(\"...\") and embedded quotes inside.css\" .foo{color:black}", output); css = "@import url( 'funny name with \" single double quote.css' ) .foo { color : black }"; output = buildCss(new StringResource(css, resuri)); Assert.assertEquals("@import url('funny name with \" single double quote.css') .foo{color:black}", output); css = "@import 'funny name \"with double\" quote.css' .foo { color : black }"; output = buildCss(new StringResource(css, resuri)); Assert.assertEquals("@import 'funny name \"with double\" quote.css' .foo{color:black}", output); css = ".foo:after{content:\"\\a\";white-space:pre}"; output = buildCss(new StringResource(css, resuri)); Assert.assertEquals(css, output); } @Test public void testImport() throws Exception { String css, output; URI resuri = testdir.toURI(); // create file to import css = "/* Importe file */\r\n\r\n.imported {\r\n\tcolor : black;\r\n}"; CopyUtil.copy(css, new FileWriter(new File(testdir, "imported.css"))); /* * Make sure imported css files get inlined */ configScript.put(CSSModuleBuilder.INLINEIMPORTS_REQPARAM_NAME, configScript, Boolean.TRUE); IConfig config = new ConfigImpl(mockAggregator, tmpdir.toURI(), configScript); builder.configLoaded(config, seq++); css = "/* importing file */\n\r@import \"imported.css\""; output = buildCss(new StringResource(css, resuri)); Assert.assertEquals(".imported{color:black}", output); // Test relative url resolution css = "/* importing file */\n\r@import \"./imported.css\""; output = buildCss(new StringResource(css, resuri)); Assert.assertEquals(".imported{color:black}", output); css = "/* importing file */\n\r@import url(\"././imported.css\")"; output = buildCss(new StringResource(css, resuri)); Assert.assertEquals(".imported{color:black}", output); css = "/* importing file */\n\r@import url('foo/../imported.css')"; output = buildCss(new StringResource(css, resuri)); Assert.assertEquals(".imported{color:black}", output); css = "/* importing file */\n\r@import url( \"./foo/bar/.././../imported.css\" )"; output = buildCss(new StringResource(css, resuri)); Assert.assertEquals(".imported{color:black}", output); css = "/* importing file */\n\r@import \"foo/bar/../../imported.css\""; output = buildCss(new StringResource(css, resuri)); Assert.assertEquals(".imported{color:black}", output); // Test forced LESS import css = "/* importing file */\n\r@import (less) \"imported.css\""; output = buildCss(new StringResource(css, resuri)); Assert.assertEquals(".imported{color:black}", output); // This should fail css = "/* importing file */\n\r@import \"foo/imported.css\""; boolean exceptionCaught = false; try { output = buildCss(new StringResource(css, resuri)); } catch (FileNotFoundException e) { exceptionCaught = true; } Assert.assertTrue("Expected FileNotFoundException", exceptionCaught); css = "/* Importe file */\r\n\r\n.background-image: url( \"images/img.jpg\" );"; CopyUtil.copy(css, new FileWriter(new File(testdir, "imported.css"))); output = buildCss(new StringResource(css, resuri)); Assert.assertEquals(".background-image:url(\"images/img.jpg\");", output); File subdir = new File(testdir, "subdir"); File imported = new File(subdir, "imported.css"); subdir.mkdir(); String importedCss = "/* Importe file */\r\n\r\n.background-image: url( \"images/img.jpg\" );"; CopyUtil.copy(importedCss, new FileWriter(imported)); css = "/* importing file */\n\r@import \"subdir/imported.css\""; output = buildCss(new StringResource(css, resuri)); Assert.assertEquals(".background-image:url(\"subdir/images/img.jpg\");", output); // test imported path normalizing importedCss = "/* Importe file */\r\n\r\n.background-image: url('./images/./img.jpg' );"; CopyUtil.copy(importedCss, new FileWriter(imported)); output = buildCss(new StringResource(css, resuri)); Assert.assertEquals(".background-image:url('subdir/images/img.jpg');", output); importedCss = "/* Importe file */\r\n\r\n.background-image: url( \"./images/foo/../img.jpg\" );"; CopyUtil.copy(importedCss, new FileWriter(imported)); output = buildCss(new StringResource(css, resuri)); Assert.assertEquals(".background-image:url(\"subdir/images/img.jpg\");", output); importedCss = "/* Importe file */\r\n\r\n.background-image: url(./images/foo/bar/../../img.jpg);"; CopyUtil.copy(importedCss, new FileWriter(imported)); output = buildCss(new StringResource(css, resuri)); Assert.assertEquals(".background-image:url(subdir/images/img.jpg);", output); importedCss = "/* Importe file */\r\n\r\n.background-image: url( images/../images/img.jpg );"; CopyUtil.copy(importedCss, new FileWriter(imported)); output = buildCss(new StringResource(css, resuri)); Assert.assertEquals(".background-image:url(subdir/images/img.jpg);", output); importedCss = "/* Importe file */\r\n\r\n.background-image: url( '/images/img.jpg' );"; CopyUtil.copy(importedCss, new FileWriter(imported)); output = buildCss(new StringResource(css, resuri)); Assert.assertEquals(".background-image:url('/images/img.jpg');", output); importedCss = "/* Importe file */\r\n\r\n.background-image: url( 'http://server.com/images/img.jpg' );"; CopyUtil.copy(importedCss, new FileWriter(imported)); output = buildCss(new StringResource(css, resuri)); Assert.assertEquals(".background-image:url('http://server.com/images/img.jpg');", output); importedCss = "/* Importe file */\r\n\r\n.background-image: url( '#images/img.jpg' );"; CopyUtil.copy(importedCss, new FileWriter(imported)); output = buildCss(new StringResource(css, resuri)); Assert.assertEquals(".background-image:url('#images/img.jpg');", output); // Make sure we can disable inlining of imports by request parameter requestParams.put(CSSModuleBuilder.INLINEIMPORTS_REQPARAM_NAME, new String[] { "false" }); output = buildCss(new StringResource(css, resuri)); Assert.assertEquals("@import \"subdir/imported.css\"", output); requestParams.put(CSSModuleBuilder.INLINEIMPORTS_REQPARAM_NAME, new String[] { "true" }); output = buildCss(new StringResource(css, resuri)); Assert.assertEquals(".background-image:url('#images/img.jpg');", output); requestParams.put(CSSModuleBuilder.INLINEIMPORTS_REQPARAM_NAME, new String[] { "0" }); output = buildCss(new StringResource(css, resuri)); Assert.assertEquals("@import \"subdir/imported.css\"", output); requestParams.put(CSSModuleBuilder.INLINEIMPORTS_REQPARAM_NAME, new String[] { "1" }); output = buildCss(new StringResource(css, resuri)); Assert.assertEquals(".background-image:url('#images/img.jpg');", output); // make sure we can output filenames if requested and development mode is enabled requestAttributes.put(IHttpTransport.SHOWFILENAMES_REQATTRNAME, Boolean.TRUE); output = buildCss(new StringResource(css, resuri)); Assert.assertEquals(".background-image:url('#images/img.jpg');", output); mockAggregator.getOptions().setOption(IOptions.DEVELOPMENT_MODE, "true"); output = buildCss(new StringResource(css, resuri)); Assert.assertEquals("/* @import subdir/imported.css */ .background-image:url('#images/img.jpg');", output); requestAttributes.remove(IHttpTransport.SHOWFILENAMES_REQATTRNAME); output = buildCss(new StringResource(css, resuri)); Assert.assertEquals(".background-image:url('#images/img.jpg');", output); } @Test public void testInlineUrls() throws Exception { String css, output; URI resuri = testdir.toURI(); // Test image inlining options byte[] bytes = Base64.decodeBase64(base64PngData.getBytes()); File images = new File(testdir, "images"); images.mkdir(); File image = new File(images, "testImage.png"); OutputStream out = new FileOutputStream(image); ByteArrayInputStream in = new ByteArrayInputStream(bytes); CopyUtil.copy(in, out); css = ".foo {background-image:url(images/testImage.png)}"; output = buildCss(new StringResource(css, resuri)); Assert.assertEquals(".foo{background-image:url(images/testImage.png)}", output); configScript.put(CSSModuleBuilder.INLINEIMPORTS_CONFIGPARAM, configScript, "true"); IConfig config = new ConfigImpl(mockAggregator, tmpdir.toURI(), configScript); builder.configLoaded(config, seq++); output = buildCss(new StringResource(css, resuri)); long size = image.length(); configScript.put(CSSModuleBuilder.SIZETHRESHOLD_CONFIGPARAM, configScript, Long.toString(size)); config = new ConfigImpl(mockAggregator, tmpdir.toURI(), configScript); builder.configLoaded(config, seq++); output = buildCss(new StringResource(css, resuri)); Assert.assertTrue( output.matches("\\.foo\\{background-image:url\\('data:image\\/png;base64\\,[^']*'\\)\\}")); // Test with quotes and spaces in URL parameter css = ".foo {background-image:url('images/testImage.png')}"; output = buildCss(new StringResource(css, resuri)); Assert.assertTrue( output.matches("\\.foo\\{background-image:url\\('data:image\\/png;base64\\,[^']*'\\)\\}")); css = ".foo {background-image:url(\"images/testImage.png\")}"; output = buildCss(new StringResource(css, resuri)); Assert.assertTrue( output.matches("\\.foo\\{background-image:url\\('data:image\\/png;base64\\,[^']*'\\)\\}")); css = ".foo {background-image:url( 'images/testImage.png' )}"; output = buildCss(new StringResource(css, resuri)); Assert.assertTrue( output.matches("\\.foo\\{background-image:url\\('data:image\\/png;base64\\,[^']*'\\)\\}")); // Set the size threshold just below the image size and make sure the image isn't inlined css = ".foo {background-image:url(images/testImage.png)}"; output = buildCss(new StringResource(css, resuri)); size--; configScript.put(CSSModuleBuilder.SIZETHRESHOLD_CONFIGPARAM, configScript, Long.toString(size)); config = new ConfigImpl(mockAggregator, tmpdir.toURI(), configScript); builder.configLoaded(config, seq++); output = buildCss(new StringResource(css, resuri)); Assert.assertEquals(".foo{background-image:url(images/testImage.png)}", output); size++; configScript.put(CSSModuleBuilder.SIZETHRESHOLD_CONFIGPARAM, configScript, Long.toString(size)); config = new ConfigImpl(mockAggregator, tmpdir.toURI(), configScript); builder.configLoaded(config, seq++); output = buildCss(new StringResource(css, resuri)); Assert.assertTrue( output.matches("\\.foo\\{background-image:url\\('data:image\\/png;base64\\,[^']*'\\)\\}")); // Make sure we can disable image inlining by request parameter requestParams.put(CSSModuleBuilder.INLINEIMAGES_REQPARAM_NAME, new String[] { "false" }); config = new ConfigImpl(mockAggregator, tmpdir.toURI(), configScript); builder.configLoaded(config, seq++); output = buildCss(new StringResource(css, resuri)); Assert.assertEquals(".foo{background-image:url(images/testImage.png)}", output); requestParams.put(CSSModuleBuilder.INLINEIMAGES_REQPARAM_NAME, new String[] { "true" }); config = new ConfigImpl(mockAggregator, tmpdir.toURI(), configScript); builder.configLoaded(config, seq++); output = buildCss(new StringResource(css, resuri)); Assert.assertTrue( output.matches("\\.foo\\{background-image:url\\('data:image\\/png;base64\\,[^']*'\\)\\}")); // Make sure that the image is inlined if it is specifically included configScript.put(CSSModuleBuilder.SIZETHRESHOLD_CONFIGPARAM, configScript, Long.toString(0)); configScript.put(CSSModuleBuilder.INCLUDELIST_CONFIGPARAM, configScript, "testImage.png"); config = new ConfigImpl(mockAggregator, tmpdir.toURI(), configScript); builder.configLoaded(config, seq++); output = buildCss(new StringResource(css, resuri)); Assert.assertTrue( output.matches("\\.foo\\{background-image:url\\('data:image\\/png;base64\\,[^']*'\\)\\}")); // Test wildcard matching algorithm for include/exclude filenames configScript.put(CSSModuleBuilder.INCLUDELIST_CONFIGPARAM, configScript, "*.png"); config = new ConfigImpl(mockAggregator, tmpdir.toURI(), configScript); builder.configLoaded(config, seq++); output = buildCss(new StringResource(css, resuri)); Assert.assertTrue( output.matches("\\.foo\\{background-image:url\\('data:image\\/png;base64\\,[^']*'\\)\\}")); configScript.put(CSSModuleBuilder.INCLUDELIST_CONFIGPARAM, configScript, "testImage*"); config = new ConfigImpl(mockAggregator, tmpdir.toURI(), configScript); builder.configLoaded(config, seq++); output = buildCss(new StringResource(css, resuri)); Assert.assertTrue( output.matches("\\.foo\\{background-image:url\\('data:image\\/png;base64\\,[^']*'\\)\\}")); configScript.put(CSSModuleBuilder.INCLUDELIST_CONFIGPARAM, configScript, "*"); config = new ConfigImpl(mockAggregator, tmpdir.toURI(), configScript); builder.configLoaded(config, seq++); output = buildCss(new StringResource(css, resuri)); Assert.assertTrue( output.matches("\\.foo\\{background-image:url\\('data:image\\/png;base64\\,[^']*'\\)\\}")); configScript.put(CSSModuleBuilder.INCLUDELIST_CONFIGPARAM, configScript, "*Image.pn?"); config = new ConfigImpl(mockAggregator, tmpdir.toURI(), configScript); builder.configLoaded(config, seq++); output = buildCss(new StringResource(css, resuri)); Assert.assertTrue( output.matches("\\.foo\\{background-image:url\\('data:image\\/png;base64\\,[^']*'\\)\\}")); configScript.put(CSSModuleBuilder.INCLUDELIST_CONFIGPARAM, configScript, "test*.png"); config = new ConfigImpl(mockAggregator, tmpdir.toURI(), configScript); builder.configLoaded(config, seq++); output = buildCss(new StringResource(css, resuri)); Assert.assertTrue( output.matches("\\.foo\\{background-image:url\\('data:image\\/png;base64\\,[^']*'\\)\\}")); configScript.put(CSSModuleBuilder.INCLUDELIST_CONFIGPARAM, configScript, "te?tIma???png"); config = new ConfigImpl(mockAggregator, tmpdir.toURI(), configScript); builder.configLoaded(config, seq++); output = buildCss(new StringResource(css, resuri)); Assert.assertTrue( output.matches("\\.foo\\{background-image:url\\('data:image\\/png;base64\\,[^']*'\\)\\}")); configScript.put(CSSModuleBuilder.INCLUDELIST_CONFIGPARAM, configScript, "testImage.*png"); config = new ConfigImpl(mockAggregator, tmpdir.toURI(), configScript); builder.configLoaded(config, seq++); output = buildCss(new StringResource(css, resuri)); Assert.assertTrue( output.matches("\\.foo\\{background-image:url\\('data:image\\/png;base64\\,[^']*'\\)\\}")); configScript.put(CSSModuleBuilder.INCLUDELIST_CONFIGPARAM, configScript, "???Image.png"); config = new ConfigImpl(mockAggregator, tmpdir.toURI(), configScript); builder.configLoaded(config, seq++); output = buildCss(new StringResource(css, resuri)); Assert.assertEquals(".foo{background-image:url(images/testImage.png)}", output); configScript.put(CSSModuleBuilder.INCLUDELIST_CONFIGPARAM, configScript, "test*.??"); config = new ConfigImpl(mockAggregator, tmpdir.toURI(), configScript); builder.configLoaded(config, seq++); output = buildCss(new StringResource(css, resuri)); Assert.assertEquals(".foo{background-image:url(images/testImage.png)}", output); // Ensure exclude list overrides include list configScript.put(CSSModuleBuilder.INCLUDELIST_CONFIGPARAM, configScript, "*"); configScript.put(CSSModuleBuilder.EXCLUDELIST_CONFIGPARAM, configScript, "*.png"); config = new ConfigImpl(mockAggregator, tmpdir.toURI(), configScript); builder.configLoaded(config, seq++); output = buildCss(new StringResource(css, resuri)); Assert.assertEquals(".foo{background-image:url(images/testImage.png)}", output); configScript.put(CSSModuleBuilder.INCLUDELIST_CONFIGPARAM, configScript, "testImage.png"); configScript.put(CSSModuleBuilder.EXCLUDELIST_CONFIGPARAM, configScript, "testImage.png"); config = new ConfigImpl(mockAggregator, tmpdir.toURI(), configScript); builder.configLoaded(config, seq++); output = buildCss(new StringResource(css, resuri)); Assert.assertEquals(".foo{background-image:url(images/testImage.png)}", output); CopyUtil.copy("hello world!\r\n", new FileWriter(new File(testdir, "hello.txt"))); css = ".foo {background-image:url(hello.txt)}"; configScript.put(CSSModuleBuilder.SIZETHRESHOLD_CONFIGPARAM, configScript, Long.toString(size)); config = new ConfigImpl(mockAggregator, tmpdir.toURI(), configScript); builder.configLoaded(config, seq++); output = buildCss(new StringResource(css, resuri)); Assert.assertEquals(".foo{background-image:url(hello.txt)}", output); // Should not be inlined because there's still an include list configScript.put(CSSModuleBuilder.IMAGETYPES_CONFIGPARAM, configScript, "text/plain"); config = new ConfigImpl(mockAggregator, tmpdir.toURI(), configScript); builder.configLoaded(config, seq++); output = buildCss(new StringResource(css, resuri)); Assert.assertEquals(".foo{background-image:url(hello.txt)}", output); // Remove the include list and now we should be able to load the new content type configScript.delete(CSSModuleBuilder.INCLUDELIST_CONFIGPARAM); config = new ConfigImpl(mockAggregator, tmpdir.toURI(), configScript); builder.configLoaded(config, seq++); output = buildCss(new StringResource(css, resuri)); Assert.assertTrue( output.matches("\\.foo\\{background-image:url\\('data:text\\/plain;base64\\,[^']*'\\)\\}")); // Ensure exclude list overrides content type list configScript.put(CSSModuleBuilder.EXCLUDELIST_CONFIGPARAM, configScript, "*.txt"); config = new ConfigImpl(mockAggregator, tmpdir.toURI(), configScript); builder.configLoaded(config, seq++); output = buildCss(new StringResource(css, resuri)); Assert.assertEquals(".foo{background-image:url(hello.txt)}", output); // Make sure type content/unknown lets us load anything not excluded CopyUtil.copy("hello world!\r\n", new FileWriter(new File(testdir, "hello.foo"))); css = ".foo {background-image:url(hello.foo)}"; configScript.put(CSSModuleBuilder.IMAGETYPES_CONFIGPARAM, configScript, "content/unknown"); config = new ConfigImpl(mockAggregator, tmpdir.toURI(), configScript); builder.configLoaded(config, seq++); output = buildCss(new StringResource(css, resuri)); Assert.assertTrue( output.matches("\\.foo\\{background-image:url\\('data:content\\/unknown;base64\\,[^']*'\\)\\}")); // Test specifying inlineableImageTypes as property map works. CopyUtil.copy("hello world!\r\n", new FileWriter(new File(testdir, "hello.svg"))); css = ".hello {background-image:url(hello.svg)}"; String cfg = "{" + CSSModuleBuilder.IMAGETYPES_CONFIGPARAM + ":{svg:'image/svg+xml'}," + CSSModuleBuilder.SIZETHRESHOLD_CONFIGPARAM + ":1000}"; config = new ConfigImpl(mockAggregator, tmpdir.toURI(), cfg); builder.configLoaded(config, seq++); output = buildCss(new StringResource(css, resuri)); Assert.assertTrue( output.matches("\\.hello\\{background-image:url\\('data:image\\/svg\\+xml;base64\\,[^']*'\\)\\}")); } @Test public void testCacheKeyGen() throws Exception { List<ICacheKeyGenerator> keyGens = builder.getCacheKeyGenerators(mockAggregator); Assert.assertEquals("expn:0;css:0:0:0:0", KeyGenUtil.generateKey(mockRequest, keyGens)); requestParams.put(CSSModuleBuilder.INLINEIMAGES_REQPARAM_NAME, new String[] { "true" }); Assert.assertEquals("expn:0;css:0:1:0:0", KeyGenUtil.generateKey(mockRequest, keyGens)); requestParams.put(CSSModuleBuilder.INLINEIMPORTS_REQPARAM_NAME, new String[] { "true" }); Assert.assertEquals("expn:0;css:1:1:0:0", KeyGenUtil.generateKey(mockRequest, keyGens)); requestAttributes.put(IHttpTransport.EXPORTMODULENAMES_REQATTRNAME, Boolean.TRUE); Assert.assertEquals("expn:1;css:1:1:0:0", KeyGenUtil.generateKey(mockRequest, keyGens)); requestAttributes.put(IHttpTransport.SHOWFILENAMES_REQATTRNAME, Boolean.TRUE); Assert.assertEquals("expn:1;css:1:1:1:0", KeyGenUtil.generateKey(mockRequest, keyGens)); requestAttributes.put(CSSModuleBuilder.INCLUDEAMDPATHS_CONFIGPARAM, Boolean.TRUE); Assert.assertEquals("expn:1;css:1:1:1:1", KeyGenUtil.generateKey(mockRequest, keyGens)); } @Test public void testToRegexp() { CSSModuleBuilder builder = new CSSModuleBuilder() { @Override public Pattern toRegexp(String filespec) { return super.toRegexp(filespec); } }; Pattern regexp = builder.toRegexp("test?.*"); Assert.assertEquals("(^|/)test[^/]\\.[^/]*?$", regexp.toString()); Assert.assertTrue(regexp.matcher("test1.abc").find()); Assert.assertFalse(regexp.matcher("test11.abc").find()); Assert.assertTrue(regexp.matcher("/test1.abc").find()); Assert.assertTrue(regexp.matcher("/some/path/test1.abc").find()); regexp = builder.toRegexp("test/*/hello@$!.???"); Assert.assertEquals("(^|/)test/[^/]*?/hello@\\$!\\.[^/][^/][^/]$", regexp.toString()); Assert.assertTrue(regexp.matcher("test/abc/hello@$!.foo").find()); Assert.assertTrue(regexp.matcher("/test/xyz/hello@$!.123").find()); Assert.assertTrue(regexp.matcher("somepath/test/xyz/hello@$!.123").find()); Assert.assertFalse(regexp.matcher("/test/xyz/hello@$!.ab").find()); Assert.assertFalse(regexp.matcher("/test/hello@$!.123").find()); regexp = builder.toRegexp("/a?c"); Assert.assertEquals("/a[^/]c$", regexp.toString()); } @Test public void testNonRelativeImports() throws Exception { String css, output; //create a subdirectory and put a css file in it File subdir = new File(testdir, "randomDir"); File imported = new File(subdir, "randomFile.css"); subdir.mkdir(); String importedCss = "/* Importe file */\r\n\r\n.imported {\r\n\tcolor : black;\r\n}"; CopyUtil.copy(importedCss, new FileWriter(imported)); //test that a non relative import fails when includeAMDPaths is false IConfig config = new ConfigImpl(mockAggregator, tmpdir.toURI(), "{paths: {AMDDir:'" + subdir.toURI() + "'}, cssEnableAMDIncludePaths: false}"); builder.configLoaded(config, seq++); css = "/* importing file */\n\r@import 'AMDDir/randomFile.css'"; File importingFile = new File(subdir, "importingFile.css"); CopyUtil.copy(css, new FileWriter(importingFile)); boolean exceptionCaught = false; try { output = buildCss(new FileResource(importingFile.toURI())); } catch (NotFoundException e) { exceptionCaught = true; } Assert.assertTrue("Expected FileNotFoundException", exceptionCaught); //test that non relative imports work when includeAMDPaths is true config = new ConfigImpl(mockAggregator, tmpdir.toURI(), "{paths: {AMDDir:'" + subdir.toURI() + "'}, cssEnableAMDIncludePaths: true}"); configRef.set(config); builder.configLoaded(config, seq++); css = "/* importing file */\n\r@import 'AMDDir/randomFile.css'"; importingFile = new File(subdir, "importingFile.css"); CopyUtil.copy(css, new FileWriter(importingFile)); output = buildCss(new FileResource(importingFile.toURI())); Assert.assertEquals(".imported{color:black}", output); } private String buildCss(IResource css) throws Exception { Reader reader = builder.getContentReader("test", css, mockRequest, keyGens); StringWriter writer = new StringWriter(); CopyUtil.copy(reader, writer); String output = writer.toString(); System.out.println(output); return output; } }