Package org.carrot2.labs.smartsprites

Source Code of org.carrot2.labs.smartsprites.SpriteBuilderTest

package org.carrot2.labs.smartsprites;

import static org.carrot2.labs.test.Assertions.assertThat;
import static org.fest.assertions.Assertions.assertThat;

import java.awt.Dimension;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.List;

import javax.imageio.ImageIO;

import org.apache.commons.io.FileUtils;
import org.carrot2.labs.smartsprites.SmartSpritesParameters.PngDepth;
import org.carrot2.labs.smartsprites.message.Message;
import org.carrot2.labs.smartsprites.message.Message.MessageLevel;
import org.carrot2.labs.smartsprites.message.Message.MessageType;
import org.junit.*;

import com.google.common.collect.Lists;

/**
* Test cases for {@link SpriteBuilder}. The test cases read/ write files to the
* directories contained in the test/ directory.
*/
public class SpriteBuilderTest extends TestWithMemoryMessageSink
{
    /** Builder under tests, initialized in {@link #buildSprites(SmartSpritesParameters)} */
    private SpriteBuilder spriteBuilder;

    @Before
    public void setUpHeadlessMode()
    {
        System.setProperty("java.awt.headless", "true");
    }

    @Test
    public void testNoSpriteDeclarations() throws FileNotFoundException, IOException
    {
        final File testDir = testDir("no-sprite-declarations");

        buildSprites(testDir);

        assertThat(processedCss()).doesNotExist();
        assertThat(messages).doesNotHaveMessagesOfLevel(MessageLevel.WARN);
    }

    @Test
    public void testNoSpriteReferences() throws FileNotFoundException, IOException
    {
        final File testDir = testDir("no-sprite-references");
        buildSprites(testDir);

        assertThat(processedCss()).hasSameContentAs(expectedCss());
        assertThat(messages).doesNotHaveMessagesOfLevel(MessageLevel.WARN);
    }

    @Test
    public void testTargetSpriteImageDirNotExists() throws FileNotFoundException,
        IOException
    {
        final File testDir = testDir("target-sprite-image-dir-not-exists");
        buildSprites(testDir);

        assertThat(processedCss()).hasSameContentAs(expectedCss());
        assertThat(new File(testDir, "img-sprite/sprite.png")).exists();
        assertThat(messages).doesNotHaveMessagesOfLevel(MessageLevel.WARN);

        FileUtils.deleteDirectory(new File(testDir, "img-sprite"));
    }

    @Test
    public void testSimpleHorizontalSprite() throws FileNotFoundException, IOException
    {
        final File testDir = testDir("simple-horizontal-sprite");
        buildSprites(testDir);

        assertThat(processedCss()).hasSameContentAs(expectedCss());
        assertThat(new File(testDir, "img/sprite.png")).exists();
        org.fest.assertions.Assertions.assertThat(sprite(testDir)).hasSize(
            new Dimension(17 + 15 + 48, 47));
        assertThat(messages).doesNotHaveMessagesOfLevel(MessageLevel.WARN);
    }

    @Test
    public void testSimpleHorizontalSpriteImportant() throws FileNotFoundException,
        IOException
    {
        final File testDir = testDir("simple-horizontal-sprite-important");
        buildSprites(testDir, true);

        assertThat(messages).doesNotHaveMessagesOfLevel(MessageLevel.WARN);
        assertThat(processedCss()).hasSameContentAs(expectedCss());
        assertThat(new File(testDir, "img/sprite.png")).exists();
        org.fest.assertions.Assertions.assertThat(sprite(testDir)).hasSize(
            new Dimension(17 + 15 + 48 + 20, 47));
    }

    @Test
    public void testLayoutPropertiesFromSpriteImageDirective()
        throws FileNotFoundException, IOException
    {
        final File testDir = testDir("layout-properties-from-sprite-image-directive");
        buildSprites(testDir);

        assertThat(processedCss()).hasSameContentAs(expectedCss());
        assertThat(new File(testDir, "img/sprite.png")).exists();
        org.fest.assertions.Assertions.assertThat(sprite(testDir)).hasSize(
            new Dimension(17 + 15 + 48 + 3 * (2 + 3), 47 + 5 + 7));
        assertThat(messages).doesNotHaveMessagesOfLevel(MessageLevel.WARN);
    }

    @Test
    public void testMultipleCssFiles() throws FileNotFoundException, IOException
    {
        final File testDir = testDir("multiple-css-files");
        buildSprites(testDir);

        assertThat(processedCss()).hasSameContentAs(expectedCss());
        assertThat(css("css/style2-sprite.css")).hasSameContentAs(
            css("css/style2-expected.css"));
        assertThat(new File(testDir, "img/sprite.png")).exists();
        org.fest.assertions.Assertions.assertThat(sprite(testDir)).hasSize(
            new Dimension(17 + 15 + 48, 47));
        assertThat(messages).doesNotHaveMessagesOfLevel(MessageLevel.WARN);
    }

    @Test
    public void testLargeRepeat() throws FileNotFoundException, IOException
    {
        final File testDir = testDir("large-repeat");
        buildSprites(testDir);

        final String spriteHorizontalPath = "img/sprite-horizontal.png";
        final String spriteVerticalPath = "img/sprite-vertical.png";

        assertThat(processedCss()).hasSameContentAs(expectedCss());
        assertThat(new File(testDir, spriteHorizontalPath)).exists();
        assertThat(new File(testDir, spriteVerticalPath)).exists();
        org.fest.assertions.Assertions.assertThat(sprite(testDir, spriteHorizontalPath))
            .hasSize(new Dimension(17 + 15, 16 * 17 /* lcm(16, 17) */));
        org.fest.assertions.Assertions.assertThat(sprite(testDir, spriteVerticalPath))
            .hasSize(new Dimension(15 * 17 /* lcm(15, 17) */, 17 + 16));
        assertThat(messages).doesNotHaveMessagesOfLevel(MessageLevel.WARN);
    }

    @Test
    public void testMissingImages() throws FileNotFoundException, IOException
    {
        final File testDir = testDir("missing-images");
        buildSprites(testDir);

        assertThat(processedCss()).hasSameContentAs(expectedCss());
        assertThat(new File(testDir, "img/sprite.png")).exists();
        org.fest.assertions.Assertions.assertThat(sprite(testDir)).hasSize(
            new Dimension(18, 17 + 6 + 5));

        // The unsatisfied sprite references are not removed from the output
        // file, hence we have two warnings
        assertThat(messages).contains(
            new Message(Message.MessageLevel.WARN,
                Message.MessageType.CANNOT_NOT_LOAD_IMAGE, new File(testDir,
                    "css/style.css").getPath(), 15,
                new File(testDir, "img/logo.png").getPath(), "Can't read input file!"),
            new Message(Message.MessageLevel.WARN,
                Message.MessageType.CANNOT_NOT_LOAD_IMAGE, new File(testDir,
                    "css/style-expected.css").getPath(), 15, new File(testDir,
                    "img/logo.png").getPath(), "Can't read input file!"));
    }

    @Test
    public void testUnsupportedIndividualImageFormat() throws FileNotFoundException,
        IOException
    {
        final File testDir = testDir("unsupported-image-format");
        buildSprites(testDir);

        assertThat(processedCss()).hasSameContentAs(expectedCss());
        assertThat(new File(testDir, "img/sprite.png")).doesNotExist();

        assertThat(messages).contains(
            new Message(Message.MessageLevel.WARN,
                Message.MessageType.UNSUPPORTED_INDIVIDUAL_IMAGE_FORMAT, new File(
                    testDir, "css/style.css").getPath(), 8, new File(testDir,
                    "img/web.iff").getPath()));
    }

    @Test
    public void testUnsupportedSpriteProperties() throws FileNotFoundException,
        IOException
    {
        final File testDir = testDir("unsupported-sprite-properties");
        buildSprites(testDir);

        assertThat(processedCss()).hasSameContentAs(expectedCss());
        assertThat(new File(testDir, "img/sprite.png")).exists();
        org.fest.assertions.Assertions.assertThat(sprite(testDir)).hasSize(
            new Dimension(48, 16 + 17 + 47));

        final String styleCssPath = new File(testDir, "css/style.css").getPath();
        assertThat(messages).isEquivalentTo(
            Message.MessageLevel.WARN,
            new Message(Message.MessageLevel.WARN,
                Message.MessageType.UNSUPPORTED_PROPERTIES_FOUND, styleCssPath, 4,
                "sprites-layout"),
            new Message(Message.MessageLevel.WARN,
                Message.MessageType.UNSUPPORTED_PROPERTIES_FOUND, styleCssPath, 14,
                "sprites-margin-top"),
            new Message(Message.MessageLevel.WARN,
                Message.MessageType.UNSUPPORTED_PROPERTIES_FOUND, styleCssPath, 18,
                "sprites-alignment"));
    }

    @Test
    public void testOverridingCssProperties() throws FileNotFoundException, IOException
    {
        final File testDir = testDir("overriding-css-properties");
        buildSprites(testDir);

        assertThat(processedCss()).hasSameContentAs(expectedCss());
        assertThat(new File(testDir, "img/sprite.png")).exists();
        org.fest.assertions.Assertions.assertThat(sprite(testDir)).hasSize(
            new Dimension(17 + 15 + 48, 47));

        final String styleCssPath = new File(testDir, "css/style.css").getPath();
        assertThat(messages).isEquivalentTo(
            Message.MessageLevel.WARN,
            new Message(Message.MessageLevel.WARN,
                Message.MessageType.OVERRIDING_PROPERTY_FOUND, styleCssPath, 10,
                "background-image", 9),
            new Message(Message.MessageLevel.WARN,
                Message.MessageType.OVERRIDING_PROPERTY_FOUND, styleCssPath, 21,
                "background-position", 20));
    }

    @Test
    public void testAbsoluteImageUrl() throws FileNotFoundException, IOException
    {
        final File testDir = testDir("absolute-image-url");
        final File documentRootDir = testDir("absolute-image-url/absolute-path");
        buildSprites(filesystemSmartSpritesParameters(testDir, null, documentRootDir,
            MessageLevel.INFO, SmartSpritesParameters.DEFAULT_CSS_FILE_SUFFIX,
            SmartSpritesParameters.DEFAULT_SPRITE_PNG_DEPTH,
            SmartSpritesParameters.DEFAULT_SPRITE_PNG_IE6,
            SmartSpritesParameters.DEFAULT_CSS_FILE_ENCODING));

        assertThat(processedCss()).hasSameContentAs(expectedCss());
        final File spriteFile = new File(documentRootDir, "img/sprite.png");
        assertThat(spriteFile).exists();
        org.fest.assertions.Assertions.assertThat(ImageIO.read(spriteFile)).hasSize(
            new Dimension(17, 17));
        assertThat(messages).doesNotHaveMessagesOfLevel(MessageLevel.WARN);

        org.carrot2.util.FileUtils.deleteThrowingExceptions(spriteFile);
    }

    @Test
    public void testNonDefaultOutputDir() throws FileNotFoundException, IOException
    {
        final File testDir = testDir("non-default-output-dir");
        final File documentRootDir = testDir("non-default-output-dir");
        final File outputDir = testDir("non-default-output-dir/output-dir");
        org.carrot2.util.FileUtils.mkdirsThrowingExceptions(outputDir);
        buildSprites(filesystemSmartSpritesParameters(testDir, outputDir,
            documentRootDir, MessageLevel.INFO,
            SmartSpritesParameters.DEFAULT_CSS_FILE_SUFFIX,
            SmartSpritesParameters.DEFAULT_SPRITE_PNG_DEPTH,
            SmartSpritesParameters.DEFAULT_SPRITE_PNG_IE6,
            SmartSpritesParameters.DEFAULT_CSS_FILE_ENCODING));

        assertThat(processedCss()).hasSameContentAs(expectedCss());

        final File absoluteSpriteFile = new File(documentRootDir, "img/absolute.png");
        assertThat(absoluteSpriteFile).exists();
        org.fest.assertions.Assertions.assertThat(ImageIO.read(absoluteSpriteFile))
            .hasSize(new Dimension(17, 17));

        final File relativeSpriteFile = new File(outputDir, "img/relative.png");
        assertThat(relativeSpriteFile).exists();
        org.fest.assertions.Assertions.assertThat(ImageIO.read(relativeSpriteFile))
            .hasSize(new Dimension(15, 16));
        assertThat(messages).doesNotHaveMessagesOfLevel(MessageLevel.WARN);

        FileUtils.deleteDirectory(outputDir);
        org.carrot2.util.FileUtils.deleteThrowingExceptions(absoluteSpriteFile);
    }

    @Test
    public void testScaledSpriteImage() throws FileNotFoundException, IOException
    {
        final File testDir = testDir("scaled-sprite");
        final File documentRootDir = testDir("scaled-sprite");
        buildSprites(filesystemSmartSpritesParameters(testDir, null,
            documentRootDir, MessageLevel.INFO,
            SmartSpritesParameters.DEFAULT_CSS_FILE_SUFFIX,
            SmartSpritesParameters.DEFAULT_SPRITE_PNG_DEPTH,
            SmartSpritesParameters.DEFAULT_SPRITE_PNG_IE6,
            SmartSpritesParameters.DEFAULT_CSS_FILE_ENCODING));

        assertThat(processedCss()).hasSameContentAs(expectedCss());

        final File absoluteSpriteFile = new File(documentRootDir, "img/absolute.png");
        assertThat(absoluteSpriteFile).exists();
        org.fest.assertions.Assertions.assertThat(ImageIO.read(absoluteSpriteFile))
            .hasSize(new Dimension(17, 17));

        assertThat(messages).doesNotHaveMessagesOfLevel(MessageLevel.WARN);

        org.carrot2.util.FileUtils.deleteThrowingExceptions(absoluteSpriteFile);
    }

    @Test
    public void testFractionalScaledSpriteImage() throws FileNotFoundException, IOException
    {
        final File testDir = testDir("scaled-sprite-fractional");
        final File documentRootDir = testDir("scaled-sprite-fractional");
        buildSprites(filesystemSmartSpritesParameters(testDir, null,
            documentRootDir, MessageLevel.INFO,
            SmartSpritesParameters.DEFAULT_CSS_FILE_SUFFIX,
            SmartSpritesParameters.DEFAULT_SPRITE_PNG_DEPTH,
            SmartSpritesParameters.DEFAULT_SPRITE_PNG_IE6,
            SmartSpritesParameters.DEFAULT_CSS_FILE_ENCODING));

        assertThat(processedCss()).hasSameContentAs(expectedCss());

        final File absoluteSpriteFile = new File(documentRootDir, "img/absolute.png");
        assertThat(absoluteSpriteFile).exists();
        org.fest.assertions.Assertions.assertThat(ImageIO.read(absoluteSpriteFile))
            .hasSize(new Dimension(17, 17));

//        assertThat(messages).doesNotHaveMessagesOfLevel(MessageLevel.WARN);

        assertThat(messages).isEquivalentTo(
            Message.MessageLevel.WARN,
            new Message(Message.MessageLevel.WARN,
                Message.MessageType.IMAGE_FRACTIONAL_SCALE_VALUE, null, 8, "../img/web.gif",
                8.5f, 8.5f),
            new Message(Message.MessageLevel.WARN,
                Message.MessageType.FRACTIONAL_SCALE_VALUE, null, 8, "absolute",
                8.5f, 8.5f));

        org.carrot2.util.FileUtils.deleteThrowingExceptions(absoluteSpriteFile);
    }

    @Test
    public void testCssOutputDir() throws FileNotFoundException, IOException
    {
        final File testDir = testDir("css-output-dir");
        final File rootDir = new File(testDir, "css/sprite").getCanonicalFile();
        final File outputDir = testDir("css-output-dir/output-dir/css");
        org.carrot2.util.FileUtils.mkdirsThrowingExceptions(outputDir);
        buildSprites(filesystemSmartSpritesParameters(rootDir, outputDir, null,
            MessageLevel.INFO, SmartSpritesParameters.DEFAULT_CSS_FILE_SUFFIX,
            SmartSpritesParameters.DEFAULT_SPRITE_PNG_DEPTH,
            SmartSpritesParameters.DEFAULT_SPRITE_PNG_IE6,
            SmartSpritesParameters.DEFAULT_CSS_FILE_ENCODING));

        assertThat(processedCss(new File(rootDir, "style.css"))).hasSameContentAs(
            new File(rootDir, "style-expected.css"));

        final File relativeSpriteFile = new File(outputDir, "../img/relative.png");
        assertThat(relativeSpriteFile).exists();
        org.fest.assertions.Assertions.assertThat(ImageIO.read(relativeSpriteFile))
            .hasSize(new Dimension(17 + 15, 17));
        assertThat(messages).doesNotHaveMessagesOfLevel(MessageLevel.WARN);

        FileUtils.deleteDirectory(outputDir.getParentFile());
    }

    @Test
    public void testRepeatedImageReferences() throws FileNotFoundException, IOException
    {
        final File testDir = testDir("repeated-image-references");
        buildSprites(testDir);

        assertThat(processedCss()).hasSameContentAs(expectedCss());
        assertThat(new File(testDir, "img/sprite.png")).exists();
        org.fest.assertions.Assertions.assertThat(sprite(testDir)).hasSize(
            new Dimension(17 + 19, 19));
        assertThat(messages).doesNotHaveMessagesOfLevel(MessageLevel.WARN);
    }

    @Test
    public void testIndexedColor() throws FileNotFoundException, IOException
    {
        final File testDir = testDir("indexed-color");
        buildSprites(testDir);

        org.carrot2.labs.test.Assertions
            .assertThat(sprite(testDir, "img/sprite-bit-alpha.gif")).isIndexedColor()
            .hasBitAlpha();
        org.carrot2.labs.test.Assertions
            .assertThat(sprite(testDir, "img/sprite-bit-alpha.png")).isIndexedColor()
            .hasBitAlpha();
        org.carrot2.labs.test.Assertions
            .assertThat(sprite(testDir, "img/sprite-full-alpha.png")).isDirectColor()
            .hasTrueAlpha();
        org.carrot2.labs.test.Assertions
            .assertThat(sprite(testDir, "img/sprite-many-colors.png")).isDirectColor()
            .doesNotHaveAlpha();

        assertThat(messages).doesNotHaveMessagesOfLevel(MessageLevel.WARN);
    }

    @Test
    public void testIndexedForcedDirectColor() throws FileNotFoundException, IOException
    {
        final File testDir = testDir("indexed-color");
        buildSprites(filesystemSmartSpritesParameters(testDir, null, null,
            MessageLevel.INFO, SmartSpritesParameters.DEFAULT_CSS_FILE_SUFFIX,
            PngDepth.DIRECT, SmartSpritesParameters.DEFAULT_SPRITE_PNG_IE6,
            SmartSpritesParameters.DEFAULT_CSS_FILE_ENCODING));

        org.carrot2.labs.test.Assertions
            .assertThat(sprite(testDir, "img/sprite-bit-alpha.gif")).isIndexedColor()
            .hasBitAlpha();
        org.carrot2.labs.test.Assertions
            .assertThat(sprite(testDir, "img/sprite-bit-alpha.png")).isDirectColor()
            .hasBitAlpha();
        org.carrot2.labs.test.Assertions
            .assertThat(sprite(testDir, "img/sprite-full-alpha.png")).isDirectColor()
            .hasTrueAlpha();
        org.carrot2.labs.test.Assertions
            .assertThat(sprite(testDir, "img/sprite-many-colors.png")).isDirectColor()
            .doesNotHaveAlpha();

        assertThat(messages).doesNotHaveMessagesOfLevel(MessageLevel.WARN);
    }

    @Test
    public void testIndexedForcedIndexedColor() throws FileNotFoundException, IOException
    {
        final File testDir = testDir("indexed-color");
        buildSprites(filesystemSmartSpritesParameters(testDir, null, null,
            MessageLevel.INFO, SmartSpritesParameters.DEFAULT_CSS_FILE_SUFFIX,
            PngDepth.INDEXED, SmartSpritesParameters.DEFAULT_SPRITE_PNG_IE6,
            SmartSpritesParameters.DEFAULT_CSS_FILE_ENCODING));

        org.carrot2.labs.test.Assertions
            .assertThat(sprite(testDir, "img/sprite-bit-alpha.gif")).isIndexedColor()
            .hasBitAlpha();
        org.carrot2.labs.test.Assertions
            .assertThat(sprite(testDir, "img/sprite-bit-alpha.png")).isIndexedColor()
            .hasBitAlpha();
        org.carrot2.labs.test.Assertions
            .assertThat(sprite(testDir, "img/sprite-full-alpha.png")).isIndexedColor()
            .hasBitAlpha();
        org.carrot2.labs.test.Assertions
            .assertThat(sprite(testDir, "img/sprite-many-colors.png")).isIndexedColor()
            .doesNotHaveAlpha();

        assertThat(messages).isEquivalentTo(
            Message.MessageLevel.WARN,
            new Message(Message.MessageLevel.WARN,
                Message.MessageType.ALPHA_CHANNEL_LOSS_IN_INDEXED_COLOR, null, 25,
                "full-alpha"),
            new Message(Message.MessageLevel.WARN,
                Message.MessageType.USING_WHITE_MATTE_COLOR_AS_DEFAULT, null, 25,
                "full-alpha"),
            new Message(Message.MessageLevel.WARN,
                Message.MessageType.TOO_MANY_COLORS_FOR_INDEXED_COLOR, null, 32,
                "many-colors", 293, 255));
    }

    @Test
    public void testMatteColor() throws FileNotFoundException, IOException
    {
        final File testDir = testDir("matte-color");
        buildSprites(testDir);

        org.carrot2.labs.test.Assertions
            .assertThat(sprite(testDir, "img/sprite-bit-alpha.png")).isIndexedColor()
            .hasBitAlpha();
        org.carrot2.labs.test.Assertions
            .assertThat(sprite(testDir, "img/sprite-full-alpha-m1.png")).isDirectColor()
            .hasTrueAlpha();
        org.carrot2.labs.test.Assertions
            .assertThat(sprite(testDir, "img/sprite-full-alpha-m2.png")).isDirectColor()
            .hasTrueAlpha();
        org.carrot2.labs.test.Assertions
            .assertThat(sprite(testDir, "img/sprite-full-alpha-m3.png")).isDirectColor()
            .hasTrueAlpha();
        org.carrot2.labs.test.Assertions
            .assertThat(sprite(testDir, "img/sprite-many-colors.png")).isDirectColor()
            .doesNotHaveAlpha();

        assertThat(messages).isEquivalentTo(
            Message.MessageLevel.WARN,
            new Message(Message.MessageLevel.WARN,
                Message.MessageType.IGNORING_MATTE_COLOR_NO_SUPPORT, null, 12,
                "full-alpha-m1"),
            new Message(Message.MessageLevel.WARN,
                Message.MessageType.IGNORING_MATTE_COLOR_NO_SUPPORT, null, 19,
                "full-alpha-m2"),
            new Message(Message.MessageLevel.WARN,
                Message.MessageType.IGNORING_MATTE_COLOR_NO_SUPPORT, null, 26,
                "full-alpha-m3"),
            new Message(Message.MessageLevel.WARN,
                Message.MessageType.IGNORING_MATTE_COLOR_NO_PARTIAL_TRANSPARENCY, null,
                33, "bit-alpha"),
            new Message(Message.MessageLevel.WARN,
                Message.MessageType.IGNORING_MATTE_COLOR_NO_SUPPORT, null, 40,
                "many-colors"));
    }

    @Test
    public void testMatteColorForcedIndex() throws FileNotFoundException, IOException
    {
        final File testDir = testDir("matte-color");
        buildSprites(filesystemSmartSpritesParameters(testDir, null, null,
            MessageLevel.INFO, SmartSpritesParameters.DEFAULT_CSS_FILE_SUFFIX,
            PngDepth.INDEXED, SmartSpritesParameters.DEFAULT_SPRITE_PNG_IE6,
            SmartSpritesParameters.DEFAULT_CSS_FILE_ENCODING));

        org.carrot2.labs.test.Assertions
            .assertThat(sprite(testDir, "img/sprite-bit-alpha.png")).isIndexedColor()
            .hasBitAlpha();
        org.carrot2.labs.test.Assertions
            .assertThat(sprite(testDir, "img/sprite-full-alpha-m1.png")).isIndexedColor()
            .hasBitAlpha().isEqualTo(sprite(testDir, "img/sprite-full-alpha-m2.png"))
            .isNotEqualTo(sprite(testDir, "img/sprite-full-alpha-m3.png"));
        org.carrot2.labs.test.Assertions
            .assertThat(sprite(testDir, "img/sprite-full-alpha-m2.png")).isIndexedColor()
            .hasBitAlpha().isEqualTo(sprite(testDir, "img/sprite-full-alpha-m1.png"))
            .isNotEqualTo(sprite(testDir, "img/sprite-full-alpha-m3.png"));
        org.carrot2.labs.test.Assertions
            .assertThat(sprite(testDir, "img/sprite-full-alpha-m3.png")).isIndexedColor()
            .hasBitAlpha().isNotEqualTo(sprite(testDir, "img/sprite-full-alpha-m1.png"));
        org.carrot2.labs.test.Assertions
            .assertThat(sprite(testDir, "img/sprite-many-colors.png")).isIndexedColor()
            .doesNotHaveAlpha();

        assertThat(messages).isEquivalentTo(
            Message.MessageLevel.WARN,
            new Message(Message.MessageLevel.WARN,
                Message.MessageType.ALPHA_CHANNEL_LOSS_IN_INDEXED_COLOR, null, 12,
                "full-alpha-m1"),
            new Message(Message.MessageLevel.WARN,
                Message.MessageType.ALPHA_CHANNEL_LOSS_IN_INDEXED_COLOR, null, 19,
                "full-alpha-m2"),
            new Message(Message.MessageLevel.WARN,
                Message.MessageType.ALPHA_CHANNEL_LOSS_IN_INDEXED_COLOR, null, 26,
                "full-alpha-m3"),
            new Message(Message.MessageLevel.WARN,
                Message.MessageType.IGNORING_MATTE_COLOR_NO_PARTIAL_TRANSPARENCY, null,
                33, "bit-alpha"),
            new Message(Message.MessageLevel.WARN,
                Message.MessageType.TOO_MANY_COLORS_FOR_INDEXED_COLOR, null, 40,
                "many-colors", 293, 255));
    }

    @Test
    public void testIe6IndexedColor() throws FileNotFoundException, IOException
    {
        final File testDir = testDir("indexed-color-ie6");
        buildSprites(filesystemSmartSpritesParameters(testDir, null, null,
            MessageLevel.INFO, SmartSpritesParameters.DEFAULT_CSS_FILE_SUFFIX,
            PngDepth.AUTO, true, SmartSpritesParameters.DEFAULT_CSS_FILE_ENCODING));

        org.carrot2.labs.test.Assertions
            .assertThat(sprite(testDir, "img/sprite-bit-alpha.gif")).isIndexedColor()
            .hasBitAlpha();
        org.carrot2.labs.test.Assertions
            .assertThat(sprite(testDir, "img/sprite-bit-alpha.png")).isIndexedColor()
            .hasBitAlpha();
        org.carrot2.labs.test.Assertions
            .assertThat(sprite(testDir, "img/sprite-full-alpha.png")).isDirectColor()
            .hasTrueAlpha();
        org.carrot2.labs.test.Assertions
            .assertThat(sprite(testDir, "img/sprite-full-alpha-ie6.png"))
            .isIndexedColor().hasBitAlpha();
        org.carrot2.labs.test.Assertions
            .assertThat(sprite(testDir, "img/sprite-many-colors.png")).isDirectColor()
            .doesNotHaveAlpha();
        org.carrot2.labs.test.Assertions
            .assertThat(sprite(testDir, "img/sprite-many-colors-bit-alpha-ie6.png"))
            .isIndexedColor().hasBitAlpha();
        org.carrot2.labs.test.Assertions
            .assertThat(sprite(testDir, "img/sprite-many-colors-bit-alpha-no-ie6.png"))
            .isDirectColor().hasBitAlpha();
        org.carrot2.labs.test.Assertions
            .assertThat(sprite(testDir, "img/sprite-many-colors-bit-alpha.png"))
            .isDirectColor().hasBitAlpha();

        assertThat(processedCss()).hasSameContentAs(expectedCss());

        assertThat(messages).doesNotHaveMessagesOfLevel(MessageLevel.WARN);
        assertThat(messages).isEquivalentTo(
            Message.MessageLevel.IE6NOTICE,
            new Message(Message.MessageLevel.IE6NOTICE,
                Message.MessageType.ALPHA_CHANNEL_LOSS_IN_INDEXED_COLOR, null, 27,
                "full-alpha"),
            new Message(Message.MessageLevel.IE6NOTICE,
                Message.MessageType.USING_WHITE_MATTE_COLOR_AS_DEFAULT, null, 27,
                "full-alpha"),
            new Message(Message.MessageLevel.IE6NOTICE,
                Message.MessageType.TOO_MANY_COLORS_FOR_INDEXED_COLOR, null, 41,
                "many-colors-bit-alpha", 293, 255));
    }

    @Test
    public void testSpriteImageUidMd5() throws FileNotFoundException, IOException
    {
        final File testDir = testDir("sprite-image-uid-md5");
        buildSprites(testDir);

        assertThat(processedCss()).hasSameContentAs(expectedCss());
        assertThat(new File(testDir, "img/sprite.png")).exists();
        org.fest.assertions.Assertions.assertThat(sprite(testDir)).hasSize(
            new Dimension(17 + 15, 17));
        org.fest.assertions.Assertions.assertThat(sprite(testDir, "img/sprite2.png"))
            .hasSize(new Dimension(48, 47));
        assertThat(messages).doesNotHaveMessagesOfLevel(MessageLevel.WARN);
    }

    @Test
    public void testSpriteImageUidMd5Ie6() throws FileNotFoundException, IOException
    {
        final File testDir = testDir("sprite-image-uid-md5-ie6");
        buildSprites(filesystemSmartSpritesParameters(testDir, null, null,
            MessageLevel.INFO, SmartSpritesParameters.DEFAULT_CSS_FILE_SUFFIX,
            PngDepth.AUTO, true, SmartSpritesParameters.DEFAULT_CSS_FILE_ENCODING));

        assertThat(processedCss()).hasSameContentAs(expectedCss());
        assertThat(new File(testDir, "img/sprite.png")).exists();
        assertThat(new File(testDir, "img/sprite-ie6.png")).exists();
        org.fest.assertions.Assertions.assertThat(sprite(testDir)).hasSize(
            new Dimension(20, 20));
        assertThat(messages).doesNotHaveMessagesOfLevel(MessageLevel.WARN);
    }

    @Test
    public void variableSubstitutionInSpriteImagePath() throws FileNotFoundException, IOException
    {
        final File testDir = testDir("variable-substitution-in-sprite-image-path");
        final String sprite1 = "img/sprite-4f597e065cfe89bf84fdb6594bd3b59a.png";
        final String sprite2 = "img/1cbb5bd4c5577f487e1ca434009967c/sprite2.png";

        try
        {
            buildSprites(testDir);

            assertThat(processedCss()).hasSameContentAs(expectedCss());
            assertThat(new File(testDir, sprite1)).exists();
            assertThat(new File(testDir, sprite2)).exists();
            org.fest.assertions.Assertions.assertThat(sprite(testDir, sprite1)).hasSize(
                new Dimension(17 + 15, 17));
            org.fest.assertions.Assertions.assertThat(sprite(testDir, sprite2)).hasSize(
                new Dimension(48, 47));
            assertThat(messages).doesNotHaveMessagesOfLevel(MessageLevel.WARN);
        }
        finally
        {
            FileUtils
                .deleteDirectory(new File(testDir, "img/1cbb5bd4c5577f487e1ca434009967c"));
        }
    }

    @Test
    public void testIndividualCssFileDoesNotExist() throws IOException
    {
        final String path = testDir("does-not-exist").getPath();
        buildSprites(Lists.newArrayList(path));
        assertThat(messages).contains(
            Message.warn(MessageType.CSS_FILE_DOES_NOT_EXIST, path));
    }

    @Test
    public void testDirectoryProvidedAsIndividualCssFile() throws IOException
    {
        final String path = testDir(".").getPath();
        buildSprites(Lists.newArrayList(path));
        assertThat(messages).contains(
            Message.warn(MessageType.CSS_PATH_IS_NOT_A_FILE, path));
    }

    @Test
    public void testIndividualCssFilesWithoutOutputDir() throws IOException
    {
        final File testDir = testDir("individual-css-files-without-output-dir");
        final File css = new File(testDir, "css/style-sprite.css");
        final File customCss = new File(testDir, "css/custom/style-sprite.css");
        final File otherCss = new File(testDir, "css-other/style-sprite.css");
        final File sprite = new File(testDir, "img/sprite.png");
        try
        {
            buildSprites(Lists.newArrayList(
                new File(testDir, "/css/style.css").getPath(), new File(testDir,
                    "css/custom/style.css").getPath(), new File(testDir,
                    "css-other/style.css").getPath()));
            assertThat(messages).doesNotHaveMessagesOfLevel(MessageLevel.WARN);
            assertThat(css).hasSameContentAs(new File(testDir, "css/style-expected.css"));
            assertThat(customCss).hasSameContentAs(
                new File(testDir, "css/custom/style-expected.css"));
            assertThat(otherCss).hasSameContentAs(
                new File(testDir, "css-other/style-expected.css"));
            assertThat(sprite).exists();
            org.fest.assertions.Assertions.assertThat(sprite(testDir)).hasSize(
                new Dimension(17, 17));
        }
        finally
        {
            org.carrot2.util.FileUtils.deleteThrowingExceptions(css, otherCss, customCss,
                sprite);
        }
    }

    @Test
    public void testIndividualCssFilesWithOutputDir() throws IOException
    {
        final File testDir = testDir("individual-css-files-with-output-dir");
        final File outputDir = new File(testDir, "output");
        final File css = new File(outputDir, "style-sprite.css");
        final File customCss = new File(outputDir, "custom/style-sprite.css");
        final File otherCss = new File(testDir, "css-other/style-sprite.css");
        final File sprite = new File(testDir, "img/sprite.png");
        try
        {
            final String otherCssPath = new File(testDir, "css-other/style.css")
                .getPath();
            buildSprites(Lists.newArrayList(new File(testDir, "css/style.css").getPath(),
                new File(testDir, "css/custom/style.css").getPath(), otherCssPath),
                new File(testDir, "css").getPath(), outputDir.getPath());
            assertThat(css).hasSameContentAs(new File(testDir, "css/style-expected.css"));
            assertThat(customCss).hasSameContentAs(
                new File(testDir, "css/custom/style-expected.css"));
            assertThat(otherCss).doesNotExist();
            assertThat(sprite).exists();
            org.fest.assertions.Assertions.assertThat(sprite(testDir)).hasSize(
                new Dimension(17, 17));
            assertThat(messages).contains(
                Message.warn(
                    MessageType.IGNORING_CSS_FILE_OUTSIDE_OF_ROOT_DIR, otherCssPath));
        }
        finally
        {
            FileUtils.deleteDirectory(outputDir);
            org.carrot2.util.FileUtils.deleteThrowingExceptions(sprite);
        }
    }

    @Test
    public void testSpriteMargins() throws FileNotFoundException, IOException
    {
        final File testDir = testDir("sprite-margins");
        buildSprites(testDir);

        assertThat(processedCss()).hasSameContentAs(expectedCss());
        final String horizontalSpritePath = "img/sprite-horizontal.png";
        assertThat(new File(testDir, horizontalSpritePath)).exists();
        org.fest.assertions.Assertions.assertThat(sprite(testDir, horizontalSpritePath))
            .hasSize(new Dimension(48 + 100 + 100 + 48 + 48, 47 * 6));

        final String verticalSpritePath = "img/sprite-vertical.png";
        org.fest.assertions.Assertions.assertThat(sprite(testDir, verticalSpritePath))
            .hasSize(new Dimension(48 * 6, 47 + 100 + 100 + 47 + 47));

        assertThat(messages).doesNotHaveMessagesOfLevel(MessageLevel.WARN);
    }

    @Test
    public void testSpriteCentering() throws FileNotFoundException, IOException {
        final File testDir = testDir("sprite-centering");
        buildSprites(testDir);

        assertThat(processedCss()).hasSameContentAs(expectedCss());
        final String horizontalSpritePath = "img/sprite-horizontal.png";
        assertThat(new File(testDir, horizontalSpritePath)).exists();
        org.fest.assertions.Assertions.assertThat(
                sprite(testDir, horizontalSpritePath)).hasSize(
                new Dimension(48, 47));

        final String verticalSpritePath = "img/sprite-vertical.png";
        org.fest.assertions.Assertions.assertThat(
                sprite(testDir, verticalSpritePath)).hasSize(
                new Dimension(48, 47));

        assertThat(messages).doesNotHaveMessagesOfLevel(MessageLevel.WARN);
    }

    /**
     * Test case for bug SMARTSPRITES-69.
     */
    @Test
    public void testCssSubfolders() throws FileNotFoundException, IOException
    {
        final File testDir = testDir("css-in-subfolders");
        buildSprites(testDir);

        assertThat(processedCss()).hasSameContentAs(expectedCss());
        assertThat(css("css/library/common-sprite.css")).hasSameContentAs(
            css("css/library/common-expected.css"));
        assertThat(new File(testDir, "img/sprite.png")).exists();
        org.fest.assertions.Assertions.assertThat(sprite(testDir)).hasSize(
            new Dimension(17, 17 + 16));
        assertThat(messages).doesNotHaveMessagesOfLevel(MessageLevel.WARN);

        org.carrot2.util.FileUtils
            .deleteThrowingExceptions(css("css/library/common-sprite.css"));
    }

    /**
     * Test case for bug SMARTSPRITES-78. The bug was caused by the lack of clear contract
     * on the format of paths in {@link SpriteBuilder#buildSprites(java.util.Collection)}.
     */
    @Test
    public void testCssFileApiInvocation() throws FileNotFoundException, IOException
    {
        final File testDir = testDir("simple-horizontal-sprite");
        final File outputCss = new File(testDir, "css/style-sprite.css");
        final File sprite = new File(testDir, "img/sprite.png");

        try
        {
            buildSprites(Lists.newArrayList(new File(testDir, "css/style.css").getPath()
                .replace(File.separatorChar, '/')));

            assertThat(outputCss).hasSameContentAs(
                new File(testDir, "css/style-expected.css"));
            assertThat(sprite).exists();
            org.fest.assertions.Assertions.assertThat(sprite(testDir)).hasSize(
                new Dimension(17 + 15 + 48, 47));
            assertThat(messages).doesNotHaveMessagesOfLevel(MessageLevel.WARN);
        }
        finally
        {
            org.carrot2.util.FileUtils.deleteThrowingExceptions(outputCss, sprite);
        }
    }

    @After
    public void cleanUp() throws IOException
    {
        // Delete sprite CSS
        final String rootDir = spriteBuilder.parameters.getRootDir();
        if (rootDir == null)
        {
            return;
        }

        org.carrot2.util.FileUtils.deleteThrowingExceptions(new File(rootDir, "css")
            .listFiles(new FilenameFilter()
            {
                public boolean accept(File dir, String name)
                {
                    return name.contains("-sprite");
                }
            }));

        // Delete sprites
        org.carrot2.util.FileUtils.deleteThrowingExceptions(new File(rootDir, "img")
            .listFiles(new FilenameFilter()
            {
                public boolean accept(File dir, String name)
                {
                    return name.startsWith("sprite");
                }
            }));
    }

    private File testDir(String test)
    {
        return new File("test/" + test);
    }

    private BufferedImage sprite(final File testDir) throws IOException
    {
        return sprite(testDir, "img/sprite.png");
    }

    private BufferedImage sprite(final File testDir, String imagePath) throws IOException
    {
        return ImageIO.read(new File(testDir, imagePath));
    }

    private File expectedCss()
    {
        return css("css/style-expected.css");
    }

    private File sourceCss()
    {
        return css("css/style.css");
    }

    private File processedCss()
    {
        return processedCss(sourceCss());
    }

    private File css(String cssPath)
    {
        return new File(spriteBuilder.parameters.getRootDir(), cssPath);
    }

    private File processedCss(File sourceCss)
    {
        return new File(spriteBuilder.getProcessedCssFile(sourceCss.getPath()));
    }

    private void buildSprites(File dir) throws IOException
    {
        buildSprites(dir, false);
    }

    private void buildSprites(File dir, boolean ie6) throws IOException
    {
        buildSprites(new SmartSpritesParameters(dir.getPath(), null, null, null,
            SmartSpritesParameters.DEFAULT_LOGGING_LEVEL,
            SmartSpritesParameters.DEFAULT_CSS_FILE_SUFFIX,
            SmartSpritesParameters.DEFAULT_SPRITE_PNG_DEPTH, ie6,
            SmartSpritesParameters.DEFAULT_CSS_FILE_ENCODING));
    }

    private void buildSprites(List<String> cssFiles) throws IOException
    {
        buildSprites(cssFiles, null, null);
    }

    private void buildSprites(List<String> cssFiles, String rootDir, String outputDir)
        throws IOException
    {
        buildSprites(new SmartSpritesParameters(rootDir, cssFiles, outputDir, null,
            SmartSpritesParameters.DEFAULT_LOGGING_LEVEL,
            SmartSpritesParameters.DEFAULT_CSS_FILE_SUFFIX,
            SmartSpritesParameters.DEFAULT_SPRITE_PNG_DEPTH,
            SmartSpritesParameters.DEFAULT_SPRITE_PNG_IE6,
            SmartSpritesParameters.DEFAULT_CSS_FILE_ENCODING));
    }

    private void buildSprites(SmartSpritesParameters parameters) throws IOException
    {
        spriteBuilder = new SpriteBuilder(parameters, messageLog);
        spriteBuilder.buildSprites();
    }

    private static SmartSpritesParameters filesystemSmartSpritesParameters(File rootDir,
        File outputDir, File documentRootDir, MessageLevel logLevel,
        String cssFileSuffix, PngDepth spritePngDepth, boolean spritePngIe6,
        String cssEncoding)
    {
        return new SmartSpritesParameters(rootDir.getPath(), null,
            outputDir != null ? outputDir.getPath() : null,
            documentRootDir != null ? documentRootDir.getPath() : null, logLevel,
            cssFileSuffix, spritePngDepth, spritePngIe6, cssEncoding);
    }

}
TOP

Related Classes of org.carrot2.labs.smartsprites.SpriteBuilderTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.